xxxxxxxxxx
3175
let bgCol = [0,10,10]
let primaryCol = [0,230,180]
let darkCol = [0,30,30]
let darkishCol = [0,100,100]
let sparkyName = "SRK-907"
sparkyBusy = false
sparkyFixing = null
introComplete = false
let centerX
let centerY
let mainScreenButtons
let stalloutWarnTimer = new timer()
shieldWarnTimer = new timer()
lowPowerWarnTimer = new timer()
let gameTimer = new timer()
causeOfDeath = "guh???" // if you see that text then thats a bug, probably won't show up though
gameOverTimer = new timer()
powerFailureTimer = new timer()
powerFailureImminent = false
meltdown = false
powerFailureTimer.paused = true
gameTimer.paused = true
let dialogueIndex = 1
dialogueSpeed = 30
// reactor values
let reactorOnline = false
shieldOnline = false
systemsEnabled = false
let temperature = 20
let shield = 0
let degredationThreshold = 3000
let reactorSurge = false
let RECU1power = 2
RECU2power = 2
RECU1online = false
RECU2online = false
RECU1calibration = 0
RECU2calibration = 0
let REIL1power = 5
REIL2power = 5
REIL3power = 5
REIL4power = 5
REIL1online = false
REIL2online = false
REIL3online = false
REIL4online = false
REIL1integrity = 100
REIL2integrity = 100
REIL3integrity = 100
REIL4integrity = 100
REIL1enabled = true
REIL2enabled = true
REIL3enabled = true
REIL4enabled = true
REILshutoff = false
REILshutoffAvailible = true
let EESonline = false
EESpower = 2
coolantTemp = 0
ventActive = false
let powerGen = 0
powerDraw = 100 // power demanded by the rest of the ship
powerRequired = powerDraw // power draw plus reactor power usage
powerStorage = 20000
maxPowerStorage = 20000
maxOvergen = 250
let weaponsEngaged = false
shieldEngaged = false
FTLengaged = false
FTLtimer = new timer()
thrustersEngaged = true
lifeSupportEngaged = true
randomEventTimer = new timer()
// dialogue
let calling = false
let callingText = "inbound communication from [UNKNOWN]..."
let testDialogue = {}
let testDialogue2 = {}
let introDialogue = {}
let introNo = {}
let introYes = {}
let introIKnowWhatImDoing = {}
let introPleaseDontFuckUp = {}
let introTutorial = {}
let introEnd = {}
let maintainenceBegin1 = {}
maintainenceBegin2 = {}
maintainenceBegin3 = {}
mBegins = [maintainenceBegin1,maintainenceBegin2,maintainenceBegin3]
maintainenceSelectREIL = {}
maintainenceREILfine = {}
maintainenceREILok = {}
maintainenceREIL = {}
maintainenceREILbad = {}
maintainenceREILbroken = {}
function maintainenceLoop(){
if(sparkyFixing == "REIL 1"){
REIL1integrity += 3
if(REIL1integrity < 100){
// this is bad practice, but its convenient and shouldn't break (hopefully)
executeDelayed(function(){
maintainenceLoop()
},1)
}else{
REIL1integrity = 100
printTerminal("[MSG: "+sparkyName+"] all done",5,1)
printTerminal("REIL1 rebooting...",5,2)
printTerminal("user exiting reactor chamber",5,3)
printTerminal("REIL1 online",5,4)
executeDelayed(function(){
REIL1enabled = true
REIL1power = 2
REIL1powerLever.active = true
sparkyBusy = false
},4)
}
}else if(sparkyFixing == "REIL 2"){
REIL2integrity += 3
if(REIL2integrity < 100){
// this is bad practice, but its convenient and shouldn't break (hopefully)
executeDelayed(function(){
maintainenceLoop()
},1)
}else{
REIL2integrity = 100
printTerminal("[MSG: "+sparkyName+"] all done",5,1)
printTerminal("REIL2 rebooting...",5,2)
printTerminal("user exiting reactor chamber",5,3)
printTerminal("REIL2 online",5,4)
executeDelayed(function(){
REIL2enabled = true
REIL2power = 2
REIL2powerLever.active = true
sparkyBusy = false
},4)
}
}else if(sparkyFixing == "REIL 3"){
REIL3integrity += 3
if(REIL3integrity < 100){
// this is bad practice, but its convenient and shouldn't break (hopefully)
executeDelayed(function(){
maintainenceLoop()
},1)
}else{
REIL3integrity = 100
printTerminal("[MSG: "+sparkyName+"] all done",5,1)
printTerminal("REIL3 rebooting...",5,2)
printTerminal("user exiting reactor chamber",5,3)
printTerminal("REIL3 online",5,4)
executeDelayed(function(){
REIL3enabled = true
REIL3power = 2
REIL3powerLever.active = true
sparkyBusy = false
},4)
}
}else if(sparkyFixing == "REIL 4"){
REIL4integrity += 3
if(REIL4integrity < 100){
// this is bad practice, but its convenient and shouldn't break (hopefully)
executeDelayed(function(){
maintainenceLoop()
},1)
}else{
REIL4integrity = 100
printTerminal("[MSG: "+sparkyName+"] all done",5,1)
printTerminal("REIL4 rebooting...",5,2)
printTerminal("user exiting reactor chamber",5,3)
printTerminal("REIL4 online",5,4)
executeDelayed(function(){
REIL4enabled = true
REIL4power = 2
REIL4powerLever.active = true
sparkyBusy = false
},4)
}
}
}
function runMaintainence(){
if(sparkyFixing != null && !sparkyBusy){
let result = split(sparkyFixing, " ")
if(result[0] == "REIL"){
sparkyBusy = true
printTerminal("user MAINTAINENCE_USR is accessing reactor systems in administrator mode",5)
printTerminal("REIL"+result[1]+"-mode has been set to MAINTAINENCE",5,2)
printTerminal("REIL"+result[1]+" controls disabled",5,2)
executeDelayed(function(){
if(result[1]=="1"){
REIL1powerLever.active = false
REIL1powerLever.pressed = false
REIL1powerLever.hover = false
}else if(result[1]=="2"){
REIL2powerLever.active = false
REIL2powerLever.pressed = false
REIL2powerLever.hover = false
}else if(result[1]=="3"){
REIL3powerLever.active = false
REIL3powerLever.pressed = false
REIL3powerLever.hover = false
}else if(result[1]=="4"){
REIL4powerLever.active = false
REIL4powerLever.pressed = false
REIL4powerLever.hover = false
}
},2)
printTerminal("REIL"+result[1]+" shutting down...",5,4)
executeDelayed(function(){
if(result[1]=="1"){
REIL1power = 0
REIL1enabled = false
}else if(result[1]=="2"){
REIL2power = 0
REIL2enabled = false
}else if(result[1]=="3"){
REIL3power = 0
REIL3enabled = false
}else if(result[1]=="4"){
REIL4power = 0
REIL4enabled = false
}
},4)
printTerminal("purging REIL"+result[1]+" power...",5,5)
printTerminal("REIL"+result[1]+" ready for maintainence",5,6)
printTerminal("[ALERT] reactor chamber entry requested, user authorized",5,10)
printTerminal("airlock cycling...",5,12)
printTerminal("[ALERT] user in reactor chamber! please ensure safe chamber conditions!",5,14)
printTerminal("[MSG: "+sparkyName+"] working on it now...",5,16)
executeDelayed(function(){ maintainenceLoop() },16)
}
}
}
function loadDialogue(){
maintainenceREILbroken = {
dialogue: [
{text: "let me take a look-", name: sparkyName, img: sparkyNeutral},
{img: sparkyTired, name: sparkyName, text: "oh"},
{text: "yeah, that thing's really broken"},
{text: "call me before it gets to this point next time"},
{text: "I'm assuming you want me to fix this though"}
],
options: [
{text: "yeah", result: "END", run: runMaintainence},
{text: "actually no", result: "END"}
]
}
maintainenceREILbad = {
dialogue: [
{text: "let me take a look...", name: sparkyName, img: sparkyNeutral},
{text: "yeah, that thing looks like its a minute from breaking"},
{text: "want me to fix it?"}
],
options: [
{text: "yeah", result: "END", run: runMaintainence},
{text: "nevermind", result: "END"}
]
}
maintainenceREIL = {
dialogue: [
{text: "let me take a look...", name: sparkyName, img: sparkyNeutral},
{text: "yeah, that could definitely could use some maintainence"},
{text: "want me to fix this one?"}
],
options: [
{text: "yeah", result: "END", run: runMaintainence},
{text: "nevermind", result: "END"}
]
}
maintainenceREILfine = {
dialogue: [
{text: "let me take a look...", name: sparkyName, img: sparkyNeutral},
{text: "..."},
{text: "are you sure this one needs to be fixed?"},
{text: "it looks fine"},
{text: "and I've got better things to do"}
],
options: [
{text: "yeah", result: "END", run: runMaintainence},
{text: "nevermind", result: "END"}
]
}
maintainenceREILok = {
dialogue: [
{text: "let me take a look...", img: sparkyNeutral, name: sparkyName},
{text: "it looks okay"},
{text: "want me to fix it anyways?"}
],
options: [
{text: "yeah", result: "END", run: runMaintainence},
{text: "nevermind", result: "END"}
]
}
maintainenceSelectREIL = {
dialogue: [
{text: "sure, which one?", img: sparkyNeutral, name: sparkyName}
],
options:[
{text:"REIL 1", run: function(){
sparkyFixing = "REIL 1"
// select next dialogue based on REIL integrity
// ex: "oh crap what happened to this one" if its at zero integrity
// or "you sure? this one looks fine" if its at high integrity
dialogueIndex = 1
dialogueTimer.value = 0
if(REIL1integrity > 90){
currentDialogue = maintainenceREILfine
}else if(REIL1integrity > 50){
currentDialogue = maintainenceREILok
}else if(REIL1integrity > 20){
currentDialogue = maintainenceREIL
}else if(REIL1integrity > 0){
currentDialogue = maintainenceREILbad
}else{
currentDialogue = maintainenceREILbroken
}
}},
{text:"REIL 2", run: function(){
sparkyFixing = "REIL 2"
dialogueIndex = 1
dialogueTimer.value = 0
if(REIL2integrity > 90){
currentDialogue = maintainenceREILfine
}else if(REIL2integrity > 50){
currentDialogue = maintainenceREILok
}else if(REIL2integrity > 20){
currentDialogue = maintainenceREIL
}else if(REIL2integrity > 0){
currentDialogue = maintainenceREILbad
}else{
currentDialogue = maintainenceREILbroken
}
}},
{text:"REIL 3", run: function(){
sparkyFixing = "REIL 3"
dialogueIndex = 1
dialogueTimer.value = 0
if(REIL3integrity > 90){
currentDialogue = maintainenceREILfine
}else if(REIL3integrity > 50){
currentDialogue = maintainenceREILok
}else if(REIL3integrity > 20){
currentDialogue = maintainenceREIL
}else if(REIL3integrity > 0){
currentDialogue = maintainenceREILbad
}else{
currentDialogue = maintainenceREILbroken
}
}},
{text:"REIL 4", run: function(){
sparkyFixing = "REIL 4"
dialogueIndex = 1
dialogueTimer.value = 0
if(REIL4integrity > 90){
currentDialogue = maintainenceREILfine
}else if(REIL4integrity > 50){
currentDialogue = maintainenceREILok
}else if(REIL4integrity > 20){
currentDialogue = maintainenceREIL
}else if(REIL4integrity > 0){
currentDialogue = maintainenceREILbad
}else{
currentDialogue = maintainenceREILbroken
}
}}
]
}
maintainenceBegin1 = {
dialogue: [
{name: sparkyName, img: sparkyNeutral, text: "need something?"}
],
options: [
{text: "could you fix one of the REILs",result: maintainenceSelectREIL}
]
}
maintainenceBegin2 = {
dialogue: [
{name: sparkyName, img: sparkyNeutral, text: "want something?"}
],
options: [
{text: "could you fix one of the REILs",result: maintainenceSelectREIL}
]
}
maintainenceBegin3 = {
dialogue: [
{name: sparkyName, img: sparkyNeutral, text: "yo"}
],
options: [
{text: "could you fix one of the REILs",result: maintainenceSelectREIL}
]
}
mBegins = [maintainenceBegin1,maintainenceBegin2,maintainenceBegin3]
introEnd = {
dialogue: [
{name: sparkyName, img: sparkyNeutral, text: "alright, good luck"},
{text: "wait"},
{text: "one last thing"},
{text: "if something breaks [press C] to call me"}
],
options: [
{text: "ok, thanks", result: "END"}
]
}
introTutorial = {
dialogue: [
{name: sparkyName, img: sparkyNeutral, text: "ok"},
{text: "to start the reactor, enable the shield, then ignition"},
{text: "once its running you need it to generate power"},
{name: sparkyName, img: sparkyAlert, text: "DO NOT let us run out of power"},
{text: "if you do, we're dead"},
{name: sparkyName, img: sparkyNeutral, text: "the EES cools the reactor,"},
{text: "but its also how you generate power"},
{text: "power generation is proportional to coolant temperature"},
{text: "and the hotter the core, the faster the coolant will heat up"},
{text: "and vice-versa"},
{name: "you", text: "how do I heat up the core then"},
{name: sparkyName, img: sparkyNeutral, text: "that's the next part"},
{text: "you use the REILs to heat up the core"},
{text: "the more power, the more heat added"},
{text: "pretty simple"},
{name: "you", text: "why do some of them look different"},
{name: sparkyName, img: sparkyNeutral, text: "the two big ones are the RECUs"},
{text: "they keep the reactor contained"},
{text: "so it dosen't explode"},
{text: "at high power they also increase the rate of reaction"},
{text: "aka they make it heat up faster"},
{text: "make sure they're calibrated"},
{text: "otherwise they don't work as well"},
{name: "you", text: "how do I do that"},
{name: sparkyName, img: sparkyNeutral, text: "use the little buttons next to the sliders"},
{text: "you have to keep the wave aligned with the darker wave"},
{text: "you'll see what I mean"},
{name: sparkyName, img: sparkyHappy, text: "that should be it"},
{text: "anything else you want to know?"}
],
options: [
{text: "no, I'm all set", result: introEnd},
{text: "could you repeat that?", result: introTutorial},
{text: "what do you do?"},
{text: "what are you?"}
]
}
introPleaseDontFuckUp = {
dialogue: [
{name: sparkyName, img: sparkyNeutral, text:"okay"},
{text: "if you insist"}
],
options: [
{text: "bye", result: "END"}
]
}
introIKnowWhatImDoing = {
dialogue: [
{name: sparkyName, img: sparkyNeutral, text: "oh?"},
{text: "are you sure you know what you're doing?"}
],
options: [
{text: "yep", result: introPleaseDontFuckUp},
{text: "nope", result: introTutorial}
]
}
introYes = {
dialogue: [
{name: "captain", img: logo, text: "good."},
{text: "well if that's over with"},
{text: "I'll have you talk with our maintainence guy."},
{text: "SPARKY!"},
{text: "..."},
{text: "if that goddamn animal isn't-"},
{name: sparkyName, img: sparkyNeutral, text: "sorry sir, I was-"},
{name: "captain", img: logo, text: "I don't give a rat's ass what you were doing!"},
{text: "make sure this meat computer knows how to not kill us all!"},
{name: sparkyName, img: sparkyTired, text: "yes sir."},
{text: "..."},
{text: "yeah that's the captain"},
{text: "you'll get used to him."},
{text: "hopefully."},
{name: sparkyName, img: sparkyNeutral, text: "anyways, I'm supposed to tell you how to operate the reactor."},
{text: "I'm assuming you don't know what you're doing."}
],
options: [
{text: "correct", result: introTutorial},
{text: "wrong.", result: introIKnowWhatImDoing}
]
}
introNo = {
dialogue: [
{name: "captain", img: logo, text: "god dammit-"},
{text: "wait a minute."},
{text: "you've got a sense of humor, haven't you?"},
{text: "that's both promising and concerning..."},
{text: "you better behave yourself."},
{text: "you're a brain in a box at MY mercy."},
{text: "you understand me?"}
],
options: [
{text: "yes, sir", result: introYes}
]
}
introDialogue = {
dialogue: [
{name: "captain", img: logo, text: "oh good,"},
{text: "this one's figured out how to turn it on."},
{text: "I had to throw out the last two neural cores,"},
{text: "too dumb to do their job,"},
{text: "expensive buggers too."},
{text: "you can understand me, right?"}
],
options:[
{text: "yes, sir", result: introYes},
{text: "no, sir", result: introNo},
{text: "..."},
{text: "[SKIP INTRO/TUTORIAL]", result: "END"}
]
}
testDialogue2 = {
dialogue:[
{name: "you", text: "Lets keep talking."},
{name: sparkyName, img: sparkyTired, text: "why"},
{name: "you", text: "idk"},
{name: sparkyName, img: sparkyTired, text: "..."},
{text: "nah"},
{text: "bye."},
{name: "captain", img: logo, text: "GET BACK TO WORK"}
],
options:[
{text: "damn ok",result:"END"},
]
}
testDialogue = {
dialogue:[
{name: sparkyName, img: sparkyNeutral, text: "What's up dork."},
{text: "It appears that you're finally making this system"},
{name: sparkyName, img: sparkyHappy, text: "Good luck lmao."}
],
options:[
{text: "ok bye",result:"END"},
{text: "lets keep talking", result:testDialogue2},
{text: "you know what? die.", result: "END", run: function(){ temperature = 10000 }}
]
}
}
// dialogue system
let currentDialogue = null
let dWindowWidth = 600
let dWindowHeight = 400
let dPadding = 9
let dChoose = false
function displayDialogue(){
if(currentDialogue != null){
push()
translate(windowWidth/2 - dWindowWidth/2, windowHeight/2 - dWindowHeight/2)
noStroke()
fill(primaryCol)
rect(0, -28.5, dWindowWidth, 30.5)
noStroke()
fill(bgCol)
textAlign(LEFT,CENTER)
textFont("sans-serif")
textSize(20)
text("COMMUNICATIONS",10,-13)
beginClip()
rect(0,0,dWindowWidth,dWindowHeight)
endClip()
fill(bgCol)
stroke(primaryCol)
strokeWeight(2)
rect(0,0,dWindowWidth,dWindowHeight)
let gOffset = 0
for(let c = 0; c < dialogueIndex; c++){
if(currentDialogue.dialogue[c].name != undefined){
gOffset += 62
}else{
gOffset += 35
}
gOffset += dPadding
}
push()
if(gOffset > dWindowHeight - 130){
translate(0,-(gOffset - 270))
}
// add code to move chat up on overflow
// draw dialogue
// oh boy
for(let i = 0; i < dialogueIndex; i++){
let yOffset = 0
for(let c = 0; c < i; c++){
if(currentDialogue.dialogue[c].name != undefined){
yOffset += 62
}else{
yOffset += 35
}
yOffset += dPadding
}
push()
translate(0,yOffset)
if(currentDialogue.dialogue[i].name != undefined){
if(currentDialogue.dialogue[i].name == "you"){
noStroke()
fill(primaryCol)
textFont(inter)
textSize(18)
textAlign(RIGHT,TOP)
text(currentDialogue.dialogue[i].name,dWindowWidth - 20,20+2)
textAlign(LEFT,CENTER)
textSize(14)
let textw = inter.textBounds(currentDialogue.dialogue[i].text,0,0).w
let p = 10
stroke(primaryCol)
strokeWeight(2)
fill(darkCol)
rect(dWindowWidth-20-textw-p*2 ,20+28,textw+p*2,35)
noStroke()
fill(primaryCol)
if(i+1 != dialogueIndex){
text(currentDialogue.dialogue[i].text,dWindowWidth-20-textw-p,20+28+35/2)
}else{
text(currentDialogue.dialogue[i].text.substring(0,min(dialogueTimer.value*dialogueSpeed,currentDialogue.dialogue[i].text.length)),dWindowWidth-20-textw-p,20+28+35/2)
}
}else{
noFill()
stroke(primaryCol)
strokeWeight(4)
rect(20,20,62,62)
image(currentDialogue.dialogue[i].img,20,20,62,62)
noStroke()
fill(primaryCol)
textFont(inter)
textSize(18)
textAlign(LEFT,TOP)
text(currentDialogue.dialogue[i].name,20+62+10,20+2)
textAlign(LEFT,CENTER)
textSize(14)
let textw = inter.textBounds(currentDialogue.dialogue[i].text,0,0).w
let p = 10
stroke(primaryCol)
strokeWeight(2)
fill(darkCol)
rect(20+62+10,20+28,textw+p*2,35)
noStroke()
fill(primaryCol)
if(i+1 != dialogueIndex){
text(currentDialogue.dialogue[i].text,20+62+10+p,20+28+35/2)
}else{
text(currentDialogue.dialogue[i].text.substring(0,min(dialogueTimer.value*dialogueSpeed,currentDialogue.dialogue[i].text.length)),20+62+10+p,20+28+35/2)
}
}
}else{
textAlign(LEFT,CENTER)
textSize(14)
let textw = inter.textBounds(currentDialogue.dialogue[i].text,0,0).w
let p = 10
stroke(primaryCol)
strokeWeight(2)
fill(darkCol)
rect(19,20,textw+p*2,35)
noStroke()
fill(primaryCol)
textFont(inter)
if(i+1 == dialogueIndex){
text(currentDialogue.dialogue[i].text.substring(0,min(dialogueTimer.value*dialogueSpeed,currentDialogue.dialogue[i].text.length)),19+p,20+35/2)
}else{
text(currentDialogue.dialogue[i].text,19+p,20+35/2)
}
}
pop()
}
pop()
if(currentDialogue.dialogue != undefined){
if(dialogueIndex >= currentDialogue.dialogue.length && dialogueTimer.value*dialogueSpeed >= currentDialogue.dialogue[currentDialogue.dialogue.length - 1].text.length){
dChoose = true
for(let i = 0; i < currentDialogue.options.length; i++){
textFont(consolas)
noStroke()
fill(255)
textSize(12)
textAlign(LEFT,TOP)
text("[" + (i+1) + "] " + currentDialogue.options[i].text,100,300 + (i*20))
}
}else{
dChoose = false
textFont(consolas)
noStroke()
fill(255)
textSize(22)
textAlign(CENTER,CENTER)
text("\\/ [ENTER] to continue \\/",dWindowWidth/2,dWindowHeight - 50)
}
noFill()
stroke(primaryCol)
strokeWeight(2)
rect(0,0,dWindowWidth,dWindowHeight)
pop()
}
}
}
// define buttons
// reactor button
let reactorButton = new Button("circle",200,200)
reactorButton.radius = 150
reactorButton.hidden = true
reactorButton.active = false
reactorButton.stroke = primaryCol
reactorButton.strokeWeight = 5
reactorButton.fill = bgCol
reactorButton.Pstroke = primaryCol
reactorButton.Pfill = bgCol
reactorButton.arcRadius = 0
reactorButton.ParcRadius = 0
reactorButton.arcRot = 0
reactorButton.ParcRot = 0
reactorButton.centerRot = 0
reactorButton.render = function(){
//this.centerRot += (PI*2*round(deltaTime/1000,3))/32
let x = this.x
let y = this.y
let r = this.radius
let s = this.shrink
// animations
let Ptimer = this.timeSincePressedChange
let Htimer = min(this.timeSinceHoverChange, Ptimer)
this.Pstroke = color(this.Pstroke)
this.Pfill = color(this.Pfill)
if(this.hover && !this.pressed){ // when hovered over
this.fill = ClerpColor(this.Pfill, primaryCol, sin(min(Htimer*3,1)*PI/2))
this.stroke = ClerpColor(this.Pstroke, bgCol, sin(min(Htimer*3,1)*PI/2))
this.arcRadius = Clerp(this.ParcRadius, 10, sin(min(Htimer*4,1)*PI/2))
if(Htimer <= 0.25 && Ptimer > 0.25) this.arcRot = Clerp(this.ParcRot, this.ParcRot + PI/4, sin(min(Htimer*4,1)*PI/2))
this.arcRot += (2*PI*round(deltaTime/1000,3))/8
}else if(this.pressed){ // when clicked
this.fill = ClerpColor(this.Pfill, bgCol, sin(min(Ptimer*6,1)*PI/2))
this.stroke = ClerpColor(this.Pstroke, primaryCol, sin(min(Ptimer*6,1)*PI/2))
this.arcRadius = Clerp(this.ParcRadius, 20, sin(min(Ptimer*6,1)*PI/2))
this.arcRot += (2*PI*round(deltaTime/1000,3))/16
}else{ // when not hovered or clicked
this.fill = ClerpColor(this.Pfill, bgCol, sin(min(Htimer*3,1)*PI/2))
this.stroke = ClerpColor(this.Pstroke, primaryCol, sin(min(Htimer*3,1)*PI/2))
this.arcRadius = Clerp(this.ParcRadius, 0, sin(min(Htimer*4,1)*PI/2))
this.arcRot = this.arcRot % (PI/2)
this.ParcRot = this.ParcRot % (PI/2)
this.arcRot = Clerp(this.ParcRot, this.ParcRot + PI/4, sin(min(Htimer*4,1)*PI/2))
}
fill(this.fill)
stroke(primaryCol)
strokeWeight(this.strokeWeight)
circle(this.x, this.y, this.radius * 2)
fill(this.fill)
stroke(this.stroke)
strokeWeight(20)
circle(this.x, this.y, this.radius * 2 - 40)
noFill()
stroke(this.stroke)
strokeWeight(5)
circle(this.x, this.y, 70)
fill(this.stroke)
noStroke()
circle(this.x, this.y, 50)
stroke(primaryCol)
strokeWeight(this.strokeWeight)
noFill()
strokeCap(SQUARE)
arc(x, y, r*2 + this.arcRadius*2, r*2 + this.arcRadius*2, PI/16 + this.arcRot, PI/2 - PI/16 + this.arcRot)
arc(x, y, r*2 + this.arcRadius*2, r*2 + this.arcRadius*2, (PI/2*1) + PI/16 + this.arcRot, (PI/2*1) + PI/2 - PI/16 + this.arcRot)
arc(x, y, r*2 + this.arcRadius*2, r*2 + this.arcRadius*2, (PI/2*2) + PI/16 + this.arcRot, (PI/2*2) + PI/2 - PI/16 + this.arcRot)
arc(x, y, r*2 + this.arcRadius*2, r*2 + this.arcRadius*2, (PI/2*3) + PI/16 + this.arcRot, (PI/2*3) + PI/2 - PI/16 + this.arcRot)
// lasers
push()
translate(x, y)
rotate(PI/4 - this.centerRot)
noStroke()
fill(this.stroke)
rect(-20, 70, 40, 60)
rect(-10, 60, 20, 20)
rect(-5, 0, 10, 70)
fill(this.fill)
rect(-15, 80, 5, 30)
rect(10, 80, 5, 30)
pop()
push()
translate(x, y)
rotate(PI/4 + (PI/2*1) - this.centerRot)
noStroke()
fill(this.stroke)
rect(-20, 70, 40, 60)
rect(-10, 60, 20, 20)
rect(-5, 0, 10, 70)
fill(this.fill)
rect(-15, 80, 5, 30)
rect(10, 80, 5, 30)
pop()
push()
translate(x, y)
rotate(PI/4 + (PI/2*2) - this.centerRot)
noStroke()
fill(this.stroke)
rect(-20, 70, 40, 60)
rect(-10, 60, 20, 20)
rect(-5, 0, 10, 70)
fill(this.fill)
rect(-15, 80, 5, 30)
rect(10, 80, 5, 30)
pop()
push()
translate(x, y)
rotate(PI/4 + (PI/2*3) - this.centerRot)
noStroke()
fill(this.stroke)
rect(-20, 70, 40, 60)
rect(-10, 60, 20, 20)
rect(-5, 0, 10, 70)
fill(this.fill)
rect(-15, 80, 5, 30)
rect(10, 80, 5, 30)
pop()
}
reactorButton.onHoverBegin = function(){
this.Pstroke = this.stroke
this.Pfill = this.fill
this.ParcRadius = this.arcRadius
this.ParcRot = this.arcRot
cursor(HAND)
UI_hover1.play()
UI_hover1.setVolume(0.1)
}
reactorButton.onHoverEnd = function(){
this.Pstroke = this.stroke
this.Pfill = this.fill
this.ParcRadius = this.arcRadius
this.ParcRot = this.arcRot
cursor()
}
reactorButton.onPressBegin = function(){
this.Pstroke = this.stroke
this.Pfill = this.fill
this.ParcRadius = this.arcRadius
this.ParcRot = this.arcRot
}
reactorButton.onPressEnd = function(){
this.Pstroke = this.stroke
this.Pfill = this.fill
this.ParcRadius = this.arcRadius
this.ParcRot = this.arcRot
printTerminal("authorizing reactor access...",5)
printTerminal("reactor access authorized",5,0.5)
printTerminal("loading reactor interface...",5,1)
executeDelayed(function(){
mainScreenButtons = saveButtonStatus()
disableAllButtons()
screen = "reactor"
screenLoaded = false
},1)
}
let pumpButton = new Button("box",200,200)
pumpButton.hidden = true
pumpButton.active = false
pumpButton.fill = bgCol
pumpButton.stroke = primaryCol
pumpButton.strokeWeight = 5
pumpButton.width = 150
pumpButton.height = 300
pumpButton.Pstroke = pumpButton.stroke
pumpButton.Pfill = pumpButton.fill
pumpButton.onUpdate = function(){
this.x = windowWidth - 300
this.y = 400
}
pumpButton.onPressEnd = function(){
screen = "pumps"
screenLoaded = false
disableAllButtons()
}
let startupLever = new Lever(true, 200, 200)
startupLever.hidden = true
startupLever.active = false
startupLever.stroke = primaryCol
startupLever.fill = bgCol
startupLever.strokeWeight = 2
startupLever.width = 35
startupLever.height = 10
startupLever.Slength = 40
startupLever.segments = 8
startupLever.smooth = false
startupLever.value = 8
startupLever.onUpdate = function(){
this.x = windowWidth/2
this.y = windowHeight - 125 + this.Slength/2
}
startupLever.onValueChange = function(dv){
if(this.value == 0 && shieldOnline){
executeDelayed(function(){reactorOnline = true; temperature = 1000},5)
this.hover = false
this.pressed = false
this.active = false
cursor()
printTerminal("[ALERT] reactor ignition engaged!", 10)
printTerminal("[ALERT] reactor core formed!", 5, 5)
executeDelayed(function(){
reactorSurge = true
},5.5)
warnTerminal("[WARN] core energy levels surging!", 5, 6)
printTerminal("[ALERT] overdriving containment field", 5, 6.2)
executeDelayed(function(){
RECU1power = 5
RECU2power = 5
},6.2)
printTerminal("[ALERT] reactor core stabilized", 5, 12)
executeDelayed(function(){
RECU1power = 2
RECU2power = 2
REIL1power = 2
REIL2power = 2
REIL3power = 2
REIL4power = 2
REIL1powerLever.enable()
REIL2powerLever.enable()
REIL3powerLever.enable()
REIL4powerLever.enable()
REILshutoffLever.enable()
REILshutoffButton.enable()
EESdial.enable()
ventSwitch.enable()
RECU1powerLever.enable()
RECU1caliLeft.enable()
RECU1caliRight.enable()
RECU2powerLever.enable()
RECU2caliLeft.enable()
RECU2caliRight.enable()
gameTimer.paused = false
randomEventTimer.value = -60
reactorSurge = false
},12)
printTerminal("[ALERT] core ignition success!", 10, 9)
}
}
let shieldLever = new Lever(true, 200, 200)
shieldLever.hidden = true
shieldLever.active = false
shieldLever.stroke = primaryCol
shieldLever.fill = bgCol
shieldLever.strokeWeight = 2
shieldLever.width = 35
shieldLever.height = 10
shieldLever.Slength = 40
shieldLever.segments = 8
shieldLever.smooth = false
shieldLever.value = 8
shieldLever.onUpdate = function(){
this.x = windowWidth/2 + 45
this.y = windowHeight - 125 + this.Slength/2
}
shieldLever.onValueChange = function(dv){
if(this.value == 0 && systemsEnabled){
RECU1online = true
RECU2online = true
executeDelayed(function(){
shieldOnline = true
startupLever.active = true
},2)
this.hover = false
this.pressed = false
this.active = false
cursor()
printTerminal("[ALERT] reactor confinement system inititated", 5)
printTerminal("[ALERT] reactor confinement system active", 5, 2)
}
}
let systemPowerLever = new Lever(true, 200, 200)
systemPowerLever.hidden = true
systemPowerLever.active = false
systemPowerLever.stroke = primaryCol
systemPowerLever.fill = bgCol
systemPowerLever.strokeWeight = 2
systemPowerLever.width = 35
systemPowerLever.height = 10
systemPowerLever.Slength = 40
systemPowerLever.segments = 8
systemPowerLever.smooth = false
systemPowerLever.value = 8
systemPowerLever.onUpdate = function(){
this.x = windowWidth/2 - 45
this.y = windowHeight - 125 + this.Slength/2
}
systemPowerLever.onValueChange = function(dv){
if(this.value == 0){
executeDelayed(function(){
systemsEnabled = true
shieldLever.active = true
REIL1powerLever.onUpdate()
REIL1powerLever.hidden = false
REIL2powerLever.onUpdate()
REIL2powerLever.hidden = false
REIL3powerLever.onUpdate()
REIL3powerLever.hidden = false
REIL4powerLever.onUpdate()
REIL4powerLever.hidden = false
REILshutoffLever.onUpdate()
REILshutoffLever.hidden = false
REILshutoffButton.onUpdate()
REILshutoffButton.hidden = false
EESdial.onUpdate()
EESdial.hidden = false
ventSwitch.onUpdate()
ventSwitch.hidden = false
RECU1powerLever.onUpdate()
RECU1powerLever.hidden = false
RECU1caliLeft.onUpdate()
RECU1caliLeft.hidden = false
RECU1caliRight.onUpdate()
RECU1caliRight.hidden = false
RECU2powerLever.onUpdate()
RECU2powerLever.hidden = false
RECU2caliLeft.onUpdate()
RECU2caliLeft.hidden = false
RECU2caliRight.onUpdate()
RECU2caliRight.hidden = false
REILtooltip.enable()
RECUtooltip.enable()
EEStooltip.enable()
PowerTooltip.enable()
},3)
this.hover = false
this.pressed = false
this.active = false
cursor()
printTerminal("booting reactor systems...",5)
printTerminal("initializing all subsystems...",5,0.5)
printTerminal("sensors: ONLINE",5, 1)
printTerminal("RECU_2: ONLINE",5, 1.1)
printTerminal("RECU_1: ONLINE",5, 1.15)
printTerminal("EES: ONLINE",5, 1.7)
printTerminal("REIL_1: ONLINE",5, 1.9)
printTerminal("REIL_2: ONLINE",5, 1.95)
printTerminal("REIL_4: ONLINE",5, 2.05)
printTerminal("REIL_3: ONLINE",5, 2.7)
printTerminal("[ALERT] reactor systems enabled", 5,3.2)
calling = true
callingText = "inbound communication from CAPTAIN..."
executeDelayed(function(){
calling = false
currentDialogue = introDialogue
introComplete = true
},3)
}
}
let REIL1powerLever = new Lever(true, 200, 200)
REIL1powerLever.hidden = true
REIL1powerLever.active = false
REIL1powerLever.stroke = primaryCol
REIL1powerLever.fill = bgCol
REIL1powerLever.strokeWeight = 2
REIL1powerLever.width = 35
REIL1powerLever.height = 10
REIL1powerLever.Slength = 45
REIL1powerLever.segments = 3
REIL1powerLever.smooth = false
REIL1powerLever.value = 1
REIL1powerLever.onUpdate = function(){
this.x = this.width/2 + 25
this.y = windowHeight - 250 + this.Slength + 35
}
REIL1powerLever.onValueChange = function(dv){
REIL1power = this.value + 1
}
let REIL2powerLever = new Lever(true, 200, 200)
REIL2powerLever.hidden = true
REIL2powerLever.active = false
REIL2powerLever.stroke = primaryCol
REIL2powerLever.fill = bgCol
REIL2powerLever.strokeWeight = 2
REIL2powerLever.width = 35
REIL2powerLever.height = 10
REIL2powerLever.Slength = 45
REIL2powerLever.segments = 3
REIL2powerLever.smooth = false
REIL2powerLever.value = 1
REIL2powerLever.onUpdate = function(){
this.x = (this.width/2 + 25)*2
this.y = windowHeight - 250 + this.Slength + 35
}
REIL2powerLever.onValueChange = function(dv){
REIL2power = this.value + 1
}
let REIL3powerLever = new Lever(true, 200, 200)
REIL3powerLever.hidden = true
REIL3powerLever.active = false
REIL3powerLever.stroke = primaryCol
REIL3powerLever.fill = bgCol
REIL3powerLever.strokeWeight = 2
REIL3powerLever.width = 35
REIL3powerLever.height = 10
REIL3powerLever.Slength = 45
REIL3powerLever.segments = 3
REIL3powerLever.smooth = false
REIL3powerLever.value = 1
REIL3powerLever.onUpdate = function(){
this.x = (this.width/2 + 25)*3
this.y = windowHeight - 250 + this.Slength + 35
}
REIL3powerLever.onValueChange = function(dv){
REIL3power = this.value + 1
}
let REIL4powerLever = new Lever(true, 200, 200)
REIL4powerLever.hidden = true
REIL4powerLever.active = false
REIL4powerLever.stroke = primaryCol
REIL4powerLever.fill = bgCol
REIL4powerLever.strokeWeight = 2
REIL4powerLever.width = 35
REIL4powerLever.height = 10
REIL4powerLever.Slength = 45
REIL4powerLever.segments = 3
REIL4powerLever.smooth = false
REIL4powerLever.value = 1
REIL4powerLever.onUpdate = function(){
this.x = (this.width/2 + 25)*4
this.y = windowHeight - 250 + this.Slength + 35
}
REIL4powerLever.onValueChange = function(dv){
REIL4power = this.value + 1
}
REILshutoffLever = new Slider("Box", true, 200,200)
REILshutoffLever.hidden = true
REILshutoffLever.active = false
REILshutoffLever.stroke = primaryCol
REILshutoffLever.fill = bgCol
REILshutoffLever.strokeWeight = 2
REILshutoffLever.width = 10
REILshutoffLever.height = 10
REILshutoffLever.Slength = 25
REILshutoffLever.segments = 5
REILshutoffLever.smooth = false
REILshutoffLever.value = REILshutoffLever.segments
REILshutoffLever.onUpdate = function(){
this.x = 200 + 70 - 15
this.y = windowHeight - 250 + this.Slength + 42
}
REILshutoffButton = new Button("box",200,200)
REILshutoffButton.hidden = true
REILshutoffButton.active = false
REILshutoffButton.stroke = [250,0,0]
REILshutoffButton.fill = [10,0,0]
REILshutoffButton.strokeWeight = 2
REILshutoffButton.width = 30
REILshutoffButton.height = 30
REILshutoffButton.onUpdate = function(){
this.x = 200 + 70 - 55
this.y = windowHeight - 250 + 40
if(!REILshutoff){
this.stroke = [250,0,0]
if(REILshutoffLever.value == 0){
this.fill = [250,0,0]
}else{
this.fill = [10,0,0]
}
}else{
this.stroke = primaryCol
if(REILshutoffLever.value == REILshutoffLever.segments){
this.fill = primaryCol
}else{
this.fill = darkCol
}
}
}
REILshutoffButton.onPressEnd = function(){
if(REILshutoffLever.value == 0 && !REILshutoff && REILshutoffAvailible){
REILshutoffAvailible = false
warnTerminal("[ALERT] emergency REIL shutoff engaged!",5)
printTerminal("shutting down all REILs...",5,1)
executeDelayed(function(){
REILshutoff = true
REILshutoffAvailible = true
REIL1enabled = false
REIL2enabled = false
REIL3enabled = false
REIL4enabled = false
REIL1power = 0
REIL1power = 0
REIL1power = 0
REIL1power = 0
printTerminal("all REILs offline",5)
},2)
}
if(REILshutoffLever.value == REILshutoffLever.segments && REILshutoff && REILshutoffAvailible){
REILshutoffAvailible = false
warnTerminal("[ALERT] rebooting REILs...",5)
printTerminal("re-engaging power supply...",5,1)
printTerminal("priming REIL systems...",5,3)
printTerminal("recalibrating REILs...",5,4)
printTerminal("spooling up...",5,6)
printTerminal("25% spooled",5,7)
printTerminal("50% spooled",5,8)
printTerminal("75% spooled",5,9)
printTerminal("fully spooled",5,12)
printTerminal("re-engaging all REILs",5,13)
executeDelayed(function(){
REILshutoff = false
REIL1enabled = true
REIL2enabled = true
REIL3enabled = true
REIL4enabled = true
printTerminal("all REILs online",5)
REILshutoffAvailible = true
},14)
}
}
let RECU1powerLever = new Slider("Box",true, 200, 200)
RECU1powerLever.hidden = true
RECU1powerLever.active = false
RECU1powerLever.stroke = primaryCol
RECU1powerLever.fill = bgCol
RECU1powerLever.strokeWeight = 2
RECU1powerLever.width = 35
RECU1powerLever.height = 10
RECU1powerLever.Slength = 45
RECU1powerLever.segments = 3
RECU1powerLever.smooth = false
RECU1powerLever.value = 1
RECU1powerLever.onUpdate = function(){
this.x = (this.width/2 + 25)*1
this.y = windowHeight - 250 + this.Slength + 130
}
RECU1powerLever.onValueChange = function(dv){
RECU1power = this.value + 1
}
let RECU2powerLever = new Slider("Box",true, 200, 200)
RECU2powerLever.hidden = true
RECU2powerLever.active = false
RECU2powerLever.stroke = primaryCol
RECU2powerLever.fill = bgCol
RECU2powerLever.strokeWeight = 2
RECU2powerLever.width = 35
RECU2powerLever.height = 10
RECU2powerLever.Slength = 45
RECU2powerLever.segments = 3
RECU2powerLever.smooth = false
RECU2powerLever.value = 1
RECU2powerLever.onUpdate = function(){
this.x = (this.width/2 + 25)*1
this.y = windowHeight - 250 + this.Slength + 180
}
RECU2powerLever.onValueChange = function(dv){
RECU2power = this.value + 1
}
let RECU1caliLeft = new Button("box",200,200)
RECU1caliLeft.active = false
RECU1caliLeft.hidden = true
RECU1caliLeft.x = 10
RECU1caliLeft.y = 10
RECU1caliLeft.width = 15
RECU1caliLeft.height = 15
RECU1caliLeft.shrink = 0
RECU1caliLeft.Pshrink = 0
RECU1caliLeft.stroke = primaryCol
RECU1caliLeft.strokeWeight = 2
RECU1caliLeft.fill = darkCol
RECU1caliLeft.text = ""
RECU1caliLeft.textSize = 15
RECU1caliLeft.triangleSize = 5
RECU1caliLeft.triangleRotation = Math.PI
RECU1caliLeft.render = function(){
let x = this.x
let y = this.y
let w = this.width
let h = this.height
let s = this.shrink
fill((this.hover == this.pressed)?this.fill:this.stroke)
stroke(this.stroke)
strokeWeight(this.strokeWeight)
rect(x + s,y + s,w - s*2,h - s*2)
noStroke()
fill(this.stroke)
textAlign(CENTER,CENTER)
textSize(this.textSize)
text(this.text, x,y,w,h)
fill((this.hover == this.pressed)?this.stroke:this.fill)
noStroke()
x = x + w/2 + (this.triangleSize*(0.2)-(this.shrink*0.2))
y = y + h/2
triangle(x + cos(this.triangleRotation + (PI*2/3)*0)*(this.triangleSize-this.shrink),y + sin(this.triangleRotation + (PI*2/3)*0)*(this.triangleSize-this.shrink),
x + cos(this.triangleRotation + (PI*2/3)*1)*(this.triangleSize-this.shrink), y + sin(this.triangleRotation + (PI*2/3)*1)*(this.triangleSize-this.shrink),
x + cos(this.triangleRotation + (PI*2/3)*2)*(this.triangleSize-this.shrink),y + sin(this.triangleRotation + (PI*2/3)*2)*(this.triangleSize-this.shrink))
}
RECU1caliLeft.onUpdate = function(){
this.x = 70
this.y = windowHeight - 250 + 145
}
RECU1caliLeft.onHoverBegin = function(){
cursor(HAND)
}
RECU1caliLeft.onHoverEnd = function(){
cursor()
}
RECU1caliLeft.onPressEnd = function(){
RECU1calibration = (RECU1calibration + 1 + 0.1)%2 - 1
}
let RECU1caliRight = new Button("box",200,200)
RECU1caliRight.active = false
RECU1caliRight.hidden = true
RECU1caliRight.x = 10
RECU1caliRight.y = 10
RECU1caliRight.width = 15
RECU1caliRight.height = 15
RECU1caliRight.shrink = 0
RECU1caliRight.Pshrink = 0
RECU1caliRight.stroke = primaryCol
RECU1caliRight.strokeWeight = 2
RECU1caliRight.fill = darkCol
RECU1caliRight.text = ""
RECU1caliRight.textSize = 15
RECU1caliRight.triangleSize = 5
RECU1caliRight.triangleRotation = 0
RECU1caliRight.render = function(){
let x = this.x
let y = this.y
let w = this.width
let h = this.height
let s = this.shrink
fill((this.hover == this.pressed)?this.fill:this.stroke)
stroke(this.stroke)
strokeWeight(this.strokeWeight)
rect(x + s,y + s,w - s*2,h - s*2)
noStroke()
fill(this.stroke)
textAlign(CENTER,CENTER)
textSize(this.textSize)
text(this.text, x,y,w,h)
fill((this.hover == this.pressed)?this.stroke:this.fill)
noStroke()
x = x + w/2 - (this.triangleSize*(0.2)-(this.shrink*0.2))
y = y + h/2
triangle(x + cos(this.triangleRotation + (PI*2/3)*0)*(this.triangleSize-this.shrink),y + sin(this.triangleRotation + (PI*2/3)*0)*(this.triangleSize-this.shrink),
x + cos(this.triangleRotation + (PI*2/3)*1)*(this.triangleSize-this.shrink), y + sin(this.triangleRotation + (PI*2/3)*1)*(this.triangleSize-this.shrink),
x + cos(this.triangleRotation + (PI*2/3)*2)*(this.triangleSize-this.shrink),y + sin(this.triangleRotation + (PI*2/3)*2)*(this.triangleSize-this.shrink))
}
RECU1caliRight.onUpdate = function(){
this.x = 90
this.y = windowHeight - 250 + 145
}
RECU1caliRight.onHoverBegin = function(){
cursor(HAND)
}
RECU1caliRight.onHoverEnd = function(){
cursor()
}
RECU1caliRight.onPressEnd = function(){
RECU1calibration = (RECU1calibration + 1 - 0.1)%2 - 1
}
let RECU2caliLeft = new Button("box",200,200)
RECU2caliLeft.active = false
RECU2caliLeft.hidden = true
RECU2caliLeft.x = 10
RECU2caliLeft.y = 10
RECU2caliLeft.width = 15
RECU2caliLeft.height = 15
RECU2caliLeft.shrink = 0
RECU2caliLeft.Pshrink = 0
RECU2caliLeft.stroke = primaryCol
RECU2caliLeft.strokeWeight = 2
RECU2caliLeft.fill = darkCol
RECU2caliLeft.text = ""
RECU2caliLeft.textSize = 15
RECU2caliLeft.triangleSize = 5
RECU2caliLeft.triangleRotation = Math.PI
RECU2caliLeft.render = function(){
let x = this.x
let y = this.y
let w = this.width
let h = this.height
let s = this.shrink
fill((this.hover == this.pressed)?this.fill:this.stroke)
stroke(this.stroke)
strokeWeight(this.strokeWeight)
rect(x + s,y + s,w - s*2,h - s*2)
noStroke()
fill(this.stroke)
textAlign(CENTER,CENTER)
textSize(this.textSize)
text(this.text, x,y,w,h)
fill((this.hover == this.pressed)?this.stroke:this.fill)
noStroke()
x = x + w/2 + (this.triangleSize*(0.2)-(this.shrink*0.2))
y = y + h/2
triangle(x + cos(this.triangleRotation + (PI*2/3)*0)*(this.triangleSize-this.shrink),y + sin(this.triangleRotation + (PI*2/3)*0)*(this.triangleSize-this.shrink),
x + cos(this.triangleRotation + (PI*2/3)*1)*(this.triangleSize-this.shrink), y + sin(this.triangleRotation + (PI*2/3)*1)*(this.triangleSize-this.shrink),
x + cos(this.triangleRotation + (PI*2/3)*2)*(this.triangleSize-this.shrink),y + sin(this.triangleRotation + (PI*2/3)*2)*(this.triangleSize-this.shrink))
}
RECU2caliLeft.onUpdate = function(){
this.x = 70
this.y = windowHeight - 250 + 195
}
RECU2caliLeft.onHoverBegin = function(){
cursor(HAND)
}
RECU2caliLeft.onHoverEnd = function(){
cursor()
}
RECU2caliLeft.onPressEnd = function(){
RECU2calibration = (RECU2calibration + 1 + 0.1)%2 - 1
}
let RECU2caliRight = new Button("box",200,200)
RECU2caliRight.active = false
RECU2caliRight.hidden = true
RECU2caliRight.x = 10
RECU2caliRight.y = 10
RECU2caliRight.width = 15
RECU2caliRight.height = 15
RECU2caliRight.shrink = 0
RECU2caliRight.Pshrink = 0
RECU2caliRight.stroke = primaryCol
RECU2caliRight.strokeWeight = 2
RECU2caliRight.fill = darkCol
RECU2caliRight.text = ""
RECU2caliRight.textSize = 15
RECU2caliRight.triangleSize = 5
RECU2caliRight.triangleRotation = 0
RECU2caliRight.render = function(){
let x = this.x
let y = this.y
let w = this.width
let h = this.height
let s = this.shrink
fill((this.hover == this.pressed)?this.fill:this.stroke)
stroke(this.stroke)
strokeWeight(this.strokeWeight)
rect(x + s,y + s,w - s*2,h - s*2)
noStroke()
fill(this.stroke)
textAlign(CENTER,CENTER)
textSize(this.textSize)
text(this.text, x,y,w,h)
fill((this.hover == this.pressed)?this.stroke:this.fill)
noStroke()
x = x + w/2 - (this.triangleSize*(0.2)-(this.shrink*0.2))
y = y + h/2
triangle(x + cos(this.triangleRotation + (PI*2/3)*0)*(this.triangleSize-this.shrink),y + sin(this.triangleRotation + (PI*2/3)*0)*(this.triangleSize-this.shrink),
x + cos(this.triangleRotation + (PI*2/3)*1)*(this.triangleSize-this.shrink), y + sin(this.triangleRotation + (PI*2/3)*1)*(this.triangleSize-this.shrink),
x + cos(this.triangleRotation + (PI*2/3)*2)*(this.triangleSize-this.shrink),y + sin(this.triangleRotation + (PI*2/3)*2)*(this.triangleSize-this.shrink))
}
RECU2caliRight.onUpdate = function(){
this.x = 90
this.y = windowHeight - 250 + 195
}
RECU2caliRight.onHoverBegin = function(){
cursor(HAND)
}
RECU2caliRight.onHoverEnd = function(){
cursor()
}
RECU2caliRight.onPressEnd = function(){
RECU2calibration = (RECU2calibration + 1 - 0.1)%2 - 1
}
let EESdial = new Dial(false, 200, 200)
EESdial.hidden = true
EESdial.active = false
EESdial.segments = 3
EESdial.value = 1
EESdial.minAngle = 60
EESdial.maxAngle = 300
EESdial.radius = 20
EESdial.fill = bgCol
EESdial.stroke = primaryCol
EESdial.strokeWeight = 2
EESdial.onUpdate = function(){
this.x = windowWidth - 40
this.y = windowHeight - 250 + 50
}
EESdial.onValueChange = function(dv){
EESpower = this.value + 1
}
let ventSwitch = new ToggleButton("box",200,200)
ventSwitch.active = false
ventSwitch.hidden = true
ventSwitch.width = 30
ventSwitch.height = 30
ventSwitch.stroke = primaryCol
ventSwitch.fill = darkCol
ventSwitch.strokeWeight = 2
ventSwitch.value = false
ventSwitch.onUpdate = function(){
this.x = windowWidth - 190
this.y = windowHeight - 250 + 45
}
ventSwitch.onPressEnd = function(){
this.value = !this.value
ventActive = this.value
}
let REILtooltip = new TooltipButton("box",200,200)
REILtooltip.active = false
REILtooltip.hidden = true
REILtooltip.width = 10
REILtooltip.height = 10
REILtooltip.fill = bgCol
REILtooltip.stroke = primaryCol
REILtooltip.strokeWeight = 1
REILtooltip.textSize = 8
REILtooltip.tooltipText = "Increasing REIL power will add more heat to the reactor core. Heat output will fall as REIL integrity drops."
REILtooltip.tooltipFill = bgCol
REILtooltip.tooltipStroke = primaryCol
REILtooltip.tooltipWidth = 220
REILtooltip.tooltipHeight = 60
REILtooltip.tooltipTextColor = primaryCol
REILtooltip.onUpdate = function(){
this.x = 190
this.y = windowHeight - 250 + 5
}
let RECUtooltip = new TooltipButton("box",200,200)
RECUtooltip.active = false
RECUtooltip.hidden = true
RECUtooltip.width = 10
RECUtooltip.height = 10
RECUtooltip.fill = bgCol
RECUtooltip.stroke = primaryCol
RECUtooltip.strokeWeight = 1
RECUtooltip.textSize = 8
RECUtooltip.tooltipText = "The RECUs maintain the confinement integrity, but also multiply the core's temperature gain. They must be periodically calibrated so that the two waves align, if you only see one wave, they're calibrated."
RECUtooltip.tooltipFill = bgCol
RECUtooltip.tooltipStroke = primaryCol
RECUtooltip.tooltipWidth = 220
RECUtooltip.tooltipHeight = 100
RECUtooltip.tooltipTextColor = primaryCol
RECUtooltip.onUpdate = function(){
this.x = 175
this.y = windowHeight - 250 + 105
}
let EEStooltip = new TooltipButton("box",200,200)
EEStooltip.active = false
EEStooltip.hidden = true
EEStooltip.width = 10
EEStooltip.height = 10
EEStooltip.fill = bgCol
EEStooltip.stroke = primaryCol
EEStooltip.strokeWeight = 1
EEStooltip.textSize = 8
EEStooltip.tooltipTextSize = 11
EEStooltip.tooltipText = "The EES is the main way to cool the core. Higher levels (rightmost) will absorb more energy from the core, but also heat the coolant more. The hotter the coolant, the more power is generated. The rate at which the core is cooled is propottional to the temperature difference between the coolant and core. The vent will directly cool the coolant."
EEStooltip.tooltipFill = bgCol
EEStooltip.tooltipStroke = primaryCol
EEStooltip.tooltipWidth = 240
EEStooltip.tooltipHeight = 120
EEStooltip.tooltipTextColor = primaryCol
EEStooltip.tooltipRight = false
EEStooltip.onUpdate = function(){
this.x = windowWidth - 150
this.y = windowHeight - 250 + 5
}
let PowerTooltip = new TooltipButton("box",200,200)
PowerTooltip.active = false
PowerTooltip.hidden = true
PowerTooltip.width = 10
PowerTooltip.height = 10
PowerTooltip.fill = bgCol
PowerTooltip.stroke = primaryCol
PowerTooltip.strokeWeight = 1
PowerTooltip.textSize = 8
PowerTooltip.tooltipTextSize = 11
PowerTooltip.tooltipText = "The purpose of the reactor is to generate power. Power is generated by heating the coolant above 100 degrees. If power generation is lower than the required power, power storage will begin to drain. Do not run out of power. If the battery is full and you generate more than " + maxOvergen + " power units over the requirement, the excess power will damage systems such as the REILs."
PowerTooltip.tooltipFill = bgCol
PowerTooltip.tooltipStroke = primaryCol
PowerTooltip.tooltipWidth = 250
PowerTooltip.tooltipHeight = 120
PowerTooltip.tooltipTextColor = primaryCol
PowerTooltip.tooltipRight = false
PowerTooltip.onUpdate = function(){
this.x = windowWidth - 155
this.y = windowHeight - 250 + 95
}
let exitButton = new Button("box", 200, 10)
exitButton.hidden = true
exitButton.active = false
exitButton.width = 30
exitButton.height = 30
exitButton.col1 = [230,0,0]
exitButton.col2 = [30,0,0]
exitButton.stroke = exitButton.col2
exitButton.strokeWeight = 2
exitButton.fill = exitButton.col1
exitButton.Pfill = exitButton.fill
exitButton.Pstroke = exitButton.stroke
exitButton.text = "x"
exitButton.textSize = 25
exitButton.textColor = exitButton.col2
exitButton.PtextColor = exitButton.col2
exitButton.render = function(){
// animations
let Ptimer = this.timeSincePressedChange
let Htimer = min(this.timeSinceHoverChange, Ptimer)
if(this.hover && !this.pressed){ // when hovered over
this.fill = ClerpColor(this.Pfill, this.col1, Htimer*5)
this.textColor = ClerpColor(this.PtextColor, this.col2, Htimer*5)
}else if(this.pressed){ // when clicked
this.fill = ClerpColor(this.Pfill, this.col2, Ptimer*5)
this.textColor = ClerpColor(this.PtextColor, this.col1, Htimer*5)
}else{ // when not hovered or clicked
this.fill = ClerpColor(this.Pfill, this.col2, Htimer*5)
this.textColor = ClerpColor(this.PtextColor, this.col1, Htimer*5)
}
fill(this.fill)
stroke(this.textColor)
strokeWeight(this.strokeWeight)
rect(this.x, this.y, this.width, this.height)
textAlign(CENTER,CENTER)
noStroke()
fill(this.textColor)
textSize(this.textSize)
text(this.text,this.x, this.y, this.width, this.height)
let x = this.x
let y = this.y
let w = this.width
let h = this.height
}
exitButton.onHoverBegin = function(){
this.Pfill = this.fill
this.PtextColor = this.textColor
UI_hover1.play()
UI_hover1.setVolume(0.1)
cursor(HAND)
}
exitButton.onPressBegin = function(){
this.Pfill = this.fill
this.PtextColor = this.textColor
}
exitButton.onPressEnd = function(){
this.Pfill = this.fill
this.PtextColor = this.textColor
screen = "game"
screenLoaded = false
if(reactorOnline && reactorHumming){
REACTOR_HUM.stop()
reactorHumming = false
}
}
exitButton.onHoverEnd = function(){
this.Pfill = this.fill
this.PtextColor = this.textColor
cursor()
}
function gameButtonsSetup(){
centerX = windowWidth/2
centerY = windowHeight/2
reactorButton.onUpdate = function(){
this.x = windowWidth - 200
this.y = 200
}
exitButton.onUpdate = function(){
this.x = windowWidth - 35
this.y = 5
}
}
let RECU1r = 0
let RECU2r = 0
function coreFlux(t){
return sin(t*0.1)*10 + cos(t*0.3)*3*sin(t*0.05)
}
function game(){
// background game logic
if(!reactorOnline && shieldOnline){
shield += 20*dt
if(shield > 100) shield = 100
}
if(reactorOnline){
let addedEnergy = coreFlux(time)
addedEnergy += ((temperature - 3000)*0.012 )*(1+abs(RECU1calibration)+abs(RECU2calibration)) // reaction criticality
if(reactorSurge) addedEnergy += 60
if(REIL1enabled) addedEnergy += REIL1power * 3 * (sqrt(REIL1integrity/100))
if(REIL2enabled) addedEnergy += REIL2power * 3 * (sqrt(REIL2integrity/100))
if(REIL3enabled) addedEnergy += REIL3power * 3 * (sqrt(REIL3integrity/100))
if(REIL4enabled) addedEnergy += REIL4power * 3 * (sqrt(REIL4integrity/100))
RECU1calibration = (RECU1calibration + ( (FTLengaged?2:1)* coreFlux(-time+100)/(abs(coreFlux(time/2))+0.1) )*dt/(300*RECU1power*0.5) + 1)%2 - 1
RECU2calibration = (RECU2calibration + ( (FTLengaged?2:1)* coreFlux(time+100)/(abs(coreFlux(-time/2) )+0.1))*dt/(300*RECU2power*0.5) + 1)%2 - 1
addedEnergy *= ( RECU1power*0.25*(1-(0.25*abs(RECU1calibration))) + RECU2power*0.25*(1-(0.25*abs(RECU2calibration))) )
temperature += addedEnergy*dt
let removedEnergy = 0
let diffMult = (temperature - coolantTemp)/1000
removedEnergy = EESpower * 8 * diffMult
temperature -= removedEnergy*dt
coolantTemp += removedEnergy*dt*diffMult*0.8
coolantTemp -= 15*dt*((coolantTemp + 100)/400)*((powerStorage >= maxPowerStorage)&&(powerGen-powerRequired > maxOvergen)?0.5:1)
if(ventActive) coolantTemp -= 10*dt
if(coolantTemp < -100) coolantTemp = -100
let deltaShield = 0
deltaShield -= temperature/1000
deltaShield += RECU1power*(1-(0.25*abs(RECU1calibration))) + RECU2power*(1-(0.25*abs(RECU2calibration)))
shield += deltaShield*dt
powerGen = min(max(0,coolantTemp*0.6 - 60),3000)
powerRequired = powerDraw + (REIL1power + REIL2power + REIL3power + REIL4power)*4 + (RECU1power + RECU2power)*5 + (FTLengaged?500:0) + (thrustersEngaged?100:0) + (lifeSupportEngaged?50:0)
powerStorage += (powerGen - powerRequired)*dt
powerStorage = max(0, min( powerStorage, maxPowerStorage))
if(REIL1enabled) REIL1integrity -= max(0.025*dt*(REIL1power/2)+((powerGen-powerRequired > maxOvergen && powerStorage >= maxPowerStorage)?0.1*dt:0),0)
if(REIL2enabled) REIL2integrity -= max(0.025*dt*(REIL2power/2)+((powerGen-powerRequired > maxOvergen && powerStorage >= maxPowerStorage)?0.1*dt:0),0)
if(REIL3enabled) REIL3integrity -= max(0.025*dt*(REIL3power/2)+((powerGen-powerRequired > maxOvergen && powerStorage >= maxPowerStorage )?0.1*dt:0),0)
if(REIL4enabled) REIL4integrity -= max(0.025*dt*(REIL4power/2)+((powerGen-powerRequired > maxOvergen && powerStorage >= maxPowerStorage)?0.1*dt:0),0)
REIL1integrity = max(0,REIL1integrity)
REIL2integrity = max(0,REIL2integrity)
REIL3integrity = max(0,REIL3integrity)
REIL4integrity = max(0,REIL4integrity)
if(temperature < 500 && stalloutWarnTimer.value > 10){
warnTerminal("[WARN] reactor temperature low, stallout possible!",5)
stalloutWarnTimer.value = 0
}
if(temperature < 0){
temperature = 20
reactorOnline = false
warnTerminal("[WARN] REACTOR STALLOUT, RESTART REACTOR IMMEDIATELY!",10)
startupLever.enable()
startupLever.value = startupLever.segments
}
let powerPercentage = powerStorage/maxPowerStorage
if(powerPercentage < 0.25 && lowPowerWarnTimer.value > 10){
warnTerminal("[WARN] POWER LOW, INCREASE POWER OUTPUT IMMEDIATELY",5)
lowPowerWarnTimer.value = 0
}
if(powerStorage <= 0){
powerFailureTimer.paused = false
powerFailureImminent = true
if(powerFailureTimer.value >= 10){
causeOfDeath = "power failure"
screenLoaded = false
screen = "game over"
REACTOR_HUM.stop()
reactorOnline = false
powerFailureImminent = false
}
}else{
powerFailureImminent = false
powerFailureTimer.paused = true
powerFailureTimer.value -= dt
powerFailureTimer.value = max(0, powerFailureTimer.value)
}
if(shield > 100) shield = 100
if(shield < 50 && shieldWarnTimer.value > 10){
printTerminalColor("[WARN] SHIELD INTEGRITY LOW, REDUCE CORE TEMPERATURE IMMEDIATELY",[255,100,0],5)
shieldWarnTimer.value = 0
}else if(shield < 100 && shieldWarnTimer.value > 10){
warnTerminal("[WARN] shield integrity dropping!",5)
shieldWarnTimer.value = 0
}
if(shield <= 0 && !meltdown){
printTerminalColor("[DANGER] REACTOR SHIELD FAILURE",[255,0,0],10)
printTerminalColor("[DANGER] EXPLOSION IMMINENT",[255,0,0],10,1)
printTerminalColor("[PRIOTITY ALERT] ALL PERSONELL ABANDON SHIP",[255,0,0],10,5)
meltdown = true
// make meltdown sequence
executeDelayed(function(){
causeOfDeath = "reactor explosion"
screenLoaded = false
screen = "game over"
REACTOR_HUM.stop()
reactorOnline = false
powerFailureImminent = false
}, 10)
}
// random events
if(randomEventTimer.value > 30){
let jumpChance = (1/120)*dt
if(Math.random() < jumpChance && !FTLengaged){
randomEventTimer.value = -40
warnTerminal("[ALERT] FTL activating in 10 seconds!",10)
warnTerminal("[ALERT] FTL engaged!",5,10)
printTerminal("ETA: 45 seconds",10,10)
executeDelayed(function(){
FTLengaged = true
},10)
executeDelayed(function(){
FTLengaged = false
printTerminal("[ALERT] FTL disengaged!",5)
},55)
}
let surgeChance = (1/90)*dt*(temperature/2000)
if(Math.random() < surgeChance){
randomEventTimer.value = -10
reactorSurge = true
warnTerminal("[WARN] REACTOR SURGE DETECTED!!",20)
executeDelayed(function(){
reactorSurge = false
},20)
}
}
}
centerX = windowWidth/2
centerY = windowHeight/2
if(screen == "game"){
if(!screenLoaded){
for(let button of buttons){
button.hidden = true
button.active = false
}
if(timer1.value >= 5){
flicker1.paused = false
flicker2.paused = false
flicker3.paused = false
reactorButton.hidden = false
reactorButton.active = true
terminalPaused = false
screenLoaded = true
}
}else{
reactorButton.hidden = !flicker1.value
if(flicker2.value){
noFill()
strokeJoin(ROUND)
stroke(primaryCol)
strokeWeight(30)
rect(centerX + 50, 200, (windowWidth - 200) - (centerX + 50), windowHeight - 300)
stroke(darkCol)
strokeWeight(20)
rect(centerX + 50, 200, (windowWidth - 200) - (centerX + 50), windowHeight - 300)
strokeJoin(MITER)
}
if(flicker3.value){
noFill()
strokeJoin(ROUND)
stroke(primaryCol)
strokeWeight(30)
rect( 150, 200, (centerX - 50) - 150, windowHeight - 300)
stroke(darkCol)
strokeWeight(20)
rect( 150, 200, (centerX - 50) - 150, windowHeight - 300)
strokeJoin(MITER)
}
}
}
if(screen == "reactor"){
if(!screenLoaded){
exitButton.enable()
startupLever.hidden = false
shieldLever.hidden = false
systemPowerLever.enable()
if(systemsEnabled) systemPowerLever.active = false
if(reactorOnline){
REIL1powerLever.enable()
REIL2powerLever.enable()
REIL3powerLever.enable()
REIL4powerLever.enable()
REILshutoffLever.enable()
REILshutoffButton.enable()
EESdial.enable()
ventSwitch.enable()
RECU1powerLever.enable()
RECU1caliLeft.enable()
RECU1caliRight.enable()
RECU2powerLever.enable()
RECU2caliLeft.enable()
RECU2caliRight.enable()
REILtooltip.enable()
RECUtooltip.enable()
EEStooltip.enable()
PowerTooltip.enable()
}
screenLoaded = true
}
if(reactorOnline && !reactorHumming){
REACTOR_HUM.setVolume(1.0)
REACTOR_HUM.rate(1.0)
REACTOR_HUM.loop()
reactorHumming = true
}
startupLever.onUpdate()
shieldLever.onUpdate()
systemPowerLever.onUpdate()
stroke(primaryCol)
strokeWeight(1)
// control panel
line(0, round(windowHeight - 250) + 0.5, windowWidth, round(windowHeight - 250) + 0.5)
noFill()
strokeWeight(2)
stroke(primaryCol)
rect(windowWidth/2 - 80, windowHeight - 165, 160, 80)
noStroke()
fill(primaryCol)
textSize(10)
textFont(consolas)
textAlign(CENTER,CENTER)
text("ignition",windowWidth/2,windowHeight - 125 - 33)
text("shield",windowWidth/2 + 45,windowHeight - 125 - 33)
text("power",windowWidth/2 - 45,windowHeight - 125 - 33)
textFont("sans-serif")
// controls decorations
if(systemsEnabled){
// REILs
noFill()
strokeWeight(2)
stroke(primaryCol)
rect(20, windowHeight - 250 + 20, 172, 70)
noStroke()
fill(primaryCol)
textSize(12)
textFont(consolas)
textAlign(CENTER,CENTER)
text("REILs (energy injection)",20, windowHeight - 250, 170, 20)
// REIL shutoff
noFill()
strokeWeight(2)
stroke(primaryCol)
rect(200, windowHeight - 250 + 20, 70, 70)
noStroke()
fill(primaryCol)
textSize(10)
textFont(consolas)
textAlign(CENTER,CENTER)
text("emergency",235, windowHeight - 250 + 28)
text("shutoff",235, windowHeight - 250 + 81)
// RECUs
noFill()
strokeWeight(2)
stroke(primaryCol)
rect(20, windowHeight - 250 + 120, 170, 115)
if(shieldOnline){
strokeWeight(2)
stroke(darkishCol)
let graphSegments = 30
for(let i = 0; i < graphSegments; i++){
let tOff = (8*PI)/graphSegments
let y1 = windowHeight - 250 + 140 + 25/2 - (sin(time*PI + i*tOff)*9*(RECU1power/4))
let y2 = windowHeight - 250 + 140 + 25/2 - (sin(time*PI + (i+1)*tOff)*9*(RECU1power/4))
let xOff = 70/graphSegments
let x = 110
line(x + xOff*i, y1, x + xOff*(i+1), y2)
}
strokeWeight(1)
stroke(primaryCol)
graphSegments = 30
for(let i = 0; i < graphSegments; i++){
let tOff = (8*PI)/graphSegments
let y1 = windowHeight - 250 + 140 + 25/2 - (sin(time*PI + i*tOff + RECU1calibration*PI)*9*(RECU1power/4))
let y2 = windowHeight - 250 + 140 + 25/2 - (sin(time*PI + (i+1)*tOff + RECU1calibration*PI)*9*(RECU1power/4))
let xOff = 70/graphSegments
let x = 110
line(x + xOff*i, y1, x + xOff*(i+1), y2)
}
}else{
noStroke()
fill(primaryCol)
textSize(14)
textFont(consolas)
textAlign(CENTER,CENTER)
text("OFFLINE",110, windowHeight - 250 + 140, 70, 25)
}
noFill()
strokeWeight(2)
stroke(primaryCol)
rect(110, windowHeight - 250 + 140, 70, 25)
// RECU 2
if(shieldOnline){
strokeWeight(2)
stroke(darkishCol)
let graphSegments = 30
for(let i = 0; i < graphSegments; i++){
let tOff = (8*PI)/graphSegments
let y1 = windowHeight - 250 + 190 + 25/2 - (sin(time*PI + i*tOff)*9*(RECU2power/4))
let y2 = windowHeight - 250 + 190 + 25/2 - (sin(time*PI + (i+1)*tOff)*9*(RECU2power/4))
let xOff = 70/graphSegments
let x = 110
line(x + xOff*i, y1, x + xOff*(i+1), y2)
}
strokeWeight(1)
stroke(primaryCol)
graphSegments = 30
for(let i = 0; i < graphSegments; i++){
let tOff = (8*PI)/graphSegments
let y1 = windowHeight - 250 + 190 + 25/2 - (sin(time*PI + i*tOff + RECU2calibration*PI)*9*(RECU2power/4))
let y2 = windowHeight - 250 + 190 + 25/2 - (sin(time*PI + (i+1)*tOff + RECU2calibration*PI)*9*(RECU2power/4))
let xOff = 70/graphSegments
let x = 110
line(x + xOff*i, y1, x + xOff*(i+1), y2)
}
}else{
noStroke()
fill(primaryCol)
textSize(14)
textFont(consolas)
textAlign(CENTER,CENTER)
text("OFFLINE",110, windowHeight - 250 + 190, 70, 25)
}
noFill()
strokeWeight(2)
stroke(primaryCol)
rect(110, windowHeight - 250 + 190, 70, 25)
noStroke()
fill(primaryCol)
textSize(12)
textFont(consolas)
textAlign(CENTER,CENTER)
text("RECUs (confinement)",20, windowHeight - 250 + 100, 170, 20)
// EES
noFill()
strokeWeight(2)
stroke(primaryCol)
rect(windowWidth - 200, windowHeight - 250 + 20, 190, 60)
rect(windowWidth - 150, windowHeight - 250 + 50, 80, 20)
noStroke()
fill(primaryCol)
textSize(12)
textFont(consolas)
textAlign(CENTER,CENTER)
text("EES (cooling)",windowWidth - 160, windowHeight - 250, 150, 20)
textSize(10)
text("coolant temp.",windowWidth - 150, windowHeight - 250 + 25, 80, 20)
text("vent",windowWidth - 200, windowHeight - 250 + 20, 50, 25)
textSize(11)
text(round(coolantTemp) + " °C",windowWidth - 150, windowHeight - 250 + 50, 80, 20)
// power generation
noFill()
strokeWeight(2)
stroke(primaryCol)
rect(windowWidth - 160, windowHeight - 250 + 110, 150, 110)
rect(windowWidth - 90, windowHeight - 250 + 120, 70, 18)
rect(windowWidth - 90, windowHeight - 250 + 142, 70, 18)
rect(windowWidth - 90, windowHeight - 250 + 164, 70, 18)
// indicator logic
if(powerStorage/maxPowerStorage < 0.25){
stroke(errorCol)
}else if(powerGen < powerRequired){
stroke(warnCol)
}else if(powerGen > powerRequired + maxOvergen && powerStorage >= maxPowerStorage){
stroke(warnCol)
}else{
stroke(primaryCol)
}
rect(windowWidth - 150, windowHeight - 250 + 190, 130, 20)
noStroke()
textAlign(CENTER,CENTER)
textFont("sans-serif")
if(powerStorage/maxPowerStorage < 0.25){
fill(errorCol)
text("POWER LOW",windowWidth - 150, windowHeight - 250 + 190, 130, 20)
}else if(powerGen < powerRequired){
fill(warnCol)
text("DISCHARGING",windowWidth - 150, windowHeight - 250 + 190, 130, 20)
}else if(powerGen > powerRequired + maxOvergen && powerStorage >= maxPowerStorage){
fill(warnCol)
text("EXCESS POWER",windowWidth - 150, windowHeight - 250 + 190, 130, 20)
}else{
fill(primaryCol)
text("OK",windowWidth - 150, windowHeight - 250 + 190, 130, 20)
}
fill(primaryCol)
noStroke()
rect(windowWidth - 90, windowHeight - 250 + 164, 70*(powerStorage/maxPowerStorage), 18)
noStroke()
fill(primaryCol)
textSize(12)
textFont(consolas)
textAlign(CENTER,CENTER)
text("power generation",windowWidth - 160, windowHeight - 250 + 90, 150, 20)
text("req.",windowWidth - 160, windowHeight - 250 + 120, 70, 20)
text("gen.",windowWidth - 160, windowHeight - 250 + 140, 70, 20)
text("stor.",windowWidth - 160, windowHeight - 250 + 160, 70, 20)
text(round(powerRequired),windowWidth - 90, windowHeight - 250 + 120, 70, 18)
text(round(powerGen),windowWidth - 90, windowHeight - 250 + 142, 70, 18)
}
// exit button
noStroke()
fill(primaryCol)
rect(windowWidth - 300, 0, 300, 40)
fill(darkCol)
textAlign(LEFT, CENTER)
textSize(18)
text("REACTOR CONTROL", windowWidth - 270, 0, 270, 40)
fill(bgCol)
triangle(windowWidth - 300,0, windowWidth - 300,40, windowWidth - 280,40)
if(systemsEnabled){
// diagnostics
textAlign(LEFT, CENTER)
textSize(18)
fill(primaryCol)
textFont(consolas)
text("temperature: " + round(temperature) + " °C", windowWidth - 210, 40, 230, 30)
if((reactorOnline) && shield < 50) fill(warnCol)
text("confinement integrity: " + (shield<50&&reactorOnline?"! ":"") + ((!reactorOnline && !shieldOnline)?("N/A"):(round(shield,1) + "%")), windowWidth - 310, 70, 350, 30)
textFont("sans-serif")
// E.E.S (energy extraction/cooling system)
push()
translate(centerX, centerY - 125)
noStroke()
fill(primaryCol)
EEScolor = bgCol
if(reactorOnline){
EEScolor = [coolantTemp/25, 50 * (EESpower/2), 100 * (EESpower/2)]
}
rect(-180, -40, 100, 80)
fill(EEScolor)
rect(-170, -30, 20, 60)
rect(-140, -30, 20, 60)
rect(-110, -30, 20, 60)
fill(primaryCol)
rect(80, -40, 100, 80)
fill(EEScolor)
rect(90, -30, 20, 60)
rect(120, -30, 20, 60)
rect(150, -30, 20, 60)
pop()
// reactor core
let coreVibrate = (random()-0.5)*(min(temperature,10000)/2000)
noStroke()
fill(primaryCol)
if(reactorOnline) circle(centerX, centerY - 125, 40 + coreVibrate)
let shieldFlux = sin(time*PI*(0.25))*(5 + (100 - shield)*0.1)
noFill()
stroke(primaryCol)
strokeWeight(3)
if(shieldOnline) circle(centerX, centerY - 125, 60 + shieldFlux)
if(reactorSurge){
fill(warnCol)
noStroke()
if(time%1 < 0.5){
rect(centerX - 60, centerY - 125 - 2.5, 20, 5)
rect(centerX + 40, centerY - 125 - 2.5, 20, 5)
}else{
push()
translate(centerX, centerY - 125)
rotate(PI/4)
rect(-60, -2.5, 20, 5)
rect(40, -2.5, 20, 5)
pop()
push()
translate(centerX, centerY - 125)
rotate(-PI/4)
rect(-60, -2.5, 20, 5)
rect(40, -2.5, 20, 5)
pop()
}
}
// reactor flux
stroke(primaryCol)
strokeWeight(2)
line(centerX, centerY - 125, centerX + 50, centerY - 125 + 50)
line(centerX + 50, centerY - 125 + 50, centerX + 75, centerY - 125 + 50)
fill(bgCol)
rect(centerX + 75, centerY - 125 + 50, 100, 70)
if(reactorOnline){
rect(centerX + 80, centerY - 125 + 55, 90, 40)
line(centerX + 80, centerY - 125 + 75,centerX + 170, centerY - 125 + 75)
strokeWeight(1)
let graphSegments = 20
for(let i = 0; i < graphSegments; i++){
let tOff = 30/graphSegments
let y1 = centerY - 125 + 75 - (coreFlux(time + i*tOff)*1.2)
let y2 = centerY - 125 + 75 - (coreFlux(time + (i+1)*tOff)*1.2)
let xOff = 90/graphSegments
let x = centerX + 80
line(x + xOff*i, y1, x + xOff*(i+1), y2)
}
textAlign(CENTER,CENTER)
textFont(consolas)
textSize(12)
noStroke()
if(temperature < 2500){
fill(primaryCol)
text("SUBCRITICAL",centerX + 80, centerY - 125 + 95, 90, 25)
}else if(temperature >= 2500 && temperature <= 3500){
fill(primaryCol)
text("CRITICAL",centerX + 80, centerY - 125 + 95, 90, 25)
}else{
fill(warnCol)
text("SUPERCRITICAL",centerX + 80, centerY - 125 + 95, 90, 25)
}
}else{
textAlign(CENTER, CENTER)
textSize(16)
noStroke()
fill(primaryCol)
textFont(consolas)
text("OFFLINE",centerX + 75, centerY - 125 + 50, 100, 75)
}
// R.E.C.Us (confinement beams)
push()
translate(centerX, centerY - 125)
let bh = (windowHeight-250)/2
let bw = (windowWidth)/2
let sm1 = RECU1online?RECU1power/2:0
noStroke()
fill(primaryCol)
rect(-40, bh - 140, 80, 30)
rect(-40, bh - 70, 80, 70)
rect(-35, bh - 110, 70, 40)
rect(-20, bh - 150, 40, 20)
if(shieldOnline) rect(-5 - sin(time*PI*sm1)*(1), 30 + shieldFlux/2, 10 + sin(time*PI*sm1)*(2), bh - (30 + shieldFlux/2) )
RECU1r += dt*PI*sm1
for(let i = 0; i < 5; i++){
rect(15 * sin(RECU1r + (i*((2*PI)/5))) - 1, bh - 160, 2, 10)
}
pop()
push()
translate(centerX, centerY - 125)
rotate(PI)
let sm2 = RECU2online?RECU2power/2:0
noStroke()
fill(primaryCol)
rect(-40, bh - 140, 80, 30)
rect(-40, bh - 70, 80, 70)
rect(-35, bh - 110, 70, 40)
rect(-20, bh - 150, 40, 20)
if(shieldOnline) rect(-5 - sin(time*PI*sm2)*(1*sm2), 30 + shieldFlux/2, 10 + sin(time*PI*sm2)*(2*sm2), bh - (30 + shieldFlux/2) )
RECU2r += dt*PI*sm2
for(let i = 0; i < 5; i++){
rect(15 * sin(RECU2r + (i*((2*PI)/5))) - 1, bh - 160, 2, 10)
}
pop()
// R.E.I.Ls (power lasers)
push()
translate(centerX, centerY - 125)
rotate(PI/16)
stroke(primaryCol)
strokeWeight(1)
fill(primaryCol)
rect(-bw + 100, -30, 300, 60)
rect(-bw + 100, -40, 150, 80)
rect(-bw + 350, -35, 40, 70)
rect(-bw + 300, -35, 40, 70)
rect(-bw + 250, -35, 40, 70)
rect(-bw + 400, -10, 10, 20)
noFill()
let panelColor = bgCol
// color logic
if(REIL1integrity == 0){
panelColor = errorCol
}else if(REIL1integrity < 20 && time%1 < 0.5){
panelColor = errorCol
}else if(REIL1integrity < 50 && time%1 < 0.5){
panelColor = warnCol
}
stroke(panelColor)
strokeWeight(2)
rect(-bw + 120, -30, 110, 10)
rect(-bw + 120, 20, 110, 10)
// beam
stroke(primaryCol)
strokeWeight(1)
fill(primaryCol)
if(reactorOnline && REIL1enabled && REIL1integrity > 0){
rect(-bw + 410, -2 - REIL1power/2 - sin(time*PI)*0.5, bw - 410, 4 + REIL1power + sin(time*PI))
}
push()
translate(-bw + 100, -60)
rotate(-PI/16)
textSize(14)
noStroke()
fill(primaryCol)
textAlign(LEFT,CENTER)
text("REIL 1 integrity: " + round(REIL1integrity,1) + "%",0,0)
pop()
pop()
push()
translate(centerX, centerY - 125)
rotate(-PI/16)
stroke(primaryCol)
strokeWeight(1)
fill(primaryCol)
rect(-bw + 100, -30, 300, 60)
rect(-bw + 100, -40, 150, 80)
rect(-bw + 350, -35, 40, 70)
rect(-bw + 300, -35, 40, 70)
rect(-bw + 250, -35, 40, 70)
rect(-bw + 400, -10, 10, 20)
noFill()
panelColor = bgCol
// color logic
if(REIL2integrity == 0){
panelColor = errorCol
}else if(REIL2integrity < 20 && time%1 < 0.5){
panelColor = errorCol
}else if(REIL2integrity < 50 && time%1 < 0.5){
panelColor = warnCol
}
stroke(panelColor)
strokeWeight(2)
rect(-bw + 120, -30, 110, 10)
rect(-bw + 120, 20, 110, 10)
// beam
stroke(primaryCol)
strokeWeight(1)
fill(primaryCol)
if(reactorOnline && REIL2enabled && REIL2integrity > 0){
rect(-bw + 410, -2 - REIL2power/2 - sin(time*PI)*0.5, bw - 410, 4 + REIL2power + sin(time*PI))
}
push()
translate(-bw + 100, 60)
rotate(PI/16)
textSize(14)
noStroke()
fill(primaryCol)
textAlign(LEFT,CENTER)
text("REIL 2 integrity: " + round(REIL2integrity,1) + "%",0,0)
pop()
pop()
push()
translate(centerX, centerY - 125)
scale(-1,1)
rotate(PI/16)
stroke(primaryCol)
strokeWeight(1)
fill(primaryCol)
rect(-bw + 100, -30, 300, 60)
rect(-bw + 100, -40, 150, 80)
rect(-bw + 350, -35, 40, 70)
rect(-bw + 300, -35, 40, 70)
rect(-bw + 250, -35, 40, 70)
rect(-bw + 400, -10, 10, 20)
noFill()
panelColor = bgCol
// color logic
if(REIL3integrity == 0){
panelColor = errorCol
}else if(REIL3integrity < 20 && time%1 < 0.5){
panelColor = errorCol
}else if(REIL3integrity < 50 && time%1 < 0.5){
panelColor = warnCol
}
stroke(panelColor)
strokeWeight(2)
rect(-bw + 120, -30, 110, 10)
rect(-bw + 120, 20, 110, 10)
// beam
stroke(primaryCol)
strokeWeight(1)
fill(primaryCol)
if(reactorOnline && REIL3enabled && REIL3integrity > 0){
rect(-bw + 410, -2 - REIL3power/2 - sin(time*PI)*0.5, bw - 410, 4 + REIL3power + sin(time*PI))
}
push()
translate(-bw + 100, -60)
scale(-1,1)
rotate(PI/16)
textSize(14)
noStroke()
fill(primaryCol)
textAlign(RIGHT,CENTER)
text("REIL 3 integrity: " + round(REIL3integrity,1) + "%",0,0)
pop()
pop()
push()
translate(centerX, centerY - 125)
scale(-1,1)
rotate(-PI/16)
stroke(primaryCol)
strokeWeight(1)
fill(primaryCol)
rect(-bw + 100, -30, 300, 60)
rect(-bw + 100, -40, 150, 80)
rect(-bw + 350, -35, 40, 70)
rect(-bw + 300, -35, 40, 70)
rect(-bw + 250, -35, 40, 70)
rect(-bw + 400, -10, 10, 20)
noFill()
panelColor = bgCol
// color logic
if(REIL4integrity == 0){
panelColor = errorCol
}else if(REIL4integrity < 20 && time%1 < 0.5){
panelColor = errorCol
}else if(REIL4integrity < 50 && time%1 < 0.5){
panelColor = warnCol
}
stroke(panelColor)
strokeWeight(2)
rect(-bw + 120, -30, 110, 10)
rect(-bw + 120, 20, 110, 10)
// beam
stroke(primaryCol)
strokeWeight(1)
fill(primaryCol)
if(reactorOnline && REIL4enabled && REIL4integrity > 0){
rect(-bw + 410, -2 - REIL4power/2 - sin(time*PI)*0.5, bw - 410, 4 + REIL4power + sin(time*PI))
}
push()
translate(-bw + 100, 60)
scale(-1,1)
rotate(-PI/16)
textSize(14)
noStroke()
fill(primaryCol)
textAlign(RIGHT,CENTER)
text("REIL 4 integrity: " + round(REIL4integrity,1) + "%",0,0)
pop()
pop()
}else{
noFill()
stroke(primaryCol)
strokeWeight(2)
rect(windowWidth/2 - 185 , windowHeight/2 - 125 - 25, 370, 50)
noStroke()
fill(primaryCol)
textSize(30)
textFont(consolas)
textAlign(CENTER,CENTER)
text("ERROR: SYSTEM OFFLINE" ,windowWidth/2,windowHeight/2 - 125)
}
}
// pump screen
if(screen == "pumps"){
if(!screenLoaded){
screenLoaded = true
}
}
if(powerFailureImminent){
textAlign(CENTER,CENTER)
textFont(consolas)
textSize(28)
fill(errorCol)
noStroke()
text("--- POWER FAILURE IN " + round(10 -powerFailureTimer.value,3) + " ---",windowWidth/2,100)
text("--- POWER FAILURE IN " + round(10 - powerFailureTimer.value,3) + " ---",windowWidth/2,windowHeight - 100)
}
if(screen == "game over"){
if(!screenLoaded){
disableAllButtons()
gameTimer.paused = true
gameOverTimer.value = 0
terminalPaused = true
exeQueue = []
printTerminalColor("[ERROR] connection to external systems lost",errorCol,1,3)
printTerminalColor("[ERROR] NO POWER INPUT, RUNNING ON EMERGENCY RESERVES",errorCol,1,3.2)
printTerminalColor("attempting to reconnect...",errorCol,1,4)
printTerminalColor("...",errorCol,1,6)
printTerminalColor("...",errorCol,1,8)
printTerminalColor("...",errorCol,1,10)
printTerminalColor("[ERROR] unable to reconnect",errorCol,1,12)
printTerminalColor("activating maintainence beacon",errorCol,1,12)
printTerminalColor("[WARN] neural core in panic state, administering sedatives...",errorCol,1,15)
printTerminalColor("[WARN] ESTIMATED TIME UNTIL LIFE SUPPORT FAILIURE: 4m 17s",errorCol,1,17)
printTerminalColor("[WARN] no maintainence agents availible!",errorCol,1,20)
printTerminalColor("estimating neural core survival chance...",errorCol,1,23)
printTerminalColor("[FATAL] ESTIMATED CHANCE OF IMMINDENT CORE DEATH: 99.982%",errorCol,1,27)
screenLoaded = true
}
if(gameOverTimer.value > 7){
noFill()
stroke(errorCol)
strokeWeight(6)
rect(windowWidth/2-250,50,500,100)
noStroke()
fill(errorCol)
textFont("sans-serif")
textAlign(CENTER,CENTER)
textSize(50)
text("SYSTEM FAILURE",windowWidth/2-250,50,500,100)
}
if(gameOverTimer.value > 9){
textAlign(LEFT,CENTER)
textFont(consolas)
stroke(errorBgCol)
strokeWeight(4)
fill(errorCol)
textSize(20)
text("you lasted: " + floor(gameTimer.value/60) + "m " + floor(gameTimer.value%60) + "s", 40, 200)
text("cause of death: " + causeOfDeath, 40, 230)
text("[ADD MORE STATS]",40,260)
}
}
for(let button of p5.prototype.buttons){
if(!button.updated) button.update()
if(!button.drawn) button.draw()
}
if(screen != "game over" && screen != "start" && screen != "begin"){
if(calling){
fill(secondaryCol)
noStroke()
rect(centerX - 250, centerY - 30, 500,60)
stroke(0,240,255)
strokeWeight(2-2*(time%1))
noFill()
rect(centerX - 250 - 20*(time%1), centerY - 30 - 20*(time%1), 500 + 40*(time%1),60 + 40*(time%1))
noStroke()
fill(bgCol)
textSize(20)
textAlign(CENTER,CENTER)
textFont("sans-serif")
text(callingText, centerX - 250, centerY - 30, 500,60)
}
displayDialogue()
}
}