cc-utilities/quarry.lua
2024-12-01 04:37:58 +01:00

149 lines
3.7 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 turtle.getItemCount(i) > 0 then
turtle.select(i)
turtle.refuel()
end
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 handleFullInv(minEmpty)
local didPlace = false
-- 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
if not (turtle.placeUp() or ((not turtle.inspectUp() or turtle.digUp()) and turtle.placeUp())) then
Logger:error("Can't place chest :(")
os.sleep(5)
goto continue
end
didPlace = true
end
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 turtle.dropUp()) then
Logger:error("Couldn't drop items into chest!")
goto continue
end
::continue_SLOT::
end
::continue::
end
if didPlace and CHEST_PICKUP then
turtle.select(CHEST_SLOT)
turtle.digUp()
end
end
local function dig(checkRefuel)
while not turtle.forward() do
turtle.dig()
checkRefuel()
end
turtle.digDown()
end
local function line(length, turn, checkRefuel)
turtle.digDown()
for i=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 i=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 i=1,depth do
panel(width, length, leftFirst, checkRefuel, checkFullInv)
while not turtle.down() do
turtle.digDown()
checkRefuel()
end
leftFirst = (not not leftFirst) ~= (width % 2 == 0)
end
end
rectPrism(200, 16, 16)