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 [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 width, 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 width, 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 ))---