-- Manages an oregen facility local STOCK_TICKER = "" local EXPORT_STORAGE = "" local SPEEDOMETER = "" local CRUSHER_ADDR = "Crusher" local MELTER_ADDR = "Melter" local MIXER_ADDR = "Mixer" local WASHER_ADDR = "Washer" local SMELTER_ADDR = "Smelter" local HAUNTER_ADDR = "Haunter" local PRESS_ADDR = "Press" local EXPORT_ADDR = "Output" -- Packages sent here leave the oregen system and go to main storage. -- Helps keep slots freed up in oregen storage local MAIN_STORAGE_ADDR = "Main Storage" -- amount to keep in EXPORT_STORAGE local KEEP_STOCKED = { ["minecraft:iron_nugget"] = 4 * 64, ["minecraft:gold_nugget"] = 4 * 64, ["create:zinc_nugget"] = 4 * 64, ["create:copper_nugget"] = 4 * 64, ["minecraft:netherrack"] = 4 * 64, ["create:cinder_flour"] = 0, ["minecraft:gravel"] = 0, ["minecraft:netherite_scrap"] = 4, ["minecraft:nether_bricks"] = 0, ["oreganized:silver_nugget"] = 4 * 64, ["tfmg:nickel_nugget"] = 4 * 64, ["tfmg:bauxite_powder"] = 4 * 64, ["minecraft:flint"] = 0, ["minecraft:andesite"] = 4 * 64, ["minecraft:clay_ball"] = 4 * 64, } local GLOBAL_LIMS = { lower = 6 * 64, upper = 10 * 64, } local LIMIT_EXCEPTIONS = { ["create:cinder_flour"] = { lower = 64, upper = 2 * 64, }, ["minecraft:gravel"] = { lower = 10 * 64, upper = 20 * 64, }, ["minecraft:netherite_scrap"] = { lower = 0, upper = 4, }, ["minecraft:flint"] = { lower = 64, upper = 2 * 64, }, ["minecraft:andesite"] = { lower = 0, upper = 2 * 64, }, ["minecraft:clay_ball"] = { lower = 0, upper = 4 * 64, }, } -- if these exist, they will be used up -- "limit" is the limit on the amt sent at a time (default is 64) -- "keep" is the amount not to use up (default is 0) local PRODUCTS = { {"create:crimsite", CRUSHER_ADDR}, {"create:crushed_raw_iron", MELTER_ADDR}, {"create:crushed_raw_zinc", MELTER_ADDR}, {"create:asurine", CRUSHER_ADDR}, {"create:crushed_raw_copper", MELTER_ADDR}, {"create:veridium", CRUSHER_ADDR, limit = 32}, {"create:ochrum", CRUSHER_ADDR}, {"create:crushed_raw_gold", MELTER_ADDR}, {"minecraft:sand", WASHER_ADDR}, {"minecraft:clay_ball", SMELTER_ADDR, keep = 4 * 64}, {"minecraft:brick", HAUNTER_ADDR}, {"minecraft:flint", CRUSHER_ADDR, keep = 4 * 64}, {"minecraft:nether_bricks", CRUSHER_ADDR}, {"minecraft:basalt", CRUSHER_ADDR}, {"create:crushed_raw_silver", WASHER_ADDR, limit = 16}, {"minecraft:calcite", CRUSHER_ADDR}, {"create:crushed_raw_nickel", WASHER_ADDR, limit = 32}, {"tfmg:bauxite", CRUSHER_ADDR}, {"tfmg:lithium_nugget", MAIN_STORAGE_ADDR}, -- Can reduce these numbers to 12 * 64 in future if it becomes an issue {"minecraft:iron_nugget", MAIN_STORAGE_ADDR, keep = 16 * 64, limit = 4 * 64}, {"minecraft:gold_nugget", MAIN_STORAGE_ADDR, keep = 16 * 64, limit = 4 * 64}, {"create:copper_nugget", MAIN_STORAGE_ADDR, keep = 16 * 64, limit = 4 * 64}, {"create:zinc_nugget", MAIN_STORAGE_ADDR, keep = 16 * 64, limit = 4 * 64}, {"tfmg:nickel_nugget", MAIN_STORAGE_ADDR, keep = 16 * 64, limit = 4 * 64}, {"oreganized:silver_nugget", MAIN_STORAGE_ADDR, keep = 16 * 64, limit = 4 * 64}, {"minecraft:netherrack", MAIN_STORAGE_ADDR, keep = 16 * 64, limit = 4 *64}, } -- these will be crafted when needed local RECIPES = { ["minecraft:gravel"] = { ingredients = { {"minecraft:cobblestone", 2 * 64}, }, addr = CRUSHER_ADDR, limit = 6, }, ["minecraft:iron_nugget"] = { ingredients = { {"minecraft:iron_nugget", 60}, {"minecraft:gravel", 24}, }, addr = PRESS_ADDR, }, ["minecraft:gold_nugget"] = { ingredients = { {"minecraft:gold_nugget", 64}, {"minecraft:gravel", 64}, }, addr = PRESS_ADDR, }, ["create:zinc_nugget"] = { ingredients = { {"create:zinc_nugget", 64}, {"minecraft:gravel", 32}, }, addr = PRESS_ADDR, }, ["create:copper_nugget"] = { ingredients = { {"create:copper_nugget", 63}, {"minecraft:gravel", 18}, }, addr = PRESS_ADDR, }, ["minecraft:netherrack"] = { ingredients = { {"create:cinder_flour", 64}, {"minecraft:cobblestone", 64}, }, addr = MIXER_ADDR, }, ["create:cinder_flour"] = { ingredients = { {"minecraft:netherrack", 64} }, addr = CRUSHER_ADDR, }, ["minecraft:netherite_scrap"] = { ingredients = { {"minecraft:gravel", 2 * 64}, }, addr = CRUSHER_ADDR, limit = 6, }, ["minecraft:nether_bricks"] = { ingredients = { {"minecraft:nether_brick", 64}, }, addr = PRESS_ADDR, }, ["oreganized:silver_nugget"] = { ingredients = { {"oreganized:silver_nugget", 60}, {"minecraft:gravel", 24}, }, addr = PRESS_ADDR, }, ["tfmg:nickel_nugget"] = { ingredients = { {"tfmg:nickel_nugget", 64}, {"minecraft:gravel", 64}, }, addr = PRESS_ADDR, }, ["tfmg:bauxite_powder"] = { ingredients = { {"tfmg:bauxite_powder", 64}, {"minecraft:gravel", 64}, }, addr = PRESS_ADDR, limit = 6, }, ["minecraft:flint"] = { ingredients = { {"minecraft:gravel", 64}, }, addr = WASHER_ADDR, limit = 8, }, ["minecraft:andesite"] = { ingredients = { {"minecraft:flint", 64}, {"minecraft:gravel", 32}, }, addr = PRESS_ADDR, limit = 6, }, ["minecraft:clay_ball"] = { ingredients = { {"minecraft:gravel", 2 * 64}, }, addr = CRUSHER_ADDR, limit = 6, }, } local SLEEP_T = 20 function createModes (items) local result = {} for item, _ in pairs(items) do result[item] = {"export", 0} end return result end function updateModes (current_modes, current_stock, first_run) local lower_lim, upper_lim local limits = {} for item, _ in pairs(current_modes) do if LIMIT_EXCEPTIONS[item] ~= nil then lower_lim = LIMIT_EXCEPTIONS[item].lower upper_lim = LIMIT_EXCEPTIONS[item].upper else lower_lim = GLOBAL_LIMS.lower upper_lim = GLOBAL_LIMS.upper end limits[item] = { lower = lower_lim, upper = upper_lim, } end for item, limits in pairs(limits) do local count = current_stock[item] if count == nil then count = 0 end if count <= limits.lower then current_modes[item] = {"recipe"} elseif count >= limits.upper or first_run then current_modes[item] = { "export", count - limits.lower, } end end end function cycleItems (ticker, items) local makeRequest makeRequest = function (item, amt, addr, limit_override) local limit = 64 if addr == MELTER_ADDR then limit = 9 end if limit_override ~= nil then limit = limit_override end if amt < limit then return end local request = { name = item, _requestCount = limit } ticker.requestFiltered(addr, request) os.sleep(1) return makeRequest(item, amt - limit, addr, limit_override) end for _, pair in pairs(PRODUCTS) do local name, addr, limit, keep = pair[1], pair[2], pair.limit, pair.keep if items[name] ~= nil then local amt = items[name] if keep ~= nil then amt = amt - keep end if amt < 0 then amt = 0 end makeRequest(name, amt, addr, limit) end end end function getAmounts (storage_f) local result = {} for _, item in pairs(storage_f()) do if result[item.name] == nil then result[item.name] = 0 end result[item.name] = result[item.name] + item.count end return result end function getNumCraftable (ingredients, current_stock) local result = nil local item, count for _, ingredient in ipairs(ingredients) do item, count = ingredient[1], ingredient[2] if current_stock[item] == nil then return 0 end local num = math.floor(current_stock[item] / count) if result == nil then result = num else result = math.min(result, num) end end if result == nil then result = 0 end return result end function adjustStock (current_stock, ingredients, count) if count == 0 then return end local item, i_count for _, ingredient in ipairs(ingredients) do item, i_count = ingredient[1], ingredient[2] current_stock[item] = current_stock[item] - (i_count * count) end end function craftRecipe (ticker, recipe, current_stock) local count = getNumCraftable(recipe.ingredients, current_stock) if recipe.limit ~= nil then count = math.min(count, recipe.limit) end adjustStock(current_stock, recipe.ingredients, count) local createRequest createRequest = function (recipe, i) if i == nil then i = 1 end local ingredient = recipe.ingredients[i] if ingredient == nil then return end local item = { name = ingredient[1], _requestCount = ingredient[2], } return item, createRequest(recipe, i + 1) end while count > 0 do ticker.requestFiltered(recipe.addr, createRequest(recipe)) os.sleep(1) count = count - 1 end end function export (ticker, item, amt) if amt <= 0 then return end local request = { name = item, _requestCount = amt } ticker.requestFiltered(EXPORT_ADDR, request) end function run (ticker, export_storage, current_modes, first_run) if SPEEDOMETER ~= "" and peripheral.call(SPEEDOMETER, "getSpeed") == 0 then os.sleep(SLEEP_T) return run (ticker, export_storage, current_modes, first_run) end local export_amounts = getAmounts(export_storage.list) local stock_amounts = getAmounts(ticker.stock) updateModes(current_modes, stock_amounts, first_run) for item, mode in pairs(current_modes) do -- mode[1] is mode, mode[2] is amt_extra when exporting if mode[1] == "recipe" then -- make as many recipes as you can with current stock local recipe = RECIPES[item] craftRecipe(ticker, recipe, stock_amounts) elseif mode[1] == "export" then local export_amt = export_amounts[item] if export_amt == nil then export_amt = 0 end local amt_needed = KEEP_STOCKED[item] - export_amt local amt = math.min(amt_needed, mode[2]) export(ticker, item, amt) end end cycleItems(ticker, stock_amounts) os.sleep(SLEEP_T) return run (ticker, export_storage, current_modes) end if arg ~= nil and arg[1] == "run" then local ticker = peripheral.wrap(STOCK_TICKER) local export_storage = peripheral.wrap(EXPORT_STORAGE) local current_modes = createModes(KEEP_STOCKED) run(ticker, export_storage, current_modes, true) end