Advertisement
1lann

reactor

Jan 6th, 2014
112
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 12.86 KB | None | 0 0
  1. -- Nuclear Reactor Monitor Panel v1.4.1 Beta. By: 1lann. 2013
  2.  
  3. -- User Configuration:
  4. -- Valid sides: top bottom left right front back
  5. -- Sides are from your perspective, assuming you are facing the computer's face.
  6. local reactorSide = "back"
  7. local alarmSide = "top"
  8. -- Side for turning off reactor on redstone input
  9. local controlSide = "front"
  10. local alarmOnReplace = true
  11. local maxThreshold = 7000
  12. local cooldownTemp = 5000
  13. local updateRate = 0.5 -- In seconds
  14. ------------------------------------
  15.  
  16. local reactor = peripheral.wrap(reactorSide)
  17. if not reactor.getMaxHeat then
  18.     print("Could not find reactor!")
  19.     error()
  20. end
  21.  
  22. -- Basic Reactor Monitoring by: 1lann
  23. local wid,hei = term.getSize()
  24. local function centerPrint(text)
  25.     local x,y = term.getCursorPos()
  26.     term.setCursorPos(math.ceil((wid/2)-(#text/2)),y)
  27.     print(text)
  28. end
  29.  
  30. local function getPercent(fraction)
  31.     return math.ceil(fraction*100-0.5)
  32. end
  33.  
  34. local function printStatus(state,text,color)
  35.     term.setCursorPos(2,3)
  36.     term.setBackgroundColor(colors.white)
  37.     term.setTextColor(colors.gray)
  38.     write("State: ")
  39.     if state then
  40.         term.setTextColor(colors.lime)
  41.         write("On ")
  42.     else
  43.         term.setTextColor(colors.red)
  44.         write("Off")
  45.     end
  46.     term.setTextColor(colors.gray)
  47.     term.setCursorPos(2,4)
  48.     write("Remarks: ")
  49.     term.setTextColor(color)
  50.     write(text..string.rep(" ",wid-#text-5))
  51. end
  52.  
  53. local function emergency()
  54.     local allSlots = reactor.getAllStacks()
  55.     for k,v in pairs(allSlots) do
  56.         if v["name"]:lower():find("uranium") then
  57.             pcall(function() reactor.destroyStack(k) end)
  58.         end
  59.     end
  60.     term.setBackgroundColor(colors.red)
  61.     term.setTextColor(colors.yellow)
  62.     term.clear()
  63.     term.setCursorPos(1,4)
  64.     centerPrint("-- EMERGENCY NOTICE --")
  65.     centerPrint("The system has just stopped a")
  66.     centerPrint("reactor explosion due to the reactor")
  67.     centerPrint("being out of the system's control.")
  68.     centerPrint("The catastrophe was stopped by")
  69.     centerPrint("destroying all of the Uranium in")
  70.     centerPrint("the reactor.")
  71.     print("")
  72.     centerPrint("Please reset the reactor and system")
  73.     centerPrint("Press any key to continue...")
  74.     os.pullEvent("key")
  75.     term.setTextColor(colors.white)
  76.     term.setBackgroundColor(colors.black)
  77.     term.clear()
  78.     term.setCursorPos(1,1)
  79.     sleep(0.2)
  80.     error("emergency")
  81. end
  82.  
  83. term.setBackgroundColor(colors.white)
  84. term.clear()
  85. term.setCursorPos(2,1)
  86. term.setBackgroundColor(colors.lightGray)
  87. term.clearLine()
  88. term.setTextColor(colors.white)
  89. write("Nuclear Reactor Panel (By: 1lann)")
  90. printStatus(false,"Initializing",colors.gray)
  91. term.setTextColor(colors.gray)
  92. term.setCursorPos(2,6)
  93. print("Current Heat Level: ")
  94. term.setCursorPos(2,7)
  95. write("[")
  96. term.setCursorPos(wid-1,7)
  97. write("]")
  98. term.setCursorPos(2,9)
  99. print("Current Output: ")
  100. term.setCursorPos(2,10)
  101. print("Average Output: ")
  102. term.setCursorPos(2,11)
  103. print("Coolant Durability: Calculating...")
  104. term.setCursorPos(2,12)
  105. write("[")
  106. term.setCursorPos(wid-1,12)
  107. write("]")
  108. term.setCursorPos(2,13)
  109. print("Time til empty: Calculating...")
  110.  
  111. local function heatLevel()
  112.     local heat = reactor.getHeat()
  113.     local function getColor(heat)
  114.         local percent = heat/maxThreshold
  115.         if percent >= 0.9 then
  116.             return colors.red
  117.         elseif percent >= 0.7 then
  118.             return colors.orange
  119.         elseif percent >= 0.4 then
  120.             return colors.yellow
  121.         else
  122.             return colors.lime
  123.         end
  124.     end
  125.     term.setBackgroundColor(colors.white)
  126.     term.setTextColor(colors.gray)
  127.     term.setCursorPos(2,6)
  128.     write("Current Heat Level: ")
  129.     term.setTextColor(getColor(heat))
  130.     write(tostring(getPercent(heat/maxThreshold)).."% ("..tostring(heat).."/"..tostring(maxThreshold)..")     ")
  131.     local total = wid-4
  132.     local bar = math.ceil((heat/maxThreshold)*total)
  133.     if bar > total then bar = total end
  134.     term.setCursorPos(3,7)
  135.     term.setBackgroundColor(colors.white)
  136.     term.write(string.rep(" ",total))
  137.     term.setCursorPos(3,7)
  138.     term.setBackgroundColor(getColor(heat))
  139.     term.write(string.rep(" ",bar))
  140. end
  141.  
  142. local previousOutputs = {}
  143.  
  144. local function calculateOutput()
  145.     term.setBackgroundColor(colors.white)
  146.     term.setTextColor(colors.gray)
  147.     local output = math.ceil(reactor.getEUOutput()*50-0.5)/10
  148.     term.setCursorPos(18,9)
  149.     write(output .. " EU/t          ")
  150.     if #previousOutputs > 1000 then
  151.         table.remove(previousOutputs,#previousOutputs)
  152.     end
  153.     table.insert(previousOutputs,output)
  154.     local total = 0
  155.     for k,v in pairs(previousOutputs) do
  156.         total = total+v
  157.     end
  158.     term.setCursorPos(18,10)
  159.     write(tostring(math.ceil((total/#previousOutputs)*10-0.5)/10) .. " EU/t          ")
  160. end
  161.  
  162. local manual = false
  163. local damage = false
  164. local firstDamage = "first-time"
  165. local cooldownCheck = false
  166. local cooldownClock = false
  167. local previousDamages = {}
  168.  
  169. local function damageLevel()
  170.     local highestDamage = -1
  171.     local allSlots = reactor.getAllStacks()
  172.     for k,v in pairs(allSlots) do
  173.         if not(v["name"]:lower():find("uranium")) then
  174.             local test = v["dmg"]
  175.             if test > highestDamage then highestDamage = test end
  176.         end
  177.     end
  178.     if highestDamage < 0 then
  179.         highestDamage = 10000
  180.     end
  181.     if #previousDamages > 1000 then
  182.         table.remove(previousDamages,#previousDamages)
  183.     end
  184.     table.insert(previousDamages,{highestDamage,os.clock()})
  185.     local function getColor(dmg)
  186.         local percent = dmg/10000
  187.         if percent >= 0.9 then
  188.             return colors.red
  189.         elseif percent >= 0.7 then
  190.             return colors.orange
  191.         elseif percent >= 0.4 then
  192.             return colors.yellow
  193.         else
  194.             return colors.lime
  195.         end
  196.     end
  197.     term.setCursorPos(22,11)
  198.     term.setBackgroundColor(colors.white)
  199.     term.setTextColor(getColor(highestDamage))
  200.     write(getPercent((10000-highestDamage)/10000).."%            ")
  201.     local total = wid-4
  202.     local bar = math.ceil(((10000-highestDamage)/10000)*total)
  203.     term.setCursorPos(3,12)
  204.     term.setBackgroundColor(colors.white)
  205.     term.write(string.rep(" ",total))
  206.     term.setCursorPos(3,12)
  207.     term.setBackgroundColor(getColor(highestDamage))
  208.     term.write(string.rep(" ",bar))
  209.     local average = 0
  210.     for i = 1, #previousDamages-1 do
  211.         average = average+(previousDamages[i][1]-previousDamages[i+1][1])/(previousDamages[i][2]-previousDamages[i+1][2])
  212.     end
  213.     local remainder = (10000-highestDamage)/(average/(#previousDamages-1))
  214.     term.setBackgroundColor(colors.white)
  215.     term.setTextColor(colors.gray)
  216.     term.setCursorPos(18,13)
  217.     term.write(tostring(math.ceil(remainder-0.5)).." seconds          ")
  218.     os.queueEvent("reactor-durability")
  219.     if getPercent((10000-highestDamage)/10000) < 5 then
  220.         damage = true
  221.     else
  222.         damage = false
  223.     end
  224. end
  225.  
  226. local function cooling()
  227.     if reactor.getHeat() <= cooldownTemp then
  228.         rs.setOutput(reactorSide,true)
  229.         rs.setOutput(alarmSide,false)
  230.         cooldownCheck = false
  231.         return "heat"
  232.     end
  233.     rs.setOutput(reactorSide,false)
  234.     if reactor.getHeat() >= reactor.getMaxHeat()-1000 then
  235.         emergency()
  236.     elseif reactor.getHeat() >= maxThreshold then
  237.         printStatus(false,"DANGER: REACTOR OVERHEATING!",colors.red)
  238.         rs.setOutput(alarmSide,true)
  239.     else
  240.         if cooldownCheck then
  241.             if cooldownClock < os.clock() then
  242.                 if reactor.getHeat() >= cooldownCheck then
  243.                     printStatus(false,"DANGER: REACTOR NOT COOLING!",colors.red)
  244.                     rs.setOutput(alarmSide,true)
  245.                 elseif reactor.isActive() then
  246.                     printStatus(false,"DANGER: REACTOR SABOTAGED!",colors.red)
  247.                     rs.setOutput(alarmSide,true)
  248.                 else
  249.                     rs.setOutput(alarmSide,false)
  250.                     printStatus(false,"Cooldown",colors.lightBlue)
  251.                 end
  252.             elseif reactor.isActive() then
  253.                 printStatus(false,"DANGER: REACTOR SABOTAGED!",colors.red)
  254.                 rs.setOutput(alarmSide,true)
  255.             else
  256.                 rs.setOutput(alarmSide,false)
  257.                 printStatus(false,"Cooldown",colors.lightBlue)
  258.             end
  259.         else
  260.             cooldownCheck = reactor.getHeat()
  261.             cooldownClock = os.clock()+10
  262.             rs.setOutput(alarmSide,false)
  263.             printStatus(false,"Cooldown",colors.lightBlue)
  264.         end
  265.     end
  266. end
  267.  
  268. local function heating()
  269.     if reactor.getHeat() >= (maxThreshold*0.9) then
  270.         outputCheck = false
  271.         rs.setOutput(reactorSide,false)
  272.         return "cool"
  273.     end
  274.     rs.setOutput(reactorSide,true)
  275.     if outputCheck then
  276.         if reactor.getEUOutput() < 1 then
  277.             if alarmOnReplace then
  278.                 rs.setOutput(alarmSide,true)
  279.             else
  280.                 rs.setOutput(alarmSide,false)
  281.             end
  282.             printStatus(true,"No power being generated!",colors.yellow)
  283.         else
  284.             rs.setOutput(alarmSide,false)
  285.             printStatus(true,"Normal Operation",colors.lime)
  286.         end
  287.     else
  288.         outputCheck = true
  289.         rs.setOutput(alarmSide,false)
  290.         printStatus(true,"Normal Operation",colors.lime)
  291.     end
  292. end
  293.  
  294. local function main()
  295.     local state = "heating"
  296.     while true do
  297.         sleep(updateRate/4)
  298.         heatLevel()
  299.         sleep(updateRate/4)
  300.         calculateOutput()
  301.         sleep(updateRate/4)
  302.         damageLevel()
  303.         sleep(updateRate/4)
  304.         if manual then
  305.             rs.setOutput(reactorSide,false)
  306.             rs.setOutput(alarmSide,false)
  307.             if reactor.isActive() then
  308.                 printStatus(true,"Manual Control",colors.yellow)
  309.             else
  310.                 printStatus(false,"Manual Control",colors.yellow)
  311.             end
  312.         elseif rs.getInput(controlSide) then
  313.             printStatus(false,"Redstone Override",colors.yellow)
  314.         elseif damage then
  315.             rs.setOutput(reactorSide,false)
  316.             if firstDamage then
  317.                 if alarmOnReplace then
  318.                     rs.setOutput(alarmSide,true)
  319.                     printStatus(false,"Replace or remove used parts!",colors.red)
  320.                 else
  321.                     rs.setOutput(alarmSide,false)
  322.                     printStatus(false,"Replace or remove used parts!",colors.red)
  323.                 end
  324.                 firstDamage = false
  325.                 sleep(1)
  326.             else
  327.                 if reactor.getHeat() >= reactor.getMaxHeat()-1000 then
  328.                     emergency()
  329.                 elseif reactor.getHeat() >= maxThreshold then
  330.                     printStatus(false,"Replace parts: REACTOR OVERHEATING!",colors.red)
  331.                     rs.setOutput(alarmSide,true)
  332.                 elseif reactor.isActive() then
  333.                     printStatus(false,"Replace parts: REACTOR SABOTAGED!",colors.red)
  334.                     rs.setOutput(alarmSide,true)
  335.                 elseif alarmOnReplace then
  336.                     rs.setOutput(alarmSide,true)
  337.                     printStatus(false,"Replace or remove used parts!",colors.red)
  338.                 else
  339.                     rs.setOutput(alarmSide,false)
  340.                     printStatus(false,"Replace or remove used parts!",colors.red)
  341.                 end
  342.             end
  343.         else
  344.             if state == "heating" then
  345.                 if heating() == "cool" then
  346.                     state = "cooling"
  347.                 end
  348.             else
  349.                 if cooling() == "heat" then
  350.                     state = "heating"
  351.                 end
  352.             end
  353.             if firstDamage == "first-time" then
  354.                 sleep(1)
  355.                 previousDamages = {}
  356.                 previousOutputs = {}
  357.                 firstDamage = true
  358.             end
  359.         end
  360.     end
  361. end
  362.  
  363. local function control()
  364.     local previousTime = nil
  365.     local resetAverages = nil
  366.     local time = nil
  367.     term.setBackgroundColor(colors.lightGray)
  368.     term.setTextColor(colors.white)
  369.     term.setCursorPos(2,15)
  370.     write("                    ")
  371.     term.setCursorPos(2,16)
  372.     write("  Manual-mode (Off) ")
  373.     term.setCursorPos(2,17)
  374.     write("                    ")
  375.  
  376.     if fs.exists("/.reactor-manual") then
  377.         term.setCursorPos(2,16)
  378.         write("   Auto-mode (On)   ")
  379.         manual = true
  380.         rs.setOutput(reactorSide,false)
  381.     end
  382.  
  383.     term.setCursorPos(wid-21,15)
  384.     write("                    ")
  385.     term.setCursorPos(wid-21,16)
  386.     write("   Reset Averages   ")
  387.     term.setCursorPos(wid-21,17)
  388.     write("                    ")
  389.     while true do
  390.         local e,t,x,y = os.pullEvent()
  391.         if e == "mouse_click" then
  392.             if (x >= 2) and (x <= 22) and (y >= 15) and (y <= 17) then
  393.                 if not manual then
  394.                     manual = true
  395.                     rs.setOutput(reactorSide,false)
  396.                     term.setBackgroundColor(colors.lightGray)
  397.                     term.setTextColor(colors.white)
  398.                     term.setCursorPos(2,16)
  399.                     write("   Auto-mode (On)  ")
  400.                     local f = io.open("/.reactor-manual","w")
  401.                     f:write("\n")
  402.                     f:close()
  403.                 else
  404.                     manual = false
  405.                     fs.delete("/.reactor-manual")
  406.                     term.setBackgroundColor(colors.lightGray)
  407.                     term.setTextColor(colors.white)
  408.                     term.setCursorPos(2,16)
  409.                     write("  Manual-mode (Off) ")
  410.                 end
  411.             elseif (x >= wid-21) and (x <= wid-1) and (y >= 15) and (y <= 17) then
  412.                 previousDamages = {}
  413.                 previousOutputs = {}
  414.                 term.setTextColor(colors.white)
  415.                 term.setBackgroundColor(colors.lightGray)
  416.                 term.setCursorPos(wid-21,16)
  417.                 write("   Averages Reset!  ")
  418.                 resetAverages = os.startTimer(2)
  419.             end
  420.         elseif e == "timer" then
  421.             if t == resetAverages then
  422.                 term.setCursorPos(wid-21,16)
  423.                 term.setTextColor(colors.white)
  424.                 term.setBackgroundColor(colors.lightGray)
  425.                 write("   Reset Averages   ")
  426.             end
  427.         end
  428.     end
  429. end
  430.  
  431.  
  432. local e, msg = pcall(function()parallel.waitForAny(control,main)end)
  433. term.setBackgroundColor(colors.black)
  434. term.setTextColor(colors.red)
  435. term.setCursorPos(1,1)
  436. term.clear()
  437. if not peripheral.isPresent(reactorSide) then
  438.     print("Reactor removed!")
  439. elseif msg:find("emergency") then
  440.     return
  441. else
  442.     print("An unexpected error has occured!")
  443.     print("The error will be recorded in /reactor-logs")
  444.     print("The monitor will reboot in 5 seconds...")
  445.     print("")
  446.     print("Error message:")
  447.     print(msg)
  448.     if fs.exists("/reactor-logs") then
  449.         local f = io.open("/reactor-logs","a")
  450.         f:write("\n"..msg)
  451.         f:close()
  452.     else
  453.         local f = io.open("/reactor-logs","w")
  454.         f:write("\n"..msg)
  455.         f:close()
  456.     end
  457.     sleep(5)
  458.     shell.run(shell.getRunningProgram())
  459. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement