From a88b85336248b1dc9a2bbae10457b19914f342dc Mon Sep 17 00:00:00 2001 From: GHXX Date: Sun, 20 Sep 2026 21:29:11 +0200 Subject: [PATCH] add two more autocrafting scripts --- fuelAutocraft.lua | 88 ++++++++++++++++++++++++ genericAutocraft.lua | 156 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 244 insertions(+) create mode 100644 fuelAutocraft.lua create mode 100644 genericAutocraft.lua diff --git a/fuelAutocraft.lua b/fuelAutocraft.lua new file mode 100644 index 0000000..45abbcb --- /dev/null +++ b/fuelAutocraft.lua @@ -0,0 +1,88 @@ +print("Reactor fuel autocrafter :D") + +local function agc(name) + return assert(components:getFirst(name), "failed to get component "..name) +end + +local computer = agc("computer") +local fs = require("filesystem") +local kernel = require("kernel") +local crafter = agc("digitalCrafter") +local interface = agc("adapter") + +-- to be prefixed with nuclearcraft:fuel_ +local possibleFuelsRaw = --"leu-235,len-236,hen-236,hecf-249,hecm-245,mix-241,mix-239,lep-241,hep-241,heu-233,lecm-245,leu-233,lecf-249,hecm-243,lep-239,hep-239,lecm-243,heu-235,lea-242,tbu,hea_242,lecf_251,heb_248,leb_248" +([[ +uranium_leu_235,neptunium_len_236,neptunium_hen_236,californium_hecf_249,curium_hecm_245,mixed_mix_241, +mixed_mix_239,plutonium_lep_241,plutonium_hep_241,uranium_heu_233,curium_lecm_245,uranium_leu_233,californium_lecf_249,curium_hecm_243,plutonium_lep_239, +plutonium_hep_239,curium_lecm_243,uranium_heu_235,americium_lea_242,thorium_tbu,americium_hea_242,californium_lecf_251,berkelium_heb_248, +berkelium_leb_248,curium_hecm_247,californium_hecf_251,curium_lecm_247 +]]):gsub("[^,%w_]","") + +local possibleFuels = {} +for match in possibleFuelsRaw:gmatch("[^,]+") do + table.insert(possibleFuels, "nuclearcraft:fuel_"..match) +end + +print("Possible fuels: ", table.concat(possibleFuels, ";")) + + +local function pp(tbl) + for k,v in pairs(tbl) do print(k, tostring(v)) end +end + +local function safeCraft(...) + while true do + local cooldown = crafter.cooldownRemaining + if cooldown <= 0 then break end + sleep(cooldown) + end + return crafter:craft(...) +end + +local skipSleep = true +while true do + if not skipSleep then print("nothing to craft, waiting 30 seconds"); sleep(30) end + + print("New iteration started.") + for _, fuelToCraft in ipairs(possibleFuels) do + local recipesForFuel = crafter:searchRecipesWithResult(fuelToCraft) + assert(#recipesForFuel == 1, "somehow there was not exactly one recipe for "..tostring(fuelToCraft)) + local recipe = recipesForFuel[1] + local ingredientsStacked = {} + local stockOfIngredient = {} + for i = 1, 9 do + local currIngredient = recipe.ingredients[i][1] + assert(currIngredient, "somehow this is a recipe that has an empty slot :C for "..tostring(fuelToCraft)) + recipe.ingredients[i] = currIngredient + ingredientsStacked[currIngredient] = (ingredientsStacked[currIngredient] or 0) + 1 + + if stockOfIngredient[currIngredient] == nil then + stockOfIngredient[currIngredient] = interface:getCount(currIngredient) + end + end + + local maxStackSize = 64 -- fuels always stack 64, same for ingredients, so in principle we could craft 64 fuel at once + local recipeCraftCount = 64 -- how many recipes to craft + for ingredient, count in pairs(ingredientsStacked) do + local maxCraftForCurrIngredient = math.floor(stockOfIngredient[ingredient]/count) -- how often we could craft with this current ingredient + recipeCraftCount = math.min(recipeCraftCount, maxCraftForCurrIngredient) + end + recipeCraftCount = math.min(recipeCraftCount, math.floor(maxStackSize/recipe.resultCount)) + + if recipeCraftCount == 0 then + print(("We dont have enough to craft %s."):format(fuelToCraft)) + else + print(("Time to craft %dx %s."):format(recipeCraftCount, fuelToCraft)) + for itemName, count in pairs(ingredientsStacked) do + local remainingCount = recipeCraftCount * count + while remainingCount > 0 do + local extracted = interface:extract(itemName, 1, remainingCount) + assert(extracted > 0) + remainingCount = remainingCount - extracted + end + end + safeCraft(recipe.ingredients, recipe.result, recipeCraftCount, false) + end + end +end diff --git a/genericAutocraft.lua b/genericAutocraft.lua new file mode 100644 index 0000000..a5be934 --- /dev/null +++ b/genericAutocraft.lua @@ -0,0 +1,156 @@ +print("AC autocrafter :D") + +local function agc(name) + return assert(components:getFirst(name), "failed to get component "..name) +end + +local computer = agc("computer") +local fs = require("filesystem") +local kernel = require("kernel") +local crafter = agc("digitalCrafter") +local interface = agc("adapter") + +local recipesToAutocraft = {} +local function addRecipeDirect(recipe) + assert(type(recipe) == "table", "recipe was not table but "..type(recipe)) + assert(recipe.ingredients, "key ingredients was not contained in recipe") + assert(recipe.result, "key result was not contained in recipe") + assert(recipe.resultCount, "key resultCount was not contained in recipe") + table.insert(recipesToAutocraft, recipe) +end + +local function addSingleRecipeOfItem(name) -- ensures that there is exactly one recipe to use + local recipesForItem = crafter:searchRecipesWithResult(name) + assert(#recipesForItem == 1, "somehow there was not exactly one recipe for "..tostring(name)) + local recipe = recipesForItem[1] + addRecipeDirect(recipe) +end + + +local function addSingleRecipeForAllCsv(csv, prefixOrNil) + for match in csv:gsub("%s",""):gmatch("[^,]+") do + addSingleRecipeOfItem((prefixOrNil or "")..match) + end +end + +local function addSingleRecipeThatUsesItem(itemToConsume) + local recipesForItem = crafter:searchRecipesWithIngredient(itemToConsume) + assert(#recipesForItem == 1, "somehow there was not exactly one recipe that uses "..tostring(itemToConsume)) + local recipe = recipesForItem[1] + addRecipeDirect(recipe) +end +addSingleRecipeThatUsesItem("mysticalagriculture:sulfur_essence") +addSingleRecipeThatUsesItem("mysticalagriculture:draconium_essence") + +-- to be prefixed with nuclearcraft:fuel_ +local possibleFuelsRaw = --"leu-235,len-236,hen-236,hecf-249,hecm-245,mix-241,mix-239,lep-241,hep-241,heu-233,lecm-245,leu-233,lecf-249,hecm-243,lep-239,hep-239,lecm-243,heu-235,lea-242,tbu,hea_242,lecf_251,heb_248,leb_248" +([[ +uranium_leu_235,neptunium_len_236,neptunium_hen_236,californium_hecf_249,curium_hecm_245,mixed_mix_241, +mixed_mix_239,plutonium_lep_241,plutonium_hep_241,uranium_heu_233,curium_lecm_245,uranium_leu_233,californium_lecf_249,curium_hecm_243,plutonium_lep_239, +plutonium_hep_239,curium_lecm_243,uranium_heu_235,americium_lea_242,thorium_tbu,americium_hea_242,californium_lecf_251,berkelium_heb_248, +berkelium_leb_248,curium_hecm_247,californium_hecf_251,curium_lecm_247 +]]) + +addSingleRecipeForAllCsv(possibleFuelsRaw, "nuclearcraft:fuel_") + +addSingleRecipeForAllCsv([[osmium,uranium]], "mekanism:block_raw_") +addSingleRecipeForAllCsv([[iron_block,copper_block,gold_block]], "minecraft:raw_") +addSingleRecipeForAllCsv([[zinc_block]], "create:raw_") +addSingleRecipeForAllCsv([[aluminum_block,platinum_block,iridium_block]], "alltheores:raw_") +addSingleRecipeForAllCsv([[tin_block,lead_block,silver_block,nickel_block]], "thermal:raw_") + +print(("%s Recipes loaded."):format(#recipesToAutocraft)) + +local function safeCraft(...) + while true do + local cooldown = crafter.cooldownRemaining + if cooldown <= 0 then break end + sleep(cooldown) + end + return crafter:craft(...) +end + +-- try to craft the given recipe as often as possible; greedy not optimal. Might need to be called multiple times in order to consume all valid items in case there are multiple options +local function tryCraftRecipeAsOftenAsPossible(recipe) + local ingredientsStacked = {} -- itemName: count_needed_per_craft + local stockOfIngredientForCraftCountSelection = {} -- itemName: count_in_me_system + local stockOfIngredientForItemSelection = {} + local resultItemName = recipe.result + local actualIngredients = {} + + -- pick concrete items that we have in stock for this recipe + for i = 1, 9 do + local currentSlotOptions = recipe.ingredients[i] + if currentSlotOptions == nil then + actualIngredients[i] = nil + else + local anyInStock = false + for _, slotOption in ipairs(currentSlotOptions) do + if stockOfIngredientForItemSelection[slotOption] == nil then + local x = interface:getCount(slotOption) + stockOfIngredientForItemSelection[slotOption] = x + stockOfIngredientForCraftCountSelection[slotOption] = x + end + local selectionCountOfCurrItem = stockOfIngredientForItemSelection[slotOption] + assert(selectionCountOfCurrItem >= 0, "somehow countOfCurrItem was not >= 0?") + if selectionCountOfCurrItem > 0 then -- select this item and reduce the count + stockOfIngredientForItemSelection[slotOption] = selectionCountOfCurrItem - 1 + anyInStock = true + ingredientsStacked[slotOption] = (ingredientsStacked[slotOption] or 0) + 1 + actualIngredients[i] = slotOption + break + end + end + + if not anyInStock then + print(("We dont have enough to craft %s for slot %d."):format(resultItemName, i)) + return false + end + end + end + + -- at this point we found an item for every slot; so figure out how many recipes we can craft + local maxStackSize = 64 -- fuels always stack 64, same for ingredients, so in principle we could craft 64 fuel at once + local recipeCraftCount = 64 -- how many recipes to craft + for ingredient, count in pairs(ingredientsStacked) do + local maxCraftForCurrIngredient = math.floor(stockOfIngredientForCraftCountSelection[ingredient]/count) -- how often we could craft with this current ingredient + recipeCraftCount = math.min(recipeCraftCount, maxCraftForCurrIngredient) + end + recipeCraftCount = math.min(recipeCraftCount, math.floor(maxStackSize/recipe.resultCount)) + + if recipeCraftCount == 0 then + error(("We somehow dont have enough to craft %s. Is our math wrong?"):format(resultItemName)) + else + print(("Time to craft %dx %s."):format(recipeCraftCount, resultItemName)) + --crafter:dumpInventoryUp() + for itemName, count in pairs(ingredientsStacked) do + local remainingCount = recipeCraftCount * count + while remainingCount > 0 do + local extracted = interface:extract(itemName, 1, remainingCount) + assert(extracted > 0, "somehow we ran out of an item during exporting???") + remainingCount = remainingCount - extracted + end + end + safeCraft(actualIngredients, recipe.result, recipeCraftCount, false) + return true + end +end + +local skipSleep = true +while true do + if not skipSleep then print("nothing to craft, waiting 30 seconds"); sleep(30) end + + print("New iteration started.") + skipSleep = false + for _, recipe in ipairs(recipesToAutocraft) do + local maxCraft = (recipe.result:find("fuel") and 1 or 10) -- craft 10 stacks at once to speed things up, unless this is a fuel recipe + for _ = 1, maxCraft do + local success = tryCraftRecipeAsOftenAsPossible(recipe) + if success then + skipSleep = true + else + break + end + end + end +end