2016-12-11 19:24:52 +00:00
|
|
|
local function follow(id)
|
|
|
|
|
2016-12-11 21:36:36 +00:00
|
|
|
require = requireInjector(getfenv(1))
|
2016-12-11 19:24:52 +00:00
|
|
|
local GPS = require('gps')
|
|
|
|
local Socket = require('socket')
|
|
|
|
local Point = require('point')
|
|
|
|
local process = require('process')
|
|
|
|
|
|
|
|
turtle.status = 'follow ' .. id
|
|
|
|
|
|
|
|
local pt = GPS.getPointAndHeading()
|
|
|
|
if not pt or not pt.heading then
|
|
|
|
error('turtle: No GPS found')
|
|
|
|
end
|
|
|
|
|
|
|
|
turtle.setPoint(pt)
|
|
|
|
|
|
|
|
local socket = Socket.connect(id, 161)
|
|
|
|
if not socket then
|
|
|
|
error('turtle: Unable to connect to ' .. id)
|
|
|
|
return
|
|
|
|
end
|
|
|
|
|
|
|
|
local lastPoint
|
|
|
|
local following = false
|
|
|
|
|
|
|
|
local followThread = process:newThread('follower', function()
|
|
|
|
while true do
|
|
|
|
|
|
|
|
local function getRemotePoint()
|
|
|
|
if not turtle.abort then
|
|
|
|
if socket:write({ type = 'gps' }) then
|
|
|
|
return socket:read(3)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
-- sometimes gps will fail if moving
|
|
|
|
local pt, d
|
|
|
|
|
|
|
|
for i = 1, 3 do
|
|
|
|
pt, d = getRemotePoint()
|
|
|
|
if pt then
|
|
|
|
break
|
|
|
|
end
|
|
|
|
os.sleep(.5)
|
|
|
|
end
|
|
|
|
|
|
|
|
if not pt or turtle.abort then
|
|
|
|
error('Did not receive GPS location')
|
|
|
|
end
|
|
|
|
|
|
|
|
if not lastPoint or (lastPoint.x ~= pt.x or lastPoint.y ~= pt.y or lastPoint.z ~= pt.z) then
|
|
|
|
|
|
|
|
if following then
|
|
|
|
turtle.abort = true
|
|
|
|
while following do
|
|
|
|
os.sleep(.1)
|
|
|
|
end
|
|
|
|
turtle.abort = false
|
|
|
|
end
|
|
|
|
|
|
|
|
-- check if gps is inaccurate (player moving too fast)
|
|
|
|
if d < Point.pythagoreanDistance(turtle.point, pt) + 10 then
|
|
|
|
lastPoint = Point.copy(pt)
|
|
|
|
following = true
|
|
|
|
process:newThread('turtle_follow', function()
|
|
|
|
|
|
|
|
local pts = {
|
|
|
|
{ x = pt.x + 2, z = pt.z, y = pt.y },
|
|
|
|
{ x = pt.x - 2, z = pt.z, y = pt.y },
|
|
|
|
{ x = pt.x, z = pt.z + 2, y = pt.y },
|
|
|
|
{ x = pt.x, z = pt.z - 2, y = pt.y },
|
|
|
|
}
|
|
|
|
|
|
|
|
local cpt = Point.closest(turtle.point, pts)
|
|
|
|
|
|
|
|
local blocks = { }
|
|
|
|
|
|
|
|
local function addBlocks(tpt)
|
|
|
|
table.insert(blocks, tpt)
|
|
|
|
local apts = Point.adjacentPoints(tpt)
|
|
|
|
for _,apt in pairs(apts) do
|
|
|
|
table.insert(blocks, apt)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
-- don't run into player
|
|
|
|
addBlocks(pt)
|
|
|
|
addBlocks({ x = pt.x, z = pt.z, y = pt.y + 1 })
|
|
|
|
|
|
|
|
if turtle.pathfind(cpt, blocks) then
|
|
|
|
turtle.headTowards(pt)
|
|
|
|
end
|
|
|
|
following = false
|
|
|
|
end)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
os.sleep(.5)
|
|
|
|
end
|
|
|
|
end)
|
|
|
|
|
|
|
|
while true do
|
|
|
|
local e = process:pullEvent()
|
|
|
|
if e == 'terminate' or followThread:isDead() or e =='turtle_abort' then
|
|
|
|
process:threadEvent('terminate')
|
|
|
|
break
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
socket:close()
|
|
|
|
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
|
|
|
|
local s, m = turtle.run(function() follow({COMPUTER_ID}) end)
|
|
|
|
if not s and m then
|
|
|
|
error(m)
|
|
|
|
end
|
|
|
|
|