diff --git a/turtle.lua b/turtle.lua index f3db946..f3de564 100644 --- a/turtle.lua +++ b/turtle.lua @@ -1,609 +1,141 @@ --- Server-Driven Turtle v5 (Pure Eval Protocol)-- Advanced Autonomous Mining Turtle v4 (Eval/Response Protocol) - --- All behavior is driven by the server via eval commands.-- Features: Server-driven state machine, UUID command correlation, - --- This script only handles: eval execution, status broadcasting,-- GPS tracking, local fallback intelligence, block scanning - +-- Server-Driven Turtle v5 (Pure Eval Protocol) +-- All behavior is driven by the server via eval commands. +-- This script only handles: eval execution, status broadcasting, -- GPS tracking, inventory/peripheral events. local CHANNEL_RECEIVE = 100 - -local CHANNEL_RECEIVE = 100local CHANNEL_SEND = 101 - -local CHANNEL_SEND = 101local STATUS_CHANNEL = 102 - +local CHANNEL_SEND = 101 local STATUS_CHANNEL = 102 --- State tracking (lightweight - server drives behavior via eval) - --- State tracking (lightweight - server drives everything)local state = { - -local state = { mode = "idle", - - position = nil, position = nil, - - homePosition = nil, homePosition = nil, - - fuel = 0, fuel = 0, - - inventory = {}, inventory = {}, - - facing = 0, facing = 0, - - lastStatusUpdate = 0, lastStatusUpdate = 0, - -} evalSupported = true, - +-- State tracking (lightweight - server drives everything) +local state = { + position = nil, + homePosition = nil, + fuel = 0, + inventory = {}, + facing = 0, + lastStatusUpdate = 0, } -- Configuration +local config = { + statusUpdateInterval = 5, +} -local config = {-- Configuration - - statusUpdateInterval = 5,local config = { - -} statusUpdateInterval = 5, - - valuableBlocks = { - --- Check for modem ["minecraft:coal_ore"] = 1, - -local modem = peripheral.find("modem") ["minecraft:iron_ore"] = 2, - -if not modem then ["minecraft:gold_ore"] = 3, - - error("No wireless modem found!") ["minecraft:diamond_ore"] = 5, - -end ["minecraft:emerald_ore"] = 5, - -modem.open(CHANNEL_RECEIVE) ["minecraft:redstone_ore"] = 2, - -print("Server-Driven Turtle v5 (Pure Eval Protocol)") ["minecraft:lapis_ore"] = 2, - -print("ID: " .. os.getComputerID()) ["minecraft:deepslate_coal_ore"] = 1, - -print("Modem opened on channel " .. CHANNEL_RECEIVE) ["minecraft:deepslate_iron_ore"] = 2, - - ["minecraft:deepslate_gold_ore"] = 3, - --- Store facing in global for eval access ["minecraft:deepslate_diamond_ore"] = 5, - -_G._turtleFacing = 0 ["minecraft:deepslate_emerald_ore"] = 5, - - ["minecraft:deepslate_redstone_ore"] = 2, - --- ========== GPS Functions ========== ["minecraft:deepslate_lapis_ore"] = 2, - - } - -local function updatePosition()} - - local x, y, z = gps.locate(2) - - if x then-- Check for modem - - state.position = {x = math.floor(x), y = math.floor(y), z = math.floor(z)}local modem = peripheral.find("modem") - - return trueif not modem then - - end error("No wireless modem found!") - - return falseend - -endmodem.open(CHANNEL_RECEIVE) - -print("Advanced Mining Turtle v4 (Eval Protocol)") - --- ========== Fuel & Inventory ==========print("ID: " .. os.getComputerID()) +-- Check for modem +local modem = peripheral.find("modem") +if not modem then + error("No wireless modem found!") +end +modem.open(CHANNEL_RECEIVE) +print("Server-Driven Turtle v5 (Pure Eval Protocol)") +print("ID: " .. os.getComputerID()) print("Modem opened on channel " .. CHANNEL_RECEIVE) -local function updateFuel() - - state.fuel = turtle.getFuelLevel()-- Store facing in global for eval access - - return state.fuel_G._turtleFacing = 0 - -end +-- Store facing in global for eval access +_G._turtleFacing = 0 -- ========== GPS Functions ========== -local function updateInventory() - - state.inventory = {}local function updatePosition() - - for slot = 1, 16 do local x, y, z = gps.locate(2) - - local item = turtle.getItemDetail(slot) if x then - - if item then state.position = {x = math.floor(x), y = math.floor(y), z = math.floor(z)} - - table.insert(state.inventory, { return true - - slot = slot, end - - name = item.name, return false - - count = item.countend - - }) - - end-- ========== Movement Functions (with position tracking) ========== - +local function updatePosition() + local x, y, z = gps.locate(2) + if x then + state.position = {x = math.floor(x), y = math.floor(y), z = math.floor(z)} + return true end - -endlocal function updateFacingAfterTurn(right) - - if right then - --- ========== Status Broadcasting ========== state.facing = (state.facing + 1) % 4 - - else - -local function broadcastStatus() state.facing = (state.facing - 1) % 4 - - updateFuel() end - - updateInventory() _G._turtleFacing = state.facing - + return false end - local surroundings = {} - - local hasBlock, datalocal function smartForward() - - local success = turtle.forward() - - hasBlock, data = turtle.inspect() if success and state.position then - - if hasBlock then surroundings.forward = {name = data.name, metadata = data.metadata or 0} end if state.facing == 0 then state.position.z = state.position.z - 1 - - elseif state.facing == 1 then state.position.x = state.position.x + 1 - - hasBlock, data = turtle.inspectUp() elseif state.facing == 2 then state.position.z = state.position.z + 1 - - if hasBlock then surroundings.up = {name = data.name, metadata = data.metadata or 0} end elseif state.facing == 3 then state.position.x = state.position.x - 1 - - end - - hasBlock, data = turtle.inspectDown() end - - if hasBlock then surroundings.down = {name = data.name, metadata = data.metadata or 0} end return success - -end - - local statusPacket = { - - type = "status",local function smartBack() - - turtleID = os.getComputerID(), local success = turtle.back() - - position = state.position, if success and state.position then - - homePosition = state.homePosition, if state.facing == 0 then state.position.z = state.position.z + 1 - - fuel = state.fuel, elseif state.facing == 1 then state.position.x = state.position.x - 1 - - inventoryCount = #state.inventory, elseif state.facing == 2 then state.position.z = state.position.z - 1 - - inventory = state.inventory, elseif state.facing == 3 then state.position.x = state.position.x + 1 - - facing = state.facing, end - - surroundings = surroundings, end - - evalSupported = true, return success - - label = os.getComputerLabel(),end - - } - -local function smartUp() - - modem.transmit(STATUS_CHANNEL, CHANNEL_RECEIVE, statusPacket) local success = turtle.up() - -end if success and state.position then - - state.position.y = state.position.y + 1 - --- ========== Eval/Response Protocol ========== end - - return success - -local function executeEval(uuid, code)end - - local fn, compileError = load(code, "eval", "t") - - if not fn thenlocal function smartDown() - - modem.transmit(CHANNEL_SEND, CHANNEL_RECEIVE, { local success = turtle.down() - - type = "eval_response", if success and state.position then - - uuid = uuid, state.position.y = state.position.y - 1 - - result = nil, end - - error = "Compile error: " .. tostring(compileError), return success - - turtleID = os.getComputerID()end - - }) - - returnlocal function smartTurnRight() - - end local success = turtle.turnRight() - - if success then updateFacingAfterTurn(true) end - - local results = table.pack(pcall(fn)) return success - - local ok = results[1]end - - - - if ok thenlocal function smartTurnLeft() - - local returnVal local success = turtle.turnLeft() - - if results.n <= 2 then if success then updateFacingAfterTurn(false) end - - returnVal = results[2] return success - - elseend - - returnVal = {} - - for i = 2, results.n do-- ========== Fuel & Inventory ========== - - returnVal[i - 1] = results[i] - - endlocal function updateFuel() - - end state.fuel = turtle.getFuelLevel() - - modem.transmit(CHANNEL_SEND, CHANNEL_RECEIVE, { return state.fuel - - type = "eval_response",end - - uuid = uuid, - - result = returnVal,local function tryRefuel() - - error = nil, for slot = 1, 16 do - - turtleID = os.getComputerID() turtle.select(slot) - - }) if turtle.refuel(0) then - - else local count = turtle.getItemCount() - - modem.transmit(CHANNEL_SEND, CHANNEL_RECEIVE, { if count > 0 then - - type = "eval_response", turtle.refuel(1) - - uuid = uuid, return true - - result = nil, end - - error = "Runtime error: " .. tostring(results[2]), end - - turtleID = os.getComputerID() end - - }) return false - - endend +-- ========== Fuel & Inventory ========== +local function updateFuel() + state.fuel = turtle.getFuelLevel() + return state.fuel end local function updateInventory() - --- ========== Message Processing ========== state.inventory = {} - + state.inventory = {} for slot = 1, 16 do - -local function processMessage(channel, message) local item = turtle.getItemDetail(slot) - - if type(message) ~= "table" then return end if item then - - local myID = os.getComputerID() table.insert(state.inventory, { - - if message.target and message.target ~= myID then return end slot = slot, - + local item = turtle.getItemDetail(slot) + if item then + table.insert(state.inventory, { + slot = slot, name = item.name, - - if message.type == "eval" and message.uuid and message.code then count = item.count - - print("Eval: " .. message.uuid:sub(1, 8) .. "...") }) - - executeEval(message.uuid, message.code) end - - end - - elseif message.type == "home_position" and message.turtleID == myID thenend - - if message.homePosition then - - state.homePosition = message.homePositionlocal function inventoryFull() - - print("Home synced from server") for slot = 1, 16 do - - end if turtle.getItemCount(slot) == 0 then - - return false - - elseif message.type == "home_set_confirm" and message.turtleID == myID then end - - if message.homePosition then end - - state.homePosition = message.homePosition return true - - print("Home confirmed by server")end - - end - --- ========== Block Scanning ========== - - elseif message.type == "rename" and message.name then - - os.setComputerLabel(message.name)local function scanAllDirections() - - print("Renamed to: " .. message.name) if not state.position then return {} end - - broadcastStatus() - - end local scannedBlocks = {} - -end local myID = os.getComputerID() - - - --- ========== Sync Home ========== local function addBlock(relX, relY, relZ, blockData) - - if blockData and blockData.name then - -local function syncHomeWithServer() table.insert(scannedBlocks, { - - modem.transmit(CHANNEL_SEND, CHANNEL_RECEIVE, { x = state.position.x + relX, - - type = "request_home", y = state.position.y + relY, - - turtleID = os.getComputerID() z = state.position.z + relZ, - - }) name = blockData.name, - - return true metadata = blockData.metadata or 0, - -end discoveredBy = myID - + count = item.count }) - --- ========== Initialization ========== end - + end end - -print("Initializing...") - -local x, y, z = gps.locate(5) local hasBlock, data - -if x then hasBlock, data = turtle.inspectUp() - - state.position = {x = math.floor(x), y = math.floor(y), z = math.floor(z)} if hasBlock then addBlock(0, 1, 0, data) end - - print("GPS: OK - " .. state.position.x .. "," .. state.position.y .. "," .. state.position.z) - -else hasBlock, data = turtle.inspectDown() - - print("GPS: Not available") if hasBlock then addBlock(0, -1, 0, data) end - - state.position = nil - -end local originalFacing = state.facing - - for i = 0, 3 do - -syncHomeWithServer() hasBlock, data = turtle.inspect() - -updateFuel() if hasBlock then - -print("Ready! Turtle " .. os.getComputerID() .. " online (v5 server-driven)") local relX, relZ = 0, 0 - -broadcastStatus() if state.facing == 0 then relZ = -1 - - elseif state.facing == 1 then relX = 1 - --- ========== Main Loop ========== elseif state.facing == 2 then relZ = 1 - - elseif state.facing == 3 then relX = -1 - -parallel.waitForAny( end - - function() addBlock(relX, 0, relZ, data) - - -- GPS retry loop end - - while true do if i < 3 then smartTurnRight() end - - if not state.position then end - - sleep(10) - - if updatePosition() then if state.facing ~= originalFacing then - - print("GPS acquired!") smartTurnRight() - - broadcastStatus() end - - end - - else return scannedBlocks - - sleep(30)end - - end - - endlocal function reportDiscoveredBlocks(blocks) - - end, if #blocks == 0 then return end - - modem.transmit(CHANNEL_SEND, CHANNEL_RECEIVE, { - - function() type = "blocks_discovered", - - -- Status broadcast loop turtleID = os.getComputerID(), - - while true do blocks = blocks, - - sleep(config.statusUpdateInterval) timestamp = os.epoch("utc") - - broadcastStatus() }) - - endend - - end, +end -- ========== Status Broadcasting ========== - function() +local function broadcastStatus() + updateFuel() + updateInventory() - -- Command processing (eval protocol)local function broadcastStatus() - - while true do updateFuel() - - local event, side, channel, replyChannel, message = os.pullEvent("modem_message") updateInventory() - - if channel == CHANNEL_RECEIVE then - - processMessage(channel, message) local surroundings = {} - - end local hasBlock, data - - end - - end, hasBlock, data = turtle.inspect() + local surroundings = {} + local hasBlock, data + hasBlock, data = turtle.inspect() if hasBlock then surroundings.forward = {name = data.name, metadata = data.metadata or 0} end - function() + hasBlock, data = turtle.inspectUp() + if hasBlock then surroundings.up = {name = data.name, metadata = data.metadata or 0} end - -- Inventory change events (real-time) hasBlock, data = turtle.inspectUp() - - while true do if hasBlock then surroundings.up = {name = data.name, metadata = data.metadata or 0} end - - os.pullEvent("turtle_inventory") - - local inventory = {} hasBlock, data = turtle.inspectDown() - - for i = 1, 16 do if hasBlock then surroundings.down = {name = data.name, metadata = data.metadata or 0} end - - local item = turtle.getItemDetail(i) - - if item then local statusPacket = { - - table.insert(inventory, { type = "status", - - slot = i, turtleID = os.getComputerID(), - - name = item.name, mode = state.mode, - - count = item.count position = state.position, - - }) homePosition = state.homePosition, - - end fuel = state.fuel, - - end inventoryCount = #state.inventory, + hasBlock, data = turtle.inspectDown() + if hasBlock then surroundings.down = {name = data.name, metadata = data.metadata or 0} end + local statusPacket = { + type = "status", + turtleID = os.getComputerID(), + position = state.position, + homePosition = state.homePosition, + fuel = state.fuel, + inventoryCount = #state.inventory, inventory = state.inventory, + facing = state.facing, + surroundings = surroundings, + evalSupported = true, + label = os.getComputerLabel(), + } - modem.transmit(CHANNEL_SEND, CHANNEL_RECEIVE, { facing = state.facing, + modem.transmit(STATUS_CHANNEL, CHANNEL_RECEIVE, statusPacket) +end - type = "inventory_update", surroundings = surroundings, - - turtleID = os.getComputerID(), evalSupported = true, - - inventory = inventory, label = os.getComputerLabel(), - - timestamp = os.epoch("utc") } - - }) - - end modem.transmit(STATUS_CHANNEL, CHANNEL_RECEIVE, statusPacket) - - end,end - - - - function()-- ========== Eval/Response Protocol ========== - - -- Peripheral attached events (real-time) - - while true dolocal function executeEval(uuid, code) - - os.pullEvent("peripheral") local fn, compileError = load(code, "eval", "t") - - sleep(0.1) if not fn then - - local peripherals = {} modem.transmit(CHANNEL_SEND, CHANNEL_RECEIVE, { - - local names = peripheral.getNames() type = "eval_response", - - for _, name in ipairs(names) do uuid = uuid, - - peripherals[name] = {types = {peripheral.getType(name)}} result = nil, - - end error = "Compile error: " .. tostring(compileError), +-- ========== Eval/Response Protocol ========== +local function executeEval(uuid, code) + local fn, compileError = load(code, "eval", "t") + if not fn then + modem.transmit(CHANNEL_SEND, CHANNEL_RECEIVE, { + type = "eval_response", + uuid = uuid, + result = nil, + error = "Compile error: " .. tostring(compileError), turtleID = os.getComputerID() + }) + return + end - modem.transmit(CHANNEL_SEND, CHANNEL_RECEIVE, { }) - - type = "peripheral_attached", return - - turtleID = os.getComputerID(), end - - peripherals = peripherals, - - timestamp = os.epoch("utc") local results = table.pack(pcall(fn)) - - }) local ok = results[1] - - end - - end, if ok then + local results = table.pack(pcall(fn)) + local ok = results[1] + if ok then local returnVal - - function() if results.n <= 2 then - - -- Peripheral detached events (real-time) -- Single return value - - while true do returnVal = results[2] - - local _, side = os.pullEvent("peripheral_detach") else - - if not peripheral.isPresent(side) then -- Multiple return values - pack into array - - modem.transmit(CHANNEL_SEND, CHANNEL_RECEIVE, { returnVal = {} - - type = "peripheral_detached", for i = 2, results.n do - - turtleID = os.getComputerID(), returnVal[i - 1] = results[i] - - side = side, end - - timestamp = os.epoch("utc") end - - }) modem.transmit(CHANNEL_SEND, CHANNEL_RECEIVE, { - - end type = "eval_response", - - end uuid = uuid, - - end result = returnVal, - -) error = nil, - + if results.n <= 2 then + returnVal = results[2] + else + returnVal = {} + for i = 2, results.n do + returnVal[i - 1] = results[i] + end + end + modem.transmit(CHANNEL_SEND, CHANNEL_RECEIVE, { + type = "eval_response", + uuid = uuid, + result = returnVal, + error = nil, turtleID = os.getComputerID() }) else @@ -617,286 +149,36 @@ parallel.waitForAny( end end end --- ========== Legacy Command Handling ========== - -local legacyCommands = { - forward = function() return smartForward(), "Moved forward" end, - back = function() return smartBack(), "Moved back" end, - up = function() return smartUp(), "Moved up" end, - down = function() return smartDown(), "Moved down" end, - turnLeft = function() return smartTurnLeft(), "Turned left" end, - turnRight = function() return smartTurnRight(), "Turned right" end, - dig = function() - local hasBlock, data = turtle.inspect() - if hasBlock then - turtle.dig() - return true, "Dug: " .. (data.name or "block") - end - return false, "Nothing to dig" - end, - digUp = function() - local hasBlock, data = turtle.inspectUp() - if hasBlock then - turtle.digUp() - return true, "Dug up: " .. (data.name or "block") - end - return false, "Nothing above" - end, - digDown = function() - local hasBlock, data = turtle.inspectDown() - if hasBlock then - turtle.digDown() - return true, "Dug down: " .. (data.name or "block") - end - return false, "Nothing below" - end, - place = function() return turtle.place(), "Placed" end, - select = function(slot) return turtle.select(slot), "Selected slot " .. slot end, - refuel = function() - local success = tryRefuel() - updateFuel() - broadcastStatus() - return success, success and ("Refueled! Now: " .. state.fuel) or "No fuel" - end, - status = function() - broadcastStatus() - return true, "Status sent" - end, - setHome = function() - if not state.position then - if not updatePosition() then - return false, "No GPS" - end - end - state.homePosition = { - x = state.position.x, - y = state.position.y, - z = state.position.z - } - modem.transmit(CHANNEL_SEND, CHANNEL_RECEIVE, { - type = "set_home", - turtleID = os.getComputerID(), - position = state.homePosition - }) - return true, "Home set" - end, - explore = function() - if not state.homePosition then - if state.position then - state.homePosition = { - x = state.position.x, - y = state.position.y, - z = state.position.z - } - modem.transmit(CHANNEL_SEND, CHANNEL_RECEIVE, { - type = "set_home", - turtleID = os.getComputerID(), - position = state.homePosition - }) - else - return false, "No home or GPS" - end - end - state.mode = "exploring" - broadcastStatus() - return true, "Exploring" - end, - mine = function() - if not state.homePosition then - if state.position then - state.homePosition = { - x = state.position.x, - y = state.position.y, - z = state.position.z - } - modem.transmit(CHANNEL_SEND, CHANNEL_RECEIVE, { - type = "set_home", - turtleID = os.getComputerID(), - position = state.homePosition - }) - else - return false, "No home or GPS" - end - end - state.mode = "mining" - broadcastStatus() - return true, "Mining" - end, - returnHome = function() - state.mode = "returning" - broadcastStatus() - return true, "Returning home" - end, - stop = function() - state.mode = "idle" - broadcastStatus() - return true, "Stopped" - end, - manual = function() - state.mode = "manual" - broadcastStatus() - return true, "Manual control" - end, -} - -local function processLegacyCommand(message) - if type(message) ~= "table" then return end - local myID = os.getComputerID() - if message.target and message.target ~= myID then return end - - if message.command then - local handler = legacyCommands[message.command] - if handler then - local success, result = handler(message.param) - modem.transmit(CHANNEL_SEND, CHANNEL_RECEIVE, { - status = success and "ok" or "error", - message = result or "", - turtleID = myID - }) - broadcastStatus() - end - end -end - -- ========== Message Processing ========== local function processMessage(channel, message) if type(message) ~= "table" then return end local myID = os.getComputerID() if message.target and message.target ~= myID then return end - + if message.type == "eval" and message.uuid and message.code then print("Eval: " .. message.uuid:sub(1, 8) .. "...") executeEval(message.uuid, message.code) - if message.stateUpdate then - state.mode = message.stateUpdate - end - - elseif message.type == "state_change" and message.state then - state.mode = message.state - broadcastStatus() - + elseif message.type == "home_position" and message.turtleID == myID then if message.homePosition then state.homePosition = message.homePosition print("Home synced from server") end - + elseif message.type == "home_set_confirm" and message.turtleID == myID then if message.homePosition then state.homePosition = message.homePosition print("Home confirmed by server") end - + elseif message.type == "rename" and message.name then os.setComputerLabel(message.name) print("Renamed to: " .. message.name) broadcastStatus() - - elseif message.command then - processLegacyCommand(message) end end --- ========== Local Autonomous Behavior (fallback) ========== - -local localStuckCounter = 0 - -local function getDistance(pos1, pos2) - return math.abs(pos1.x - pos2.x) + math.abs(pos1.y - pos2.y) + math.abs(pos1.z - pos2.z) -end - -local function localExploreStep() - if state.position then - local blocks = scanAllDirections() - if #blocks > 0 then - reportDiscoveredBlocks(blocks) - end - end - - -- Mine valuable ores - for _, direction in ipairs({"forward", "up", "down"}) do - local inspectFn = direction == "forward" and turtle.inspect - or direction == "up" and turtle.inspectUp - or turtle.inspectDown - local digFn = direction == "forward" and turtle.dig - or direction == "up" and turtle.digUp - or turtle.digDown - - local hasBlock, data = inspectFn() - if hasBlock and config.valuableBlocks[data.name] then - digFn() - end - end - - local r = math.random(1, 100) - if r < 75 then - local hasBlock = turtle.inspect() - if hasBlock then turtle.dig() end - if not smartForward() then - smartTurnRight() - localStuckCounter = localStuckCounter + 1 - else - localStuckCounter = 0 - end - elseif r < 90 and state.position and state.position.y > 15 then - local hasBlock = turtle.inspectDown() - if hasBlock then turtle.digDown() end - smartDown() - else - local hasBlock = turtle.inspectUp() - if hasBlock then turtle.digUp() end - smartUp() - end - - if localStuckCounter > 5 then - turtle.digUp() - smartUp() - localStuckCounter = 0 - end -end - -local function localReturnHomeStep() - if not state.homePosition or not state.position then - state.mode = "idle" - return true - end - - if getDistance(state.position, state.homePosition) <= 1 then - state.mode = "idle" - broadcastStatus() - return true - end - - local dx = state.homePosition.x - state.position.x - local dy = state.homePosition.y - state.position.y - local dz = state.homePosition.z - state.position.z - - if math.abs(dy) > 3 then - if dy > 0 then - turtle.digUp(); smartUp() - else - turtle.digDown(); smartDown() - end - else - local targetFacing - if math.abs(dx) > math.abs(dz) then - targetFacing = dx > 0 and 1 or 3 - else - targetFacing = dz > 0 and 2 or 0 - end - while state.facing ~= targetFacing do - smartTurnRight() - end - turtle.dig() - if not smartForward() then - smartTurnRight() - end - end - - return false -end - -- ========== Sync Home ========== local function syncHomeWithServer() @@ -921,14 +203,14 @@ end syncHomeWithServer() updateFuel() -print("Ready! Turtle " .. os.getComputerID() .. " online (v4 eval protocol)") +print("Ready! Turtle " .. os.getComputerID() .. " online (v5 server-driven)") broadcastStatus() -- ========== Main Loop ========== parallel.waitForAny( function() - -- GPS retry + -- GPS retry loop while true do if not state.position then sleep(10) @@ -941,17 +223,17 @@ parallel.waitForAny( end end end, - + function() - -- Status broadcast + -- Status broadcast loop while true do sleep(config.statusUpdateInterval) broadcastStatus() end end, - + function() - -- Command processing + -- Command processing (eval protocol) while true do local event, side, channel, replyChannel, message = os.pullEvent("modem_message") if channel == CHANNEL_RECEIVE then @@ -959,7 +241,7 @@ parallel.waitForAny( end end end, - + function() -- Inventory change events (real-time) while true do @@ -975,7 +257,7 @@ parallel.waitForAny( }) end end - + modem.transmit(CHANNEL_SEND, CHANNEL_RECEIVE, { type = "inventory_update", turtleID = os.getComputerID(), @@ -984,7 +266,7 @@ parallel.waitForAny( }) end end, - + function() -- Peripheral attached events (real-time) while true do @@ -995,7 +277,7 @@ parallel.waitForAny( for _, name in ipairs(names) do peripherals[name] = {types = {peripheral.getType(name)}} end - + modem.transmit(CHANNEL_SEND, CHANNEL_RECEIVE, { type = "peripheral_attached", turtleID = os.getComputerID(), @@ -1004,7 +286,7 @@ parallel.waitForAny( }) end end, - + function() -- Peripheral detached events (real-time) while true do @@ -1018,43 +300,5 @@ parallel.waitForAny( }) end end - end, - - function() - -- Local autonomous fallback - while true do - if state.mode == "exploring" or state.mode == "mining" then - updateFuel() - - if state.position and state.homePosition then - local dist = getDistance(state.position, state.homePosition) - if dist > 200 then - state.mode = "returning" - broadcastStatus() - elseif state.fuel ~= "unlimited" and state.fuel < 500 then - if not tryRefuel() then - state.mode = "returning" - broadcastStatus() - end - elseif inventoryFull() then - state.mode = "returning" - broadcastStatus() - else - localExploreStep() - sleep(0.2) - end - else - localExploreStep() - sleep(0.2) - end - - elseif state.mode == "returning" then - local done = localReturnHomeStep() - if not done then sleep(0.1) end - - else - sleep(0.5) - end - end end )