add two more autocrafting scripts
This commit is contained in:
@@ -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
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user