Files
Draconic-ComputerCraft-Program/reactor.lua
T
2025-02-28 03:21:28 +00:00

511 lines
15 KiB
Lua

os.loadAPI("lib/f")
os.loadAPI("lib/button")
local targetStrength = 50
local maxTemp = 8000
local safeTemp = 3000
local lowFieldPer = 15
local activateOnCharge = true
local version = 0.3
local autoInputGate = 1
local curInputGate = 222000
local mon, monitor, monX, monY
local reactor
local fluxgate
local inputFluxgate
local ri
local action = "None since reboot"
local actioncolor = colors.gray
local emergencyCharge = false
local emergencyTemp = false
monitor = f.periphSearch("monitor")
-- inputFluxgate = f.periphSearch("flow_gate")
-- fluxgate = f.getPeripheral("flow_gate")
reactor = f.periphSearch("draconic_reactor")
function detectFlowGates()
local gates = {peripheral.find("flow_gate")}
if #gates < 2 then
error("Error: Less than 2 flow gates detected!")
return nil, nil
end
print("Please set input flow gate to **10 RF/t** manually.")
local inputGate, outputGate, inputName, outputName
while not inputGate do
sleep(1) -- Wait before checking again
for _, name in pairs(peripheral.getNames()) do
if peripheral.getType(name) == "flow_gate" then
local gate = peripheral.wrap(name)
local setFlow = gate.getSignalLowFlow()
if setFlow == 10 then
inputGate, inputName = gate, name
print("Detected input gate:", name)
else
outputGate, outputName = gate, name
end
end
end
end
if not outputGate then
print("Error: Could not identify output gate!")
return nil, nil
end
return inputGate, outputGate, inputName, outputName
end
function saveFlowGateNames(inputName, outputName)
local file = fs.open("flowgate_names.txt", "w")
file.writeLine(inputName)
file.writeLine(outputName)
file.close()
print("Saved flow gate names for reboot!")
end
function loadFlowGateNames()
if not fs.exists("flowgate_names.txt") then
print("No saved flow gate names found! Running detection again...")
return nil, nil, nil, nil
end
local file = fs.open("flowgate_names.txt", "r")
local inputName = file.readLine()
local outputName = file.readLine()
file.close()
print("Loaded saved flow gate names:", inputName, outputName)
if peripheral.isPresent(inputName) and peripheral.isPresent(outputName) then
return peripheral.wrap(inputName), peripheral.wrap(outputName), inputName, outputName
else
print("Saved peripherals not found! Running detection again...")
return nil, nil, nil, nil
end
end
function setupFlowGates()
-- Try to load saved names
local inputFluxgate, outputFluxgate, inputName, outputName = loadFlowGateNames()
-- If names don't exist, detect manually
if not inputFluxgate or not outputFluxgate then
inputFluxgate, outputFluxgate, inputName, outputName = detectFlowGates()
if inputFluxgate and outputFluxgate then
saveFlowGateNames(inputName, outputName)
else
error("Flow gate setup failed! Make sure to set the input flow gate to 10 before running the script again!")
return nil, nil
end
end
return inputFluxgate, outputFluxgate
end
inputFluxgate, fluxgate = setupFlowGates()
if monitor == nil then
error("No valid monitor was found")
end
if fluxgate == nil then
error("No valid flow gate was found")
end
if inputFluxgate == nil then
error("No input flow gate was found. Please put the low signal value to 10")
end
if reactor == nil then
error("No reactor was found")
end
monX, monY = monitor.getSize()
mon = {}
mon.monitor, mon.X, mon.Y = monitor, monX, monY
f.firstSet(mon)
function mon.clear()
mon.monitor.setBackgroundColor(colors.black)
mon.monitor.clear()
mon.monitor.setCursorPos(1,1)
button.screen()
end
function save_config()
sw = fs.open("reactorconfig.txt", "w")
sw.writeLine(autoInputGate)
sw.writeLine(curInputGate)
sw.close()
end
function load_config()
sr = fs.open("reactorconfig.txt", "r")
autoInputGate = tonumber(sr.readLine())
curInputGate = tonumber(sr.readLine())
sr.close()
end
if fs.exists("reactorconfig.txt") == false then
save_config()
else
load_config()
end
function reset()
term.clear()
term.setCursorPos(1,1)
end
function reactorStatus(r)
local tbl = {}
if r == "running" then
tbl = {"Online", colors.green}
elseif r == "cold" then
tbl = {"Offline", colors.gray}
elseif r =="warming_up" then
tbl = {"Charging", colors.orange}
elseif r == "cooling" then
tbl = {"Cooling Down", colors.blue}
else
tbl = {"Shutting Down", colors.red}
end
return tbl
end
local lastTerminalValues = {}
function drawTerminalText(x, y, label, newValue)
local key = label -- Use label as key to track changes
-- Only update if the value changed
if lastTerminalValues[key] ~= newValue then
term.setCursorPos(x, y)
term.clearLine() -- Clear only the current line
term.write(label .. ": " .. newValue)
lastTerminalValues[key] = newValue -- Store new value
end
end
function reactorControl()
reset()
while true do
ri = reactor.getReactorInfo()
--reset()
if ri == nil then
error("Reactor not setup correctly")
end
local i = 1
for k, v in pairs(ri) do
drawTerminalText(1, i, k, tostring(v))
i = i + 1
end
i = i + 1
drawTerminalText(1, i, "Output Gate", fluxgate.getSignalLowFlow())
i = i + 1
drawTerminalText(1, i, "Input Gate", inputFluxgate.getSignalLowFlow())
if emergencyCharge == true then
reactor.chargeReactor()
end
if ri.status == "warming_up" then
inputFluxgate.setSignalLowFlow(900000)
emergencyCharge = false
end
if emergencyTemp == true and ri.status == "stopping" and ri.temperature < safeTemp then
reactor.activateReactor()
emergencyTemp = false
end
if ri.status == "warming_up" and activateOnCharge == true then
reactor.activateReactor()
end
if ri.status == "running" then
if autoInputGate == 1 then
fluxval = ri.fieldDrainRate / (1 - (targetStrength/100))
i = i + 1
drawTerminalText(1, i, "Target Gate", fluxval)
inputFluxgate.setSignalLowFlow(fluxval)
else
inputFluxgate.setSignalLowFlow(curInputGate)
end
end
-- Safe guards
local fuelPercent = 100 - math.ceil(ri.fuelConversion / ri.maxFuelConversion * 10000)*.01
local fieldPercent = math.ceil(ri.fieldStrength / ri.maxFieldStrength * 10000)*.01
if fuelPercent <= 10 then
reactor.stopReactor()
actioncolor = colors.red
action = "Fuel is low. Refuel"
ActionMenu()
end
if fieldPercent <= lowFieldPer and ri.status == "running" then
actioncolor = colors.red
action = "Field str < "..lowFieldPer.."%"
ActionMenu()
reactor.stopReactor()
reactor.chargeReactor()
emergencyCharge = true
end
if ri.temperature > maxTemp then
reactor.stopReactor()
actioncolor = colors.red
action = "Reactor overheated"
ActionMenu()
emergencyTemp = true
end
sleep(0.5) -- Prevents excessive CPU usage
end
end
local MenuText = "Loading..."
function clearMenuArea()
-- Ensure we clear enough space for buttons
for i = 26, monY-1 do
f.draw_line(mon, 2, i, monX-2, colors.black)
end
button.clearTable() -- Clear stored button references
f.draw_line(mon, 2, 26, monX-2, colors.gray) -- Redraw top of the menu box
f.draw_line(mon, 2, monY-1, monX-2, colors.gray) -- Redraw bottom border
f.draw_line_y(mon, 2, 26, monY-1, colors.gray) -- Left border
f.draw_line_y(mon, monX-1, 26, monY-1, colors.gray) -- Right border
f.draw_text(mon, 4, 26, " "..MenuText.." ", colors.white, colors.black)
end
function toggleReactor()
ri = reactor.getReactorInfo()
if ri.status == "running" then
reactor.stopReactor()
elseif ri.status == "stopping" then
reactor.activateReactor()
else
reactor.chargeReactor()
end
end
function ActionMenu()
button.setButton("action", action, buttonMain, 2, 23, monX-1, 25, 0, 0, colors.red)
end
function rebootSystem()
os.reboot()
end
function buttonControls()
if currentMenu == "controls" then return end
currentMenu = "controls"
MenuText = "CONTROLS"
clearMenuArea() -- Clear old buttons
local sLength = 6+(string.len("Toggle Reactor")+1)
button.setButton("toggle", "Toggle Reactor", toggleReactor, 6, 28, sLength, 30, 0, 0, colors.blue)
local sLength2 = (sLength+12+(string.len("Reboot"))+1)
button.setButton("reboot", "Reboot", rebootSystem, sLength+12, 28, sLength2, 30, 0, 0, colors.blue)
local sLength3 = 4+(string.len("Back")+1)
button.setButton("back", "Back", buttonMain, 4, 32, sLength3, 34, 0, 0, colors.blue)
button.screen()
end
function changeOutputValue(num, val)
local cFlow = fluxgate.getSignalLowFlow()
if val == 1 then
cFlow = cFlow+num
else
cFlow = cFlow-num
end
fluxgate.setSignalLowFlow(cFlow)
updateReactorInfo()
end
function outputMenu()
if currentMenu == "output" then return end
currentMenu = "output"
MenuText = "OUTPUT"
clearMenuArea() -- Clear old buttons
local sLengthX = monX-3-(string.len(">>>>")+1)
local sLength = sLengthX+string.len(">>>>")+1
button.setButton("+1,000,000", ">>>>", changeOutputValue, sLengthX, 28, sLength, 30, 1000000, 1, colors.blue)
local sLengthX2 = sLengthX-3-string.len(">>>")
local sLength2 = sLengthX2+string.len(">>>")+1
button.setButton("+100,000", ">>>", changeOutputValue, sLengthX2, 28, sLength2, 30, 100000, 1, colors.blue)
local sLengthX3 = sLengthX2-3-string.len(">>")
local sLength3 = sLengthX3+string.len(">>")+1
button.setButton("+10,000", ">>", changeOutputValue, sLengthX3, 28, sLength3, 30, 10000, 1, colors.blue)
local sLengthX4 = sLengthX3-3-string.len(">")
local sLength4 = sLengthX4+string.len(">")+1
button.setButton("+1,000", ">", changeOutputValue, sLengthX4, 28, sLength4, 30, 1000, 1, colors.blue)
local nLength = 4+(string.len("<<<<")+1)
button.setButton("-1,000,000", "<<<<", changeOutputValue, 4, 28, nLength, 30, 1000000, 0, colors.blue)
local nLength2 = nLength+2+(string.len("<<<")+1)
button.setButton("-100,000", "<<<", changeOutputValue, nLength+2, 28, nLength2, 30, 100000, 0, colors.blue)
local nLength3 = nLength2+2+(string.len("<<")+1)
button.setButton("-10,000", "<<", changeOutputValue, nLength2+2, 28, nLength3, 30, 10000, 0, colors.blue)
local nLength4 = nLength3+2+(string.len("<<")+1)
button.setButton("-1,000", "<", changeOutputValue, nLength3+2, 28, nLength4, 30, 1000, 0, colors.blue)
local sLength4 = 4+(string.len("Back")+1)
button.setButton("back", "Back", buttonMain, 4, 32, sLength4, 34, 0, 0, colors.blue)
button.screen()
end
function buttonMain()
if currentMenu == "main" then return end
currentMenu = "main"
MenuText = "MAIN MENU"
clearMenuArea() -- Clear old buttons
local sLength = 4+(string.len("Controls")+1)
button.setButton("controls", "Controls", buttonControls, 4, 28, sLength, 30, 0, 0, colors.blue)
local sLength2 = (sLength+13+(string.len("Output"))+1)
button.setButton("output", "Output", outputMenu, sLength+13, 28, sLength2, 30, 0, 0, colors.blue)
button.screen()
end
local lastValues = {}
function reactorInfoScreen()
mon.clear()
f.draw_text(mon, 2, 38, "Made by: StormFusions v"..version, colors.gray, colors.black)
-- Draw Static UI Elements (Frames, Labels)
f.draw_line(mon, 2, 22, monX-2, colors.gray)
f.draw_line(mon, 2, 2, monX-2, colors.gray)
f.draw_line_y(mon, 2, 2, 22, colors.gray)
f.draw_line_y(mon, monX-1, 2, 22, colors.gray)
f.draw_text(mon, 4, 2, " INFO ", colors.white, colors.black)
f.draw_line(mon, 2, 26, monX-2, colors.gray)
f.draw_line(mon, 2, monY-1, monX-2, colors.gray)
f.draw_line_y(mon, 2, 26, monY-1, colors.gray)
f.draw_line_y(mon, monX-1, 26, monY-1, colors.gray)
f.draw_text(mon, 4, 26, " "..MenuText.." ", colors.white, colors.black)
-- Loop to continuously update screen
while true do
updateReactorInfo()
sleep(1)
end
end
function updateReactorInfo()
ri = reactor.getReactorInfo()
if not ri then return end
-- Update only when values change
drawUpdatedText(4, 4, "Status:", reactorStatus(ri.status)[1], reactorStatus(ri.status)[2])
drawUpdatedText(4, 5, "Generation:", f.format_int(ri.generationRate).." rf/t", colors.lime)
local tempColor = getTempColor(ri.temperature)
drawUpdatedText(4, 7, "Temperature:", f.format_int(ri.temperature).."C", tempColor)
drawUpdatedText(4, 9, "Output Gate:", f.format_int(fluxgate.getSignalLowFlow()).." rf/t", colors.lightBlue)
drawUpdatedText(4, 10, "Input Gate:", f.format_int(inputFluxgate.getSignalLowFlow()).." rf/t", colors.lightBlue)
local satPercent = getPercentage(ri.energySaturation, ri.maxEnergySaturation)
drawUpdatedText(4, 12, "Energy Saturation:", satPercent.."%", colors.green)
f.progress_bar(mon, 4, 13, monX-7, satPercent, 100, colors.green, colors.lightGray)
local fieldPercent = getPercentage(ri.fieldStrength, ri.maxFieldStrength)
local fieldColor = getFieldColor(fieldPercent)
drawUpdatedText(4, 15, "Field Strength:", fieldPercent.."%", fieldColor)
f.progress_bar(mon, 4, 16, monX-7, fieldPercent, 100, fieldColor, colors.lightGray)
local fuelPercent = 100 - getPercentage(ri.fuelConversion, ri.maxFuelConversion)
local fuelColor = getFuelColor(fuelPercent)
drawUpdatedText(4, 18, "Fuel:", fuelPercent.."%", fuelColor)
f.progress_bar(mon, 4, 19, monX-7, fuelPercent, 100, fuelColor, colors.lightGray)
end
function drawUpdatedText(x, y, label, value, color)
local key = label
if lastValues[key] ~= value then
f.draw_text_lr(mon, x, y, 3, " ", " ", colors.white, color, colors.black)
f.draw_text_lr(mon, x, y, 3, label, value, colors.white, color, colors.black)
lastValues[key] = value
end
end
function getTempColor(temp)
if temp <= 5000 then return colors.green end
if temp <= 6500 then return colors.orange end
return colors.red
end
function getFieldColor(percent)
if percent >= 50 then return colors.blue end
if percent > 30 then return colors.orange end
return colors.red
end
function getFuelColor(percent)
if percent >= 70 then return colors.green end
if percent > 30 then return colors.orange end
return colors.red
end
function getPercentage(value, maxValue)
return math.ceil(value / maxValue * 10000) * 0.01
end
mon.clear()
mon.monitor.setTextScale(0.5)
buttonMain() -- Initialize buttons before the event listener
parallel.waitForAny(reactorInfoScreen, reactorControl, button.clickEvent)