I am currently working on making this a full suite. It may include its own api at some point, but for now just take the programs you want.
Note: The goto program uses the GPS api. Have some host servers within range so that the turtle can tell where it is. This is very important, otherwise it will go all over the place.
Programs (Version 1.56):
Goto:
Spoiler
args = {...}
if not fs.isDir("locations") then
fs.makeDir("locations")
end
local function getDirection()
local f = 0
local x, y, z = gps.locate(5,false)
y = nil
if args[1] == "special" then
if turtle.detect() then
if not turtle.dig() then
error("Tried to dig bedrock.")
end
end
while not turtle.forward() do
turtle.attack()
end
else
if not turtle.forward() then
error("I am against a wall.")
end
end
local newx, newy, newz = gps.locate(5,false)
newy = nil
turtle.back()
if newz > z then
f = 0
elseif newx < x then
f = 1
elseif newz < z then
f = 2
elseif newx > x then
f = 3
end
return f
end
local function gotox(x,newx,f)
if f == 0 then
turtle.turnRight()
elseif f == 2 then
turtle.turnLeft()
elseif f == 3 then
turtle.turnRight()
turtle.turnRight()
end
if newx < x then
local j = x - newx
for i=1,j do
if args[1] == "special" then
local i = 0
while not turtle.forward() do
if not turtle.dig() then
i = i + 1
turtle.attack()
if i == 30 then
error("Path blocked.")
end
end
end
else
if not turtle.forward() then
error("Path blocked.")
end
end
end
elseif newx > x then
local j = newx - x
turtle.turnRight()
turtle.turnRight()
for i=1,j do
if args[1] == "special" then
local i = 0
while not turtle.forward() do
if not turtle.dig() then
i = i + 1
turtle.attack()
if i == 30 then
error("Path blocked.")
end
end
end
else
if not turtle.forward() then
error("Path blocked.")
end
end
end
turtle.turnLeft()
turtle.turnLeft()
end
if f == 0 then
turtle.turnLeft()
elseif f == 2 then
turtle.turnRight()
elseif f == 3 then
turtle.turnLeft()
turtle.turnLeft()
end
end
local function gotoy(y,newy)
if newy > y then
local j = newy - y
for i=1,j do
if args[1] == "special" then
local i = 0
while not turtle.up() do
if not turtle.digUp() then
i = i + 1
turtle.attackUp()
if i == 30 then
error("Path blocked.")
end
end
end
else
if not turtle.up() then
error("Path blocked.")
end
end
end
elseif newy < y then
local j = y - newy
for i=1,j do
if args[1] == "special" then
local i = 0
while not turtle.down() do
if not turtle.digDown() then
i = i + 1
turtle.attackDown()
if i == 30 then
error("Path blocked.")
end
end
end
else
if not turtle.down() then
error("Path blocked.")
end
end
end
end
end
local function gotoz(z,newz,f)
if f == 1 then
turtle.turnLeft()
elseif f == 2 then
turtle.turnLeft()
turtle.turnLeft()
elseif f == 3 then
turtle.turnRight()
end
if newz > z then
local j = newz - z
for i=1,j do
if args[1] == "special" then
local i = 0
while not turtle.forward() do
if not turtle.dig() then
i = i + 1
turtle.attack()
if i == 30 then
error("Path blocked.")
end
end
end
else
if not turtle.forward() then
error("Path blocked.")
end
end
end
elseif newz < z then
turtle.turnRight()
turtle.turnRight()
local j = z - newz
for i=1,j do
if args[1] == "special" then
local i = 0
while not turtle.forward() do
if not turtle.dig() then
i = i + 1
turtle.attack()
if i == 30 then
error("Path blocked.")
end
end
end
else
if not turtle.forward() then
error("Path blocked.")
end
end
end
turtle.turnLeft()
turtle.turnLeft()
end
if f == 1 then
turtle.turnRight()
elseif f == 2 then
turtle.turnRight()
turtle.turnRight()
elseif f == 3 then
turtle.turnLeft()
end
end
local function findDistance(x,y,z,newx,newy,newz)
local distance = 0
local xDist = 0
local yDist = 0
local zDist = 0
if x > newx then
xDist = x - newx
elseif x < newx then
xDist = newx - x
end
if y > newy then
yDist = y - newy
elseif x < newx then
yDist = newy - y
end
if z > newz then
zDist = z - newz
elseif z < newz then
zDist = newz - z
end
distance = xDist + yDist + zDist
return distance
end
if args[1] ~= "special" then
rednet.open("right")
end
x, y, z, f, newx, newy, newz, newf = 0, 0, 0, 0, 0, 0, 0, 0
if #args == 1 then
local location = args[1]
if fs.exists("locations/"..location) then
local fLocation = fs.open("locations/"..location,"r")
newx = tonumber(fLocation.readLine())
newy = tonumber(fLocation.readLine())
newz = tonumber(fLocation.readLine())
fLocation.close()
print("Going to "..location.."...")
else
error("Unknown location.")
end
elseif #args == 2 and tonumber(args[1]) and tonumber(args[2]) then
newx, newz = tonumber(args[1]), tonumber(args[2])
print("Going to x: "..newx..", z: "..newz.."...")
elseif #args == 3 and tonumber(args[1]) and tonumber(args[2]) and tonumber(args[3])then
newx, newy, newz = tonumber(args[1]), tonumber(args[2]), tonumber(args[3])
print("Going to x: "..newx..", y: "..newy..", z: "..newz.."...")
elseif #args == 4 and tonumber(args[1]) and tonumber(args[2]) and tonumber(args[3]) and tonumber(args[4]) then
newx, newy, newz, newf = tonumber(args[1]), tonumber(args[2]), tonumber(args[3]), tonumber(args[4])
print("Going to x: "..newx..", y: "..newy..", z: "..newz..", f: "..newf.."...")
elseif #args == 9 and args[1] == "special" and tonumber(args[2]) and tonumber(args[3]) and tonumber(args[4]) and tonumber(args[5]) and tonumber(args[6]) and tonumber(args[6]) and tonumber(args[7]) and tonumber(args[8]) and tonumber(args[9]) then
newx, newy, newz, newf = tonumber(args[2]), tonumber(args[3]), tonumber(args[4]), tonumber(args[5])
x, y, z, f = tonumber(args[6]), tonumber(args[7]), tonumber(args[8]), tonumber(args[9])
elseif #args == 5 and args[1] == "add" and tonumber(args[3]) and tonumber(args[4]) and tonumber(args[5]) then
local location, xname, yname, zname = args[2], args[3], args[4], args[5]
if not fs.exists("locations/"..location) then
local fLocation = fs.open("locations/"..location,"w")
fLocation.writeLine(xname)
fLocation.writeLine(yname)
fLocation.writeLine(zname)
fLocation.close()
print("Location \""..location.."\" added.")
else
print("This location already exists. Would you like to replace it?\n\(y/n\)")
while true do
event, character = os.pullEvent()
if event == "char" and character == "y" then
local fLocation = fs.open("locations/"..location,"w")
fLocation.writeLine(xname)
fLocation.writeLine(yname)
fLocation.writeLine(zname)
fLocation.close()
print("Location changed.")
break
elseif event == "char" and character == "n" then
print("Location not changed.")
break
end
end
end
error()
else
print("To goto coords, use: \"goto <x> <z>\" or \"goto <x> <y> <z>\"")
print("To goto a set location, use: \"goto <name>\"")
print("To set a new location, use: \"goto add <name> <x> <y> <z>\"")
error()
end
if args[1] ~= "special" then
x, y, z = gps.locate(5,false)
end
if not x or not y or not z then
error("Out of GPS range")
end
local distance = findDistance(x,y,z,newx,newy,newz)
local fuelLevel = turtle.getFuelLevel()
if type(fuelLevel) == "string" then
fuelLevel = 9001e9001
end
if distance > fuelLevel then
error("Not enough fuel to travel so far!")
end
if args[1] ~= "special" then
turtle.up()
turtle.up()
turtle.up()
f = getDirection()
end
if newy > y then
gotoy(y,newy)
end
if newx ~= x then
gotox(x,newx,f)
end
if newz ~= z then
gotoz(z,newz,f)
end
if newy < y then
gotoy(y,newy)
end
if newf ~= f then
if f == 1 then
turtle.turnLeft()
elseif f == 2 then
turtle.turnLeft()
turtle.turnLeft()
elseif f == 3 then
turtle.turnRight()
end
if newf == 1 then
turtle.turnRight()
elseif newf == 2 then
turtle.turnLeft()
turtle.turnLeft()
elseif newf == 3 then
turtle.turnLeft()
end
end
if args[1] ~= "special" then
turtle.down()
turtle.down()
turtle.down()
print("Done traveling!")
end
if args[1] ~= "special" then
rednet.close("right")
end
args, x, y, z, f, newx, newy, newz, newf = nil, nil, nil, nil, nil, nil, nil, nil, nil
GPSExcavate:
Spoiler
args = {...}
rednet.open("right")
-- Make sure turtle is positioned correctly
term.clear()
term.setCursorPos(1,1)
print("I am set up to dig a rectangle downward in a forward-left direction. There should be a refuel chest to my right and a dropoff chest behind me. Is this how I am set up?")
print("\(y/n\)")
while true do
local event, character = os.pullEvent()
if event == "char" and character == "y" then
print("Initializing...")
sleep(1)
break
elseif event == "char" and character == "n" then
print("Please set up correctly.")
error()
end
end
local function forward() --Forward movement
--Move forward
local i = 0 --Iterator for bedrock/strong player detection
while not turtle.forward() do
if not turtle.dig() then --Detect blocks
i = i + 1
turtle.attack() --Detect entities
if i == 30 then
return false --If movement fails
end
end
end
--Clear above and below
while turtle.detectUp() do
turtle.digUp()
end
while turtle.detectDown() do
turtle.digDown()
end
--Position tracking
if currentpos.f == 0 then
currentpos.z = currentpos.z + 1
elseif currentpos.f == 1 then
currentpos.x = currentpos.x - 1
elseif currentpos.f == 2 then
currentpos.z = currentpos.z - 1
elseif currentpos.f == 3 then
currentpos.x = currentpos.x + 1
else
running = false
error("Something went wrong with the direction :P/>/>/>")
end
return true
end
local function turnRight() --Right turn with position tracking
turtle.turnRight()
if currentpos.f < 3 then
currentpos.f = currentpos.f + 1
else
currentpos.f = 0
end
end
local function turnLeft() --Left turn with position tracking
turtle.turnLeft()
if currentpos.f > 0 then
currentpos.f = currentpos.f - 1
else
currentpos.f = 3
end
end
local function down() --Downward movement
--Move down
local i = 0 --Iterator for bedrock detection
while not turtle.down() do
if not turtle.digDown() then --Detect blocks
i = i + 1
turtle.attackDown() --Detect entities
if i == 25 then
return false --If movement fails
end
end
end
--Position tracking
currentpos.y = currentpos.y - 1
return true
end
local function mineDown() --Moves one layer downward
if currentpos.y == edge.y + 2 then --If close to bottom (2 blocks away)
if not down() then --If downward movement fails, return to start
shell.run("goto","special",0,0,0,0,currentpos.x,currentpos.y,currentpos.z,currentpos.f)
running = false
error("I think I tried to dig bedrock.")
end
elseif currentpos.y == edge.y + 3 then --If close to bottom (3 blocks away)
for i=1,2 do
if not down() then --If downward movement fails, return to start
shell.run("goto","special",0,0,0,0,currentpos.x,currentpos.y,currentpos.z,currentpos.f)
running = false
error("I think I tried to dig bedrock.")
end
end
else --If far enough from bottom
for i=1,3 do
if not down() then --If downward movement fails, return to start
shell.run("goto","special",0,0,0,0,currentpos.x,currentpos.y,currentpos.z,currentpos.f)
running = false
error("I think I tried to dig bedrock.")
end
end
end
end
local function getFuelLevel() --Check if fuel level is unlimited
local fuelLevel = turtle.getFuelLevel()
if type(fuelLevel) == "string" then
fuelLevel = 9001e9001
end
return fuelLevel
end
local function findDistance(x,y,z,newx,newy,newz) --Find how many blocks to travel to get somewhere (non-diagonally)
local distance = 0
local xDist = 0
local yDist = 0
local zDist = 0
if x > newx then
xDist = x - newx
elseif x < newx then
xDist = newx - x
end
if y > newy then
yDist = y - newy
elseif y < newy then
yDist = newy - y
end
if z > newz then
zDist = z - newz
elseif z < newz then
zDist = newz - z
end
distance = xDist + yDist + zDist
return distance
end
local function saveLoc()
--Write variables to savefile
local fPos = fs.open("GPSExcavateCurrentpos","w")
fPos.writeLine(currentpos.x)
fPos.writeLine(currentpos.y)
fPos.writeLine(currentpos.z)
fPos.writeLine(currentpos.f)
fPos.writeLine(edge.x)
fPos.writeLine(edge.y)
fPos.writeLine(edge.z)
fPos.writeLine(backwards)
fPos.writeLine(totalMined)
fPos.writeLine(lastSlot)
fPos.close()
end
local function detectUnwanted()
local unwantedSlots = 0
for i=1, lastSlot do
turtle.select(i)
if turtle.compareTo(13) or turtle.compareTo(14) or turtle.compareTo(15) or turtle.compareTo(16) then
unwantedSlots = unwantedSlots + 1
end
end
turtle.select(1)
return unwantedSlots
end
local function dropUnwanted()
local freeSlots = 0
turtle.turnLeft()
turtle.turnLeft()
for i=1, lastSlot do
turtle.select(i)
if turtle.compareTo(13) or turtle.compareTo(14) or turtle.compareTo(15) or turtle.compareTo(16) then
turtle.drop()
end
end
turtle.turnLeft()
turtle.turnLeft()
turtle.select(1)
end
local function dropAll() --Drop mined resources, display amounts
local mined = 0
turtle.turnRight()
turtle.turnRight()
for i=1,lastSlot do
turtle.select(i)
mined = mined + turtle.getItemCount(i)
turtle.drop()
end
--This will send to rednet soon
totalMined = totalMined + mined
print("Minerals mined this run: "..mined)
print("Total mined: "..totalMined)
turtle.select(1)
turtle.turnRight()
turtle.turnRight()
end
local function refuel() --Refuel if needed
turtle.turnRight()
turtle.select(1)
while getFuelLevel() < findDistance(currentpos.x,currentpos.y,currentpos.z,0,0,0) + 400 do --Enough to make it back to where he was digging and dig a bit
turtle.suck()
if turtle.getItemCount(1) == 0 then --If no fuel is in the box
print("Please put fuel in my top-left slot, then press space.")
while true do
local event, character = os.pullEvent()
if event == "key" and character == 57 then
print("Refueling...")
sleep(1)
break
end
end
end
if not turtle.refuel() then --If item isn't fuel
print("This is not fuel! Please remove it, then press space.")
while true do
local event, character = os.pullEvent()
if event == "key" and character == 57 then
print("Refueling...")
sleep(1)
break
end
end
end
end
turtle.turnLeft()
end
local function dropRefuel()
print("Dropping & refueling")
shell.run("goto","special",0,0,0,0,currentpos.x,currentpos.y,currentpos.z,currentpos.f) --Return to start
dropAll()
refuel()
shell.run("goto","special",currentpos.x,currentpos.y,currentpos.z,currentpos.f,0,0,0,0) --Return to where he left off
end
local function excavate() --The actual excavation process
while running do --Make sure stop signal hasn't been sent
turtle.select(1)
if currentpos.x == 0 and currentpos.y == 0 and currentpos.z == 0 then --To start off a layer down
down()
turtle.digDown()
end
if ( currentpos.x == edge.x and currentpos.y == edge.y + 1 and currentpos.z == edge.z or currentpos.x == edge.x and currentpos.y == edge.y + 1 and currentpos.z == 0 ) and not backwards or ( currentpos.x == 0 and currentpos.y == edge.y + 1 and currentpos.z == 0 or currentpos.x == 0 and currentpos.y == edge.y + 1 and currentpos.z == edge.z ) and backwards then --Very long check to see if at the end of process
if lastSlot ~= 16 and detectUnwanted() then
dropUnwanted()
end
shell.run("goto","special",0,0,0,0,currentpos.x,currentpos.y,currentpos.z,currentpos.f) --Return to start
dropAll()
print("Done digging a hole! Whew, that was hard work.")
done = true --Record that turtle is finished digging
running = false --Stop other "stopping" loop
break
end
if turtle.getItemCount(lastSlot) > 0 then --Check if inventory is full or fuel is low
if lastSlot ~= 16 then
dropUnwanted()
if detectUnwanted() < 3 then
dropRefuel()
elseif turtle.getItemCount(lastSlot) > 0 then
turtle.select(lastSlot)
while turtle.getItemCount(lastSlot) > 0 do
for i=1, lastSlot do
turtle.transferTo(i)
end
end
end
else
dropRefuel()
end
end
if getFuelLevel() < (findDistance(currentpos.x,currentpos.y,currentpos.z,0,0,0) + 16) then
if lastSlot ~= 16 then
dropUnwanted()
end
dropRefuel()
end
if ( currentpos.x == edge.x and currentpos.z == edge.z or currentpos.x == edge.x and currentpos.z == 0 ) and not backwards then --If at the end of a layer
mineDown()
turnRight()
turnRight()
backwards = true --Switching directions
turtle.digDown()
elseif ( currentpos.x == 0 and currentpos.z == 0 or currentpos.x == 0 and currentpos.z == edge.z ) and backwards then --If at the end of a layer
mineDown()
turnLeft()
turnLeft()
backwards = false --Switching directions
turtle.digDown()
elseif currentpos.z == edge.z then --If at edge, turn around and do next line
if backwards then
turnRight()
forward()
turnRight()
else
turnLeft()
forward()
turnLeft()
end
elseif currentpos.z == 0 and currentpos.x ~= 0 then --If at edge, turn around and do next line
if backwards then
turnLeft()
forward()
turnLeft()
else
turnRight()
forward()
turnRight()
end
end
if not forward() then --If movement fails, return to start
shell.run("goto","special",0,0,0,0,currentpos.x,currentpos.y,currentpos.z,currentpos.f)
running = false
error("I think I tried to dig bedrock.")
end
saveLoc()
end
end
local function stop() --Ability to stop turtle mid-excavation. This will wait until current action is done, then exit the excavate function
while running do
local event, data, message = os.pullEvent()
if event == "char" and data == "p" then --If direct keypress
print("Stopping...")
running = false
break
elseif event == "rednet_message" and message == "stop" then --If rednet stop signal
print("Stopping...")
running = false
id = tonumber(data)
break
end
end
end
local function restart() --To restart from previous digging
print("Restarting from saved position...")
if not fs.exists("GPSExcavateCurrentpos") then -- Check for save file
error("Could not find saved position!")
end
--Read save file, change variables
local fPos = fs.open("GPSExcavateCurrentpos","r")
currentpos.x = tonumber(fPos.readLine())
currentpos.y = tonumber(fPos.readLine())
currentpos.z = tonumber(fPos.readLine())
currentpos.f = tonumber(fPos.readLine())
edge.x = tonumber(fPos.readLine())
edge.y = tonumber(fPos.readLine())
edge.z = tonumber(fPos.readLine())
local backwardsString = fPos.readLine()
if backwardsString == "true" then
backwards = true
else
backwards = false
end
totalMined = tonumber(fPos.readLine())
lastSlot = tonumber(fPos.readLine())
fPos.close()
shell.run("goto","special",currentpos.x,currentpos.y,currentpos.z,currentpos.f,0,0,0,0) --Go to position where turtle left off
restarting = true
print("Let the diggy-hole recommence!")
end
totalMined = 0 --Total mined out blocks over course of excavation
restarting = false --Whether turtle is restarting from save
done = false --Whether turtle has completed excavation
running = true --Whether turtle is currently digging
backwards = false --Which direction turtle is digging the layers currently
currentpos = {} --Current position storage. It's a table just because it is easier, no real need for it
edge = {} --Boundaries of hole. Same deal as currentpos, no real reason to have it as a table
id = -1 --Id of computer that sent the rednet message. This is so that it can reply when it has stopped
w, l, d = 0, 0, 0 --Width, length, depth of hole. This is just for input of numbers
currentpos.x, currentpos.y, currentpos.z, currentpos.f = 0, 0, 0, 0 --Initialise pieces of currentpos
lastSlot = 16 --Slot in which to make sure there are no blocks: this is to keep any comparing slots free
if #args == 1 and args[1] == "restart" then --If restarting from save
restart()
elseif #args == 2 and tonumber(args[1]) > 1 and tonumber(args[2]) > 2 then --If a square hole is wanted
w = tonumber(args[1])
l = w
d = tonumber(args[2])
elseif #args == 3 and tonumber(args[1]) > 1 and tonumber(args[2]) > 1 and tonumber(args[3]) > 2 then --If a non-square hole is wanted
w = tonumber(args[1])
l = tonumber(args[2])
d = tonumber(args[3])
else --If arguments improperly input, print usage
print("Usage: \"GPSExcavate <side> <depth>\" or \"GPSExcavate <width> <length> <depth>\"")
print("Note: depth must be at least 3.")
print("To restart digging, use: \"GPSExcavate restart\"")
error()
end
if not restarting then --Input edge locations
edge.x = w - 1
edge.y = -(d - 1)
edge.z = l - 1
print("Would you like the turtle not to collect certain blocks?")
print("\(y/n\)")
while true do
local event, character = os.pullEvent()
if event == "char" and character == "y" then
lastSlot = 12
print("Please put unwanted blocks in the bottom four slots, then press space to continue.")
while true do
local event, character = os.pullEvent()
if event == "key" and character == 57 then
print("Turtle will not collect these blocks.")
break
end
end
break
elseif event == "char" and character == "n" then
lastSlot = 16
break
end
end
print("Let the diggy-hole commence! Digging a hole "..w.." by "..l.." by "..d.." meters.")
end
print("Press \"p\" to save and stop at any time.")
parallel.waitForAll(excavate,stop) --Actual running of program. This is to enable stopping mid-digging
if not done then --If turtle was stopped before the end
print("Saving position and dimensions...")
sleep(1)
saveLoc()
print("Position and dimensions saved. Returning to base...")
shell.run("goto","special",0,0,0,0,currentpos.x,currentpos.y,currentpos.z,currentpos.f) --Return to start
dropAll()
print("Excavation stopped.")
if id ~= -1 then --If stop signal was sent by rednet, reply when done returning
rednet.send(id,"stopped")
end
else --Get rid of save file if turtle is done excavating. I will find a way to have rednet in here too
fs.delete("GPSExcavateCurrentpos")
end
print("Next hole please? :D/>/>/>")
--Delete variables so they don't persist
args, currentpos, edge, id, done, restarting, running, w, l, d, backwards, lastSlot = nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil
rednet.close("right")
FarmTree:
Spoiler
local function keypress(key)
while true do
local event, press=os.pullEvent("char")
if press ~= "esc" then
if key == "any" then
return press
elseif press == key then
return true
end
end
end
end
local function yesno()
while true do
local key = keypress("any")
if key == "y" then
return true
elseif key == "n" then
return false
end
end
end
local function forward()
local i = 0
while not turtle.forward() do
if not turtle.dig() then
i = i + 1
turtle.attack()
if i == 30 then
error("Help! I'm stuck.")
end
end
end
end
local function drop()
local wood=0
turtle.turnRight()
turtle.turnRight()
for f=3,16 do
turtle.select(f)
wood = wood + turtle.getItemCount(f)
turtle.drop()
end
totalWood = totalWood + wood
print("Wood gathered this round: "..wood)
turtle.turnLeft()
if turtle.getItemCount(1)>0 or turtle.getItemCount(2)>0 then
turtle.select(1)
turtle.drop()
turtle.select(2)
turtle.drop()
end
turtle.select(1)
turtle.suck()
turtle.select(2)
turtle.suck()
turtle.turnLeft()
end
local function farm()
while farmloop do
local neededSaplings = (W*L)/4
local waitTime = 1200/(W*L)
turtle.up()
for a=1,W do
for b=1,L do
if tonumber(turtle.getFuelLevel()) and turtle.getFuelLevel()<128 then
print("Fuel low. Refueling using collected wood...")
turtle.select(3)
turtle.refuel()
turtle.select(1)
end
forward()
turtle.turnLeft()
if turtle.detect() then
trees = trees + 1
turtle.select(3)
turtle.dig()
forward()
turtle.digDown()
while turtle.compareUp() do
turtle.digUp()
turtle.up()
end
while not turtle.detectDown() do
turtle.down()
end
turtle.back()
if turtle.getItemCount(1)>1 then
turtle.select(1)
else
turtle.select(2)
end
turtle.place()
turtle.up()
end
if b<L then
turtle.turnRight()
forward()
forward()
end
end
turtle.turnLeft()
for c=1,(x-1) do
forward()
end
if a<W then
turtle.turnRight()
forward()
forward()
forward()
turtle.turnRight()
end
end
turtle.turnLeft()
for d=1,(y-2) do
forward()
end
turtle.turnLeft()
turtle.down()
--When saplings run low
if turtle.getItemCount(1)+turtle.getItemCount(2)<neededSaplings then
drop()
end
sleep(waitTime)
end
end
local function stop()
while farmloop do
local event, data, message = os.pullEvent()
if event == "char" and data == "p" then
print("Stopping...")
farmloop = false
break
elseif event == "rednet_message" and message == "stop" then
print("Stopping...")
farmloop = false
id = tonumber(data)
break
end
end
end
setup=false
setuploop=true
farmloop=true
autoMeasure=" "
trees=0
totalWood=0
L=0
W=0
x=0
y=0
if fs.isDir("treesettings") and fs.exists("treesettings/autoMeasure") and fs.exists("treesettings/L") and fs.exists("treesettings/W") then
autoMeasurefile = fs.open("treesettings/autoMeasure","r")
autoMeasure = autoMeasurefile.readAll()
autoMeasurefile.close()
Lfile=fs.open("treesettings/L","r")
L=tonumber(Lfile.readAll())
Lfile.close()
Wfile=fs.open("treesettings/W","r")
W=tonumber(Wfile.readAll())
Wfile.close()
else
setup = true
fs.makeDir("treesettings")
end
term.clear()
term.setCursorPos(1,1)
textutils.slowPrint("Initialization in progress...")
sleep(2)
print("This Turtle is programmed for a rectangular birch or spruce tree farm, with 2 spaces between each tree, and at least one block of space around the whole farm.")
sleep(1)
print("I am supposed to be placed in the bottom-left corner of the farm, with a dropoff chest behind me and a sapling chest to my right. If this is not the case, please move me there and try again.")
print("Press any key to continue.")
keypress("any")
term.clear()
term.setCursorPos(1,1)
while true do
print("Type 'last' to use last settings, or 'setup' to reconfigure.")
local doSetup=io.read()
if setup or doSetup=="setup" or doSetup=="Setup" then
setup=true
if setup then
print("Past settings not detected.")
end
print("Prepare to enter your information.")
break
elseif doSetup=="last" or doSetup=="Last" then
setup=false
print("Using last settings.")
break
else
term.clear()
term.setCursorPos(1,1)
end
end
if setup then
while true do
print("Type 'auto' for auto-measurement, or 'manual' for manual input of farm dimensions.")
local AorM=io.read()
if AorM=="Auto" or AorM=="auto" then
autoMeasure="true"
print("Measuring set to automatic.")
break
elseif AorM=="Manual" or AorM=="manual" then
autoMeasure="false"
print("Please enter length of farm \(direction I am facing\).")
L=tonumber(io.read())
print("Please enter width of farm.")
W=tonumber(io.read())
print("Dimensions set.")
break
else
term.clear()
term.setCursorPos(1,1)
end
end
print("Would you like to save your settings? (y/n)")
local save=yesno()
if save then
print("Saving...")
sleep(2)
setAutoMeasurefile=fs.open("treesettings/autoMeasure","w")
setAutoMeasurefile.write(autoMeasure)
setAutoMeasurefile.close()
if autoMeasure=="false" then
setLfile=fs.open("treesettings/L","w")
setLfile.write(tostring(L))
setLfile.close()
setWfile=fs.open("treesettings/W","w")
setWfile.write(tostring(W))
setWfile.close()
end
print("Save Complete!")
else
print("Settings will be temporary.")
end
end
term.clear()
term.setCursorPos(1,1)
print("Please fill slots 1 and 2 with saplings.")
print("When finished, press any key to continue.")
keypress("any")
term.clear()
term.setCursorPos(1,1)
if turtle.getFuelLevel()<256 then
print("Please refuel me first.")
error()
end
if autoMeasure=="true" then
print("Auto-Measuring...")
--Auto-init:
L=0
W=0
--Measure length
forward()
local starting = true
while not turtle.detect() do
turtle.turnLeft()
if turtle.detect() then
L=L+1
elseif not starting then
turtle.turnLeft()
forward()
forward()
turtle.turnRight()
turtle.turnRight()
break
else
print("No saplings detected. Very confused.")
error()
end
turtle.turnRight()
forward()
if not turtle.detect() then
forward()
forward()
end
starting = false
end
turtle.turnLeft()
turtle.turnLeft()
--Return to start
x=3*L-1
for e=1,x do
forward()
end
turtle.turnRight()
--Measure width
forward()
while not turtle.detect() do
turtle.turnRight()
if turtle.detect() then
W=W+1
else
turtle.turnRight()
forward()
forward()
turtle.turnLeft()
turtle.turnLeft()
break
end
turtle.turnLeft()
forward()
if not turtle.detect() then
forward()
forward()
end
end
turtle.turnRight()
turtle.turnRight()
--Return to start
y=3*W-1
for f=1,y do
forward()
end
turtle.turnLeft()
print("Saving...")
sleep(2)
autoMeasurefile=fs.open("treesettings/autoMeasure","w")
autoMeasurefile.write("false")
autoMeasurefile.close()
Lfile=fs.open("treesettings/L","w")
Lfile.write(tostring(L))
Lfile.close()
Wfile=fs.open("treesettings/W","w")
Wfile.write(tostring(W))
Wfile.close()
print("Save Complete!")
else
x=3*L-1
y=3*W-1
end
print("Initialization complete! Beginning farming...")
print("Press \"p\" at any time to stop. The turtle will complete one more circuit before stopping.")
--Actual Farming
parallel.waitForAll(farm,stop)
--When finished
drop()
print("Farming Complete! This tree farming program courtesy of ClAnta :D/>/>/>/>/>/>/>/>")
print("Total trees chopped down: "..trees)
print("Total wood gathered: "..totalWood)
setup, autoMeasure, L, W, x, y, trees, totalWood = nil, nil, nil, nil, nil, nil, nil, nil
Utilities (somewhat related):
ChopLargeTree:
Spoiler
local altitude = 0
local fuelLevel = turtle.getFuelLevel()
if not (type(fuelLevel) == "string" or fuelLevel > 400) then
error("May not have enough fuel. Please add some.")
end
for i=1,3 do
if turtle.detect() then
break
else
turtle.turnLeft()
end
end
if not turtle.detect() then
error("Could not find tree")
end
turtle.turnLeft()
turtle.forward()
turtle.turnRight()
if not turtle.detect() then
turtle.turnRight()
turtle.forward()
turtle.turnLeft()
end
turtle.dig()
turtle.forward()
if turtle.detect() then
turtle.dig()
while turtle.detectUp() do
altitude = altitude + 1
turtle.digUp()
turtle.up()
turtle.dig()
end
turtle.turnRight()
turtle.dig()
turtle.forward()
turtle.turnLeft()
turtle.dig()
for i=1,altitude do
turtle.digDown()
turtle.down()
turtle.dig()
end
turtle.turnLeft()
turtle.forward()
turtle.turnRight()
else
while turtle.detectUp() do
altitude = altitude + 1
turtle.digUp()
turtle.up()
end
for i=1,altitude do
turtle.digDown()
turtle.down()
end
end
turtle.turnLeft()
turtle.turnLeft()
turtle.forward()
for i=1,16 do
turtle.select(i)
turtle.drop()
end
turtle.select(1)
print("Done chopping!")
————————————————————————————————————————————————————————
Usage:
Name the goto and excavate programs "goto" and "GPSExcavate", respectively. The goto program should create a "locations" folder, while the excavate program (when it saves) will create a "GPSExcavateCurrentpos" file. Do not modify this file unless you know what it does, or things will mess up :)/>/>
Also, set up some gps host servers in the vicinity. This is REQUIRED for the goto program to work.
This is now no longer required for the GPSExcavate, but for the sake of simplicity I will continue to call it that, at least for the time being.
Check the wiki for help setting these up, or I can provide help if needed.
Goto:
To goto coordinates, use: "goto <x> <y> <z>" or "goto <x> <z>"
To goto a saved location, use: "goto <location>"
To add a location to the saved list, use: "goto add <location> <x> <y> <z>"
To change the locations directory name, change all instances of "locations" to whatever you want to call it (find/replace). Just make sure the directory is in the same place as the program. I may make this easier soon.
GPSExcavate:
First, install goto! This is REQUIRED for the program to run. You don't need gps hosts (contrary to what the name would suggest), but you must have the goto program.
To excavate an area, use: "GPSExcavate <side> <depth>" or "GPSExcavate <width> <length> <depth>".
If you want it not to collect certain blocks, select "yes" when starting up and place the unwanted ones in the bottom four slots of its inventory. It should try to avoid collecting them.
At the moment, depth must be at least 3. I am working on this.
To restart an excavation, use: "GPSExcavate restart". Always remember to do this from the starting position, otherwise your turtle will dig where you don't want it to.
It will dig in a forward-left direction of itself, down (obviously).
FarmTree:
Lay out your tree farm with two spaces in between each tree, and make them birch, spruce or jungle.
If you choose to have a fence around the farm (strongly suggested), make sure there is at least a one-block space. If you do not want a fence, leave several blocks space so that the measuring function can detect the edge. The reason a fence is suggested is that the turtle will attack anything in its way, and may have mob drops interfering with its function.
Make sure you use birch, spruce, jungle or another straight-growing tree: this cannot handle branches.
Plant the saplings before starting the program; it is very picky about the layout :P/>
ChopLargeTree:
Simply make sure your turtle has fuel, place it at the base of the tree, and let it go. Make sure the base is clear as well.
——————————————————————————————————————————————————————————————————————
iFAQ (imaginary frequently asked questions):
Spoiler
What is it?An excavation program that can save its position and restart later, as well as some other utilities.
Why should I use it?
No reason. Honestly. Unless you want to. Then you should use it.
In all seriousness, I made this program because I wanted an excavate program that did not need continuous use. I'm sure I could have used someone else's, but I wanted to have fun. I'm sharing it here because I'm fairly proud of it, and hopefully some people will find it useful.
Your code sucks! Why would you even post this it's so bad!!!!!! *rage*
Then tell me how to make it better. Please. I'm a code noob.
Especially tell me about stuff like improper functions and persistent global variables, because I sometimes lose track.
Your program goes to the wrong spot/digs the wrong area.
Make sure you have GPS host computers set up close by the turtle and a good distance from each other. Otherwise, the coordinates will not be accurate. Having computers high in the sky will not work, as far as I have tested, but run some "gps locate" tests to check beforehand.
If you are sure this is not the problem, try to explain what is going wrong so I can reproduce and debug it.
The Excavate program should not need GPS, but if it tells you it does, let me know.
Help! Your turtle is a mass murderer! Anything in the pit is killed!
Yes, I know. I did that on purpose, so it wouldn't get stuck. The other option is for it to wait for whatever is in the way to move, but I decided to have fun with 1.4 features I haven't used yet :D/>
If enough people don't like it, I can upload a "peaceful" version -_-/>
The FarmTree program does weird things.
It was made a while ago, and so is probably worse code than the other two. Let me know what is happening; I will do a re-write if needed, but I felt like moving on to better things.
——————————————————————————————————————————————————————————————————————
Todo:
- Integrate rednet capabilities
- Make changing save directory / save name easier
- Bugtest, bugtest, bugtest
Changelog:
Version 1.56
- Quick fix for GPSExcavate; declaring functions before calling them is always a smart idea
- Fixed a weird bug in GPSExcavate, where the turtle would go at molasses pace once it dropped its unwanted items
- Also fixed dropping items even if that wasn't required (!)
- Bugfixes to goto and GPSExcavate, fixed fatal error in excavate
- Same pastebin links: I may release an installer for further convenience
- Catch for proper farm now included in FarmTree
- Excavation will now not waste time dropping materials
- Pastebin links now permanent: this will facilitate future rednet systems
- Tiny update to FarmTree to fix failed function
- Tiny update to FarmTree to fix misnamed function
- GPSExcavate can now accept blocks not to collect! No more walls of boxes of cobble
- Also saves its position very frequently, so no big deal if the chunk is accidentally unloaded
- See new excavate instructions; no changes to other programs
Spoiler
Version 1.43
- Small update to goto to be able to go through gravel
- Should fix excavation issues with gravel
- No changes to other programs
- Comments to GPSExcavate! Finally, Loki can rest :)/>
- Bugfixes: Unlimited fuel catch now works properly, small fixes around excavation program
- No changes to other programs
- Bugfixes: GPSExcavate no longer digs staircase pattern: simple fail in starting up digging
- Small fix for calculation of fuel levels
- No changes to other programs
- Bugfixes: GPSExcavate no longer flies away when finishing, FarmTree can be stopped
- Unified fuel and non-fuel versions
- Excavate is roughly 3x faster: digs above and below, and doesn't return to start every leve;
- Bugfixes: FarmTree now works (again, grr…)
- It can now dig through leaf blocks, to work with spruce trees
- Fixed a possible error with detecting length if loading previous settings
- Bugfixes: FarmTree now works (very stupid error on my part)
- Minor changes to FarmTree, cleaning up some code
- No changes to other programs
- Tree farming program! Reusing old code, so it's pretty noobish. But it works (I think).
- GPSExcavate now displays the amount of minerals mined. We're moving towards rednet, people.
- Non-fuel versions of both goto and GPSExcavate: the tree farming program can be used with either.
- GPSExcavate now no longer needs GPS! Hooray! Just remember to restart it in its "base" position, or else it won't work. The name will stay the same for the time being, just because it's easier that way ;)/>/>
- Proper saving of position! It should now start exactly where it left off.
- Goto program changed slightly
- GPSExcavate "restart" now works properly (apparently I didn't test this enough)
- Turtle can now dig through gravel
- Small position error catch (hopefully)
- Big improvement: excavating turtles no longer need to be placed in a specific direction!
- Bugfixes: many :)/>/> caused a bunch of bugs by the changes, fixed a bunch, in both programs
- Bugfix: Turtle no longer ends up running away when digging an even-sided hole
- Variables now delete themselves, instead of persisting
- Release
————————————————————————————————————————————————————————
One last note/disclaimer: This program was made in 1.46. If you get any issues, please check your version number before trying to figure out the error.
The programs should guide you through the rest. If you have any questions, comments, improvements or compliments, feel free to post!