Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- local reactor = peripheral.wrap("BigReactors-Reactor_0")
- local monitor = peripheral.wrap("monitor_0")
- rednet.open("top")
- controllers = {}
- controllers[1] = true -- Allow computer ID#1 to access reactor control
- local target_power = 5000 -- RF/Tick
- local control_rod_level = 50
- function clamp(val, min, max)
- if val > max then
- return max
- elseif val < min then
- return min
- else
- return val
- end
- end
- function drawBar(x, y, size, perc)
- local bgColor = monitor.getBackgroundColor()
- local ox, oy = monitor.getCursorPos()
- monitor.setCursorPos(x, y)
- monitor.setBackgroundColor(colors.green)
- local percGreen = clamp(math.floor(perc * size), 0, size)
- local percGray = clamp(size - percGreen, 0, size - percGreen)
- if percGray < 0 then
- percGray = 0
- end
- for i = percGreen,1,-1 do
- monitor.write(" ")
- end
- monitor.setBackgroundColor(colors.lightGray)
- for i = percGray,1,-1 do
- monitor.write(" ")
- end
- monitor.setBackgroundColor(bgColor)
- monitor.setCursorPos(ox, oy)
- end
- function getControlRodDiff(RFDiff)
- if RFDiff > 10000 then
- return 5
- elseif RFDiff > 5000 then
- return 3
- elseif RFDiff > 1000 then
- return 1
- elseif RFDiff > 500 then
- return 0.5
- elseif RFDiff > 100 then
- return 0.1
- else
- return 0.05
- end
- end
- function formatRF(rf)
- if rf >= 1000000 then
- return round(rf/1000000, 2) .. " MiRF"
- elseif rf >= 1000 then
- return round(rf/1000, 2) .. " KiRF"
- else
- return math.floor(rf) .. " RF"
- end
- end
- function round(num, numDecimalPlaces)
- local mult = 10^(numDecimalPlaces or 0)
- return math.floor(num * mult + 0.5) / mult
- end
- function drawBoxWithCenteredText(x,y,w,h,text,color)
- local ox,oy = monitor.getCursorPos()
- local bgColor = monitor.getBackgroundColor()
- monitor.setBackgroundColor(color)
- for cy=1,h,1 do
- for cx=1,w,1 do
- monitor.setCursorPos(x+cx,y+cy)
- monitor.write(" ")
- end
- end
- local cx = math.floor(w / 2 + x - string.len(text) / 2 + 1)
- local cy = math.floor(h / 2 + y + 1)
- monitor.setCursorPos(cx, cy)
- monitor.write(text)
- monitor.setBackgroundColor(bgColor)
- monitor.setCursorPos(ox, oy)
- end
- monitor.setBackgroundColor(colors.black)
- monitor.clear()
- local mw, mh = monitor.getSize()
- local reactor_enabled = false
- local buttons = {}
- function renderButtons()
- for i = 1, #buttons do
- local button = buttons[i]
- if not reactor_enabled then
- if button.drod then
- drawBoxWithCenteredText(button.x,button.y,button.w,button.h,button.text,button.color)
- end
- else
- drawBoxWithCenteredText(button.x,button.y,button.w,button.h,button.text,button.color)
- end
- end
- end
- function inBounds(n, min, max)
- return n <= max and n >= min
- end
- function addButton(x,y,w,h,text,color,doRenderOnDisable, executor)
- local button = {
- x = x,
- y = y,
- w = w,
- h = h,
- text = text,
- color = color,
- drod = doRenderOnDisable,
- executor = executor
- }
- buttons[#buttons+1] = button
- end
- function startReactor(btn)
- monitor.clear()
- reactor_enabled = true
- end
- function stopReactor(btn)
- monitor.clear()
- reactor_enabled = false
- end
- function changeTargetPower(btn)
- local num = btn.text:sub(2)
- num = tonumber(num)
- if btn.color == colours.red then
- num = num * -1
- end
- target_power = target_power + num
- end
- addButton(2,mh - 8,15,5,"SHUT DOWN",colours.red, true, stopReactor)
- addButton(19,mh - 8,15,5,"START",colours.green, true, startReactor)
- addButton(2, 9, 7, 3, "-10", colours.red, false, changeTargetPower)
- addButton(11, 9, 7, 3, "-100", colours.red, false, changeTargetPower)
- addButton(20, 9, 7, 3, "-1000", colours.red, false, changeTargetPower)
- addButton(29, 9, 7, 3, "+1000", colours.green, false, changeTargetPower)
- addButton(38, 9, 7, 3, "+100", colours.green, false, changeTargetPower)
- addButton(47, 9, 7, 3, "+10", colours.green, false, changeTargetPower)
- local cur_power_gen = 0
- function controlReactor()
- while true do
- cur_power_gen = reactor.getEnergyProducedLastTick()
- reactor.setActive(reactor_enabled)
- if cur_power_gen ~= 0 and reactor_enabled then
- local diff = getControlRodDiff(math.abs(cur_power_gen - target_power))
- if cur_power_gen > target_power then
- control_rod_level = clamp(control_rod_level + diff, 0, 100)
- elseif cur_power_gen < target_power then
- control_rod_level = clamp(control_rod_level - diff, 0, 100)
- end
- reactor.setAllControlRodLevels(control_rod_level)
- monitor.setCursorPos(2,2)
- monitor.write("Control Rod Level: ")
- drawBar(22,2,40,control_rod_level/100)
- monitor.setCursorPos(22,3)
- monitor.write(math.floor(control_rod_level) .. "\% ")
- monitor.setCursorPos(2,5)
- monitor.write("Power Generation: ")
- drawBar(22,5,40,cur_power_gen/target_power)
- monitor.setCursorPos(22,6)
- monitor.write(formatRF(cur_power_gen) .. "/t ")
- monitor.setCursorPos(2,8)
- monitor.write("Target power generation: " .. formatRF(target_power) .. "/t")
- end
- if not reactor_enabled then
- monitor.setCursorPos(2,2)
- monitor.write("Reactor is offline")
- end
- renderButtons()
- sleep(0.1)
- end
- end
- function pullEvents()
- while true do
- event, side, x, y = os.pullEvent("monitor_touch")
- for i=1, #buttons do
- local button = buttons[i]
- if inBounds(x, button.x, button.x + button.w) and inBounds(y, button.y, button.y + button.h) then
- button.executor(button)
- break
- end
- end
- end
- end
- function waitForRednetCommand()
- while true do
- local senderId, command, protocol = rednet.receive("reactor_control")
- command = textutils.unserialize(command)
- if controllers[senderId] ~= nil and controllers[senderId] then
- print("Received rednet command from " .. senderId)
- print(command)
- local reactorStatus = {
- control_rod_level = control_rod_level,
- cur_power_gen = cur_power_gen,
- target_power = target_power,
- reactor_enabled = reactor_enabled,
- command_executed = false
- }
- for i=1, #buttons do
- local button = buttons[i]
- if command.button == button.text then
- button.executor(button)
- reactorStatus.command_executed = true
- break
- end
- end
- rednet.send(senderId, textutils.serialize(reactorStatus), "reactor_response")
- end
- end
- end
- parallel.waitForAny(pullEvents, controlReactor, waitForRednetCommand)
Add Comment
Please, Sign In to add comment