local r = 0
currSlot = 2 --reserve slot #1 for fuel all time!
mfid = 0 --monitor computer's id
osid = os.getComputerID() --turtle's computer id
isSent = false --send all messages just once
fReserve = 10 --fuel can't go below this
print("What radius of circle would you like me to create?")
r = tonumber(io.read())
if r == 0 then
print("Radius 0 circle? Done!")
end
--send message to monitor computer(if any) and write it out locally
function sendM(message)
if peripheral.isPresent("right") and peripheral.getType("right") == "modem" then
rednet.open("right")
rednet.send(mfid, "Turtle("..osid..":("..message, false)
rednet.close("right")
end
print(message)
end
--return gps location if it has a modem and can retrive turtles's location
--if not then return x,y based on turtle's startup location
function gpsLoc(fx,fy)
if peripheral.isPresent("right") and peripheral.getType("right") == "modem" then
rednet.open("right")
local x, y, z = gps.locate(5)
rednet.close("right")
if x == nil then
return "x:"..tostring(fx)..",y:"..tostring(fy).."(rel)"
else
return "x:"..tostring(x)..",y:"..tostring(y)..",z:"..tostring(z)
end
else
return "x:"..tostring(fx)..",y:"..tostring(fy).."(rel)"
end
end
function findBlock ()
if turtle.getItemCount(currSlot) ~= 0 then
return true
end
local tmp = 8
turtle.select(tmp)
while (turtle.getItemCount(tmp) == 0 and tmp <= 16) do
if tmp == 16 then
if isSent == false then --only print once
sendM("Out of blocks! Turtle at "..gpsLoc(x,y))
isSent = true
end
sleep(5)
tmp = 2
turtle.select(tmp)
else
tmp = tmp + 1
turtle.select(tmp)
end
end
isSent = false
currSlot = tmp
tmp = 2
return true
end
function tryPlaceDown (x,y)
turtle.digDown()
if turtle.detectDown() == true then
if turtle.compareDown() == true then
return true
else
sendM("Can't place block("..gpsLoc(x,y)..")!")
return false
end
else
if turtle.placeDown() == true then
return true
else
sendM("Can't place block("..gpsLoc(x,y)..")!")
return false
end
end
end
function forward()
local count = 0;
while not turtle.forward() do
sleep(0) --Calls coroutine.yield to prevent errors
count = count + 1
if not turtle.dig() then
turtle.attack()
end
if count > 10 then
turtle.attack()
sleep(0.2)
end
if count > 50 then
sendM("error?");
sleep(2);
end
end
end
round = function (inputN)
if inputN % 2 ~= 0.5 then
return math.floor(inputN + 0.5)
end
return inputN - 0.5
end
turtle.select(currSlot)
local coords = {}
local coordsCount = 0
local f = 1 - r
local ddF_x = 1
local ddF_y = -2 * r
x = 0
y = r
coords[0 .. "," .. round(0+r)] = true
coords[0 .. "," .. round(0-r)] = true
coords[0+r .. "," .. 0] = true
coords[0-r .. "," .. 0] = true
coordsCount = 4
while (x < y) do
if (f >= 0) then
y = y - 1
ddF_y = ddF_y + 2
f = f + ddF_y
end
x = x + 1
ddF_x = ddF_x + 2
f = f + ddF_x
coords[round(0+x) .. "," .. round(0+y)] = true
coords[round(0-x) .. "," .. round(0+y)] = true
coords[round(0+x) .. "," .. round(0-y)] = true
coords[round(0-x) .. "," .. round(0-y)] = true
coords[round(0+y) .. "," .. round(0+x)] = true
coords[round(0-y) .. "," .. round(0+x)] = true
coords[round(0+y) .. "," .. round(0-x)] = true
coords[round(0-y) .. "," .. round(0-x)] = true
coordsCount = coordsCount + 8
end
checkCoords = function (x0,y0)
if coords[x0 .. "," .. y0] == true then
return true
else
return false
end
end
--watch fuel level and if smaller than the reserve level refuel from slot #1
function fuelProc()
local flvl = turtle.getFuelLevel()
if flvl == "unlimited" then
return true
elseif flvl > fReserve then
return true
else
turtle.select(1)
while turtle.refuel(1) == false do
if isSent == false then
sendM("Out of fuel! turtle at "..gpsLoc(x,y))
print("Please insert fuel to slot #1 to resume!")
isSent = true
end
sleep(5)
end
isSent = false
turtle.select(currSlot)
end
end
-- Move from the center to the first position it can find.
local x = 0
local y = 0
while checkCoords(x,y) ~= true do
fuelProc()
forward()
x = x + 1
end
-- Place a block in the first position.
--findBlock()
--tryPlaceDown() <-block will be placed last so won't be any route blocking at multi lvl structures
-- Keep track of which way the turtle is facing.
facingX = 1
facingY = 0
-- Look clockwise from each block and find the next block in the space.
spinsDone = 0
while (coordsCount > 0 and spinsDone < 5) do
fuelProc()
cX = x + facingX
cY = y + facingY
if checkCoords(cX, cY) then
forward()
findBlock()
tryPlaceDown(x,y)
x = cX
y = cY
coords[x .. "," .. y] = nil
coordsCount = coordsCount - 1
spinsDone = 0
else
-- Check diagnals
if facingX == 1 then
cY = y + 1
newFacingX = 0
newFacingY = 1
elseif facingX == -1 then
cY = y - 1
newFacingX = 0
newFacingY = -1
elseif facingY == 1 then
cX = x - 1
newFacingX = -1
newFacingY = 0
elseif facingY == -1 then
cX = x + 1
newFacingX = 1
newFacingY = 0
end
if checkCoords(cX,cY) then
forward()
turtle.turnRight()
forward()
turtle.turnLeft()
findBlock()
tryPlaceDown(x,y)
x = cX
y = cY
coords[x .. "," .. y] = nil
coordsCount = coordsCount - 1
spinsDone = 0
else
turtle.turnRight()
facingX = newFacingX
facingY = newFacingY
spinsDone = spinsDone + 1
end
end
end
--return to starting point
repeat
fuelProc()
forward()
x = x - 1
until x == 0
turtle.turnRight()
turtle.turnRight()
sendM("Work done!")
x = nil
y = nil
r = nil
coords = nil
coordsCount = nil
Comments