feat: enhance crafting execution to support batch processing with clamping to max stack size

This commit is contained in:
MayaTheShy
2026-03-25 21:45:33 -04:00
parent 1606d60a06
commit df436ff84d

View File

@@ -168,7 +168,8 @@ end
-- @param recipe crafting recipe table -- @param recipe crafting recipe table
-- @param ctx context table with ops, cfg, state, log, craftTurtleName, networkModem -- @param ctx context table with ops, cfg, state, log, craftTurtleName, networkModem
-- @return success, error_message -- @return success, error_message
function craft.executeSingleCraft(recipe, ctx) function craft.executeSingleCraft(recipe, ctx, batches)
batches = batches or 1
local ops = ctx.ops local ops = ctx.ops
local cfg = ctx.cfg local cfg = ctx.cfg
local st = ctx.state local st = ctx.state
@@ -177,11 +178,14 @@ function craft.executeSingleCraft(recipe, ctx)
if not ctx.networkModem then return false, "No modem" end if not ctx.networkModem then return false, "No modem" end
if not peripheral.isPresent(ctx.craftTurtleName) then return false, "Turtle offline" end if not peripheral.isPresent(ctx.craftTurtleName) then return false, "Turtle offline" end
-- Clamp batches to 64 (max stack size per slot)
batches = math.min(batches, 64)
local chests = ops.getChests() local chests = ops.getChests()
local slotMap = {} local slotMap = {}
local reserved = {} local reserved = {}
-- Map each grid position to a chest slot -- Map each grid position to a chest slot, pulling `batches` items per slot
for gridPos = 1, 9 do for gridPos = 1, 9 do
local itemName = recipe.grid[gridPos] local itemName = recipe.grid[gridPos]
if itemName then if itemName then
@@ -195,11 +199,12 @@ function craft.executeSingleCraft(recipe, ctx)
for slot, si in pairs(chest.list()) do for slot, si in pairs(chest.list()) do
local key = src.chest .. ":" .. slot local key = src.chest .. ":" .. slot
if si.name == itemName and not reserved[key] then if si.name == itemName and not reserved[key] then
local pullCount = math.min(batches, si.count)
slotMap[tostring(tSlot)] = { slotMap[tostring(tSlot)] = {
chestName = src.chest, chestName = src.chest,
chestSlot = slot, chestSlot = slot,
itemName = itemName, itemName = itemName,
count = 1, count = pullCount,
} }
reserved[key] = true reserved[key] = true
found = true found = true
@@ -298,16 +303,20 @@ function craft.executeChain(targetItem, count, ctx)
ctx.state.needsRedraw = true ctx.state.needsRedraw = true
ctx.state.smelterNeedsRedraw = true ctx.state.smelterNeedsRedraw = true
for batch = 1, step.count do -- Batch in chunks of 64 (max stack per turtle slot)
local ok, batchErr = craft.executeSingleCraft(step.recipe, ctx) local remaining = step.count
while remaining > 0 do
local chunk = math.min(remaining, 64)
local ok, batchErr = craft.executeSingleCraft(step.recipe, ctx, chunk)
if not ok then if not ok then
ctx.state.activity.crafting = false ctx.state.activity.crafting = false
ctx.state.needsRedraw = true ctx.state.needsRedraw = true
ctx.log.error("CRAFT", "Chain failed at step %d batch %d: %s", i, batch, batchErr) ctx.log.error("CRAFT", "Chain failed at step %d: %s", i, batchErr)
return false, string.format("Step %d/%d failed: %s", i, #steps, batchErr) return false, string.format("Step %d/%d failed: %s", i, #steps, batchErr)
end end
-- Brief pause between batches to let turtle finish remaining = remaining - chunk
if batch < step.count then os.sleep(0.3) end -- Brief pause between chunks to let turtle finish
if remaining > 0 then os.sleep(0.3) end
end end
ctx.log.info("CRAFT", "Step %d/%d complete: %s x%d", i, #steps, step.output, step.outputCount) ctx.log.info("CRAFT", "Step %d/%d complete: %s x%d", i, #steps, step.output, step.outputCount)