begin moving turtle specific code from opus into turtle package
This commit is contained in:
@@ -446,7 +446,7 @@ function TurtleBuilder:inAirDropoff()
|
|||||||
self:log('Received supply location')
|
self:log('Received supply location')
|
||||||
os.sleep(0)
|
os.sleep(0)
|
||||||
|
|
||||||
turtle._goto(pt)
|
turtle.go(pt)
|
||||||
os.sleep(.1) -- random computer is not connected error
|
os.sleep(.1) -- random computer is not connected error
|
||||||
|
|
||||||
local chestAdapter = Adapter.wrap({ direction = 'down', side = 'top' })
|
local chestAdapter = Adapter.wrap({ direction = 'down', side = 'top' })
|
||||||
@@ -508,7 +508,7 @@ function TurtleBuilder:inAirResupply()
|
|||||||
self:log('Received supply location')
|
self:log('Received supply location')
|
||||||
os.sleep(0)
|
os.sleep(0)
|
||||||
|
|
||||||
turtle._goto(pt)
|
turtle.go(pt)
|
||||||
os.sleep(.1) -- random computer is not connected error
|
os.sleep(.1) -- random computer is not connected error
|
||||||
|
|
||||||
local chestAdapter = Adapter.wrap({ direction = 'down', side = 'top' })
|
local chestAdapter = Adapter.wrap({ direction = 'down', side = 'top' })
|
||||||
@@ -608,7 +608,7 @@ function TurtleBuilder:gotoSupplyPoint()
|
|||||||
-- go to the corner closest to the supplies point
|
-- go to the corner closest to the supplies point
|
||||||
-- pathfind the rest of the way
|
-- pathfind the rest of the way
|
||||||
local pt = self:getBuildingCorner(turtle.point.y)
|
local pt = self:getBuildingCorner(turtle.point.y)
|
||||||
turtle._goto({ x = pt.x, z = pt.z })
|
turtle.go({ x = pt.x, z = pt.z })
|
||||||
turtle.set({
|
turtle.set({
|
||||||
digPolicy = 'digNone',
|
digPolicy = 'digNone',
|
||||||
attackPolicy = 'attackNone',
|
attackPolicy = 'attackNone',
|
||||||
@@ -818,8 +818,8 @@ function TurtleBuilder:placePiston(b)
|
|||||||
return success
|
return success
|
||||||
end
|
end
|
||||||
|
|
||||||
function TurtleBuilder:_goto(x, z, y, heading)
|
function TurtleBuilder:go(x, z, y, heading)
|
||||||
if not turtle._goto({ x = x, z = z, y = y, heading = heading }) then
|
if not turtle.go({ x = x, z = z, y = y, heading = heading }) then
|
||||||
print('stuck')
|
print('stuck')
|
||||||
print('Press enter to continue')
|
print('Press enter to continue')
|
||||||
os.sleep(1)
|
os.sleep(1)
|
||||||
@@ -844,7 +844,7 @@ function TurtleBuilder:gotoEx(x, z, y, h, travelPlane)
|
|||||||
elseif distance > 1 then
|
elseif distance > 1 then
|
||||||
self:gotoTravelPlane(travelPlane)
|
self:gotoTravelPlane(travelPlane)
|
||||||
end
|
end
|
||||||
self:_goto(x, z, y, h)
|
self:go(x, z, y, h)
|
||||||
end
|
end
|
||||||
|
|
||||||
function TurtleBuilder:placeDirectionalBlock(b, slot, travelPlane)
|
function TurtleBuilder:placeDirectionalBlock(b, slot, travelPlane)
|
||||||
@@ -1128,7 +1128,7 @@ function TurtleBuilder:build()
|
|||||||
if b.y ~= turtle.getPoint().y then
|
if b.y ~= turtle.getPoint().y then
|
||||||
turtle.gotoY(b.y)
|
turtle.gotoY(b.y)
|
||||||
end
|
end
|
||||||
self:_goto(b.x, b.z, b.y)
|
self:go(b.x, b.z, b.y)
|
||||||
turtle.digDown()
|
turtle.digDown()
|
||||||
|
|
||||||
-- if no supplier, then should fill all slots
|
-- if no supplier, then should fill all slots
|
||||||
@@ -1171,7 +1171,7 @@ function TurtleBuilder:build()
|
|||||||
end
|
end
|
||||||
else
|
else
|
||||||
self:gotoTravelPlane(travelPlane)
|
self:gotoTravelPlane(travelPlane)
|
||||||
self:_goto(b.x, b.z, b.y)
|
self:go(b.x, b.z, b.y)
|
||||||
b.placed = self:placeDown(slot)
|
b.placed = self:placeDown(slot)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -163,7 +163,7 @@ function turtle.level(startPt, endPt, firstPt, verbose)
|
|||||||
|
|
||||||
local node = closestPoint(turtle.point, nodes)
|
local node = closestPoint(turtle.point, nodes)
|
||||||
node = getAdjacentPoint(node)
|
node = getAdjacentPoint(node)
|
||||||
if not turtle._goto(node) then
|
if not turtle.go(node) then
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
until turtle.isAborted()
|
until turtle.isAborted()
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ local function summon(id)
|
|||||||
local function doGPS()
|
local function doGPS()
|
||||||
tFixes = { }
|
tFixes = { }
|
||||||
for i = 1, 4 do
|
for i = 1, 4 do
|
||||||
if not turtle._goto(pts[i]) then
|
if not turtle.go(pts[i]) then
|
||||||
error('turtle: Unable to perform GPS maneuver')
|
error('turtle: Unable to perform GPS maneuver')
|
||||||
end
|
end
|
||||||
local distance = getDistance()
|
local distance = getDistance()
|
||||||
|
|||||||
@@ -139,7 +139,7 @@ local function harvest(blocks)
|
|||||||
turtle.digForwardAt(b)
|
turtle.digForwardAt(b)
|
||||||
|
|
||||||
elseif b.action == 'drop' and not dropped then
|
elseif b.action == 'drop' and not dropped then
|
||||||
if turtle._goto(Point.above(b)) then
|
if turtle.go(Point.above(b)) then
|
||||||
turtle.eachFilledSlot(function(slot)
|
turtle.eachFilledSlot(function(slot)
|
||||||
if not retain[slot.name] and not retain[slot.key] then
|
if not retain[slot.name] and not retain[slot.key] then
|
||||||
turtle.select(slot.index)
|
turtle.select(slot.index)
|
||||||
@@ -212,7 +212,7 @@ local function harvest(blocks)
|
|||||||
local hi = Point.headings[(h + 2) % 4] -- opposite heading
|
local hi = Point.headings[(h + 2) % 4] -- opposite heading
|
||||||
|
|
||||||
-- without pathfinding, will be unable to circle log
|
-- without pathfinding, will be unable to circle log
|
||||||
if turtle._goto({ x = b.x + hi.xd, z = b.z + hi.zd, heading = h }) then
|
if turtle.go({ x = b.x + hi.xd, z = b.z + hi.zd, heading = h }) then
|
||||||
if turtle.dig() then
|
if turtle.dig() then
|
||||||
turtle.place(crops[b.name].seed)
|
turtle.place(crops[b.name].seed)
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -308,7 +308,7 @@ local function getCobblestone(count)
|
|||||||
|
|
||||||
until turtle.getItemCount(COBBLESTONE) >= count
|
until turtle.getItemCount(COBBLESTONE) >= count
|
||||||
|
|
||||||
turtle._goto(pt)
|
turtle.go(pt)
|
||||||
turtle.placeDown(DIRT)
|
turtle.placeDown(DIRT)
|
||||||
|
|
||||||
turtle.drop(DIRT)
|
turtle.drop(DIRT)
|
||||||
|
|||||||
@@ -295,7 +295,7 @@ local function getCobblestone(count)
|
|||||||
|
|
||||||
until turtle.getItemCount(COBBLESTONE) >= count
|
until turtle.getItemCount(COBBLESTONE) >= count
|
||||||
|
|
||||||
turtle._goto(pt)
|
turtle.go(pt)
|
||||||
turtle.placeDown(DIRT)
|
turtle.placeDown(DIRT)
|
||||||
|
|
||||||
turtle.drop(DIRT)
|
turtle.drop(DIRT)
|
||||||
|
|||||||
@@ -185,7 +185,7 @@ if args[1] == 'build' then
|
|||||||
|
|
||||||
turtle.setPoint({ x = 0, y = -y, z = 0, heading = 0 })
|
turtle.setPoint({ x = 0, y = -y, z = 0, heading = 0 })
|
||||||
build()
|
build()
|
||||||
turtle._goto({ x = 0, y = 1, z = 0, heading = 0 })
|
turtle.go({ x = 0, y = 1, z = 0, heading = 0 })
|
||||||
|
|
||||||
configure()
|
configure()
|
||||||
|
|
||||||
|
|||||||
@@ -2,8 +2,8 @@
|
|||||||
local Event = require('event')
|
local Event = require('event')
|
||||||
local GPS = require('gps')
|
local GPS = require('gps')
|
||||||
local Point = require('point')
|
local Point = require('point')
|
||||||
local Socket = require('socket')
|
|
||||||
local Sound = require('sound')
|
local Sound = require('sound')
|
||||||
|
local Swarm = require('swarm')
|
||||||
local Util = require('util')
|
local Util = require('util')
|
||||||
|
|
||||||
local device = _G.device
|
local device = _G.device
|
||||||
@@ -19,7 +19,7 @@ end
|
|||||||
|
|
||||||
local paused, abort
|
local paused, abort
|
||||||
local chunkIndex = 0
|
local chunkIndex = 0
|
||||||
local pool = { }
|
local swarm = Swarm()
|
||||||
local blocks = Util.transpose({
|
local blocks = Util.transpose({
|
||||||
'minecraft:chest',
|
'minecraft:chest',
|
||||||
-- 'minecraft:mob_spawner',
|
-- 'minecraft:mob_spawner',
|
||||||
@@ -41,8 +41,6 @@ local function getLocations()
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
getLocations()
|
|
||||||
|
|
||||||
for _, b in pairs(scanner.scan()) do
|
for _, b in pairs(scanner.scan()) do
|
||||||
if b.name == 'computercraft:turtle_advanced' or
|
if b.name == 'computercraft:turtle_advanced' or
|
||||||
b.name == 'computercraft:turtle' then
|
b.name == 'computercraft:turtle' then
|
||||||
@@ -54,46 +52,20 @@ for _, b in pairs(scanner.scan()) do
|
|||||||
elseif v.turtle.fuel < 100 then
|
elseif v.turtle.fuel < 100 then
|
||||||
print('not enough fuel: ' .. v.computer.id)
|
print('not enough fuel: ' .. v.computer.id)
|
||||||
else
|
else
|
||||||
pool[v.computer.id] = {
|
swarm:add(v.computer.id, {
|
||||||
id = v.computer.id,
|
|
||||||
point = {
|
point = {
|
||||||
x = gpt.x + b.x,
|
x = gpt.x + b.x,
|
||||||
y = gpt.y + b.y,
|
y = gpt.y + b.y,
|
||||||
z = gpt.z + b.z,
|
z = gpt.z + b.z,
|
||||||
heading = Point.facings[v.state.facing].heading,
|
heading = Point.facings[v.state.facing].heading,
|
||||||
},
|
},
|
||||||
index = Util.size(pool),
|
index = Util.size(swarm.pool),
|
||||||
}
|
})
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local function hijackTurtle(remoteId)
|
|
||||||
local socket, msg = Socket.connect(remoteId, 188)
|
|
||||||
|
|
||||||
if not socket then
|
|
||||||
error(msg)
|
|
||||||
end
|
|
||||||
|
|
||||||
socket:write('turtle')
|
|
||||||
local methods = socket:read()
|
|
||||||
|
|
||||||
local hijack = { }
|
|
||||||
for _,method in pairs(methods) do
|
|
||||||
hijack[method] = function(...)
|
|
||||||
socket:write({ fn = method, args = { ... } })
|
|
||||||
local resp = socket:read()
|
|
||||||
if not resp then
|
|
||||||
error('timed out: ' .. method)
|
|
||||||
end
|
|
||||||
return table.unpack(resp)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
return hijack, socket
|
|
||||||
end
|
|
||||||
|
|
||||||
local function getNextPoint(member)
|
local function getNextPoint(member)
|
||||||
local z = math.floor(chunkIndex / COLUMNS)
|
local z = math.floor(chunkIndex / COLUMNS)
|
||||||
local x = chunkIndex % COLUMNS
|
local x = chunkIndex % COLUMNS
|
||||||
@@ -107,85 +79,75 @@ local function getNextPoint(member)
|
|||||||
return {
|
return {
|
||||||
x = gpt.x + (x * 16),
|
x = gpt.x + (x * 16),
|
||||||
y = gpt.y + member.index,
|
y = gpt.y + member.index,
|
||||||
z = gpt.z + (z * 16) }
|
z = gpt.z + (z * 16)
|
||||||
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
local function run(member)
|
local function run(member)
|
||||||
Event.addRoutine(function()
|
local turtle = member.turtle
|
||||||
local turtle, socket
|
|
||||||
local _, m = pcall(function()
|
|
||||||
member.active = true
|
|
||||||
turtle, socket = hijackTurtle(member.id)
|
|
||||||
|
|
||||||
if turtle then
|
if not turtle.has('plethora:module:2') then
|
||||||
if not turtle.has('plethora:module:2') then
|
error('missing scanner')
|
||||||
error('missing scanner')
|
end
|
||||||
|
turtle.reset()
|
||||||
|
turtle.set({
|
||||||
|
attackPolicy = 'attack',
|
||||||
|
digPolicy = 'turtleSafe',
|
||||||
|
movementStrategy = 'goto',
|
||||||
|
point = member.point,
|
||||||
|
})
|
||||||
|
turtle.select(1)
|
||||||
|
|
||||||
|
repeat
|
||||||
|
local pt = getNextPoint(member)
|
||||||
|
if pt then
|
||||||
|
turtle.go({ y = pt.y })
|
||||||
|
while not turtle.go(pt) do
|
||||||
|
if abort then
|
||||||
|
break
|
||||||
end
|
end
|
||||||
turtle.reset()
|
os.sleep(.5)
|
||||||
turtle.set({
|
|
||||||
attackPolicy = 'attack',
|
|
||||||
digPolicy = 'turtleSafe',
|
|
||||||
movementStrategy = 'goto',
|
|
||||||
point = member.point,
|
|
||||||
})
|
|
||||||
turtle.select(1)
|
|
||||||
|
|
||||||
repeat
|
|
||||||
local pt = getNextPoint(member)
|
|
||||||
if pt then
|
|
||||||
turtle.gotoY(pt.y)
|
|
||||||
while not turtle._goto(pt) do
|
|
||||||
if abort then
|
|
||||||
break
|
|
||||||
end
|
|
||||||
os.sleep(.5)
|
|
||||||
end
|
|
||||||
|
|
||||||
for _, v in ipairs(locations) do
|
|
||||||
if abort then
|
|
||||||
break
|
|
||||||
end
|
|
||||||
turtle.gotoY(v)
|
|
||||||
turtle.equip('right', 'plethora:module:2')
|
|
||||||
local found = turtle.scan(blocks)
|
|
||||||
turtle.equip('right', 'minecraft:diamond_pickaxe')
|
|
||||||
if Util.size(found) > 0 then
|
|
||||||
paused = true
|
|
||||||
local _, b = next(found)
|
|
||||||
print(string.format('%s:%s:%s %s', b.x, b.y, b.z, b.name))
|
|
||||||
print('press r to continue')
|
|
||||||
for _ = 1, 3 do
|
|
||||||
Sound.play('block.note.pling')
|
|
||||||
os.sleep(.3)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
turtle.gotoY(pt.y)
|
|
||||||
end
|
|
||||||
until abort
|
|
||||||
|
|
||||||
turtle.gotoY(gpt.y + member.index)
|
|
||||||
turtle._goto({ x = gpt.x, y = gpt.y + member.index, z = gpt.z })
|
|
||||||
end
|
end
|
||||||
|
|
||||||
repeat until turtle.gotoY(gpt.y)
|
for _, v in ipairs(locations) do
|
||||||
end)
|
if abort then
|
||||||
|
break
|
||||||
if m then
|
end
|
||||||
Sound.play('entity.villager.no')
|
turtle.go({ y = v })
|
||||||
_G.printError(m)
|
turtle.equip('right', 'plethora:module:2')
|
||||||
|
local found = turtle.scan(blocks)
|
||||||
|
turtle.equip('right', 'minecraft:diamond_pickaxe')
|
||||||
|
if Util.size(found) > 0 then
|
||||||
|
paused = true
|
||||||
|
local _, b = next(found)
|
||||||
|
print(string.format('%s:%s:%s %s', b.x, b.y, b.z, b.name))
|
||||||
|
print('press r to continue')
|
||||||
|
for _ = 1, 3 do
|
||||||
|
Sound.play('block.note.pling')
|
||||||
|
os.sleep(.3)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
turtle.go({ y = pt.y })
|
||||||
end
|
end
|
||||||
|
until abort
|
||||||
|
|
||||||
pool[member.id] = nil
|
turtle.go({ y = gpt.y + member.index })
|
||||||
print('Turtles: ' .. Util.size(pool))
|
turtle.go({ x = gpt.x, y = gpt.y + member.index, z = gpt.z })
|
||||||
if Util.size(pool) == 0 then
|
|
||||||
Event.exitPullEvents()
|
|
||||||
end
|
|
||||||
|
|
||||||
if socket then
|
repeat until turtle.go({ y = gpt.y })
|
||||||
socket:close()
|
end
|
||||||
end
|
|
||||||
end)
|
function swarm:onRemove(member, success, message)
|
||||||
|
if not success then
|
||||||
|
Sound.play('entity.villager.no')
|
||||||
|
_G.printError(message)
|
||||||
|
end
|
||||||
|
|
||||||
|
print('Turtles: ' .. Util.size(self.pool))
|
||||||
|
if Util.size(self.pool) == 0 then
|
||||||
|
Event.exitPullEvents()
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
print('press a to abort, r to resume')
|
print('press a to abort, r to resume')
|
||||||
@@ -200,9 +162,9 @@ Event.on('char', function(_, k)
|
|||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
Util.print('Found %s turtles', Util.size(pool))
|
getLocations()
|
||||||
Util.each(pool, function(member)
|
|
||||||
run(member)
|
Util.print('Found %s turtles', Util.size(swarm.pool))
|
||||||
end)
|
swarm:run(run)
|
||||||
|
|
||||||
Event.pullEvents()
|
Event.pullEvents()
|
||||||
|
|||||||
@@ -104,7 +104,7 @@ local function run(member, point)
|
|||||||
local topPoint = Point.copy(chestPoint)
|
local topPoint = Point.copy(chestPoint)
|
||||||
topPoint.y = topPoint.y + 2
|
topPoint.y = topPoint.y + 2
|
||||||
turtle.gotoY(topPoint.y)
|
turtle.gotoY(topPoint.y)
|
||||||
while not turtle._goto(topPoint) do
|
while not turtle.go(topPoint) do
|
||||||
os.sleep(.5)
|
os.sleep(.5)
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -196,14 +196,14 @@ local function run(member, point)
|
|||||||
|
|
||||||
if chestPoint then
|
if chestPoint then
|
||||||
dropOff()
|
dropOff()
|
||||||
while not turtle._goto(Point.above(spt)) do
|
while not turtle.go(Point.above(spt)) do
|
||||||
os.sleep(.5)
|
os.sleep(.5)
|
||||||
end
|
end
|
||||||
turtle.set({ digPolicy = 'dig' })
|
turtle.set({ digPolicy = 'dig' })
|
||||||
turtle._goto(spt)
|
turtle.go(spt)
|
||||||
else
|
else
|
||||||
turtle.gotoY(spt.y)
|
turtle.gotoY(spt.y)
|
||||||
turtle._goto(spt)
|
turtle.go(spt)
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
|||||||
@@ -233,7 +233,7 @@ end
|
|||||||
local function safeGoto(x, z, y, h)
|
local function safeGoto(x, z, y, h)
|
||||||
local oldStatus = turtle.getStatus()
|
local oldStatus = turtle.getStatus()
|
||||||
|
|
||||||
while not turtle._goto({ x = x, z = z, y = y or turtle.point.y, heading = h }) do
|
while not turtle.go({ x = x, z = z, y = y or turtle.point.y, heading = h }) do
|
||||||
status('stuck')
|
status('stuck')
|
||||||
if turtle.isAborted() then
|
if turtle.isAborted() then
|
||||||
return false
|
return false
|
||||||
@@ -647,7 +647,7 @@ Event.addRoutine(function()
|
|||||||
|
|
||||||
status(success and 'finished' or turtle.isAborted() and 'aborting' or 'error')
|
status(success and 'finished' or turtle.isAborted() and 'aborting' or 'error')
|
||||||
turtle.gotoY(0)
|
turtle.gotoY(0)
|
||||||
if turtle._goto(HOME_PT) then
|
if turtle.go(HOME_PT) then
|
||||||
unload()
|
unload()
|
||||||
end
|
end
|
||||||
turtle.reset()
|
turtle.reset()
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
local Pathing = require('turtle.pathfind')
|
local Pathing = require('pathfind')
|
||||||
local Point = require('point')
|
local Point = require('point')
|
||||||
local Util = require('util')
|
local Util = require('util')
|
||||||
|
|
||||||
|
|||||||
6
turtle/.package
Normal file
6
turtle/.package
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
title = 'Turtle programs and apis',
|
||||||
|
repository = 'kepler155c/opus-apps/{{OPUS_BRANCH}}/turtle',
|
||||||
|
description = [[Support programs and apis for turtles]],
|
||||||
|
licence = 'MIT',
|
||||||
|
}
|
||||||
42
turtle/apis/home.lua
Normal file
42
turtle/apis/home.lua
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
local Config = require('config')
|
||||||
|
local GPS = require('gps')
|
||||||
|
|
||||||
|
local turtle = _G.turtle
|
||||||
|
|
||||||
|
local Home = { }
|
||||||
|
|
||||||
|
function Home.go()
|
||||||
|
local config = { }
|
||||||
|
Config.load('gps', config)
|
||||||
|
|
||||||
|
if config.home then
|
||||||
|
if turtle.enableGPS() then
|
||||||
|
return turtle.pathfind(config.home)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function Home.set()
|
||||||
|
local config = { }
|
||||||
|
Config.load('gps', config)
|
||||||
|
|
||||||
|
local pt = GPS.getPoint()
|
||||||
|
if pt then
|
||||||
|
local originalHeading = turtle.point.heading
|
||||||
|
local heading = GPS.getHeading()
|
||||||
|
if heading then
|
||||||
|
local turns = (turtle.point.heading - originalHeading) % 4
|
||||||
|
pt.heading = (heading - turns) % 4
|
||||||
|
config.home = pt
|
||||||
|
Config.update('gps', config)
|
||||||
|
|
||||||
|
pt = GPS.getPoint()
|
||||||
|
pt.heading = heading
|
||||||
|
turtle.setPoint(pt, true)
|
||||||
|
turtle.go(config.home)
|
||||||
|
return config.home
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return Home
|
||||||
72
turtle/apis/swarm.lua
Normal file
72
turtle/apis/swarm.lua
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
local Event = require('event')
|
||||||
|
local Socket = require('socket')
|
||||||
|
local Util = require('util')
|
||||||
|
|
||||||
|
local function hijackTurtle(remoteId)
|
||||||
|
local socket, msg = Socket.connect(remoteId, 188)
|
||||||
|
|
||||||
|
if not socket then
|
||||||
|
error(msg)
|
||||||
|
end
|
||||||
|
|
||||||
|
socket:write('turtle')
|
||||||
|
local methods = socket:read()
|
||||||
|
|
||||||
|
local hijack = { }
|
||||||
|
for _,method in pairs(methods) do
|
||||||
|
hijack[method] = function(...)
|
||||||
|
socket:write({ fn = method, args = { ... } })
|
||||||
|
local resp = socket:read()
|
||||||
|
if not resp then
|
||||||
|
error('timed out: ' .. method)
|
||||||
|
end
|
||||||
|
return table.unpack(resp)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return hijack, socket
|
||||||
|
end
|
||||||
|
local class = require('class')
|
||||||
|
local Swarm = class()
|
||||||
|
function Swarm:init(args)
|
||||||
|
self.pool = { }
|
||||||
|
Util.merge(self, args)
|
||||||
|
end
|
||||||
|
function Swarm:add(id, args)
|
||||||
|
local member = Util.shallowCopy(args)
|
||||||
|
member.id = id
|
||||||
|
self.pool[id] = member
|
||||||
|
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)
|
||||||
|
|
||||||
|
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
|
||||||
|
end
|
||||||
|
function Swarm:shutdown()
|
||||||
|
for _, member in pairs(self.pool) do
|
||||||
|
if member.socket then
|
||||||
|
member.socket:close()
|
||||||
|
member.socket = nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
function Swarm:onRemove(member, success, msg)
|
||||||
|
print('removed from pool: ' .. member.id)
|
||||||
|
if not success then
|
||||||
|
_G.printError(msg)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return Swarm
|
||||||
43
turtle/autorun/gps.lua
Normal file
43
turtle/autorun/gps.lua
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
local modem = _G.device.wireless_modem
|
||||||
|
local turtle = _G.turtle
|
||||||
|
|
||||||
|
if turtle and modem then
|
||||||
|
local s, m = turtle.run(function()
|
||||||
|
|
||||||
|
_G.requireInjector(_ENV)
|
||||||
|
|
||||||
|
local Config = require('config')
|
||||||
|
local config = {
|
||||||
|
destructive = false,
|
||||||
|
}
|
||||||
|
Config.load('gps', config)
|
||||||
|
|
||||||
|
if config.home then
|
||||||
|
|
||||||
|
local s = turtle.enableGPS(2)
|
||||||
|
if not s then
|
||||||
|
s = turtle.enableGPS(2)
|
||||||
|
end
|
||||||
|
if not s and config.destructive then
|
||||||
|
turtle.set({ attackPolicy = 'attack', digPolicy = 'turtleSafe' })
|
||||||
|
s = turtle.enableGPS(2)
|
||||||
|
end
|
||||||
|
|
||||||
|
if not s then
|
||||||
|
error('Unable to get GPS position')
|
||||||
|
end
|
||||||
|
|
||||||
|
if config.destructive then
|
||||||
|
turtle.set({ attackPolicy = 'attack', digPolicy = 'turtleSafe' })
|
||||||
|
end
|
||||||
|
|
||||||
|
if not turtle.pathfind(config.home) then
|
||||||
|
error('Failed to return home')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
if not s and m then
|
||||||
|
error(m)
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -1,9 +1,12 @@
|
|||||||
local Util = require('util')
|
local Util = require('util')
|
||||||
|
|
||||||
local device = _G.device
|
local device = _G.device
|
||||||
|
local fs = _G.fs
|
||||||
local turtle = _G.turtle
|
local turtle = _G.turtle
|
||||||
|
|
||||||
if turtle then
|
if turtle then
|
||||||
|
fs.mount('sys/apps/system/turtle.lua', 'linkfs', 'packages/turtle/system/turtle.lua')
|
||||||
|
|
||||||
function turtle.scan(blocks)
|
function turtle.scan(blocks)
|
||||||
local pt = turtle.point
|
local pt = turtle.point
|
||||||
local scanner = device['plethora:scanner'] or error('Scanner not equipped')
|
local scanner = device['plethora:scanner'] or error('Scanner not equipped')
|
||||||
8
turtle/etc/apps.db
Normal file
8
turtle/etc/apps.db
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
[ "47b3d6dc1170faf4ae496fff3db374817bf32e2f" ] = {
|
||||||
|
title = "Refuel",
|
||||||
|
category = "Apps",
|
||||||
|
run = "lavaRefuel.lua",
|
||||||
|
requires = 'turtle',
|
||||||
|
},
|
||||||
|
}
|
||||||
@@ -56,7 +56,7 @@ local s, m = turtle.run(function()
|
|||||||
end)
|
end)
|
||||||
|
|
||||||
turtle.gotoY(0)
|
turtle.gotoY(0)
|
||||||
turtle._goto({ x = 0, y = 0, z = 0 })
|
turtle.go({ x = 0, y = 0, z = 0 })
|
||||||
|
|
||||||
turtle.unequip('right')
|
turtle.unequip('right')
|
||||||
print('Fuel: ' .. turtle.getFuelLevel())
|
print('Fuel: ' .. turtle.getFuelLevel())
|
||||||
@@ -1,5 +1,3 @@
|
|||||||
_G.requireInjector(_ENV)
|
|
||||||
|
|
||||||
local Point = require('point')
|
local Point = require('point')
|
||||||
local Util = require('util')
|
local Util = require('util')
|
||||||
|
|
||||||
@@ -67,7 +65,7 @@ local function findObsidian()
|
|||||||
end
|
end
|
||||||
|
|
||||||
node = Point.closest(turtle.point, nodes)
|
node = Point.closest(turtle.point, nodes)
|
||||||
if not turtle._goto(node) then
|
if not turtle.go(node) then
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
until turtle.isAborted()
|
until turtle.isAborted()
|
||||||
@@ -91,7 +89,7 @@ turtle.run(function()
|
|||||||
if not turtle.select('minecraft:water_bucket') then
|
if not turtle.select('minecraft:water_bucket') then
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
turtle._goto({ x = 0, z = 0 })
|
turtle.go({ x = 0, z = 0 })
|
||||||
turtle.placeDown()
|
turtle.placeDown()
|
||||||
os.sleep(2)
|
os.sleep(2)
|
||||||
turtle.placeDown()
|
turtle.placeDown()
|
||||||
@@ -104,5 +102,5 @@ turtle.run(function()
|
|||||||
error(m)
|
error(m)
|
||||||
end
|
end
|
||||||
|
|
||||||
turtle._goto({ x = 0, y = 0, z = 0, heading = 0 })
|
turtle.go({ x = 0, y = 0, z = 0, heading = 0 })
|
||||||
end)
|
end)
|
||||||
63
turtle/system/turtle.lua
Normal file
63
turtle/system/turtle.lua
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
local Config = require('config')
|
||||||
|
local UI = require('ui')
|
||||||
|
|
||||||
|
local fs = _G.fs
|
||||||
|
local turtle = _G.turtle
|
||||||
|
|
||||||
|
if turtle then
|
||||||
|
local Home = require('turtle.home')
|
||||||
|
|
||||||
|
local values = { }
|
||||||
|
Config.load('gps', values.home and { values.home } or { })
|
||||||
|
|
||||||
|
local gpsTab = UI.Tab {
|
||||||
|
tabTitle = 'GPS',
|
||||||
|
labelText = UI.Text {
|
||||||
|
x = 3, y = 2,
|
||||||
|
value = 'On restart, return to this location'
|
||||||
|
},
|
||||||
|
grid = UI.Grid {
|
||||||
|
x = 3, ex = -3, y = 4,
|
||||||
|
height = 2,
|
||||||
|
values = values,
|
||||||
|
inactive = true,
|
||||||
|
columns = {
|
||||||
|
{ heading = 'x', key = 'x' },
|
||||||
|
{ heading = 'y', key = 'y' },
|
||||||
|
{ heading = 'z', key = 'z' },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
button1 = UI.Button {
|
||||||
|
x = 3, y = 7,
|
||||||
|
text = 'Set home',
|
||||||
|
event = 'gps_set',
|
||||||
|
},
|
||||||
|
button2 = UI.Button {
|
||||||
|
ex = -3, y = 7, width = 7,
|
||||||
|
text = 'Clear',
|
||||||
|
event = 'gps_clear',
|
||||||
|
},
|
||||||
|
}
|
||||||
|
function gpsTab:eventHandler(event)
|
||||||
|
if event.type == 'gps_set' then
|
||||||
|
self:emit({ type = 'info_message', message = 'Determining location' })
|
||||||
|
self:sync()
|
||||||
|
if Home.set() then
|
||||||
|
Config.load('gps', values)
|
||||||
|
self.grid:setValues(values.home and { values.home } or { })
|
||||||
|
self.grid:draw()
|
||||||
|
self:emit({ type = 'success_message', message = 'Location set' })
|
||||||
|
else
|
||||||
|
self:emit({ type = 'error_message', message = 'Unable to determine location' })
|
||||||
|
end
|
||||||
|
return true
|
||||||
|
elseif event.type == 'gps_clear' then
|
||||||
|
fs.delete('usr/config/gps')
|
||||||
|
self.grid:setValues({ })
|
||||||
|
self.grid:draw()
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return gpsTab
|
||||||
|
end
|
||||||
Reference in New Issue
Block a user