Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- local computer = require("computer")
- local component = require("component")
- local event = require("event")
- local term = require("term")
- -- control just one reactor per computer. Simpler that way.
- local reactor
- do
- local t = component.list("nc_fission_reactor")
- if not next(t) then -- none!
- print("Error: no reactors found!")
- os.exit()
- end
- if next(t, (next(t))) then -- more than one!
- print("Error: this program can only control one reactor!")
- os.exit()
- end
- reactor = component.nc_fission_reactor
- end
- local isproblem = function()
- local problem = reactor.getProblem()
- if (problem == "No Problem") and (reactor.getFissionFuelName() == "No Fuel") then problem = "No Fuel" end
- return problem
- end
- reactor.deactivate() -- just so we know.
- -- scale a number in the 0 to 1 range to an integer in the 1 to n range in such a way that all integers are equally represented.
- local scalenumber = function(x, n)
- return math.floor(math.max(math.min(x * n + 1, n), 1))
- end
- -- stubs for term not being available.
- local t = {
- drawdisplay = function(t)
- if isproblem() ~= "No Problem" then computer.beep(440, .1) end
- end,
- err = function(s)
- print(s)
- os.exit()
- end,
- }
- -- set up display stuff.
- if term.isAvailable() then
- local gpu = component.gpu
- local sf, sb = gpu.setForeground, gpu.setBackground
- t.err = function(s)
- sf(0xffffff)
- sb(0x000000)
- term.clear()
- term.write(s, true)
- os.exit()
- end
- sf(0xffffff)
- sb(0x000000)
- term.clear()
- local colorscreen = gpu.getDepth() ~= 1
- local width, height = gpu.maxResolution()
- local aspectratio = 1
- width = math.min(width, height * aspectratio * 2) -- * 2 because of character size
- -- we want the height to be a multiple of 4 plus 3.
- height = math.floor((width / 2 / aspectratio - 3) / 4) * 4 + 3
- -- resize the width accordingly.
- width = math.floor(height * 2 * aspectratio)
- -- and set bar tops and height.
- local barheight = math.floor((height - 3) / 4)
- local bartops = {
- energy = 1,
- heat = 2 + barheight,
- fueltime = 3 + barheight * 2,
- runtime = 4 + barheight * 3
- }
- gpu.setResolution(width, height)
- local sevenths = {
- energy = {0xff0000, 0xff8000, 0xffff00, 0x00ff00, 0xffff00, 0xff8000, 0xff0000},
- heat = {0x00ff00, 0x00ff00, 0x00ff00, 0x00ff00, 0xffff00, 0xff8000, 0xff0000},
- fueltime = {0xff0000, 0xff8000, 0xffff00, 0x00ff00, 0x00ff00, 0x00ff00, 0x00ff00},
- runtime = {0xffff00, 0xffff00, 0xffff00, 0xffff00, 0xffff00, 0xffff00, 0xffff00}
- }
- if not colorscreen then
- for i = 1, 7 do
- sevenths.energy[i] = 0xffffff
- end
- sevenths.heat, sevenths.fueltime, sevenths.runtime = sevenths.energy, sevenths.energy, sevenths.energy
- end
- -- draw a line of the display.
- local line = function(bartype, x, y, isblack)
- sb(isblack and 0 or sevenths[bartype][scalenumber((x - 1) / (width - 1), 7)])
- gpu.fill(x, bartops[bartype], 1, y, " ")
- end
- -- initialize the display.
- for bartype, wedges in pairs(sevenths) do
- for x = 1, width do
- line(bartype, x, barheight)
- end
- end
- local lastreadings = {energy = -1, heat = -1, fueltime = -1, runtime = -1}
- local lastnoproblem = true
- local operatingtrack = {}
- for i = 1, width do table.insert(operatingtrack, false) end
- local tickson = 0
- local currenttick = 0
- -- draw the display.
- t.drawdisplay = function(t)
- sf(0xffffff)
- currenttick = (currenttick % width) + 1
- if t.reactoron ~= operatingtrack[currenttick] then
- tickson = tickson + (t.reactoron and 1 or -1)
- operatingtrack[currenttick] = t.reactoron
- end
- t.runtime, t.reactoron = tickson / width, nil
- for bartype, fraction in pairs(t) do
- local reading = scalenumber(fraction, width)
- if lastreadings[bartype] ~= reading then
- line(bartype, lastreadings[bartype], math.floor(barheight / 2))
- line(bartype, reading, math.floor(barheight / 2), true)
- lastreadings[bartype] = reading
- end
- end
- local problem = isproblem()
- local noproblem = (problem == "No Problem")
- if lastnoproblem ~= noproblem then
- problem = string.format("Error: %s!", problem)
- problem = string.format("%s%s", string.rep(" ", math.floor((width - problem:len()) / 2)), problem)
- sf(0xff0000)
- for _, bartype in pairs({"heat", "fueltime", "runtime"}) do
- local y = bartops[bartype] - 1
- gpu.fill(1, y, width - 1, 1, " ")
- if not noproblem then
- term.setCursor(1, y)
- term.write(problem)
- end
- end
- sf(0x000000)
- lastnoproblem = noproblem
- end
- if not noproblem then computer.beep(440, .1) end
- end
- end
- local drawdisplay, err = t.drawdisplay, t.err
- local scrub = function(reason)
- reactor.deactivate()
- err(string.format("%s! Shutting down reactor.", reason))
- end
- local MaxEnergyStoredConstant, MaxHeatLevelConstant = reactor.getMaxEnergyStored(), reactor.getMaxHeatLevel()
- -- and here we go.
- computer.beep(440, .1)
- repeat
- local keypress = event.pull(0, "key_down")
- if keypress then scrub("Keypress detected") end
- local status = {
- energy = reactor.getEnergyStored() / MaxEnergyStoredConstant,
- heat = reactor.getHeatLevel() / MaxHeatLevelConstant,
- fueltime = reactor.getFissionFuelTime(),
- }
- if status.fueltime ~= 0 then status.fueltime = 1 - reactor.getCurrentProcessTime() / status.fueltime end -- avoiding divide by zero for no fuel
- status.reactoron = (status.energy <= 0.5) and (status.heat <= 0.5)
- reactor[status.reactoron and "activate" or "deactivate"]()
- drawdisplay(status)
- until false
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement