Filmos

Lua Cuntdown

Sep 2nd, 2023 (edited)
1,162
0
Never
1
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 6.15 KB | None | 0 0
  1. network = peripheral.find("rsBridge")
  2. monitor = peripheral.find("monitor")
  3.  
  4. function getIngredients(targetItem)
  5.     local cache = {}
  6.     function loadItemData(item, fallback, isFalseCall)
  7.         if cache[item] == nil then
  8.             cache[item] = {}
  9.  
  10.             local storageCount = 0
  11.             local storage = network.getItem({
  12.                 name = item
  13.             })
  14.             local recipe = network.getPattern({
  15.                 name = item
  16.             })
  17.  
  18.             cache[item]["recipe"] = recipe
  19.             cache[item]["displayName"] = storage.displayName:match("^%s*%[?(.-)%]?%s*$")
  20.             if cache[item]["displayName"] == "Air" and fallback ~= nil then
  21.                 cache[item]["displayName"] = fallback.displayName:match("^%s*%[?(.-)%]?%s*$")
  22.             end
  23.  
  24.             -- monkey-patching a bug in rsBridge
  25.             if storage ~= nil and storage.amount ~= 0 then
  26.                 storageCount = storage.amount
  27.                 if storageCount == getCraftingMultiplier(item) and recipe ~= nil then
  28.                     storageCount = 0
  29.                 end
  30.             end
  31.  
  32.             cache[item].isFalseCall = (isFalseCall == true)
  33.             cache[item]["inStorage"] = storageCount
  34.             cache[item]["available"] = storageCount
  35.             cache[item]["needed"] = 0
  36.         end
  37.  
  38.         if isFalseCall ~= true then
  39.             cache[item].isFalseCall = false
  40.         end
  41.         return cache[item]
  42.     end
  43.  
  44.     function getCraftingMultiplier(item)
  45.         local itemData = loadItemData(item)
  46.         if itemData.recipe == nil then
  47.             return 0
  48.         end
  49.         for _, result in pairs(itemData.recipe.outputs) do
  50.             if result.name == item then
  51.                 return result.amount
  52.             end
  53.         end
  54.         return 0
  55.     end
  56.  
  57.     function determineBestIngredient(ingredients)
  58.         if table.getn(ingredients) <= 1 then
  59.             return ingredients[1]
  60.         end
  61.  
  62.         for i, ingredient in pairs(ingredients) do
  63.             if cache[ingredient.name] ~= nil and not cache[ingredient.name].isFalseCall then
  64.                 return ingredient
  65.             end
  66.         end
  67.  
  68.         for i, ingredient in pairs(ingredients) do
  69.             local ingredientData = loadItemData(ingredient.name, ingredient, true)
  70.             if ingredientData.recipe ~= nil then
  71.                 cache[ingredient.name].isFalseCall = false
  72.                 return ingredient
  73.             end
  74.         end
  75.  
  76.         local maxCount = 0
  77.         local maxIngredient = nil
  78.         for i, ingredient in pairs(ingredients) do
  79.             local ingredientData = loadItemData(ingredient.name, ingredient, true)
  80.             if ingredientData.inStorage > maxCount then
  81.                 maxCount = ingredientData.inStorage
  82.                 maxIngredient = ingredient
  83.             end
  84.         end
  85.         if maxCount > 0 then
  86.             cache[maxIngredient.name].isFalseCall = false
  87.             return maxIngredient
  88.         end
  89.  
  90.         return ingredients[1]
  91.     end
  92.  
  93.     function simplifyRecipeIngredients(recipe)
  94.         local ingredients = {}
  95.         for _, input in pairs(recipe.inputs) do
  96.             input = determineBestIngredient(input)
  97.             if input ~= nil and input.amount ~= nil and input.name ~= "minecraft:air" then
  98.                 if ingredients[input.name] == nil then
  99.                     ingredients[input.name] = {
  100.                         count = 0,
  101.                         fallback = input
  102.                     }
  103.                 end
  104.                 ingredients[input.name].count = ingredients[input.name].count + input.amount
  105.             end
  106.         end
  107.         return ingredients
  108.     end
  109.  
  110.     function mark(item, amount, fallback)
  111.         local itemData = loadItemData(item, fallback)
  112.         itemData.available = itemData.available - amount
  113.         itemData.needed = itemData.needed + amount
  114.  
  115.         if itemData.available < 0 then
  116.             local multiplier = getCraftingMultiplier(item)
  117.             if multiplier == 0 then
  118.                 return
  119.             end
  120.  
  121.             local craftingCount = math.ceil(-itemData.available / multiplier)
  122.  
  123.             for input, inputData in pairs(simplifyRecipeIngredients(itemData.recipe)) do
  124.                 mark(input, inputData.count * craftingCount, inputData.fallback)
  125.             end
  126.         end
  127.     end
  128.  
  129.     mark(targetItem, 1)
  130.     local result = {}
  131.     for item, itemData in pairs(cache) do
  132.         if not itemData.isFalseCall and itemData.recipe == nil and itemData.inStorage < itemData.needed then
  133.             table.insert(result, {
  134.                 inStorage = itemData.inStorage,
  135.                 needed = itemData.needed,
  136.                 displayName = itemData.displayName
  137.             })
  138.         end
  139.     end
  140.     function compare(a, b)
  141.         return (a.inStorage + 1) / (a.needed + 1) < (b.inStorage + 1) / (b.needed + 1)
  142.     end
  143.     table.sort(result, compare)
  144.     return result
  145. end
  146.  
  147. function formatNumber(number)
  148.     if number <= 1 then
  149.         return number .. ""
  150.     end
  151.  
  152.     local roundingSize = math.pow(10, math.ceil(math.log10(number + 1)) - 3)
  153.     number = math.ceil(number / roundingSize) * roundingSize
  154.  
  155.     if number >= 1000000 then
  156.         return (number / 1000000) .. "m"
  157.     elseif number >= 1000 then
  158.         return (number / 1000) .. "k"
  159.     end
  160.  
  161.     return number .. ""
  162. end
  163.  
  164. function displayIngredients(ingredients)
  165.     monitor.clear()
  166.     monitor.setCursorPos(1, 1)
  167.     for _, itemData in pairs(ingredients) do
  168.         monitor.setTextColor(colors.orange)
  169.         monitor.write(itemData.displayName .. ": ")
  170.         monitor.setTextColor(colors.lightBlue)
  171.         monitor.write(formatNumber(itemData.inStorage))
  172.         monitor.setTextColor(colors.blue)
  173.         monitor.write("/" .. formatNumber(itemData.needed))
  174.  
  175.         _, cursorPos = monitor.getCursorPos()
  176.         monitor.setCursorPos(1, cursorPos + 1)
  177.     end
  178. end
  179.  
  180. function startClock()
  181.     while (true) do
  182.         print("Starting calculation")
  183.         ingredients = getIngredients('allthetweaks:atm_star')
  184.         print("Finished calculation")
  185.         displayIngredients(ingredients)
  186.         sleep(60)
  187.     end
  188. end
  189. startClock()
  190.  
Advertisement
Comments
Add Comment
Please, Sign In to add comment