diff --git a/mine.lua b/mine.lua index 2be7dc7..e9a1508 100644 --- a/mine.lua +++ b/mine.lua @@ -158,7 +158,7 @@ function pathThrough(points, dist, s, e) end -- A* -function findPath(s, e, neighbors) +function findPath(s, e, neighbors, limit) local points = {} function addPoint(p) local k = p:tostring() @@ -201,11 +201,16 @@ function findPath(s, e, neighbors) local prev = {} local found = false + local brokeLimit = false while not openSet:empty() do local current = openSet:dequeue() if current == e then found = true break + elseif limit and (points[current] - points[s]):length() > limit then + e = current + brokeLimit = true + break end local ns = neighbors(points[current]) @@ -225,7 +230,7 @@ function findPath(s, e, neighbors) end end end - assert(found) + assert(found or brokeLimit) local path = {points[e]} local current = e @@ -233,7 +238,7 @@ function findPath(s, e, neighbors) current = prev[current] table.insert(path, 1, points[current]) end - return path + return path, brokeLimit end local ORES = Set{ @@ -372,7 +377,7 @@ function Miner:dig(dir) end end -function Miner:xchgItems() +function Miner:xchgItems(forceUnload) local slots = {} local emptySlots = 0 for i = 1, 16 do @@ -387,7 +392,7 @@ function Miner:xchgItems() end end - if emptySlots >= 2 and turtle.getFuelLevel() >= 1000 then + if (emptySlots >= 2 and not forceUnload) and turtle.getFuelLevel() >= 1000 then return end @@ -395,7 +400,7 @@ function Miner:xchgItems() self:dig("down") end - if emptySlots < 2 then + if emptySlots < 2 or forceUnload then selectItem("enderchests:ender_chest") assert(turtle.placeDown()) @@ -515,7 +520,7 @@ function Miner:faceDir(newDir) end end -function Miner:navigateThrough(path) +function Miner:navigateThrough(path, limit) for _, p in ipairs(path) do -- print("move from to", self.pos, p) local delta = p - self.pos @@ -523,12 +528,17 @@ function Miner:navigateThrough(path) -- print("doing", delta) if delta:length() ~= 1 then -- print("path finding between points") - local path = findPath(self.pos, p, function(v) return self:safeNeighbors(v) end) + local path, brokeLimit = findPath(self.pos, p, function(v) return self:safeNeighbors(v) end, limit) table.remove(path, 1) - table.remove(path, #path) + if not brokeLimit then + table.remove(path, #path) + end assert(#path ~= 0) self:navigateThrough(path) + if brokeLimit then + return false + end delta = p - self.pos end assert(delta:length() == 1) @@ -547,6 +557,7 @@ function Miner:navigateThrough(path) self.pos = p self.absolutePos = self.absolutePos + delta end + return true end function Miner:checkRecall() @@ -556,9 +567,14 @@ function Miner:checkRecall() sleep(0.5) self:sendMessage("ackRecall", msg) + self:xchgItems(true) + 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)}) + while not self:navigateThrough({self.pos + (to - self.absolutePos)}, 64) do + self:sendMessage("recallProgress", { to = msg.to }) + self:xchgItems() + end return true end diff --git a/mineMonitor.lua b/mineMonitor.lua index 85bf8be..fe3d6eb 100644 --- a/mineMonitor.lua +++ b/mineMonitor.lua @@ -90,10 +90,11 @@ function Chat:send(msg, target) end MineMonitor = {} -function MineMonitor.new(chat) +function MineMonitor.new(chat, target) local self = setmetatable({}, { __index = MineMonitor }) self.chat = chat + self.target = target self.cart = peripheral.find("cartographer") self.cart.refreshIntegrations() @@ -189,7 +190,7 @@ function MineMonitor:handleVein(msg) {text = " / ", color = "white"}, {text = tostring(msg.total), color = "red"}, {text = ")!", color = "white"}, - }, TARGET) + }, self.target) local id = self:prepareMap(msg) self:setPosMarker(msg) @@ -219,6 +220,24 @@ function MineMonitor:handleRecall(msg) }) end +function MineMonitor:handleRecallProgress(msg) + self.chat:send({ + {text = msg.name, color = "green"}, + {text = " @ ", color = "white"}, + {text = vecToStr(msg.pos), color = "aqua"}, + {text = " in ", color = "white"}, + {text = msg.dimension, color = "aqua"}, + {text = " is ", color = "white"}, + {text = "still", color = "green"}, + {text = " recalling to ", color = "white"}, + {text = vecToStr(msg.to), color = "green"}, + {text = "!", color = "white"}, + }, self.target) + + self:prepareMap(msg) + self:setPosMarker(msg) +end + function MineMonitor:loop() while true do local _, sender, msg = os.pullEvent("mine_monitor_message") @@ -229,6 +248,8 @@ function MineMonitor:loop() handler = self.handleVein elseif msg.type == "ackRecall" then handler = self.handleRecall + elseif msg.type == "recallProgress" then + handler = self.handleRecallProgress end if handler then @@ -252,5 +273,5 @@ function MineMonitor:run() end local chat = Chat.new("AutoMine") -local mineMon = MineMonitor.new(chat) +local mineMon = MineMonitor.new(chat, TARGET) mineMon:run()