monitor = peripheral.wrap("top")
term.redirect(monitor)
term.clear()
Display = {}
Display.__index = Display
function Display.create()
local display = {}
setmetatable(display, Display)
display.indent_level = 0
display.indent_size = 2
display.margin_size = 1
display.current_line = 1
display.term_width, display.term_height = term.getSize()
return display
end
function Display:GetIndentPosition()
return (self.indent_size * self.indent_level) + self.margin_size
end
function Display:DrawBorder()
for i = 1, self.term_height do
term.setCursorPos(1, i)
term.write("|")
term.setCursorPos(self.term_width, i)
term.write("|")
end
local current_position = self.current_line
self:SetLine(1)
self:DrawSeperator()
self:SetLine(self.term_height)
self:DrawSeperator()
self:SetLine(current_position)
end
function Display:DrawAlignedText(text, alignment)
if alignment == "left" then
term.setCursorPos(self:GetIndentPosition(), self.current_line)
elseif alignment == "center" then
term.setCursorPos((self.term_width/2) - (string.len(text)/2), self.current_line)
elseif alignment == "right" then
term.setCursorPos((self.term_width - self:GetIndentPosition()) - (string.len(text)), self.current_line)
end
term.write(text)
end
function Display:DrawSeperator(text)
term.setCursorPos(self:GetIndentPosition(), self.current_line)
if self.indent_level == 0 then
term.write("+")
term.write(string.rep("-", self.term_width-2))
term.write("+")
else
term.setCursorPos(self:GetIndentPosition(), self.current_line)
term.write(string.rep("-", self.term_width-(self:GetIndentPosition()*2)+1))
end
if text ~= nil then
term.setCursorPos(7 + self:GetIndentPosition(), self.current_line)
term.write(text)
end
self:NextLine()
end
function Display:ShorthandNumber(number)
if number >= 1000000 then
return math.floor(number / 1000000) .. "M";
elseif number > 1000 then
return math.floor(number / 1000) .. "K";
else
return number
end
end
function Display:CalculatePercent(current_value, max_value)
if current_value == 0 then
return 0
else
return (current_value / max_value)
end
end
function Display:DrawProgressBar(current_value, max_value, start_pos, end_pos)
local progress = self:CalculatePercent(current_value, max_value)
local bar_length = end_pos - start_pos - 2 -- -2 is for the start and end markers of the bar
local progress_length = math.ceil(bar_length * progress)
local no_progress_length = bar_length - progress_length
term.setCursorPos(start_pos, self.current_line)
term.write("[")
term.write(string.rep("=", progress_length))
term.write(string.rep(".", no_progress_length))
term.write("]")
end
function Display:DrawDecoratedProgressBar(current_value, max_value, title, decoration)
local start_pos = self:GetIndentPosition()
local end_pos = self.term_width - self:GetIndentPosition()
local progress = self:CalculatePercent(current_value, max_value)
-- Figure out title positioning
if title then
start_pos = start_pos + string.len(title) + 1
self:DrawAlignedText(title, "left")
end
-- Figure out decoration positioning
if decoration == "percentage" then
local percentage = math.ceil(progress * 100) .. "%"
end_pos = end_pos - 5
self:DrawAlignedText(percentage, "right")
elseif decoration == "amount" then
local output = "(" .. current_value .. "/" .. max_value .. ")"
end_pos = end_pos - string.len(output) - 1
term.setCursorPos(end_pos + 1, self.current_line)
term.write(output)
elseif decoration == "amount_rounded" then
local output = "(" .. self:ShorthandNumber(current_value) .. "/" .. self:ShorthandNumber(max_value) .. ")"
end_pos = end_pos - string.len(output) - 1
term.setCursorPos(end_pos + 1, self.current_line)
term.write(output)
end
self:DrawProgressBar(current_value, max_value, start_pos, end_pos)
self:NextLine()
end
function Display:DrawProgressBlock(title, current_value, max_value)
local start_pos = self:GetIndentPosition()
local end_pos = self.term_width - self:GetIndentPosition()
local amount_data = "(" .. self:ShorthandNumber(current_value) .. "/" .. self:ShorthandNumber(max_value) .. ")"
local progress = self:CalculatePercent(current_value, max_value)
self:DrawAlignedText(title, "left")
self:DrawAlignedText(amount_data, "right")
self:NextLine()
self:DrawDecoratedProgressBar(current_value, max_value, nil, "percentage")
end
function Display:DrawBoolean(trigger, title, on_text, off_text)
local word = off_text
if trigger then
word = on_text
end
self:DrawAlignedText(title, "left")
self:DrawAlignedText(word, "right")
self:NextLine()
end
function Display:Indent()
self.indent_level = self.indent_level + 1
end
function Display:Unindent()
self.indent_level = self.indent_level - 1
end
function Display:NextLine(amount)
if amount ~= nil then
self.current_line = self.current_line + amount
else
self.current_line = self.current_line + 1
end
end
function Display:PreviousLine(amount)
if amount ~= nil then
self.current_line = self.current_line - amount
else
self.current_line = self.current_line - 1
end
end
function Display:SetLine(line)
self.current_line = line
end
-- Configuration setup
header_text = "Nuclear Status & Control System"
reactor_state_side = "left"
-- Display Setup
display = Display.create()
display:DrawBorder()
-- Draw the header
display:DrawSeperator()
display:DrawAlignedText(header_text, "center")
display:NextLine()
display:DrawSeperator()
-- Load the status data
reactor_colours = rs.getBundledInput(reactor_state_side)
reactor_state = not colours.test(reactor_colours, colours.red)
coolant_state = not colours.test(reactor_colours, colours.blue)
uranium_state = not colours.test(reactor_colours, colours.orange)
-- Set up the status display
display:NextLine()
display:Indent()
display:DrawSeperator("Reactor Status")
display:Indent()
display:DrawBoolean(reactor_state, "Core Fusion System", "On", "Off")
display:DrawBoolean(coolant_state, "Coolant Injection System", "Injecting", "Off")
display:DrawBoolean(uranium_state, "Uranium Injection System", "Injecting", "Off")
display:Unindent()
-- Set up the power displays
display:NextLine()
display:DrawSeperator("Power Status")
display:Indent()
display:DrawProgressBlock("Total Power", 23000000, 160000000)
display:NextLine()
display:DrawDecoratedProgressBar(20000000, 40000000, "Store 1", "percentage")
display:DrawDecoratedProgressBar(1000000, 40000000, "Store 2", "percentage")
display:DrawDecoratedProgressBar(2000000, 40000000, "Store 3", "percentage")
display:DrawDecoratedProgressBar(0, 40000000, "Store 4", "percentage")
term.restore()