Files
remoteturtle/pocketremote.lua

594 lines
17 KiB
Lua

-- 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, modes
-- 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
-- Send state change command to turtle (new protocol)
local function sendStateCommand(turtleID, stateName, stateData)
modem.transmit(CHANNEL_SEND, CHANNEL_RECEIVE, {
type = "state_change",
state = stateName,
data = stateData or {},
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.state or turtle.mode or "idle"))
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("State: " .. (turtle.state or turtle.mode or "idle"))
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, 8, 2, "MANUAL", function()
viewMode = "manual"
sendCommand(turtle.turtleID, "manual")
end, colors.purple)
addButton(10, btnY, 8, 2, "MODES", function()
viewMode = "modes"
end, colors.cyan)
addButton(19, btnY, 7, 2, "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 drawModes()
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.cyan)
print("=STATE MACHINE=")
term.setTextColor(colors.white)
print(string.format("T-%d [%s]", turtle.turtleID or 0, turtle.state or turtle.mode or "idle"))
-- State buttons
local btnY = 4
local btnW = 12
addButton(1, btnY, btnW, 2, "IDLE", function()
sendStateCommand(turtle.turtleID, "idle")
sendCommand(turtle.turtleID, "stop")
end, colors.gray)
addButton(14, btnY, btnW, 2, "EXPLORE", function()
sendStateCommand(turtle.turtleID, "exploring")
sendCommand(turtle.turtleID, "explore")
end, colors.green)
btnY = btnY + 3
addButton(1, btnY, btnW, 2, "MINE", function()
sendStateCommand(turtle.turtleID, "mining")
sendCommand(turtle.turtleID, "explore")
end, colors.orange)
addButton(14, btnY, btnW, 2, "FARM", function()
sendStateCommand(turtle.turtleID, "farming")
end, colors.lime)
btnY = btnY + 3
addButton(1, btnY, btnW, 2, "GO HOME", function()
sendStateCommand(turtle.turtleID, "goHome")
sendCommand(turtle.turtleID, "returnHome")
end, colors.yellow)
addButton(14, btnY, btnW, 2, "REFUEL", function()
sendStateCommand(turtle.turtleID, "refueling")
sendCommand(turtle.turtleID, "refuel")
end, colors.red)
btnY = btnY + 3
addButton(1, btnY, btnW, 2, "DUMP INV", function()
sendStateCommand(turtle.turtleID, "dumpInventory")
end, colors.brown)
addButton(14, btnY, btnW, 2, "MOVE TO", function()
-- Could prompt for coordinates, for now just sends moving state
sendStateCommand(turtle.turtleID, "moving")
end, colors.lightBlue)
-- Back button
addButton(1, h - 1, 12, 2, "< BACK", function()
viewMode = "detail"
end, colors.gray)
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()
elseif viewMode == "modes" then
drawModes()
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
-- Preserve state if not in message
if not message.state then
message.state = t.state or message.mode or "idle"
end
turtles[i] = message
found = true
break
end
end
if not found then
if not message.state then
message.state = message.mode or "idle"
end
table.insert(turtles, message)
if not selectedTurtle then
selectedTurtle = 1
end
end
draw()
elseif channel == CHANNEL_RECEIVE and type(message) == "table" then
-- State change confirmation or other response
if message.type == "state_changed" and message.turtleID then
for i, t in ipairs(turtles) do
if t.turtleID == message.turtleID then
turtles[i].state = message.state
break
end
end
end
draw()
end
end
end,
function()
-- Refresh display
while true do
sleep(2)
draw()
end
end
)