222 lines
6.3 KiB
Lua
222 lines
6.3 KiB
Lua
-- 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
|