feat: enhance auto-refuel functionality with manager integration and fallback mechanism
This commit is contained in:
133
miningTurtle.lua
133
miningTurtle.lua
@@ -20,8 +20,20 @@ end
|
|||||||
local MINE_INTERVAL = 0.5 -- seconds between dig attempts
|
local MINE_INTERVAL = 0.5 -- seconds between dig attempts
|
||||||
local DUMP_THRESHOLD = 14 -- dump when this many slots are occupied
|
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 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 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
|
-- Load config from file if present
|
||||||
@@ -169,20 +181,112 @@ local function occupiedSlots()
|
|||||||
end
|
end
|
||||||
|
|
||||||
-------------------------------------------------
|
-------------------------------------------------
|
||||||
-- Auto-refuel from fuel slot
|
-- Auto-refuel: ask manager for fuel, pull directly
|
||||||
-------------------------------------------------
|
-------------------------------------------------
|
||||||
|
|
||||||
local function autoRefuel()
|
--- Try to burn whatever is already in FUEL_SLOT
|
||||||
if FUEL_SLOT <= 0 then return end
|
local function burnFuelSlot()
|
||||||
if turtle.getFuelLevel() == "unlimited" then return end
|
if FUEL_SLOT <= 0 then return false end
|
||||||
if turtle.getFuelLevel() > 100 then return end
|
|
||||||
local prev = turtle.getSelectedSlot()
|
local prev = turtle.getSelectedSlot()
|
||||||
turtle.select(FUEL_SLOT)
|
turtle.select(FUEL_SLOT)
|
||||||
if turtle.getItemCount() > 0 then
|
if turtle.getItemCount() > 0 then
|
||||||
turtle.refuel(1)
|
local ok = turtle.refuel()
|
||||||
print("[FUEL] Refueled. Level: " .. turtle.getFuelLevel())
|
turtle.select(prev)
|
||||||
|
return ok
|
||||||
end
|
end
|
||||||
turtle.select(prev)
|
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
|
end
|
||||||
|
|
||||||
-------------------------------------------------
|
-------------------------------------------------
|
||||||
@@ -223,12 +327,17 @@ local function mineLoop()
|
|||||||
-- Auto-refuel if low
|
-- Auto-refuel if low
|
||||||
autoRefuel()
|
autoRefuel()
|
||||||
|
|
||||||
-- Check fuel
|
-- Check fuel — keep trying to pull from storage
|
||||||
if turtle.getFuelLevel() ~= "unlimited" and turtle.getFuelLevel() < 1 then
|
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
|
while turtle.getFuelLevel() < 1 do
|
||||||
autoRefuel()
|
if pullFuelFromStorage() then
|
||||||
sleep(5)
|
burnFuelSlot()
|
||||||
|
end
|
||||||
|
if turtle.getFuelLevel() < 1 then
|
||||||
|
printStats()
|
||||||
|
sleep(10)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user