vittoema96

E2E InfiniteOreMachine CraftyTurtle Program

Jan 9th, 2023 (edited)
93
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 8.66 KB | None | 0 0
  1. --------------------------------------
  2. --        WHAT IS THIS?             --
  3. --------------------------------------
  4.  
  5. -- This is a Lua program for the Minecraft
  6. -- mod Computercraft (or CC: Tweaked),
  7. -- specifically for the crafting turtle.
  8.  
  9. -- This is used in an "Infinite Ore Machine"
  10. -- that I have set up in Enigmatica 2: Expert.
  11.  
  12. -- The machine consists in
  13. --  ° A Cobblestone Generator (NuclearCraft)
  14. --      .. feeding ..
  15. --  ° An Auto Hammer (Ex Compressum)
  16. --      .. feeding ..
  17. --  ° An Auto Sieve (Ex Compressum) with a Diamond Stiffened Mesh (Ex Nihilo Creatio)
  18. --      .. storing everything in a chest*
  19.  
  20. -- * This chest is the inputSide (USER OPTIONS section)
  21. --   of this program.
  22. --   The outputSide (USER OPTIONS section) will collect
  23. --   the ores crafted by the turtle and the
  24. --   "final products" that can be found in
  25. --    noCraftingItems (USER OPTIONS section)
  26.  
  27. --  TIP:
  28. --  Connect the outputSide chest to an
  29. --  ore grinding machine and that machine
  30. --  to a smelting machine to
  31. --  complete the setup.
  32. --  WARNING: Remember that not all items
  33. --           in the output chest are actually ores,
  34. --           filter those out.
  35.  
  36. ---------------------------------------
  37. --  THIS PROGRAM FOR DUMMIES   --
  38. -- What this basically does is it:
  39. --
  40. --  *  It fills the turtle with items from a storage block placed on the
  41. --     inputSide (set it under USER OPTIONS) side of the turtle.
  42. --
  43. --  *  if it finds any item with a name
  44. --     equal to one of the entries in noCraftingItems
  45. --     (set it under USER OPTIONS) it directly deposits
  46. --     it in the storage block placed on the outputSide
  47. --     (set it under USER OPTIONS) side of the turtle.
  48. --
  49. --  *  It finds the most abundant item in the turtle,
  50. --     deposits on inputSide all of the other items,
  51. --     then proceeds to place the remaining item in a
  52. --     2x2 grid, tries to craft, then deposits the result
  53. --     in the outputSide
  54. --
  55. --  *  Cleans the turtle from any remaining items (may
  56. --     happen due to machine or software mafunctions)
  57. --
  58. --  *  Loops.
  59. --
  60.  
  61.  
  62. ---------------------------------------
  63. --       HOW TO INSTALL IT?          --
  64. ---------------------------------------
  65. -- Simply run
  66. -- pastebin get pHgVd5au startup
  67. -- then run 'reboot' or press CTRL+R
  68. -- for a few seconds
  69. -- WARNING
  70. -- Remember to have the chests and
  71. -- everything set up before restarting.
  72.  
  73.  
  74. ---------------------------------------
  75. --         USER OPTIONS              --
  76. ---------------------------------------
  77.  
  78.  
  79. -- These are constants, set the values
  80. -- of inputSide and outputSide to one
  81. -- of these 3 values (NOT THE SAME ONE)
  82. TOP = 0
  83. BOTTOM = 1
  84. FRONT = 2
  85.  
  86. -- The side on which the input/output
  87. -- chests are situated
  88. inputSide = FRONT
  89. outputSide = TOP
  90.  
  91. -- These are the items that are considered
  92. -- already a final product and will be
  93. -- directly deposited in the output chest
  94. -- during the removeAllExcept phase
  95. noCraftingItems = {['minecraft:diamond']=true,
  96.                    ['minecraft:emerald']=true,
  97.                    ['actuallyadditions:item_dust']=true}  
  98.  
  99.  
  100. ---------------------------------------
  101. --         ACTUAL CODE               --
  102. ---------------------------------------
  103.  
  104. -- The function that gets called repeatedly
  105. function loop()
  106.     assureEmptyTurtle()
  107.     itemMap = loadTurtle()
  108.     record, itemMap = extractMostAbundantItem(itemMap)
  109.     removeAll(itemMap)
  110.     craft(record)
  111. end
  112.  
  113. -- Be sure that the turtle is empty
  114. -- might be full after a world restart or such
  115. function assureEmptyTurtle()
  116.     rejectFunc = getRejectFunc()
  117.     for i=1, 16 do
  118.         if turtle.getItemCount(i)>0 then
  119.             turtle.select(i)
  120.             rejectFunc()
  121.         end
  122.     end
  123. end
  124.    
  125.  
  126. function loadTurtle()
  127.     -- The function used to suck up
  128.     -- a slot of input materials
  129.     suckFunc = getSuckFunc()
  130.     -- The function used to deposit
  131.     -- materials that don't need crafting
  132.     deliverFunc = getDeliveryFunc()
  133.    
  134.     -- This is where the items get registered.
  135.     -- dict(<item_name>: list(dict("slot": int, "count": int))
  136.     itemMap = {}
  137.     firstAvailableSlot = 16
  138.    
  139.     turtle.select(1)
  140.     suckFunc()
  141.    
  142.     while turtle.getItemCount() > 0 and firstAvailableSlot > 0 do  
  143.        
  144.         name = getItemName(1)
  145.         -- The item is a final product,
  146.         -- deposit it
  147.         if noCraftingItems[name] then
  148.             deliverFunc()
  149.         -- This is an item we need to handle
  150.         else
  151.             slotList = itemMap[name]
  152.             -- We don't have the item registered
  153.             if slotList == nil then
  154.                 record = {slot=firstAvailableSlot, count=turtle.getItemCount()}
  155.                 itemMap[name] = {record}
  156.                 turtle.transferTo(firstAvailableSlot)
  157.                 firstAvailableSlot = firstAvailableSlot - 1
  158.             -- The item was already acquired
  159.             -- by the turtle
  160.             else
  161.                 -- The last used slot has space, fill it
  162.                 if slotList[#slotList]["count"] < 64 then
  163.                     turtle.transferTo(slotList[#slotList]["slot"])
  164.                 -- The last used slot is full, get a new one
  165.                 else
  166.                     slotList[#slotList+1] = {slot=firstAvailableSlot, count=turtle.getItemCount()}
  167.                     turtle.transferTo(firstAvailableSlot)
  168.                     firstAvailableSlot = firstAvailableSlot - 1
  169.                 end
  170.             end
  171.         end
  172.         if turtle.getItemCount() == 0 then
  173.             suckFunc()
  174.         end
  175.     end
  176.     return itemMap
  177. end
  178.  
  179.  
  180. -- Returns the record of the most abundant
  181. -- item, and the map without said item in it
  182. function extractMostAbundantItem(itemMap)
  183.     itemToKeep = nil
  184.     stacks = 0
  185.     for name, list in pairs(itemMap) do
  186.         if #list > stacks then
  187.             itemToKeep = name
  188.             stacks = #list
  189.         elseif #list == stacks then
  190.             challengerList = itemMap[itemToKeep]
  191.             if list[#list]["count"] > challengerList[#challengerList]["count"] then
  192.                 itemToKeep = name
  193.             end
  194.         end
  195.     end
  196.     result = itemMap[itemToKeep]
  197.     itemMap[itemToKeep] = nil
  198.     return result, itemMap
  199. end
  200.  
  201. -- Returns all the items in
  202. -- the turtle back to the input
  203. -- chest, except fot the
  204. -- item needed for crafting
  205. function removeAll(itemMap)
  206.  
  207.     rejectFunc = getRejectFunc()
  208.    
  209.     for name, list in pairs(itemMap) do
  210.         for i, record in ipairs(list) do
  211.             turtle.select(record["slot"])
  212.             rejectFunc()
  213.         end
  214.     end
  215. end    
  216.  
  217. function craft(recordList)
  218.    
  219.     tot = (#recordList - 1) * 64 + recordList[#recordList]["count"]
  220.  
  221.     deliverFunc = getDeliveryFunc()
  222.     rejectFunc = getRejectFunc()
  223.    
  224.    
  225.     if #recordList > 4 then
  226.         for i=5, #recordList do
  227.             turtle.select(recordList[i]["slot"])
  228.             rejectFunc()
  229.             recordList[i] = nil
  230.         end
  231.         tot = 64 * 4
  232.     elseif tot % 4 ~= 0 then
  233.         turtle.select(recordList[#recordList]["slot"])
  234.         rejectFunc(tot % 4)
  235.         tot = tot - tot % 4
  236.     end
  237.     slots = {16, 15, 12, 11}
  238.    
  239.     for i=1, 4 do
  240.         k = 1
  241.         rec = recordList[i]
  242.         if rec == nil then
  243.             break
  244.         end
  245.         selectedSlot = rec["slot"]
  246.         count = rec["count"]
  247.         turtle.select(selectedSlot)
  248.         if selectedSlot == 16 or selectedSlot == 15 or selectedSlot == 12 or selectedSlot == 11 then
  249.             minimum = tot / 4
  250.         else
  251.             minimum = 0
  252.         end
  253.         while turtle.getItemCount() > minimum and k < 5 do
  254.             if selectedSlot == slots[k] or turtle.getItemCount(slots[k]) >= tot / 4 then
  255.                 k = k + 1
  256.             else
  257.                 turtle.transferTo(slots[k], tot / 4 - turtle.getItemCount(slots[k]))
  258.             end
  259.         end
  260.     end
  261.     turtle.craft()
  262.     deliverFunc()
  263. end
  264.  
  265. -- If there is an item in slot "i"
  266. -- returns its name, if the slot is
  267. -- empty returns "nil"
  268. function getItemName(i)
  269.     if turtle.getItemCount(i) == 0 then
  270.         return nil
  271.     end
  272.     return turtle.getItemDetail(i)["name"]
  273. end
  274.  
  275. -- Returns the callable that sucks
  276. -- the input from the input chest
  277. function getSuckFunc()
  278.     if inputSide == FRONT then
  279.         return turtle.suck
  280.     elseif inputSide == TOP then
  281.         return turtle.suckUp
  282.     else
  283.         return turtle.suckDown
  284.     end
  285. end
  286.  
  287. -- Returns the callable that drops
  288. -- unwanted input back into the
  289. -- input chest
  290. function getRejectFunc()
  291.     if inputSide == FRONT then
  292.         return turtle.drop
  293.     elseif inputSide == TOP then
  294.         return turtle.dropUp
  295.     else
  296.         return turtle.dropDown
  297.     end
  298. end
  299.  
  300. -- Returns the callable that drops
  301. -- the resulting product to the
  302. -- output chest
  303. function getDeliveryFunc()
  304.     if outputSide == FRONT then
  305.         return turtle.drop
  306.     elseif outputSide == TOP then
  307.         return turtle.dropUp
  308.     else
  309.         return turtle.dropDown
  310.     end
  311. end
  312.  
  313.  
  314.  
  315. ---------------------------------------
  316. --         MAIN LOOP                 --
  317. ---------------------------------------
  318.  
  319. -- Check for wrong Configuration
  320.  
  321. if not pcall(turtle.craft) then
  322.     error("This turtle should be a crafty turtle, but turtle.craft() couldn't be called")
  323. end
  324. if inputSide == outputSide then
  325.     error("inputSide and outputSide were set to the same value, but this is not possible")
  326. end
  327.  
  328. -- Actual loop
  329. while true do
  330.     loop()
  331. end
Add Comment
Please, Sign In to add comment