Last active
October 3, 2023 15:44
-
-
Save zeng-github01/2a32793c49ffe713d33be34751b549b7 to your computer and use it in GitHub Desktop.
NuclearCraft Reactor AutoControl
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
local component = require("component") | |
local keyboard = require("keyboard") | |
local event = require("event") | |
local thread = require("thread") | |
local gpu = component.gpu | |
local STARTTIME = os.time() | |
local screenViewport = {gpu.getViewport()} | |
local WIDTH , HEIGHT = 64 , 16 | |
local reactors = {address = {}, reactor = {}, reactors = {}, screens = {}} | |
Colors = {} | |
local symList = {'#', '@', '$', '%', '^', '&'} | |
local function getTemperature(reactor) | |
return reactor.getHeatLevel() / 1e3 | |
end | |
local function numberToShow(number) | |
return tostring(number):sub(1 , tostring(number):find('%.') + 2) | |
end | |
local function showBar(x, y, width, height, color) | |
if (gpu.getDepth() > 1) then | |
gpu.setBackground(color) | |
gpu.fill(x ,y ,width ,height , ' ') | |
gpu.setBackground(0) | |
else | |
local sym | |
local i = 1 | |
for color_set , sym_set in pairs(Colors) do | |
if (color_set == color) then | |
sym = sym_set | |
break | |
end | |
i = i + 1 | |
end | |
if (sym == nil) then | |
Colors[color] = symList[i] or '*' | |
sym = Colors[color] | |
end | |
gpu.fill(x, y, width, height, sym) | |
end | |
end | |
local function screenLoop(reactor, i) | |
event.pull('screen set down') | |
local pos = 2 + 6 * (i - 1) | |
local reactorNumber = 'reactor '..i | |
gpu.fill(1 , pos , WIDTH , 1 , '-') | |
gpu.set((WIDTH - #reactorNumber) / 2, pos, reactorNumber) | |
gpu.set(1 , pos + 2 , 'Temperature :') | |
while true do | |
local statusShow = 'status : '..reactor.status | |
local problem = reactor.getProblem() | |
gpu.fill(1 , pos + 1 , WIDTH , 1 , ' ') | |
gpu.set(1 , pos + 1 , statusShow) | |
gpu.set(WIDTH - #problem + 1 , pos + 1 , problem) | |
local opti = reactor.optimumTemperature | |
local temp = getTemperature(reactor) | |
local maxtemp = reactor.MAXTEMPERATURE | |
local maxtemp_show = math.min(maxtemp , opti * 3.3) | |
local x1 = math.floor(temp / maxtemp_show * WIDTH) | |
local x2 = math.floor(opti / maxtemp_show * WIDTH) | |
local area_x1 = math.floor(opti / maxtemp_show * WIDTH) | |
local area_x2 = math.floor(opti / maxtemp_show * WIDTH) | |
local optiWidth = math.max(1, area_x2 - area_x1) | |
gpu.fill(1 , pos + 5 , WIDTH , 1 , ' ') | |
gpu.set(1 , pos + 5 , numberToShow(temp)) | |
gpu.set(WIDTH - #numberToShow(maxtemp) + 1 , pos + 5 , numberToShow(maxtemp)) | |
gpu.set(x2 - (#numberToShow(opti) / 2 - 1) , pos + 5 , numberToShow(opti)) | |
showBar(1, pos + 4, WIDTH, 1, 0x00DBC0) | |
showBar(1, pos + 4, x1, 1, 0xCCB600) | |
showBar(x2, pos + 4, 1, 1, 0xFF7F50) | |
showBar(area_x1, pos + 3, optiWidth , 1, 0xFF7F50) | |
os.sleep(0.05) | |
end | |
end | |
local function reactorLoop(reactor) | |
while true do | |
reactor.status = 'check temperature' | |
os.sleep(1) | |
local tem = getTemperature(reactor) | |
if(tem > reactor.optimumTemperature) then | |
reactor.deactivate() | |
reactor.status = 'cooling' | |
os.sleep(20) | |
reactor.activate() | |
elseif(tem < reactor.optimumTemperature) then | |
reactor.activate() | |
reactor.status = 'running' | |
os.sleep(1) | |
else | |
reactor.status = 'running' | |
os.sleep(1) | |
end | |
end | |
end | |
local function run() | |
local i = 1 | |
for address, componentType in component.list() do | |
if (componentType == 'nc_fission_reactor') then | |
local reactor = {} | |
reactor = component.proxy(address) | |
reactor.status = 'init' | |
reactor.MAXTEMPERATURE = reactor.getMaxHeatLevel() / 1e3 | |
reactor.optimumTemperature = reactor.getMaxHeatLevel() * 0.7 / 1e3 | |
reactors.address[i] = address | |
reactors.reactor[address] = reactor | |
reactors.reactors[address] = thread.create(reactorLoop, reactor) | |
reactors.screens[address] = thread.create(screenLoop, reactor, i) | |
i = i + 1 | |
end | |
end | |
if (i == 1) then | |
local string = 'there is no reactor' | |
WIDTH , HEIGHT = screenViewport[1], screenViewport[2] | |
gpu.setViewport(WIDTH , HEIGHT) | |
gpu.fill(1, 1, WIDTH, HEIGHT, ' ') | |
gpu.set((WIDTH - #string) / 2 , HEIGHT / 2 , string) | |
os.sleep(5) | |
gpu.fill(1, 1, WIDTH, HEIGHT, ' ') | |
os.exit() | |
end | |
HEIGHT = 1 | |
local width , height = gpu.getViewport() | |
WIDTH = math.min(width, WIDTH) | |
for j = 1, i - 1 do | |
HEIGHT = HEIGHT + 6 | |
if (HEIGHT > height) then | |
HEIGHT = HEIGHT - 6 | |
break | |
end | |
end | |
gpu.setViewport(WIDTH, HEIGHT) | |
gpu.fill(1, 1, WIDTH, HEIGHT,' ') | |
event.push('screen set down') | |
end | |
local time_thread = thread.create(function() | |
event.pull('screen set down') | |
while true do | |
local info = 'press Q to quit' | |
local time = 'running time : '..(os.time()-STARTTIME) / 100 | |
gpu.fill(1, 1, WIDTH, 1, ' ') | |
gpu.set(1 , 1 , time) | |
gpu.set(WIDTH - #info , 1 , info) | |
os.sleep(0.1) | |
end | |
end) | |
local function shutdownReactor() | |
for address, componentType in component.list() do | |
if (componentType == 'nc_fission_reactor') then | |
local reactor = {} | |
reactor = component.proxy(address) | |
reactor.deactivate() | |
end | |
end | |
end | |
local event_thread = thread.create(function() | |
while true do | |
local name,address,char,key,player = event.pull('key_down') | |
if(key == keyboard.keys.q) then | |
shutdownReactor() | |
print('\nQ pressed, exit') | |
return | |
end | |
end | |
end) | |
run() | |
thread.waitForAll({event_thread}) | |
gpu.fill(1, 1, WIDTH, HEIGHT, ' ') | |
gpu.setViewport(screenViewport[1], screenViewport[2]) | |
os.exit(0) -- closes all remaining threads |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
local component = require("component") | |
local keyboard = require("keyboard") | |
local event = require("event") | |
local thread = require("thread") | |
local gpu = component.gpu | |
local factor = (1156 / 949 + 4430 / 3635) / 2 | |
local STARTTIME = os.time() | |
local screenViewport = {gpu.getViewport()} | |
local WIDTH , HEIGHT = 64 , 16 | |
local reactors = {address = {}, reactor = {}, reactors = {}, screens = {}} | |
Colors = {} | |
local symList = {'#', '@', '$', '%', '^', '&'} | |
local function getTemperature(reactor) | |
return reactor.getTemperature() / 1e6 | |
end | |
local function numberToShow(number) | |
return tostring(number):sub(1 , tostring(number):find('%.') + 2) | |
end | |
local function showBar(x, y, width, height, color) | |
if (gpu.getDepth() > 1) then | |
gpu.setBackground(color) | |
gpu.fill(x ,y ,width ,height , ' ') | |
gpu.setBackground(0) | |
else | |
local sym | |
local i = 1 | |
for color_set , sym_set in pairs(Colors) do | |
if (color_set == color) then | |
sym = sym_set | |
break | |
end | |
i = i + 1 | |
end | |
if (sym == nil) then | |
Colors[color] = symList[i] or '*' | |
sym = Colors[color] | |
end | |
gpu.fill(x, y, width, height, sym) | |
end | |
end | |
local function screenLoop(reactor, i) | |
event.pull('screen set down') | |
local pos = 2 + 6 * (i - 1) | |
local reactorNumber = 'reactor '..i | |
gpu.fill(1 , pos , WIDTH , 1 , '-') | |
gpu.set((WIDTH - #reactorNumber) / 2, pos, reactorNumber) | |
gpu.set(1 , pos + 2 , 'Temperature :') | |
while true do | |
local statusShow = 'status : '..reactor.status | |
local problem = reactor.getProblem() | |
gpu.fill(1 , pos + 1 , WIDTH , 1 , ' ') | |
gpu.set(1 , pos + 1 , statusShow) | |
gpu.set(WIDTH - #problem + 1 , pos + 1 , problem) | |
local opti = reactor.optimumTemperature | |
local temp = getTemperature(reactor) | |
local maxtemp = reactor.MAXTEMPERATURE | |
local maxtemp_show = math.min(maxtemp , opti * 1.5) | |
local x1 = math.floor(temp / maxtemp_show * WIDTH) | |
local x2 = math.floor(opti / maxtemp_show * WIDTH) | |
local area_x1 = math.floor(opti * 0.99 / maxtemp_show * WIDTH) | |
local area_x2 = math.floor(opti * 1.01 / maxtemp_show * WIDTH) | |
local optiWidth = math.max(1, area_x2 - area_x1) | |
gpu.fill(1 , pos + 5 , WIDTH , 1 , ' ') | |
gpu.set(1 , pos + 5 , numberToShow(temp)) | |
gpu.set(WIDTH - #numberToShow(maxtemp) + 1 , pos + 5 , numberToShow(maxtemp)) | |
gpu.set(x2 - (#numberToShow(opti) / 2 - 1) , pos + 5 , numberToShow(opti)) | |
showBar(1, pos + 4, WIDTH, 1, 0x00DBC0) | |
showBar(1, pos + 4, x1, 1, 0xCCB600) | |
showBar(x2, pos + 4, 1, 1, 0xFF7F50) | |
gpu.fill(1, pos + 3, WIDTH, 1, ' ') | |
gpu.set(area_x1 - #numberToShow(opti * 0.999) - 1 , pos + 3 , numberToShow(opti * 0.99)) | |
gpu.set(area_x1 + optiWidth + 1 , pos + 3 , numberToShow(opti * 1.001)) | |
showBar(area_x1, pos + 3, optiWidth , 1, 0xFF7F50) | |
os.sleep(0.05) | |
end | |
end | |
local function reactorLoop(reactor) | |
while true do | |
reactor.status = 'check temperature' | |
os.sleep(1) | |
local tem = getTemperature(reactor) | |
if(tem > reactor.optimumTemperature * 1.001) then | |
reactor.deactivate() | |
reactor.status = 'cooling' | |
os.sleep(1) | |
reactor.activate() | |
elseif(tem < reactor.optimumTemperature * 0.999) then | |
reactor.activate() | |
reactor.status = 'running' | |
os.sleep(1) | |
else | |
reactor.status = 'running' | |
os.sleep(1) | |
end | |
end | |
end | |
local function run() | |
local i = 1 | |
for address, componentType in component.list() do | |
if (componentType == 'nc_fusion_reactor') then | |
local reactor = {} | |
reactor = component.proxy(address) | |
reactor.status = 'init' | |
reactor.optimumTemperature = reactor.getFusionComboHeatVariable() * factor | |
reactor.MAXTEMPERATURE = reactor.getMaxTemperature() / 1e6 | |
reactors.address[i] = address | |
reactors.reactor[address] = reactor | |
reactors.reactors[address] = thread.create(reactorLoop, reactor) | |
reactors.screens[address] = thread.create(screenLoop, reactor, i) | |
i = i + 1 | |
end | |
end | |
if (i == 1) then | |
local string = 'there is no reactor' | |
WIDTH , HEIGHT = screenViewport[1], screenViewport[2] | |
gpu.setViewport(WIDTH , HEIGHT) | |
gpu.fill(1, 1, WIDTH, HEIGHT, ' ') | |
gpu.set((WIDTH - #string) / 2 , HEIGHT / 2 , string) | |
os.sleep(5) | |
gpu.fill(1, 1, WIDTH, HEIGHT, ' ') | |
os.exit() | |
end | |
HEIGHT = 1 | |
local width , height = gpu.getViewport() | |
WIDTH = math.min(width, WIDTH) | |
for j = 1, i - 1 do | |
HEIGHT = HEIGHT + 6 | |
if (HEIGHT > height) then | |
HEIGHT = HEIGHT - 6 | |
break | |
end | |
end | |
gpu.setViewport(WIDTH, HEIGHT) | |
gpu.fill(1, 1, WIDTH, HEIGHT,' ') | |
event.push('screen set down') | |
end | |
local time_thread = thread.create(function() | |
event.pull('screen set down') | |
while true do | |
local info = 'press Q to quit' | |
local time = 'running time : '..(os.time()-STARTTIME) / 100 | |
gpu.fill(1, 1, WIDTH, 1, ' ') | |
gpu.set(1 , 1 , time) | |
gpu.set(WIDTH - #info , 1 , info) | |
os.sleep(0.1) | |
end | |
end) | |
local event_thread = thread.create(function() | |
while true do | |
local name,address,char,key,player = event.pull('key_down') | |
if(key == keyboard.keys.q) then | |
print('\nQ pressed, exit') | |
return | |
end | |
end | |
end) | |
run() | |
thread.waitForAll({event_thread}) | |
gpu.fill(1, 1, WIDTH, HEIGHT, ' ') | |
gpu.setViewport(screenViewport[1], screenViewport[2]) | |
os.exit(0) -- closes all remaining threads |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment