diff --git a/data/auto_craft.lua b/data/auto_craft.lua new file mode 100644 index 0000000..b9ae912 --- /dev/null +++ b/data/auto_craft.lua @@ -0,0 +1,14 @@ +-- Auto-craft rules: items that should be automatically crafted when stock exceeds reserve. +-- The system will keep `reserve` of the input item and craft all excess into the output. +-- Requires a crafting turtle to be connected. +-- +-- Format: { input = "mod:item", reserve = N, output = "mod:output_item" } +-- The output item must have a recipe in data/craftable.lua (or learned via recipeBook). +-- Recursive crafting is used, so intermediate steps are handled automatically. + +return { + -- Convert excess bamboo into planks (keeps 128 raw bamboo as reserve) + { input = "minecraft:bamboo", reserve = 128, output = "minecraft:bamboo_planks" }, + -- Convert excess bamboo blocks into planks too (keeps 64 blocks as reserve) + { input = "minecraft:bamboo_block", reserve = 64, output = "minecraft:bamboo_planks" }, +} diff --git a/inventoryManager.lua b/inventoryManager.lua index 51aafe0..95180e2 100644 --- a/inventoryManager.lua +++ b/inventoryManager.lua @@ -443,6 +443,25 @@ local function main() end end, + -- Task 5c: Auto-craft excess items into target products + function() + if #cfg.AUTO_CRAFT_RULES == 0 then + while true do sleep(3600) end + end + sleep(12) -- let initial scan + discard settle first + log.info("AUTOCRAFT", "Auto-craft active with %d rule(s)", #cfg.AUTO_CRAFT_RULES) + while true do + if ctx.craftTurtleName then + activity.autocrafting = true + state.needsRedraw = true + pcall(ops.autoCraft) + activity.autocrafting = false + state.needsRedraw = true + end + sleep(cfg.AUTO_CRAFT_INTERVAL) + end + end, + -- Task 6: Low-stock alert checker function() sleep(5) diff --git a/manager/config.lua b/manager/config.lua index 13f76cf..7f66406 100644 --- a/manager/config.lua +++ b/manager/config.lua @@ -64,6 +64,9 @@ C.TRASH_DROPPERS = { -- droppers facing lava/void for destroying } C.DISCARD_INTERVAL = 5 -- seconds between discard checks +-- Auto-craft (overridable via config file) +C.AUTO_CRAFT_INTERVAL = 10 -- seconds between auto-craft checks + -- Peripheral C.PERIPHERAL_CACHE_TTL = 5 @@ -126,6 +129,7 @@ function C.loadConfig() if cfg.compostHopper then C.COMPOST_HOPPER = cfg.compostHopper end if cfg.trashDroppers then C.TRASH_DROPPERS = cfg.trashDroppers end if cfg.discardInterval then C.DISCARD_INTERVAL = cfg.discardInterval end + if cfg.autoCraftInterval then C.AUTO_CRAFT_INTERVAL = cfg.autoCraftInterval end if cfg.stockLimits then for item, limit in pairs(cfg.stockLimits) do C.STOCK_LIMITS[item] = limit -- merge / override per-item @@ -149,6 +153,7 @@ local _compostData = dofile(_path("data/compostable.lua")) C.COMPOSTABLE = _compostData.items C.COMPOST_TRASH = _compostData.trash C.STOCK_LIMITS = dofile(_path("data/stock_limits.lua")) +C.AUTO_CRAFT_RULES = dofile(_path("data/auto_craft.lua")) C.LOW_STOCK_ALERTS = dofile(_path("data/alerts.lua")) -- Recipe book: merges built-in recipes + user-learned recipes diff --git a/manager/display.lua b/manager/display.lua index b8599bb..5cf980a 100644 --- a/manager/display.lua +++ b/manager/display.lua @@ -80,6 +80,7 @@ local function getActivityString() if activity.defragging then table.insert(parts, "DEFRAG") end if activity.composting then table.insert(parts, "COMPOST") end if activity.discarding then table.insert(parts, "DISCARD") end + if activity.autocrafting then table.insert(parts, "AUTOCRAFT") end if #parts > 0 then return table.concat(parts, " | ") end @@ -93,6 +94,7 @@ local function getBottomMessage() elseif activity.defragging then return "DEFRAGMENTING..." elseif activity.composting then return "COMPOSTING..." elseif activity.discarding then return "DISCARDING EXCESS..." + elseif activity.autocrafting then return "AUTO-CRAFTING..." end return "Tap item to order" end diff --git a/manager/operations.lua b/manager/operations.lua index ad2949a..cd2bb5f 100644 --- a/manager/operations.lua +++ b/manager/operations.lua @@ -851,6 +851,64 @@ function O.discardExcess() return didWork end +------------------------------------------------- +-- Auto-craft excess stock into target items +------------------------------------------------- + +function O.autoCraft() + if #cfg.AUTO_CRAFT_RULES == 0 then return false end + if not ctx.craftEngine then return false end + if not ctx.craftTurtleName then return false end + + local catalogue = cache.catalogue + local didWork = false + + for _, rule in ipairs(cfg.AUTO_CRAFT_RULES) do + local inputName = rule.input + local reserve = rule.reserve or 0 + local outputName = rule.output + + if catalogue[inputName] then + local totalInStorage = 0 + for _, src in ipairs(catalogue[inputName]) do + totalInStorage = totalInStorage + src.total + end + + local excess = totalInStorage - reserve + if excess > 0 then + -- Figure out how many input items per craft batch + local recipe = cfg.recipeBook.getCraftingRecipe(outputName) + if recipe then + local ingredients = cfg.recipeBook.getIngredients(recipe) + local inputPerCraft = ingredients[inputName] or 0 + if inputPerCraft > 0 then + -- How many batches can we do with the excess? + local batches = math.floor(excess / inputPerCraft) + -- Limit to a reasonable amount per cycle to avoid blocking + batches = math.min(batches, 64) + if batches > 0 then + local craftCount = batches * recipe.count + log.info("AUTOCRAFT", "%s: %d excess (reserve %d), crafting %d x %s", + inputName, excess, reserve, craftCount, outputName) + local ok, err = O.recursiveCraft(outputName, craftCount) + if ok then + didWork = true + log.info("AUTOCRAFT", "Crafted %s x%d", outputName, craftCount) + else + log.warn("AUTOCRAFT", "Failed to craft %s: %s", outputName, tostring(err)) + end + end + end + else + log.warn("AUTOCRAFT", "No recipe found for output: %s", outputName) + end + end + end + end + + return didWork +end + ------------------------------------------------- -- Low-stock alert checker ------------------------------------------------- diff --git a/manager/state.lua b/manager/state.lua index dde53e0..fd1089f 100644 --- a/manager/state.lua +++ b/manager/state.lua @@ -42,6 +42,7 @@ S.activity = { composting = false, crafting = false, discarding = false, + autocrafting = false, } -------------------------------------------------