Not a member of Pastebin yet?
                        Sign Up,
                        it unlocks many cool features!                    
                - -- Lua script by nO_OnE
 - -- V2.1.2_2
 - -- This script was written to harvest a treefarm using a ComputerCraft-Miningturtle in Minecraft.
 - -- For more information visit: http://www.computercraft.info/forums2/index.php?/topic/6518-13-14-automatic-tree-farm-with-config/
 - -- DEFAULT SETTINGS SECTION
 - local slotAmount = 16 -- 9 for the old turtles, 16 for CC 1.4 or above
 - local chestOutput = true -- true if you want the turtle to put all items in a chest instead of dropping them
 - local saplingOffset = 2 -- 2 recommended (amount of blocks between two saplings)
 - local wallOffset = 2 -- 2 recommended (amount of blocks between the saplings and the wall)
 - local fullSaplings = false -- true: wait for 64 Saplings, false: wait for the amount the treefarm could possibly have
 - local throwSaplings = false -- true: throw away unnecessary saplings (only if fullSaplings = false)
 - local saplingMethod = "compare" -- "detect" or "compare" - compare works better but if you have 1.3 you should set it to detect to avoid bugs
 - local sleepTime = 0 -- set if you wish to make a break between farming runs
 - -- DEFAULT SETTINGS SECTION
 - local serverID, x, y -- leave blank! (serverID will be declared later when the first server answer comes)
 - function writeSettings ( ) --> write the current (default) settings in the file farmer.cfg
 - local file = fs.open ("farmer.cfg", "w")
 - file.writeLine (slotAmount)
 - file.writeLine (chestOutput)
 - file.writeLine (saplingOffset)
 - file.writeLine (wallOffset)
 - file.writeLine (fullSaplings)
 - file.writeLine (throwSaplings)
 - file.writeLine (saplingMethod)
 - file.writeLine (xTrees)
 - file.writeLine (yTrees)
 - file.writeLine (sleepTime)
 - file.close ( )
 - end
 - function readSettings ( ) --> replace the default values with the ones in the farmer.cfg
 - local file = fs.open ("farmer.cfg", "r")
 - slotAmount = tonumber (file.readLine ( ))
 - chestOutput = file.readLine ( ) == "true"
 - saplingOffset = tonumber (file.readLine ( ))
 - wallOffset = tonumber (file.readLine ( ))
 - fullSaplings = file.readLine ( ) == "true"
 - throwSaplings = file.readLine ( ) == "true"
 - saplingMethod = file.readLine ( )
 - xTrees = tonumber (file.readLine ( ))
 - yTrees = tonumber (file.readLine ( ))
 - sleepTime = tonumber (file.readLine ( ))
 - file.close ( )
 - end
 - function forward (value) --> func to move a amount of blocks forward even when a entity or block is blocking the way
 - for i = 1, value do
 - local forw = false
 - while not forw do
 - forw = turtle.forward ( )
 - if not forw and turtle.detect ( ) then
 - turtle.dig ( )
 - end
 - end
 - end
 - end
 - function up (value) --> func to move up (see forward)
 - for i = 1, value do
 - local upp = false
 - while not upp do
 - upp = turtle.up ( )
 - if not upp and turtle.detectUp ( ) then
 - turtle.digUp ( )
 - end
 - end
 - end
 - end
 - function down (value) --> func to move down (see forward)
 - for i = 1, value do
 - dow = false
 - while not dow do
 - dow = turtle.down ( )
 - if not dow and turtle.detectDown ( ) then
 - turtle.digDown ( )
 - end
 - end
 - end
 - end
 - function drop (value) --> func to drop evrything but slot 1 and slot 2 (value 0) or unnecessary saplings (value 1)
 - if (value == 1) and (turtle.getItemCount (1) - (xTrees * yTrees) > 1) then
 - turtle.select (1)
 - if chestOutput then
 - turn ("back")
 - if turtle.detect ( ) then turtle.drop (turtle.getItemCount (1) - (xTrees * yTrees) - 1) end
 - turn ("back")
 - end
 - turtle.drop (turtle.getItemCount (1) - (xTrees * yTrees) - 1)
 - else
 - if chestOutput then
 - turn ("back")
 - if turtle.detect ( ) then
 - for i = 3, slotAmount do
 - turtle.select (i)
 - if turtle.getItemCount (i) > 0 then turtle.drop ( ) end
 - end
 - end
 - turn ("back")
 - end
 - for i = 3, slotAmount do
 - turtle.select (i)
 - if turtle.getItemCount (i) > 0 then turtle.drop ( ) end
 - end
 - end
 - end
 - function turn (dir) --> easier turning func with a parameter or direction
 - if dir == "left" or dir == 0 then turtle.turnLeft() -- "left" or 0 for left
 - elseif dir == "right" or dir == 1 then turtle.turnRight() -- "right" or 1 for right
 - else turtle.turnLeft() turtle.turnLeft() end -- everything else (I am using "back") for turning around
 - end
 - function cutDown ( ) --> func to cut down a tree the turtle faces at height 2
 - turtle.select (3)
 - turtle.dig ( )
 - forward (1)
 - down (1)
 - turtle.select (2)
 - if not turtle.compareDown ( ) then
 - if turtle.detectDown ( ) then turtle.digDown ( ) end
 - turtle.placeDown ( )
 - end
 - up (1)
 - turtle.select (1)
 - turtle.placeDown ( )
 - turtle.select (3)
 - local height = 0
 - while turtle.compareUp ( ) do
 - up (1)
 - height = height + 1
 - end
 - down (height)
 - end
 - function tree ( ) --> return true if turtle faces a tree
 - if turtle.getItemCount (3) > 0 then
 - turtle.select (3)
 - local re = turtle.compare ( )
 - return (re)
 - else
 - return (turtle.detect ( ))
 - end
 - end
 - function farm ( ) --> doing a complete farming run
 - forward (1)
 - up (1)
 - turn ("right")
 - forward (wallOffset)
 - turn ("left")
 - forward (wallOffset - 1)
 - for j = 1, xTrees do
 - for i = 1, yTrees do
 - if i > 1 then
 - forward (saplingOffset)
 - end
 - if tree ( ) then
 - cutDown ( )
 - else
 - forward (1)
 - turtle.select (1)
 - if (not turtle.detectDown ( ) and saplingMethod == "detect") or (not turtle.compareDown ( ) and saplingMethod == "compare") then
 - down (1)
 - turtle.select (2)
 - if not turtle.compareDown ( ) then
 - if turtle.detectDown ( ) then turtle.digDown ( ) end
 - turtle.placeDown ( )
 - end
 - up (1)
 - turtle.select (1)
 - turtle.placeDown ( )
 - end
 - end
 - end
 - if j < xTrees then
 - forward (1)
 - turn (j % 2)
 - forward (saplingOffset + 1)
 - turn (j % 2)
 - end
 - end
 - if xTrees % 2 == 1 then
 - turn ("right")
 - forward (1)
 - turn ("right")
 - forward ((yTrees - 1) * (saplingOffset + 1) + wallOffset)
 - turn ("right")
 - forward (1)
 - else
 - forward (wallOffset)
 - turn ("right")
 - end
 - forward (((xTrees - 1) * (saplingOffset + 1)) + wallOffset)
 - down (1)
 - turn ("left")
 - forward (1)
 - turn ("back")
 - end
 - function waitForSaplings ( ) --> returning the amount of saplings that are needed to start farming
 - if not fullSaplings then return (xTrees * yTrees - turtle.getItemCount (1) + 1)
 - else return (64 - turtle.getItemCount (1)) end
 - sleep (1)
 - end
 - function handleRednet (message) --> processing a command received from rednet
 - local nBegin, nBeginn, nEnd, nEndd, command, attrib, n
 - nBegin, nEnd = string.find (message, " ")
 - command = message
 - attrib = { }
 - n = 0
 - if nBegin ~= nil then
 - command = string.sub (message, 1, nBegin - 1)
 - repeat
 - if n ~= 0 then nBegin, nEnd = string.find (message, " ", nBegin + 1) end
 - nBeginn, nEndd = string.find (message, " ", nBegin + 1)
 - n = n + 1
 - if nBeginn == nil then attrib[n] = string.sub (message, nBegin + 1)
 - else attrib[n] = string.sub (message, nBegin + 1, nBeginn - 1) end
 - until nBeginn == nil
 - end
 - if command == "stop" then
 - print ("\n")
 - error ("got stop command")
 - elseif command == "shutdown" then
 - print ("\n\nshutting down due to 'shutdown' command...")
 - sleep (1)
 - os.shutdown ( )
 - elseif command == "reboot" then
 - print ("\n\nrebooting due to 'reboot' command...")
 - sleep (1)
 - os.reboot ( )
 - elseif command == "change" then
 - if attrib[2] ~= nil then write ("\nchanging '"..attrib[1].."' to '"..attrib[2].."'...")
 - else write ("\nchanging '"..attrib[1].."' to '(empty)'...") end
 - readSettings ( )
 - if attrib[1] == "xTrees" then
 - xTrees = tonumber (attrib[2])
 - elseif attrib[1] == "yTrees" then
 - yTrees = tonumber (attrib[2])
 - elseif attrib[1] == "slotAmount" then
 - slotAmount = tonumber (attrib[2])
 - elseif attrib[1] == "saplingOffset" then
 - saplingOffset = tonumber (attrib[2])
 - elseif attrib[1] == "wallOffset" then
 - wallOffset = tonumber (attrib[2])
 - elseif attrib[1] == "saplingMethod" then
 - saplingMethod = attrib[2]
 - elseif attrib[1] == "throwSaplings" then
 - throwSaplings = attrib[2] == "true"
 - elseif attrib[1] == "fullSaplings" then
 - fullSaplings = attrib[2] == "true"
 - elseif attrib[1] == "chestOutput" then
 - chestOutput = attrib[2] == "true"
 - elseif attrib[1] == "sleepTime" then
 - sleepTime = tonumber (attrib[2])
 - else
 - write ("\n"..attrib[1].." is no valid parameter!")
 - end
 - writeSettings ( )
 - elseif command == "startup" then
 - if attrib[1] == nil and fs.exists ("startup") then
 - fs.delete ("startup")
 - elseif attrib[1] ~= nil then
 - file = fs.open ("startup", "w")
 - if attrib[2] == nil then
 - file.write ("shell.run (\""..attrib[1].."\")")
 - else
 - str = "shell.run (\""
 - for _, i in ipairs (attrib) do
 - str = str..i.."\", \""
 - end
 - str = string.sub (str, 1, string.len (str) - 3)..")"
 - file.write (str)
 - end
 - file.close ( )
 - end
 - end
 - end
 - function getRednet ( ) --> receiving all rednet commands which are in queue for this turtle if available
 - if serverID == nil then rednet.broadcast ("pull")
 - else rednet.send (serverID, "pull") end
 - repeat
 - serverID, message = rednet.receive (0.5)
 - until message ~= "pull" -- avoiding receiving commands from other turtles pulling
 - -- 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
 - while serverID ~= nil and message ~= "end" do
 - handleRednet (message)
 - rednet.send (serverID, "pull")
 - repeat
 - serverID, message = rednet.receive (0.5)
 - until message ~= "pull"
 - end
 - end
 - function headline ( )
 - x, y = term.getCursorPos ( )
 - term.setCursorPos (1, 2)
 - term.clearLine ( )
 - term.setCursorPos (1, 1)
 - term.clearLine ( )
 - if turtle then
 - 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
 - print ("nO_OnEs Tree Farmer [ID "..os.getComputerID ( ).."]")
 - for i = 1, term.getSize ( ) do term.write ("-") end
 - else
 - 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
 - print ("[Automatic Tree Farmer] Server Interface")
 - for i = 1, term.getSize ( ) do term.write ("-") end
 - end
 - term.setCursorPos (x, y)
 - end
 - function done ( ) --> writing '- done' at the end of the current line
 - x, y = term.getCursorPos ( )
 - if x > (term.getSize ( ) - 6) then y = y + 1 end -- if the current line is full yet
 - term.setCursorPos (term.getSize ( ) - 5, y)
 - term.write ("- done")
 - write ("\n")
 - headline ( )
 - end
 - function beServer ( )
 - rednet.open ("left")
 - rednet.open ("right")
 - rednet.open ("top")
 - headline ( )
 - write ("\n\n")
 - while true do
 - headline ( )
 - x, y = term.getCursorPos ( )
 - term.clearLine ( )
 - term.setCursorPos (1, y)
 - write ("Press any key")
 - event, one, two = os.pullEvent ( )
 - if event == "rednet_message" and two == "pull" then -- if 'pull' command received
 - x, y = term.getCursorPos ( )
 - term.clearLine ( )
 - term.setCursorPos (1, y)
 - if not fs.exists ("turtle "..one) then
 - fileWrite = fs.open ("turtle "..one, "w")
 - fileWrite.writeLine ("end")
 - fileWrite.close ( )
 - print ("new turtle registered (ID "..one..")")
 - end
 - fileRead = fs.open ("turtle "..one, "r")
 - i = 0
 - local text = { }
 - repeat
 - i = i + 1
 - line = fileRead.readLine ( )
 - text[i] = line
 - until text[i] == nil
 - fileRead.close ( )
 - rednet.send (one, text[1])
 - fileWrite = fs.open ("turtle "..one, "w")
 - i = 2
 - while text[i] ~= "end" and text[i] ~= nil do
 - fileWrite.writeLine (text[i])
 - i = i + 1
 - end
 - fileWrite.writeLine ("end")
 - fileWrite.close ( )
 - if text[1] ~= "end" then print ("sent '"..text[1].."' to turtle "..one)
 - else print ("no commands in queue for turtle "..one) end
 - elseif event == "char" then -- if key pressed
 - local turtles = { }
 - n = 1
 - for _, i in ipairs (fs.list ("")) do
 - if string.sub (i, 1, 7) == "turtle " and tonumber (string.sub (i, 8)) ~= nil then
 - turtles[n] = i
 - n = n + 1
 - end
 - end
 - if turtles[1] ~= nil then
 - term.clear ( )
 - term.setCursorPos (1, 1)
 - headline ( )
 - write ("\n\n")
 - print ("available turtles:")
 - for _, i in ipairs (turtles) do
 - print ("- "..i)
 - end
 - print ("")
 - 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)")
 - number = read ( )
 - while not (tonumber (number) ~= nil or number == "all" and tonumber (number) == nil) and number ~= "exit" do
 - print ("incorrect number")
 - headline ( )
 - number = read ( )
 - end
 - if number ~= "exit" then
 - print ("command: (type help to see command-list or exit to abort)")
 - headline ( )
 - message = read ( )
 - while message == "help" and message ~= "exit" do
 - term.clear ( )
 - term.setCursorPos (1, 1)
 - write ("\n\n")
 - headline ( )
 - print ("available commands: [attribute] (optional)")
 - print ("- change [xTrees | yTrees | saplingOffset | wallOffset | saplingMethod | fullSaplings | throwSaplings | sleepTime | slotAmount | chestOutput] [value]")
 - print ("- stop")
 - print ("- shutdown")
 - print ("- reboot")
 - print ("- startup (command) (atrribute1) (...)\n *leave command blank for no startup command")
 - print ("\ncommand: (type help to see command-list or exit to abort)")
 - message = read ( )
 - end
 - if message ~= "exit" then
 - if number == "all" then
 - for _, i in ipairs (turtles) do
 - fileNew = fs.open (i, "r")
 - file = fileNew.readAll ( )
 - fileNew.close ( )
 - fileNew = fs.open (i, "w")
 - fileNew.writeLine (message)
 - fileNew.write (file)
 - fileNew.close ( )
 - end
 - else
 - fileNew = fs.open ("turtle "..number, "r")
 - file = fileNew.readAll ( )
 - fileNew.close ( )
 - fileNew = fs.open ("turtle "..number, "w")
 - fileNew.writeLine (message)
 - fileNew.write (file)
 - fileNew.close ( )
 - end
 - end
 - end
 - term.clear ( )
 - term.setCursorPos (1, 2)
 - else
 - x, y = term.getCursorPos ( )
 - term.clearLine ( )
 - term.setCursorPos (1, y)
 - print ("No turtles available at the moment!")
 - end
 - end
 - end
 - end
 - term.clear ( )
 - term.setCursorPos (1, 1)
 - if not turtle then beServer ( ) end
 - while not fs.exists ("farmer.cfg") do --> writing default settings (while asking for the size of the Farm)
 - term.clear ( )
 - term.setCursorPos (1, 1)
 - textutils.slowPrint ("No configuration file found.")
 - sleep (0.25)
 - print ("")
 - print ("example with xTrees 4 and yTrees 3")
 - print ("+ + + + <-- sapling")
 - print ("+ + + +")
 - print ("+ + + +")
 - print ("o <-- logger facing up")
 - print ("")
 - print ("How many trees horizontally?\n(xTrees)")
 - xTrees = read ( )
 - print ("How many trees vertically?\n(yTrees)")
 - yTrees = read ( )
 - textutils.slowPrint ("Writing configuration-file")
 - print("")
 - writeSettings ( )
 - if fs.exists ("farmer.cfg") then
 - textutils.slowPrint ("farmer.cfg found, success!")
 - end
 - sleep (0.5)
 - term.clear ( )
 - term.setCursorPos (1, 1)
 - end
 - rednet.open ("right")
 - write ("\n\n")
 - headline ( )
 - while true do
 - write ("getting rednet commands...")
 - getRednet ( )
 - done ( )
 - write ("reading config...")
 - readSettings ( )
 - done ( )
 - write ("dropping Items...")
 - if not fullSaplings and throwSaplings then drop (1) end
 - drop (0)
 - done ( )
 - repeat
 - x, y = term.getCursorPos ( )
 - x = 1
 - term.setCursorPos (x, y)
 - saplings = waitForSaplings ( )
 - if saplings == 1 then write ("1 sapling remaining ...")
 - elseif saplings < 1 then write ("0 saplings remaining ...")
 - else write (saplings.." saplings remaining ...") end
 - sleep (1)
 - until saplings < 1
 - done ( )
 - for i = 0, sleepTime do
 - x, y = term.getCursorPos ( )
 - x = 1
 - term.setCursorPos (x, y)
 - write ("sleeping... ("..sleepTime-i.."sec left)")
 - sleep (1)
 - end
 - done ( )
 - write ("farming "..xTrees.." x "..yTrees.."...")
 - farm ( )
 - done ( )
 - end
 - -- Note: [removed]
 
Advertisement
 
                    Add Comment                
                
                        Please, Sign In to add comment