CCCPaste

Draconic Reactor Dashboard (ComputerCraft)

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