require("ui") -- Open a rednet connection peripheral.find("modem", rednet.open) local modules = peripheral.find("manipulator") or peripheral.find("neuralInterface") if not modules then error("Must have neural interface or manipulator", 0) end if not modules.hasModule("plethora:glasses") then error("The overlay glasses are missing", 0) end local canvas = modules.canvas() canvas.clear() local w,h = canvas.getSize() -- Trademark lol local trademark = canvas.addText({5, h-15}, "CakeHUD v1.0") trademark.setScale(0.5) local bgGroup = canvas.addGroup({0, 0}) local graphicsGroup = canvas.addGroup({0, 0}) local textGroup = canvas.addGroup({15, 5}) local powerBg = graphicsGroup.addRectangle(0, 0, 10, 80) powerBg.setColour(0, 0, 0, 255) local powerBar = graphicsGroup.addRectangle(2, 0, 6, 0) local lineGroup = { textGroup.addText({0,0}, "TPS: 0"), textGroup.addText({0,5}, "Power: 0/0"), textGroup.addText({0,10}, "Reactor status: unknown") } function getHUDHeight() local w = 0 local h = 0 for i = 1, #lineGroup do local scale = lineGroup[i].getScale() local th = 5 * scale h = h + th end return h end local th = getHUDHeight() local textBg = bgGroup.addPolygon( {0, 0}, {125, 0}, {120, th + 10}, {0, th + 10} ) textBg.setColour(0, 0, 0, 125) function makeHUD(lines) for i = 1, #lines do lineGroup[i].setScale(0.5) lineGroup[i].setText(string.format("%s", lines[i].text)) lineGroup[i].setColour(lines[i].color.r, lines[i].color.g, lines[i].color.b, lines[i].color.a) end end function updatePowerBar(power, maxPower) local percentage = power / maxPower local height = math.floor(percentage * 76) local color = getPowerColor(power, maxPower) powerBar.setSize(6, height) powerBar.setPosition(2, 76 - height + 2) powerBar.setColour(color.r, color.g, color.b, color.a) end -- colors based on power percentage local powerColors = { { color = { r = 255, g = 0, b = 0, a = 125 }, threshold = 0.1 }, { color = { r = 255, g = 0, b = 0, a = 255 }, threshold = 0.25 }, { color = { r = 255, g = 255, b = 0, a = 255 }, threshold = 0.5 }, { color = { r = 0, g = 255, b = 0, a = 255 }, threshold = 0.75 }, { color = { r = 0, g = 255, b = 0, a = 125 }, threshold = 0.8 }, { color = { r = 0, g = 255, b = 0, a = 255 }, threshold = 0.9 } } local tpsColors = { { color = { r = 0, g = 255, b = 0, a = 255 }, threshold = 19 }, { color = { r = 255, g = 255, b = 0, a = 255 }, threshold = 18 }, { color = { r = 255, g = 0, b = 0, a = 255 }, threshold = 15 }, { color = { r = 255, g = 0, b = 0, a = 255 }, threshold = 10 } } function getPowerColor(power, maxPower) local percentage = power / maxPower for i = 1, #powerColors do if percentage <= powerColors[i].threshold then return powerColors[i].color end end return powerColors[#powerColors].color end function getTPSColor(tps) for i = 1, #tpsColors do if tps >= tpsColors[i].threshold then return tpsColors[i].color end end return tpsColors[#tpsColors].color end -- Listen for responses on "cakehud" local prevRF = 0 local todo = {} function processData() local senderId, message, protocol = rednet.receive("cakehud") -- Deserialize the message local data = textutils.unserialize(message) -- Make the HUD local rfIndicator = "" if data.power.power > prevRF then rfIndicator = string.format(" (%s)", string.char(94)) else if data.power.power < prevRF then rfIndicator = string.format(" (%s)", string.char(118)) else if data.power.power == prevRF then rfIndicator = string.format(" (%s)", string.char(62)) end end end prevRF = data.power.power local lines = { { text = "TPS: " .. math.floor(data.tps), color = getTPSColor(data.tps) }, { text = "Power: " .. data.power.power .. "/" .. data.power.maxPower .. rfIndicator, color = getPowerColor(data.power.power, data.power.maxPower) }, { text = "Reactor status: " .. (data.reactorStatus and "charging" or "discharging"), color = data.reactorStatus and {r = 0, g = 255, b = 0, a = 255} or {r = 255, g = 0, b = 0, a = 255} } } makeHUD(lines) updatePowerBar(data.power.power, data.power.maxPower) todo = data.todo coroutine.yield() end -- The function that hijacks the terminal local input = "" function terminalOut(input) local bg = colors.gray local fg = colors.white local tw,th = term.getSize() term.setBackgroundColor(bg) term.clear() term.setCursorPos(1, 1) Text(1, 1, "CakeHUD", "medium", bg, colors.red) Text(1, 4, "Type anything to add a TODO", "small", bg, fg) Text(1, 5, "Type \"!\" to delete TODO", "small", bg, fg) Text(1, 7, "$ ", "small", bg, colors.orange) Text(3, 7, input, "small", bg, fg) Box(3, 8, tw - 4, th - 8, colors.black, nil) for i = 1, #todo do Text(1, 7 + i, string.format("#%s %s %s", i, string.char(16), todo[i]), "small", colors.black, fg) end term.setCursorPos(4, 6) end function inputHandler() local e, p1, p2, p3, p4, p5 = os.pullEvent() if e == "char" then input = input .. p1 else if e == "key" then if p1 == keys.backspace then input = input:sub(1, -2) else if p1 == keys.enter then -- Parse the input if input:sub(1, 1) == "!" then local id = tonumber(input:sub(2)) rednet.broadcast(textutils.serialize({type = "delete", id = id}), "cakehud_todo") else rednet.broadcast(textutils.serialize({type = "add", text = input}), "cakehud_todo") end input = "" end end end end terminalOut(input) end -- Run the main loop while true do parallel.waitForAny(processData, inputHandler) -- main() end