From 1643145cf062ff47605e86cdf7a27efb082bc60b Mon Sep 17 00:00:00 2001 From: "kepler155c@gmail.com" Date: Wed, 20 Feb 2019 08:53:12 -0500 Subject: [PATCH] turtle follow --- core/Follow.lua | 170 ++++++++++++++++++++++++++++++++ {turtle => core}/apis/swarm.lua | 24 ++--- core/etc/apps.db | 5 + core/etc/scripts/follow | 116 ---------------------- miners/findSwarm.lua | 2 +- neural/Scanner.lua | 1 - neural/Sensor.lua | 12 +-- neural/elytraFly.lua | 3 +- 8 files changed, 192 insertions(+), 141 deletions(-) create mode 100644 core/Follow.lua rename {turtle => core}/apis/swarm.lua (77%) delete mode 100644 core/etc/scripts/follow diff --git a/core/Follow.lua b/core/Follow.lua new file mode 100644 index 0000000..c9c7fa4 --- /dev/null +++ b/core/Follow.lua @@ -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 diff --git a/turtle/apis/swarm.lua b/core/apis/swarm.lua similarity index 77% rename from turtle/apis/swarm.lua rename to core/apis/swarm.lua index 57475fa..f876759 100644 --- a/turtle/apis/swarm.lua +++ b/core/apis/swarm.lua @@ -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 diff --git a/core/etc/apps.db b/core/etc/apps.db index fea7ff9..aabd715 100644 --- a/core/etc/apps.db +++ b/core/etc/apps.db @@ -72,6 +72,11 @@ Needs work requires = "turtle", }, --]] + [ "turtleFollow" ] = { + title = "Follow", + category = "Turtle", + run = "Follow.lua", + }, df485c871329671f46570634d63216761441bcd6 = { title = "Devices", category = "System", diff --git a/core/etc/scripts/follow b/core/etc/scripts/follow deleted file mode 100644 index 85fd43f..0000000 --- a/core/etc/scripts/follow +++ /dev/null @@ -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 diff --git a/miners/findSwarm.lua b/miners/findSwarm.lua index a0667ce..c2ae489 100644 --- a/miners/findSwarm.lua +++ b/miners/findSwarm.lua @@ -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 diff --git a/neural/Scanner.lua b/neural/Scanner.lua index 9b5ae0c..5e9d9f2 100644 --- a/neural/Scanner.lua +++ b/neural/Scanner.lua @@ -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 diff --git a/neural/Sensor.lua b/neural/Sensor.lua index 8c11401..f2db0ac 100644 --- a/neural/Sensor.lua +++ b/neural/Sensor.lua @@ -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 diff --git a/neural/elytraFly.lua b/neural/elytraFly.lua index 31797cf..33535ef 100644 --- a/neural/elytraFly.lua +++ b/neural/elytraFly.lua @@ -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,