AutoMine: Add recall mode and switch to rednet
This commit is contained in:
parent
e1e4ec871b
commit
50027f90b1
120
mine.lua
120
mine.lua
@ -321,7 +321,8 @@ local BLACKLIST = Set{
|
||||
"advancedperipherals:chunk_controller",
|
||||
}
|
||||
local FUEL = "minecraft:coal"
|
||||
local CHANNEL = 1337
|
||||
local PROTOCOL = "automine"
|
||||
local PROTOCOL_CTRL = "automineCtrl"
|
||||
|
||||
settings.define("mine.name", {
|
||||
description = "Miner name",
|
||||
@ -365,8 +366,7 @@ function Miner.new()
|
||||
self.scanner = peripheral.wrap("right")
|
||||
|
||||
self:equip("computercraft:wireless_modem_advanced", "right")
|
||||
self.modem = peripheral.wrap("right")
|
||||
self.modem.open(CHANNEL)
|
||||
rednet.open("right")
|
||||
|
||||
self.pos = vector.new(0, 0, 0)
|
||||
self:doGPS(true)
|
||||
@ -391,10 +391,11 @@ end
|
||||
|
||||
function Miner:sendMessage(type, msg)
|
||||
self:equip("computercraft:wireless_modem_advanced", "right")
|
||||
rednet.open("right")
|
||||
msg["type"] = type
|
||||
msg["name"] = self.name
|
||||
msg["pos"] = self.absolutePos
|
||||
self.modem.transmit(CHANNEL, CHANNEL, msg)
|
||||
rednet.broadcast(msg, PROTOCOL)
|
||||
end
|
||||
|
||||
function Miner:dig(dir)
|
||||
@ -552,6 +553,22 @@ function Miner:navigateThrough(path)
|
||||
end
|
||||
end
|
||||
|
||||
function Miner:checkRecall()
|
||||
local sender, msg = rednet.receive(PROTOCOL_CTRL, 0.5)
|
||||
if sender and msg.type == "recall" then
|
||||
-- HACK: Seems like we need this so the monitor can pick up the ack...
|
||||
sleep(0.5)
|
||||
self:sendMessage("ackRecall", msg)
|
||||
|
||||
local to = vector.new(msg.to.x, msg.to.y, msg.to.z)
|
||||
print("Recalling to " .. to:tostring())
|
||||
self:navigateThrough({self.pos + (to - self.absolutePos)})
|
||||
return true
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
function Miner:mineOres(radius)
|
||||
local startingDir = self.dir
|
||||
self.pos = vector.new(0, 0, 0)
|
||||
@ -590,6 +607,9 @@ function Miner:mineOres(radius)
|
||||
oreCount = #ores,
|
||||
veins = veinsSummary,
|
||||
})
|
||||
if self:checkRecall() then
|
||||
return false
|
||||
end
|
||||
|
||||
for pi, i in ipairs(veinsPath) do
|
||||
self:xchgItems()
|
||||
@ -631,97 +651,21 @@ function Miner:mineOres(radius)
|
||||
oreType = vein.type,
|
||||
oreCount = #vein.blocks,
|
||||
})
|
||||
if self:checkRecall() then
|
||||
return false
|
||||
end
|
||||
|
||||
self:navigateThrough(veinPath)
|
||||
end
|
||||
|
||||
self:navigateThrough({veinsPoints[2]})
|
||||
self:faceDir(startingDir)
|
||||
self.i = self.i + 1
|
||||
return true
|
||||
end
|
||||
|
||||
local miner = Miner.new()
|
||||
while true do
|
||||
miner:mineOres(16)
|
||||
local shouldRun = true
|
||||
while shouldRun do
|
||||
shouldRun = miner:mineOres(16)
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
-- test code, please ignore
|
||||
assert(false)
|
||||
|
||||
-- local f, err = fs.open("points.csv", "w")
|
||||
-- assert(f, err)
|
||||
|
||||
local points = {
|
||||
vector.new(0, 0, 0),
|
||||
vector.new(0, 0, -16),
|
||||
}
|
||||
for _, b in ipairs(ores) do
|
||||
-- print("found " .. b.name .. " at " .. b.x .. ", " .. b.y .. ", " .. b.z)
|
||||
table.insert(points, vector.new(b.x, b.y, b.z))
|
||||
end
|
||||
print("found "..#ores.." ores")
|
||||
|
||||
local dist = findDistances(points)
|
||||
local groups = groupOres(ores, dist, 2)
|
||||
|
||||
for _, g in ipairs(groups) do
|
||||
print("group of "..#g.blocks.." "..g.type.." at", g.center)
|
||||
end
|
||||
print(#groups, "groups of ore found")
|
||||
|
||||
local gPoints = {
|
||||
vector.new(0, 0, 0),
|
||||
vector.new(0, 0, -16),
|
||||
}
|
||||
for _, g in ipairs(groups) do
|
||||
table.insert(gPoints, g.center)
|
||||
end
|
||||
|
||||
local gDist = findDistances(gPoints)
|
||||
local gPath = pathThrough(gPoints, gDist, 1, 2)
|
||||
for _, i in ipairs(gPath) do
|
||||
local p = gPoints[i]
|
||||
f.write(p.x..","..p.y..","..p.z.."\n")
|
||||
end
|
||||
|
||||
f.write("MARK\n")
|
||||
|
||||
-- print(points[1], gPoints[gPath[1]])
|
||||
-- local pathTo = findPath(points[1], gPoints[gPath[1]])
|
||||
-- for _, p in ipairs(pathTo) do
|
||||
-- -- local p = pathTo[i]
|
||||
-- -- print(p)
|
||||
-- f.write(p.x..","..p.y..","..p.z.."\n")
|
||||
-- end
|
||||
|
||||
miner:mineOres(groups)
|
||||
|
||||
-- table.remove(pathTo, 1)
|
||||
-- table.remove(pathTo, #pathTo)
|
||||
-- miner:navigateThrough(pathTo)
|
||||
|
||||
-- f.write("MARK\n")
|
||||
|
||||
-- local allPath = pathThrough(points, dist, 1, 2)
|
||||
-- for _, i in ipairs(allPath) do
|
||||
-- local p = points[i]
|
||||
-- -- print(points[i])
|
||||
-- f.write(p.x..","..p.y..","..p.z.."\n")
|
||||
-- end
|
||||
|
||||
f.close()
|
||||
|
||||
-- local f = vector.new(1, 0, 0)
|
||||
-- local p = vector.new(0, -1, 7)
|
||||
-- local t = vector.new(-1, -1, 7)
|
||||
|
||||
-- print(direction(t - p) - direction(f))
|
||||
|
193
mineMonitor.lua
193
mineMonitor.lua
@ -1,4 +1,4 @@
|
||||
local CHANNEL = 1337
|
||||
local PROTOCOL = "automine"
|
||||
local TARGET = "devplayer0"
|
||||
local ICON_BASE = "https://p.nul.ie/cc/icon/"
|
||||
local ORE_ICONS = {
|
||||
@ -41,11 +41,6 @@ function oreIcon(t)
|
||||
return ICON_BASE .. "ore-" .. i .. ".png"
|
||||
end
|
||||
|
||||
local modem = peripheral.find("modem")
|
||||
-- local monitor = peripheral.find("monitor")
|
||||
local chat = peripheral.find("chatBox")
|
||||
local cartographer = peripheral.find("cartographer")
|
||||
|
||||
function vecToStr(v)
|
||||
return v.x .. "," .. v.y .. "," .. v.z
|
||||
end
|
||||
@ -54,18 +49,60 @@ function markerSet(msg)
|
||||
return "autominer_" .. msg.name
|
||||
end
|
||||
|
||||
function setPosMarker(msg)
|
||||
Chat = {}
|
||||
function Chat.new(prefix)
|
||||
local self = setmetatable({}, { __index = Chat })
|
||||
|
||||
self.chat = peripheral.find("chatBox")
|
||||
self.prefix = prefix
|
||||
self.lastSend = 0
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
function Chat:send(msg, target)
|
||||
local delta = os.clock() - self.lastSend
|
||||
if delta < 1 then
|
||||
local amount = 1 - delta + 0.1
|
||||
sleep(amount)
|
||||
end
|
||||
|
||||
local msgJSON = textutils.serializeJSON(msg)
|
||||
-- print(msgJSON)
|
||||
if target then
|
||||
assert(self.chat.sendFormattedMessageToPlayer(msgJSON, target, self.prefix))
|
||||
else
|
||||
assert(self.chat.sendFormattedMessage(msgJSON, self.prefix))
|
||||
end
|
||||
self.lastSend = os.clock()
|
||||
end
|
||||
|
||||
MineMonitor = {}
|
||||
function MineMonitor.new(chat)
|
||||
local self = setmetatable({}, { __index = MineMonitor })
|
||||
|
||||
self.chat = chat
|
||||
|
||||
self.cart = peripheral.find("cartographer")
|
||||
self.cart.refreshIntegrations()
|
||||
|
||||
peripheral.find("modem", rednet.open)
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
function MineMonitor:setPosMarker(msg)
|
||||
local id = markerSet(msg)
|
||||
local mId = id .. "_pos"
|
||||
cartographer.removeMarker(id, mId)
|
||||
cartographer.addPOIMarker(
|
||||
self.cart.removeMarker(id, mId)
|
||||
self.cart.addPOIMarker(
|
||||
id, mId, msg.name, msg.name .. "'s position",
|
||||
msg.pos.x, msg.pos.y, msg.pos.z,
|
||||
ICON_BASE .. "turtle.png")
|
||||
end
|
||||
|
||||
function handleStart(msg)
|
||||
local cMsg = {
|
||||
function MineMonitor:handleStart(msg)
|
||||
self.chat:send({
|
||||
{text = msg.name, color = "green"},
|
||||
{text = " @ ", color = "white"},
|
||||
{text = vecToStr(msg.pos), color = "aqua"},
|
||||
@ -76,33 +113,33 @@ function handleStart(msg)
|
||||
{text = " veins) on iteration ", color = "white"},
|
||||
{text = tostring(msg.i), color = "green"},
|
||||
{text = "!", color = "white"},
|
||||
}
|
||||
local msgJSON = textutils.serializeJSON(cMsg)
|
||||
chat.sendFormattedMessage(msgJSON, "AutoMine")
|
||||
})
|
||||
|
||||
local id = markerSet(msg)
|
||||
cartographer.addMarkerSet(id, "AutoMiner " .. msg.name)
|
||||
cartographer.clearMarkerSet(id)
|
||||
self.cart.addMarkerSet(id, "AutoMiner " .. msg.name)
|
||||
self.cart.clearMarkerSet(id)
|
||||
|
||||
setPosMarker(msg)
|
||||
self:setPosMarker(msg)
|
||||
|
||||
local orePoints = {}
|
||||
local veinPoints = {}
|
||||
for i, v in ipairs(msg.veins) do
|
||||
table.insert(orePoints, v.pos)
|
||||
cartographer.addPOIMarker(
|
||||
table.insert(veinPoints, v.pos)
|
||||
self.cart.addPOIMarker(
|
||||
id, id .. "_vein_" .. i, v.count .. " " .. v.type, "Vein of " .. v.count .. " " .. v.type,
|
||||
v.pos.x, v.pos.y, v.pos.z,
|
||||
oreIcon(v.type))
|
||||
end
|
||||
|
||||
cartographer.addLineMarker(
|
||||
id, id .. "_vein_path", "Mining path #" .. msg.i, "Current mining path",
|
||||
"#FF00FF", 0.7, 3,
|
||||
orePoints)
|
||||
if #veinPoints >= 2 then
|
||||
self.cart.addLineMarker(
|
||||
id, id .. "_vein_path", "Mining path #" .. msg.i, "Current mining path",
|
||||
"#FF00FF", 0.7, 3,
|
||||
veinPoints)
|
||||
end
|
||||
end
|
||||
|
||||
function handleVein(msg)
|
||||
local cMsg = {
|
||||
function MineMonitor:handleVein(msg)
|
||||
self.chat:send({
|
||||
{text = msg.name, color = "green"},
|
||||
{text = " @ ", color = "white"},
|
||||
{text = vecToStr(msg.pos), color = "aqua"},
|
||||
@ -115,71 +152,67 @@ function handleVein(msg)
|
||||
{text = " / ", color = "white"},
|
||||
{text = tostring(msg.total), color = "red"},
|
||||
{text = ")!", color = "white"},
|
||||
}
|
||||
local msgJSON = textutils.serializeJSON(cMsg)
|
||||
chat.sendFormattedMessageToPlayer(msgJSON, TARGET, "AutoMine")
|
||||
}, TARGET)
|
||||
|
||||
local id = markerSet(msg)
|
||||
setPosMarker(msg)
|
||||
self:setPosMarker(msg)
|
||||
if msg.i ~= 1 then
|
||||
cartographer.removeMarker(id, id .. "_vein_" .. (msg.i - 1))
|
||||
self.cart.removeMarker(id, id .. "_vein_" .. (msg.i - 1))
|
||||
end
|
||||
end
|
||||
|
||||
cartographer.refreshIntegrations()
|
||||
function MineMonitor:handleRecall(msg)
|
||||
self.chat:send({
|
||||
{text = msg.name, color = "green"},
|
||||
{text = " @ ", color = "white"},
|
||||
{text = vecToStr(msg.pos), color = "aqua"},
|
||||
{text = " is recalling to ", color = "white"},
|
||||
{text = vecToStr(msg.to), color = "green"},
|
||||
{text = "!", color = "white"},
|
||||
})
|
||||
|
||||
modem.open(CHANNEL)
|
||||
local id = markerSet(msg)
|
||||
self.cart.addMarkerSet(id, "AutoMiner " .. msg.name)
|
||||
self.cart.clearMarkerSet(id)
|
||||
|
||||
-- handleStart({
|
||||
-- i = 69,
|
||||
-- oreCount = 1337,
|
||||
-- veins = {
|
||||
-- {
|
||||
-- pos = {x = 297, y = 124, z = 1935},
|
||||
-- type = "minecraft:coal_ore",
|
||||
-- count = 12,
|
||||
-- },
|
||||
-- {
|
||||
-- pos = {x = 297, y = 134, z = 1935},
|
||||
-- type = "minecraft:iron_ore",
|
||||
-- count = 7,
|
||||
-- },
|
||||
-- {
|
||||
-- pos = {x = 400, y = 134, z = 1935},
|
||||
-- type = "minecraft:diamond_ore",
|
||||
-- count = 2,
|
||||
-- },
|
||||
-- {
|
||||
-- pos = {x = 400, y = 134, z = 1975},
|
||||
-- type = "minecraft:sussy_ore",
|
||||
-- count = 7,
|
||||
-- }
|
||||
-- },
|
||||
-- name = "test",
|
||||
-- pos = {x = 297, y = 154, z = 1935},
|
||||
-- })
|
||||
-- handleVein({
|
||||
-- i = 2,
|
||||
-- total = 69,
|
||||
-- oreCount = 1337,
|
||||
-- oreType = "minecraft:yeet",
|
||||
-- name = "test",
|
||||
-- pos = {x = 1, y = 2, z = 3},
|
||||
-- })
|
||||
-- assert(false)
|
||||
self:setPosMarker({
|
||||
name = msg.name,
|
||||
pos = msg.to,
|
||||
})
|
||||
end
|
||||
|
||||
while true do
|
||||
local event, side, channel, replyChannel, msg, distance = os.pullEvent("modem_message")
|
||||
if channel == CHANNEL then
|
||||
function MineMonitor:loop()
|
||||
while true do
|
||||
local _, sender, msg = os.pullEvent("mine_monitor_message")
|
||||
local handler = nil
|
||||
if msg.type == "iterationStart" then
|
||||
handleStart(msg)
|
||||
-- sendChat(msg.name.." found "..msg.oreCount.." ores ("..msg.veinCount.." veins)")
|
||||
-- for _, v in ipairs(msg.path) do
|
||||
-- print("vein path "..v.x..", "..v.y..", "..v.z)
|
||||
-- end
|
||||
handler = self.handleStart
|
||||
elseif msg.type == "veinStart" then
|
||||
handleVein(msg)
|
||||
-- sendChat(msg.name.." is mining "..msg.count.." "..msg.oreType.." (vein "..msg.i..") @ "..msg.pos.x..", "..msg.pos.y..", "..msg.pos.z)
|
||||
handler = self.handleVein
|
||||
elseif msg.type == "ackRecall" then
|
||||
handler = self.handleRecall
|
||||
end
|
||||
|
||||
if handler then
|
||||
handler(self, msg)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function MineMonitor:netLoop()
|
||||
while true do
|
||||
local sender, msg = rednet.receive(PROTOCOL)
|
||||
os.queueEvent("mine_monitor_message", sender, msg)
|
||||
end
|
||||
end
|
||||
|
||||
function MineMonitor:run()
|
||||
parallel.waitForAll(
|
||||
function() self:loop() end,
|
||||
function() self:netLoop() end
|
||||
)
|
||||
end
|
||||
|
||||
local chat = Chat.new("AutoMine")
|
||||
local mineMon = MineMonitor.new(chat)
|
||||
mineMon:run()
|
||||
|
45
mineRemote.lua
Normal file
45
mineRemote.lua
Normal file
@ -0,0 +1,45 @@
|
||||
local PROTOCOL = "automine"
|
||||
local PROTOCOL_CTRL = "automineCtrl"
|
||||
|
||||
function Set(list)
|
||||
local set = {}
|
||||
for _, l in ipairs(list) do set[l] = true end
|
||||
return set
|
||||
end
|
||||
|
||||
function awaitMessage(types, target)
|
||||
while true do
|
||||
local targetId, msg = rednet.receive(PROTOCOL)
|
||||
if types[msg.type] and msg.name == target then
|
||||
return targetId, msg
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function run(target)
|
||||
local x, y, z = gps.locate()
|
||||
assert(x, "Couldn't run GPS")
|
||||
local to = vector.new(math.floor(x), math.floor(y), math.floor(z))
|
||||
print(target .. " will recall to " .. to:tostring())
|
||||
|
||||
print("Waiting for " .. target .. "...")
|
||||
local targetId, msg = awaitMessage(Set{"iterationStart", "veinStart"}, target)
|
||||
assert(targetId)
|
||||
|
||||
print("Sending recall request")
|
||||
rednet.send(targetId, {
|
||||
type = "recall",
|
||||
to = to,
|
||||
}, PROTOCOL_CTRL)
|
||||
|
||||
local _, msg = awaitMessage(Set{"ackRecall"}, target)
|
||||
assert(msg)
|
||||
print("Received confirmation of recall from " .. target )
|
||||
end
|
||||
|
||||
if arg[1] then
|
||||
rednet.open("back")
|
||||
run(arg[1])
|
||||
else
|
||||
print("usage: " .. arg[0] .. " <target>")
|
||||
end
|
Loading…
Reference in New Issue
Block a user