365 lines
11 KiB
Lua
365 lines
11 KiB
Lua
-- 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,
|
|
}
|
|
|
|
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,
|
|
},
|
|
}
|
|
|
|
-- 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},
|
|
{"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},
|
|
}
|
|
|
|
-- 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,
|
|
},
|
|
}
|
|
|
|
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
|