Skip to content

Instantly share code, notes, and snippets.

@zeng-github01
Last active October 3, 2023 15:44
Show Gist options
  • Save zeng-github01/2a32793c49ffe713d33be34751b549b7 to your computer and use it in GitHub Desktop.
Save zeng-github01/2a32793c49ffe713d33be34751b549b7 to your computer and use it in GitHub Desktop.
NuclearCraft Reactor AutoControl
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
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