From ff73f3ec5e2b280c1979d395f234fdabac664f77 Mon Sep 17 00:00:00 2001 From: MayaTheShy Date: Sun, 15 Feb 2026 23:29:41 -0500 Subject: [PATCH] inital commit --- pocketremote.lua | 488 +++++++++++++++++++++++++++++++++++++ turtle.lua | 611 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 1099 insertions(+) create mode 100644 pocketremote.lua create mode 100644 turtle.lua diff --git a/pocketremote.lua b/pocketremote.lua new file mode 100644 index 0000000..f1aadfb --- /dev/null +++ b/pocketremote.lua @@ -0,0 +1,488 @@ +-- Touch-Enabled Command Center for Pocket Computer (FIXED) +-- Monitor and control autonomous mining turtles + +local CHANNEL_SEND = 100 +local CHANNEL_RECEIVE = 101 +local STATUS_CHANNEL = 102 + +local modem = peripheral.find("modem") +if not modem then + error("No wireless modem found!") +end + +if pocket then + pocket.equipBack() + modem = peripheral.find("modem") +end + +modem.open(CHANNEL_RECEIVE) +modem.open(STATUS_CHANNEL) + +local w, h = term.getSize() + +-- Tracked turtles +local turtles = {} +local selectedTurtle = nil +local viewMode = "overview" -- overview, detail, manual + +-- Button system +local buttons = {} + +local function clearButtons() + buttons = {} +end + +local function addButton(x, y, width, height, label, action, color) + table.insert(buttons, { + x = x, + y = y, + width = width, + height = height, + label = label, + action = action, + color = color or colors.gray + }) +end + +local function drawButton(btn, highlight) + term.setCursorPos(btn.x, btn.y) + + if highlight then + term.setBackgroundColor(colors.white) + term.setTextColor(colors.black) + else + term.setBackgroundColor(btn.color) + term.setTextColor(colors.white) + end + + local text = btn.label + local padding = math.floor((btn.width - #text) / 2) + + for dy = 0, btn.height - 1 do + term.setCursorPos(btn.x, btn.y + dy) + if dy == math.floor(btn.height / 2) then + term.write(string.rep(" ", padding) .. text .. string.rep(" ", btn.width - padding - #text)) + else + term.write(string.rep(" ", btn.width)) + end + end + + term.setBackgroundColor(colors.black) + term.setTextColor(colors.white) +end + +local function checkButton(x, y) + for _, btn in ipairs(buttons) do + if x >= btn.x and x < btn.x + btn.width and + y >= btn.y and y < btn.y + btn.height then + return btn + end + end + return nil +end + +-- Send command to turtle +local function sendCommand(turtleID, command, param) + modem.transmit(CHANNEL_SEND, CHANNEL_RECEIVE, { + command = command, + param = param, + target = turtleID + }) +end + +-- Helper function to format fuel display +local function formatFuel(fuel) + if not fuel then + return "?" + elseif fuel == "unlimited" then + return "INF" + else + return tostring(fuel) + end +end + +-- Draw UI modes +local function drawOverview() + clearButtons() + term.setBackgroundColor(colors.black) + term.clear() + term.setCursorPos(1, 1) + term.setTextColor(colors.yellow) + print("=MINING CMD CENTER=") + term.setTextColor(colors.white) + + local startY = 3 + + if #turtles == 0 then + term.setCursorPos(1, startY) + print("No turtles online") + print("Waiting...") + else + for i, turtle in ipairs(turtles) do + if i > 3 then break end -- Max 3 turtles on screen + + local y = startY + (i - 1) * 4 + local selected = (selectedTurtle == i) + + -- Turtle info box + term.setCursorPos(1, y) + term.setTextColor(selected and colors.lime or colors.white) + print(string.format("T-%d [%s]", turtle.turtleID or 0, turtle.mode or "unknown")) + + if turtle.position then + print(string.format(" %d,%d,%d", + turtle.position.x or 0, + turtle.position.y or 0, + turtle.position.z or 0)) + else + print(" No GPS") + end + + print(string.format(" F:%s I:%d", + formatFuel(turtle.fuel), + turtle.inventoryCount or 0)) + + -- Select button + addButton(20, y, 6, 2, "SEL", function() + selectedTurtle = i + viewMode = "detail" + end, selected and colors.lime or colors.blue) + + drawButton(buttons[#buttons]) + end + end + + -- Bottom buttons + local btnY = h - 3 + addButton(1, btnY, 8, 2, "EXPLORE", function() + if selectedTurtle and turtles[selectedTurtle] then + sendCommand(turtles[selectedTurtle].turtleID, "explore") + end + end, colors.green) + + addButton(10, btnY, 8, 2, "HOME", function() + if selectedTurtle and turtles[selectedTurtle] then + sendCommand(turtles[selectedTurtle].turtleID, "returnHome") + end + end, colors.orange) + + addButton(19, btnY, 7, 2, "STOP", function() + if selectedTurtle and turtles[selectedTurtle] then + sendCommand(turtles[selectedTurtle].turtleID, "stop") + end + end, colors.red) + + for _, btn in ipairs(buttons) do + drawButton(btn) + end + + term.setTextColor(colors.white) +end + +local function drawDetail() + if not selectedTurtle or not turtles[selectedTurtle] then + viewMode = "overview" + drawOverview() + return + end + + clearButtons() + local turtle = turtles[selectedTurtle] + + term.setBackgroundColor(colors.black) + term.clear() + term.setCursorPos(1, 1) + term.setTextColor(colors.yellow) + print("=TURTLE " .. (turtle.turtleID or "?") .. "=") + term.setTextColor(colors.white) + + print("") + print("Mode: " .. (turtle.mode or "unknown")) + print("Fuel: " .. formatFuel(turtle.fuel)) + + if turtle.position then + print(string.format("Pos: %d,%d,%d", + turtle.position.x or 0, + turtle.position.y or 0, + turtle.position.z or 0)) + else + print("Pos: No GPS") + end + + if turtle.homePosition and turtle.position then + local dist = math.abs((turtle.position.x or 0) - (turtle.homePosition.x or 0)) + + math.abs((turtle.position.y or 0) - (turtle.homePosition.y or 0)) + + math.abs((turtle.position.z or 0) - (turtle.homePosition.z or 0)) + print("Home: " .. dist .. " blocks") + elseif turtle.homePosition then + print("Home: Set") + else + print("Home: Not set") + end + + print("") + print("Inventory:") + if turtle.inventory and #turtle.inventory > 0 then + for i, item in ipairs(turtle.inventory) do + if i <= 4 then + local name = item.name:match("minecraft:(.+)") or item.name + if #name > 18 then name = name:sub(1, 15) .. "..." end + print(string.format("%d:%s x%d", item.slot or 0, name, item.count or 0)) + end + end + else + print(" Empty") + end + + -- Action buttons + local btnY = h - 7 + addButton(1, btnY, 8, 2, "EXPLORE", function() + sendCommand(turtle.turtleID, "explore") + end, colors.green) + + addButton(10, btnY, 8, 2, "HOME", function() + sendCommand(turtle.turtleID, "returnHome") + end, colors.orange) + + addButton(19, btnY, 7, 2, "STOP", function() + sendCommand(turtle.turtleID, "stop") + end, colors.red) + + btnY = h - 4 + addButton(1, btnY, 12, 2, "MANUAL", function() + viewMode = "manual" + sendCommand(turtle.turtleID, "manual") + end, colors.purple) + + addButton(14, btnY, 12, 2, "SET HOME", function() + sendCommand(turtle.turtleID, "setHome") + end, colors.blue) + + addButton(1, h - 1, 12, 2, "< BACK", function() + viewMode = "overview" + end, colors.gray) + + for _, btn in ipairs(buttons) do + drawButton(btn) + end + + term.setTextColor(colors.white) +end + +local function drawManual() + if not selectedTurtle or not turtles[selectedTurtle] then + viewMode = "overview" + return + end + + clearButtons() + local turtle = turtles[selectedTurtle] + + term.setBackgroundColor(colors.black) + term.clear() + term.setCursorPos(1, 1) + term.setTextColor(colors.red) + print("=MANUAL CONTROL=") + term.setTextColor(colors.white) + + print(string.format("T-%d Fuel:%s", + turtle.turtleID or 0, + formatFuel(turtle.fuel))) + + -- Movement buttons + local centerX = 6 + local centerY = 5 + + -- Forward + addButton(centerX, centerY, 3, 2, "W", function() + sendCommand(turtle.turtleID, "forward") + end, colors.blue) + + -- Left + addButton(centerX - 4, centerY + 2, 3, 2, "A", function() + sendCommand(turtle.turtleID, "turnLeft") + end, colors.blue) + + -- Back + addButton(centerX, centerY + 2, 3, 2, "S", function() + sendCommand(turtle.turtleID, "back") + end, colors.blue) + + -- Right + addButton(centerX + 4, centerY + 2, 3, 2, "D", function() + sendCommand(turtle.turtleID, "turnRight") + end, colors.blue) + + -- Up/Down + addButton(centerX + 9, centerY, 4, 2, "UP", function() + sendCommand(turtle.turtleID, "up") + end, colors.cyan) + + addButton(centerX + 9, centerY + 2, 4, 2, "DN", function() + sendCommand(turtle.turtleID, "down") + end, colors.cyan) + + -- Action buttons + local actY = centerY + 5 + addButton(1, actY, 6, 2, "DIG", function() + sendCommand(turtle.turtleID, "dig") + end, colors.orange) + + addButton(8, actY, 6, 2, "PLACE", function() + sendCommand(turtle.turtleID, "place") + end, colors.green) + + addButton(15, actY, 6, 2, "DIGUP", function() + sendCommand(turtle.turtleID, "digUp") + end, colors.orange) + + addButton(22, actY, 5, 2, "DIGD", function() + sendCommand(turtle.turtleID, "digDown") + end, colors.orange) + + -- Bottom buttons + addButton(1, h - 3, 8, 2, "HOME", function() + sendCommand(turtle.turtleID, "returnHome") + end, colors.orange) + + addButton(10, h - 3, 8, 2, "REFUEL", function() + sendCommand(turtle.turtleID, "refuel") + end, colors.lime) + + addButton(19, h - 3, 7, 2, "INFO", function() + sendCommand(turtle.turtleID, "status") + end, colors.lightBlue) + + addButton(1, h, 12, 1, "< BACK", function() + viewMode = "detail" + end, colors.gray) + + addButton(14, h, 13, 1, "AUTO MODE", function() + sendCommand(turtle.turtleID, "explore") + viewMode = "detail" + end, colors.purple) + + for _, btn in ipairs(buttons) do + drawButton(btn) + end + + term.setTextColor(colors.white) +end + +local function draw() + if viewMode == "overview" then + drawOverview() + elseif viewMode == "detail" then + drawDetail() + elseif viewMode == "manual" then + drawManual() + end +end + +-- Handle keyboard input (still works alongside touch) +local function handleKey(key) + if viewMode == "manual" then + local turtle = turtles[selectedTurtle] + if not turtle then return end + + local cmd = nil + if key == keys.w then cmd = "forward" + elseif key == keys.s then cmd = "back" + elseif key == keys.a then cmd = "turnLeft" + elseif key == keys.d then cmd = "turnRight" + elseif key == keys.space then cmd = "up" + elseif key == keys.leftShift or key == keys.rightShift then cmd = "down" + elseif key == keys.e then cmd = "dig" + elseif key == keys.q then cmd = "place" + end + + if cmd then + sendCommand(turtle.turtleID, cmd) + end + elseif viewMode == "overview" then + if key >= keys.one and key <= keys.nine then + local index = key - keys.one + 1 + if turtles[index] then + selectedTurtle = index + viewMode = "detail" + draw() + end + end + end +end + +-- Handle touch +local function handleTouch(x, y) + local btn = checkButton(x, y) + if btn and btn.action then + -- Visual feedback + drawButton(btn, true) + sleep(0.1) + drawButton(btn, false) + + -- Execute action + btn.action() + draw() + end +end + +-- Main loop +print("Initializing...") +sleep(0.5) +draw() + +parallel.waitForAny( + function() + -- Touch/click handler + while true do + local event, p1, p2, p3 = os.pullEvent() + if event == "mouse_click" or event == "monitor_touch" then + handleTouch(p2, p3) + end + end + end, + function() + -- Keyboard handler + while true do + local event, key = os.pullEvent("key") + handleKey(key) + end + end, + function() + -- Status receiver + while true do + local event, side, channel, replyChannel, message = os.pullEvent("modem_message") + + if channel == STATUS_CHANNEL and type(message) == "table" and message.type == "status" then + -- Update or add turtle + local found = false + for i, t in ipairs(turtles) do + if t.turtleID == message.turtleID then + turtles[i] = message + found = true + break + end + end + + if not found then + table.insert(turtles, message) + if not selectedTurtle then + selectedTurtle = 1 + end + end + + draw() + elseif channel == CHANNEL_RECEIVE and type(message) == "table" and message.status then + -- Response from turtle + draw() + end + end + end, + function() + -- Refresh display + while true do + sleep(2) + draw() + end + end +) diff --git a/turtle.lua b/turtle.lua new file mode 100644 index 0000000..a8b8284 --- /dev/null +++ b/turtle.lua @@ -0,0 +1,611 @@ +-- Advanced Autonomous Mining Turtle (FIXED v3) +-- Features: GPS tracking, auto-mining, fuel management, smart navigation + +local CHANNEL_RECEIVE = 100 +local CHANNEL_SEND = 101 +local STATUS_CHANNEL = 102 + +-- State management +local state = { + mode = "idle", -- idle, manual, exploring, mining, returning + position = nil, + homePosition = nil, + fuel = 0, + inventory = {}, + target = nil, + path = {}, + lastStatusUpdate = 0, + stuckCounter = 0 +} + +-- Configuration +local config = { + minFuelToReturn = 500, + minFuelToExplore = 1000, + statusUpdateInterval = 5, -- seconds + maxStuckAttempts = 3, + valuableBlocks = { + ["minecraft:coal_ore"] = 1, + ["minecraft:iron_ore"] = 2, + ["minecraft:gold_ore"] = 3, + ["minecraft:diamond_ore"] = 5, + ["minecraft:emerald_ore"] = 5, + ["minecraft:redstone_ore"] = 2, + ["minecraft:lapis_ore"] = 2, + ["minecraft:deepslate_coal_ore"] = 1, + ["minecraft:deepslate_iron_ore"] = 2, + ["minecraft:deepslate_gold_ore"] = 3, + ["minecraft:deepslate_diamond_ore"] = 5, + ["minecraft:deepslate_emerald_ore"] = 5, + ["minecraft:deepslate_redstone_ore"] = 2, + ["minecraft:deepslate_lapis_ore"] = 2, + } +} + +-- Check for modem +local modem = peripheral.find("modem") +if not modem then + error("No wireless modem found!") +end +modem.open(CHANNEL_RECEIVE) + +print("Advanced Mining Turtle System") +print("ID: " .. os.getComputerID()) + +-- GPS Functions +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 + return false +end + +local function setHome() + if updatePosition() then + state.homePosition = { + x = state.position.x, + y = state.position.y, + z = state.position.z + } + print("Home set at: " .. state.homePosition.x .. ", " .. state.homePosition.y .. ", " .. state.homePosition.z) + return true + end + print("Failed to get GPS position for home") + return false +end + +-- Movement tracking +local facing = 0 -- 0=North(Z-), 1=East(X+), 2=South(Z+), 3=West(X-) + +local function updateFacingAfterTurn(right) + if right then + facing = (facing + 1) % 4 + else + facing = (facing - 1) % 4 + end +end + +local function smartForward() + local success = turtle.forward() + if success and state.position then + if facing == 0 then state.position.z = state.position.z - 1 + elseif facing == 1 then state.position.x = state.position.x + 1 + elseif facing == 2 then state.position.z = state.position.z + 1 + elseif facing == 3 then state.position.x = state.position.x - 1 + end + end + return success +end + +local function smartBack() + local success = turtle.back() + if success and state.position then + if facing == 0 then state.position.z = state.position.z + 1 + elseif facing == 1 then state.position.x = state.position.x - 1 + elseif facing == 2 then state.position.z = state.position.z - 1 + elseif facing == 3 then state.position.x = state.position.x + 1 + end + end + return success +end + +local function smartUp() + local success = turtle.up() + if success and state.position then + state.position.y = state.position.y + 1 + end + return success +end + +local function smartDown() + local success = turtle.down() + if success and state.position then + state.position.y = state.position.y - 1 + end + return success +end + +local function smartTurnRight() + local success = turtle.turnRight() + if success then + updateFacingAfterTurn(true) + end + return success +end + +local function smartTurnLeft() + local success = turtle.turnLeft() + if success then + updateFacingAfterTurn(false) + end + return success +end + +-- Fuel management +local function updateFuel() + state.fuel = turtle.getFuelLevel() + return state.fuel +end + +local function needsRefuel() + return state.fuel ~= "unlimited" and state.fuel < config.minFuelToReturn +end + +local function tryRefuel() + for slot = 1, 16 do + turtle.select(slot) + if turtle.refuel(0) then -- Check if it's fuel + local count = turtle.getItemCount() + if count > 0 then + turtle.refuel(1) + return true + end + end + end + return false +end + +-- Inventory management +local function updateInventory() + state.inventory = {} + for slot = 1, 16 do + local item = turtle.getItemDetail(slot) + if item then + table.insert(state.inventory, { + slot = slot, + name = item.name, + count = item.count + }) + end + end +end + +local function inventoryFull() + for slot = 1, 16 do + if turtle.getItemCount(slot) == 0 then + return false + end + end + return true +end + +local function isValuableBlock(blockName) + return config.valuableBlocks[blockName] ~= nil +end + +-- Check if block is unbreakable +local function isUnbreakable(blockName) + if not blockName then return false end + return string.find(blockName, "bedrock") or string.find(blockName, "barrier") +end + +-- Mining functions +local function smartDig(direction) + direction = direction or "forward" + + local digFunc, inspectFunc + if direction == "forward" then + digFunc = turtle.dig + inspectFunc = turtle.inspect + elseif direction == "up" then + digFunc = turtle.digUp + inspectFunc = turtle.inspectUp + elseif direction == "down" then + digFunc = turtle.digDown + inspectFunc = turtle.inspectDown + end + + local hasBlock, data = inspectFunc() + if hasBlock then + if isUnbreakable(data.name) then + return false, false, data.name + end + local valuable = isValuableBlock(data.name) + digFunc() + return true, valuable, data.name + end + return false, false, nil +end + +-- Pathfinding (improved with obstacle handling) +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 + +-- Try to dig and move forward +local function forceForward() + for i = 1, 5 do + if smartForward() then + return true + end + smartDig("forward") + sleep(0.3) + end + return false +end + +-- Try to dig and move up +local function forceUp() + for i = 1, 5 do + if smartUp() then + return true + end + smartDig("up") + sleep(0.3) + end + return false +end + +-- Try to dig and move down +local function forceDown() + for i = 1, 5 do + if smartDown() then + return true + end + smartDig("down") + sleep(0.3) + end + return false +end + +-- Advanced navigation with unstuck logic +local function navigateTowards(target) + if not state.position or not target then + return false + end + + local dx = target.x - state.position.x + local dy = target.y - state.position.y + local dz = target.z - state.position.z + + local lastPos = {x = state.position.x, y = state.position.y, z = state.position.z} + + -- Prioritize vertical movement if needed + if math.abs(dy) > 3 then + if dy > 0 then + if forceUp() then + state.stuckCounter = 0 + return false + end + else + if forceDown() then + state.stuckCounter = 0 + return false + end + end + end + + -- Horizontal movement + 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 + + -- Face the right direction + while facing ~= targetFacing do + smartTurnRight() + end + + -- Try to move forward + if forceForward() then + state.stuckCounter = 0 + else + -- Stuck! Try alternative routes + state.stuckCounter = state.stuckCounter + 1 + print("Stuck counter: " .. state.stuckCounter) + + if state.stuckCounter > config.maxStuckAttempts then + print("Trying alternative path...") + state.stuckCounter = 0 + + -- Try going up to go over obstacle + if forceUp() then + return false + end + + -- Try going around + smartTurnRight() + if forceForward() then + return false + end + + smartTurnLeft() + smartTurnLeft() + if forceForward() then + return false + end + + -- Last resort: dig down and try lower path + smartTurnRight() + forceDown() + end + end + + -- Check if we're close enough + return getDistance(state.position, target) < 2 +end + +-- Status broadcasting +function broadcastStatus() + updateFuel() + updateInventory() + updatePosition() + + modem.transmit(STATUS_CHANNEL, CHANNEL_RECEIVE, { + type = "status", + turtleID = os.getComputerID(), + mode = state.mode, + position = state.position, + homePosition = state.homePosition, + fuel = state.fuel, + inventoryCount = #state.inventory, + inventory = state.inventory, + facing = facing + }) +end + +-- Return to home with better navigation +local function returnHome() + print("Returning home...") + state.mode = "returning" + state.stuckCounter = 0 + broadcastStatus() + + local maxAttempts = 1000 + local attempts = 0 + + while state.homePosition and state.position and + getDistance(state.position, state.homePosition) > 1 and + attempts < maxAttempts do + + -- Check for stop command + if state.mode ~= "returning" then + print("Return cancelled") + return + end + + updateFuel() + if needsRefuel() then + print("Low fuel, trying to refuel...") + if tryRefuel() then + print("Refueled!") + else + print("WARNING: Out of fuel!") + state.mode = "idle" + broadcastStatus() + return + end + end + + local arrived = navigateTowards(state.homePosition) + if arrived then + break + end + + attempts = attempts + 1 + + -- Update GPS position every few steps + if attempts % 10 == 0 then + updatePosition() + print("Distance to home: " .. getDistance(state.position, state.homePosition)) + end + + sleep(0.1) + end + + if attempts >= maxAttempts then + print("Could not reach home - gave up after " .. maxAttempts .. " attempts") + else + print("Arrived at home!") + end + + state.mode = "idle" + state.stuckCounter = 0 + broadcastStatus() +end + +-- Exploration algorithm +local function exploreStep() + -- Check all directions for valuable ores + for _, direction in ipairs({"forward", "up", "down"}) do + local dug, valuable, blockName = smartDig(direction) + if valuable then + print("Found: " .. blockName) + broadcastStatus() + end + end + + -- Random exploration with preference for going deeper + local r = math.random(1, 10) + if r <= 3 then + -- Go down 30% of the time + if not smartDown() then + smartDig("down") + smartDown() + end + elseif r <= 5 then + -- Turn + if math.random() > 0.5 then + smartTurnRight() + else + smartTurnLeft() + end + else + -- Move forward + if not smartForward() then + smartDig("forward") + if not smartForward() then + smartTurnRight() + end + end + end +end + +-- Command handling +local commands = { + 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 dug, val, name = smartDig("forward") + return dug, dug and "Dug: " .. (name or "block") or "Nothing to dig" + end, + digUp = function() + local dug, val, name = smartDig("up") + return dug, dug and "Dug up: " .. (name or "block") or "Nothing above" + end, + digDown = function() + local dug, val, name = smartDig("down") + return dug, dug and "Dug down: " .. (name or "block") or "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, + + -- Autonomous commands + setHome = function() return setHome(), "Home set" end, + + explore = function() + print("Explore command received") + state.mode = "exploring" + state.stuckCounter = 0 + broadcastStatus() + return true, "Starting exploration" + end, + + returnHome = function() + print("Return home command received") + state.mode = "returning" + state.stuckCounter = 0 + broadcastStatus() + return true, "Returning home" + end, + + stop = function() + print("STOP command received") + state.mode = "idle" + state.stuckCounter = 0 + broadcastStatus() + return true, "Stopped" + end, + + manual = function() + state.mode = "manual" + broadcastStatus() + return true, "Manual control" + end, +} + +-- Process incoming messages +local function processMessage(message) + if type(message) == "table" and message.command then + print("Command: " .. message.command) + + local handler = commands[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 = os.getComputerID() + }) + + broadcastStatus() + end + end +end + +-- Main loop +print("Initializing...") +updatePosition() +updateFuel() + +if not state.position then + print("WARNING: No GPS signal!") + print("Limited functionality available") +end + +print("Ready! Waiting for commands...") +broadcastStatus() + +-- Main execution loop +parallel.waitForAny( + function() + -- Status broadcast loop + while true do + sleep(config.statusUpdateInterval) + broadcastStatus() + end + end, + + function() + -- Command processing loop + while true do + local event, side, channel, replyChannel, message = os.pullEvent() + + if event == "modem_message" then + processMessage(message) + end + end + end, + + function() + -- Autonomous execution loop + while true do + if state.mode == "exploring" then + updateFuel() + + -- Check if we should stop + if needsRefuel() or inventoryFull() then + print("Need to return home") + state.mode = "returning" + broadcastStatus() + else + exploreStep() + sleep(0.2) + end + + elseif state.mode == "returning" then + returnHome() + + else + -- Idle or manual mode + sleep(0.5) + end + end + end +)