diff --git a/inventoryManager.lua b/inventoryManager.lua index 669e126..6645009 100644 --- a/inventoryManager.lua +++ b/inventoryManager.lua @@ -2267,6 +2267,7 @@ local function autoSmelt() local chests = getChests() local catalogue = cache.catalogue local didWork = false + local emptyInputFurnaces = {} -- collected during steps 1-3, filled in step 5 for _, fname in ipairs(furnaces) do local furnace = peripheral.wrap(fname) @@ -2369,40 +2370,80 @@ local function autoSmelt() end end - -- 4) Load smeltable items into empty input slot + -- 4) Collect furnaces with empty input for balanced loading below inputItem = contents[SLOT_INPUT] if not inputItem then - -- Use pre-built candidate list (already sorted: food first, then alpha) - local candidates = smeltCandidatesByType[furnaceType] or {} + table.insert(emptyInputFurnaces, { name = fname, type = furnaceType }) + end + end + end - -- Try each candidate - for _, cand in ipairs(candidates) do - local itemName = cand.name - if not disabledRecipes[itemName] and catalogue[itemName] then - -- Count total of this item across all chests - local totalInStorage = 0 - for _, src in ipairs(catalogue[itemName]) do - totalInStorage = totalInStorage + src.total - end + -- 5) Balanced distribution of smeltable items across all empty furnaces + -- Instead of greedily filling one furnace at a time, we spread items + -- evenly so all compatible furnaces work in parallel. + if #emptyInputFurnaces > 0 then + -- Build a unified, deduplicated candidate list across all empty furnace types + local typesSeen = {} + for _, ef in ipairs(emptyInputFurnaces) do typesSeen[ef.type] = true end - -- Only smelt the excess beyond SMELT_RESERVE - local available = totalInStorage - SMELT_RESERVE - if available > 0 then + local allCandidates = {} + local candSeen = {} + for ftype in pairs(typesSeen) do + for _, cand in ipairs(smeltCandidatesByType[ftype] or {}) do + if not candSeen[cand.name] then + candSeen[cand.name] = true + table.insert(allCandidates, cand) + end + end + end + -- Sort: food first, then alphabetical (same priority as before) + table.sort(allCandidates, function(a, b) + if a.food ~= b.food then return a.food end + return a.name < b.name + end) + + local usedFurnaces = {} -- furnaces already assigned an item + + for _, cand in ipairs(allCandidates) do + local itemName = cand.name + if not disabledRecipes[itemName] and catalogue[itemName] then + -- Find all compatible empty furnaces not yet used + local compatFurnaces = {} + for _, ef in ipairs(emptyInputFurnaces) do + if not usedFurnaces[ef.name] and cand.recipe.furnaceSet[ef.type] then + table.insert(compatFurnaces, ef) + end + end + + if #compatFurnaces > 0 then + local totalInStorage = 0 + for _, src in ipairs(catalogue[itemName]) do + totalInStorage = totalInStorage + src.total + end + local available = totalInStorage - SMELT_RESERVE + if available > 0 then + local perFurnace = math.min(64, math.ceil(available / #compatFurnaces)) + + for _, ef in ipairs(compatFurnaces) do + if available <= 0 then break end + local toLoad = math.min(perFurnace, available) + local remaining = toLoad local loaded = false - local remaining = math.min(available, 64) + for _, source in ipairs(catalogue[itemName]) do local chest = peripheral.wrap(source.chest) if chest then for slot, slotItem in pairs(chest.list()) do if slotItem.name == itemName then local toMove = math.min(slotItem.count, remaining) - local n = chest.pushItems(fname, slot, toMove, SLOT_INPUT) + local n = chest.pushItems(ef.name, slot, toMove, SLOT_INPUT) if n and n > 0 then adjustCache(itemName, source.chest, -n) - print(string.format("[SMELT] Input %s x%d -> %s (reserve %d)", - itemName, n, fname, math.max(0, totalInStorage - n))) + print(string.format("[SMELT] Input %s x%d -> %s (balanced %d/furnace)", + itemName, n, ef.name, perFurnace)) didWork = true remaining = remaining - n + available = available - n if remaining <= 0 then loaded = true break @@ -2413,7 +2454,10 @@ local function autoSmelt() end if loaded then break end end - if loaded or remaining < math.min(available, 64) then break end + + if loaded or remaining < toLoad then + usedFurnaces[ef.name] = true + end end end end