Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- Nuclear Reactor Monitor Panel v1.5.1 Beta. By: 1lann. 2015
- -- User Configuration:
- -- Valid sides: top bottom left right front back
- -- Sides are from your perspective, assuming you are facing the computer's face.
- local reactorSide = "back"
- local alarmSide = "top"
- -- Side for turning off reactor on redstone input
- local controlSide = "front"
- local alarmOnReplace = true
- local maxThreshold = 7000
- local cooldownTemp = 5000
- local updateRate = 0.5 -- In seconds
- ------------------------------------
- local reactor = peripheral.wrap(reactorSide)
- if not reactor.getMaxHeat then
- print("Could not find reactor!")
- error()
- end
- -- Basic Reactor Monitoring by: 1lann
- local wid,hei = term.getSize()
- local function centerPrint(text)
- local x,y = term.getCursorPos()
- term.setCursorPos(math.ceil((wid/2)-(#text/2)),y)
- print(text)
- end
- local function getPercent(fraction)
- return math.ceil(fraction*100-0.5)
- end
- local function printStatus(state,text,color)
- term.setCursorPos(2,3)
- term.setBackgroundColor(colors.white)
- term.setTextColor(colors.gray)
- write("State: ")
- if state then
- term.setTextColor(colors.lime)
- write("On ")
- else
- term.setTextColor(colors.red)
- write("Off")
- end
- term.setTextColor(colors.gray)
- term.setCursorPos(2,4)
- write("Remarks: ")
- term.setTextColor(color)
- write(text..string.rep(" ",wid-#text-5))
- end
- local function emergency()
- local allSlots = reactor.getAllStacks()
- for k,v in pairs(allSlots) do
- item = v.all()
- if item["name"]:lower():find("uranium") or item["name"]:lower():find("mox") then
- pcall(function() reactor.destroyStack(k) end)
- end
- end
- term.setBackgroundColor(colors.red)
- term.setTextColor(colors.yellow)
- term.clear()
- term.setCursorPos(1,4)
- centerPrint("-- EMERGENCY NOTICE --")
- centerPrint("The system has just stopped a")
- centerPrint("reactor explosion due to the reactor")
- centerPrint("being out of the system's control.")
- centerPrint("The catastrophe was stopped by")
- centerPrint("destroying all of the Uranium in")
- centerPrint("the reactor.")
- print("")
- centerPrint("Please reset the reactor and system")
- centerPrint("Press any key to continue...")
- os.pullEvent("key")
- term.setTextColor(colors.white)
- term.setBackgroundColor(colors.black)
- term.clear()
- term.setCursorPos(1,1)
- sleep(0.2)
- error("emergency")
- end
- term.setBackgroundColor(colors.white)
- term.clear()
- term.setCursorPos(2,1)
- term.setBackgroundColor(colors.lightGray)
- term.clearLine()
- term.setTextColor(colors.white)
- write("Nuclear Reactor Panel (By: 1lann)")
- printStatus(false,"Initializing",colors.gray)
- term.setTextColor(colors.gray)
- term.setCursorPos(2,6)
- print("Current Heat Level: ")
- term.setCursorPos(2,7)
- write("[")
- term.setCursorPos(wid-1,7)
- write("]")
- term.setCursorPos(2,9)
- print("Current Output: ")
- term.setCursorPos(2,10)
- print("Average Output: ")
- term.setCursorPos(2,11)
- print("Coolant Durability: Calculating...")
- term.setCursorPos(2,12)
- write("[")
- term.setCursorPos(wid-1,12)
- write("]")
- term.setCursorPos(2,13)
- print("Time til empty: Calculating...")
- local function heatLevel()
- local heat = reactor.getHeat()
- local function getColor(heat)
- local percent = heat/maxThreshold
- if percent >= 0.9 then
- return colors.red
- elseif percent >= 0.7 then
- return colors.orange
- elseif percent >= 0.4 then
- return colors.yellow
- else
- return colors.lime
- end
- end
- term.setBackgroundColor(colors.white)
- term.setTextColor(colors.gray)
- term.setCursorPos(2,6)
- write("Current Heat Level: ")
- term.setTextColor(getColor(heat))
- write(tostring(getPercent(heat/maxThreshold)).."% ("..tostring(heat).."/"..tostring(maxThreshold)..") ")
- local total = wid-4
- local bar = math.ceil((heat/maxThreshold)*total)
- if bar > total then bar = total end
- term.setCursorPos(3,7)
- term.setBackgroundColor(colors.white)
- term.write(string.rep(" ",total))
- term.setCursorPos(3,7)
- term.setBackgroundColor(getColor(heat))
- term.write(string.rep(" ",bar))
- end
- local previousOutputs = {}
- local function calculateOutput()
- term.setBackgroundColor(colors.white)
- term.setTextColor(colors.gray)
- local output = math.ceil(reactor.getEUOutput()*50-0.5)/10
- term.setCursorPos(18,9)
- write(output .. " EU/t ")
- if #previousOutputs > 1000 then
- table.remove(previousOutputs,#previousOutputs)
- end
- table.insert(previousOutputs,output)
- local total = 0
- for k,v in pairs(previousOutputs) do
- total = total+v
- end
- term.setCursorPos(18,10)
- write(tostring(math.ceil((total/#previousOutputs)*10-0.5)/10) .. " EU/t ")
- end
- local manual = false
- local damage = false
- local firstDamage = "first-time"
- local cooldownCheck = false
- local cooldownClock = false
- local previousDamages = {}
- local function damageLevel()
- local highestDamage = -1
- local allSlots = reactor.getAllStacks()
- for k,v in pairs(allSlots) do
- item = v.all()
- if not(item["name"]:lower():find("uranium") or item["name"]:lower():find("mox")) then
- local test = item["dmg"]
- if test > highestDamage then highestDamage = test end
- end
- end
- if highestDamage < 0 then
- highestDamage = 10000
- end
- if #previousDamages > 1000 then
- table.remove(previousDamages,#previousDamages)
- end
- table.insert(previousDamages,{highestDamage,os.clock()})
- local function getColor(dmg)
- local percent = dmg/10000
- if percent >= 0.9 then
- return colors.red
- elseif percent >= 0.7 then
- return colors.orange
- elseif percent >= 0.4 then
- return colors.yellow
- else
- return colors.lime
- end
- end
- term.setCursorPos(22,11)
- term.setBackgroundColor(colors.white)
- term.setTextColor(getColor(highestDamage))
- write(getPercent((10000-highestDamage)/10000).."% ")
- local total = wid-4
- local bar = math.ceil(((10000-highestDamage)/10000)*total)
- term.setCursorPos(3,12)
- term.setBackgroundColor(colors.white)
- term.write(string.rep(" ",total))
- term.setCursorPos(3,12)
- term.setBackgroundColor(getColor(highestDamage))
- term.write(string.rep(" ",bar))
- local average = 0
- for i = 1, #previousDamages-1 do
- average = average+(previousDamages[i][1]-previousDamages[i+1][1])/(previousDamages[i][2]-previousDamages[i+1][2])
- end
- local remainder = (10000-highestDamage)/(average/(#previousDamages-1))
- term.setBackgroundColor(colors.white)
- term.setTextColor(colors.gray)
- term.setCursorPos(18,13)
- term.write(tostring(math.ceil(remainder-0.5)).." seconds ")
- os.queueEvent("reactor-durability")
- if getPercent((10000-highestDamage)/10000) < 5 then
- damage = true
- else
- damage = false
- end
- end
- local function cooling()
- if reactor.getHeat() <= cooldownTemp then
- rs.setOutput(reactorSide,true)
- rs.setOutput(alarmSide,false)
- cooldownCheck = false
- return "heat"
- end
- rs.setOutput(reactorSide,false)
- if reactor.getHeat() >= reactor.getMaxHeat()-1000 then
- emergency()
- elseif reactor.getHeat() >= maxThreshold then
- printStatus(false,"DANGER: REACTOR OVERHEATING!",colors.red)
- rs.setOutput(alarmSide,true)
- else
- if cooldownCheck then
- if cooldownClock < os.clock() then
- if reactor.getHeat() >= cooldownCheck then
- printStatus(false,"DANGER: REACTOR NOT COOLING!",colors.red)
- rs.setOutput(alarmSide,true)
- elseif reactor.isActive() then
- printStatus(false,"DANGER: REACTOR SABOTAGED!",colors.red)
- rs.setOutput(alarmSide,true)
- else
- rs.setOutput(alarmSide,false)
- printStatus(false,"Cooldown",colors.lightBlue)
- end
- elseif reactor.isActive() then
- printStatus(false,"DANGER: REACTOR SABOTAGED!",colors.red)
- rs.setOutput(alarmSide,true)
- else
- rs.setOutput(alarmSide,false)
- printStatus(false,"Cooldown",colors.lightBlue)
- end
- else
- cooldownCheck = reactor.getHeat()
- cooldownClock = os.clock()+10
- rs.setOutput(alarmSide,false)
- printStatus(false,"Cooldown",colors.lightBlue)
- end
- end
- end
- local function heating()
- if reactor.getHeat() >= (maxThreshold*0.9) then
- outputCheck = false
- rs.setOutput(reactorSide,false)
- return "cool"
- end
- rs.setOutput(reactorSide,true)
- if outputCheck then
- if reactor.getEUOutput() < 1 then
- if alarmOnReplace then
- rs.setOutput(alarmSide,true)
- else
- rs.setOutput(alarmSide,false)
- end
- printStatus(true,"No power being generated!",colors.yellow)
- else
- rs.setOutput(alarmSide,false)
- printStatus(true,"Normal Operation",colors.lime)
- end
- else
- outputCheck = true
- rs.setOutput(alarmSide,false)
- printStatus(true,"Normal Operation",colors.lime)
- end
- end
- local function main()
- local state = "heating"
- while true do
- sleep(updateRate/4)
- heatLevel()
- sleep(updateRate/4)
- calculateOutput()
- sleep(updateRate/4)
- damageLevel()
- sleep(updateRate/4)
- if manual then
- rs.setOutput(reactorSide,false)
- rs.setOutput(alarmSide,false)
- if reactor.isActive() then
- printStatus(true,"Manual Control",colors.yellow)
- else
- printStatus(false,"Manual Control",colors.yellow)
- end
- elseif rs.getInput(controlSide) then
- printStatus(false,"Redstone Override",colors.yellow)
- elseif damage then
- rs.setOutput(reactorSide,false)
- if firstDamage then
- if alarmOnReplace then
- rs.setOutput(alarmSide,true)
- printStatus(false,"Replace or remove used parts!",colors.red)
- else
- rs.setOutput(alarmSide,false)
- printStatus(false,"Replace or remove used parts!",colors.red)
- end
- firstDamage = false
- sleep(1)
- else
- if reactor.getHeat() >= reactor.getMaxHeat()-1000 then
- emergency()
- elseif reactor.getHeat() >= maxThreshold then
- printStatus(false,"Replace parts: REACTOR OVERHEATING!",colors.red)
- rs.setOutput(alarmSide,true)
- elseif reactor.isActive() then
- printStatus(false,"Replace parts: REACTOR SABOTAGED!",colors.red)
- rs.setOutput(alarmSide,true)
- elseif alarmOnReplace then
- rs.setOutput(alarmSide,true)
- printStatus(false,"Replace or remove used parts!",colors.red)
- else
- rs.setOutput(alarmSide,false)
- printStatus(false,"Replace or remove used parts!",colors.red)
- end
- end
- else
- if state == "heating" then
- if heating() == "cool" then
- state = "cooling"
- end
- else
- if cooling() == "heat" then
- state = "heating"
- end
- end
- if firstDamage == "first-time" then
- sleep(1)
- previousDamages = {}
- previousOutputs = {}
- firstDamage = true
- end
- end
- end
- end
- local function control()
- local previousTime = nil
- local resetAverages = nil
- local time = nil
- term.setBackgroundColor(colors.lightGray)
- term.setTextColor(colors.white)
- term.setCursorPos(2,15)
- write(" ")
- term.setCursorPos(2,16)
- write(" Manual-mode (Off) ")
- term.setCursorPos(2,17)
- write(" ")
- if fs.exists("/.reactor-manual") then
- term.setCursorPos(2,16)
- write(" Auto-mode (On) ")
- manual = true
- rs.setOutput(reactorSide,false)
- end
- term.setCursorPos(wid-21,15)
- write(" ")
- term.setCursorPos(wid-21,16)
- write(" Reset Averages ")
- term.setCursorPos(wid-21,17)
- write(" ")
- while true do
- local e,t,x,y = os.pullEvent()
- if e == "mouse_click" then
- if (x >= 2) and (x <= 22) and (y >= 15) and (y <= 17) then
- if not manual then
- manual = true
- rs.setOutput(reactorSide,false)
- term.setBackgroundColor(colors.lightGray)
- term.setTextColor(colors.white)
- term.setCursorPos(2,16)
- write(" Auto-mode (On) ")
- local f = io.open("/.reactor-manual","w")
- f:write("\n")
- f:close()
- else
- manual = false
- fs.delete("/.reactor-manual")
- term.setBackgroundColor(colors.lightGray)
- term.setTextColor(colors.white)
- term.setCursorPos(2,16)
- write(" Manual-mode (Off) ")
- end
- elseif (x >= wid-21) and (x <= wid-1) and (y >= 15) and (y <= 17) then
- previousDamages = {}
- previousOutputs = {}
- term.setTextColor(colors.white)
- term.setBackgroundColor(colors.lightGray)
- term.setCursorPos(wid-21,16)
- write(" Averages Reset! ")
- resetAverages = os.startTimer(2)
- end
- elseif e == "timer" then
- if t == resetAverages then
- term.setCursorPos(wid-21,16)
- term.setTextColor(colors.white)
- term.setBackgroundColor(colors.lightGray)
- write(" Reset Averages ")
- end
- end
- end
- end
- local e, msg = pcall(function()parallel.waitForAny(control,main)end)
- term.setBackgroundColor(colors.black)
- term.setTextColor(colors.red)
- term.setCursorPos(1,1)
- term.clear()
- if not peripheral.isPresent(reactorSide) then
- print("Reactor removed!")
- elseif msg:find("emergency") then
- return
- else
- print("An unexpected error has occured!")
- print("The error will be recorded in /reactor-logs")
- print("The monitor will reboot in 5 seconds...")
- print("")
- print("Error message:")
- print(msg)
- if fs.exists("/reactor-logs") then
- local f = io.open("/reactor-logs","a")
- f:write("\n"..msg)
- f:close()
- else
- local f = io.open("/reactor-logs","w")
- f:write("\n"..msg)
- f:close()
- end
- sleep(5)
- shell.run(shell.getRunningProgram())
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement