local tArgs = {...}
local LEFT = 0
local FORWARD = 1
local RIGHT = 2
local nCurrentDir = FORWARD
local nCurrentX = 0
local nCurrentY = 0
--(( Functions ))--
local function look(nDir)
while nDir < nCurrentDir do
turtle.turnLeft()
nCurrentDir = nCurrentDir - 1
end
while nDir > nCurrentDir do
turtle.turnRight()
nCurrentDir = nCurrentDir + 1
end
end
local function _go(move, suffix)
while not turtle[move]() do
if not turtle["dig"..suffix]() then
if turtle["detect"..suffix]() then
error("Bedrock while trying to move " .. move, 0)
end
turtle["attack"..suffix]()
end
end
end
local function goForward()
_go("forward", "")
if nCurrentDir == RIGHT then
nCurrentX = nCurrentX + 1
elseif nCurrentDir == LEFT then
nCurrentX = nCurrentX - 1
end
end
local function goUp()
_go("up", "Up")
nCurrentY = nCurrentY + 1
end
local function goDown()
_go("down", "Down")
nCurrentY = nCurrentY - 1
end
local function goToY(y)
if nCurrentY < y then
-- +1 because for loops are inclusive
for _ = nCurrentY + 1, y, 1 do
goUp()
end
else
-- -1 because for loops are inclusive
for _ = nCurrentY - 1, y, -1 do
goDown()
end
end
end
---If current `Y` position is higher than the given `Y` coordinate
---then move to said `Y` coordinate.
local function goToYIfHigher(y)
if nCurrentY > y then
goToY(y)
end
end
---If current `Y` position is lower than the given `Y` coordinate
---then move to said `Y` coordinate.
local function goToYIfLower(y)
if nCurrentY < y then
goToY(y)
end
end
local function goToX(x)
if nCurrentX < x then
look(RIGHT)
-- +1 because for loops are inclusive
for _ = nCurrentX + 1, x do
goForward()
end
elseif nCurrentX > x then
look(LEFT)
-- -1 because for loops are inclusive
for _ = nCurrentX - 1, x, -1 do
goForward()
end
end
end
local function _digTilTop(nHeight)
-- dig til top-1
while nCurrentY < nHeight - 2 do
goUp()
end
if nCurrentY <= nHeight - 2 then
repeat until not turtle.digUp()
end
end
local function _digTilBottom()
-- dig til bottom+1
while nCurrentY > 1 do
goDown()
end
if nCurrentY >= 1 then
repeat until not turtle.digDown()
end
end
local function digColumn(nHeight)
if nCurrentY < nHeight / 2 then
-- bot to top
_digTilBottom()
_digTilTop(nHeight)
else
-- top to bot
_digTilTop(nHeight)
_digTilBottom()
end
end
local function digFrame(nHeight, nWidth)
digColumn(nHeight)
if nWidth == 1 or nWidth == -1 then
return
end
if nCurrentX > nWidth / 2 then
look(LEFT)
else
look(RIGHT)
end
for _ = 1, math.abs(nWidth) - 1 do
goForward()
digColumn(nHeight)
end
end
local function adjustForYDiff(nHeight, nYDiff)
if nYDiff == 0 then
return
end
if nYDiff > 0 then
local lowestY = nYDiff
goToYIfLower(lowestY)
else
local highestY = nHeight + nYDiff - 1
goToYIfHigher(highestY)
end
nCurrentY = nCurrentY - nYDiff
end
local function goHome()
goToX(0)
look(FORWARD)
goToY(0)
end
local function tunnel(nLength, nHeight, nWidth, nYDiff)
for _ = 1, nLength do
look(FORWARD)
goForward()
adjustForYDiff(nHeight, nYDiff)
digFrame(nHeight, nWidth)
end
goHome()
end
--(( Error checking ))--
local nArgLength = tonumber(tArgs[1])
local nArgHeight = tonumber(tArgs[2] or 2)
local nArgWidth = tonumber(tArgs[3] or 1)
local nArgYDiff = tonumber(tArgs[4] or 0)
local function usage(sMsg)
sMsg = sMsg and (sMsg .. "\n") or ""
error(sMsg .. "Usage: tunnel <length> [height=2] [width=1] [y-diff=0]", 0)
end
if #tArgs==0 then usage("Missing length.") end
if not nArgLength then usage("Invalid length, expected number.") end
if not nArgHeight then usage("Invalid height, expected number.") end
if not nArgWidth then usage("Invalid right, expected number.") end
if not nArgYDiff then usage("Invalid y-diff, expected number.") end
if nArgLength <= 0 then usage("Invalid length, negative not supported.") end
if nArgHeight <= 0 then usage("Invalid height, negative not supported.") end
if nArgWidth == 0 then usage("Invalid width, zero not supported.") end
if math.abs(nArgYDiff) > nArgHeight - 1 then usage("Invalid y-diff, cannot be longer than height - 1.") end
if nArgLength % 1 ~= 0 then usage("Invalid length, fractions not supported.") end
if nArgHeight % 1 ~= 0 then usage("Invalid height, fractions not supported.") end
if nArgWidth % 1 ~= 0 then usage("Invalid right, fractions not supported.") end
if nArgYDiff % 1 ~= 0 then usage("Invalid y-diff, fractions not supported.") end
--(( Main program ))--
tunnel(nArgLength, nArgHeight, nArgWidth, nArgYDiff)
--(( EOF ))---
Comments