2019-04-13 03:22:46 +02:00
/ * *
* Implementation for what happens when you destroy a BitNode
* /
2019-04-11 10:37:40 +02:00
import { BitNodes } from "./BitNode/BitNode" ;
import { Engine } from "./engine" ;
import { Player } from "./Player" ;
import { prestigeSourceFile } from "./Prestige" ;
import { PlayerOwnedSourceFile } from "./SourceFile/PlayerOwnedSourceFile" ;
2019-07-09 03:34:31 +02:00
import { SourceFileFlags } from "./SourceFile/SourceFileFlags" ;
import { SourceFiles } from "./SourceFile/SourceFiles" ;
2019-04-11 10:37:40 +02:00
import { setTimeoutRef } from "./utils/SetTimeoutRef" ;
import { dialogBoxCreate } from "../utils/DialogBox" ;
import {
yesNoBoxCreate ,
yesNoBoxGetYesButton ,
yesNoBoxGetNoButton ,
2021-04-30 05:52:56 +02:00
yesNoBoxClose ,
2019-04-11 10:37:40 +02:00
} from "../utils/YesNoBox" ;
import { clearEventListeners } from "../utils/uiHelpers/clearEventListeners" ;
import { removeChildrenFromElement } from "../utils/uiHelpers/removeChildrenFromElement" ;
2017-08-30 19:44:29 +02:00
2019-04-13 03:22:46 +02:00
// Returns promise
2017-07-04 23:18:42 +02:00
function writeRedPillLine ( line ) {
return new Promise ( function ( resolve , reject ) {
2018-08-12 21:45:35 +02:00
var container = document . getElementById ( "red-pill-content" ) ;
2017-07-04 23:18:42 +02:00
var pElem = document . createElement ( "p" ) ;
container . appendChild ( pElem ) ;
2017-08-13 07:01:33 +02:00
2017-07-04 23:18:42 +02:00
var promise = writeRedPillLetter ( pElem , line , 0 ) ;
promise . then ( function ( res ) {
resolve ( res ) ;
} , function ( e ) {
reject ( e ) ;
} ) ;
} ) ;
}
function writeRedPillLetter ( pElem , line , i = 0 ) {
return new Promise ( function ( resolve , reject ) {
2019-02-20 09:42:27 +01:00
setTimeoutRef ( function ( ) {
2017-07-04 23:18:42 +02:00
if ( i >= line . length ) {
2017-07-22 00:54:55 +02:00
var textToShow = line . substring ( 0 , i ) ;
pElem . innerHTML = "> " + textToShow ;
return resolve ( true ) ;
2017-07-04 23:18:42 +02:00
}
var textToShow = line . substring ( 0 , i ) ;
pElem . innerHTML = "> " + textToShow + "<span class='typed-cursor'> █ </span>" ;
var promise = writeRedPillLetter ( pElem , line , i + 1 ) ;
promise . then ( function ( res ) {
resolve ( res ) ;
} , function ( e ) {
reject ( e ) ;
} ) ;
2017-07-22 00:54:55 +02:00
} , 30 ) ;
2017-07-04 23:18:42 +02:00
} ) ;
}
2017-08-30 19:44:29 +02:00
let redPillFlag = false ;
2021-05-02 05:23:04 +02:00
function hackWorldDaemon ( currentNodeNumber , flume = false , quick = false ) {
2018-10-23 20:55:42 +02:00
// Clear Red Pill screen first
var container = document . getElementById ( "red-pill-content" ) ;
removeChildrenFromElement ( container ) ;
2019-01-15 14:11:14 +01:00
2017-07-22 00:54:55 +02:00
redPillFlag = true ;
Engine . loadRedPillContent ( ) ;
2021-05-02 05:23:04 +02:00
if ( quick ) {
return loadBitVerse ( currentNodeNumber , flume , quick ) ;
}
2017-07-22 00:54:55 +02:00
return writeRedPillLine ( "[ERROR] SEMPOOL INVALID" ) . then ( function ( ) {
return writeRedPillLine ( "[ERROR] Segmentation Fault" ) ;
} ) . then ( function ( ) {
return writeRedPillLine ( "[ERROR] SIGKILL RECVD" ) ;
} ) . then ( function ( ) {
return writeRedPillLine ( "Dumping core..." ) ;
} ) . then ( function ( ) {
return writeRedPillLine ( "0000 000016FA 174FEE40 29AC8239 384FEA88" ) ;
} ) . then ( function ( ) {
return writeRedPillLine ( "0010 745F696E 2BBBE394 390E3940 248BEC23" ) ;
} ) . then ( function ( ) {
return writeRedPillLine ( "0020 7124696B 0000FF69 74652E6F FFFF1111" ) ;
} ) . then ( function ( ) {
return writeRedPillLine ( "----------------------------------------" ) ;
} ) . then ( function ( ) {
return writeRedPillLine ( "Failsafe initiated..." ) ;
} ) . then ( function ( ) {
2017-08-13 07:01:33 +02:00
return writeRedPillLine ( "Restarting BitNode-" + currentNodeNumber + "..." ) ;
2017-07-22 00:54:55 +02:00
} ) . then ( function ( ) {
return writeRedPillLine ( "..........." ) ;
} ) . then ( function ( ) {
return writeRedPillLine ( "..........." ) ;
} ) . then ( function ( ) {
return writeRedPillLine ( "[ERROR] FAILED TO AUTOMATICALLY REBOOT BITNODE" ) ;
} ) . then ( function ( ) {
return writeRedPillLine ( ".............................................." )
} ) . then ( function ( ) {
return writeRedPillLine ( ".............................................." )
} ) . then ( function ( ) {
2018-01-20 05:47:57 +01:00
return loadBitVerse ( currentNodeNumber , flume ) ;
2017-07-22 00:54:55 +02:00
} ) . catch ( function ( e ) {
2021-03-08 04:46:50 +01:00
console . error ( e . toString ( ) ) ;
2017-07-22 00:54:55 +02:00
} ) ;
}
2017-08-13 07:01:33 +02:00
function giveSourceFile ( bitNodeNumber ) {
var sourceFileKey = "SourceFile" + bitNodeNumber . toString ( ) ;
var sourceFile = SourceFiles [ sourceFileKey ] ;
if ( sourceFile == null ) {
2021-03-08 04:46:50 +01:00
console . error ( ` Could not find source file for Bit node: ${ bitNodeNumber } ` ) ;
2017-08-13 07:01:33 +02:00
return ;
}
2019-04-13 03:22:46 +02:00
// Check if player already has this source file
2017-08-13 07:01:33 +02:00
var alreadyOwned = false ;
var ownedSourceFile = null ;
2017-08-20 03:36:19 +02:00
for ( var i = 0 ; i < Player . sourceFiles . length ; ++ i ) {
if ( Player . sourceFiles [ i ] . n === bitNodeNumber ) {
2017-08-13 07:01:33 +02:00
alreadyOwned = true ;
ownedSourceFile = Player . sourceFiles [ i ] ;
break ;
}
}
if ( alreadyOwned && ownedSourceFile ) {
2018-06-05 08:52:59 +02:00
if ( ownedSourceFile . lvl >= 3 && ownedSourceFile . n !== 12 ) {
2017-08-13 07:01:33 +02:00
dialogBoxCreate ( "The Source-File for the BitNode you just destroyed, " + sourceFile . name + ", " +
"is already at max level!" ) ;
} else {
++ ownedSourceFile . lvl ;
dialogBoxCreate ( sourceFile . name + " was upgraded to level " + ownedSourceFile . lvl + " for " +
"destroying its corresponding BitNode!" ) ;
}
} else {
var playerSrcFile = new PlayerOwnedSourceFile ( bitNodeNumber , 1 ) ;
Player . sourceFiles . push ( playerSrcFile ) ;
2019-04-13 03:22:46 +02:00
if ( bitNodeNumber === 5 ) { // Artificial Intelligence
2017-09-19 20:38:03 +02:00
Player . intelligence = 1 ;
}
2017-08-13 07:01:33 +02:00
dialogBoxCreate ( "You received a Source-File for destroying a Bit Node!<br><br>" +
sourceFile . name + "<br><br>" + sourceFile . info ) ;
}
}
2019-07-09 03:34:31 +02:00
// Keeps track of what Source-Files the player will have AFTER the current bitnode
// is destroyed. Updated every time loadBitVerse() is called
let nextSourceFileFlags = [ ] ;
2021-05-02 05:23:04 +02:00
function loadBitVerse ( destroyedBitNodeNum , flume = false , quick = false ) {
2019-04-13 03:22:46 +02:00
// Clear the screen
2019-07-09 03:34:31 +02:00
const container = document . getElementById ( "red-pill-content" ) ;
2018-01-20 05:47:57 +01:00
removeChildrenFromElement ( container ) ;
2017-08-13 07:01:33 +02:00
2019-07-09 03:34:31 +02:00
// Update NextSourceFileFlags
nextSourceFileFlags = SourceFileFlags . slice ( ) ;
if ( ! flume ) {
2021-05-03 07:50:09 +02:00
if ( nextSourceFileFlags [ destroyedBitNodeNum ] < 3 )
2021-03-21 23:41:48 +01:00
++ nextSourceFileFlags [ destroyedBitNodeNum ] ;
2019-07-09 03:34:31 +02:00
}
2019-04-13 03:22:46 +02:00
// Create the Bit Verse
2019-07-09 03:34:31 +02:00
const bitVerseImage = document . createElement ( "pre" ) ;
const bitNodes = [ ] ;
for ( let i = 1 ; i <= 12 ; ++ i ) {
2017-07-22 00:54:55 +02:00
bitNodes . push ( createBitNode ( i ) ) ;
}
2017-08-13 07:01:33 +02:00
bitVerseImage . innerHTML =
2017-07-22 00:54:55 +02:00
" O <br>" +
" | O O | O O | <br>" +
" O | | / __| \\ | | O <br>" +
" O | O | | O / | O | | O | O <br>" +
" | | | | |_/ |/ | \\_ \\_| | | | | <br>" +
" O | | | O | | O__/ | / \\__ | | O | | | O <br>" +
" | | | | | | | / /| O / \\| | | | | | | <br>" +
"O | | | \\| | O / _/ | / O | |/ | | | O<br>" +
"| | | |O / | | O / | O O | | \\ O| | | |<br>" +
"| | |/ \\/ / __| | |/ \\ | \\ | |__ \\ \\/ \\| | |<br>" +
" \\| O | |_/ |\\| \\ O \\__| \\_| | O |/ <br>" +
" | | |_/ | | \\| / | \\_| | | <br>" +
" \\| / \\| | / / \\ |/ <br>" +
" | " + bitNodes [ 9 ] + " | | / | " + bitNodes [ 10 ] + " | <br>" +
" " + bitNodes [ 8 ] + " | | | | | | | " + bitNodes [ 11 ] + " <br>" +
" | | | / / \\ \\ | | | <br>" +
" \\| | / " + bitNodes [ 6 ] + " / \\ " + bitNodes [ 7 ] + " \\ | |/ <br>" +
" \\ | / / | | \\ \\ | / <br>" +
" \\ \\JUMP " + bitNodes [ 4 ] + "3R | | | | | | R3" + bitNodes [ 5 ] + " PMUJ/ / <br>" +
" \\|| | | | | | | | | ||/ <br>" +
" \\| \\_ | | | | | | _/ |/ <br>" +
" \\ \\| / \\ / \\ |/ / <br>" +
" " + bitNodes [ 0 ] + " |/ " + bitNodes [ 1 ] + " | | " + bitNodes [ 2 ] + " \\| " + bitNodes [ 3 ] + " <br>" +
" | | | | | | | | <br>" +
2017-08-13 07:01:33 +02:00
" \\JUMP3R|JUMP|3R| |R3|PMUJ|R3PMUJ/ <br><br><br><br>" ;
2017-07-22 00:54:55 +02:00
container . appendChild ( bitVerseImage ) ;
2017-08-13 07:01:33 +02:00
2019-07-09 03:34:31 +02:00
// BitNode event listeners
for ( let i = 1 ; i <= 12 ; ++ i ) {
2017-08-13 07:01:33 +02:00
( function ( i ) {
2019-07-09 03:34:31 +02:00
const elemId = "bitnode-" + i . toString ( ) ;
const elem = clearEventListeners ( elemId ) ;
if ( elem == null ) { return ; }
2019-03-25 04:03:24 +01:00
if ( i >= 1 && i <= 12 ) {
2017-07-22 00:54:55 +02:00
elem . addEventListener ( "click" , function ( ) {
2019-07-09 03:34:31 +02:00
const bitNodeKey = "BitNode" + i ;
const bitNode = BitNodes [ bitNodeKey ] ;
2017-08-13 07:01:33 +02:00
if ( bitNode == null ) {
2019-07-09 03:34:31 +02:00
console . error ( ` Could not find BitNode object for number: ${ i } ` ) ;
2017-08-13 07:01:33 +02:00
return ;
2017-07-22 00:54:55 +02:00
}
2019-07-09 03:34:31 +02:00
const maxSourceFileLevel = i === 12 ? "∞" : "3" ;
const popupBoxText = ` BitNode- ${ i } : ${ bitNode . name } <br> ` +
` Source-File Level: ${ nextSourceFileFlags [ i ] } / ${ maxSourceFileLevel } <br><br> ` +
` ${ bitNode . info } ` ;
yesNoBoxCreate ( popupBoxText ) ;
createBitNodeYesNoEventListener ( i , destroyedBitNodeNum , flume ) ;
2017-07-22 00:54:55 +02:00
} ) ;
} else {
elem . addEventListener ( "click" , function ( ) {
dialogBoxCreate ( "Not yet implemented! Coming soon!" )
} ) ;
}
2019-04-13 03:22:46 +02:00
} ( i ) ) ; // Immediate invocation closure
2017-07-22 00:54:55 +02:00
}
2017-08-13 07:01:33 +02:00
2021-05-02 05:23:04 +02:00
if ( quick ) {
return Promise . resolve ( true ) ;
}
2019-04-13 03:22:46 +02:00
// Create lore text
2017-07-22 00:54:55 +02:00
return writeRedPillLine ( "Many decades ago, a humanoid extraterrestial species which we call the Enders descended on the Earth...violently" ) . then ( function ( ) {
return writeRedPillLine ( "Our species fought back, but it was futile. The Enders had technology far beyond our own..." ) ;
} ) . then ( function ( ) {
return writeRedPillLine ( "Instead of killing every last one of us, the human race was enslaved..." ) ;
} ) . then ( function ( ) {
return writeRedPillLine ( "We were shackled in a digital world, chained into a prison for our minds..." ) ;
} ) . then ( function ( ) {
return writeRedPillLine ( "Using their advanced technology, the Enders created complex simulations of a virtual reality..." ) ;
} ) . then ( function ( ) {
return writeRedPillLine ( "Simulations designed to keep us content...ignorant of the truth." ) ;
} ) . then ( function ( ) {
return writeRedPillLine ( "Simulations used to trap and suppress our consciousness, to keep us under control..." ) ;
} ) . then ( function ( ) {
return writeRedPillLine ( "Why did they do this? Why didn't they just end our entire race? We don't know, not yet." ) ;
} ) . then ( function ( ) {
return writeRedPillLine ( "Humanity's only hope is to destroy these simulations, destroy the only realities we've ever known..." ) ;
} ) . then ( function ( ) {
return writeRedPillLine ( "Only then can we begin to fight back..." ) ;
} ) . then ( function ( ) {
return writeRedPillLine ( "By hacking the daemon that generated your reality, you've just destroyed one simulation, called a BitNode..." ) ;
} ) . then ( function ( ) {
return writeRedPillLine ( "But there is still a long way to go..." ) ;
} ) . then ( function ( ) {
return writeRedPillLine ( "The technology the Enders used to enslave the human race wasn't just a single complex simulation..." ) ;
} ) . then ( function ( ) {
return writeRedPillLine ( "There are tens if not hundreds of BitNodes out there..." ) ;
} ) . then ( function ( ) {
return writeRedPillLine ( "Each with their own simulations of a reality..." ) ;
} ) . then ( function ( ) {
return writeRedPillLine ( "Each creating their own universes...a universe of universes" ) ;
} ) . then ( function ( ) {
return writeRedPillLine ( "And all of which must be destroyed..." ) ;
} ) . then ( function ( ) {
return writeRedPillLine ( "......................................." ) ;
} ) . then ( function ( ) {
return writeRedPillLine ( "Welcome to the Bitverse..." ) ;
2017-11-02 22:47:09 +01:00
} ) . then ( function ( ) {
return writeRedPillLine ( " " ) ;
} ) . then ( function ( ) {
return writeRedPillLine ( "(Enter a new BitNode using the image above)" ) ;
2017-07-22 00:54:55 +02:00
} ) . then ( function ( ) {
return Promise . resolve ( true ) ;
} ) . catch ( function ( e ) {
2021-03-08 04:46:50 +01:00
console . error ( e . toString ( ) ) ;
2017-07-22 00:54:55 +02:00
} ) ;
}
2019-04-13 03:22:46 +02:00
// Returns string with DOM element for Bit Node
2017-07-22 00:54:55 +02:00
function createBitNode ( n ) {
2019-07-09 03:34:31 +02:00
const bitNodeStr = "BitNode" + n . toString ( ) ;
const bitNode = BitNodes [ bitNodeStr ] ;
if ( bitNode == null ) { return "O" ; }
const level = nextSourceFileFlags [ n ] ;
let cssClass ;
if ( n === 12 && level >= 2 ) {
// Repeating BitNode
cssClass = "level-2" ;
} else {
cssClass = ` level- ${ level } ` ;
}
return ` <a class='bitnode ${ cssClass } tooltip' id='bitnode- ${ bitNode . number } '><strong>O</strong> ` +
"<span class='tooltiptext'>" +
` <strong>BitNode- ${ bitNode . number . toString ( ) } <br> ${ bitNode . name } </strong><br> ` +
` ${ bitNode . desc } <br> ` +
"</span></a>" ;
2017-07-22 00:54:55 +02:00
}
2019-07-09 03:34:31 +02:00
function createBitNodeYesNoEventListener ( newBitNode , destroyedBitNode , flume = false ) {
const yesBtn = yesNoBoxGetYesButton ( ) ;
2017-08-13 07:01:33 +02:00
yesBtn . innerHTML = "Enter BitNode-" + newBitNode ;
yesBtn . addEventListener ( "click" , function ( ) {
2018-02-01 00:41:02 +01:00
if ( ! flume ) {
giveSourceFile ( destroyedBitNode ) ;
} else {
2021-03-20 10:29:53 +01:00
// If player used flume, subtract 300 int exp. The prestigeSourceFile()
// function below grants 300 int exp, so this allows sets net gain to 0
Player . gainIntelligenceExp ( - 300 ) ;
2018-02-01 00:41:02 +01:00
}
2017-08-13 07:01:33 +02:00
redPillFlag = false ;
2018-10-23 20:55:42 +02:00
var container = document . getElementById ( "red-pill-content" ) ;
2018-01-20 05:47:57 +01:00
removeChildrenFromElement ( container ) ;
2017-08-13 07:01:33 +02:00
2019-04-13 03:22:46 +02:00
// Set new Bit Node
2017-08-13 07:01:33 +02:00
Player . bitNodeN = newBitNode ;
2019-04-13 03:22:46 +02:00
// Reenable terminal
2017-08-13 07:01:33 +02:00
$ ( "#hack-progress-bar" ) . attr ( 'id' , "old-hack-progress-bar" ) ;
$ ( "#hack-progress" ) . attr ( 'id' , "old-hack-progress" ) ;
document . getElementById ( "terminal-input-td" ) . innerHTML = '$ <input type="text" id="terminal-input-text-box" class="terminal-input" tabindex="1"/>' ;
$ ( 'input[class=terminal-input]' ) . prop ( 'disabled' , false ) ;
prestigeSourceFile ( ) ;
yesNoBoxClose ( ) ;
} ) ;
2019-07-09 03:34:31 +02:00
const noBtn = yesNoBoxGetNoButton ( ) ;
2017-08-13 07:01:33 +02:00
noBtn . innerHTML = "Back" ;
noBtn . addEventListener ( "click" , function ( ) {
yesNoBoxClose ( ) ;
} ) ;
}
2017-08-30 19:44:29 +02:00
export { redPillFlag , hackWorldDaemon } ;