185 lines
4.6 KiB
Lua
185 lines
4.6 KiB
Lua
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) |