Advertisement
1lann

reactor 1.5

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