local args = {...} local Logging = require("logging") local Logger = Logging.firstLoad( Logging.OUTPUTS.file("tunnel.log"), Logging.OUTPUTS.stdout() ) local CHEST_SLOT = #args == 1 and tonumber(args[1]) or 1 if type(CHEST_SLOT) ~= "number" or CHEST_SLOT < 1 or CHEST_SLOT > 16 then Logger:error("Slot number is not valid:", CHEST_SLOT) end local CHEST_PICKUP = #args == 2 and (args[2]:lower() ) local CHEST_DETAIL = turtle.getItemDetail(CHEST_SLOT) if CHEST_DETAIL == nil then Logger:error("No chest in slot! Quitting...") return end local CHEST_NAME = CHEST_DETAIL.name local function refuel(minFuel) local fuelLevel = turtle.getFuelLevel() while fuelLevel < minFuel do Logger:debug("Checking fuel level:", fuelLevel) for i=1,16 do if i == CHEST_SLOT then goto continue end if turtle.getItemCount(i) > 0 then turtle.select(i) turtle.refuel() end ::continue:: end fuelLevel = turtle.getFuelLevel() end Logger:debug("Fuel level is sufficient:", fuelLevel) turtle.select(1) end local function isFull(minEmpty) local emptyCount = 0 for i=1,16 do if i == CHEST_SLOT then goto continue end if turtle.getItemCount(i) == 0 then emptyCount = emptyCount + 1 if emptyCount >= minEmpty then return false end end ::continue:: end return true end local function placeChest() if not turtle.select(CHEST_SLOT) then Logger:error("Cannot select chest slot", CHEST_SLOT) return false, nil, nil, nil end if turtle.placeUp() or (turtle.digUp() and turtle.placeUp()) then return true, turtle.dropUp, turtle.digUp, function() end end if turtle.turnLeft() and turtle.turnLeft() and (turtle.place() or (turtle.dig() and turtle.place())) then return true, turtle.drop, turtle.dig, function() turtle.turnRight() turtle.turnRight() end end return false, nil, nil, nil end local function handleFullInv(minEmpty) local didPlace = false local result, drop, dig, onComplete = false, nil, nil, nil -- Empty inventory while isFull(minEmpty) do if not didPlace then local detail = turtle.getItemDetail(CHEST_SLOT) if type(detail) ~= "table" or detail.name ~= CHEST_NAME then Logger:error("Can't find chest :(") os.sleep(5) goto continue end -- Try: place, check block above is empty or dig it, place -- If all fails, print error, wait and repeat result, drop, dig, onComplete = placeChest() if not result then Logger:error("Can't place chest :(") os.sleep(5) goto continue end didPlace = true end assert(drop ~= nil, "Placed chest, but drop operation is nil") for i=1,16 do if i == CHEST_SLOT then goto continue_SLOT end if turtle.getItemCount(i) > 0 and not (turtle.select(i) and drop()) then Logger:error("Couldn't drop items into chest!") goto continue end ::continue_SLOT:: end ::continue:: end if result then assert(dig ~= nil, "Placed chest, but dig operation is nil") if didPlace and CHEST_PICKUP then turtle.select(CHEST_SLOT) dig() end assert(onComplete ~= nil, "Placed chest, but onComplete operation is nil") onComplete() end end local function dig(checkRefuel) while not turtle.forward() do turtle.dig() checkRefuel() end turtle.digUp() turtle.digDown() end local function line(length, turn, checkRefuel) turtle.digDown() for _=2,length do dig(checkRefuel) end turn() end local function panel(width, length, leftFirst, checkRefuel, checkFullInv) Logger:trace("Panel:", width, length) local turn, otherTurn = leftFirst and turtle.turnLeft or turtle.turnRight, leftFirst and turtle.turnRight or turtle.turnLeft for _=2,width do checkFullInv() line(length, turn, checkRefuel) dig(checkRefuel) turn() turn, otherTurn = otherTurn, turn end line(length, turn, checkRefuel) turn() end local function rectPrism(depth, width, length, leftFirst) local refuelTarget = width * length * 1.5 local function checkRefuel() refuel(refuelTarget) end local invEmptyTarget = 3 local function checkFullInv() Logger:debug("Handling full inventory with target:", invEmptyTarget, " handled:", handleFullInv(invEmptyTarget)) end Logger:trace("RectPrism:", depth, width, length) for _=1,depth do panel(width, length, leftFirst, checkRefuel, checkFullInv) for __=1,3 do while not turtle.down() do turtle.digDown() checkRefuel() end end leftFirst = (not not leftFirst) ~= (width % 2 == 0) end end rectPrism(200, 16, 16)