feat: add new crafting recipes for cobblestone and stone variants; enhance auto-crafting logic for excess items

This commit is contained in:
MayaTheShy
2026-03-25 18:11:23 -04:00
parent f327f82677
commit 1606d60a06
5 changed files with 203 additions and 9 deletions

View File

@@ -123,6 +123,114 @@ return {
"minecraft:cobblestone", "minecraft:cobblestone", "minecraft:cobblestone", "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", output = "minecraft:ladder",
count = 3, count = 3,

View File

@@ -445,11 +445,9 @@ local function main()
-- Task 5c: Auto-craft excess items into target products -- Task 5c: Auto-craft excess items into target products
function() function()
if #cfg.AUTO_CRAFT_RULES == 0 then
while true do sleep(3600) end
end
sleep(12) -- let initial scan + discard settle first 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 while true do
if ctx.craftTurtleName then if ctx.craftTurtleName then
activity.autocrafting = true activity.autocrafting = true

View File

@@ -245,4 +245,22 @@ function recipeBook.count()
return cc, sc return cc, sc
end 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 return recipeBook

View File

@@ -65,7 +65,9 @@ C.TRASH_DROPPERS = { -- droppers facing lava/void for destroying
C.DISCARD_INTERVAL = 5 -- seconds between discard checks C.DISCARD_INTERVAL = 5 -- seconds between discard checks
-- Auto-craft (overridable via config file) -- 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 -- Peripheral
C.PERIPHERAL_CACHE_TTL = 5 C.PERIPHERAL_CACHE_TTL = 5
@@ -130,6 +132,8 @@ function C.loadConfig()
if cfg.trashDroppers then C.TRASH_DROPPERS = cfg.trashDroppers end if cfg.trashDroppers then C.TRASH_DROPPERS = cfg.trashDroppers end
if cfg.discardInterval then C.DISCARD_INTERVAL = cfg.discardInterval end if cfg.discardInterval then C.DISCARD_INTERVAL = cfg.discardInterval end
if cfg.autoCraftInterval then C.AUTO_CRAFT_INTERVAL = cfg.autoCraftInterval 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 if cfg.stockLimits then
for item, limit in pairs(cfg.stockLimits) do for item, limit in pairs(cfg.stockLimits) do
C.STOCK_LIMITS[item] = limit -- merge / override per-item C.STOCK_LIMITS[item] = limit -- merge / override per-item

View File

@@ -856,13 +856,13 @@ end
------------------------------------------------- -------------------------------------------------
function O.autoCraft() function O.autoCraft()
if #cfg.AUTO_CRAFT_RULES == 0 then return false end
if not ctx.craftEngine then return false end if not ctx.craftEngine then return false end
if not ctx.craftTurtleName then return false end if not ctx.craftTurtleName then return false end
local catalogue = cache.catalogue local catalogue = cache.catalogue
local didWork = false local didWork = false
-- Phase 1: Explicit rules from auto_craft.lua
for _, rule in ipairs(cfg.AUTO_CRAFT_RULES) do for _, rule in ipairs(cfg.AUTO_CRAFT_RULES) do
local inputName = rule.input local inputName = rule.input
local reserve = rule.reserve or 0 local reserve = rule.reserve or 0
@@ -876,15 +876,12 @@ function O.autoCraft()
local excess = totalInStorage - reserve local excess = totalInStorage - reserve
if excess > 0 then if excess > 0 then
-- Figure out how many input items per craft batch
local recipe = cfg.recipeBook.getCraftingRecipe(outputName) local recipe = cfg.recipeBook.getCraftingRecipe(outputName)
if recipe then if recipe then
local ingredients = cfg.recipeBook.getIngredients(recipe) local ingredients = cfg.recipeBook.getIngredients(recipe)
local inputPerCraft = ingredients[inputName] or 0 local inputPerCraft = ingredients[inputName] or 0
if inputPerCraft > 0 then if inputPerCraft > 0 then
-- How many batches can we do with the excess?
local batches = math.floor(excess / inputPerCraft) local batches = math.floor(excess / inputPerCraft)
-- Limit to a reasonable amount per cycle to avoid blocking
batches = math.min(batches, 64) batches = math.min(batches, 64)
if batches > 0 then if batches > 0 then
local craftCount = batches * recipe.count local craftCount = batches * recipe.count
@@ -906,6 +903,75 @@ function O.autoCraft()
end end
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 return didWork
end end