diff --git a/miningTurtle.lua b/miningTurtle.lua index a704ff9..53dca4f 100644 --- a/miningTurtle.lua +++ b/miningTurtle.lua @@ -20,8 +20,20 @@ end local MINE_INTERVAL = 0.5 -- seconds between dig attempts local DUMP_THRESHOLD = 14 -- dump when this many slots are occupied local DUMP_INTERVAL = 30 -- force dump every N seconds even if not full -local FUEL_SLOT = 16 -- reserve this slot for fuel (0 = disabled) +local FUEL_SLOT = 16 -- slot used for pulling/burning fuel +local FUEL_THRESHOLD = 200 -- pull fuel when below this level local SYSTEM_CHANNEL = 4205 -- remote reboot channel +local ORDER_CHANNEL = 4201 -- channel to talk to manager +local FUEL_REQUEST_TIMEOUT = 5 -- seconds to wait for manager reply + +-- Fuel items the turtle will look for in storage (best first) +local FUEL_ITEMS = { + "minecraft:coal", + "minecraft:charcoal", + "minecraft:coal_block", + "minecraft:blaze_rod", + "minecraft:dried_kelp_block", +} ------------------------------------------------- -- Load config from file if present @@ -169,20 +181,112 @@ local function occupiedSlots() end ------------------------------------------------- --- Auto-refuel from fuel slot +-- Auto-refuel: ask manager for fuel, pull directly ------------------------------------------------- -local function autoRefuel() - if FUEL_SLOT <= 0 then return end - if turtle.getFuelLevel() == "unlimited" then return end - if turtle.getFuelLevel() > 100 then return end +--- Try to burn whatever is already in FUEL_SLOT +local function burnFuelSlot() + if FUEL_SLOT <= 0 then return false end local prev = turtle.getSelectedSlot() turtle.select(FUEL_SLOT) if turtle.getItemCount() > 0 then - turtle.refuel(1) - print("[FUEL] Refueled. Level: " .. turtle.getFuelLevel()) + local ok = turtle.refuel() + turtle.select(prev) + return ok end turtle.select(prev) + return false +end + +--- Ask the inventory manager where fuel items are +local function askManagerForFuel() + local replyChannel = ORDER_CHANNEL + 100 + os.getComputerID() + modem.open(replyChannel) + + modem.transmit(ORDER_CHANNEL, replyChannel, { + type = "find_item", + items = FUEL_ITEMS, + limit = 1, + }) + + local deadline = os.clock() + FUEL_REQUEST_TIMEOUT + local result = nil + + while os.clock() < deadline do + local timerId = os.startTimer(math.max(0.1, deadline - os.clock())) + local event, p1, p2, p3, p4 = os.pullEvent() + if event == "modem_message" and p2 == replyChannel then + if type(p4) == "table" and p4.type == "find_item_result" then + result = p4.results + break + end + elseif event == "timer" and p1 == timerId then + break + end + end + + modem.close(replyChannel) + return result +end + +--- Pull fuel from a specific chest+slot (told by manager) +local function pullFuelFromSource(source) + if FUEL_SLOT <= 0 then return false end + local chest = peripheral.wrap(source.chest) + if not chest then return false end + local ok, n = pcall(chest.pushItems, selfName, source.slot, 64, FUEL_SLOT) + if ok and n and n > 0 then + print(string.format("[FUEL] Pulled %s x%d from %s", source.name, n, source.chest)) + return true + end + return false +end + +local function pullFuelFromStorage() + -- Ask manager first (it knows exactly where fuel is) + local sources = askManagerForFuel() + if sources and #sources > 0 then + for _, source in ipairs(sources) do + if pullFuelFromSource(source) then return true end + end + end + + -- Fallback: scan chests directly (in case manager is offline) + local fuelSet = {} + for _, name in ipairs(FUEL_ITEMS) do fuelSet[name] = true end + local chests = getChests() + for _, chestName in ipairs(chests) do + local chest = peripheral.wrap(chestName) + if chest and chest.list then + for slot, item in pairs(chest.list() or {}) do + if fuelSet[item.name] then + local ok, n = pcall(chest.pushItems, selfName, slot, 64, FUEL_SLOT) + if ok and n and n > 0 then + print(string.format("[FUEL] Pulled %s x%d (fallback)", item.name, n)) + return true + end + end + end + end + end + return false +end + +local function autoRefuel() + if turtle.getFuelLevel() == "unlimited" then return end + if turtle.getFuelLevel() >= FUEL_THRESHOLD then return end + + -- First try burning whatever is already in the fuel slot + if burnFuelSlot() then + print("[FUEL] Burned local fuel. Level: " .. turtle.getFuelLevel()) + return + end + + -- Pull fresh fuel from networked storage + if pullFuelFromStorage() then + burnFuelSlot() + print("[FUEL] Refueled from storage. Level: " .. turtle.getFuelLevel()) + end end ------------------------------------------------- @@ -223,12 +327,17 @@ local function mineLoop() -- Auto-refuel if low autoRefuel() - -- Check fuel + -- Check fuel — keep trying to pull from storage if turtle.getFuelLevel() ~= "unlimited" and turtle.getFuelLevel() < 1 then - print("[WARN] Out of fuel! Waiting...") + print("[WARN] Out of fuel! Searching storage...") while turtle.getFuelLevel() < 1 do - autoRefuel() - sleep(5) + if pullFuelFromStorage() then + burnFuelSlot() + end + if turtle.getFuelLevel() < 1 then + printStats() + sleep(10) + end end end