r = peripheral.wrap("bottom")
m = peripheral.wrap("monitor_0")
term.clear()
m.clear()
local y_padding = 2
local x_padding = 3
local value_align = 25
local width, height = m.getSize()
-- Rainbow colors for border animation
local rainbow_colors = {colors.red, colors.orange, colors.yellow, colors.lime, colors.cyan, colors.blue, colors.purple, colors.magenta}
-- Function to draw progress bar
local function drawProgressBar(x, y, value, min_val, max_val, target, unit, bar_width, force_color, min_indicator)
bar_width = bar_width or 20
local percentage = math.max(0, math.min(100, ((value - min_val) / (max_val - min_val)) * 100))
local filled_chars = math.floor((percentage / 100) * bar_width)
-- Color coding based on proximity to target
local color = colors.red
if force_color then
color = force_color
elseif target then
local target_percentage = ((target - min_val) / (max_val - min_val)) * 100
local diff = math.abs(percentage - target_percentage)
if diff < 10 then
color = colors.lime
elseif diff < 25 then
color = colors.yellow
end
else
-- Default color grading for values without targets
if percentage > 66 then
color = colors.lime
elseif percentage > 33 then
color = colors.yellow
end
end
m.setCursorPos(x, y)
m.setTextColor(colors.gray)
m.write("[")
-- Calculate minimum indicator position if provided
local min_indicator_pos = nil
if min_indicator then
min_indicator_pos = math.floor(((min_indicator - min_val) / (max_val - min_val)) * bar_width)
end
-- Draw filled portion
for i = 1, bar_width do
if min_indicator_pos and i == min_indicator_pos then
m.setTextColor(colors.cyan)
m.write("|")
elseif i <= filled_chars then
m.setTextColor(color)
m.write("=")
else
m.setTextColor(colors.gray)
m.write("-")
end
end
m.setTextColor(colors.gray)
m.write("] ")
m.setTextColor(colors.white)
m.write(string.format("%.2f %s", value, unit))
end
m.setTextScale(1)
m.clear()
-- Phase 2: Moving rainbow border with centered text
local title_lines = {"Lag 4 President", "Draconic Reactor", "Quantum Monitor v1.0", " ~ By THCoder aka David"}
local corner_text = "Kennst du eigentlich Andi? :D"
for frame = 1, 25 do
m.clear()
-- Draw moving rainbow border
local color_offset = frame % #rainbow_colors
-- Top and bottom borders
for x = 1, width do
local color_index = ((x + color_offset - 1) % #rainbow_colors) + 1
m.setTextColor(rainbow_colors[color_index])
m.setCursorPos(x, 1)
m.write("=")
m.setCursorPos(x, height)
m.write("=")
end
-- Left and right borders
for y = 2, height - 1 do
local color_index = ((y + color_offset - 1) % #rainbow_colors) + 1
m.setTextColor(rainbow_colors[color_index])
m.setCursorPos(1, y)
m.write("|")
m.setCursorPos(width, y)
m.write("|")
end
-- Draw centered title text with rainbow colors
local start_y = math.floor((height - #title_lines) / 2)
for i, line in ipairs(title_lines) do
local x_pos = math.floor((width - #line) / 2) + 1
local line_color = rainbow_colors[((i - 1) % #rainbow_colors) + 1]
if frame > i * 3 then
for j = 1, math.min(#line, frame - i * 3) do
m.setTextColor(line_color)
m.setCursorPos(x_pos + j - 1, start_y + i)
m.write(line:sub(j, j))
end
end
end
-- Draw corner text (bottom right)
if frame > 15 then
m.setTextColor(colors.cyan)
m.setCursorPos(width - #corner_text - 2, height - 2)
m.write(corner_text)
end
sleep(0.1)
end
sleep(3)
while true do
-- Get reactor information
local info = r.getReactorInfo()
-- Debug: Print all available info to terminal
term.clear()
term.setCursorPos(1,1)
print("Available reactor data:")
for key, value in pairs(info) do
print(key .. ": " .. tostring(value))
end
-- Clear and prepare monitor
m.clear()
m.setTextScale(1)
-- Header line
m.setCursorPos(x_padding + 8, 1)
m.setTextColor(colors.white)
m.write("* ")
m.setTextColor(colors.red)
m.write("Lag4President")
m.setTextColor(colors.white)
m.write(" - ")
m.setTextColor(colors.purple)
m.write("Draconic Reactor")
m.setTextColor(colors.white)
m.write(" *")
-- Extract data
local status = info["status"]
local temp = info["temperature"]
local energyOut = info["generationRate"] / 1000 -- Convert to kRF/t
local shieldIn = info["fieldDrainRate"] / 1000 -- Convert to kRF/t
local netEnergy = energyOut - shieldIn
local fieldStrength = (info["fieldStrength"] / info["maxFieldStrength"]) * 100
local saturation = (info["energySaturation"] / info["maxEnergySaturation"]) * 100
-- Check for fuel-related data
local fuelConversion = info["fuelConversion"] or 0
local maxFuelConversion = info["maxFuelConversion"] or 1
local fuelConversionRate = info["fuelConversionRate"] or 0
-- Calculate fuel percentage if available
local fuelPercentage = 0
if maxFuelConversion > 0 then
fuelPercentage = (fuelConversion / maxFuelConversion) * 100
end
-- Calculate field percentage for emergency shutdown
local fieldPercent = fieldStrength / 100
local row = y_padding + 1 -- Start below header
-- Status (no progress bar)
m.setCursorPos(x_padding, row)
m.setTextColor(colors.white)
m.write("Reactor Status:")
m.setCursorPos(value_align, row)
if status == "running" or status == "online" then
m.setTextColor(colors.lime)
m.write("Running")
elseif status == "stopping" then
m.setTextColor(colors.red)
m.write("Stopping")
elseif status == "charging" then
m.setTextColor(colors.yellow)
m.write("Charging")
elseif status == "charged" then
m.setTextColor(colors.lime)
m.write("Ready")
elseif status == "offline" then
m.setTextColor(colors.red)
m.write("Offline")
end
row = row + 2
-- Temperature progress bar (0-8000, with minimum indicator at 2000)
m.setCursorPos(x_padding, row)
m.setTextColor(colors.white)
m.write("Temperature:")
drawProgressBar(value_align, row, temp, 0, 8000, 7500, "C", 15, nil, 2000)
row = row + 2
-- Energy Output progress bar with efficiency scaling
-- Draconic reactor efficiency increases with fuel conversion
-- Formula: efficiency = 1 + (fuelPercentage / 100) * 1.5
-- This means at 0% fuel conversion: 1x efficiency
-- At 100% fuel conversion: 2.5x efficiency
local base_output = 4000 -- Base expected output at 0% fuel conversion
local efficiency_multiplier = 1 + (fuelPercentage / 100) * 1.5
local expected_output = base_output * efficiency_multiplier
local max_output = base_output * 2.5 -- Maximum at 100% fuel conversion
m.setCursorPos(x_padding, row)
m.setTextColor(colors.white)
m.write("Energy Output:")
drawProgressBar(value_align, row, energyOut, 0, max_output, expected_output, "kRF/t", 15)
row = row + 2
-- Field Input progress bar (0-2000, target 1400)
m.setCursorPos(x_padding, row)
m.setTextColor(colors.white)
m.write("Field Input:")
drawProgressBar(value_align, row, shieldIn, 0, 2000, 1400, "kRF/t", 15)
row = row + 2
-- Net Energy (just value with color grading)
m.setCursorPos(x_padding, row)
m.setTextColor(colors.white)
m.write("Net Energy:")
m.setCursorPos(value_align, row)
if netEnergy < 0 then
m.setTextColor(colors.red)
elseif netEnergy < 1000 then
m.setTextColor(colors.yellow)
else
m.setTextColor(colors.lime)
end
m.write(string.format("%.2f kRF/t", netEnergy))
row = row + 2
-- Field Strength progress bar (0-100, target 15)
m.setCursorPos(x_padding, row)
m.setTextColor(colors.white)
m.write("Field Strength:")
drawProgressBar(value_align, row, fieldStrength, 0, 100, 25, "%", 15)
row = row + 2
-- Energy Saturation progress bar (0-100, target 15)
m.setCursorPos(x_padding, row)
m.setTextColor(colors.white)
m.write("Energy Saturation:")
drawProgressBar(value_align, row, saturation, 0, 100, 15, "%", 15)
row = row + 2
-- Fuel Conversion progress bar (0-100) - white color
m.setCursorPos(x_padding, row)
m.setTextColor(colors.white)
m.write("Fuel Progress:")
drawProgressBar(value_align, row, fuelPercentage, 0, 100, nil, "%", 15, colors.white)
row = row + 2
-- Fuel Rate progress bar (0-5)
m.setCursorPos(x_padding, row)
m.setTextColor(colors.white)
m.write("Fuel Rate:")
drawProgressBar(value_align, row, fuelConversionRate / 1000, 0, 5, nil, "nb/t", 15)
-- Bottom warning notes
m.setCursorPos(x_padding + 5, height - 3)
m.setTextColor(colors.red)
m.write("NOTE:")
m.setTextColor(colors.orange)
m.write(" NEVER exceed 8000 C temperature!")
m.setCursorPos(x_padding + 11, height - 2)
m.write("NEVER let shield drop below 10%!")
m.setCursorPos(x_padding + 11, height - 1)
m.write("But making it close is quite rewarding :)")
-- Emergency Shutdown
if (status == "online" or status == "running") and (fieldPercent <= 0.1 or (saturation/100) <= 0.1) then
r.stopReactor()
m.clear()
m.setCursorPos(x_padding, y_padding)
m.setTextColor(colors.red)
m.write("EMERGENCY SHUTDOWN")
m.setCursorPos(x_padding, y_padding + 1)
m.write("Critical levels detected")
sleep(2)
end
sleep(0.5)
end