local function follow(id) requireInjector(getfenv(1)) local Event = require('event') local Point = require('point') local Socket = require('socket') turtle.status = 'follow ' .. id if not turtle.enableGPS() then error('turtle: No GPS found') end local socket = Socket.connect(id, 161) if not socket then error('turtle: Unable to connect to ' .. id) return end local lastPoint local following = false Event.on('turtle_follow', function(_, pt) 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 = blocks }) then turtle.headTowards(pt) end following = false end) Event.onInterval(.5, function() 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 os.queueEvent('turtle_follow', pt) end end end) Event.on('turtle_abort', function() Event.exitPullEvents() end) Event.pullEvents() socket:close() return true end local s, m = turtle.run(function() follow({COMPUTER_ID}) end) if not s and m then error(m) end