Flawedspirit icon

DE Orb Monitor

Flawedspirit | PRO | 11/08/16 06:15:57 PM UTC | 0 ⭐ | 385 👁️ | Never ⏰ | []
Lua |

11.27 KB

|

None

|

0 👍

/

0 👎

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