feat: add new crafting recipes for cobblestone and stone variants; enhance auto-crafting logic for excess items
This commit is contained in:
@@ -123,6 +123,114 @@ return {
|
||||
"minecraft:cobblestone", "minecraft:cobblestone", "minecraft:cobblestone",
|
||||
},
|
||||
},
|
||||
{
|
||||
output = "minecraft:cobblestone_slab",
|
||||
count = 6,
|
||||
grid = {
|
||||
"minecraft:cobblestone", "minecraft:cobblestone", "minecraft:cobblestone",
|
||||
nil, nil, nil,
|
||||
nil, nil, nil,
|
||||
},
|
||||
},
|
||||
{
|
||||
output = "minecraft:cobblestone_stairs",
|
||||
count = 4,
|
||||
grid = {
|
||||
"minecraft:cobblestone", nil, nil,
|
||||
"minecraft:cobblestone", "minecraft:cobblestone", nil,
|
||||
"minecraft:cobblestone", "minecraft:cobblestone", "minecraft:cobblestone",
|
||||
},
|
||||
},
|
||||
{
|
||||
output = "minecraft:cobblestone_wall",
|
||||
count = 6,
|
||||
grid = {
|
||||
"minecraft:cobblestone", "minecraft:cobblestone", "minecraft:cobblestone",
|
||||
"minecraft:cobblestone", "minecraft:cobblestone", "minecraft:cobblestone",
|
||||
nil, nil, nil,
|
||||
},
|
||||
},
|
||||
{
|
||||
output = "minecraft:stone_bricks",
|
||||
count = 4,
|
||||
grid = {
|
||||
"minecraft:stone", "minecraft:stone", nil,
|
||||
"minecraft:stone", "minecraft:stone", nil,
|
||||
nil, nil, nil,
|
||||
},
|
||||
},
|
||||
{
|
||||
output = "minecraft:stone_slab",
|
||||
count = 6,
|
||||
grid = {
|
||||
"minecraft:stone", "minecraft:stone", "minecraft:stone",
|
||||
nil, nil, nil,
|
||||
nil, nil, nil,
|
||||
},
|
||||
},
|
||||
{
|
||||
output = "minecraft:stone_stairs",
|
||||
count = 4,
|
||||
grid = {
|
||||
"minecraft:stone", nil, nil,
|
||||
"minecraft:stone", "minecraft:stone", nil,
|
||||
"minecraft:stone", "minecraft:stone", "minecraft:stone",
|
||||
},
|
||||
},
|
||||
{
|
||||
output = "minecraft:smooth_stone_slab",
|
||||
count = 6,
|
||||
grid = {
|
||||
"minecraft:smooth_stone", "minecraft:smooth_stone", "minecraft:smooth_stone",
|
||||
nil, nil, nil,
|
||||
nil, nil, nil,
|
||||
},
|
||||
},
|
||||
{
|
||||
output = "minecraft:polished_andesite",
|
||||
count = 4,
|
||||
grid = {
|
||||
"minecraft:andesite", "minecraft:andesite", nil,
|
||||
"minecraft:andesite", "minecraft:andesite", nil,
|
||||
nil, nil, nil,
|
||||
},
|
||||
},
|
||||
{
|
||||
output = "minecraft:polished_diorite",
|
||||
count = 4,
|
||||
grid = {
|
||||
"minecraft:diorite", "minecraft:diorite", nil,
|
||||
"minecraft:diorite", "minecraft:diorite", nil,
|
||||
nil, nil, nil,
|
||||
},
|
||||
},
|
||||
{
|
||||
output = "minecraft:polished_granite",
|
||||
count = 4,
|
||||
grid = {
|
||||
"minecraft:granite", "minecraft:granite", nil,
|
||||
"minecraft:granite", "minecraft:granite", nil,
|
||||
nil, nil, nil,
|
||||
},
|
||||
},
|
||||
{
|
||||
output = "minecraft:polished_deepslate",
|
||||
count = 4,
|
||||
grid = {
|
||||
"minecraft:cobbled_deepslate", "minecraft:cobbled_deepslate", nil,
|
||||
"minecraft:cobbled_deepslate", "minecraft:cobbled_deepslate", nil,
|
||||
nil, nil, nil,
|
||||
},
|
||||
},
|
||||
{
|
||||
output = "minecraft:polished_tuff",
|
||||
count = 4,
|
||||
grid = {
|
||||
"minecraft:tuff", "minecraft:tuff", nil,
|
||||
"minecraft:tuff", "minecraft:tuff", nil,
|
||||
nil, nil, nil,
|
||||
},
|
||||
},
|
||||
{
|
||||
output = "minecraft:ladder",
|
||||
count = 3,
|
||||
|
||||
@@ -445,11 +445,9 @@ local function main()
|
||||
|
||||
-- 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)
|
||||
log.info("AUTOCRAFT", "Auto-craft active (%d explicit rule(s), smart=%s)",
|
||||
#cfg.AUTO_CRAFT_RULES, tostring(cfg.AUTO_CRAFT_FROM_EXCESS))
|
||||
while true do
|
||||
if ctx.craftTurtleName then
|
||||
activity.autocrafting = true
|
||||
|
||||
@@ -245,4 +245,22 @@ function recipeBook.count()
|
||||
return cc, sc
|
||||
end
|
||||
|
||||
--- Find all crafting recipes that use a given item as an ingredient.
|
||||
-- @param ingredientName string — the input item to search for
|
||||
-- @return array of recipe tables
|
||||
function recipeBook.findRecipesUsing(ingredientName)
|
||||
local results = {}
|
||||
for _, recipe in pairs(recipes.crafting) do
|
||||
if recipe.grid then
|
||||
for _, item in ipairs(recipe.grid) do
|
||||
if item == ingredientName then
|
||||
table.insert(results, recipe)
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
return results
|
||||
end
|
||||
|
||||
return recipeBook
|
||||
|
||||
@@ -65,7 +65,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
|
||||
C.AUTO_CRAFT_INTERVAL = 10 -- seconds between auto-craft checks
|
||||
C.AUTO_CRAFT_OUTPUT_CAP = 512 -- max items of any output before smart-craft stops crafting it
|
||||
C.AUTO_CRAFT_FROM_EXCESS = true -- auto-discover recipes for over-stocked items
|
||||
|
||||
-- Peripheral
|
||||
C.PERIPHERAL_CACHE_TTL = 5
|
||||
@@ -130,6 +132,8 @@ function C.loadConfig()
|
||||
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.autoCraftOutputCap then C.AUTO_CRAFT_OUTPUT_CAP = cfg.autoCraftOutputCap end
|
||||
if cfg.autoCraftFromExcess ~= nil then C.AUTO_CRAFT_FROM_EXCESS = cfg.autoCraftFromExcess end
|
||||
if cfg.stockLimits then
|
||||
for item, limit in pairs(cfg.stockLimits) do
|
||||
C.STOCK_LIMITS[item] = limit -- merge / override per-item
|
||||
|
||||
@@ -856,13 +856,13 @@ end
|
||||
-------------------------------------------------
|
||||
|
||||
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
|
||||
|
||||
-- Phase 1: Explicit rules from auto_craft.lua
|
||||
for _, rule in ipairs(cfg.AUTO_CRAFT_RULES) do
|
||||
local inputName = rule.input
|
||||
local reserve = rule.reserve or 0
|
||||
@@ -876,15 +876,12 @@ function O.autoCraft()
|
||||
|
||||
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
|
||||
@@ -906,6 +903,75 @@ function O.autoCraft()
|
||||
end
|
||||
end
|
||||
|
||||
-- Phase 2: Smart excess-to-craft — auto-discover recipes for over-stocked items
|
||||
if cfg.AUTO_CRAFT_FROM_EXCESS then
|
||||
-- Track outputs we've already handled via explicit rules to avoid duplicates
|
||||
local handledOutputs = {}
|
||||
for _, rule in ipairs(cfg.AUTO_CRAFT_RULES) do
|
||||
handledOutputs[rule.output] = true
|
||||
end
|
||||
|
||||
for itemName, maxCount in pairs(cfg.STOCK_LIMITS) do
|
||||
if catalogue[itemName] then
|
||||
local totalInStorage = 0
|
||||
for _, src in ipairs(catalogue[itemName]) do
|
||||
totalInStorage = totalInStorage + src.total
|
||||
end
|
||||
|
||||
local excess = totalInStorage - maxCount
|
||||
if excess > 0 then
|
||||
-- Find all crafting recipes that use this item
|
||||
local usingRecipes = cfg.recipeBook.findRecipesUsing(itemName)
|
||||
for _, recipe in ipairs(usingRecipes) do
|
||||
if not handledOutputs[recipe.output] then
|
||||
-- Check how much of the output we already have
|
||||
local outputTotal = O.getItemTotal(recipe.output)
|
||||
if outputTotal < cfg.AUTO_CRAFT_OUTPUT_CAP then
|
||||
local ingredients = cfg.recipeBook.getIngredients(recipe)
|
||||
local inputPerCraft = ingredients[itemName] or 0
|
||||
if inputPerCraft > 0 then
|
||||
-- Only craft up to the output cap
|
||||
local outputRoom = cfg.AUTO_CRAFT_OUTPUT_CAP - outputTotal
|
||||
local maxBatches = math.floor(excess / inputPerCraft)
|
||||
local batchesByRoom = math.ceil(outputRoom / recipe.count)
|
||||
local batches = math.min(maxBatches, batchesByRoom, 64)
|
||||
if batches > 0 then
|
||||
-- Check all other ingredients are available
|
||||
local canCraft = true
|
||||
for ingr, needed in pairs(ingredients) do
|
||||
if ingr ~= itemName then
|
||||
local have = O.getItemTotal(ingr)
|
||||
if have < needed * batches then
|
||||
canCraft = false
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
if canCraft then
|
||||
local craftCount = batches * recipe.count
|
||||
log.info("AUTOCRAFT", "Smart: %s over limit, crafting %d x %s",
|
||||
itemName, craftCount, recipe.output)
|
||||
local ok, err = O.recursiveCraft(recipe.output, craftCount)
|
||||
if ok then
|
||||
didWork = true
|
||||
handledOutputs[recipe.output] = true
|
||||
log.info("AUTOCRAFT", "Smart-crafted %s x%d", recipe.output, craftCount)
|
||||
-- Recalculate excess after crafting
|
||||
break
|
||||
else
|
||||
log.warn("AUTOCRAFT", "Smart craft failed %s: %s", recipe.output, tostring(err))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return didWork
|
||||
end
|
||||
|
||||
|
||||
Reference in New Issue
Block a user