Advertisement
fatboychummy

Turtle Item Repairer

May 16th, 2023 (edited)
882
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 7.27 KB | None | 0 0
  1. -- User configurable
  2. local CHECK_DELAY = 60 -- Delay between each batch crafting operation.
  3. local BUFFER_DELAY_REMOVAL = 5 -- Time subtracted from the delay-between-crafting-operations per item that had to be stored in the buffer chest. Default case = 5 with 60 delay will mean 12 items in the buffer chest will cause the crafting operation to instantly resume.
  4. local INPUT_CHEST = "minecraft:shulker_box_0" -- The input chest's (or other inventory) name on the network.
  5. local OUTPUT_CHEST = "minecraft:shulker_box_1" -- The output chest's (or other inventory) name on the network.
  6. local BUFFER_CHEST = "minecraft:chest_1" -- A third chest (or other inventory) on the network. The turtle will move things here temporarily if the input inventory is full and it cannot push damaged items back into it.
  7. local ERROR_DELAY = 2 -- Delay between retries if an error occurs (ie: failing to move items to the output inventory)
  8.  
  9. -- Don't touch
  10. local modem = peripheral.wrap("front") --[[@as WiredModem]]
  11. if not modem or not modem.getNameLocal or not modem.getNameLocal() then
  12.   error("Expected activated wired modem in front!", 0)
  13. end
  14. local local_name = modem.getNameLocal() --[[@as string we have already verified this will return an appropriate value]]
  15.  
  16. local inv = peripheral.wrap(INPUT_CHEST) --[[@as Inventory]]
  17. if not inv or not inv.list then
  18.   error("Expected input inventory on network!", 0)
  19. end
  20.  
  21. local output = peripheral.wrap(OUTPUT_CHEST) --[[@as Inventory]]
  22. if not output or not output.list then
  23.   error("Expected output inventory to be on the network!", 0)
  24. end
  25.  
  26. local buffer = peripheral.wrap(BUFFER_CHEST) --[[@as Inventory]]
  27. if not buffer or not buffer.list then
  28.   error("Expected buffer inventory to be on the network!", 0)
  29. end
  30.  
  31. --- Grab an item from the input inventory and move it to the turtle.
  32. ---@param slot integer The slot to pull from.
  33. local function get_item(slot)
  34.   print("Pulling item from input slot", slot, "to the turtle.")
  35.   return inv.pushItems(local_name, slot)
  36. end
  37.  
  38. --- Move item in the turtle to the output chest, if fully repaired.
  39. ---@return boolean outputted If the item was outputted (ie: was fully repaired).
  40. local function attempt_output()
  41.   for slot = 1, 16 do
  42.     -- Need detailed mode for damage.
  43.     local item = turtle.getItemDetail(slot, true) --[[@as turtleDetailsDetailed|nil]]
  44.     if item then
  45.       if item.damage == 0 then
  46.         -- To the output chest!
  47.         print("Pulling repaired item from turtle.")
  48.         -- While we fail to move items, display an error.
  49.         while output.pullItems(local_name, slot) == 0 do
  50.           printError("Output chest is likely full. Cannot do anything until it is emptied!")
  51.           sleep(ERROR_DELAY)
  52.         end
  53.        
  54.         print("Successfully repaired and outputted an item.")
  55.         return true
  56.       end
  57.     end
  58.   end
  59.  
  60.   return false
  61. end
  62.  
  63. local function force_output()
  64.   for slot = 1, 16 do
  65.     -- Need detailed mode for damage.
  66.     local item = turtle.getItemDetail(slot, true) --[[@as turtleDetailsDetailed|nil]]
  67.     if item then
  68.       -- To the output chest!
  69.       print("Pulling item from turtle to output chest.")
  70.       while output.pullItems(local_name, slot) == 0 do
  71.         printError("Output chest is likely full. Cannot do anything until it is emptied!")
  72.         sleep(ERROR_DELAY)
  73.       end
  74.     end
  75.   end
  76. end
  77.  
  78. --- Empty the buffer chest
  79. ---@return integer buffered The amount of items that were taken out of the buffer.
  80. local function empty_buffer()
  81.   local buffered = 0
  82.  
  83.   for slot, item in pairs(buffer.list()) do
  84.     buffered = buffered + item.count
  85.     inv.pullItems(BUFFER_CHEST, slot)
  86.   end
  87.  
  88.   return buffered
  89. end
  90.  
  91. --- Dump the contents of the turtle to the buffer chest
  92. ---@return integer buffered The amount of items that were taken out of the buffer, if the buffer needed to be emptied during this cycle.
  93. local function dump_to_buffer()
  94.   local buffered = 0
  95.  
  96.   for slot = 1, 16 do
  97.     if turtle.getItemCount(slot) > 0 then
  98.       if buffer.pullItems(local_name, slot) == 0 then
  99.         buffered = buffered + empty_buffer()
  100.         while buffer.pullItems(local_name, slot) == 0 do
  101.           printError("Buffer chest and input chest are likely full. Cannot do anything until they are emptied!")
  102.           sleep(ERROR_DELAY)
  103.         end
  104.       end
  105.     end
  106.   end
  107.  
  108.   return buffered
  109. end
  110.  
  111. while true do
  112.   local size = inv.size()
  113.   local repairs = 0
  114.   local full_health = 0
  115.   local buffered = 0
  116.   for test_slot = 1, size - 1 do
  117.     -- Get the item in that slot.
  118.     local item = inv.getItemDetail(test_slot)
  119.    
  120.     if item then
  121.       -- An item exists in this slot.
  122.      
  123.       -- Then, check if we even need to combine this item with anything...
  124.       if item.damage == 0 then
  125.         print("Found an undamaged item in the chest, moving it to output.")
  126.         full_health = full_health + 1
  127.         while output.pullItems(INPUT_CHEST, test_slot) == 0 do
  128.           printError("Output chest is likely full. Cannot do anything until it is emptied!")
  129.           sleep(ERROR_DELAY)
  130.         end
  131.       else -- Item is damaged,
  132.         get_item(test_slot)
  133.  
  134.         -- we will try to combine it until we can no longer do so.
  135.         for secondary_slot = test_slot + 1, size do
  136.           -- Get the item in that slot
  137.           local second_item = inv.getItemDetail(secondary_slot)
  138.  
  139.           if second_item then
  140.             -- First, check if the item is undamaged already (it's a waste to craft these).
  141.             if second_item.damage == 0 then
  142.               -- Move it to the output chest if undamaged.
  143.               print("Found an undamaged item in the chest, moving it to output.")
  144.               full_health = full_health + 1
  145.               while output.pullItems(INPUT_CHEST, secondary_slot) == 0 do
  146.                 printError("Output chest is likely full. Cannot do anything until it is emptied!")
  147.                 sleep(ERROR_DELAY)
  148.               end
  149.             elseif item.name == second_item.name then -- Check if the two item names are equal.
  150.               -- Items are the same!
  151.               get_item(secondary_slot)
  152.               if not turtle.craft() then
  153.                 printError("Items were not craftable!")
  154.                 print("Moving them into the output chest.")
  155.                 force_output()
  156.                 -- We do not break out of the loop here: if more of this item remain, it will get pulled and moved to the output immediately.
  157.               end
  158.  
  159.               -- And if we were able to output this item, break out of this inner loop.
  160.               if attempt_output() then
  161.                 repairs = repairs + 1
  162.                 break
  163.               end
  164.             end
  165.           end
  166.         end
  167.        
  168.         -- If we went through all the items in the chest and failed to repair it, throw it into the buffer chest.
  169.         buffered = buffered + dump_to_buffer()
  170.       end
  171.     end
  172.   end
  173.  
  174.   -- Empty the contents of the buffer inventory into the main inventory.
  175.   buffered = buffered + empty_buffer()
  176.  
  177.   print(("Done cycle.\n  Successful repairs: %d\n  Full-health items found: %d\n  Items buffered: %d\n  Time until next cycle: %d seconds"):format(
  178.     repairs,
  179.     full_health,
  180.     buffered,
  181.     math.max(CHECK_DELAY - BUFFER_DELAY_REMOVAL * buffered, 0)
  182.   ))
  183.   sleep(math.max(CHECK_DELAY - BUFFER_DELAY_REMOVAL * buffered, 0))
  184. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement