Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- network = peripheral.find("rsBridge")
- monitor = peripheral.find("monitor")
- function getIngredients(targetItem)
- local cache = {}
- function loadItemData(item, fallback, isFalseCall)
- if cache[item] == nil then
- cache[item] = {}
- local storageCount = 0
- local storage = network.getItem({
- name = item
- })
- local recipe = network.getPattern({
- name = item
- })
- cache[item]["recipe"] = recipe
- cache[item]["displayName"] = storage.displayName:match("^%s*%[?(.-)%]?%s*$")
- if cache[item]["displayName"] == "Air" and fallback ~= nil then
- cache[item]["displayName"] = fallback.displayName:match("^%s*%[?(.-)%]?%s*$")
- end
- -- monkey-patching a bug in rsBridge
- if storage ~= nil and storage.amount ~= 0 then
- storageCount = storage.amount
- if storageCount == getCraftingMultiplier(item) and recipe ~= nil then
- storageCount = 0
- end
- end
- cache[item].isFalseCall = (isFalseCall == true)
- cache[item]["inStorage"] = storageCount
- cache[item]["available"] = storageCount
- cache[item]["needed"] = 0
- end
- if isFalseCall ~= true then
- cache[item].isFalseCall = false
- end
- return cache[item]
- end
- function getCraftingMultiplier(item)
- local itemData = loadItemData(item)
- if itemData.recipe == nil then
- return 0
- end
- for _, result in pairs(itemData.recipe.outputs) do
- if result.name == item then
- return result.amount
- end
- end
- return 0
- end
- function determineBestIngredient(ingredients)
- if table.getn(ingredients) <= 1 then
- return ingredients[1]
- end
- for i, ingredient in pairs(ingredients) do
- if cache[ingredient.name] ~= nil and not cache[ingredient.name].isFalseCall then
- return ingredient
- end
- end
- for i, ingredient in pairs(ingredients) do
- local ingredientData = loadItemData(ingredient.name, ingredient, true)
- if ingredientData.recipe ~= nil then
- cache[ingredient.name].isFalseCall = false
- return ingredient
- end
- end
- local maxCount = 0
- local maxIngredient = nil
- for i, ingredient in pairs(ingredients) do
- local ingredientData = loadItemData(ingredient.name, ingredient, true)
- if ingredientData.inStorage > maxCount then
- maxCount = ingredientData.inStorage
- maxIngredient = ingredient
- end
- end
- if maxCount > 0 then
- cache[maxIngredient.name].isFalseCall = false
- return maxIngredient
- end
- return ingredients[1]
- end
- function simplifyRecipeIngredients(recipe)
- local ingredients = {}
- for _, input in pairs(recipe.inputs) do
- input = determineBestIngredient(input)
- if input ~= nil and input.amount ~= nil and input.name ~= "minecraft:air" then
- if ingredients[input.name] == nil then
- ingredients[input.name] = {
- count = 0,
- fallback = input
- }
- end
- ingredients[input.name].count = ingredients[input.name].count + input.amount
- end
- end
- return ingredients
- end
- function mark(item, amount, fallback)
- local itemData = loadItemData(item, fallback)
- itemData.available = itemData.available - amount
- itemData.needed = itemData.needed + amount
- if itemData.available < 0 then
- local multiplier = getCraftingMultiplier(item)
- if multiplier == 0 then
- return
- end
- local craftingCount = math.ceil(-itemData.available / multiplier)
- for input, inputData in pairs(simplifyRecipeIngredients(itemData.recipe)) do
- mark(input, inputData.count * craftingCount, inputData.fallback)
- end
- end
- end
- mark(targetItem, 1)
- local result = {}
- for item, itemData in pairs(cache) do
- if not itemData.isFalseCall and itemData.recipe == nil and itemData.inStorage < itemData.needed then
- table.insert(result, {
- inStorage = itemData.inStorage,
- needed = itemData.needed,
- displayName = itemData.displayName
- })
- end
- end
- function compare(a, b)
- return (a.inStorage + 1) / (a.needed + 1) < (b.inStorage + 1) / (b.needed + 1)
- end
- table.sort(result, compare)
- return result
- end
- function formatNumber(number)
- if number <= 1 then
- return number .. ""
- end
- local roundingSize = math.pow(10, math.ceil(math.log10(number + 1)) - 3)
- number = math.ceil(number / roundingSize) * roundingSize
- if number >= 1000000 then
- return (number / 1000000) .. "m"
- elseif number >= 1000 then
- return (number / 1000) .. "k"
- end
- return number .. ""
- end
- function displayIngredients(ingredients)
- monitor.clear()
- monitor.setCursorPos(1, 1)
- for _, itemData in pairs(ingredients) do
- monitor.setTextColor(colors.orange)
- monitor.write(itemData.displayName .. ": ")
- monitor.setTextColor(colors.lightBlue)
- monitor.write(formatNumber(itemData.inStorage))
- monitor.setTextColor(colors.blue)
- monitor.write("/" .. formatNumber(itemData.needed))
- _, cursorPos = monitor.getCursorPos()
- monitor.setCursorPos(1, cursorPos + 1)
- end
- end
- function startClock()
- while (true) do
- print("Starting calculation")
- ingredients = getIngredients('allthetweaks:atm_star')
- print("Finished calculation")
- displayIngredients(ingredients)
- sleep(60)
- end
- end
- startClock()
Advertisement