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)
Comments