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)
|
||||
for id, member in pairs(self.pool) do
|
||||
Event.addRoutine(function()
|
||||
local s, m = pcall(function()
|
||||
member.turtle, member.socket = hijackTurtle(id)
|
||||
if not member.socket then
|
||||
Event.addRoutine(function()
|
||||
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)
|
||||
if member.socket then
|
||||
member.socket:close()
|
||||
member.socket = nil
|
||||
end
|
||||
self.pool[id] = nil
|
||||
self:onRemove(member, s, m)
|
||||
end)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -72,6 +72,11 @@ Needs work
|
||||
requires = "turtle",
|
||||
},
|
||||
--]]
|
||||
[ "turtleFollow" ] = {
|
||||
title = "Follow",
|
||||
category = "Turtle",
|
||||
run = "Follow.lua",
|
||||
},
|
||||
df485c871329671f46570634d63216761441bcd6 = {
|
||||
title = "Devices",
|
||||
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 Point = require('point')
|
||||
local Sound = require('sound')
|
||||
local Swarm = require('turtle.swarm')
|
||||
local Swarm = require('core.swarm')
|
||||
local Util = require('util')
|
||||
|
||||
local device = _G.device
|
||||
|
||||
@@ -103,7 +103,6 @@ end
|
||||
function page.detail:eventHandler(event)
|
||||
if event.type == 'grid_select' then
|
||||
projecting = event.selected
|
||||
_G._p = scanner.getBlockMeta(projecting.x, projecting.y, projecting.z)
|
||||
else
|
||||
return UI.SlideOut.eventHandler(self, event)
|
||||
end
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
local Config = require('config')
|
||||
local Event = require('event')
|
||||
local Mobs = require('neural.mobs')
|
||||
local Project = require('neural.project')
|
||||
local Sound = require('sound')
|
||||
local UI = require('ui')
|
||||
local Util = require('util')
|
||||
|
||||
@@ -14,7 +12,6 @@ local function equip(side, rawName)
|
||||
return turtle and turtle.equip(side, rawName) and peripheral.wrap(side)
|
||||
end
|
||||
|
||||
local lastWarning = os.clock()
|
||||
local target = nil
|
||||
local ni = device.neuralInterface
|
||||
local sensor = ni or
|
||||
@@ -81,7 +78,7 @@ function page.grid:getDisplayValues(row)
|
||||
row = Util.shallowCopy(row)
|
||||
row.x = row.x and math.floor(row.x) 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
|
||||
end
|
||||
|
||||
@@ -181,13 +178,6 @@ Event.onInterval(.5, function()
|
||||
Project:drawPoints(meta, t, 'X', 0xFFDF50AA)
|
||||
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
|
||||
local t = { }
|
||||
for _,v in pairs(entities) do
|
||||
|
||||
@@ -33,7 +33,7 @@ local function run()
|
||||
else
|
||||
os.sleep(0.1)
|
||||
end
|
||||
|
||||
|
||||
elseif meta.isSneaking and not meta.isElytraFlying and meta.pitch == -90 then
|
||||
if launchCounter < 2 then
|
||||
launchCounter = launchCounter + 1
|
||||
@@ -63,6 +63,7 @@ parallel.waitForAny(
|
||||
function()
|
||||
print('\nFlight control initialized')
|
||||
print('\nSneak and look straight up for launch')
|
||||
print('Sneak to deactivate during flight')
|
||||
print('\nPress any key to exit')
|
||||
os.pullEvent('char')
|
||||
end,
|
||||
|
||||
Reference in New Issue
Block a user