-- DIRECTIONS
north = "n"
south = "s"
east = "e"
west = "w"
up = "u"
down = "d"
-- TURTLE POSITION
absPos = {} --{x=0,y=0,z=0,dir=north}
homePos = {}
-- gets all global variables
function init( global )
setfenv(1,global)
-- gps functions included in CC
gpsModule = _G["gps".._G.oldAPISyntax]
end
function isDir( dir )
if dir == north
or dir == south
or dir == east
or dir == west
or dir == up
or dir == down
then
return true
else
return false
end
end
function getDirectionOffset( dir )
local x,y,z = 0,0,0
if dir == up then y = y + 1 end
if dir == down then y = y - 1 end
if dir == south then z = z + 1 end
if dir == north then z = z - 1 end
if dir == east then x = x + 1 end
if dir == west then x = x - 1 end
return x,y,z
end
function getPosition( offset,dir )
local ox,oy,oz = 0,0,0
local x,y,z = absPos.x,absPos.y,absPos.z
if type(offset) ~= "number" then
offset = 0
end
if type(dir) == "string" then
ox,oy,oz = getDirectionOffset(dir)
end
x = x + ox*offset
y = y + oy*offset
z = z + oz*offset
return x,y,z,absPos.dir
end
function setPosition( x,y,z,dir )
absPos.x = x or absPos.x
absPos.y = y or absPos.y
absPos.z = z or absPos.z
absPos.dir = dir or absPos.dir
end
function addPosition( x,y,z )
absPos.x = absPos.x + (x or 0)
absPos.y = absPos.y + (y or 0)
absPos.z = absPos.z + (z or 0)
end
function getHome( offset,dir )
local ox,oy,oz = 0,0,0
local x,y,z = homePos.x,homePos.y,homePos.z
if type(offset) ~= "number" then
offset = 0
end
if type(dir) == "string" then
ox,oy,oz = getDirectionOffset(dir)
end
x = x + ox*offset
y = y + oy*offset
z = z + oz*offset
return x,y,z,homePos.dir
end
function setHome( x,y,z,dir )
homePos.x = x or homePos.x
homePos.y = y or homePos.y
homePos.z = z or homePos.z
homePos.dir = dir or homePos.dir
end
function dirToValue( dir )
if dir == south then return 0 end
if dir == west then return 1 end
if dir == north then return 2 end
if dir == east then return 3 end
if dir == up then return math.huge end
if dir == down then return -math.huge end
end
function valueToDir( value )
if value == 0 then return south end
if value == 1 then return west end
if value == 2 then return north end
if value == 3 then return east end
if value == math.huge then return up end
if value == -math.huge then return down end
end
function turnRight( times )
if type(times)~="number" then times = 1 end
if times<1 then times = 1 end
if times%1~=0 then times = math.floor(times) end
for count = 1,times do
-- turn the dir var
absPos.dir = valueToDir(((dirToValue(absPos.dir) or 0)+1)%4)
turtle.turnRight()
end
end
function turnLeft( times )
if type(times)~="number" then times = 1 end
if times<1 then times = 1 end
if times%1~=0 then times = math.floor(times) end
for count = 1,times do
-- turn the dir var
absPos.dir = valueToDir(((dirToValue(absPos.dir) or 0)+3)%4)
turtle.turnLeft()
end
end
-- locate where the turtle is in the real world by using the built in gps system
-- requires the turtle to have a wireless modem on the right side
function autoSetPosition()
print("gps start")
if peripheral.getType("right")~="modem" then return false end
rednet.open("right")
print("gps step 1")
local x1,y1,z1 = gpsModule.locate()print("gps step 2")
if type(x1)~="number" or type(y1)~="number" or type(z1)~="number" then return false end
local dir = "unknown"
local try = 0
while not turtle.forward() do
try = try + 1
turtle.turnRight()
if try == 4 then return false end
end
print("gps step 3")
local x2,y2,z2 = gpsModule.locate()print("gps step 4")
if type(x2)~="number" or type(y2)~="number" or type(z2)~="number" then return false end
if x2 == x1 + 1 then dir = east end
if x2 == x1 - 1 then dir = west end
if z2 == z1 + 1 then dir = south end
if z2 == z1 - 1 then dir = north end
if dir == "unknown" then
return false
end
print("gps step 5")
setPosition(x2,y2,z2,dir)
print("gps step final")
return true
end
function getFacing()
return absPos.dir
end
function face( dir )
-- stop if dir is not a valid direction
if not isDir(dir) then return end
if dir == up then return end
if dir == down then return end
--
if type(absPos.dir) ~= "string" then
locate()
end
local wantedValue = dirToValue(dir)
local currentValue = dirToValue(absPos.dir)
-- continue looping until you face the desired direction
while currentValue ~= wantedValue do
if (currentValue+1)%4 == wantedValue then
-- disered direction is to the right
turnRight()
elseif (currentValue+3)%4 == wantedValue then
-- disered direction is to the left
turnLeft()
else
-- desired direction is behind us, so turn either right or left
if math.random(0,1) == 1 then
turnRight()
else
turnLeft()
end
end
-- update currentValue variable
currentValue = dirToValue(absPos.dir)
end
end
function moveUp( times,killMobs,destroyBlocks )
if type(times)~="number" then times = 1 end
--if times<1 then times = 1 end
if times%1~=0 then times = math.floor(times) end
if type(absPos.dir) ~= "string" then
autoSetPosition()
end
for count = 1,times do
while not turtle.up() do
if not destroyBlocks then return false end
dig.up(killMobs,destroyBlocks)
end
addPosition(_,1)
end
return true
end
function moveDown( times,killMobs,destroyBlocks )
if type(times)~="number" then times = 1 end
--if times<1 then times = 1 end
if times%1~=0 then times = math.floor(times) end
if type(absPos.dir) ~= "string" then
autoSetPosition()
end
for count = 1,times do
while not turtle.down() do
if not destroyBlocks then return false end
dig.down(killMobs,destroyBlocks)
end
addPosition(_,-1)
end
return true
end
function moveForward( times,killMobs,destroyBlocks )
if type(times)~="number" then times = 1 end
--if times<1 then times = 1 end
if times%1~=0 then times = math.floor(times) end
if type(absPos.dir) ~= "string" then
autoSetPosition()
end
for count = 1,times do
while not turtle.forward() do
if destroyBlocks then
dig.forward(killMobs,destroyBlocks)
else
return false
end
end
addPosition(getDirectionOffset(absPos.dir))
end
return true
end
function goto( x,y,z,dir,killMobs,destroyBlocks )
--print("goto function: x="..tostring(x).." y="..tostring(y).." z="..tostring(z).." killMobs="..tostring(killMobs).." destroyBlocks="..tostring(destroyBlocks))
if type(x)~="number" then x=absPos.x end
if type(y)~="number" then y=absPos.y end
if type(z)~="number" then z=absPos.z end
x=math.floor(x) y=math.floor(y) z=math.floor(z)
if type(killMobs)~="boolean" then killMobs=false end
if type(destroyBlocks)~="boolean" then destroyBlocks=false end
if type(absPos.dir) ~= "string" then
autoSetPosition()
end
while absPos.x~=x or absPos.y~=y or absPos.z~=z do
-- current location
local cx,cy,cz = getPosition()
-- y
if y~=cy then
for count = math.min(cy,y),math.max(cy,y)-1 do
if y>cy then
if not moveUp(_,killMobs,destroyBlocks) then break end
elseif y<cy then
if not moveDown(_,killMobs,destroyBlocks) then break end
end
end
end
-- x
if x~=cx then
for count = math.min(cx,x),math.max(cx,x)-1 do
if x>cx then -- x increasing
face(east)
elseif x<cx then -- x decreasing
face(west)
end
if not moveForward(_,killMobs,destroyBlocks) then break end
end
end
-- z
if z~=cz then
for count = math.min(cz,z),math.max(cz,z)-1 do
if z>cz then -- z increasing
face(south)
elseif z<cz then -- z decreasing
face(north)
end
if not moveForward(_,killMobs,destroyBlocks) then break end
end
end
end
if isDir(dir) then
face(dir)
end
end
Comments