turtle follow
This commit is contained in:
170
core/Follow.lua
Normal file
170
core/Follow.lua
Normal file
@@ -0,0 +1,170 @@
|
|||||||
|
local Event = require('event')
|
||||||
|
local GPS = require('gps')
|
||||||
|
local Point = require('point')
|
||||||
|
local Socket = require('socket')
|
||||||
|
local Swarm = require('core.swarm')
|
||||||
|
local UI = require('ui')
|
||||||
|
local Util = require('util')
|
||||||
|
|
||||||
|
local colors = _G.colors
|
||||||
|
local network = _G.network
|
||||||
|
local os = _G.os
|
||||||
|
|
||||||
|
local swarm = Swarm()
|
||||||
|
local gpt = GPS.getPoint()
|
||||||
|
local pts, blocks
|
||||||
|
|
||||||
|
local page = UI.Page {
|
||||||
|
mode = UI.Chooser {
|
||||||
|
x = 18,
|
||||||
|
choices = {
|
||||||
|
{ name = 'No breaking', value = 'digNone' },
|
||||||
|
{ name = 'Destructive', value = 'turtleSafe' },
|
||||||
|
},
|
||||||
|
value = 'digNone',
|
||||||
|
},
|
||||||
|
grid = UI.ScrollingGrid {
|
||||||
|
y = 2,
|
||||||
|
columns = {
|
||||||
|
{ heading = 'Label', key = 'label' },
|
||||||
|
{ heading = 'Dist', key = 'distance' },
|
||||||
|
{ heading = 'Status', key = 'status' },
|
||||||
|
{ heading = 'Fuel', key = 'fuel' },
|
||||||
|
},
|
||||||
|
sortColumn = 'label',
|
||||||
|
autospace = true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
function page.grid:getRowTextColor(row, selected)
|
||||||
|
if swarm.pool[row.id] then
|
||||||
|
return colors.yellow
|
||||||
|
end
|
||||||
|
return UI.ScrollingGrid.getRowTextColor(self, row, selected)
|
||||||
|
end
|
||||||
|
|
||||||
|
function page.grid:getDisplayValues(row)
|
||||||
|
row = Util.shallowCopy(row)
|
||||||
|
if row.fuel then
|
||||||
|
row.fuel = row.fuel > 0 and Util.toBytes(row.fuel) or ''
|
||||||
|
end
|
||||||
|
if row.distance then
|
||||||
|
row.distance = Util.round(row.distance, 1)
|
||||||
|
end
|
||||||
|
return row
|
||||||
|
end
|
||||||
|
|
||||||
|
function page:enable()
|
||||||
|
local function update()
|
||||||
|
local t = { }
|
||||||
|
for _,v in pairs(network) do
|
||||||
|
if v.fuel and v.active then
|
||||||
|
table.insert(t, v)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
self.grid:setValues(t)
|
||||||
|
end
|
||||||
|
|
||||||
|
Event.onInterval(3, function()
|
||||||
|
update()
|
||||||
|
self.grid:draw()
|
||||||
|
self:sync()
|
||||||
|
end)
|
||||||
|
|
||||||
|
update()
|
||||||
|
|
||||||
|
UI.Page.enable(self)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function follow(member)
|
||||||
|
local turtle = member.turtle
|
||||||
|
turtle.setStatus('follow ' .. member.id)
|
||||||
|
turtle.reset()
|
||||||
|
turtle.set({
|
||||||
|
digPolicy = page.mode.value,
|
||||||
|
})
|
||||||
|
|
||||||
|
if not turtle.enableGPS(nil, true) then
|
||||||
|
error('turtle: No GPS found')
|
||||||
|
end
|
||||||
|
|
||||||
|
member.snmp = Socket.connect(member.id, 161)
|
||||||
|
|
||||||
|
local pt
|
||||||
|
|
||||||
|
while true do
|
||||||
|
while pt and Point.same(gpt, pt) do
|
||||||
|
os.sleep(.5)
|
||||||
|
end
|
||||||
|
pt = Point.copy(gpt)
|
||||||
|
|
||||||
|
local cpt = Point.closest(turtle.getPoint(), pts)
|
||||||
|
|
||||||
|
turtle.abort(false)
|
||||||
|
if turtle.pathfind(cpt, { blocks = blocks }) then
|
||||||
|
turtle.headTowards(pt)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function page:eventHandler(event)
|
||||||
|
if event.type == 'grid_select' then
|
||||||
|
swarm:add(event.selected.id, { })
|
||||||
|
swarm:run(follow)
|
||||||
|
self.grid:draw()
|
||||||
|
|
||||||
|
elseif event.type == 'choice_change' then
|
||||||
|
local script = string.format('turtle.set({ digPolicy = "%s"})', event.value)
|
||||||
|
for _, member in pairs(swarm.pool) do
|
||||||
|
member.snmp:write({ type = 'scriptEx', args = script })
|
||||||
|
end
|
||||||
|
|
||||||
|
else
|
||||||
|
return UI.Page.eventHandler(self, event)
|
||||||
|
end
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
Event.addRoutine(function()
|
||||||
|
while true do
|
||||||
|
local pt = GPS.getPoint()
|
||||||
|
if pt then
|
||||||
|
gpt = pt
|
||||||
|
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 },
|
||||||
|
}
|
||||||
|
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 })
|
||||||
|
|
||||||
|
for _, member in pairs(swarm.pool) do
|
||||||
|
if member.snmp then
|
||||||
|
member.snmp:write({ type = 'scriptEx', args = 'turtle.abort(true)' })
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
os.sleep(1)
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
--swarm:run(follow)
|
||||||
|
|
||||||
|
UI:setPage(page)
|
||||||
|
UI:pullEvents()
|
||||||
|
|
||||||
|
for _, member in pairs(swarm.pool) do
|
||||||
|
member.snmp:write({ type = 'scriptEx', args = 'turtle.abort(true)' })
|
||||||
|
end
|
||||||
@@ -42,19 +42,21 @@ end
|
|||||||
|
|
||||||
function Swarm:run(fn)
|
function Swarm:run(fn)
|
||||||
for id, member in pairs(self.pool) do
|
for id, member in pairs(self.pool) do
|
||||||
Event.addRoutine(function()
|
if not member.socket then
|
||||||
local s, m = pcall(function()
|
Event.addRoutine(function()
|
||||||
member.turtle, member.socket = hijackTurtle(id)
|
local s, m = pcall(function()
|
||||||
|
member.turtle, member.socket = hijackTurtle(id)
|
||||||
|
|
||||||
fn(member)
|
fn(member)
|
||||||
|
end)
|
||||||
|
if member.socket then
|
||||||
|
member.socket:close()
|
||||||
|
member.socket = nil
|
||||||
|
end
|
||||||
|
self.pool[id] = nil
|
||||||
|
self:onRemove(member, s, m)
|
||||||
end)
|
end)
|
||||||
if member.socket then
|
end
|
||||||
member.socket:close()
|
|
||||||
member.socket = nil
|
|
||||||
end
|
|
||||||
self.pool[id] = nil
|
|
||||||
self:onRemove(member, s, m)
|
|
||||||
end)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -72,6 +72,11 @@ Needs work
|
|||||||
requires = "turtle",
|
requires = "turtle",
|
||||||
},
|
},
|
||||||
--]]
|
--]]
|
||||||
|
[ "turtleFollow" ] = {
|
||||||
|
title = "Follow",
|
||||||
|
category = "Turtle",
|
||||||
|
run = "Follow.lua",
|
||||||
|
},
|
||||||
df485c871329671f46570634d63216761441bcd6 = {
|
df485c871329671f46570634d63216761441bcd6 = {
|
||||||
title = "Devices",
|
title = "Devices",
|
||||||
category = "System",
|
category = "System",
|
||||||
|
|||||||
@@ -1,116 +0,0 @@
|
|||||||
local os = _G.os
|
|
||||||
local turtle = _G.turtle
|
|
||||||
|
|
||||||
local function follow(id)
|
|
||||||
|
|
||||||
_G.requireInjector(_ENV)
|
|
||||||
|
|
||||||
local Event = require('event')
|
|
||||||
local Point = require('point')
|
|
||||||
local Socket = require('socket')
|
|
||||||
|
|
||||||
turtle.setStatus('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.isAborted() then
|
|
||||||
if socket:write({ type = 'gps' }) then
|
|
||||||
return socket:read(3)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- sometimes gps will fail if moving
|
|
||||||
local pt, d
|
|
||||||
|
|
||||||
for _ = 1, 3 do
|
|
||||||
pt, d = getRemotePoint()
|
|
||||||
if pt then
|
|
||||||
break
|
|
||||||
end
|
|
||||||
os.sleep(.5)
|
|
||||||
end
|
|
||||||
|
|
||||||
if not pt or turtle.isAborted() 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.getState().abort = true
|
|
||||||
while following do
|
|
||||||
os.sleep(.1)
|
|
||||||
end
|
|
||||||
turtle.getState().abort = false
|
|
||||||
end
|
|
||||||
|
|
||||||
-- check if gps is inaccurate (player moving too fast)
|
|
||||||
if d < Point.distance(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
|
|
||||||
@@ -2,7 +2,7 @@ local Event = require('event')
|
|||||||
local GPS = require('gps')
|
local GPS = require('gps')
|
||||||
local Point = require('point')
|
local Point = require('point')
|
||||||
local Sound = require('sound')
|
local Sound = require('sound')
|
||||||
local Swarm = require('turtle.swarm')
|
local Swarm = require('core.swarm')
|
||||||
local Util = require('util')
|
local Util = require('util')
|
||||||
|
|
||||||
local device = _G.device
|
local device = _G.device
|
||||||
|
|||||||
@@ -103,7 +103,6 @@ end
|
|||||||
function page.detail:eventHandler(event)
|
function page.detail:eventHandler(event)
|
||||||
if event.type == 'grid_select' then
|
if event.type == 'grid_select' then
|
||||||
projecting = event.selected
|
projecting = event.selected
|
||||||
_G._p = scanner.getBlockMeta(projecting.x, projecting.y, projecting.z)
|
|
||||||
else
|
else
|
||||||
return UI.SlideOut.eventHandler(self, event)
|
return UI.SlideOut.eventHandler(self, event)
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
local Config = require('config')
|
local Config = require('config')
|
||||||
local Event = require('event')
|
local Event = require('event')
|
||||||
local Mobs = require('neural.mobs')
|
|
||||||
local Project = require('neural.project')
|
local Project = require('neural.project')
|
||||||
local Sound = require('sound')
|
|
||||||
local UI = require('ui')
|
local UI = require('ui')
|
||||||
local Util = require('util')
|
local Util = require('util')
|
||||||
|
|
||||||
@@ -14,7 +12,6 @@ local function equip(side, rawName)
|
|||||||
return turtle and turtle.equip(side, rawName) and peripheral.wrap(side)
|
return turtle and turtle.equip(side, rawName) and peripheral.wrap(side)
|
||||||
end
|
end
|
||||||
|
|
||||||
local lastWarning = os.clock()
|
|
||||||
local target = nil
|
local target = nil
|
||||||
local ni = device.neuralInterface
|
local ni = device.neuralInterface
|
||||||
local sensor = ni or
|
local sensor = ni or
|
||||||
@@ -81,7 +78,7 @@ function page.grid:getDisplayValues(row)
|
|||||||
row = Util.shallowCopy(row)
|
row = Util.shallowCopy(row)
|
||||||
row.x = row.x and math.floor(row.x) or ''
|
row.x = row.x and math.floor(row.x) or ''
|
||||||
row.y = row.y and math.floor(row.y) or ''
|
row.y = row.y and math.floor(row.y) or ''
|
||||||
row.z = math.floor(row.z)
|
row.z = row.z and math.floor(row.z) or ''
|
||||||
return row
|
return row
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -181,13 +178,6 @@ Event.onInterval(.5, function()
|
|||||||
Project:drawPoints(meta, t, 'X', 0xFFDF50AA)
|
Project:drawPoints(meta, t, 'X', 0xFFDF50AA)
|
||||||
end
|
end
|
||||||
|
|
||||||
if os.clock() > lastWarning + 5 then
|
|
||||||
if Util.any(entities, function(e) return Mobs.getNames()[e.name] end) then
|
|
||||||
lastWarning = os.clock()
|
|
||||||
Sound.play('entity.player.breath')
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if config.totals then
|
if config.totals then
|
||||||
local t = { }
|
local t = { }
|
||||||
for _,v in pairs(entities) do
|
for _,v in pairs(entities) do
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ local function run()
|
|||||||
else
|
else
|
||||||
os.sleep(0.1)
|
os.sleep(0.1)
|
||||||
end
|
end
|
||||||
|
|
||||||
elseif meta.isSneaking and not meta.isElytraFlying and meta.pitch == -90 then
|
elseif meta.isSneaking and not meta.isElytraFlying and meta.pitch == -90 then
|
||||||
if launchCounter < 2 then
|
if launchCounter < 2 then
|
||||||
launchCounter = launchCounter + 1
|
launchCounter = launchCounter + 1
|
||||||
@@ -63,6 +63,7 @@ parallel.waitForAny(
|
|||||||
function()
|
function()
|
||||||
print('\nFlight control initialized')
|
print('\nFlight control initialized')
|
||||||
print('\nSneak and look straight up for launch')
|
print('\nSneak and look straight up for launch')
|
||||||
|
print('Sneak to deactivate during flight')
|
||||||
print('\nPress any key to exit')
|
print('\nPress any key to exit')
|
||||||
os.pullEvent('char')
|
os.pullEvent('char')
|
||||||
end,
|
end,
|
||||||
|
|||||||
Reference in New Issue
Block a user