Posted 28 November 2012 - 12:05 AM
Why should I use this Farmer instead of another one?
- Because you need only one Turtle to start farming quite well! No Server-Computer is needed but it is possible to use one as a Terminal. Also the interface is very user-friendly
Terminal? For what?
- The Terminal can pass various commands to the turtle like shutting it down, changing settings and so on.
Hello,
I recently started to use some different treefarming scripts I found in the Forums, and because none of them were perfect for my uses I decided to create one on my own!
Pastebin: http://pastebin.com/4aZfqGMN
Code: (I do not guarantee that this version is up-to-date! Please check Pastebin when the version of this code is different to the version below)
Installation:
%appdata%\.minecraft\mods\ComputerCraft\lua\rom\programs
or if you are using Tekkit:
%appdata%\.techniclauncher\tekkit\mods\ComputerCraft\lua\rom\programs
Now you will be able to access it from any computer with 'farmer'
Another way is to use the pastebin command in-game. The syntax for this would be 'pastebin 4aZfqGMN farmer'.
This will result in a new file called farmer in the current directory. Run it with 'farmer'
(Note: When you use the in-game pastebin command only the turtle you downloaded the file to will be able to use the farmer command!)Multiplayer:
As a server owner you can simply paste the code to a file located in server\mods\ComputerCraft\lua\rom\programs and called farmer. Now every computer on your Server will be able to access the 'farmer' command.
Instructions:
After finishing the installation process you can simply type 'tree' on any turtle you want to be a Farmer and the same command on any computer you want to be the server. If you want to change the default settings of the turtle you can access the file and change the values at the very top!
Note: try to avoid 'wrong' values meaning for example that you should avoid having more than 64 trees because there are no false value processing algorithms in the program yet, also you should avoid messaging a turtle with a not existing number! (Will change this circumstance soon, I promise!)
To all 1.3 users out there: you have to set
- First official release
Version 1.0.1:
- Minor bug fixes
Version 1.0.2:
- Minor bug fixes
Version 1.0.3:
+ More configuration variables added
Version 1.0.4:
- Configuration bug fixes
Version 1.0.5:
- Minor bug fixes
Version 2.0:
+ Added rednet feature including Server feature
Version 2.1:
+ Better interface
+ More user-friendly
Version 2.1.1
- Removed odd (and very unnecessary*) getSize function :wacko:/>
Version 2.1.2
+ Brandnew interface with headline
+ New Chest-Output function for 1.4+ Turtles
+ Smaller Script improvements
+ Changed default settings to fit with 1.4+ Turtles
- Removed second unnecessary Item Drop
Version 2.1.2_2
- Removed note and set default saplingMethod to compare because detect is best for 1.3 but in 1.4 compare is better
*this goddamn word caused me to overpaste the 'Code:' section with 'unnecessary' because I really had to google and copy this word and totally forgot about this while pasting what I thought was the new code :D/> embarrassing…
Todo:
Recent Version: V2.1.2_2
I'm updating every week, check for new updates!
PS: I love feedback ;)/>
- Because you need only one Turtle to start farming quite well! No Server-Computer is needed but it is possible to use one as a Terminal. Also the interface is very user-friendly
Terminal? For what?
- The Terminal can pass various commands to the turtle like shutting it down, changing settings and so on.
Hello,
I recently started to use some different treefarming scripts I found in the Forums, and because none of them were perfect for my uses I decided to create one on my own!
Pastebin: http://pastebin.com/4aZfqGMN
Code: (I do not guarantee that this version is up-to-date! Please check Pastebin when the version of this code is different to the version below)
Spoiler
-- 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]
Installation:
Spoiler
Singleplayer:Spoiler
Copy the code and paste it or download the attached files and rename it into a file called 'farmer' for example (NO .txt!) and is located in:%appdata%\.minecraft\mods\ComputerCraft\lua\rom\programs
or if you are using Tekkit:
%appdata%\.techniclauncher\tekkit\mods\ComputerCraft\lua\rom\programs
Now you will be able to access it from any computer with 'farmer'
Another way is to use the pastebin command in-game. The syntax for this would be 'pastebin 4aZfqGMN farmer'.
This will result in a new file called farmer in the current directory. Run it with 'farmer'
(Note: When you use the in-game pastebin command only the turtle you downloaded the file to will be able to use the farmer command!)
Spoiler
To install it as a Player you could simply download it via pastebin ('pastebin 4aZfqGMN farmer') but this option is only available if the server has enabled the http api. If the server has disabled it, you should definitely ask him to do so. Otherwise you could ask a friendly admin to get it for you or you have to type the code on your own! Good luck ;)/>As a server owner you can simply paste the code to a file located in server\mods\ComputerCraft\lua\rom\programs and called farmer. Now every computer on your Server will be able to access the 'farmer' command.
Instructions:
After finishing the installation process you can simply type 'tree' on any turtle you want to be a Farmer and the same command on any computer you want to be the server. If you want to change the default settings of the turtle you can access the file and change the values at the very top!
Note: try to avoid 'wrong' values meaning for example that you should avoid having more than 64 trees because there are no false value processing algorithms in the program yet, also you should avoid messaging a turtle with a not existing number! (Will change this circumstance soon, I promise!)
To all 1.3 users out there: you have to set
- slotAmount to 9
- chestOutput to false
- saplingMethod to "detect"
- Falling the trees in a grid (size variable)
- Replacing saplings
- Placing dirt to stay secure while placing saplings
- Automatically dropping all collected wood into a chest behind it or into a water system
- Waiting for full saplings (either enough to fill the farm or one entire Stack, can be changed in config)
- Avoiding wrong destinations because of entities or blocks in his way
- When executed on a computer with wireless modem the computer will act like a server which can be used to send messages to the (wireless) turtle/s
- Quite a lot of settings
- change all variables from the .cfg
- set the turtles startup script
- delete the turtles startup script
- stop the farming process
- shut the turtle down
- reboot the turtle
- Amount of itemslots (which differ according to the ComputerCraft version)
- Size of the grid (x, y)
- Space between two saplings in the grid
- Space between the saplings and the wall of the Farm
- Method of detecting Saplings
- Amount of saplings he will need to start farming (example: If you have a 3*3 grid and set fullSaplings to false the Farmer would wait for 10 saplings (1 reserve))
- Dropping unnecessary saplings or not (fullSaplings = false only)
- Waiting time between to runs (after the sapling-time ends)
Spoiler
Version 1.0:- First official release
Version 1.0.1:
- Minor bug fixes
Version 1.0.2:
- Minor bug fixes
Version 1.0.3:
+ More configuration variables added
Version 1.0.4:
- Configuration bug fixes
Version 1.0.5:
- Minor bug fixes
Version 2.0:
+ Added rednet feature including Server feature
Version 2.1:
+ Better interface
+ More user-friendly
Version 2.1.1
- Removed odd (and very unnecessary*) getSize function :wacko:/>
Version 2.1.2
+ Brandnew interface with headline
+ New Chest-Output function for 1.4+ Turtles
+ Smaller Script improvements
+ Changed default settings to fit with 1.4+ Turtles
- Removed second unnecessary Item Drop
Version 2.1.2_2
- Removed note and set default saplingMethod to compare because detect is best for 1.3 but in 1.4 compare is better
*this goddamn word caused me to overpaste the 'Code:' section with 'unnecessary' because I really had to google and copy this word and totally forgot about this while pasting what I thought was the new code :D/> embarrassing…
Todo:
Add the possibility to put all Items in a chest instead of dropping them- Add a redstone output which you can toggle
- Add fuel refilling options
Rewrite the headlines from Turtle and Server- Add the possibility to change the side where the chest is
- … whatever you want! ;)/>
Spoiler
Recent Version: V2.1.2_2
I'm updating every week, check for new updates!
PS: I love feedback ;)/>
Edited on 17 December 2012 - 07:38 AM