turtle follow

This commit is contained in:
kepler155c@gmail.com
2019-02-20 08:53:12 -05:00
parent 9f009c164a
commit 1643145cf0
8 changed files with 192 additions and 141 deletions

170
core/Follow.lua Normal file
View 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

View File

@@ -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

View File

@@ -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",

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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,