local function follow(id) require = requireInjector(getfenv(1)) 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