Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ---start vbuffer functions
- function new(_w, _h)
- --just in case, declare these guys locally
- local i;
- local j;
- --initialize the template buffer
- local buffer = {};
- --loop through one iteration of _w, and catch all elements on the way
- for i = 1, _w do
- --create the three parts of the array: bgCol, txCol, and tx
- buffer[i] = {};
- buffer[i + _w] = {};
- buffer[i + (2 * _w)] = {};
- for j = 1, _h do
- buffer[i][j] = colors.black;
- buffer[i + _w][j] = colors.white;
- buffer[i + (2 * _w)][j] = "";
- end
- end
- return buffer;
- end
- function init()
- --get terminal width and height
- local _w;
- local _h;
- _w, _h = term.getSize();
- --call the new() function to generate the template buffer
- local buffer = new(_w, _h);
- buffer = textutils.serialize(buffer);
- --set the video and frame buffer to equal the template buffer
- _G.vBuffer = textutils.unserialize(buffer);
- _G.fBuffer = textutils.unserialize(buffer);
- --set the application buffer to equal the template buffer
- _G.aBuffer = textutils.unserialize(buffer);
- --set the error buffer to equal the template buffer
- _G.eBuffer = textutils.unserialize(buffer);
- end
- function add(buffer, x, y, bgCol, txcol, tx)
- --make sure that everything is not out of bounds
- if x <= #buffer / 3 and y <= #buffer[1] then
- --make sure they want to change bgCol
- if bgCol ~= nil then
- buffer[x][y] = bgCol;
- end
- --make sure they want to change txCol
- if txcol ~= nil then
- buffer[x + (#buffer / 3)][y] = txcol;
- end
- --make sure they want to change tx
- if tx ~= nil then
- buffer[x + ( 2 * #buffer / 3)][y] = tx;
- end
- end
- --return the buffer
- return buffer;
- end
- function write(buffer, x, y, bgCol, txcol, tx)
- --declare this locally just in case
- local i;
- for i = 1, string.len(tx) do
- --they obviously want to change the text
- buffer = add(buffer, x + i - 1, y, bgCol, txcol, string.sub(tx, i, i));
- end
- --return the new buffer
- return buffer;
- end
- function rect(buffer, x1, y1, x2, y2, bgCol, txcol, tx)
- --declare these locally just in case
- local i;
- local j;
- if tx == nil then
- tx = " ";
- end
- --loop through the all of the elements needed
- for i = x1, x2 do
- for j = y1, y2 do
- buffer = add(buffer, i, j, bgCol, txcol, tx);
- end
- end
- --return the buffer
- return buffer;
- end
- function fill(buffer, bgCol, txcol, tx)
- --declare these locally just in case
- local i;
- local j;
- local _w;
- local _h;
- --get the terminal size
- _w, _h = term.getSize();
- --fill the screen
- buffer = rect(buffer, 1, 1, _w, _h, bgCol, txcol, tx);
- --return the buffer
- return buffer;
- end
- function renderto(buffer, renderBuffer)
- --declare these locally just in case
- local i;
- local j;
- for i = 1, #buffer / 3 do
- for j = 1, #buffer[1] do
- if buffer[i + (2 * #buffer / 3)][j] ~= "" and buffer[i + (2 * #buffer / 3)][j] ~= nil then
- renderBuffer = add(renderBuffer, i, j, buffer[i][j], buffer[i + (#buffer / 3)][j], buffer[i + (2 * #buffer / 3)][j]);
- end
- end
- end
- end
- function drawScreen()
- --render the current desktop and application buffers to the frame buffer
- renderto(aBuffer, fBuffer);
- renderto(eBuffer, fBuffer);
- --declare these locally just in case
- local i;
- local j;
- for i = 1, #fBuffer / 3 do
- for j = 1, #fBuffer[1] do
- --set the cursor position to the current pixel
- term.setCursorPos(i, j);
- --make sure that the current frame's bgCol is not nil
- if fBuffer[i][j] ~= nil then
- term.setBackgroundColor(fBuffer[i][j]);
- else
- --otherwise set the background color to black
- term.setBackgroundColor(vBuffer[i][j]);
- end
- --make sure that the current frame's txCol is not nil
- if fBuffer[i + (#fBuffer / 3)][j] ~= nil then
- term.setTextColor(fBuffer[i + (#fBuffer / 3)][j]);
- else
- --otherwise set the text color to white
- term.setTextColor(vBuffer[i + (#vBuffer / 3)][j]);
- end
- --make sure that the current frame's tx is not nil or ""
- if fBuffer[i + (2 * #fBuffer / 3)][j] ~= nil and fBuffer[i + (2 * #fBuffer / 3)][j] ~= "" then
- term.write(fBuffer[i + (2 * #fBuffer / 3)][j]);
- end
- end
- end
- --render the current frame to vBuffer
- renderto(fBuffer, vBuffer);
- end
- ---load settings api
- local s;
- if fs.exists("/Settings") then
- os.loadAPI("/Settings");
- --if it doesn't exist, make the default settings
- else
- local file = fs.open("/Settings", "w");
- file.writeLine("--reactor optimization");
- file.writeLine("--NOTE: this will adjust control rods to keep reactor at");
- file.writeLine("-- an optimal temperature to conserve fuel");
- file.writeLine("-- activated at the fuel percentage specified below (0 for off)");
- file.writeLine("--WARNING: this can limit power output by as much as half");
- file.writeLine("optimizeLevel = 50;");
- file.writeLine("");
- file.writeLine("--reactor automation");
- file.writeLine("--NOTE: this will enable and disable the reactor to keep");
- file.writeLine("-- stored power in specified range (in millions)")
- file.writeLine("deactivateLevel = 9");
- file.writeLine("activateLevel = 7.5");
- file.writeLine("");
- file.writeLine("--set reactor warmup before OS starts (in seconds)");
- file.writeLine("--NOTE: warmup is disabled if reactor is already on");
- file.writeLine("--NOTE: disabling warmup completely can cause issues with graphing");
- file.writeLine("warmup = 5;")
- file.writeLine("");
- file.writeLine("--set update frequencies (in seconds; minimum of 0.05)");
- file.writeLine("powerUpdate = 0.5;");
- file.writeLine("graphUpdate = 3;");
- file.writeLine("fuelUpdate = 0.5;");
- file.writeLine("tempUpdate = 1;");
- file.writeLine("");
- file.writeLine("--set graph type (0 is power usage graph, 1 is power production graph)")
- file.writeLine("--NOTE: graph type 0 can get buggy when reactor is on...");
- file.writeLine("graphType = 0;");
- file.writeLine("");
- file.writeLine("--set colors");
- file.writeLine("--NOTE: only use colors API color definitions");
- file.writeLine("backgroundColor = colors.black;");
- file.writeLine("textColor = colors.white;");
- file.writeLine("borderColor = colors.lightGray;");
- file.writeLine("labelColor = colors.lightBlue;");
- file.writeLine("graphColor = colors.blue;");
- file.writeLine("freeSpaceColor = colors.yellow;");
- file.writeLine("fuelColor = colors.lightBlue;");
- file.writeLine("wasteColor = colors.blue;");
- file.writeLine("positiveColor = colors.green;");
- file.writeLine("negativeColor = colors.red;");
- file.writeLine("");
- file.writeLine("--enable terminal glasses HUD");
- file.writeLine("--NOTE: this will draw over current HUD");
- file.writeLine("enableGlasses = false;");
- file.writeLine("--quadrant to display the HUD in the corner of");
- file.writeLine("quadrant = 3;");
- file.writeLine("opacity = 0.2");
- file.close();
- os.loadAPI("/Settings");
- end
- --redirect to monitor
- local mon = peripheral.find("monitor");
- term.redirect(mon);
- mon.setTextScale(0.5);
- --get terminal width and height
- local _w, _h = mon.getSize();
- --attach reactor
- local r = peripheral.find("BigReactors-Reactor");
- ---load necessary vbuffers
- init();
- ---initialize necessary graphing array
- local graphArray = {};
- local lastPower = r.getEnergyStored();
- local highest = 0;
- for i = 0, _w - 16 do
- graphArray[i] = 0;
- end
- ---import variables from settings file
- --reactor optimization
- local oLevel = Settings.optimizeLevel;
- --reactor automation
- local hBound = Settings.deactivateLevel * 1000000;
- local lBound = Settings.activateLevel * 1000000;
- --warmup period
- local warm = Settings.warmup;
- --update frequencies
- local pTick = Settings.powerUpdate;
- local gTick = Settings.graphUpdate;
- local fTick = Settings.fuelUpdate;
- local tTick = Settings.tempUpdate;
- --graph type
- local gType = Settings.graphType;
- --colors
- local bgCol = Settings.backgroundColor;
- local tCol = Settings.textColor;
- local bCol = Settings.borderColor;
- local lCol = Settings.labelColor;
- local gCol = Settings.graphColor;
- local sCol = Settings.freeSpaceColor;
- local fCol = Settings.fuelColor;
- local wCol = Settings.wasteColor;
- local pCol = Settings.positiveColor;
- local nCol = Settings.negativeColor;
- --terminal glasses
- local gEnabled = Settings.enableGlasses;
- local q = Settings.quadrant;
- local o = Settings.opacity;
- ---reactor main functions
- function drawStatus()
- --turn on if power is below low bound
- if r.getEnergyStored() <= lBound and r.getActive() == false then
- r.setActive(true);
- elseif r.getEnergyStored() >= hBound and r.getActive() then
- r.setActive(false);
- end
- --draw border
- aBuffer = rect(aBuffer, 2, 2, _w * 0.5 - 1, 9, bCol, tCol, ' ');
- aBuffer = rect(aBuffer, 3, 3, _w * 0.5 - 2, 8, bgCol, tCol, ' ');
- aBuffer = write(aBuffer, math.ceil(((_w * 0.5) - 1 - string.len(" Status ")) / 2), 2, bgCol, tCol, " Status ");
- --reactor activity
- aBuffer = write(aBuffer, 4, 4, bgCol, tCol, "Reactor is ");
- if r.getActive() then
- aBuffer = write(aBuffer, 4 + string.len("Reactor is "), 4, bgCol, pCol, "Active");
- else
- aBuffer = write(aBuffer, 4 + string.len("Reactor is "), 4, bgCol, nCol, "Inactive");
- end
- --reactor temps
- --fuel temp
- aBuffer = write(aBuffer, 4, 6, bgCol, tCol, "Core Temp: ");
- if (r.getFuelTemperature() > 1000 or r.getFuelTemperature() < 800) and r.getActive() then
- aBuffer = write(aBuffer, 4 + string.len("Core Temp: "), 6, bgCol, nCol, math.ceil(r.getFuelTemperature()));
- else
- aBuffer = write(aBuffer, 4 + string.len("Core Temp: "), 6, bgCol, pCol, math.ceil(r.getFuelTemperature()));
- end
- aBuffer = write(aBuffer, 4 + string.len("Core Temp: ") + #tostring(math.ceil(r.getFuelTemperature())) + 1, 6, bgCol, tCol, "C");
- --case temp
- aBuffer = write(aBuffer, 4, 7, bgCol, tCol, "Case Temp: ");
- if r.getCasingTemperature() > 1000 then
- aBuffer = write(aBuffer, 4 + string.len("Case Temp: "), 7, bgCol, nCol, math.floor(r.getCasingTemperature()));
- else
- aBuffer = write(aBuffer, 4 + string.len("Case Temp: "), 7, bgCol, pCol, math.floor(r.getCasingTemperature()));
- end
- aBuffer = write(aBuffer, 4 + string.len("Case Temp: ") + #tostring(math.floor(r.getCasingTemperature())) + 1, 7, bgCol, tCol, "C");
- end
- function drawFuel()
- --draw border
- aBuffer = rect(aBuffer, math.ceil(_w * 0.5), 2, _w - 1, 9, bCol, tCol, ' ');
- aBuffer = rect(aBuffer, math.ceil(_w * 0.5) + 1, 3, _w - 2, 8, bgCol, tCol, ' ');
- aBuffer = write(aBuffer, math.ceil(_w * 0.5) + math.ceil(((_w - 1) - math.ceil(_w * 0.5) - string.len(" Fuel ")) / 2), 2, bgCol, tCol, " Fuel ");
- --draw mB/t display
- aBuffer = write(aBuffer, math.ceil(_w * 0.5) + 2, 4, bgCol, tCol, "Fuel Usage: " .. tostring(math.ceil(r.getFuelConsumedLastTick() * 100) / 100) .. " mB/t");
- --draw free space bar
- aBuffer = rect(aBuffer, math.ceil(_w * 0.5) + 2, 7, _w - 3, 7, sCol, tCol, ' ');
- --draw fuel bar
- local wastePercent = r.getWasteAmount() / r.getFuelAmountMax();
- local fuelPercent = r.getFuelAmount() / r.getFuelAmountMax();
- local byAmount = (_w - 3) - math.floor(((_w - 3) - ((_w * 0.5) + 2)) * (fuelPercent + wastePercent));
- aBuffer = rect(aBuffer, byAmount, 7, _w - 3, 7, fCol, tCol, ' ');
- --draw waste bar
- byAmount = (_w - 3) - math.floor(((_w - 3) - ((_w * 0.5) + 2)) * wastePercent);
- aBuffer = rect(aBuffer, byAmount, 7, _w - 3, 7, wCol, tCol, ' ');
- --draw percentages
- aBuffer = write(aBuffer, math.ceil(_w * 0.5) + 2, 6, bgCol, sCol, math.ceil(100 - ((fuelPercent + wastePercent) * 100)));
- aBuffer = write(aBuffer, math.ceil(_w * 0.5) + 2 + string.len(tostring(math.ceil(100 - ((fuelPercent + wastePercent) * 100)))), 6, bgCol, tCol, "% | ");
- aBuffer = write(aBuffer, math.ceil(_w * 0.5) + 2 + string.len(tostring(math.ceil(100 - ((fuelPercent + wastePercent) * 100)))) + #"% | ", 6, bgCol, fCol, 100 - (math.ceil(100 - ((fuelPercent + wastePercent) * 100)) + math.ceil(wastePercent * 100)));
- aBuffer = write(aBuffer, math.ceil(_w * 0.5) + 2 + string.len(tostring(math.ceil(100 - ((fuelPercent + wastePercent) * 100)))) + #"% | " + #tostring(100 - (math.ceil(100 - ((fuelPercent + wastePercent) * 100)) + math.ceil(wastePercent * 100))), 6, bgCol, tCol, "% | ");
- aBuffer = write(aBuffer, math.ceil(_w * 0.5) + 2 + string.len(tostring(math.ceil(100 - ((fuelPercent + wastePercent) * 100)))) + (2 * #"% | ") + #tostring(100 - (math.ceil(100 - ((fuelPercent + wastePercent) * 100)) + math.ceil(wastePercent * 100))), 6, bgCol, wCol, math.ceil(wastePercent * 100));
- aBuffer = write(aBuffer, math.ceil(_w * 0.5) + 2 + string.len(tostring(math.ceil(100 - ((fuelPercent + wastePercent) * 100)))) + (2 * #"% | ") + #tostring(100 - (math.ceil(100 - ((fuelPercent + wastePercent) * 100)) + math.ceil(wastePercent * 100))) + #tostring(math.floor(wastePercent * 100)), 6, bgCol, tCol, "%");
- end
- function drawRod()
- --draw border
- aBuffer = rect(aBuffer, _w - 10, 11, _w - 1, _h - 1, bCol, tCol, ' ');
- aBuffer = rect(aBuffer, _w - 9, 12, _w - 2, _h - 2, bgCol, tCol, ' ');
- aBuffer = write(aBuffer, _w - 10 + math.ceil(((_w - 1) - (_w - 10) - #" Rods ") / 2), 11, bgCol, tCol, " Rods ");
- --draw control rod level
- aBuffer = write(aBuffer, _w - 8 + math.ceil(((_w - 3) - (_w - 8) - #(tostring(r.getControlRodLevel(0)).. "%")) / 2), 13, bgCol, tCol, tostring(r.getControlRodLevel(0)) .. "%");
- --draw rod visual indicator
- aBuffer = rect(aBuffer, _w - 7, 15, _w - 4, _h - 3, fCol, tCol, ' ');
- aBuffer = rect(aBuffer, _w - 6, 15, _w - 5, 15 + math.floor((_h - 18) * ((r.getControlRodLevel(0) - 1) / 100)), wCol, tCol, ' ');
- end
- function drawPower()
- --draw border
- aBuffer = rect(aBuffer, 2, 11, _w - 12, _h - 9, bCol, tCol, ' ');
- aBuffer = rect(aBuffer, 3, 12, _w - 13, _h - 9, bgCol, tCol, ' ');
- aBuffer = write(aBuffer, math.ceil(((_w - 9) - #" Energy ") / 2), 11, bgCol, tCol, " Energy ");
- --draw production
- aBuffer = write(aBuffer, 4, 13, bgCol, tCol, "Energy Produced: ");
- aBuffer = write(aBuffer, 4 + #"Energy Produced: ", 13, bgCol, pCol, math.floor(r.getEnergyProducedLastTick()));
- aBuffer = write(aBuffer, 4 + #"Energy Produced: " + #tostring(math.floor(r.getEnergyProducedLastTick())), 13, bgCol, tCol, " RF/t");
- --draw stored
- aBuffer = write(aBuffer, 4, 14, bgCol, tCol, "Energy Stored: ");
- aBuffer = write(aBuffer, 4 + #"Energy Stored: ", 14, bgCol, pCol, r.getEnergyStored());
- aBuffer = write(aBuffer, 4 + #"Energy Stored: " + #tostring(r.getEnergyStored()), 14, bgCol, tCol, " RF");
- end
- function drawGraph()
- aBuffer = rect(aBuffer, 2, _h - 9, _w - 12, _h - 1, bCol, tCol, ' ');
- aBuffer = rect(aBuffer, 3, _h - 9, _w - 13, _h - 2, bgCol, tCol, ' ');
- for i = 0, _w - 16 do
- if i == 0 and graphArray[i] == highest then
- highest = 0;
- for j = 1, _w - 16 do
- highest = math.max(graphArray[j], highest);
- end
- end
- if i < _w - 16 then
- graphArray[i] = graphArray[i + 1];
- else
- if gType == 1 then
- graphArray[i] = r.getEnergyProducedLastTick();
- else
- graphArray[i] = math.max((lastPower - r.getEnergyStored()) / (20 * gTick), 0);
- end
- end
- highest = math.max(graphArray[i], highest);
- if highest ~= 0 then
- aBuffer = rect(aBuffer, 3 + i, math.floor(_h - 2 - ((_h - 18) * (graphArray[i] / highest))), 3 + i, _h - 2, gCol, tCol, ' ');
- end
- end
- lastPower = r.getEnergyStored();
- end
- function calibrate()
- if r.getFuelAmount() * 100 / r.getFuelAmountMax() <= oLevel and r.getActive() == true then
- if r.getFuelTemperature() > 1000 then
- r.setAllControlRodLevels(r.getControlRodLevel(0) + (100 - r.getControlRodLevel(0)) / 8)
- elseif r.getFuelTemperature() < 800 then
- r.setAllControlRodLevels(r.getControlRodLevel(0)/8);
- end
- elseif r.getActive() == true then
- r.setAllControlRodLevels(0);
- end
- end
- function drawGlasses()
- g.clear();
- stText = g.addText(5, -15, "Reactor Status: ");
- if r.getActive() then
- active = g.addText(5 + 5 * #"Reactor Status: ", -15, "Active", 0x00FF00);
- else
- active = g.addText(5 + 5 * #"Reactor Status: ", -15, "Inactive", 0xFF0000);
- end
- fText = g.addText(5, -5, "Reactor Fuel: ");
- local col = 0x000000;
- if math.floor((r.getFuelAmount() * 100) / r.getFuelAmountMax()) >= 75 then
- col = 0x00FF00;
- elseif math.floor((r.getFuelAmount() * 100) / r.getFuelAmountMax()) < 75 and math.floor((r.getFuelAmount() * 100) / r.getFuelAmountMax()) >= 50 then
- col = 0xFFFF00;
- else
- col = 0xFF0000;
- end
- fuel = g.addText(5 + 5 * #"Reactur Fuel: ", -5, tostring(math.floor(r.getFuelAmount() * 100/ r.getFuelAmountMax())) .. "%", col)
- if q == 1 then
- stText.setAlignment("right", "top");
- active.setAlignment("right", "top");
- fText.setAlignment("right", "top");
- fuel("right", "top");
- elseif q == 2 then
- stText.setAlignment("left", "top");
- active.setAlignment("left", "top");
- fText.setAlignment("left", "top");
- fuel.setAlignment("left", "top");
- elseif q == 3 then
- stText.setAlignment("left", "bottom");
- active.setAlignment("left", "bottom");
- fText.setAlignment("left", "bottom");
- fuel.setAlignment("left", "bottom");
- elseif q == 4 then
- stText.setAlignment("right", "bottom");
- active.setAlignment("right", "bottom");
- fText.setAlignment("right", "bottom");
- fuel.setAlignment("right", "bottom");
- end
- g.sync()
- end
- --attach glasses bridge
- if gEnabled == true then
- g = peripheral.find("openperipheral_bridge");
- end
- ---start warmup
- if warm > 0 and not r.getActive() then
- local w = 0;
- while w < warm do
- r.setActive(true);
- local percent = math.ceil((_w - 3) * (w / warm));
- aBuffer = fill(aBuffer, bgCol, tCol, ' ');
- aBuffer = rect(aBuffer, 1, 1, _w, 1, bCol, nil, nil, nil)
- aBuffer = write(aBuffer, math.ceil((_w - string.len("Reactor warmup in progress...")) / 2), 1, bCol, tCol, "Reactor warmup in progress...")
- aBuffer = rect(aBuffer, 5, math.ceil(_h / 2) + 1, _w - 3, math.ceil(_h / 2) + 1, fCol, tCol, ' ');
- aBuffer = rect(aBuffer, 5, math.ceil(_h / 2) + 1, percent, math.ceil(_h / 2) + 1, wCol, nil, ' ');
- drawScreen();
- sleep(1);
- w = w + 1;
- end
- end
- --initialize screen
- aBuffer = fill(aBuffer, bgCol, tCol, nil);
- --pre-render the screen
- drawStatus();
- drawFuel();
- drawRod();
- drawPower();
- drawGraph();
- drawScreen();
- --schedule events
- local status = os.startTimer(tTick);
- local fuel = os.startTimer(fTick);
- local rod = os.startTimer(fTick);
- local power = os.startTimer(pTick);
- local graph = os.startTimer(gTick);
- local getStore = os.startTimer(pTick - 0.05);
- local glasses;
- local optimum = os.startTimer(10);
- local dstat, dfuel, drod, dpower, dgraph, dglass;
- --start glasses timer
- if gEnabled == true then
- glasses = os.startTimer(0.05);
- end
- local stored = 0;
- --run main loop
- while true do
- local event, timerID = os.pullEvent("timer");
- if timerID == status then
- dstat = coroutine.create(drawStatus);
- ok, err = coroutine.resume(dstat);
- if not ok then
- error(err);
- end
- status = os.startTimer(tTick);
- elseif timerID == fuel then
- dfuel = coroutine.create(drawFuel);
- ok, err = coroutine.resume(dfuel);
- if not ok then
- error(err);
- end
- fuel = os.startTimer(fTick);
- elseif timerID == rod then
- drod = coroutine.create(drawRod);
- ok, err = coroutine.resume(drod);
- if not ok then
- error(err);
- end
- rod = os.startTimer(fTick);
- elseif timerID == graph then
- dgraph = coroutine.create(drawGraph);
- ok, err = coroutine.resume(dgraph);
- if not ok then
- error(err);
- end
- graph = os.startTimer(gTick);
- elseif timerID == glasses then
- dglass = coroutine.create(drawGlasses);
- ok, err = coroutine.resume(dglass);
- if not ok then
- error(err);
- end
- glasses = os.startTimer(0.05);
- elseif timerID == power then
- dpower = coroutine.create(drawPower);
- ok, err = coroutine.resume(dpower);
- if not ok then
- error(err);
- end
- power = os.startTimer(pTick);
- elseif timerID == optimum then
- dcalibrate = coroutine.create(calibrate);
- ok, err = coroutine.resume(dcalibrate);
- if not ok then
- error(err);
- end
- optimum = os.startTimer(10);
- end
- --draw the screen
- drawScreen();
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement