iconmaster

elementalbinder.lua

Jan 9th, 2022 (edited)
430
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 5.34 KB | None | 0 0
  1. local function logMsg(text) print("[" .. os.date("%T") .. "] " .. text) end
  2.  
  3. local function selectItem(id)
  4.     -- match exact
  5.     for i = 1, 16 do
  6.         local data = turtle.getItemDetail(i)
  7.         if data and data.name == id then
  8.             turtle.select(i)
  9.             return true
  10.         end
  11.     end
  12.     -- match by tags
  13.     for i = 1, 16 do
  14.         local data = turtle.getItemDetail(i, true)
  15.         if data then
  16.             for tag, _ in pairs(data.tags) do
  17.                 if tag == id then
  18.                     turtle.select(i)
  19.                     return true
  20.                 end
  21.             end
  22.         end
  23.     end
  24.     -- no match
  25.     return false
  26. end
  27.  
  28. local function nKeys(t)
  29.     local i = 0
  30.     for _, _ in pairs(t) do i = i + 1 end
  31.     return i
  32. end
  33.  
  34. local function getInventory()
  35.     local result = {}
  36.     for i = 1, 16 do
  37.         local details = turtle.getItemDetail(i, true)
  38.         if details then
  39.             if details.name then result[details.name] = true end
  40.             if details.tags then
  41.                 for tag, _ in pairs(details.tags) do
  42.                     result[tag] = true
  43.                 end
  44.             end
  45.         end
  46.     end
  47.     return result
  48. end
  49.  
  50. local function getItemInPeripheral(peripheral, id)
  51.     -- match exact
  52.     for i = 1, peripheral.size() do
  53.         local data = peripheral.getItemDetail(i)
  54.         if data and data.name == id then return i end
  55.     end
  56.     -- match by tags
  57.     for i = 1, peripheral.size() do
  58.         local data = peripheral.getItemDetail(i, true)
  59.         if data then
  60.             for tag, _ in pairs(data.tags) do
  61.                 if tag == id then return i end
  62.             end
  63.         end
  64.     end
  65.     -- no match
  66.     return nil
  67. end
  68.  
  69. local function selectEmptySlot()
  70.     for i = 1, 16 do
  71.         local data = turtle.getItemDetail(i)
  72.         if not data then
  73.             turtle.select(i)
  74.             return true
  75.         end
  76.     end
  77.     return false
  78. end
  79.  
  80. local function selectItemOrEmpty(id) return selectItem(id) or selectEmptySlot() end
  81.  
  82. local RECIPES = {
  83.     ["elementalcraft:swift_alloy_ingot"] = {
  84.         "minecraft:gold_ingot", "elementalcraft:drenched_iron_ingot",
  85.         "minecraft:redstone", "elementalcraft:aircrystal"
  86.     },
  87.     ["elementalcraft:pedestal_fire"] = {
  88.         "elementalcraft:infuser", "elementalcraft:gems/fine_fire",
  89.         "elementalcraft:swift_alloy_ingot", "elementalcraft:whiterock",
  90.         "elementalcraft:whiterock"
  91.     },
  92.     ["elementalcraft:pedestal_water"] = {
  93.         "elementalcraft:infuser", "elementalcraft:gems/fine_water",
  94.         "elementalcraft:swift_alloy_ingot", "elementalcraft:whiterock",
  95.         "elementalcraft:whiterock"
  96.     },
  97.     ["elementalcraft:pedestal_earth"] = {
  98.         "elementalcraft:infuser", "elementalcraft:gems/fine_earth",
  99.         "elementalcraft:swift_alloy_ingot", "elementalcraft:whiterock",
  100.         "elementalcraft:whiterock"
  101.     },
  102.     ["elementalcraft:pedestal_air"] = {
  103.         "elementalcraft:infuser", "elementalcraft:gems/fine_air",
  104.         "elementalcraft:swift_alloy_ingot", "elementalcraft:whiterock",
  105.         "elementalcraft:whiterock"
  106.     },
  107.     ["elementalcraft:fireite_ingot"] = {
  108.         "minecraft:netherite_ingot", "elementalcraft:swift_alloy_ingot",
  109.         "elementalcraft:purecrystal"
  110.     }
  111. }
  112.  
  113. local function possibleRecipes()
  114.     local inventory = getInventory()
  115.     local possible = {}
  116.     for result, recipe in pairs(RECIPES) do
  117.         local isPossible = true
  118.         for _, ingredient in ipairs(recipe) do
  119.             if not inventory[ingredient] then
  120.                 isPossible = false
  121.                 break
  122.             end
  123.         end
  124.         if isPossible then possible[result] = recipe end
  125.     end
  126.     return possible
  127. end
  128.  
  129. local function mainLoop()
  130.     if not binder then binder = peripheral.find("elementalcraft:binder") end
  131.  
  132.     local recipes = possibleRecipes()
  133.     if nKeys(recipes) > 0 then
  134.         for result, ingredients in pairs(recipes) do
  135.             logMsg("Crafting " .. result .. "...")
  136.             for _, ingredient in ipairs(ingredients) do
  137.                 logMsg("Adding " .. ingredient .. "...")
  138.                 while not selectItem(ingredient) do os.sleep(0.1) end
  139.                 turtle.drop(1) -- binder is in front of turtle
  140.             end
  141.             logMsg("Waiting for result...")
  142.             while not getItemInPeripheral(binder, result) do
  143.                 os.sleep(0.1)
  144.             end
  145.             logMsg("Produced result!")
  146.             while nKeys(binder.list()) > 0 do
  147.                 if not selectItemOrEmpty(result) then
  148.                     error("inventory full!")
  149.                 else
  150.                     turtle.suck(1) -- binder is in front of turtle
  151.                     while not turtle.dropUp(1) do -- output chest below
  152.                         os.sleep(0.1)
  153.                     end
  154.                 end
  155.             end
  156.             logMsg("Craft complete.")
  157.             break
  158.         end
  159.     end
  160.  
  161.     os.sleep(0.1)
  162. end
  163.  
  164. local function errorHandler(error)
  165.     if error == "Terminated" then
  166.         return true
  167.     else
  168.         logMsg("internal error: " .. error)
  169.         return false
  170.     end
  171. end
  172.  
  173. logMsg("Elemental binder crafter started up.")
  174. while true do
  175.     local _, shouldExit = xpcall(mainLoop, errorHandler)
  176.     if shouldExit then break end
  177.     -- mainLoop() -- for debugging
  178. end
  179.  
Add Comment
Please, Sign In to add comment