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

View File

@@ -72,6 +72,11 @@ Needs work
requires = "turtle",
},
--]]
[ "turtleFollow" ] = {
title = "Follow",
category = "Turtle",
run = "Follow.lua",
},
df485c871329671f46570634d63216761441bcd6 = {
title = "Devices",
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 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

View File

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

View File

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

View File

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