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",
|
"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,
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user