nO_0nE

Automated TreeFarmer for ComputerCraft

Nov 27th, 2012
1,172
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 16.04 KB | None | 0 0
  1. -- Lua script by nO_OnE
  2. -- V2.1.2_2
  3. -- This script was written to harvest a treefarm using a ComputerCraft-Miningturtle in Minecraft.
  4. -- For more information visit: http://www.computercraft.info/forums2/index.php?/topic/6518-13-14-automatic-tree-farm-with-config/
  5.  
  6.  
  7. -- DEFAULT SETTINGS SECTION
  8. local slotAmount = 16           -- 9 for the old turtles, 16 for CC 1.4 or above
  9. local chestOutput = true        -- true if you want the turtle to put all items in a chest instead of dropping them
  10. local saplingOffset = 2         -- 2 recommended (amount of blocks between two saplings)
  11. local wallOffset = 2            -- 2 recommended (amount of blocks between the saplings and the wall)
  12. local fullSaplings = false      -- true: wait for 64 Saplings, false: wait for the amount the treefarm could possibly have
  13. local throwSaplings = false     -- true: throw away unnecessary saplings (only if fullSaplings = false)
  14. local saplingMethod = "compare" -- "detect" or "compare" - compare works better but if you have 1.3 you should set it to detect to avoid bugs
  15. local sleepTime = 0             -- set if you wish to make a break between farming runs
  16. -- DEFAULT SETTINGS SECTION
  17.  
  18. local serverID, x, y            -- leave blank! (serverID will be declared later when the first server answer comes)
  19.  
  20. function writeSettings ( ) --> write the current (default) settings in the file farmer.cfg
  21.     local file = fs.open ("farmer.cfg", "w")
  22.     file.writeLine (slotAmount)
  23.     file.writeLine (chestOutput)
  24.     file.writeLine (saplingOffset)
  25.     file.writeLine (wallOffset)
  26.     file.writeLine (fullSaplings)
  27.     file.writeLine (throwSaplings)
  28.     file.writeLine (saplingMethod)
  29.     file.writeLine (xTrees)
  30.     file.writeLine (yTrees)
  31.     file.writeLine (sleepTime)
  32.     file.close ( )
  33. end
  34.  
  35. function readSettings ( ) --> replace the default values with the ones in the farmer.cfg
  36.     local file = fs.open ("farmer.cfg", "r")
  37.     slotAmount      = tonumber (file.readLine ( ))
  38.     chestOutput     = file.readLine ( ) == "true"
  39.     saplingOffset   = tonumber (file.readLine ( ))
  40.     wallOffset      = tonumber (file.readLine ( ))
  41.     fullSaplings    = file.readLine ( ) == "true"
  42.     throwSaplings   = file.readLine ( ) == "true"
  43.     saplingMethod   = file.readLine ( )
  44.     xTrees          = tonumber (file.readLine ( ))
  45.     yTrees          = tonumber (file.readLine ( ))
  46.     sleepTime       = tonumber (file.readLine ( ))
  47.     file.close ( )
  48. end
  49.  
  50. function forward (value) --> func to move a amount of blocks forward even when a entity or block is blocking the way
  51.     for i = 1, value do
  52.         local forw = false
  53.         while not forw do
  54.             forw = turtle.forward ( )
  55.             if not forw and turtle.detect ( ) then
  56.                 turtle.dig ( )
  57.             end
  58.         end
  59.     end
  60. end
  61.  
  62. function up (value) --> func to move up (see forward)
  63.     for i = 1, value do
  64.         local upp = false
  65.         while not upp do
  66.             upp = turtle.up ( )
  67.             if not upp and turtle.detectUp ( ) then
  68.                 turtle.digUp ( )
  69.             end
  70.         end
  71.     end
  72. end
  73.  
  74. function down (value) --> func to move down (see forward)
  75.     for i = 1, value do
  76.         dow = false
  77.         while not dow do
  78.             dow = turtle.down ( )
  79.             if not dow and turtle.detectDown ( ) then
  80.                 turtle.digDown ( )
  81.             end
  82.         end
  83.     end
  84. end
  85.  
  86. function drop (value) --> func to drop evrything but slot 1 and slot 2 (value 0) or unnecessary saplings (value 1)
  87.     if (value == 1) and (turtle.getItemCount (1) - (xTrees * yTrees) > 1) then
  88.         turtle.select (1)
  89.         if chestOutput then
  90.             turn ("back")
  91.             if turtle.detect ( ) then turtle.drop (turtle.getItemCount (1) - (xTrees * yTrees) - 1) end
  92.             turn ("back")
  93.         end
  94.         turtle.drop (turtle.getItemCount (1) - (xTrees * yTrees) - 1)
  95.     else
  96.         if chestOutput then
  97.             turn ("back")
  98.             if turtle.detect ( ) then
  99.                 for i = 3, slotAmount do
  100.                     turtle.select (i)
  101.                     if turtle.getItemCount (i) > 0 then turtle.drop ( ) end
  102.                 end
  103.             end
  104.             turn ("back")
  105.         end
  106.         for i = 3, slotAmount do
  107.             turtle.select (i)
  108.             if turtle.getItemCount (i) > 0 then turtle.drop ( ) end
  109.         end
  110.     end
  111. end
  112.  
  113. function turn (dir) --> easier turning func with a parameter or direction
  114.     if dir == "left" or dir == 0 then turtle.turnLeft()         -- "left" or 0 for left
  115.     elseif dir == "right" or dir == 1 then turtle.turnRight()   -- "right" or 1 for right
  116.     else turtle.turnLeft() turtle.turnLeft() end                -- everything else (I am using "back") for turning around
  117. end
  118.  
  119. function cutDown ( ) --> func to cut down a tree the turtle faces at height 2
  120.     turtle.select (3)
  121.     turtle.dig ( )
  122.     forward (1)
  123.     down (1)
  124.     turtle.select (2)
  125.     if not turtle.compareDown ( ) then
  126.         if turtle.detectDown ( ) then turtle.digDown ( ) end
  127.         turtle.placeDown ( )
  128.     end
  129.     up (1)
  130.     turtle.select (1)
  131.     turtle.placeDown ( )
  132.     turtle.select (3)
  133.     local height = 0
  134.     while turtle.compareUp ( ) do
  135.         up (1)
  136.         height = height + 1
  137.     end
  138.     down (height)
  139. end
  140.  
  141. function tree ( ) --> return true if turtle faces a tree
  142.     if turtle.getItemCount (3) > 0 then
  143.         turtle.select (3)
  144.         local re = turtle.compare ( )
  145.         return (re)
  146.     else
  147.         return (turtle.detect ( ))
  148.     end
  149. end
  150.  
  151. function farm ( ) --> doing a complete farming run
  152.     forward (1)
  153.     up (1)
  154.     turn ("right")
  155.     forward (wallOffset)
  156.     turn ("left")
  157.     forward (wallOffset - 1)
  158.     for j = 1, xTrees do
  159.         for i = 1, yTrees do
  160.             if i > 1 then
  161.                 forward (saplingOffset)
  162.             end
  163.             if tree ( ) then
  164.                 cutDown ( )
  165.             else
  166.                 forward (1)
  167.                 turtle.select (1)
  168.                 if (not turtle.detectDown ( ) and saplingMethod == "detect") or (not turtle.compareDown ( ) and saplingMethod == "compare") then
  169.                     down (1)
  170.                     turtle.select (2)
  171.                     if not turtle.compareDown ( ) then
  172.                         if turtle.detectDown ( ) then turtle.digDown ( ) end
  173.                         turtle.placeDown ( )
  174.                     end
  175.                     up (1)
  176.                     turtle.select (1)
  177.                     turtle.placeDown ( )
  178.                 end
  179.             end
  180.         end
  181.         if j < xTrees then
  182.             forward (1)
  183.             turn (j % 2)
  184.             forward (saplingOffset + 1)
  185.             turn (j % 2)
  186.         end
  187.     end
  188.     if xTrees % 2 == 1 then
  189.         turn ("right")
  190.         forward (1)
  191.         turn ("right")
  192.         forward ((yTrees - 1) * (saplingOffset + 1) + wallOffset)
  193.         turn ("right")
  194.         forward (1)
  195.     else
  196.         forward (wallOffset)
  197.         turn ("right")
  198.     end
  199.     forward (((xTrees - 1) * (saplingOffset + 1)) + wallOffset)
  200.     down (1)
  201.     turn ("left")
  202.     forward (1)
  203.     turn ("back")
  204. end
  205.  
  206. function waitForSaplings ( ) --> returning the amount of saplings that are needed to start farming
  207.     if not fullSaplings then return (xTrees * yTrees - turtle.getItemCount (1) + 1)
  208.     else return (64 - turtle.getItemCount (1)) end
  209.     sleep (1)
  210. end
  211.  
  212. function handleRednet (message) --> processing a command received from rednet
  213.     local nBegin, nBeginn, nEnd, nEndd, command, attrib, n
  214.     nBegin, nEnd = string.find (message, " ")
  215.     command = message
  216.     attrib = { }
  217.     n = 0
  218.     if nBegin ~= nil then
  219.         command = string.sub (message, 1, nBegin - 1)
  220.         repeat
  221.             if n ~= 0 then nBegin, nEnd = string.find (message, " ", nBegin + 1) end
  222.             nBeginn, nEndd = string.find (message, " ", nBegin + 1)
  223.             n = n + 1
  224.             if nBeginn == nil then attrib[n] = string.sub (message, nBegin + 1)
  225.             else attrib[n] = string.sub (message, nBegin + 1, nBeginn - 1) end
  226.         until nBeginn == nil
  227.     end
  228.     if command == "stop" then
  229.         print ("\n")
  230.         error ("got stop command")
  231.     elseif command == "shutdown" then
  232.         print ("\n\nshutting down due to 'shutdown' command...")
  233.         sleep (1)
  234.         os.shutdown ( )
  235.     elseif command == "reboot" then
  236.         print ("\n\nrebooting due to 'reboot' command...")
  237.         sleep (1)
  238.         os.reboot ( )
  239.     elseif command == "change" then
  240.         if attrib[2] ~= nil then write ("\nchanging '"..attrib[1].."' to '"..attrib[2].."'...")
  241.         else  write ("\nchanging '"..attrib[1].."' to '(empty)'...") end
  242.         readSettings ( )
  243.         if attrib[1] == "xTrees" then
  244.             xTrees = tonumber (attrib[2])
  245.         elseif attrib[1] == "yTrees" then
  246.             yTrees = tonumber (attrib[2])
  247.         elseif attrib[1] == "slotAmount" then
  248.             slotAmount = tonumber (attrib[2])
  249.         elseif attrib[1] == "saplingOffset" then
  250.             saplingOffset = tonumber (attrib[2])
  251.         elseif attrib[1] == "wallOffset" then
  252.             wallOffset = tonumber (attrib[2])
  253.         elseif attrib[1] == "saplingMethod" then
  254.             saplingMethod = attrib[2]
  255.         elseif attrib[1] == "throwSaplings" then
  256.             throwSaplings = attrib[2] == "true"
  257.         elseif attrib[1] == "fullSaplings" then
  258.             fullSaplings = attrib[2] == "true"
  259.         elseif attrib[1] == "chestOutput" then
  260.             chestOutput = attrib[2] == "true"
  261.         elseif attrib[1] == "sleepTime" then
  262.             sleepTime = tonumber (attrib[2])
  263.         else
  264.             write ("\n"..attrib[1].." is no valid parameter!")
  265.         end
  266.         writeSettings ( )
  267.     elseif command == "startup" then
  268.         if attrib[1] == nil and fs.exists ("startup") then
  269.             fs.delete ("startup")
  270.         elseif attrib[1] ~= nil then
  271.             file = fs.open ("startup", "w")
  272.             if attrib[2] == nil then
  273.                 file.write ("shell.run (\""..attrib[1].."\")")
  274.             else
  275.                 str = "shell.run (\""
  276.                 for _, i in ipairs (attrib) do
  277.                     str = str..i.."\", \""
  278.                 end
  279.                 str = string.sub (str, 1, string.len (str) - 3)..")"
  280.                 file.write (str)
  281.             end
  282.             file.close ( )
  283.         end
  284.     end
  285. end
  286.  
  287. function getRednet ( ) --> receiving all rednet commands which are in queue for this turtle if available
  288.     if serverID == nil then rednet.broadcast ("pull")
  289.     else rednet.send (serverID, "pull") end
  290.     repeat
  291.         serverID, message = rednet.receive (0.5)
  292.     until message ~= "pull" -- avoiding receiving commands from other turtles pulling
  293.                             -- NOTE: this wont happen often because the first server answer will set a turtle to use the ID from this server as its sending ID
  294.     while serverID ~= nil and message ~= "end" do
  295.         handleRednet (message)
  296.         rednet.send (serverID, "pull")
  297.         repeat
  298.             serverID, message = rednet.receive (0.5)
  299.         until message ~= "pull"
  300.     end
  301. end
  302.  
  303. function headline ( )
  304.     x, y = term.getCursorPos ( )
  305.     term.setCursorPos (1, 2)
  306.     term.clearLine ( )
  307.     term.setCursorPos (1, 1)
  308.     term.clearLine ( )
  309.     if turtle then
  310.         for i = 1, math.floor ((term.getSize ( ) - (25 + string.len (os.getComputerID ( )))) / 2) do write (" ") end -- looks more complicated than it is, only writes n times (" ") while n is the amount of empty digits after the headline devided by 2
  311.         print ("nO_OnEs Tree Farmer [ID "..os.getComputerID ( ).."]")
  312.         for i = 1, term.getSize ( ) do term.write ("-") end
  313.     else
  314.         for i = 1, math.floor ((term.getSize ( ) - 40) / 2) do write (" ") end -- looks more complicated than it is, only writes n times (" ") while n is the amount of empty digits after the headline devided by 2
  315.         print ("[Automatic Tree Farmer] Server Interface")
  316.         for i = 1, term.getSize ( ) do term.write ("-") end
  317.     end
  318.     term.setCursorPos (x, y)
  319. end
  320.  
  321. function done ( ) --> writing '- done' at the end of the current line
  322.     x, y = term.getCursorPos ( )
  323.     if x > (term.getSize ( ) - 6) then y = y + 1 end -- if the current line is full yet
  324.     term.setCursorPos (term.getSize ( ) - 5, y)
  325.     term.write ("- done")
  326.     write ("\n")
  327.     headline ( )
  328. end
  329.  
  330. function beServer ( )
  331.     rednet.open ("left")
  332.     rednet.open ("right")
  333.     rednet.open ("top")
  334.     headline ( )
  335.     write ("\n\n")
  336.     while true do
  337.         headline ( )
  338.         x, y = term.getCursorPos ( )
  339.         term.clearLine ( )
  340.         term.setCursorPos (1, y)
  341.         write ("Press any key")
  342.         event, one, two = os.pullEvent ( )
  343.         if event == "rednet_message" and two == "pull" then -- if 'pull' command received
  344.             x, y = term.getCursorPos ( )
  345.             term.clearLine ( )
  346.             term.setCursorPos (1, y)
  347.             if not fs.exists ("turtle "..one) then
  348.                 fileWrite = fs.open ("turtle "..one, "w")
  349.                 fileWrite.writeLine ("end")
  350.                 fileWrite.close ( )
  351.                 print ("new turtle registered (ID "..one..")")
  352.             end
  353.             fileRead = fs.open ("turtle "..one, "r")
  354.             i = 0
  355.             local text = { }
  356.             repeat
  357.                 i = i + 1
  358.                 line = fileRead.readLine ( )
  359.                 text[i] = line
  360.             until text[i] == nil
  361.             fileRead.close ( )
  362.             rednet.send (one, text[1])
  363.             fileWrite = fs.open ("turtle "..one, "w")
  364.             i = 2
  365.             while text[i] ~= "end" and text[i] ~= nil do
  366.                 fileWrite.writeLine (text[i])
  367.                 i = i + 1
  368.             end
  369.             fileWrite.writeLine ("end")
  370.             fileWrite.close ( )
  371.             if text[1] ~= "end" then print ("sent '"..text[1].."' to turtle "..one)
  372.             else print ("no commands in queue for turtle "..one) end
  373.         elseif event == "char" then -- if key pressed
  374.             local turtles = { }
  375.             n = 1
  376.             for _, i in ipairs (fs.list ("")) do
  377.                 if string.sub (i, 1, 7) == "turtle " and tonumber (string.sub (i, 8)) ~= nil then
  378.                     turtles[n] = i
  379.                     n = n + 1
  380.                 end
  381.             end
  382.             if turtles[1] ~= nil then
  383.                 term.clear ( )
  384.                 term.setCursorPos (1, 1)
  385.                 headline ( )
  386.                 write ("\n\n")
  387.                 print ("available turtles:")
  388.                 for _, i in ipairs (turtles) do
  389.                     print ("- "..i)
  390.                 end
  391.                 print ("")
  392.                 print ("please enter the number of the turtle you want to send a command to or 'all' if you want to message every turtle (exit to abort)")
  393.                 number = read ( )
  394.                 while not (tonumber (number) ~= nil or number == "all" and tonumber (number) == nil) and number ~= "exit" do
  395.                     print ("incorrect number")
  396.                     headline ( )
  397.                     number = read ( )
  398.                 end
  399.                 if number ~= "exit" then
  400.                     print ("command: (type help to see command-list or exit to abort)")
  401.                     headline ( )
  402.                     message = read ( )
  403.                     while message == "help" and message ~= "exit" do
  404.                         term.clear ( )
  405.                         term.setCursorPos (1, 1)
  406.                         write ("\n\n")
  407.                         headline ( )
  408.                         print ("available commands: [attribute] (optional)")
  409.                         print ("- change [xTrees | yTrees | saplingOffset | wallOffset | saplingMethod | fullSaplings | throwSaplings | sleepTime | slotAmount | chestOutput] [value]")
  410.                         print ("- stop")
  411.                         print ("- shutdown")
  412.                         print ("- reboot")
  413.                         print ("- startup (command) (atrribute1) (...)\n  *leave command blank for no startup command")
  414.                         print ("\ncommand: (type help to see command-list or exit to abort)")
  415.                         message = read ( )
  416.                     end
  417.                     if message ~= "exit" then
  418.                         if number == "all" then
  419.                             for _, i in ipairs (turtles) do
  420.                                 fileNew = fs.open (i, "r")
  421.                                 file = fileNew.readAll ( )
  422.                                 fileNew.close ( )
  423.                                 fileNew = fs.open (i, "w")
  424.                                 fileNew.writeLine (message)
  425.                                 fileNew.write (file)
  426.                                 fileNew.close ( )
  427.                             end
  428.                         else   
  429.                             fileNew = fs.open ("turtle "..number, "r")
  430.                             file = fileNew.readAll ( )
  431.                             fileNew.close ( )
  432.                             fileNew = fs.open ("turtle "..number, "w")
  433.                             fileNew.writeLine (message)
  434.                             fileNew.write (file)
  435.                             fileNew.close ( )
  436.                         end
  437.                     end
  438.                 end
  439.                 term.clear ( )
  440.                 term.setCursorPos (1, 2)
  441.             else
  442.                 x, y = term.getCursorPos ( )
  443.                 term.clearLine ( )
  444.                 term.setCursorPos (1, y)
  445.                 print ("No turtles available at the moment!")
  446.             end
  447.         end
  448.     end
  449. end
  450.  
  451. term.clear ( )
  452. term.setCursorPos (1, 1)
  453.  
  454. if not turtle then beServer ( ) end
  455.  
  456. while not fs.exists ("farmer.cfg") do --> writing default settings (while asking for the size of the Farm)
  457.     term.clear ( )
  458.     term.setCursorPos (1, 1)
  459.     textutils.slowPrint ("No configuration file found.")
  460.     sleep (0.25)
  461.     print ("")
  462.     print ("example with xTrees 4 and yTrees 3")
  463.     print ("+  +  +  + <-- sapling")
  464.     print ("+  +  +  +")
  465.     print ("+  +  +  +")
  466.     print ("o <-- logger facing up")
  467.     print ("")
  468.     print ("How many trees horizontally?\n(xTrees)")
  469.     xTrees = read ( )
  470.     print ("How many trees vertically?\n(yTrees)")
  471.     yTrees = read ( )
  472.     textutils.slowPrint ("Writing configuration-file")
  473.     print("")
  474.     writeSettings ( )
  475.     if fs.exists ("farmer.cfg") then
  476.         textutils.slowPrint ("farmer.cfg found, success!")
  477.     end
  478.     sleep (0.5)
  479.     term.clear ( )
  480.     term.setCursorPos (1, 1)
  481. end
  482.  
  483. rednet.open ("right")
  484. write ("\n\n")
  485. headline ( )
  486.  
  487. while true do
  488.     write ("getting rednet commands...")
  489.     getRednet ( )
  490.     done ( )
  491.     write ("reading config...")
  492.     readSettings ( )
  493.     done ( )
  494.     write ("dropping Items...")
  495.     if not fullSaplings and throwSaplings then drop (1) end
  496.     drop (0)
  497.     done ( )
  498.     repeat
  499.         x, y = term.getCursorPos ( )
  500.         x = 1
  501.         term.setCursorPos (x, y)
  502.         saplings = waitForSaplings ( )
  503.         if saplings == 1 then write ("1 sapling remaining ...")
  504.         elseif saplings < 1 then write ("0 saplings remaining ...")
  505.         else write (saplings.." saplings remaining ...") end
  506.         sleep (1)
  507.     until saplings < 1
  508.     done ( )
  509.     for i = 0, sleepTime do
  510.         x, y = term.getCursorPos ( )
  511.         x = 1
  512.         term.setCursorPos (x, y)
  513.         write ("sleeping... ("..sleepTime-i.."sec left)")
  514.         sleep (1)
  515.     end
  516.     done ( )
  517.     write ("farming "..xTrees.." x "..yTrees.."...")
  518.     farm ( )
  519.     done ( )
  520. end
  521.  
  522. -- Note: [removed]
Advertisement
Add Comment
Please, Sign In to add comment