Skortioth

[OC]: Applied Energistics 2 Autocrafter

Oct 9th, 2021 (edited)
1,182
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 10.01 KB | None | 0 0
  1. print("Loading autocrafter...")
  2.  
  3. local component = require("component")
  4. local ae2 = component.me_interface
  5. local inventory = component.inventory_controller
  6. local side = require("sides")
  7.  
  8. local maxTaskCount = 4
  9. local maxCoWorker = 1
  10.  
  11. local recipeList = {}
  12. local craftingQueue = {}
  13.  
  14.  
  15.  
  16. local function StringSeperate(str, seperator)
  17. local words = {}
  18. local word = ""
  19.  
  20.   if(string.sub(str, str:len(), str:len())~=seperator)then
  21.     str = str.. "" .. seperator
  22.   end
  23.   for x=1,str:len() do
  24.     local s = string.sub(str,x,x)
  25.     if(s == seperator)then
  26.       table.insert(words, word)
  27.       word = ""
  28.     else
  29.       word = word .. s
  30.     end
  31.   end
  32.   return words
  33. end
  34.  
  35. local f = io.open("recipes", "ab")
  36.   for line in io.lines("recipes")do
  37.     local tab = StringSeperate(line, "|")
  38.     --print("asd"..tab[1])
  39.     if(tab[1]~=nil)and(tab[2]~=nil)and(tab[3]~=nil)and(tab[4]~=nil)and(tab[5]~=nil)then
  40.     print("Registered recipe: "..tab[3].."x "..tab[1]..":"..tab[2])
  41.     os.sleep(0.2)
  42.     local recipe = {name=tab[1],damage=tonumber(tab[2]),minAmount=tonumber(tab[3]),maxCraftAmount=tonumber(tab[4]),fails=0,timer=0}
  43.     if(tab[5]=="true")then
  44.       recipe.useDmg = true
  45.     else
  46.       recipe.useDmg = false
  47.     end
  48.     table.insert(recipeList, recipe)
  49.     end
  50.   end
  51. f:close()
  52.  
  53. function SaveToFile()
  54.     local file = io.open("recipes", "wb")
  55.     for k,v in pairs(recipeList)do
  56.         if(v.useDmg)then
  57.             file:write(v.name.."|"..v.damage.."|"..v.minAmount.."|"..v.maxCraftAmount.."|true|", "\n")
  58.         else
  59.             file:write(v.name.."|"..v.damage.."|"..v.minAmount.."|"..v.maxCraftAmount.."|false|", "\n")
  60.         end
  61.     end
  62.     file:close()
  63. end
  64.  
  65. local function GetActiveTaskCount()
  66. local n = 0
  67.     for k,v in pairs(ae2.getCpus())do
  68.     if(type(v)=="table")then
  69.         if(v.busy==true)then
  70.         n = n+1
  71.         end
  72.     end
  73.     end
  74.     return n
  75. end
  76.  
  77. local function GetAvailableCpuCount()
  78.     return ae2.getCpus() - GetActiveTaskCount()
  79. end
  80.  
  81. local function GetRecipe(pattern)
  82.   for k,v in pairs(recipeList)do
  83.     if(v.name==pattern.name)then
  84.       if(v.useDmg)then
  85.         if(v.damage == pattern.damage)then
  86.           return v
  87.         end
  88.       else
  89.         return v
  90.       end
  91.     end
  92.   end
  93.   return nil
  94. end
  95.  
  96. local function GetStoredItemAmountNetwork(recipe)
  97. local count = 0
  98.   for k,v in pairs(ae2.getItemsInNetwork())do
  99.     if(type(v)=="number")then break end
  100.     if(v.name == recipe.name)then
  101.       if(recipe.useDmg)then
  102.         if(v.damage == recipe.damage)then
  103.           count = count + v.size
  104.         end
  105.       else
  106.           count = count + v.size
  107.       end
  108.     end
  109.   end
  110.   return count
  111. end
  112.  
  113. local function GetAmount(itemAmount, recipe)
  114.     local amount = 0
  115.     if(itemAmount < recipe.minAmount)then
  116.         if(recipe.maxCraftAmount > 0)then
  117.             if(recipe.minAmount-itemAmount > recipe.maxCraftAmount)then
  118.                 amount = recipe.maxCraftAmount
  119.             else
  120.                 amount = recipe.minAmount-itemAmount
  121.             end
  122.         else
  123.             amount = recipe.minAmount-itemAmount
  124.         end
  125.     end
  126.     return amount
  127. end
  128.  
  129. function GetRecipeKey(pattern)
  130.     for k,v in pairs(recipeList)do
  131.         if(v.name == pattern.name)then
  132.             if(v.useDmg)then
  133.                 if(v.damage == pattern.damage)then
  134.                     return k
  135.                 end
  136.             else
  137.                 return k
  138.             end
  139.         end
  140.     end
  141.     return nil
  142. end
  143.  
  144. local function CheckCraftingRecipe(pattern)
  145.     local stack = pattern.getItemStack()
  146.     local recipe = GetRecipe(stack)
  147.     if(recipe~=nil)then
  148.       local storedAmount = GetStoredItemAmountNetwork(recipe)
  149.       local neededItemAmount = GetAmount(storedAmount, recipe)
  150.       if(neededItemAmount > 0)then
  151.         table.insert(craftingQueue, {item=pattern, amount=neededItemAmount})
  152.         return true
  153.       end
  154.     end
  155.     return false
  156. end
  157.  
  158. local function CheckAllRecipes()
  159.     for k,v in pairs(ae2.getCraftables())do
  160.         if(type(v)=="number")then break end
  161.         CheckCraftingRecipe(v)
  162.     end
  163. end
  164.  
  165. function RemoveRecipe(item)
  166.     local key = -1
  167.         for k,v in pairs(recipeList)do
  168.             if(v.name == item.name)and(v.damage== item.damage)then
  169.                 key = k
  170.             end
  171.         end
  172.         if(key>=0)then
  173.             table.remove(recipeList, key)
  174.         end
  175.         SaveToFile()
  176.     end
  177.  
  178. local function GetCraftable(item)
  179.       for k,v in pairs(ae2.getCraftables())do
  180.         if(item.useDmg)then
  181.             if(v.getItemStack().name==item.name)then
  182.             if(item.useDmg)then
  183.                 if(v.damage==item.damage)then
  184.                 return v          
  185.                 end
  186.             end
  187.             return v
  188.             end
  189.         end
  190.     end
  191. end
  192.  
  193. local function FindKeyInTable(table, item)
  194.     for k,v in pairs(table)do
  195.         if(v==item)then
  196.             return k
  197.         end
  198.     end
  199.     return nil
  200. end
  201.  
  202. local function UpdateCraftingQueue()
  203.     while(#craftingQueue > 0)do
  204.         local activeCoWorkers = {}
  205.         local coworkerAmount = 0
  206.         local craftingQueuesToRemove = {}
  207.         for k,v in pairs(craftingQueue)do
  208.             if(coworkerAmount+1 <= maxCoWorker)then
  209.                 local stack = v.item.getItemStack()
  210.                 local recipeKey = GetRecipeKey(stack)
  211.  
  212.                 local waittimer = 0
  213.                 local multiplier = 1
  214.  
  215.                 if(recipeList[recipeKey].fails > 0)and(recipeList[recipeKey].fails <=10)then
  216.                     multiplier = recipeList[recipeKey].fails
  217.                 elseif(recipeList[recipeKey].fails > 10)then
  218.                     multiplier = 10
  219.                 end
  220.                 waittimer = multiplier * 3000
  221.  
  222.                 if(os.time()>=recipeList[recipeKey].timer+waittimer)then
  223.                     local task = v.item.request(v.amount)
  224.                     if(task~=nil)then
  225.                         print("Scheduled Task: "..v.amount.." "..stack.label)    
  226.                         table.insert(activeCoWorkers, task)
  227.                         coworkerAmount = coworkerAmount + 1
  228.                         recipeList[recipeKey].fails = 0
  229.                     else
  230.                         print("------------------")
  231.                         print("Error scheduling task: "..v.amount.." "..stack.label)
  232.                         print("Recipe got removed from the recipe list")
  233.                         print("------------------")
  234.                         RemoveRecipe(stack)
  235.                     end
  236.                 end
  237.                 table.insert(craftingQueuesToRemove, v)
  238.             end
  239.         end
  240.  
  241.         if(#craftingQueuesToRemove > 0)then
  242.             for k,v in pairs(craftingQueuesToRemove)do
  243.                 local id = FindKeyInTable(craftingQueue, v)
  244.                 table.remove(craftingQueue, id)
  245.             end
  246.         end
  247.  
  248.         while(#activeCoWorkers > 0)do
  249.             local finishedCoworker = {}
  250.             for k,v in pairs(activeCoWorkers)do
  251.                 if(v.isDone() or v.isCanceled())then
  252.                     table.insert(finishedCoworker, v)
  253.                 end
  254.             end
  255.             if(#finishedCoworker>0)then
  256.                 for k,v in pairs(finishedCoworker)do
  257.                     local id = FindKeyInTable(activeCoWorkers, v)
  258.                     table.remove(activeCoWorkers, id)
  259.                 end
  260.             end
  261.             os.sleep(0.75)
  262.         end
  263.         os.sleep(0.75)
  264.     end
  265. end
  266.  
  267. function FindKeyWithItemName(table, itemname, damage)
  268.     for k,v in pairs(table)do
  269.         if(v.name==itemname)and(v.damage == damage)then
  270.             return k
  271.         end
  272.     end
  273.     return nil
  274. end
  275.  
  276. local function CheckChestForNewEntrys()
  277.     local items = {}
  278.     local itemAmounts = {}
  279.     local sides = {0,1,2,3,4,5}
  280.     local somethingChanged = false
  281.      
  282.         if(inventory~=nil)then
  283.             for k,v in pairs(sides)do
  284.                 local chest = inventory.getAllStacks(v)
  285.                 if(chest~=nil)then
  286.                     local chestItems = chest.getAll()
  287.                     for a,b in pairs(chestItems)do
  288.                         if(b.name~="minecraft:air")then
  289.                             table.insert(items, b)
  290.                         end
  291.                         os.sleep(0.5)
  292.                     end
  293.                 end
  294.                 os.sleep(1)
  295.             end
  296.         end
  297.      
  298.         if(#items > 0)then
  299.             for k,v in pairs(items)do
  300.                 local key = FindKeyWithItemName(itemAmounts, v.name, v.damage)
  301.                 if(key~=nil)then
  302.                     itemAmounts[key].size = itemAmounts[key].size + v.size
  303.                 else
  304.                     table.insert( itemAmounts, {name=v.name, damage=v.damage, label = v.label, size = v.size})
  305.                 end
  306.      
  307.             end
  308.         end
  309.      
  310.         if(#itemAmounts > 0)then
  311.             for k,v in pairs(itemAmounts)do
  312.                 local key = FindKeyWithItemName(recipeList, v.name, v.damage)
  313.                 if(key~=nil)then
  314.                     if(recipeList[key].minAmount ~= v.size)then
  315.                         print("Edited recipe: "..v.name.. ":"..v.damage.." ("..v.label..") new count: "..v.size)
  316.                     end
  317.                     somethingChanged = true
  318.                     recipeList[key].minAmount = v.size
  319.                 else
  320.                     table.insert( recipeList, {name=v.name, damage=v.damage, minAmount = v.size, maxCraftAmount = 0, useDmg = true, fails = 0, timer = 0})
  321.                     somethingChanged = true
  322.                     print("Registered recipe: "..v.size.."x "..v.name.. ":"..v.damage.." ("..v.label..")")
  323.                 end
  324.             end
  325.             if(somethingChanged)then
  326.                 SaveToFile()        
  327.             end
  328.         end
  329.     end
  330.  
  331.  
  332. print("Autocrafter successfully loaded!")
  333.  
  334. while true do
  335.   CheckChestForNewEntrys()
  336.   os.sleep(1)
  337.   if(GetActiveTaskCount()<maxTaskCount)then
  338.     CheckAllRecipes()
  339.     os.sleep(1)
  340.     UpdateCraftingQueue()
  341.   else
  342.     os.sleep(5)
  343.   end
  344.   os.sleep(1)
  345. end
Add Comment
Please, Sign In to add comment