From efb7b6f6d16eb680986a8abbbe4523b1b1d892b8 Mon Sep 17 00:00:00 2001 From: Emerson Rosen-Jones Date: Fri, 2 Jan 2026 17:37:49 -0500 Subject: [PATCH] feat: create first draft of oregen-manager --- oregen-manager.lua | 222 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 222 insertions(+) create mode 100644 oregen-manager.lua diff --git a/oregen-manager.lua b/oregen-manager.lua new file mode 100644 index 0000000..21fad92 --- /dev/null +++ b/oregen-manager.lua @@ -0,0 +1,222 @@ +-- Manages an oregen facility + +local STOCK_TICKER = "" +local EXPORT_STORAGE = "" + +local CRUSHER_ADDR = "Crusher" +local MELTER_ADDR = "Melter" +local WASHER_ADDR = "Washer" +local PRESS_ADDR = "Press" +local EXPORT_ADDR = "Output" + +-- amount to keep in EXPORT_STORAGE +local KEEP_STOCKED = { + ["minecraft:iron_nugget"] = 4 * 64, +} + +local GLOBAL_LIMS = { + lower = 4 * 64, + upper = 8 * 64, +} + +local LIMIT_EXCEPTIONS = {} + +local CRUSHABLE = { + "create:crimsite", +} +local WASHABLE = { +} +local MELTABLE = { + "create:crushed_raw_iron", +} +local RECIPES = { + ["minecraft:iron_nugget"] = { + {"create:crimsite", 60}, + {"minecraft:gravel", 24}, + }, +} + +local SLEEP_T = 20 + +-- logic: keep a certain amount of certain items in stock in STOCK via +-- RECIPES. while the number is over a certain amount, excess can be used +-- to keep items in stock in EXPORT_STORAGE +-- e.g. lower_lim is 100, upper_lim is 200. export_amt is 100 +-- when below 100, go into recipe mode, producing the item +-- when above 200, go into export mode, sending items to export until there are +-- 100 in EXPORT_STORAGE or until at or below 100 in stock (lower_lim) +-- i.e. mode = match (stock_amt, current_mode) { +-- (x, _), x <= lower_lim = RecipeMode; +-- (x, _), x >= upper_lim = ExportMode; +-- (_, curr) = curr; +-- } +-- in order to push the other products through the system, they will be checked +-- and sent if enough of them accrue + +function createModes (items) + local result = {} + for item, _ in pairs(items) do + result[item] = {"export", 0} + end + return result +end + +function updateModes (current_modes) + 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 in pairs(ticker.stock()) do + if limits[item.name] ~= nil then + if item.count <= limits[item.name].lower then + current_modes[item.name] = {"recipe"} + elseif item.count >= limits[item.name].upper then + current_modes[item.name] = { + "export", + item.count - limits[item.name].lower, + } + end + end + end +end + +function cycleItems (ticker) + local crush, wash, melt + crush = function (item, amt) + local limit = 64 + if item.count < limit then return end + local request = { + name = item, + _requestCount = limit + } + ticker.requestFiltered(CRUSHER_ADDR, request) + os.sleep(1) + return crush(item, amt - limit) + end + wash = function (item, amt) + local limit = 64 + if item.count < limit then return end + local request = { + name = item, + _requestCount = limit + } + ticker.requestFiltered(WASHER_ADDR, request) + os.sleep(1) + return wash(item, amt - limit) + end + melt = function (item, amt) + local limit = 9 + if item.count < limit then return end + local request = { + name = item, + _requestCount = limit + } + ticker.requestFiltered(MELTER_ADDR, request) + os.sleep(1) + return melt(item, amt - limit) + end + for _, item in pairs(ticker.stock()) do + if CRUSHABLE[item.name] ~= nil then + crush(item.name, item.count) + end + if WASHABLE[item.name] ~= nil then + wash(item.name, item.count) + end + if MELTABLE[item.name] ~= nil then + melt(item.name, item.count) + 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 (recipe, current_stock) + local result = nil + local item, count + for _, ingredient in ipairs(recipe) 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 + return result +end + +function craftRecipe (ticker, recipe, count) + if count == nil then count = 1 end + local createRequest + createRequest = function (recipe) + local ingredient = table.remove(recipe) + if ingredient == nil then return end + local item = { + name = ingredient[1], + _requestCount = ingredient[2], + } + return item, createRequest(recipe) + end + while count > 0 do + ticker.requestFiltered(PRESS_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) + cycleItems(ticker) + updateModes(current_modes) + local export_amounts = getAmounts(export_storage.list) + local stock_amounts = getAmounts(ticker.stock) + 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] + local count = getNumCraftable(recipe, stock_amounts) + craftRecipe(ticker, recipe, count) + elseif mode[1] == "export" then + local amt_needed = export_amounts[item] + local amt = math.min(amt_needed, mode[2]) + export(ticker, item, amt) + end + end + 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) +end