This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
Ikkalyzte's profile picture

GPS Excavate

Started by Ikkalyzte, 30 September 2012 - 04:43 AM
Ikkalyzte #1
Posted 30 September 2012 - 06:43 AM
Here it is, everyone. Your standard excavate program. Only, this one can save its position, and restart later! As well, I'm pretty certain it can go faster than is possible for a buildcraft quarry. Full remote-triggering coming soon.
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 &amp; 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):


SpoilerWhat 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
Version 1.55
  • 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 (!)
Version 1.54
  • Bugfixes to goto and GPSExcavate, fixed fatal error in excavate
  • Same pastebin links: I may release an installer for further convenience
Version 1.53
  • 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
Version 1.52
  • Tiny update to FarmTree to fix failed function
Version 1.51
  • Tiny update to FarmTree to fix misnamed function
Version 1.5
  • 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
Older:
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
Version 1.42
  • Comments to GPSExcavate! Finally, Loki can rest :)/>
  • Bugfixes: Unlimited fuel catch now works properly, small fixes around excavation program
  • No changes to other programs
Version 1.41
  • 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
Version 1.4
  • 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;
Version 1.32
  • 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
Version 1.31
  • Bugfixes: FarmTree now works (very stupid error on my part)
  • Minor changes to FarmTree, cleaning up some code
  • No changes to other programs
Version 1.3
  • 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.
Version 1.2
  • 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
Version 1.11
  • GPSExcavate "restart" now works properly (apparently I didn't test this enough)
  • Turtle can now dig through gravel
  • Small position error catch (hopefully)
Version 1.1
  • 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
Version 1.01
  • Bugfix: Turtle no longer ends up running away when digging an even-sided hole
  • Variables now delete themselves, instead of persisting
Version 1.0
  • 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!
Ikkalyzte #2
Posted 05 October 2012 - 05:41 AM
Update:
Bugfixes! Feel free to post your bugs in this thread, no need to PM me :(/>/>
Kane Hart #3
Posted 05 October 2012 - 09:55 AM
I have not used this since I'm to derpy but I wanted to thank you for your hardwork since I'm sure there is a lot of tekkit assholes ripping off all the scripts here without saying thanks!
Puds22 #4
Posted 05 October 2012 - 10:04 AM
Can you put the paste-bin link up for the excavate, I find it easier to add to my turtle through paste-bin's program where you just go: Pastebin get (numbers on website) (program name)
Ikkalyzte #5
Posted 05 October 2012 - 06:38 PM
Oh yeah, sorry, forgot to do that too when I added the direct code :(/>/>
As well, I put this out there to be used. As long as they don't claim it as they're own, I think I'm ok :D/>/>

Edit: Pastebin links now added
lokilotus #6
Posted 05 October 2012 - 07:33 PM
Hey,

Bit of a Noob when it comes to CC. Ok, I'm a complete novice. But Still.

WARNING: NOOB QUESTION/ERROR THINGY

How do I install the program/s? I've tried putting it in my CC Zip, but that doesn't seem to work- I got a crash last night (unfortunately I closed the log before I could get on here to post) and then it reverted my CC install to before I put them in the places I thought they should go (/lua/roms/programs/turtle/)…

I would use the in-built pastebin thing if I could work out how to use it, but doesn't that only give it to the one turtle? I would like it in-built on all turtles I craft if possible…

Any help would be GREATLY appreciated. I've looked on the forums all over and can't seem to find anything…

CC Version: 1.43

Thanks All! :(/>/>
Cranium #7
Posted 05 October 2012 - 07:40 PM
There should be a folder labelled computers in your saves folder. That is where you will find each id of the computer you have, which is where you will put the programs.
Ikkalyzte #8
Posted 05 October 2012 - 08:30 PM
Thanks cranium.
Also, both of these programs read/write access to their directories. This means, unfortunately, that you can't put them in the ROM folder to make them installed on every turtle. As well, it means that "goto" locations will not be the same between turtles. If anyone can think of a good way to do that, let me know.
TheSturgyBoy #9
Posted 06 October 2012 - 08:18 PM
hey, when I try moving my turtle to the coords it after it says where its moving, it says 'goto:262: attempt to call nil' and doesnt move O.o
Ikkalyzte #10
Posted 09 October 2012 - 01:36 AM
Thanks. Uploaded fixed versions.
tommy__123__ #11
Posted 09 October 2012 - 02:34 AM
So will this work say if the world gets unloaded and reloaded
TheSturgyBoy #12
Posted 09 October 2012 - 08:26 AM
it now says ':goto:265: attempt to call nil' would this be because Im trying to use a negative x?
Ikkalyzte #13
Posted 14 October 2012 - 12:41 AM
Tommy: I'm not sure, but the idea of this program is that you tell it to stop before you exit the game, and it saves its position. No clue how unloading and reloading works; that might even work with the normal excavate program.

Sturgy: Sorry, I can't reproduce that bug. I've tested using a negative x. The only thing I can think of is that your gps computers might be messing up somehow: either giving a wrong position, or not responding. I also assume you're using a turtle…
Ikkalyzte #14
Posted 14 October 2012 - 01:10 AM
I found some a bug with the excavate program; hold off on using it. I'll have a fixed version up in an hour or two hopefully, with some extras :)/>/>
Ikkalyzte #15
Posted 14 October 2012 - 04:38 AM
Update:

Version 1.1
  • 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

Thanks to all who provided bug reports! I think I fixed all of them.
Keep letting me know about the bugs. I'll fix the critical ones, but I'm working on a program to work together with these, so additions are not a priority at the moment.
Doyle3694 #16
Posted 14 October 2012 - 11:18 AM
Where is the pastebin links? :S
Ikkalyzte #17
Posted 14 October 2012 - 08:35 PM
Just click on the name of the program :)/>/>
Should I put it somewhere more explicit? I thought that it would be obvious enough, but if you have a better suggestion then I'd be happy to put it somewhere else.
DooMJake #18
Posted 16 October 2012 - 06:48 PM
Whenever I try to restart an GPSminer, it either runs amok(mines in a wrong direction) or it tells me: GPSExcavate:283: attemt to index ? (a nil value) what did I do wrong?
dustpuppy #19
Posted 16 October 2012 - 07:09 PM
This looks like, that the turtle can't get it's facing. Possible the GPS array didn't answer.
I also have problems with this problem.
lokilotus #20
Posted 16 October 2012 - 10:41 PM
Hey all, back again.

So, I'm playing with the previous version (haven't had time to update) of both programs, and have come across a problem in GPSEx: Falling gravel makes it stall, it can't dig more than one block. As I love digging out rooms with it and also mining under mountains (EMERALDS!) I've found this to be a huge problem. So…

I tried editing both programs (as they both reference each other) and I've got that sorted. Problem is it now, at seemingly random times, decides to do some or all of the following:

-Dig the next layer in the opposite direction
-Miss out the next layer completely and dig the same layer underneath it twice
-Dig out to (0,64,0)
-Other Random things, E.G. Dance (strangely)

All I've done is add a loop function that says if you can't move forward, then do the following: attack, break forwards, sleep for a few milliseconds, try again.

So I have no clue what I've done wrong. Here's my question:

Could you (or rather would you maybe possibly) add this functionality into the next version maybe?

Many thanks in advance,

-Loki
ChunLing #21
Posted 17 October 2012 - 02:00 AM
You need to make your movement function be able to have a return so that the turtle can know if it worked or not. Even the most robust movement function won't succeed every time
Ikkalyzte #22
Posted 17 October 2012 - 04:40 AM
Found many bugs with the restarting, thanks for the reports guys. I'll see if I can fix the gravel issue, but I thought I would have solved that with the nature of my "forward" function: if there is a block, it digs it, and if it still can't go, it attacks. I'll make some modifications and then upload a new version
Ikkalyzte #23
Posted 17 October 2012 - 05:51 AM
Wow. So, with apologies, I won't be able to get a fix out tonight. Apparently I left a crapton of bugs in the restarting function, and so I think I'll only be able to fix it by tomorrow at this same time. Sorry guys!
Ikkalyzte #24
Posted 20 October 2012 - 03:10 AM
Update:

Version 1.11
  • GPSExcavate "restart" now works properly (apparently I didn't test this enough)
  • Turtle can now dig through gravel
  • Small position error catch (hopefully)

Thanks for all the error reports. Sorry for the wait, been kind of busy at school.
Hopefully this will solve your problems Loki: the code can be a little tricky to modify because it's all over the place. I'll see about putting in some comments, but I have a lot of left random things in that I plan to implement (or planned to implement :P/>/> ).

Also, I have another program that I think will go well with these two. It is completely untested because it's a pain in the butt to set up in the world, but I hopefully can release it in a couple days…
Ikkalyzte #25
Posted 22 October 2012 - 06:14 AM
Almost got the previously untested program working, but it looks like it'll have to wait another week. In the mean time I may add some rednet functionality to these two.
Also, would anyone want to use a treefarming program? I feel like I should include it for the sake of completeness, but I know everyone and their dog has already made one.
ChunLing #26
Posted 22 October 2012 - 08:22 AM
Yeah, but there's no harm in it, right? I actually probably should put on in my package, but I'm not that interested in tree farming. I just plant a bunch of trees and eventually use an excavate-style function to take them all out at once.
lokilotus #27
Posted 25 October 2012 - 10:47 PM
Ooh, updates!

Am curious to see how you did it without mucking everything up like I did ^_^/>/> (Still a code noob over here)

Downloading again and trying out :D/>/>

I'd enjoy a Treefarming Program- Like your code (even if it ain't clean, but who am I to talk, eh?) and I never know which one to download. As a side note, I was thinking of making one myself that would go around a Pam's Mods tree and collect all the fruit before harvesting… Not sure if a normal treefarming program would do that. But Anywho. Would like it if you're prepared to put it up :)/>/>

Am excited about the unreleased program too! :D/>/>

Thanks again!

-Loki


EDIT: Had another idea for a treefarming program: ExtrabiomesXL. Haven't seen one that can cut down a huge fir tree. And I have a few hours tonight… :P/>/>
Ikkalyzte #28
Posted 26 October 2012 - 04:51 AM
Update:

Version 1.2
  • GPSExcavate now no longer needs GPS! Hooray! Just remember to restart it in its old starting position, or else it won't work. The name will stay the same for the time being, just because it's easier that way :D/>/>
  • Proper saving of position! It should now start exactly where it left off.
  • Goto program changed slightly
I think I solved several problems with the stopping - restarting this way. It never really needed the GPS, it was just easier. Anyone have any good ideas for names? I left it as this for this version, but I may change it if I get a better name :)/>/>
Let me know if you get issues with the stopping: it doesn't seem to respond right away for me, but it might just be lag, I'm not sure…


As for the treefarming program, it's actually complete, but I need to go through it and bugfix, and make it more user-friendly.

Loki: Comments are coming soon, I promise… :D/>/>
Seriously though, I will comment things. The giant fir trees I've actually never seen, so I might have to take a look. Sounds pretty cool.
ChunLing #29
Posted 26 October 2012 - 05:42 AM
GPS/Inertial Excavator
lokilotus #30
Posted 26 October 2012 - 11:09 AM
Ooh, more updates! :)/>/>

Take your time, I'm in no rush; my philosophy is do it slow, do it right. Don't let us (ME) push you for features and updates. Release each version when YOU think it should be released. :D/>/>

In terms of the name, how about Positional Excavator? Or maybe GPSExcavate- Nohost Edition? :)/>/>

Comments coming soon! Yay! (But don't let me push you!)

You could release the treefarming program as an open beta, so we could help bugtest it for you? :)/>/> Just an Idea. :)/>/>

So many emoticons in this post! :D/>/>

-Loki
Zecharian #31
Posted 27 October 2012 - 11:45 PM
Greetings! I currently seem to have a slight issue using the 1.2 version. I have Computercraft 1.45 installed and when I attempt to use the GPSExcavate i get the following error:

parallel:22: GPSExcavate:99: Tried to go to low :D/>/>

Now I started the program like so:

GPSExcavate 5 5 5

To dig a 5 x 5 room thats 5 deep. It does the whole back and forth and covers the 5 x 5 area, goes to dig down (the block below it disappears) and then the error comes up on the screen. Now its just normal stone below the turtle, and it did dig out the spot, but looking at the source, its supposed to go down, but seems to think it cannot at all. A second time I tried it from the same positions and same command, it went and dug down, but stopped when it hit an open area below where it was digging (a cave) and gave the same error.

I'm do know LUA enough to get by and program some interesting things, but the code looks fine to me at glance. Hopefully you or someone may have some ideas.
Ikkalyzte #32
Posted 28 October 2012 - 12:59 AM
Thanks for the bug report; however, I actually removed that error when I changed the code over to not use GPS. Since it actually no longer exists in the code, I would suggest you download the latest version; if you still get it then something is really weird.
Ikkalyzte #33
Posted 28 October 2012 - 01:50 AM
Ok, guys, here's the beta of the tree farming program. I haven't done anything but get it running, so expect it to be pretty rough.
I know that there are some issues with the text help, but that is a pretty low priority. I just want it to be working properly.
There are also some pretty strict limitations for the farm; here's an example of what it should look like:

[][][][][][][][][]
[]u[][]u[][]u[]
[][][][][][][][][]
[][][][][][][][][]
[]u[][]u[][]u[]
[][][][][][][][]t

where u are the trees and t is the turtle. There should also be a fence around this whole area.

Pastebin: http://pastebin.com/Jf74Kuw4
ChunLing #34
Posted 28 October 2012 - 05:08 AM
You should have torches too if you're needing a fence.
Ikkalyzte #35
Posted 28 October 2012 - 07:35 AM
What I did with mine is I put water one block down, flowing toward a central point. The only spot that has a block is the turtle's "home"; you could even have a floating tree farm.
ChunLing #36
Posted 28 October 2012 - 09:22 AM
That's a pretty good idea, that way you get the saplings without having to run around after every stray leaf. Flowing water is still one of the great automation tools, even in the modern era.
DZCreeper #37
Posted 09 November 2012 - 01:15 PM
Got this error when attempting to run the program.

parallel:22: GPSExcavate:163: attempt to compare number with string expected, got number
Ikkalyzte #38
Posted 10 November 2012 - 09:04 AM
Sorry about the absence guys, school's been a little busy. However, I have finally made the treefarming program workable! It now takes advantage of the extra slots, and it works properly without a fence. It still doesn't have a way to stop it, nor does it have rednet capability - I'm going to add rednet to the excavate program first.
Also, I have it refueling from the wood it collects: is this ok, or does it need an option?

Pastebin: http://pastebin.com/0LnpS3Zm

Got this error when attempting to run the program.

parallel:22: GPSExcavate:163: attempt to compare number with string expected, got number

I think you have fuel requirements for turtles off, is that true? I'll see if I can build in something for that. For now, if you want you can just take out the refueling lines.
I may just upload separate versions for with and without fuel needs, because that would be a lot easier.
DZCreeper #39
Posted 11 November 2012 - 05:13 PM
Yes, I was trying without fuel turned on. I am going to take out those lines then.
DZCreeper #40
Posted 11 November 2012 - 05:55 PM
Ok, new bug thingy. I took out the refuel lines. Now the error I get is goto:280: attempt to compare with string expected, got number

The program still runs, but it is buggy. As in I tell the turtle to dig a 5x5x5 hole, its digs 1 layer thats much larger than 5x5.

Edit: I feel dumb, I didn't take out the refuel code from the GOTO program. I fixed that myself.
Ikkalyzte #41
Posted 13 November 2012 - 08:44 AM
Does it work now? Or is the one layer problem still there?
DZCreeper #42
Posted 13 November 2012 - 12:18 PM
No, it works great, as soon as I can get 3 diamonds for a pick, I am going to make my first legit wireless mining turtle and use your code to strip mine many, many chunks.
DZCreeper #43
Posted 14 November 2012 - 05:35 PM
Okay, had 1 small problem that hung me up for a whiles, actually 2, and now just 1 new one. The first was lack of diamonds, a few hours of mining fixed that. The next was that when the turtle would drop off its items, it would try to refuel, which with the refuel setting turned off, caused a problem. Easy to fix. The new problem is that whenever the dropoff runs, its works, and goes back to its position. But there the problem appears. After it goes back, it mines 1 block, runs dropoff again, and continues to repeat that pattern until I stop the turtles with "P" and restart the program using "GPSExcavate restart". I can't figure out what is wrong, please look into fixing this if possible.
Ikkalyzte #44
Posted 15 November 2012 - 10:00 AM
Update:

Version 1.3
  • 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.
Finally, tree farming program complete! Let me know if you get issues with it, because I've basically been editing code that I made just after being introduced to lua.

DZ, your problem was a pretty minor one, and it got fixed, as well as put out some non-fuel programs. Hopefully people like them.
DZCreeper #45
Posted 15 November 2012 - 11:58 AM
*Downloading, and mining out my massive 64x64 pit of death.

Edit: When it tries to mine a piece of bedrock, the code fires properly. However, I wish that the turtle would return to dropoff point when that happened. I just dug a pit that was 63 blocks deep and I died twice trying to get the mining turtle back before I remembered my long fall boots.
EntombedJester #46
Posted 16 November 2012 - 02:30 PM
I like your code but i have some issues with it mostly that it isn't as fast and efficient as it could be. If you had it mine out the blocks like this http://i.imgur.com/eKqCJ.png where the turtle mines the three blue blocks before continuing. Also it seems to go all the way back to the corner it started from in order to start the next layer instead of just dropping down after it finishes a layer. Also i get this wierd bug sometimes where after the turtle drops off and refuels it will go up and off to the right for no reason, it also will sometimes restart the mining process and if i don't catch it it will mine out an area i don't want it to.
Ikkalyzte #47
Posted 18 November 2012 - 08:46 AM
Update:

Version 1.31
  • Bugfixes: FarmTree now works (very stupid error on my part)
  • Minor changes to FarmTree, cleaning up some code
  • No changes to other programs
I will work on making the excavation code more efficient, Jester. I had planned to do that but had forgotten in the midst of making new programs :)/>/>
I have had your bug before, but not recently: do you have the most recent version? I hadn't figured out what made it, so it's possible it's still there.

DZ, that's a good idea. I will implement it now, and you'll have it in the next update
Ikkalyzte #48
Posted 18 November 2012 - 12:19 PM
Update (yes, again):

Version 1.32
  • 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 setting

Sorry for the quick double update. I apparently broke some things when I cleaned up the code.
The excavation efficiency will come, as soon as I'm sure there are no more bugs :)/>/>
Chigy #49
Posted 21 November 2012 - 04:10 PM
i did GPSExcavate 15 15 10. The turtler did a 15X15, then moved 15 to the left, dug down 1, and did a seperate 15x15.

I tried a GPSExcavate 2 2 2. It did a 2x2, unloaded, and stopped 1 block below where it started.
Atukaski #50
Posted 22 November 2012 - 02:11 AM
er guys can u use a computer to remotely control the turtle that's GPSexcavate'ing?
Well basically i just started a world but every time when i tell the turtle to start digging and give it enough time, i need to go down the pit so that i can tell them to save their position and often die so. So is there a way to do that with a computer at the top of the pit instead? (yes i am totally new to the mod and i wanted to start my turtle in my house so that i don't get ambushed by slimes every time i go restarting/ starting up a turtle)
ChunLing #51
Posted 23 November 2012 - 03:51 AM
You need a remote control program that incorporates an excavating program (or has the ability to remotely command another program to run). Here's one that does both. If you're using GPS excavate, you can activate it remotely by using the "xqtfl" command.
Atukaski #52
Posted 24 November 2012 - 12:33 AM
By the way the non-fuel excavation program is bugged in terms of directions
TheEisbaer #53
Posted 24 November 2012 - 05:56 AM
HELP: I'm new to this. I downloaded the goto program, one stationary computer is GPS hoster and i typed in "gps -295 65 344" f.e. and on the turtle I copied the GOTO program and now if I type in "goto -295 65 346" it says "goto:277: Out of GPS range. How to fix that?
ChunLing #54
Posted 24 November 2012 - 06:08 AM
More GPS arrays to cover the area you're moving to/through.
TheEisbaer #55
Posted 24 November 2012 - 06:16 AM
okay i got three of GPS hosters now. but now the turtle goes up moves one block forwards one block backwards and then i got : "goto:28: attempt to compare__lt on nil and nil" :/
I have to use 4 GPS hosters because i want to make a stripmining program the "room" is 2 blocks high so i have to build a gps hoster on hight "2" …
lokilotus #56
Posted 26 November 2012 - 11:11 AM
I'm back! :D/> Need to play more with CC.

Anywho. It seems all I'm doing is bugreporting here and not actually offering improvements, but there's a flaw in FarmTree.

yesno() doesn't work- causes infinite loop. I've tried to fix it myself, but I keep getting errors on line 227 where it's called (I think the only time it is)- the save dimensions part of the script. Doesn't seem to like me, however many then statements I put in- it's complaining that the if loop doesn't have a then but it does- and I add more and it complains I've got none too. I delete them all and I still don't have one (obviously).

No idea how this could be fixed, but I'm happy to provide my edited version so you can see what I tried to do to fix it- it originally crashed with another error, but by editing the yesno() code I fixed that but now I've got the infinite loop. Oh well. Happy to provide my edits like I said before.

Anywho. Still love that I don't need GPS towers for Goto and Excavate. :D/>

-Loki
Ikkalyzte #57
Posted 02 December 2012 - 04:52 PM
Update:

Version 1.4
  • 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 level
Finally! I think I got all the modifications you guys wanted in there. Sorry for not being active on the thread, kinda wanted to have something to show for myself as well as being busy. Thanks to loki, jester, and DZ for suggesting modifications and bug reports. Also thanks to ChunLing for helping other users. I haven't let computercraft go, don't worry!

Chigy, I've never seen your problem before. Let me know if this update still has it, because it seems to work for me.

Next project is centralized rednet control with an interface. Should be fun. I gave up on my previous sorting turtle program, because it's too much of a pain to set up for the user. Use redpower when it comes out, buildcraft until then (maybe logistics pipes) :P/>.
DZCreeper #58
Posted 03 December 2012 - 09:51 AM
Thanks for all the work man. I am going to see how much faster the new mining program is. Cause I use this on my server, and I don't keep the server on 24/7. But if a turtle is near the bottom of a pit, I can't pause it. Therefore, I can't turn the server off, or the turtles while lose their spot in the pit. But with faster mining, I don't have to wait so long to turn the server on and off.
Ikkalyzte #59
Posted 03 December 2012 - 02:22 PM
I'm pretty sure you can send the turtle a rednet message "stop", and it will stop. It should reply with "stopped" if it's working properly. It's not fully implemented or bugtested, but I will be making this easier with my user interface. For me, the thing is that I have an IC2 jetpack, so I don't worry about it :P/>

On a related note, does anyone know how to show changes in an interface without re-writing the whole screen? It's kind of a pain to do this every time.
Peewee #60
Posted 04 December 2012 - 03:06 AM
Hmm, my GPSExcavate turtle is acting strangely. I told it "GPSExcavate 5 5 5" as a test, it instead started digging in this pattern: http://i.imgur.com/nw4Ye.png down to bedrock, though it did at least return to the surface correctly.

Also, FarmTree has a typo in line 15: it should not use camelcase for keypress()
DZCreeper #61
Posted 05 December 2012 - 05:58 PM
Same issue as Peewee, I also ran a 5 x 5 x 55 sized hole. I will test with a 4 x 4 x 4 hole to see if the problem remains.

Same issue, except with my 4 x 4 x 55 hole, it returned to start correctly, unlike with a 5 x 5 x 55 hole. I call my first result a fluke, as I ran GPSExcavate without "GOTO", which may have been the cause. I really don't like the staircase pattern it made out of my landscape, hopefully this problem is easy to fix.
Ikkalyzte #62
Posted 05 December 2012 - 07:44 PM
Yeah, it will not work without goto. I will make that more clear in the op; sorry about the damage.

Edit: It doesn't need gps, in case you were wondering… just goto.
Edited on 05 December 2012 - 06:52 PM
Peewee #63
Posted 06 December 2012 - 05:09 AM
I do have goto installed, and I test programs in a sandbox world, so no harm done. :)/>
First I do this…
[attachment=745:2012-12-05_11.14.39.png]
Then run the program like this…
[attachment=746:2012-12-05_11.14.57.png]
It replies like this…
[attachment=747:2012-12-05_11.15.07.png]
And digs down to bedrock in a stair pattern.
[attachment=748:2012-12-05_11.19.31.png]

This time it didn't return to the surface when it hit bedrock.
MrFrostmaul #64
Posted 06 December 2012 - 06:01 AM
Hello, I run the program "GPSExcavate <side> <depth>" etc.

It all works fine with the message about dropoff and refuel.

But when I run it come sup with "GPSexcavate:294: attempt to compare nil with number"

What does this mean

I have entered the code fine and not edited it and have the goto downloaded
Ikkalyzte #65
Posted 06 December 2012 - 11:05 AM
Frostmaul, it looks like you haven't entered numbers as your dimensions. Can you post how you activated the program?

Peewee, when I tested it in my world it seemed to work, so I will try it again when I get a chance tonight with your numbers. Hopefully it's a simple fix :(/>

Edit: Nevermind, I found the staircase problem. It was introduced when I made the digging more efficient. Should have it fixed today. Yay!
Edited on 06 December 2012 - 10:19 AM
Peewee #66
Posted 06 December 2012 - 11:30 AM
Hehe, sounds like you missed a step in the standard software release process: before releasing to the public, run the installer script (in this case, pastebin get <blah> <foo>) on a separate machine (new virtual machine, or in this case, a new sandbox save with a new turtle) and make sure it actually runs correctly. :)/>

Thanks!
DZCreeper #67
Posted 06 December 2012 - 02:10 PM
Okay, does that mean it is already out, or is it going to be fixed today, but not done yet? Either way, great news. I also think you should make another program after you fix that bug. Just something that will run GPSExcavate, but in "batch mode". That would mean, you tell the program the size of the hole like normal. You then place chests in the second slot, because fuel normally goes in the first slot correct?

Example: I run GPSBatch like so. "GPSBatch 16 16 16 4" This makes a hole 1 chunk is diameter, and the same depth. After digging the first hole, it places all of its items in the chest you set out for it. It then turns left, moves 16 blocks forward and turns left, placing a chest. Then it turns right twice, to align itself with the edge of the last hole. It then digs a hole the same size as the previous until there are 4 holes total.

Let me know what you think, I thought it would be useful for prolonged automated mining runs.
Ikkalyzte #68
Posted 06 December 2012 - 04:59 PM
Update:

Version 1.41
  • 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
I had figured the bug out, I just was on mobile and so couldn't actually edit the program, pastebin, etc. And peewee, I had tested it, and apparently the small change I made afterwards was just a huge derp of a change. Lesson learned: test again after any changes :P/>

DZ, this would be possible, but why wouldn't you just have the turtle dig a 64 by 64 instead of four 16 by 16s? Or am I misunderstanding your idea?…
DZCreeper #69
Posted 07 December 2012 - 07:08 AM
You are miss understanding the point somewhat. For 1, the batch mode would allow me to have get rare materials faster. Rather than running 1 turtle digging a massive area, it digs a 16x16 area all the way to bedrock, then repeats that 4 times, so rather than waiting for an hour or so while its digs up nothing but dirt and stone, I can be bathing in diamonds. Also, if the program limits to 64x64 holes by default, then batch mode would allow even larger holes say up to 4096 blocks diameter. 64 blocks holes, in 64 times batch mode, though that would be extreme.
DZCreeper #70
Posted 07 December 2012 - 12:28 PM
Another problem with the refueling functionality. parallel:22: GPSExcavate:147: attempt to compare number with string expected, got number

Edit: I removed all code related to refueling, and it works again, and I must say, I am impressed with the speed improvements.
Ikkalyzte #71
Posted 07 December 2012 - 06:52 PM
Found the bug; just forgot to edit the part in the actual refueling. Haven't uploaded the new version, I'm just going to wait a bit to make sure no other bugs turn up and I don't come up with any simple implementations.

Also, about the batch thing: Couldn't you just start it lower? There are no limits on side length, as well. I might make an implementation anyway, but I just don't see the usage myself.
DZCreeper #72
Posted 08 December 2012 - 06:16 AM
Ok, its just I am lazy I guess. Also, I would check for some gravel related issues, I somehow ended up with a layer of stone and ores being completely missed after the turtle hit a large gravel pocket. Not sure what happened.
lokilotus #73
Posted 08 December 2012 - 01:18 PM
Thanks to loki, jester, and DZ for suggesting modifications and bug reports.

That's Cool, glad I can be of some use somewhere to someone. :D/>


Sorry for not being active on the thread, kinda wanted to have something to show for myself as well as being busy. I haven't let computercraft go, don't worry!

DW about it, I've been real busy with family problems myself.

I haven't let computercraft go, don't worry!

Yay! :D/> One less thing to panic about ;)/>


Finally! I think I got all the modifications you guys wanted in there.

Even Comments? XD

Upgrading now :)/>

YAY! A POST FROM ME WITH NO BUG REPORT YET! :D/>

Oh, there'll be one, I'm sure. Give me time. ;)/>
Ikkalyzte #74
Posted 09 December 2012 - 08:44 AM
Update:

Version 1.42
  • Comments to GPSExcavate! Finally, Loki can rest :)/>
  • Bugfixes: Unlimited fuel catch now works properly, small fixes around excavation program
  • No changes to other programs
There you go, Loki. I didn't forget, I swear…
DZ, thanks for the fuel bug report. I may work on the batch thing anyway, I just don't see why it would be more useful. Not sure about the gravel thing either; will do some testing.
Now to work on rednet controller…
lokilotus #75
Posted 09 December 2012 - 09:40 AM
YAY! :D/> :D/> :D/> :D/> *parties*

Ahem. Thanks :)/>

Will update in a sec and continue to report bugs for ya :)/>

Yay! Another post w/o a bug! :D/>
Ikkalyzte #76
Posted 10 December 2012 - 01:35 PM
Update:

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
Hopefully this fixes your problem, DZ. My turtle didn't miss a layer, but it just stopped, so I knew something was wrong. Let me know if it doesn't.
Modernkennnern #77
Posted 11 December 2012 - 04:03 AM
Oh yeah, sorry, forgot to do that too when I added the direct code -_-/>/>
As well, I put this out there to be used. As long as they don't claim it as they're own, I think I'm ok :)/>/>

Edit: Pastebin links now added


where are the Pastebin Links?
Ikkalyzte #78
Posted 11 December 2012 - 06:54 AM
Pastebin links are in the names, just click on them. I will add them more explicitly when I get off mobile
soccer16x #79
Posted 14 December 2012 - 01:35 PM
I really like these programs and was just wondering, when does it save the location for the GPSExcavate? Because just as a test for it i was just quitting out after a layer or so just to see that the program did in fact work and the only thing that happened for me when i came back in and restarted was that it said there was no file. So when does it save?

EDIT:Okay so I see how it saves by pressing "p" but would there be anyway you could implement an autosave after every time it completes a section?
Ikkalyzte #80
Posted 14 December 2012 - 07:28 PM
That's a smart idea. I will implement that now.
As well, I have added a functionality to not collect certain blocks. This is not useful to me (I use IC2 recyclers), but it seemed like something that would save fuel and time if you didn't want the cobble/dirt etc. However, I do not have time to test this right now; will probably release in a couple days.

Edit: I currently have it saving each time it reaches the edge. Is this often enough? I could easily make it every movement, but that seemed unnecessary.
Edited on 14 December 2012 - 06:36 PM
soccer16x #81
Posted 15 December 2012 - 03:57 PM
Yes I believe after every time it reaches the edge would be enough and do agree that after every movement would be unnecessary since having it just restart from the edge would be better than having to completely restart everything or whatever just because of you leaving the chunk and it unloading,And then would you also be able to do something where on startup it would go back to its home location so you could restart it? Or be able to use a computer to restart it, since you can use a computer to have the turtle stop?
Ikkalyzte #82
Posted 15 December 2012 - 05:06 PM
Update!

Version 1.5
  • 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

I ended up making the turtle save every movement, because it seemed to be glitching out half the time otherwise. Just remember to start it from its "base" position when restarting.

I will add the functionality of sending it back to its base automatically, but only once I've created the rednet control system. For now, just set a goto location at the base to make it easier on yourself.
soccer16x #83
Posted 15 December 2012 - 05:13 PM
Thanks for the update! :)/> and also for farmtree I keep getting an error when setting up my tree farm. One it says Would you like to save your settings?(y/n) it gets the error farmtree:15: attempt to call nil
Ikkalyzte #84
Posted 17 December 2012 - 11:10 AM
Update!

Version 1.51
  • Tiny update to FarmTree to fix misnamed function

Thanks for the bug report. That was probably the smallest bug I've ever fixed :)/>
Hopefully everything's working well for everyone else. Progress on rednet control is slow, but once it gets to the holidays I'll have lots of time.
soccer16x #85
Posted 17 December 2012 - 12:03 PM
Well at least the fix was easy >.< but anyway thanks for the update :)/> and rednet control would be fantastic cant wait to try it out once you get it done. Also, Hate to bother you again but now when at where it says would you like to save you settings? (y/n) no matter what you push nothing happens.
Ikkalyzte #86
Posted 17 December 2012 - 12:53 PM
Update!

Version 1.52
  • Tiny update to FarmTree to fix failed function

Thanks, sorry for the fails. It should work now… I hope :P/>
soccer16x #87
Posted 17 December 2012 - 02:35 PM
Alright it work,but after the first time it did everything it then went down one level for an unknown reason, and when i redo my farm and have it setup again it now only cuts down the bottom 2 logs.

EDIT: The first thing didnt happen the 2nd time though. It might have been that i had water under where the turtles home was?

EDIT:And the second was fixed when i placed the log back into the 3rd slot that was filled with something else
Ikkalyzte #88
Posted 18 December 2012 - 10:09 AM
I haven't seen the first problem in a while; water should be fine afaik. The second problem, yes, it needs to have an empty inventory when starting other than the saplings. I will look at the code tonight
mrchbx #89
Posted 18 December 2012 - 10:51 AM
Let's say, the client crash and the turtle stopped. How do I return the turtle to the start position to write "gpsexcavate restart" and continue working?

ps sorry for my english)
soccer16x #90
Posted 18 December 2012 - 12:24 PM
What you would need to do is to set up a gps tower and then on startup have it do turtle.digUp() so that way it has a clear path and then have it do shell.run("goto", "x","y","z") with the x,y and z being the coords of your start position.
mrchbx #91
Posted 18 December 2012 - 11:44 PM
I do not quite understand how to implement it, English is lame …

Solved the problem differently:
http://pastebin.com/SMAva9ZM - 'back" command, turtle will return to the starting position

http://pastebin.com/UW964Nji - sometimes turtle don't reaches the start. Then I can easily change the location of a turtle with this program
w = turtle.forward()
q = turtle.turnLeft()
e = turtle.turnRight()
t = exit
Con No 1 #92
Posted 23 December 2012 - 03:49 PM
Do you think you could make it spit out the non-wanted items less frequently? Instead of every 2 steps, maybe every stack of that item.
DZCreeper #93
Posted 24 December 2012 - 07:23 AM
Same as above. It really slows down the turtles when they constantly check for unwanted items. Maybe when they run out of inventory space they dump any unwanted items, then continue mining if they have 4 slots or more free. That would really save time.
Ikkalyzte #94
Posted 25 December 2012 - 07:58 AM
Haha that's what it's supposed to do. Let me check the code :)/>
jaruca #95
Posted 25 December 2012 - 10:38 AM
I tried using some of the programs on my private server, the Goto and GPSExcavate programs both work amazingly. When I tried the Treecuttin' program on the other hand, it had a few problems. Firstly, when it was setting up (auto) it decided to do a 180 and start destroying the chest and some of the fence. When I did it manually, it started 'planting' them. It would go next to the spot the stuff should be planted at, turn to it, then NOT plant anything. After it did this, it just kept going, and going, and going. It broke through my fence and kept attempting to plant the saplings (never planted anything). If it means anything, I downloaded it off of pastebin using the 'pastebin get idhere name' command. Anyway, that's what happened to me. If you have any ideas of anything that I did wrong, I'm open to them. (Additional stuffs- I did have a one block space between my fence, it was in the bottom left corner (and facing the right way), there were two block spaces between trees, and it was 21x21 as the farm size)
Ikkalyzte #96
Posted 25 December 2012 - 11:33 AM
Update!

Version 1.53
  • 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

Apologies for the terrible treefarmer, Jaruca. It was made when I was very new to lua, and I could do it much better now, but I really don't feel like re-writing it. It needs to be started with saplings already planted; I've now made that clear in the OP. It should work if you plant the saplings first, but if it doesn't let me know.
jaruca #97
Posted 25 December 2012 - 01:26 PM
Update!

Version 1.53
  • 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
Apologies for the terrible treefarmer, Jaruca. It was made when I was very new to lua, and I could do it much better now, but I really don't feel like re-writing it. It needs to be started with saplings already planted; I've now made that clear in the OP. It should work if you plant the saplings first, but if it doesn't let me know.

Thanks! Works really good now- except with rubber trees. I used some of 'em on the farm and it mines the block at the turtle's height, and the block at the height of the sapling. Then it just plants the sapling and goes away.
Anyway, thanks for helping. Now I can actually make stuff 'cause I'm not living off firs.

Oh, and that program isn't terrible. For me, it's amazing. The most I can really do is check the fuel level… I guess it's something.
jaruca #98
Posted 25 December 2012 - 01:31 PM
Update!

Version 1.53
  • 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
Apologies for the terrible treefarmer, Jaruca. It was made when I was very new to lua, and I could do it much better now, but I really don't feel like re-writing it. It needs to be started with saplings already planted; I've now made that clear in the OP. It should work if you plant the saplings first, but if it doesn't let me know.

Thanks! Works really good now- except with rubber trees. I used some of 'em on the farm and it mines the block at the turtle's height, and the block at the height of the sapling. Then it just plants the sapling and goes away.
Anyway, thanks for helping. Now I can actually make stuff 'cause I'm not living off firs.

Oh, and that program isn't terrible. For me, it's amazing. The most I can really do is check the fuel level… I guess it's something.

It takes out the rubber trees it looks like now. Weird. Didn't the first time around (took out some that grew back when it did its second pass).
jaruca #99
Posted 25 December 2012 - 01:35 PM
Update!

Version 1.53
  • 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
Apologies for the terrible treefarmer, Jaruca. It was made when I was very new to lua, and I could do it much better now, but I really don't feel like re-writing it. It needs to be started with saplings already planted; I've now made that clear in the OP. It should work if you plant the saplings first, but if it doesn't let me know.

Thanks! Works really good now- except with rubber trees. I used some of 'em on the farm and it mines the block at the turtle's height, and the block at the height of the sapling. Then it just plants the sapling and goes away.
Anyway, thanks for helping. Now I can actually make stuff 'cause I'm not living off firs.

Oh, and that program isn't terrible. For me, it's amazing. The most I can really do is check the fuel level… I guess it's something.

It takes out the rubber trees it looks like now. Weird. Didn't the first time around (took out some that grew back when it did its second pass).

Ok, when it did its third pass, I stopped it (sorry for the triple post) it didn't cut down the entire tree- but a different kind of tree this time (it does this kind of thing for specific trees each pass).
Ikkalyzte #100
Posted 25 December 2012 - 05:06 PM
What kind of tree are you trying now? I think the reason that the rubber trees don't always work properly is that the turtle compares to the wood, so that it doesn't dig leaves. The block id of resin-containing wood is different from that of normal rubber wood, so it won't think that there is wood there. If you want, the solution to this would be to replace the turtle.compareUp() on line 80 with turtle.detectUp(), so it mines the entire tree. That shouldn't introduce any major bugs, but it will take longer to cut down the trees.
jaruca #101
Posted 25 December 2012 - 06:19 PM
What kind of tree are you trying now? I think the reason that the rubber trees don't always work properly is that the turtle compares to the wood, so that it doesn't dig leaves. The block id of resin-containing wood is different from that of normal rubber wood, so it won't think that there is wood there. If you want, the solution to this would be to replace the turtle.compareUp() on line 80 with turtle.detectUp(), so it mines the entire tree. That shouldn't introduce any major bugs, but it will take longer to cut down the trees.
I'm using spruce trees. Thanks for the help, working great now with the change… although I don't understand the spruce thing, 'cause from what I know, they're should all be logs.
Kravyn #102
Posted 27 December 2012 - 06:36 AM
there is a question with the goto that does not make sense why does the center of this codeblock say

		if y > newy then
				yDist = y - newy
		elseif x < newx then
				yDist = newy - y
		end

elseif x < newx then <– if this is supposed to do the Y calculation then why is it calculating X
yDist = newy - y
end


That is part of this code block below


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

this code has the same info written twice…. tonumber(args[6]) and tonumber(args[6])

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
Ikkalyzte #103
Posted 29 December 2012 - 09:23 AM
Update:

Version 1.54
  • Bugfixes to goto and GPSExcavate, fixed fatal error in excavate
  • Same pastebin links: I may release an installer for further convenience

Thanks for the bug reports. It doesn't change much, but I did find a large error in excavate while I was testing.
DZCreeper #104
Posted 29 December 2012 - 09:31 PM
Thanks for the update to save time when turtles drop unwanted items. I have had nearly a dozen turtles mining using your program at layer 10, doing holes 64 blocks wide and long and 7 deep. Because I didn't want to waste time, I had them collect everything. I had amassed well over 100k cobble. Now I can setup a cobble gen, and just have turtles ignore the damn stuff.

Edit: If your not busy, I got a program idea. Make it so that you start said program, and manually orientate it toward 1 chest. You then designate it as chest 1. You then manually move said turtle to chest 2, and mark it as such. The turtle then returns to chest 1. The turtles sucks all items out of chest 1 and places them in chest 2 when it runs out of space.

Short Version:

1. Start Program
2. Navigate to Chest 1 and Mark it
3. Do step #2, except for Chest 2
4. Program records the inputs you gave the turtle for navigating between chest 1 and 2.
5. Program sends turtle to Chest 1, and brings items to Chest 2 when Chest 1 fills.
6. Profit with your now expandable storage

P.S. If turtles count other turtles as chests, then allow Chest 1 to be the turtle itself, by simply typing the word "turtle" when you are supposed to mark Chest 1.
Ikkalyzte #105
Posted 30 December 2012 - 03:20 PM
Update:

Version 1.55
  • 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 (!)

DZ, I actually wrote up a sorting system made of turtles; but it was very inefficient, and a royal pain for the user to set up. Your idea is much more workable, and I might just make a quick implementation. Of course, it would be made fairly simple with GPS :)/>
The only thing I don't understand is the "marking" of chests; did you mean with coordinates? Because turtles cannot yet "mark their territory"… ;)/>
Kravyn #106
Posted 30 December 2012 - 10:12 PM
Can you add a way so that if the turtle was shutdown because of a server crash or restart it will return back to the chest waiting for command or return to last known location and start mining from there?

your code works well when i edited the errors in the 1.53 version but im having to use a auto typer and they suck atm want to keep the formatting but the HTTP is off. I typed the goto into the turtle by hand the first time before I found a typer that workered but as I said it doesnt keep formatting.

did you fix the option where if you told the turtle dont drop anything it wont? because when I attempted that option it would throw all the bottom row of items on the ground no matter what is in it. also I was having the turtle mining marble and when it returned all the marble was not in the chest even though the turtle did bring it back to the chest. it dropped off its inventory and just went back to mining as if it unloaded and when I checked the turtle it was gone.

That only happens if I pick no for drop items. if I pick yes to drop items and dont add anything to the last row it works perfectly it drops everything off into the chest and continues even the marble.

I am enjoying this code just as long as I stick to using the yes to drop items option.

I am updating the turtles soon to the 1.55 hopefully most of the bugs I just said where fixed but if not please look into it.
Atukaski #107
Posted 31 December 2012 - 05:23 AM
So this day i set up my turtle in the world, told it to GPSexcavate, and when it asked me what blocks to not collect, i put sand, cobble, stone and gravel in the bottom (just 1 block each).
The problem is, even i did told the turtle not to collect sand, it did. And it dropped the sand in the output chest (i was mining in a desert and it didn't went down really far so…)
Anyone help?
Atukaski #108
Posted 31 December 2012 - 05:43 AM
nvm, problem solved. The unwanted blocks just pop in the quarry every time it stops. But there we go another problem. Every time when it stops, drops off the things and refuels, it displays this error (i have disabled fuel)

parrallel:22: GPSexcavate:184: attempt to call nil

After displaying that, the turtle dies. But if i call it "GPSexcavate restart", it restarts perfectly at where it left off last time. Hmm strange.
Help? (i am not a lua coder and know nearly nothing about lua)
Ikkalyzte #109
Posted 31 December 2012 - 10:29 AM
Update:

Version 1.56
  • Quick fix for GPSExcavate; declaring functions before calling them is always a smart idea

Fixed your issue, Atukaski. Kravyn, your idea is coming, right now I'm working on a manager for my programs. Should be cool, but it's taking a while :P/>
All the issues you mentioned should be fixed now, so go ahead and update. Any reason to have http api off? I can't think of one, but it's always off by default in singleplayer.
Ikkalyzte #110
Posted 05 January 2013 - 02:55 PM
Still working on the rednet manager guys. Got the main menu done, working on the buttons (it will use mouse navigation!).
Anyway, is anyone interested in a redwood/fir/large tree chopper? That was about the first thing I made in my new world, because I hate chopping the stupid giant trees. It should work on all girths of tree.
DZCreeper #111
Posted 05 January 2013 - 04:30 PM
Tree Chopper? Yes please. Jungle Tree Farm is annoying, and I live in the jungle.
Kravyn #112
Posted 07 January 2013 - 11:53 PM
A redwood and Fir logger would be good have. having it for multiple types would be good so you can get building materials and a hefty amount of charcoal.
DZCreeper #113
Posted 08 January 2013 - 08:19 PM
Someone mind helping me out? I would like to modify GPSExcavate. Basic idea is that when inventory gets full, it places an Ender Chest from Slot 1, and dumps its stuff in there, then breaks it. Same with fuel, except using Slot 2.
jaruca #114
Posted 09 January 2013 - 09:43 AM
Out of curiosity, are you going to be adding something like this –> http://www.computercraft.info/forums2/index.php?/topic/4771-advanced-gps-goto-program-with-position-file/
to your goto program? It basically lets you use it even when you're out of range of the gps towers.
DZCreeper #115
Posted 10 January 2013 - 04:15 PM
Already included, GPS is not needed.
Ikkalyzte #116
Posted 12 January 2013 - 11:38 AM
Update:

Added small tree chopping utility. Hopefully you guys find it useful.

On a related topic, I am still working on a rednet manager; but my plans of having a full program suite are gone. I think I will simply continue to upload these small utilities… I don't really have time to spend on keeping up a bunch of programs anymore. On the other hand, my brother is learning lua, so he may take these over.

The position file thing, I don't really plan on adding - it seems to have too much possibility of error.
DZCreeper #117
Posted 13 January 2013 - 01:50 PM
Here is my little edited version. I took out the part that lets the turtle not give you blocks in its bottom 4 slots. This version also needs 2 enderchests. 1 in Slot 1, and 1 in Slot 2. When the inventory gets full, its pulls out Chest in Slot 1, empties into there, then breaks it. When it needs fuel, it pulls out Chest 2, and pulls fuel from there. Should be bullet proof, I tested it carefully. Best used with a chunkloader of some kind, or a chunkloader turtle. After rednet is added, it will allow totally remote mining operations, with NO human input required what so ever.

Edits:

1. I derped and forgot to remove function that finds fuel level to pull from chest based on distance. No need, it can get fuel anywhere cause of EnderChest. It just pulls until fuel level hits 400.


Links:

Pastebin: http://pastebin.com/bHFtkPPR

Dropbox: https://www.dropbox....1vx/GPSExcavate


Basic Requirements:

Sorting system that empties Chest 1 so the turtle can keep putting stuff in there.

System that keeps fuel in Chest 2, so turtle does not seize up.

Chunk Loaded Mining Turtle.

4 EnderChests (Must be 2 pairs with different colors)
britefire #118
Posted 16 January 2013 - 01:23 PM
I would like to say, I love the GPS Excavate program!

It is amazingly useful, and even better with the new mining method that increases how fast it is!
DZCreeper #119
Posted 25 January 2013 - 04:52 PM
Is this still being worked on? I await my remote rednet control with great anticipation.
The Lone Wolfling #120
Posted 26 January 2013 - 08:37 AM
Would it be possible to add a resume command to directly resume from the current position?

I*think* it would be as simple as removing the goto command from the restart function and not printing the y/n prompt, but I'm not sure.

Also, could you make it so that it puts anything that isn't fuel from the fuel chest into the ores chest instead of waiting for user input? I use enderchests and it's a pain to walk to the quarry and restart it if something goes into the wrong chest.
MegaMech #121
Posted 26 January 2013 - 08:33 PM
Great job, LOVE The GPSExcavate RESTART, it's so great.

One thing you should maybe add is function bedrock() When the turtle is at bedrock level it get's stuck, probably because turtle.dig() returns false, instead of true.
so maybe "if false do bedrock() end"
then when it hit's layer 3 or 4 (GPS Only of course) It will go up and down, digging out anything that isn't bedrock. (I think it was mykhol on FTB who made his turtle do this)

Also is it possible to use your restart part of the program and add it to other programs? Like Sethblings wood program, it's so annoying when it's halfway done cutting a tree and then you get disconnected. Now you gotta tear down the tree and restart it.
Divide_By_0 #122
Posted 07 March 2013 - 01:02 PM
Wow, this looks cool, i will try out excavate and get it going…
Nice tho.

Also, as pastebin is down right now, i cant do it, but i hope you dont mind, im going to pastebin both goto and GPSExcavate so i can download it ingame, i will send the link(s) to the page owner, if he/she would like to put them up on the Post, that would be nice, otherwise, potatos
Riv991 #123
Posted 27 July 2013 - 09:53 AM
When I use GPSexcavate it doesn't return to the chest to drop items it just throws them all over the floor
tebbenjo #124
Posted 02 March 2014 - 04:21 AM
Not to sound ignorant, but is this wounder full program still being worked on, updated and added to, or has the developer left it to the community?
Bomb Bloke #125
Posted 02 March 2014 - 04:32 AM
According to his profile, he hasn't logged in to the forum for over a year now.
tebbenjo #126
Posted 04 March 2014 - 01:12 AM
good, then I feel well within my rights to post my edits to it, thank you:

My server program: Requires button API from https://www.youtube....h?v=i_7gR5PdmrM

m = peripheral.wrap("bottom")
m.setTextScale(.5)
rednet.open("top")
os.loadAPI("button")
button.setMon("bottom")
turtles = {name={},ID={}}
function query()

local function send()
  for i = 0,10 do
   print()
   write("brodcast "..i.." times")
   rednet.broadcast("query quarry")
   sleep(5)
  end
end

local function recv()
  local atempts = 0
  local senderId, message, distance
 
  while true do
   senderId, message, distance = rednet.receive(5)
  
   if senderId == nil or message == nil then
    --print()
    --write("no responce after "..atempts.." atempts")
   
   else
    print()
    write("computer number "..senderId.." said "..message.." from "..distance.."m away")
    for i=1,#turtles.name do
	 if turtles.name[i] == message then
	  message = -1
	 end
    end
    if message ~= -1 then
	 print(#turtles)
	 table.insert(turtles.name,message)
	 table.insert(turtles.ID,senderId)
	 print("and added to table")
    end
   end
  end
end
parallel.waitForAny(send, recv)
redraw()
end
function list()
print()
print("computers found:")
for i=1,#turtles.name do
  print( turtles.name[i].." ID:"..turtles.ID[i] )
end
redraw()
end
function FUNCstop(ID,index)
m.setCursorPos(5,ID+1)
parallel.waitForAny(function() FUNCgetnet(index) end,function() FUNCsendnet(ID) end)
end
function FUNCgetnet(i)
senderId, message, distance = rednet.receive()
m.setCursorPos(5,i+1)
m.write(message)
senderId, message, distance = rednet.receive(60)
m.setCursorPos(5,i+1)
m.write(message)
senderId, message, distance = rednet.receive(60)
m.setCursorPos(5,i+1)
m.write(message)
end
function redraw()
for i=1,#turtles.name do
  button.add(turtles.name[i],"Stop","flash",1,i+1,4,i+1,colors.gray,colors.green,colors.black,function() FUNCstop(turtles.ID[i],i) end)
end
button.draw()
for i=1,#turtles.name do
  m.setCursorPos(5,i+1)
  m.write(turtles.name[i].." ID:"..turtles.ID[i])
end
end
function FUNCsendnet(ID)
m.write("msg sent")
while true do
  rednet.send(ID,"stop")
  sleep(0.5)
end
end
query()
list()
button.add("query","Requery","flash",1,1,7,1,colors.gray,colors.green,colors.black,query)
button.add("Relist","Relist","flash",9,1,15,1,colors.gray,colors.green,colors.black,list)
redraw()

while true do
button.check()
end

replace stop() with this:

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
   rednet.send(data,"Stopping...")
   break
  elseif event == "rednet_message" and message == "query quarry" then
   rednet.send(data, os.getComputerLabel())
   print("got message "..message)
  end
end

and add rednet.broadcast("Saveing") to saveLoc() and a rednet.broadcast("Doen") to the very end, before the rednet is closed

I welcome any edits or additions
Edited on 04 March 2014 - 12:40 AM
tebbenjo #127
Posted 05 March 2014 - 03:27 AM
an update on above:

Still needs button API by DatMorgrimm,
+ now improved support for random "noise" messages on rednet, like on a busy server
* fixed display bugs on server side

QuarryServer.lua:
I apologize in advance for this forums display of tabs, in code segments
Spoiler

m = peripheral.wrap("bottom")
m.setTextScale(.5)
rednet.open("top")
os.loadAPI("button")
button.setMon("bottom")
turtles = {name={},ID={}}
function query()

local function send()
  for i = 0,10 do
   print()
   write("brodcast "..i.." times")
   rednet.broadcast("query quarry")
   sleep(5)
  end
end

local function recv()
  local atempts = 0
  local senderId, message, distance

  while true do
   senderId, msg, distance = rednet.receive()
   message = textutils.unserialize(msg).msg
   messageType = textutils.unserialize(msg).Type
  
   if senderId == nil or message == nil then
	--print()
	--write("no responce after "..atempts.." atempts")
  
   elseif messageType == "query Responce" and message ~= nil then
	print()
	print("computer number "..senderId.." said "..message.." from "..distance.."m away")
	for i=1,#turtles.name do
	 if turtles.name[i] == message then
	  message = -1
	 end
	end
	if message ~= -1 then
	 --print(#turtles)
	 table.insert(turtles.name,message)
	 table.insert(turtles.ID,senderId)
	 print("and added to table")
	end
   elseif message ~= nil then
	print(messageType)
   end
  end
end
parallel.waitForAny(send, recv)
redraw()
end
function list()
print()
print("computers found:")
for i=1,#turtles.name do
  print( turtles.name[i].." ID:"..turtles.ID[i] )
end
redraw()
end
function FUNCstop(ID,index)
m.setCursorPos(5,ID+1)
parallel.waitForAny(function() FUNCgetnet(index) end,function() FUNCsendnet(ID,index) end)
end
function FUNCgetnet(i)
while message ~= "Finshed" do
  senderId, msg, distance = rednet.receive()
  message = textutils.unserialize(msg).msg
  messageType = textutils.unserialize(msg).Type
  m.setCursorPos(5,i+1)
  if messageType == "Stop Responce" and message ~= nil then
   m.write(message.."			")
  end
end
end
function redraw()
for i=1,#turtles.name do
  button.add(turtles.name[i],"Stop","flash",1,i+1,4,i+1,colors.gray,colors.green,colors.black,function() FUNCstop(turtles.ID[i],i) end)
end
button.draw()
for i=1,#turtles.name do
  m.setCursorPos(5,i+1)
  m.write(turtles.name[i].." ID:"..turtles.ID[i])
end
end
function FUNCsendnet(ID,i)
m.setCursorPos(5,i+1)
m.write("msg sent	")
while true do
  rednet.send(ID,"stop")
  sleep(0.5)
end
end
query()
list()
button.add("query","Requery","flash",1,1,7,1,colors.gray,colors.green,colors.black,query)
button.add("Relist","Relist","flash",9,1,15,1,colors.gray,colors.green,colors.black,list)
redraw()

while true do
button.check()
end

I decided that I have made significant enough changes to the original quarry program to re-post it, in it's entirety

GPSExcavate.lua:
Spoiler

-- original by Ikkalyzte
-- http://www.computercraft.info/forums2/index.php?/topic/4574-gps-excavate/
-- this version by tebbenjo
-- http://www.computercraft.info/forums2/index.php?/topic/4574-gps-excavate/page__view__findpost__p__166822
args = {...}
rednet.open("right")
serverID = -1
finshing = false
-- 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 &amp; 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
   finshing = true
   rednet.send(data,textutils.serialize({Type = "Stop Responce", msg = "Stopping..."}))
   serverID = data
   break
  elseif event == "rednet_message" and message == "query quarry" then
   rednet.send(data,textutils.serialize({Type = "query Responce", msg = os.getComputerLabel()}))
   serverID = data
   print("got message "..message)
  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
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...")
  if serverID ~= -1 and finshing then
   rednet.send(serverID,textutils.serialize({Type = "Stop Responce", msg = "Saveing"}))
  end
		sleep(1)
		saveLoc()
		print("Position and dimensions saved. Returning to base...")
  if serverID ~= -1 and finshing then
   rednet.send(serverID,textutils.serialize({Type = "Stop Responce", msg = "Returning"}))
  end
		shell.run("goto","special",0,0,0,0,currentpos.x,currentpos.y,currentpos.z,currentpos.f) --Return to start
		dropAll()
		print("Excavation stopped.")
		if serverID ~= -1 and finshing then
   rednet.send(serverID,textutils.serialize({Type = "Stop Responce", msg = "Finshed"}))
  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, done, restarting, running, w, l, d, backwards, lastSlot = nil, nil, nil, nil, nil, nil, nil, nil, nil, nil
rednet.close("right")
tebbenjo #128
Posted 07 March 2014 - 02:44 AM
Update:

Still needs button API by DatMorgrimm,
+ approximate % finished, based solely on depth yet to go / total depth of requested hole
+ Turtles now announce start up to potential servers
* fixed sevrel rednet unserialize crashes

Server.lua
Spoiler

m = peripheral.wrap("bottom")
m.setTextScale(.5)
rednet.open("top")
os.loadAPI("button")
button.setMon("bottom")
turtles = {name={},ID={},Finshed={},Width={},Lenth={},Depth={},Doen={},PerCntDoen = {}}
function query()

local function send()
  for i = 0,3 do
   print()
   write("brodcast "..i.." times")
   rednet.broadcast("query quarry")
   sleep(5)
  end
end

local function recv()
  local atempts = 0
  local senderId, message, distance

  while true do
   senderId, msg, distance = rednet.receive()
   message = textutils.unserialize(msg).msg
   messageType = textutils.unserialize(msg).Type
   tmpWidth = textutils.unserialize(msg).Width
   tmpLenth = textutils.unserialize(msg).Lenth
   tmpDepth = textutils.unserialize(msg).Depth
   tmpDoen = textutils.unserialize(msg).Doen
  
   if senderId == nil or message == nil then
	--print()
	--write("no responce after "..atempts.." atempts")
  
   elseif messageType == "query Responce" and message ~= nil and tmpWidth ~= nil and tmpLenth~= nil and tmpDepth ~= nil then
	print()
	print("computer number "..senderId.." said "..message.." from "..distance.."m away")
	for i=1,#turtles.name do
	 if turtles.ID[i] == senderId and not turtles.Finshed[i] then
	  message = -1
	 end
	end
	if message ~= -1 then
	 --print(#turtles)
	 table.insert(turtles.name,message)
	 table.insert(turtles.ID,senderId)
	 table.insert(turtles.Width,tmpWidth)
	 table.insert(turtles.Lenth,tmpLenth)
	 table.insert(turtles.Depth,tmpDepth)
	 table.insert(turtles.Finshed,false)
	 table.insert(turtles.Doen,tmpDoen)
	 print("and added to table")
	end
   elseif message ~= nil then
	print(messageType)
   end
  end
end
parallel.waitForAny(send, recv)
redraw()
end
function list()
print()
print("computers found:")
for i=1,#turtles.name do
  if turtles.PerCntDoen[i] == nil then
   turtles.PerCntDoen[i] = math.floor((turtles.Doen[i]/(-turtles.Depth[i])*100)*100) / 100
  end
  print(turtles.name[i].." ID:"..turtles.ID[i].." Diging: "..turtles.Width[i].."m X "..turtles.Lenth[i].."m X "..turtles.Depth[i].."m is "..turtles.PerCntDoen[i].."% doen")
end
redraw()
end
function FUNCstop(ID,index)
m.setCursorPos(5,ID+1)
parallel.waitForAny(function() FUNCgetnet(index) end,function() FUNCsendnet(ID,index) end)
end
function FUNCgetnet(i)
while message ~= "Finshed" do
  senderId, msg, distance = rednet.receive()
  message = textutils.unserialize(msg).msg
  messageType = textutils.unserialize(msg).Type
  m.setCursorPos(5,i+1)
  if messageType == "Stop Responce" and message ~= nil then
   m.write(message.."																			")
  end
end
turtles.Finshed[i] = true
end
function redraw()
for i=1,#turtles.name do
  button.add(turtles.name[i],"Stop","flash",1,i+1,4,i+1,colors.gray,colors.green,colors.black,function() FUNCstop(turtles.ID[i],i) end)
end
button.draw()
for i=1,#turtles.name do
  m.setCursorPos(5,i+1)
  if not turtles.Finshed[i] then
   if turtles.PerCntDoen[i] == nil then
	turtles.PerCntDoen[i] = math.floor((turtles.Doen[i]/(-turtles.Depth[i])*100)*100) / 100
   end
   m.write(turtles.name[i].." ID:"..turtles.ID[i].." Diging: "..turtles.Width[i].."m X "..turtles.Lenth[i].."m X "..turtles.Depth[i].."m is "..turtles.PerCntDoen[i].."% doen")
  else
   m.write(turtles.name[i].." ID:"..turtles.ID[i].." Finshed																			")
  end
end
end
function FUNCsendnet(ID,i)
if not turtles.Finshed[i] then
  m.setCursorPos(5,i+1)
  m.write("msg sent																			")
  while not turtles.Finshed[i] do
   rednet.send(ID,"stop")
   sleep(0.5)
  end
end
end
function CheckButton()
while true do
  button.check()
end
end
function Listen()
local TblNum = 0
while true do
  TblNum = 0
  local senderId, IN, distance = rednet.receive()
  --print("Got: "..IN) --De-bug
  local message = textutils.unserialize(IN).msg
  local messageType = textutils.unserialize(IN).Type

  for i=1,#turtles.ID do
   if turtles.ID[i] == senderId then
	TblNum = i
   end
  end

  if messageType ~= nil then
   if messageType == "Stop Responce" and TblNum ~= 0 then
	m.setCursorPos(5,TblNum+1)
	m.write(message.."																			")
	if message == "Finshed" and TblNum ~= 0 then
	 turtles.Finshed[TblNum] = true
	end
   elseif messageType == "Startup" and TblNum == 0 and IN ~= nil and message ~= nil then
	--print("Startup recived") --De-bug
	--print("Trying Width") --De-bug
	local tmpWidth = textutils.unserialize(IN).Width
	--print("Trying Lenth") --De-bug
	local tmpLenth = textutils.unserialize(IN).Lenth
	--print("Trying Depth") --De-bug
	local tmpDepth = textutils.unserialize(IN).Depth
	--print("Trying Doen") --De-bug
	local tmpDoen = textutils.unserialize(IN).Doen
	print()
	--print(message) --De-bug
	print("computer number "..senderId.." said "..message.." from "..distance.."m away")
	table.insert(turtles.name,message)
	table.insert(turtles.ID,senderId)
	table.insert(turtles.Width,tmpWidth)
	table.insert(turtles.Lenth,tmpLenth)
	table.insert(turtles.Depth,tmpDepth)
	table.insert(turtles.Finshed,false)
	table.insert(turtles.Doen,tmpDoen)
	if #turtles.Doen == nil then
	 TblNum = 1
	else
	 TblNum = tonumber(#turtles.Doen)
	end
	--print(#turtles.Doen)--De-bug
	--print(TblNum)--De-bug
	--print(turtles.Doen[TblNum])--De-bug
	--print(-turtles.Depth[TblNum])--De-bug
	table.insert(turtles.PerCntDoen,math.floor((turtles.Doen[TblNum]/(-turtles.Depth[TblNum])*100)*100) / 100)
	print("and added to table")
	rednet.send(senderId,"query quarry")
	redraw()
   elseif messageType == "PosUpdate" and TblNum ~= 0 then
	local tmpDoen = textutils.unserialize(IN).Doen
	turtles.Doen[TblNum] = tmpDoen
	turtles.PerCntDoen[TblNum] = math.floor((turtles.Doen[TblNum]/(-turtles.Depth[TblNum])*100)*100) / 100
	--print("now "..turtles.PerCntDoen[TblNum].."% Doen") --De-bug
	redraw()
   elseif message ~= nil then
	print("Unknowen message type: "..messageType.."; witch said: "..message)
   end
  end
end
end
query()
list()
button.add("query","Requery","flash",1,1,7,1,colors.gray,colors.green,colors.black,query)
button.add("Relist","Relist","flash",9,1,15,1,colors.gray,colors.green,colors.black,list)
redraw()
parallel.waitForAny(CheckButton,Listen)

GPSExcavate.lua
Spoiler

args = {...}
rednet.open("right")
serverID = -1
finshing = false
-- 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
  if serverID ~= -1 then
   rednet.send(serverID,textutils.serialize({Type = "PosUpdate",Doen=currentpos.y}))
  end
		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) + 1000 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 &amp; 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
rednet.broadcast(textutils.serialize({Type = "Startup", msg = os.getComputerLabel(),Width=edge.x+1,Lenth=edge.z+1,Depth=-(edge.y+1),Doen=currentpos.y}))
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
   finshing = true
   rednet.send(data,textutils.serialize({Type = "Stop Responce", msg = "Stopping..."}))
   serverID = data
   break
  elseif event == "rednet_message" and message == "query quarry" then
   rednet.send(data,textutils.serialize({Type = "query Responce", msg = os.getComputerLabel(),Width=edge.x+1,Lenth=edge.z+1,Depth=-(edge.y+1),Doen=currentpos.y}))
   serverID = data
   print("got message "..message)
  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
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...")
  if serverID ~= -1 and finshing then
   rednet.send(serverID,textutils.serialize({Type = "Stop Responce", msg = "Saveing"}))
  end
		sleep(1)
		saveLoc()
		print("Position and dimensions saved. Returning to base...")
  if serverID ~= -1 and finshing then
   rednet.send(serverID,textutils.serialize({Type = "Stop Responce", msg = "Returning"}))
  end
		shell.run("goto","special",0,0,0,0,currentpos.x,currentpos.y,currentpos.z,currentpos.f) --Return to start
		dropAll()
		print("Excavation stopped.")
		if serverID ~= -1 and finshing then
   rednet.send(serverID,textutils.serialize({Type = "Stop Responce", msg = "Finshed"}))
  end
else --Get rid of save file if turtle is done excavating. I will find a way to have rednet in here too
  rednet.send(serverID,textutils.serialize({Type = "Stop Responce", msg = "Finshed"}))
		fs.delete("GPSExcavateCurrentpos")
end
print("Next hole please? :D/>/>/>/>/>/>")
--Delete variables so they don't persist
args, currentpos, edge, done, restarting, running, w, l, d, backwards, lastSlot = nil, nil, nil, nil, nil, nil, nil, nil, nil, nil
rednet.close("right")

sorry the programs are named *.lua.txt not just .lua this forum only allows attachments of known file types, you can just change it,
for editing I suggest notepad++ as it recognizes .lua files and highlights syntax and indents accordingly
Edits, improvements, suggestions, bug reports, and crash reports welcome; tough I may take a wile to reply, as I'm also working on other projects, this being only a side project.

Thanks for looking, screen shots / video with next update (maybe)
oedze #129
Posted 21 September 2014 - 07:23 PM
Nice program, really smart removing 3 blocks at the time, this makes it a lot quicker :)/> good work, keep it up