Previous: if a KEEP_STOCKED material was between lower and upper, it would sit there on startup, regardless of whether material was needed in export. New logic is that materials between the lower and upper bound will try to export until the lower bound is reached on startup.
359 lines
10 KiB
Lua
359 lines
10 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"
|
|
|
|
-- 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:lithium_nugget"] = 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,
|
|
},
|
|
["tfmg:lithium_nugget"] = {
|
|
lower = -1,
|
|
upper = 0,
|
|
},
|
|
["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},
|
|
}
|
|
|
|
-- 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
|