local buttons = {} local bars = {} local functions = {} local fgColor = colors.white local bgColor = colors.black local storage = peripheral.find("draconic_rf_storage") local energyPercent = 0 local lastRF = 0 local showingDiff = false local mon, monWidth, monHeight local args = {...} -- PARSE ARGUMENTS if not args then error("Expected program argument, got nil.") else if #args < 1 or #args > 1 then error("Usage:\n string program, number pollRate") end end local pollRate = tonumber(args[1]) or 1 -- INITIALIZE THE MONITOR -- function init() local monitors = {peripheral.find("monitor")} mon = monitors[1] if not mon.isColor() then error("This program requires a color display.") end mon.setCursorPos(1, 1) mon.setTextScale(1) mon.setTextColor(fgColor) mon.setBackgroundColor(bgColor) monWidth, monHeight = mon.getSize() term.setCursorPos(1, 1) local termWidth, termHeight = term.getSize() if monWidth < 27 or monHeight < 12 then error("The monitor must be at least 3x2 blocks.") end term.clear() print("FS Imperial Dynamics Inc. 2016") for i = 1, termWidth do term.write("-") end term.setCursorPos(1, 4) print("Monitor started on \"" .. os.getComputerLabel() .. "\"") print("Poll rate is " .. pollRate .. " second(s)") mon.clear() term.setCursorPos(1, 1) end function label(text, x, y, fg, bg) local bg = bg or colors.black mon.setBackgroundColor(bg) mon.setCursorPos(x, y) mon.setTextColor(fg) mon.write(text) mon.setBackgroundColor(bgColor) end -- BAR FUNCTIONS function newProgressBar(name, label, x, y, w, emptyColor, filledColor) bars[name] = {} bars[name]["label"] = label or "" bars[name]["x"] = x or 2 bars[name]["y"] = y bars[name]["w"] = w or (monWidth - 1) bars[name]["emptyColor"] = emptyColor or colors.gray bars[name]["filledColor"] = filledColor or colors.lightBlue end function drawProgressBar(bar, percentage, filledColor) local color = filledColor or bar.filledColor if not bar then error("A valid progressbar table was not found.") end -- Enforce minimum size if bar.w < 2 then bar.w = 2 end -- Prepare bar background for col = bar.x, ((bar.x + bar.w) - bar.x) do mon.setCursorPos(col, bar.y) mon.setBackgroundColor(bar.emptyColor) mon.write(" ") end -- Fill progress highlight for col = bar.x, ((bar.x + (bar.w * percentage)) - bar.x) do mon.setCursorPos(col, bar.y) mon.setBackgroundColor(color) mon.write(" ") end -- Prepare label, truncating if necessary if #bar.label > bar.w then bar.label = bar.label:sub(1, bar.w) end -- Draw label mon.setCursorPos(bar.x + math.floor((bar.w - #bar.label) / 2), bar.y) mon.write(bar.label) -- Reset display to normal FG and BG mon.setTextColor(fgColor) mon.setBackgroundColor(bgColor) end -- BUTTON FUNCTIONS -- function newButton(name, label, event, x, y, w, h, colorFG, colorBG, activeFG, activeBG, isActive) buttons[name] = {} buttons[name]["label"] = label or "?" buttons[name]["event"] = event buttons[name]["x"] = x buttons[name]["y"] = y buttons[name]["w"] = w or 3 buttons[name]["h"] = h or 1 buttons[name]["fgColor"] = colorFG or colors.white buttons[name]["bgColor"] = colorBG or colors.gray buttons[name]["fgPressed"] = activeFG or colors.white buttons[name]["bgPressed"] = activeBG or colors.red buttons[name]["isActive"] = isActive or false end function drawButton(button) if not button then error("A valid button table was not found.") end -- Enforce minimum size if button.w < 1 then button.w = 1 end if button.h < 1 then button.h = 1 end if not button.isActive then mon.setTextColor(button.fgColor) mon.setBackgroundColor(button.bgColor) else mon.setTextColor(button.fgPressed) mon.setBackgroundColor(button.bgPressed) end -- Preparing button background for row = 1, button.h do mon.setCursorPos(button.x, button.y + row - 1) mon.write(string.rep(" ", button.w)) end -- Prepare label, truncating if necessary if #button.label > button.w then button.label = button.label:sub(1, button.w) end -- Draw label mon.setCursorPos(button.x + math.floor((button.w - #button.label) / 2), button.y + math.floor((button.h - 1) / 2)) mon.write(button.label) -- Reset display to normal FG and BG mon.setTextColor(fgColor) mon.setBackgroundColor(bgColor) end function updateButtons() for button, data in pairs(buttons) do local isActive = data.isActive local bx = data.x local by = data.y drawButton(data, isActive, bx, by) end end function checkButtonPressed(x, y) for button, data in pairs(buttons) do if x >= data.x and x <= data.x + (data.w - 1) then if y >= data.y and y <= data.y + (data.h - 1) then functions[data.event]() end end end end function toggleButton(name) buttons[name].isActive = not buttons[name].isActive updateButtons() end function switchTab(name, exemptButtons) for button, data in pairs(buttons) do data.isActive = false end buttons[name].isActive = true -- Reset any buttons that are to be skipped by the function for button, state in pairs(exemptButtons) do buttons[button].isActive = state end updateButtons() end -- MATH FUNCTION --From Lua-users.org/wiki/FormattingNumbers -- function commaValue(value) local formatted = value while true do formatted, rep = string.gsub(formatted, "^(-?%d+)(%d%d%d)", '%1,%2') if (rep == 0) then break end end return formatted end function round(num, places) local multi = 10 ^ (places or 0) return math.floor(num * multi + 0.5) / multi end --function round(num, places) --return math.floor(num * math.pow(10, places) + 0.5) / math.pow(10, places) --end init() newButton("buttonQuit", "x", 'quit', monWidth, 1, 1, 1, nil, colors.red, nil, nil, false) newButton("buttonRF", "RF", 'showRF', 2, monHeight, 4, 1, nil, nil, nil, nil, true) newButton("buttonEU", "EU", 'showEU', 7, monHeight, 4, 1, nil, nil, nil, nil, false) newButton("buttonMJ", "MJ", 'showMJ', 12, monHeight, 4, 1, nil, nil, nil, nil, false) newButton("buttonJ", "J", 'showJ', 17, monHeight, 4, 1, nil, nil, nil, nil, false) newButton("buttonDiff", "DIFF", 'showDiff', monWidth - 4, monHeight, 4, 1, nil, nil, nil, colors.purple, false) newProgressBar("barEnergy", nil, 2, 10, monWidth - 1, nil, nil) -- BUTTON FUNCTIONS functions['showRF'] = function() switchTab("buttonRF", {["buttonDiff"] = showingDiff}) unit = "RF" end functions['showEU'] = function() switchTab("buttonEU", {["buttonDiff"] = showingDiff}) unit = "EU" end functions['showMJ'] = function() switchTab("buttonMJ", {["buttonDiff"] = showingDiff}) unit = "MJ" end functions['showJ'] = function() switchTab("buttonJ", {["buttonDiff"] = showingDiff}) unit = "J" end functions['showDiff'] = function() toggleButton("buttonDiff") showingDiff = not showingDiff end -- Quit the program and return to command line -- Bad practice using error? Yes, but IDGAF functions['quit'] = function() mon.clear() term.clear() error("User requested halt.") end function getTouchEvents() while true do local event, _, x, y = os.pullEvent() if event == "monitor_touch" then checkButtonPressed(x, y) end end end function main() while true do if buttons["buttonRF"].isActive then unitMultiplier = 1 unit = "RF" elseif buttons["buttonEU"].isActive then unitMultiplier = 0.25 unit = "EU" elseif buttons["buttonMJ"].isActive then unitMultiplier = 0.1 unit = "MJ" elseif buttons["buttonJ"].isActive then unitMultiplier = 2.5 unit = "J" else -- Fallback in case something happens unitMultiplier = 1 unit = "RF" end mon.clear() updateButtons() local current_rf = storage.getEnergyStored() local max_rf = storage.getMaxEnergyStored() energyPercent = current_rf / max_rf -- Stuff for progress bar color if energyPercent == 1 then barColor = colors.lightBlue elseif energyPercent >= 0.8 then barColor = colors.cyan elseif energyPercent >= 0.6 then barColor = colors.green elseif energyPercent >= 0.4 then barColor = colors.yellow elseif energyPercent >= 0.2 then barColor = colors.orange else barColor = colors.red end -- Actually render the bar drawProgressBar(bars["barEnergy"], energyPercent, barColor) -- Make a VERY quick and dirty guess at RF/tick in or out -- No seriously, this is freakin' FILTHY local approxRfPerTick = (current_rf - lastRF) / (20 * pollRate) -- Second verse, same as the first -- #NotHenryVIII lastRF = current_rf if approxRfPerTick > 0 then state = "[+]" stateColor = colors.green elseif approxRfPerTick == 0 then state = "[=]" stateColor = colors.gray else state = "[-]" stateColor = colors.red end label("ENERGY STORED", 1, 1, colors.lightBlue) label(string.format("%s %s", commaValue(math.floor(current_rf * unitMultiplier)), unit), 3, 2, colors.white) label(string.format("%s %s %s", commaValue(math.floor(approxRfPerTick * unitMultiplier)), unit .. "/t", state), 3, 4, stateColor) if buttons["buttonDiff"].isActive then label("ENERGY DIFFERENCE", 1, 6, colors.purple) label(string.format("%s %s", commaValue(math.floor((max_rf - current_rf) * unitMultiplier)), unit), 3, 7, colors.white) else label("ENERGY MAX", 1, 6, colors.orange) label(string.format("%s %s", commaValue(math.floor(max_rf * unitMultiplier)), unit), 3, 7, colors.white) end energyPercent = round(energyPercent * 100, 2) if energyPercent % 10 == 0 then labelEnergyPercent = string.format("\[%s\]", energyPercent .. ".00%") else labelEnergyPercent = string.format("\[%.2f%%\]", round(energyPercent, 2)) end label(labelEnergyPercent, math.floor(monWidth / 2) - math.floor(#labelEnergyPercent / 2) + 1, 9, colors.white) sleep(pollRate) end end parallel.waitForAny(getTouchEvents, main)