meigrafd

Auto Crafty Turtle (v0.3)

Aug 28th, 2015
104
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 8.89 KB | None | 0 0
  1. --[[
  2.  
  3.  v0.3 by meigrafd @ 28.08.2015
  4.  
  5.  Requires:
  6.    ComputerCraft >=1.4
  7.  
  8.  A Turtle have 16 Slots. For crafting the first 3 rows and slots are used and must match an valid recipe. All other Slots must be free!
  9.  Place a valid recipe into Turtle before first Script Start up.
  10.  Place Chests around the Turtle as Input and Drop.. Only use one Chest for one Type of Item!
  11.  Script will inspect each Side and trys to detect the Item in each Chest.
  12.  After that it saves all data for future startups and starts auto-crafting.
  13.  For a later use of another recipe simple delete the directory 'recipe'.
  14.  
  15. --]]
  16.  
  17.  
  18. ---[[ CONFIG - START ]]
  19.  
  20.  
  21. -- Chest Side for crafted item. Only valid sides: top, bottom, left, right, front, back
  22. -- NOTE: Fastest will be "top", "bottom" or "front". For all other it must turn around..
  23. -- BTW: Put the most needed Items in the 'fastest' chest to speedup crafting :)
  24. local OutDirection = "front"
  25.  
  26. -- Use Redstone signal to turn crafting on/off ?
  27. local ControlSignal = true
  28.  
  29. -- Redstone signal Side
  30. -- NOTE: "left" doesnt work.
  31. local ControlSide = "right"
  32.  
  33.  
  34. ---[[ CONFIG - END ]]
  35.  
  36.  
  37. ---[[ functions ]]
  38.  
  39.  
  40. -- http://stackoverflow.com/questions/1426954/split-string-in-lua
  41. function split(pString, pPattern)
  42.     local Table = {}  -- NOTE: use {n = 0} in Lua-5.0
  43.     local fpat = "(.-)" .. pPattern
  44.     local last_end = 1
  45.     local s, e, cap = pString:find(fpat, 1)
  46.     while s do
  47.         if s ~= 1 or cap ~= "" then
  48.             table.insert(Table, cap)
  49.         end
  50.         last_end = e+1
  51.         s, e, cap = pString:find(fpat, last_end)
  52.     end
  53.     if last_end <= #pString then
  54.         cap = pString:sub(last_end)
  55.         table.insert(Table, cap)
  56.     end
  57.     return Table
  58. end
  59.  
  60. function stringMatch(text, find)
  61.     if string.find(string.lower(text), string.lower(find)) then
  62.         return true
  63.     else
  64.         return false
  65.     end
  66. end
  67.  
  68. function lappend(list, delimiter, value)
  69.     if list == '' then
  70.         local list = value
  71.     else
  72.         local list = list..delimiter..value
  73.     end
  74.     return list
  75. end
  76.  
  77.  
  78. local turn = function(side)
  79.     if side == "left" then
  80.         turtle.turnLeft()
  81.     elseif side == "right" then
  82.         turtle.turnRight()
  83.     elseif side == "front" then
  84.         turtle.turnRight()
  85.         turtle.turnRight()
  86.     elseif side == "back" then
  87.         turtle.turnLeft()
  88.         turtle.turnLeft()
  89.     end
  90. end
  91.  
  92. local suck = function(direction, amount)
  93.     amount = amount or 1
  94.     s = {
  95.         ["top"] = function() turtle.suckUp(amount); end,
  96.         ["bottom"] = function() turtle.suckDown(amount); end,
  97.         ["front"] = function() turtle.suck(amount); end,
  98.         ["left"] = function() turn("left"); turtle.suck(amount); turn("right"); end,
  99.         ["right"] = function() turn("right"); turtle.suck(amount); turn("left"); end,
  100.         ["back"] = function() turn("back"); turtle.suck(amount); turn("front"); end
  101.     }
  102.     s[direction]()
  103. end
  104.  
  105. local drop = function(direction, amount)
  106.     amount = amount or 1
  107.     d = {
  108.         ["top"] = function() turtle.dropUp(amount); end,
  109.         ["bottom"] = function() turtle.dropDown(amount); end,
  110.         ["front"] = function() turtle.drop(amount); end,
  111.         ["left"] = function() turn("left"); turtle.drop(amount); turn("right"); end,
  112.         ["right"] = function() turn("right"); turtle.drop(amount); turn("left"); end,
  113.         ["back"] = function() turn("back"); turtle.drop(amount); turn("front"); end
  114.     }
  115.     d[direction]()
  116. end
  117.  
  118. local craft = function()
  119.     turtle.select(OutSlot)
  120.     turtle.craft()
  121.     drop(OutDirection, turtle.getItemCount(OutSlot))
  122.     Count = Count + 1
  123.     print("crafted: "..Count)
  124. end
  125.  
  126. local saveRecipe = function()
  127.     print("Trying to get Recipe..")
  128.     for i=1, #InSlots do
  129.         local data = turtle.getItemDetail(InSlots[i])
  130.         if data then
  131.             local n = data.name
  132.             local d = data.damage
  133.             local c = data.count
  134.             --maybe same name but hopeful different damage
  135.             print(InSlots[i]..": "..n.." -> damage: "..d)
  136.             RecipeItemName[InSlots[i]] = n
  137.             RecipeItemDamage[InSlots[i]] = d
  138.             RecipeItemCount[InSlots[i]] = c
  139.  
  140.             -- create own dir for each slot and save data..
  141.             if not fs.isDir("recipe/"..InSlots[i]) then
  142.                 fs.makeDir("recipe/"..InSlots[i])
  143.             end
  144.  
  145.             if fs.exists("recipe/"..InSlots[i].."/name") then
  146.                 fs.delete("recipe/"..InSlots[i].."/name")
  147.             end
  148.             local fileObject = fs.open("recipe/"..InSlots[i].."/name", "w")
  149.             fileObject.write(tostring(n))
  150.             fileObject.close()
  151.  
  152.             if fs.exists("recipe/"..InSlots[i].."/damage") then
  153.                 fs.delete("recipe/"..InSlots[i].."/damage")
  154.             end
  155.             local fileObject = fs.open("recipe/"..InSlots[i].."/damage", "w")
  156.             fileObject.write(tostring(d))
  157.             fileObject.close()
  158.  
  159.             if fs.exists("recipe/"..InSlots[i].."/count") then
  160.                 fs.delete("recipe/"..InSlots[i].."/count")
  161.             end
  162.             local fileObject = fs.open("recipe/"..InSlots[i].."/count", "w")
  163.             fileObject.write(tostring(c))
  164.             fileObject.close()
  165.         end
  166.     end
  167. end
  168.  
  169.  
  170.  
  171. --[[ Internal values ]]
  172.  
  173.  
  174. -- Mapping of slots in the turtles inventory used for recipe.
  175. InSlots = {1,2,3, 5,6,7, 9,10,11}
  176. OutSlot = 16
  177.  
  178. ChestItem = {}
  179. RecipeItemName = {}
  180. RecipeItemDamage = {}
  181. RecipeItemCount = {}
  182.  
  183. Count = 0
  184.  
  185.  
  186. --[[ Main program ]]
  187.  
  188.  
  189. if not fs.isDir("recipe") then
  190.     -- Verify valid recipe
  191.     if turtle.craft(0) == false then
  192.         print("ERROR: Invalid recipe! Please set up correctly.")
  193.         error()
  194.     end
  195.     fs.makeDir("recipe")
  196.     saveRecipe()
  197.     -- craft recipe once to get all slots free
  198.     craft()
  199. else
  200.     -- get recipe out saved data files for each slot..
  201.     print("Trying to get saved Recipe..")
  202.     local flistTable = fs.find("/recipe/*/name")
  203.     for _,file in pairs(flistTable) do
  204.         local directory = fs.getDir(file)
  205.         local tmp = split(directory,"/")
  206.         local slot = tmp[2]
  207.         local fileObject = fs.open(directory.."/name", "r")
  208.         local n = fileObject.readLine()
  209.         fileObject.close()
  210.         local fileObject = fs.open(directory.."/damage", "r")
  211.         local d = fileObject.readLine()
  212.         fileObject.close()
  213.         local fileObject = fs.open(directory.."/count", "r")
  214.         local c = fileObject.readLine()
  215.         fileObject.close()
  216.         print(slot..": "..n.." -> damage: "..d)
  217.         RecipeItemName[slot] = n
  218.         RecipeItemDamage[slot] = d
  219.         RecipeItemCount[slot] = c
  220.     end
  221. end
  222.  
  223. -- Verify needed items for recipe with items in each chest..
  224. print("Trying to get Sides for each Item..")
  225. turtle.select(OutSlot)
  226. for i,side in pairs(rs.getSides()) do
  227.     if (side ~= OutDirection) and (peripheral.isPresent(side)) then
  228.         suck(side)
  229.         for slot in pairs(RecipeItemName) do
  230.             local data = turtle.getItemDetail(OutSlot)
  231.             if data then
  232.                 local n = data.name
  233.                 local d = data.damage
  234.                 local c = data.count
  235.                 --maybe same name but hopeful also same damage -> same item
  236.                 if (stringMatch(RecipeItemName[slot], n)) and (stringMatch(RecipeItemDamage[slot], d)) then
  237.                     ChestItem[slot] = side
  238.                     print("for slot "..slot..": "..side..": "..n)
  239.                 end
  240.             end
  241.         end
  242.         drop(side)
  243.     end
  244. end
  245.  
  246. -- FIXME: Sort by value, not key (table[slot]=item -> sort by item to suck all same items from a chest (faster))
  247. table.sort(RecipeItemName)
  248.  
  249.  
  250. -- main loop
  251. print("Setup complete.")
  252.  
  253. Err0r = false
  254. while true do
  255.     -- check if redstone signal required and one..
  256.     if (ControlSignal == true) then
  257.         if (rs.getInput(ControlSide) == true) then
  258.             goForIt = true
  259.         else
  260.             goForIt = false
  261.         end
  262.     else
  263.         goForIt = true
  264.     end
  265.  
  266.     if (goForIt == true) then
  267.         -- suck in all the required slots
  268.         for slot in pairs(RecipeItemName) do
  269.             turtle.select(tonumber(slot))
  270.             while turtle.getItemCount(slot) == 0 do
  271.                 suck(ChestItem[slot], tonumber(RecipeItemCount[slot]))
  272.             end
  273.         end
  274.         if turtle.craft(0) == false then
  275.             drop(OutDirection, turtle.getItemCount(OutSlot))
  276.             if Err0r == false then
  277.                 print("ERROR: Invalid recipe! Please set up correctly.")
  278.                 Err0r = true
  279.                 -- clear/drop all slots
  280.                 for i=1,16 do
  281.                     turtle.select(i)
  282.                     drop(OutDirection, turtle.getItemCount(i))
  283.                 end
  284.             end
  285.         else
  286.             if Err0r == true then Err0r = false end
  287.             craft()
  288.         end
  289.     else
  290.         os.sleep(1)
  291.     end
  292. end
  293.  
  294.  
  295. --
  296. -- EOF
  297. --
Add Comment
Please, Sign In to add comment