Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- function PeriphSearch(type)
- local names = peripheral.getNames()
- for _, name in pairs(names) do
- if peripheral.getType(name) == type then
- return peripheral.wrap(name)
- end
- end
- return nil
- end
- ---@diagnostic disable: undefined-global
- -- Peripherals
- local monitor = PeriphSearch("monitor")
- local reactor = peripheral.wrap("back")
- local output_gate = peripheral.wrap("right")
- local input_gate = peripheral.wrap("flux_gate_0")
- -- Important variables
- local temperature
- local fuelAmmountLeft
- local energySaturation
- local fieldStrength
- local status
- local generationRate
- local autoControl
- local fieldDrainRate
- local fuelConversionRate
- local tempChange = 0 -- It has to be initialized
- local emergencyCharge = false
- local currentAction
- -- safety / autocontrol variables (adjustable however you like)
- local maxSafeTemperature = 8000 -- Maximum safe temperature in Celsius
- local minFieldStrength = 0.3 -- Minimum field strength to trigger input increase
- local minEnergySaturation = 0.075 -- Minimum energy saturation to trigger input increase
- local minFuelAmmount = 0.1 -- Mininum ammount of fuel required to operate
- local maxTempChange = 250 --Maximum change of temperature per second (negative means temp is falling per second)
- --startup calls
- if monitor == nil then error("No Monitor found!") end
- if reactor == nil then error("Invalid reactor setup!") end
- if output_gate == nil then error("No power output found!") end
- if input_gate == nil then error("No power input found!") end
- input_gate.setOverrideEnabled(true)
- output_gate.setOverrideEnabled(true)
- term.redirect(monitor)
- monitor.clear()
- monitor.setCursorPos(1, 1)
- reactor.setFailSafe(true)
- -- Other Variables
- local output_rate = 500000
- local input_rate = 300000
- local bar_length = 25
- local tempColor = colors.green
- local autoColor = colors.red
- -- Startup checks
- local x_size, y_size = monitor.getSize()
- if x_size ~= 29 or y_size ~= 19 then
- error("Invalid screen size (3x3 required)")
- end
- function DrawText(x, y, text, textColor)
- monitor.setCursorPos(x, y)
- monitor.setTextColor(textColor)
- monitor.write(text)
- end
- function DrawButtons(y)
- -- 2-4 = -1000, 6-9 = -10000, 10-12,8 = -100000
- -- 17-19 = +1000, 21-23 = +10000, 25-27 = +100000
- if autoControl then return end
- DrawText(2, y, "<<<", colors.white)
- DrawText(6, y, "<< ", colors.white)
- DrawText(10, y, " < ", colors.white)
- DrawText(17, y, " > ", colors.white)
- DrawText(21, y, " >>", colors.white)
- DrawText(25, y, ">>>", colors.white)
- end
- function Buttons()
- while true do
- local _, _, xPos, yPos = os.pullEvent("monitor_touch")
- -- input controls
- if yPos == 7 and autoControl ~= true then
- if xPos >= 2 and xPos <= 4 then
- output_rate = output_rate - 100000
- if output_rate < 0 then output_rate = 0 end
- elseif xPos >= 6 and xPos <= 8 then
- output_rate = output_rate - 10000
- if output_rate < 0 then output_rate = 0 end
- elseif xPos >= 10 and xPos <= 12 then
- output_rate = output_rate - 1000
- if output_rate < 0 then output_rate = 0 end
- elseif xPos >= 17 and xPos <= 19 then
- output_rate = output_rate + 1000
- if output_rate < 0 then output_rate = 0 end
- elseif xPos >= 21 and xPos <= 23 then
- output_rate = output_rate + 10000
- if output_rate < 0 then output_rate = 0 end
- elseif xPos >= 25 and xPos <= 27 then
- output_rate = output_rate + 100000
- if output_rate < 0 then output_rate = 0 end
- end
- elseif yPos == 10 and autoControl ~= true then
- if xPos >= 2 and xPos <= 4 then
- input_rate = input_rate - 100000
- if input_rate < 0 then input_rate = 0 end
- elseif xPos >= 6 and xPos <= 8 then
- input_rate = input_rate - 10000
- if input_rate < 0 then input_rate = 0 end
- elseif xPos >= 10 and xPos <= 12 then
- input_rate = input_rate - 1000
- if input_rate < 0 then input_rate = 0 end
- elseif xPos >= 17 and xPos <= 19 then
- input_rate = input_rate + 1000
- if input_rate < 0 then input_rate = 0 end
- elseif xPos >= 21 and xPos <= 23 then
- input_rate = input_rate + 10000
- if input_rate < 0 then input_rate = 0 end
- elseif xPos >= 25 and xPos <= 27 then
- input_rate = input_rate + 100000
- if input_rate < 0 then input_rate = 0 end
- end
- -- startup control
- elseif yPos == 18 then
- if xPos >= 20 and status == "cold" or status == "cooling" then
- reactor.chargeReactor()
- elseif xPos > 20 and status == "warming_up" then
- reactor.stopReactor()
- elseif xPos > 2 and xPos < 10 and status == "warming_up" and temperature >= 2000 and fuelAmmountLeft > minFuelAmmount and fieldStrength > minFieldStrength then
- reactor.activateReactor()
- elseif xPos > 20 and status == "running" then
- reactor.stopReactor()
- end
- -- auto control
- elseif yPos == 5 then
- if xPos > 19 and xPos < 21 then
- if autoControl == true then
- autoControl = false
- else
- autoControl = true
- end
- end
- -- exit
- elseif xPos > 13 and xPos < 17 and yPos == 1 and status ~= "running" then
- monitor.clear()
- return
- end
- end
- end
- function Render()
- while true do
- -- Reactor Variables
- local ri = reactor.getReactorInfo()
- -- values in % (for example energySaturation 0 - 1)
- temperature = ri.temperature
- fuelAmmountLeft = (ri.maxFuelConversion - ri.fuelConversion) / ri.maxFuelConversion
- energySaturation = ri.energySaturation / ri.maxEnergySaturation
- fieldStrength = ri.fieldStrength / ri.maxFieldStrength
- status = ri.status
- generationRate = ri.generationRate
- fieldDrainRate = ri.fieldDrainRate
- fuelConversionRate = ri.fuelConversionRate
- -- I figured this factor out by just abit of testing, may be unsafe
- -- Calculates an output based off of some temperature value you give beforehand (in this case maxTemp - 500 so 7500°C)
- output_gate.setFlowOverride(output_rate)
- input_gate.setFlowOverride(input_rate)
- monitor.clear()
- monitor.setBackgroundColor(colors.black)
- -- Only allow exit when reactor is not running
- if status ~= "running" then
- DrawText(14, 1, "Exit", colors.red)
- end
- -- Status of reactor draw
- DrawText(2, 2, "Status:", colors.white)
- if status == "cold" then
- DrawText(20, 2, "cold", colors.red)
- elseif status == "warming_up" then
- DrawText(20, 2, "Charging", colors.orange)
- elseif status == "running" then
- DrawText(20, 2, "Active", colors.green)
- elseif status == "stopping" then
- DrawText(20, 2, "Stopping", colors.orange)
- end
- DrawText(2, 3, "Temperature:", colors.white)
- DrawText(20, 3, tostring(temperature).."°C", tempColor)
- DrawText(2, 4, "Generation:", colors.white)
- DrawText(20, 4, tostring(generationRate), colors.purple)
- DrawText(2, 5, "Autocontrol?: ", colors.white)
- DrawText(20, 5, "X", autoColor)
- if autoControl == true then
- DrawText(2, 7, "Output: ", colors.white)
- DrawText(20, 7, tostring(output_rate), colors.red)
- DrawButtons(7)
- DrawText(2, 8, "Input:", colors.white)
- DrawText(20, 8, tostring(input_rate), colors.green)
- DrawButtons(10)
- else
- DrawText(2, 6, "Output: ", colors.white)
- DrawText(20, 6, tostring(output_rate), colors.red)
- DrawButtons(7)
- DrawText(2, 9, "Input:", colors.white)
- DrawText(20, 9, tostring(input_rate), colors.green)
- DrawButtons(10)
- end
- DrawText(2, 12, "Energy Saturation:", colors.white)
- DrawText(25, 12, tostring(energySaturation*100).."%", colors.white)
- monitor.setBackgroundColor(colors.blue)
- paintutils.drawFilledBox(2, 13, 2 + bar_length * energySaturation, 13, colors.blue)
- monitor.setBackgroundColor(colors.black)
- DrawText(2, 15, "Field Strength:", colors.white)
- DrawText(25, 15, tostring(fieldStrength*100).."%", colors.white)
- monitor.setBackgroundColor(colors.green)
- paintutils.drawFilledBox(2, 16, 2 + bar_length * fieldStrength, 16, colors.green)
- monitor.setBackgroundColor(colors.black)
- DrawText(7, 19, currentAction, colors.red)
- -- Button draw on different states
- if status == "running" then
- DrawText(23, 18, "Stop", colors.red)
- elseif status == "warming_up" then
- if temperature >= 2000 and fuelAmmountLeft > minFuelAmmount and fieldStrength > minFieldStrength then
- DrawText(2, 18, "Activate", colors.green)
- end
- DrawText(23, 18, "Stop", colors.red)
- elseif status == "cold" or status == "cooling" then
- DrawText(23, 18, "Warm up", colors.orange)
- end
- -- auto control
- if autoControl == true then
- -- auto control logic
- -- Adjust input rate based on field strength
- input_rate = 2 * fieldDrainRate
- -- Adjust output rate based on temperature and fuel conversion rate
- -- temp / maxTemp to the power of -1 will result in higher value the furhter the temp is away form the max temp
- output_rate = math.ceil(((((maxSafeTemperature) * 450 ) / 7) + ((1 / (fuelConversionRate)) * 15000000)))
- end
- if autoControl then
- autoColor = colors.green
- else autoColor = colors.red
- end
- -- Temp color
- if temperature < 2500 then
- tempColor = colors.blue
- elseif temperature > 4000 and temperature < 6000 then
- tempColor = colors.yellow
- elseif temperature > 6000 and temperature < 7000 then
- tempColor = colors.orange
- elseif temperature > 7500 then
- tempColor = colors.red
- end
- -- Safety checks:
- if emergencyCharge == true then
- input_rate = 3 * fieldDrainRate
- output_rate = 0
- reactor.stopReactor()
- currentAction = "Emergency shutdown!"
- end
- --If temperature rises way too much (250°C per second, defined in the safety variables) then shutdown
- if tempChange >= maxTempChange then
- emergencyCharge = true
- end
- if temperature >= maxSafeTemperature then
- emergencyCharge = true
- end
- if energySaturation < minEnergySaturation then
- emergencyCharge = true
- end
- if fieldStrength < minFieldStrength and status == "running" then
- emergencyCharge = true
- end
- if fuelAmmountLeft < minFuelAmmount and status == "running" then
- reactor.stopReactor()
- output_rate = 0
- input_rate = 300000
- end
- if temperature < 2000 and status ~= "running" then
- emergencyCharge = false
- input_rate = 300000
- output_rate = 500000
- currentAction = ""
- end
- sleep(0.1)
- end
- end
- function CalcTempChange()
- while true do
- -- Temp before 1 second passes
- -- Basically calculates temperature change in 1 second
- local curTemp = temperature
- sleep(1)
- -- calculated difference
- tempChange = math.ceil(temperature - curTemp)
- end
- end
- parallel.waitForAny(Buttons, Render, CalcTempChange)
- -- Cleanup
- input_gate.setOverrideEnabled(false)
- output_gate.setOverrideEnabled(false)
- --TODO: Seperate autocontrol
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement