cc-stuff/oregen-manager.lua
2026-01-02 23:14:51 -05:00

235 lines
6.5 KiB
Lua

-- Manages an oregen facility
local STOCK_TICKER = ""
local EXPORT_STORAGE = ""
local SPEEDOMETER = ""
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,
["minecraft:gold_nugget"] = 4 * 64,
["create:zinc_nugget"] = 4 * 64,
["create:copper_nugget"] = 4 * 64,
}
local GLOBAL_LIMS = {
lower = 4 * 64,
upper = 8 * 64,
}
local LIMIT_EXCEPTIONS = {}
local CRUSHABLE = {
"create:crimsite",
"create:asurine",
"create:veridium",
"create:ochrum",
}
local WASHABLE = {
}
local MELTABLE = {
"create:crushed_raw_iron",
"create:crushed_raw_zinc",
"create:crushed_raw_gold",
"create:crushed_raw_copper",
}
local RECIPES = {
["minecraft:iron_nugget"] = {
{"minecraft:iron_nugget", 60},
{"minecraft:gravel", 24},
},
["minecraft:gold_nugget"] = {
{"minecraft:gold_nugget", 64},
{"minecraft:gravel", 64},
},
["create:zinc_nugget"] = {
{"create:zinc_nugget", 64},
{"minecraft:gravel", 32},
},
["create:copper_nugget"] = {
{"create:copper_nugget", 63},
{"minecraft:gravel", 18},
},
}
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 (ticker, 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)
if SPEEDOMETER ~= "" and peripheral.call(SPEEDOMETER, "getSpeed") == 0 then
os.sleep(SLEEP_T)
return run (ticker, export_storage, current_modes)
end
cycleItems(ticker)
updateModes(ticker, 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 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
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