Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- Lua script by nO_OnE
- -- Edited by Phyrax to add refueling capabilities.
- -- V2.1.3
- -- 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 = 300 -- set if you wish to make a break between farming runs
- local minFuel = 100
- -- 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.writeLine (minFuel)
- 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 ( ))
- minFuel = 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)
- -- Altered to allow us to keep slot 3 from dropping, as it's now a fuel slot.
- 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 = 4, slotAmount do
- turtle.select (i)
- if turtle.getItemCount (i) > 0 then turtle.drop ( ) end
- end
- end
- turn ("back")
- else
- for i = 4, slotAmount do
- turtle.select (i)
- if turtle.getItemCount (i) > 0 then turtle.drop ( ) end
- 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 (4)
- 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 (4) > 0 then
- turtle.select (4)
- local re = turtle.compare ( )
- return (re)
- else
- return (turtle.detect ( ))
- end
- end
- -- Check Fuel
- function checkfuel()
- if turtle.getFuelLevel() > minFuel then
- term.clear()
- term.setCursorPos(1, 1)
- --[[
- Slot 3 is now fuel. Since we're dealing with trees
- we can use ANYTHING from that slot, be it saplings
- or logs.
- --]]
- print('=======================================')
- print(' Fuel Level')
- term.write('Fuel: ')
- fpx, fpy = term.getCursorPos()
- term.setCursorPos(fpx+4, fpy)
- term.write(' / '..minFuel);
- print('=======================================')
- term.setCursorPos(fpx, fpy)
- cFuel = tostring(math.floor( turtle.getFuelLevel() ))
- term.write( cFuel )
- end
- if turtle.getFuelLevel() < minFuel then
- term.clear()
- term.setCursorPos(1, 1)
- --[[
- Slot 3 is now fuel. Since we're dealing with trees
- we can use ANYTHING from that slot, be it saplings
- or logs.
- --]]
- print('=======================================')
- print(' Fuel Level')
- term.write('Fuel: ')
- fpx, fpy = term.getCursorPos()
- term.setCursorPos(fpx+4, fpy)
- term.write(' / '..minFuel);
- print('=======================================')
- for fNum = 3, slotAmount do
- turtle.select(fNum)
- repeat
- turtle.refuel(1)
- term.setCursorPos(fpx, fpy)
- cFuel = tostring(math.floor( turtle.getFuelLevel() ))
- term.write( cFuel )
- until turtle.getFuelLevel() > minFuel or turtle.getItemCount(fNum) == 0
- end
- if turtle.getFuelLevel() < minFuel then
- x, y = term.getCursorPos()
- term.setCursorPos(1,y+2)
- print('Error: Auto-Refuel Failure')
- print('Place fuel in slot #3')
- print('[F] Refuel')
- print('[Q] Quit')
- while true do
- local event, param1 = os.pullEvent("key")
- turtle.select(3)
- if param1 == 33 then
- checkfuel()
- if turtle.getFuelLevel() >= minFuel then term.clear() break end
- end
- if param1 == 16 then
- term.clear()
- term.setCursorPos(1,1)
- os.queueEvent('terminate')
- end
- end
- end
- end
- end
- function farm ( ) --> doing a complete farming run
- checkfuel()
- forward (1)
- up (1)
- turn ("right")
- forward (wallOffset)
- turn ("left")
- forward (wallOffset - 1)
- for j = 1, xTrees do
- for i = 1, yTrees do
- checkfuel()
- 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 ("refill saplings please...") 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
Advertisement