Advertisement
Flawedspirit

DE Orb Monitor

Nov 8th, 2016
257
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 11.27 KB | None | 0 0
  1. local buttons       = {}
  2. local bars          = {}
  3. local functions     = {}
  4.  
  5. local fgColor       = colors.white
  6. local bgColor       = colors.black
  7. local storage       = peripheral.find("draconic_rf_storage")
  8.  
  9. local energyPercent = 0
  10. local lastRF        = 0
  11. local showingDiff   = false
  12.  
  13. local mon, monWidth, monHeight
  14.  
  15. local args = {...}
  16.  
  17. -- PARSE ARGUMENTS
  18. if not args then
  19.     error("Expected program argument, got nil.")
  20. else
  21.     if #args < 1 or #args > 1 then
  22.         error("Usage:\n  string program, number pollRate")
  23.     end
  24. end
  25.  
  26. local pollRate = tonumber(args[1]) or 1
  27.  
  28. -- INITIALIZE THE MONITOR --
  29.  
  30. function init()
  31.     local monitors = {peripheral.find("monitor")}
  32.     mon = monitors[1]
  33.  
  34.     if not mon.isColor() then
  35.         error("This program requires a color display.")
  36.     end
  37.  
  38.     mon.setCursorPos(1, 1)
  39.     mon.setTextScale(1)
  40.     mon.setTextColor(fgColor)
  41.     mon.setBackgroundColor(bgColor)
  42.     monWidth, monHeight = mon.getSize()
  43.  
  44.     term.setCursorPos(1, 1)
  45.     local termWidth, termHeight = term.getSize()
  46.  
  47.     if monWidth < 27 or monHeight < 12 then
  48.         error("The monitor must be at least 3x2 blocks.")
  49.     end
  50.  
  51.     term.clear()
  52.     print("FS Imperial Dynamics Inc. 2016")
  53.  
  54.     for i = 1, termWidth do
  55.         term.write("-")
  56.     end
  57.  
  58.     term.setCursorPos(1, 4)
  59.     print("Monitor started on \"" .. os.getComputerLabel() .. "\"")
  60.     print("Poll rate is " .. pollRate .. " second(s)")
  61.  
  62.     mon.clear()
  63.     term.setCursorPos(1, 1)
  64. end
  65.  
  66. function label(text, x, y, fg, bg)
  67.     local bg = bg or colors.black
  68.     mon.setBackgroundColor(bg)
  69.  
  70.     mon.setCursorPos(x, y)
  71.     mon.setTextColor(fg)
  72.     mon.write(text)
  73.  
  74.     mon.setBackgroundColor(bgColor)
  75. end
  76.  
  77. -- BAR FUNCTIONS
  78.  
  79. function newProgressBar(name, label, x, y, w, emptyColor, filledColor)
  80.     bars[name]                = {}
  81.     bars[name]["label"]       = label or ""
  82.     bars[name]["x"]           = x or 2
  83.     bars[name]["y"]           = y
  84.     bars[name]["w"]           = w or (monWidth - 1)
  85.     bars[name]["emptyColor"]  = emptyColor or colors.gray
  86.     bars[name]["filledColor"] = filledColor or colors.lightBlue
  87. end
  88.  
  89. function drawProgressBar(bar, percentage, filledColor)
  90.     local color = filledColor or bar.filledColor
  91.  
  92.     if not bar then
  93.         error("A valid progressbar table was not found.")
  94.     end
  95.  
  96.     -- Enforce minimum size
  97.     if bar.w < 2 then
  98.         bar.w = 2
  99.     end
  100.  
  101.     -- Prepare bar background
  102.     for col = bar.x, ((bar.x + bar.w) - bar.x) do
  103.         mon.setCursorPos(col, bar.y)
  104.         mon.setBackgroundColor(bar.emptyColor)
  105.         mon.write(" ")
  106.     end
  107.  
  108.     -- Fill progress highlight
  109.     for col = bar.x, ((bar.x + (bar.w * percentage)) - bar.x) do
  110.         mon.setCursorPos(col, bar.y)
  111.         mon.setBackgroundColor(color)
  112.         mon.write(" ")
  113.     end
  114.  
  115.     -- Prepare label, truncating if necessary
  116.     if #bar.label > bar.w then
  117.         bar.label = bar.label:sub(1, bar.w)
  118.     end
  119.  
  120.     -- Draw label
  121.     mon.setCursorPos(bar.x + math.floor((bar.w - #bar.label) / 2), bar.y)
  122.     mon.write(bar.label)
  123.  
  124.     -- Reset display to normal FG and BG
  125.     mon.setTextColor(fgColor)
  126.     mon.setBackgroundColor(bgColor)
  127. end
  128.  
  129. -- BUTTON FUNCTIONS --
  130.  
  131. function newButton(name, label, event, x, y, w, h, colorFG, colorBG, activeFG, activeBG, isActive)
  132.     buttons[name]              = {}
  133.     buttons[name]["label"]     = label    or "?"
  134.     buttons[name]["event"]     = event
  135.     buttons[name]["x"]         = x
  136.     buttons[name]["y"]         = y
  137.     buttons[name]["w"]         = w        or 3
  138.     buttons[name]["h"]         = h        or 1
  139.     buttons[name]["fgColor"]   = colorFG  or colors.white
  140.     buttons[name]["bgColor"]   = colorBG  or colors.gray
  141.     buttons[name]["fgPressed"] = activeFG or colors.white
  142.     buttons[name]["bgPressed"] = activeBG or colors.red
  143.     buttons[name]["isActive"]  = isActive or false
  144. end
  145.  
  146. function drawButton(button)
  147.     if not button then
  148.         error("A valid button table was not found.")
  149.     end
  150.  
  151.     -- Enforce minimum size
  152.     if button.w < 1 then
  153.         button.w = 1
  154.     end
  155.  
  156.     if button.h < 1 then
  157.         button.h = 1
  158.     end
  159.  
  160.     if not button.isActive then
  161.         mon.setTextColor(button.fgColor)
  162.         mon.setBackgroundColor(button.bgColor)
  163.     else
  164.         mon.setTextColor(button.fgPressed)
  165.         mon.setBackgroundColor(button.bgPressed)
  166.     end
  167.  
  168.     -- Preparing button background
  169.     for row = 1, button.h do
  170.         mon.setCursorPos(button.x, button.y + row - 1)
  171.         mon.write(string.rep(" ", button.w))
  172.     end
  173.  
  174.     -- Prepare label, truncating if necessary
  175.     if #button.label > button.w then
  176.         button.label = button.label:sub(1, button.w)
  177.     end
  178.  
  179.     -- Draw label
  180.     mon.setCursorPos(button.x + math.floor((button.w - #button.label) / 2), button.y + math.floor((button.h - 1) / 2))
  181.     mon.write(button.label)
  182.  
  183.     -- Reset display to normal FG and BG
  184.     mon.setTextColor(fgColor)
  185.     mon.setBackgroundColor(bgColor)
  186. end
  187.  
  188. function updateButtons()
  189.     for button, data in pairs(buttons) do
  190.         local isActive = data.isActive
  191.         local bx = data.x
  192.         local by = data.y
  193.  
  194.         drawButton(data, isActive, bx, by)
  195.     end
  196. end
  197.  
  198. function checkButtonPressed(x, y)
  199.     for button, data in pairs(buttons) do
  200.         if x >= data.x and x <= data.x + (data.w - 1) then
  201.             if y >= data.y and y <= data.y + (data.h - 1) then
  202.                 functions[data.event]()
  203.             end
  204.         end
  205.     end
  206. end
  207.  
  208. function toggleButton(name)
  209.     buttons[name].isActive = not buttons[name].isActive
  210.     updateButtons()
  211. end
  212.  
  213. function switchTab(name, exemptButtons)
  214.     for button, data in pairs(buttons) do
  215.         data.isActive = false
  216.     end
  217.  
  218.     buttons[name].isActive = true
  219.  
  220.     -- Reset any buttons that are to be skipped by the function
  221.     for button, state in pairs(exemptButtons) do
  222.         buttons[button].isActive = state
  223.     end
  224.  
  225.     updateButtons()
  226. end
  227.  
  228. -- MATH FUNCTION
  229.  
  230. --From Lua-users.org/wiki/FormattingNumbers
  231. --
  232. function commaValue(value)
  233.     local formatted = value
  234.  
  235.     while true do  
  236.             formatted, rep = string.gsub(formatted, "^(-?%d+)(%d%d%d)", '%1,%2')
  237.  
  238.             if (rep == 0) then
  239.             break
  240.         end
  241.     end
  242.     return formatted
  243. end
  244.  
  245. function round(num, places)
  246.     local multi = 10 ^ (places or 0)
  247.     return math.floor(num * multi + 0.5) / multi
  248. end
  249.  
  250. --function round(num, places)
  251.     --return math.floor(num * math.pow(10, places) + 0.5) / math.pow(10, places)
  252. --end
  253.  
  254. init()
  255.  
  256. newButton("buttonQuit", "x", 'quit', monWidth, 1, 1, 1, nil, colors.red, nil, nil, false)
  257. newButton("buttonRF", "RF", 'showRF', 2, monHeight, 4, 1, nil, nil, nil, nil, true)
  258. newButton("buttonEU", "EU", 'showEU', 7, monHeight, 4, 1, nil, nil, nil, nil, false)
  259. newButton("buttonMJ", "MJ", 'showMJ', 12, monHeight, 4, 1, nil, nil, nil, nil, false)
  260. newButton("buttonJ", "J", 'showJ', 17, monHeight, 4, 1, nil, nil, nil, nil, false)
  261. newButton("buttonDiff", "DIFF", 'showDiff', monWidth - 4, monHeight, 4, 1, nil, nil, nil, colors.purple, false)
  262.  
  263. newProgressBar("barEnergy", nil, 2, 10, monWidth - 1, nil, nil)
  264.  
  265. -- BUTTON FUNCTIONS
  266.  
  267. functions['showRF'] = function()
  268.     switchTab("buttonRF", {["buttonDiff"] = showingDiff})
  269.     unit = "RF"
  270. end
  271.  
  272. functions['showEU'] = function()
  273.     switchTab("buttonEU", {["buttonDiff"] = showingDiff})
  274.     unit = "EU"
  275. end
  276.  
  277. functions['showMJ'] = function()
  278.     switchTab("buttonMJ", {["buttonDiff"] = showingDiff})
  279.     unit = "MJ"
  280. end
  281.  
  282. functions['showJ'] = function()
  283.     switchTab("buttonJ", {["buttonDiff"] = showingDiff})
  284.     unit = "J"
  285. end
  286.  
  287. functions['showDiff'] = function()
  288.     toggleButton("buttonDiff")
  289.     showingDiff = not showingDiff
  290. end
  291.  
  292. -- Quit the program and return to command line
  293. -- Bad practice using error? Yes, but IDGAF
  294. functions['quit'] = function()
  295.     mon.clear()
  296.     term.clear()
  297.     error("User requested halt.")
  298. end
  299.  
  300. function getTouchEvents()
  301.     while true do
  302.         local event, _, x, y = os.pullEvent()
  303.  
  304.         if event == "monitor_touch" then
  305.             checkButtonPressed(x, y)
  306.         end
  307.     end
  308. end
  309.  
  310. function main()
  311.     while true do
  312.         if buttons["buttonRF"].isActive then
  313.             unitMultiplier = 1
  314.             unit = "RF"
  315.         elseif buttons["buttonEU"].isActive then
  316.             unitMultiplier = 0.25
  317.             unit = "EU"
  318.         elseif buttons["buttonMJ"].isActive then
  319.             unitMultiplier = 0.1
  320.             unit = "MJ"
  321.         elseif buttons["buttonJ"].isActive then
  322.             unitMultiplier = 2.5
  323.             unit = "J"
  324.         else
  325.             -- Fallback in case something happens
  326.             unitMultiplier = 1
  327.             unit = "RF"
  328.         end
  329.  
  330.         mon.clear()
  331.         updateButtons()
  332.  
  333.         local current_rf = storage.getEnergyStored()
  334.         local max_rf = storage.getMaxEnergyStored()
  335.  
  336.         energyPercent = current_rf / max_rf
  337.  
  338.         -- Stuff for progress bar color
  339.         if energyPercent == 1 then
  340.             barColor = colors.lightBlue
  341.         elseif energyPercent >= 0.8 then
  342.             barColor = colors.cyan
  343.         elseif energyPercent >= 0.6 then
  344.             barColor = colors.green
  345.         elseif energyPercent >= 0.4 then
  346.             barColor = colors.yellow
  347.         elseif energyPercent >= 0.2 then
  348.             barColor = colors.orange
  349.         else
  350.             barColor = colors.red
  351.         end
  352.  
  353.         -- Actually render the bar
  354.         drawProgressBar(bars["barEnergy"], energyPercent, barColor)
  355.  
  356.         -- Make a VERY quick and dirty guess at RF/tick in or out
  357.         -- No seriously, this is freakin' FILTHY
  358.         local approxRfPerTick = (current_rf - lastRF) / (20 * pollRate)
  359.  
  360.         -- Second verse, same as the first
  361.         -- #NotHenryVIII
  362.         lastRF = current_rf
  363.  
  364.         if approxRfPerTick > 0 then
  365.             state = "[+]"
  366.             stateColor = colors.green
  367.         elseif approxRfPerTick == 0 then
  368.             state = "[=]"
  369.             stateColor = colors.gray
  370.         else
  371.             state = "[-]"
  372.             stateColor = colors.red
  373.         end
  374.  
  375.         label("ENERGY STORED", 1, 1, colors.lightBlue)
  376.         label(string.format("%s %s", commaValue(math.floor(current_rf * unitMultiplier)), unit), 3, 2, colors.white)
  377.         label(string.format("%s %s %s", commaValue(math.floor(approxRfPerTick * unitMultiplier)), unit .. "/t", state), 3, 4, stateColor)
  378.  
  379.         if buttons["buttonDiff"].isActive then
  380.             label("ENERGY DIFFERENCE", 1, 6, colors.purple)
  381.             label(string.format("%s %s", commaValue(math.floor((max_rf - current_rf) * unitMultiplier)), unit), 3, 7, colors.white)
  382.         else
  383.             label("ENERGY MAX", 1, 6, colors.orange)
  384.             label(string.format("%s %s", commaValue(math.floor(max_rf * unitMultiplier)), unit), 3, 7, colors.white)
  385.         end
  386.  
  387.         energyPercent = round(energyPercent * 100, 2)
  388.  
  389.         if energyPercent % 10 == 0 then
  390.            labelEnergyPercent = string.format("\[%s\]", energyPercent .. ".00%")
  391.         else
  392.            labelEnergyPercent = string.format("\[%.2f%%\]", round(energyPercent, 2))
  393.         end
  394.  
  395.         label(labelEnergyPercent, math.floor(monWidth / 2) - math.floor(#labelEnergyPercent / 2) + 1, 9, colors.white)
  396.  
  397.         sleep(pollRate)
  398.     end
  399. end
  400.  
  401. parallel.waitForAny(getTouchEvents, main)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement