Advertisement
Skortioth

[CC]: Refined Storage Autocrafter

Feb 3rd, 2022 (edited)
1,718
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 10.35 KB | None | 0 0
  1. --[[
  2. Steps:
  3. 1. Build a Computer and download this script onto your computer (pastebin get)
  4. 2. Create a file named "recipes" (without .lua - on my version i had to use "rename recipes.lua recipes")
  5. 3. Build a RS Bridge (Mod: Advanced Peripherals) and connect it to your computer
  6. 4. Build a Vanilla Minecraft Chest! and connect it to your computer
  7. 5. Start the script
  8. 6. Insert any (RS System) craftable item into the chest, like 10 Pistons
  9. 7. Wait for the recipe beeing registered (Registered recipe: 10x minecraft:piston)
  10. 8. You can remove the 10 pistons from the chest
  11. 9. If you want to edit the 10, either close the script and edit the recipes file OR just insert 20 pistons into the chest and wait for the computer to edit the recipe
  12.  
  13. Now the computer will always make sure you have 10 pistons in your rs system
  14.  
  15. ]]
  16. print("Loading autocrafter...")
  17.  
  18. local bridge = peripheral.find("rsBridge")
  19.  
  20. local maxCoWorker = 6
  21.  
  22. local recipeList = {}
  23. local craftingQueue = {}
  24.  
  25. local function StringSeperate(str, seperator)
  26. local words = {}
  27. local word = ""
  28.  
  29.     if(string.sub(str, str:len(), str:len())~=seperator)then
  30.         str = str..""..seperator        
  31.     end
  32.     for x=1,str:len() do
  33.         local s = string.sub(str,x,x)
  34.         if(s==seperator)then
  35.             table.insert(words, word)
  36.             word = ""
  37.         else
  38.             word = word..s
  39.         end
  40.     end
  41.     return words
  42. end
  43.  
  44. local f = io.open("recipes", ab)
  45.  
  46.     for line in io.lines("recipes")do
  47.         local tab = StringSeperate(line, "|")
  48.         if(tab[1]~=nil)and(tab[2]~=nil)and(tab[3]~=nil)and(tab[4]~=nil)and(tab[5]~=nil)then
  49.             print("Registered recipe: "..tab[3].."x "..tab[1]..":"..tab[2])
  50.             os.sleep(0.2)
  51.             local recipe = {name=tab[1],damage=tonumber(tab[2]),minAmount=tonumber(tab[3]),maxCraftAmount=tonumber(tab[4]),fails=0,timer=0}
  52.             if(tab[5]=="true")then
  53.                 recipe.useDmg=true
  54.             else
  55.                 recipe.useDmg=false
  56.             end
  57.             table.insert(recipeList, recipe)
  58.         end  
  59.     end
  60. f:close()
  61.  
  62. function SaveToFile()
  63.     local file = io.open("recipes", "wb")
  64.     for k,v in pairs(recipeList)do
  65.         if(v.useDmg)then
  66.             file:write(v.name.."|"..v.damage.."|"..v.minAmount.."|"..v.maxCraftAmount.."|true|", "\n")
  67.         else
  68.             file.write(v.name.."|"..v.damage.."|"..v.minAmount.."|"..v.maxCraftAmount.."|false|", "\n")
  69.         end
  70.     end
  71.     file:close()
  72. end
  73.  
  74. local function GetAmount(itemAmount, recipe)
  75.     local amount = 0
  76.     if(itemAmount < recipe.minAmount)then
  77.         if(recipe.maxCraftAmount > 0)then
  78.             if(recipe.minAmount-itemAmount > recipe.maxCraftAmount)then
  79.                 amount = recipe.maxCraftAmount
  80.             else
  81.                 amount = recipe.minAmount-itemAmount
  82.             end
  83.         else
  84.             amount = recipe.minAmount-itemAmount
  85.         end
  86.     end
  87.     return amount
  88. end
  89.    
  90. function GetRecipeKey(pattern)
  91.     for k,v in pairs(recipeList)do
  92.         if(v.name == pattern.name)then
  93.             if(pattern.damage==nil)then return k end
  94.             if(v.useDmg)then
  95.                 if(v.damage == pattern.damage)then
  96.                     return k
  97.                 end
  98.             else
  99.                 return k
  100.             end
  101.         end
  102.     end
  103.     return nil
  104. end
  105.  
  106. local function CheckCraftingRecipe(recipe)
  107.     local pattern = bridge.getItem({name=recipe.name})
  108.     local item = {pattern=pattern, amount=0}
  109.     if(pattern~=nil)then
  110.       local storedAmount = pattern.amount
  111.       local neededItemAmount = GetAmount(storedAmount, recipe)
  112.       if(neededItemAmount > 0)then
  113.         item.amount = neededItemAmount
  114.         table.insert(craftingQueue, item)
  115.         return true
  116.       end
  117.     end
  118.     return false
  119. end
  120.  
  121. local function CheckAllRecipes()
  122.     for k,v in pairs(recipeList)do
  123.         if(type(v)=="table")then
  124.             CheckCraftingRecipe(v)
  125.         end
  126.     end
  127. end
  128.  
  129. function RemoveRecipe(item)
  130.     local key = -1
  131.         for k,v in pairs(recipeList)do
  132.             if(v.name == item.name)and(v.damage== item.damage)then
  133.                 key = k
  134.             end
  135.         end
  136.         if(key>=0)then
  137.             table.remove(recipeList, key)
  138.         end
  139.         SaveToFile()
  140. end
  141.  
  142. local function FindKeyInTable(table, item)
  143.     for k,v in pairs(table)do
  144.         if(v==item)then
  145.             return k
  146.         end
  147.     end
  148.     return nil
  149. end
  150.  
  151. local function UpdateCraftingQueue()
  152.     while(#craftingQueue > 0)do
  153.         local activeCoWorkers = {}
  154.         local craftingQueuesToRemove = {}
  155.         for k,v in pairs(craftingQueue)do
  156.             if(#activeCoWorkers+1 <= maxCoWorker)then
  157.                 local stack = v.pattern
  158.                 local recipeKey = GetRecipeKey(stack)
  159.  
  160.                 local waittimer = 0
  161.                 local multiplier = 1
  162.  
  163.                 if(recipeList[recipeKey].fails > 0)and(recipeList[recipeKey].fails <=10)then
  164.                     multiplier = recipeList[recipeKey].fails
  165.                 elseif(recipeList[recipeKey].fails > 10)then
  166.                     multiplier = 20
  167.                 end
  168.                 waittimer = multiplier * 30
  169.                 if(os.clock()>=recipeList[recipeKey].timer+waittimer)then
  170.                     if not(bridge.isItemCrafting(stack.name))then
  171.                             local currentItemState = {item=stack, curAmount = stack.count, amountToCraft = v.amount}
  172.                         if(bridge.isItemCraftable({name=stack.name}))then
  173.                             local task, errormsg = bridge.craftItem({name=stack.name, count = v.amount})
  174.                             if(task)then
  175.                                 print("Scheduled Task: "..v.amount.." ("..stack.name..") "..stack.displayName)    
  176.                                 table.insert(activeCoWorkers, currentItemState)
  177.                                 recipeList[recipeKey].fails = 0
  178.                             else
  179.                                 print("------------------")
  180.                                 print("Error scheduling task: "..v.amount.."x ("..stack.name..") "..stack.displayName)
  181.                                 print("Not enough materials!")
  182.                                 print("------------------")
  183.                                 recipeList[recipeKey].fails = recipeList[recipeKey].fails + 1
  184.                                 recipeList[recipeKey].timer = os.clock()
  185.                             end
  186.                         else
  187.                             print("------------------")
  188.                             print("Error scheduling task: "..v.amount.."x ("..stack.name..") "..stack.displayName)
  189.                             print("No pattern available!")
  190.                             print("------------------")
  191.                             recipeList[recipeKey].fails = recipeList[recipeKey].fails + 1
  192.                             recipeList[recipeKey].timer = os.clock()
  193.                         end
  194.                     end
  195.                 end
  196.                 table.insert(craftingQueuesToRemove, v)
  197.             end
  198.         end
  199.  
  200.         if(#craftingQueuesToRemove > 0)then
  201.             for k,v in pairs(craftingQueuesToRemove)do
  202.                 local id = FindKeyInTable(craftingQueue, v)
  203.                 table.remove(craftingQueue, id)
  204.             end
  205.         end
  206.  
  207.         while(#activeCoWorkers > 0)do
  208.             local finishedCoworker = {}
  209.             for k,v in pairs(activeCoWorkers)do
  210.                 if not(bridge.isItemCrafting(v.item.name))then
  211.                     print("Task done: "..v.amountToCraft.."x ("..v.item.name..") "..v.item.displayName)    
  212.                     table.insert(finishedCoworker, v)
  213.                 end
  214.             end
  215.             if(#finishedCoworker>0)then
  216.                 for k,v in pairs(finishedCoworker)do
  217.                     local id = FindKeyInTable(activeCoWorkers, v)
  218.                     table.remove(activeCoWorkers, id)
  219.                 end
  220.             end
  221.             os.sleep(0.75)
  222.         end
  223.         os.sleep(0.75)
  224.     end
  225. end
  226.  
  227. function FindKeyWithItemName(table, itemname, damage)
  228.     for k,v in pairs(table)do
  229.         if(v.name==itemname)and(v.damage == damage)then
  230.             return k
  231.         end
  232.     end
  233.     return nil
  234. end
  235.  
  236. local function CheckChestForNewEntrys()
  237.     local inventory = peripheral.find("minecraft:chest")
  238.     local items = {}
  239.     local itemAmounts = {}
  240.     local somethingChanged = false
  241.      
  242.         if(inventory~=nil)then
  243.             for x=1,inventory.size(), 1 do
  244.                 local item = inventory.getItemDetail(x)
  245.                 if(item~=nil)then
  246.                     if(item.damage==nil)then item.damage = 0 end
  247.                     table.insert(items, item)
  248.                 end
  249.             end
  250.             os.sleep(0.5)
  251.         end
  252.         os.sleep(1)
  253.      
  254.         if(#items > 0)then
  255.             for k,v in pairs(items)do
  256.                 local key = FindKeyWithItemName(itemAmounts, v.name, v.damage)
  257.                 if(key~=nil)then
  258.                     itemAmounts[key].count = itemAmounts[key].count + v.count
  259.                 else
  260.                     table.insert( itemAmounts, {name=v.name, damage=v.damage, count = v.count})
  261.                 end
  262.      
  263.             end
  264.         end
  265.      
  266.         if(#itemAmounts > 0)then
  267.             for k,v in pairs(itemAmounts)do
  268.                 local key = FindKeyWithItemName(recipeList, v.name, v.damage)
  269.                 if(key~=nil)then
  270.                     if(recipeList[key].minAmount ~= v.count)then
  271.                         print("Edited recipe: "..v.name.. ":"..v.damage.." new count: "..v.count)
  272.                     end
  273.                     somethingChanged = true
  274.                     recipeList[key].minAmount = v.count
  275.                 else
  276.                     table.insert( recipeList, {name=v.name, damage=v.damage, minAmount = v.count, maxCraftAmount = 0, useDmg = true, fails = 0, timer = 0})
  277.                     somethingChanged = true
  278.                     print("Registered recipe: "..v.count.."x "..v.name.. ":"..v.damage)
  279.                 end
  280.             end
  281.             if(somethingChanged)then
  282.                 SaveToFile()        
  283.             end
  284.         end
  285. end
  286.  
  287. print("Autocrafter successfully loaded!")
  288.  
  289. while true do
  290.     bridge = peripheral.find("rsBridge")
  291.     CheckChestForNewEntrys()
  292.     os.sleep(1)
  293.     CheckAllRecipes()
  294.     os.sleep(1)
  295.     pcall(UpdateCraftingQueue)
  296.     os.sleep(1)
  297. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement