This commit is contained in:
Daniel Xie 2018-08-11 16:21:19 -05:00
commit b89437a52e
41 changed files with 1000 additions and 554 deletions

@ -391,21 +391,18 @@ a:visited {
@-webkit-keyframes status-text{
from{
opacity: 1;
top: 0;
}
to{
opacity: 0;
top: 0;
}
}
.status-text{
display: inline;
position: fixed;
top: 0;
-webkit-animation: status-text 3s 1;
background-color: transparent;
display: inline-block;
height: 15%;
position: fixed;
z-index: 2;
-webkit-animation: status-text 3s 1;
}
#status-text-container {
@ -413,14 +410,14 @@ a:visited {
}
#status-text {
font-size: $defaultFontSize * 1.25;
color: #fff;
right: 0;
bottom: 0;
padding: 4px;
margin-right: 14px;
background-color: transparent;
z-index: 2;
font-size: $defaultFontSize * 1.25;
bottom: 0;
color: #fff;
margin-right: 14px;
padding: 4px;
right: 0;
top: 0;
width: auto;
}

@ -1,4 +1,3 @@
import {Engine} from "./engine";
import {workerScripts,
killWorkerScript} from "./NetscriptWorker";
import {Player} from "./Player";
@ -16,6 +15,7 @@ import {formatNumber} from "../utils/StringHelperFunctions";
import {removeChildrenFromElement} from "../utils/uiHelpers/removeChildrenFromElement";
import {removeElement} from "../utils/uiHelpers/removeElement";
import {roundToTwo} from "../utils/helpers/roundToTwo";
import {Page, routing} from "./ui/navigationTracking";
/* {
* serverName: {
@ -232,7 +232,7 @@ function updateActiveScriptsItems(maxTasks=150) {
}
}
if (Engine.currentPage !== Engine.Page.ActiveScripts) {return;}
if (!routing.isOn(Page.ActiveScripts)) {return;}
var total = 0;
for (var i = 0; i < workerScripts.length; ++i) {
try {

@ -1,4 +1,4 @@
import {post} from "./Terminal";
import {post} from "./ui/postToTerminal";
let Aliases = {};
let GlobalAliases = {};

@ -1,4 +1,4 @@
import {BitNodeMultipliers} from "./BitNode";
import {BitNodeMultipliers} from "./BitNodeMultipliers";
import {CONSTANTS} from "./Constants";
import {Engine} from "./engine";
import {Factions, getNextNeurofluxLevel,

@ -1,4 +1,5 @@
import {Player} from "./Player";
import {BitNodeMultipliers} from "./BitNodeMultipliers";
import {Player} from "./Player";
function BitNode(n, name, desc="", info="") {
this.number = n;
@ -199,43 +200,6 @@ function initBitNodes() {
BitNodes["BitNode24"] = new BitNode(24, "", "COMING SOON");
}
let BitNodeMultipliers = {
HackingLevelMultiplier: 1,
ServerMaxMoney: 1,
ServerStartingMoney: 1,
ServerGrowthRate: 1,
ServerWeakenRate: 1,
ServerStartingSecurity: 1,
ManualHackMoney: 1,
ScriptHackMoney: 1,
CompanyWorkMoney: 1,
CrimeMoney: 1,
HacknetNodeMoney: 1,
CompanyWorkExpGain: 1,
ClassGymExpGain: 1,
FactionWorkExpGain: 1,
HackExpGain: 1,
CrimeExpGain: 1,
FactionWorkRepGain: 1,
FactionPassiveRepGain: 1,
RepToDonateToFaction: 1,
AugmentationRepCost: 1,
AugmentationMoneyCost: 1,
InfiltrationMoney: 1,
InfiltrationRep: 1,
CorporationValuation: 1,
BladeburnerRank: 1,
BladeburnerSkillCost: 1,
}
function initBitNodeMultipliers() {
if (Player.bitNodeN == null) {
Player.bitNodeN = 1;
@ -394,7 +358,7 @@ function initBitNodeMultipliers() {
BitNodeMultipliers.CorporationValuation = dec;
BitNodeMultipliers.BladeburnerRank = dec;
BitNodeMultipliers.BladeburnerSkillCost = dec;
BitNodeMultipliers.BladeburnerSkillCost = inc;
break;
default:
console.log("WARNING: Player.bitNodeN invalid");
@ -403,7 +367,5 @@ function initBitNodeMultipliers() {
}
export {initBitNodes,
BitNode,
BitNodes,
BitNodeMultipliers,
initBitNodeMultipliers};

178
src/BitNodeMultipliers.ts Normal file

@ -0,0 +1,178 @@
/**
* Bitnode multipliers influence the difficulty of different aspects of the game.
* Each Bitnode has a different theme/strategy to achieving the end goal, so these multipliers will can help drive the
* player toward the intended strategy. Unless they really want to play the long, slow game of waiting...
*/
interface IBitNodeMultipliers {
/**
* Influences the base cost to purchase an augmentation.
*/
AugmentationMoneyCost: number;
/**
* Influences the base rep the player must have with a faction to purchase an augmentation.
*/
AugmentationRepCost: number;
/**
* Influences how quickly the player can gain rank within Bladeburner.
*/
BladeburnerRank: number;
/**
* Influences the cost of skill levels from Bladeburner.
*/
BladeburnerSkillCost: number;
/**
* Influences the experience gained for each ability when a player completes a class.
*/
ClassGymExpGain: number;
/**
* Influences the experience gained for each ability when the player completes working their job.
*/
CompanyWorkExpGain: number;
/**
* Influences how much money the player earns when completing working their job.
*/
CompanyWorkMoney: number;
/**
* Influences the valuation of corporations created by the player.
*/
CorporationValuation: number;
/**
* Influences the base experience gained for each ability when the player commits a crime.
*/
CrimeExpGain: number;
/**
* Influences the base money gained when the player commits a crime.
*/
CrimeMoney: number;
/**
* Influences how much rep the player gains in each faction simply by being a member.
*/
FactionPassiveRepGain: number;
/**
* Influences the experience gained for each ability when the player completes work for a Faction.
*/
FactionWorkExpGain: number;
/**
* Influences how much rep the player gains when performing work for a faction.
*/
FactionWorkRepGain: number;
/**
* Influences the experienced gained when hacking a server.
*/
HackExpGain: number;
/**
* Influences how quickly the player's hacking level (not experience) scales
*/
HackingLevelMultiplier: number;
/**
* Influences how much money each Hacknet node can generate.
*/
HacknetNodeMoney: number;
/**
* Influences how much money is gained when the player infiltrates a company.
*/
InfiltrationMoney: number;
/**
* Influences how much rep the player can gain from factions when selling stolen documents and secrets
*/
InfiltrationRep: number;
/**
* Influences how much money can be stolen from a server when the player performs a hack against it through
* the Terminal.
*/
ManualHackMoney: number;
/**
* Influences the minimum favor the player must have with a faction before they can donate to gain rep.
*/
RepToDonateToFaction: number;
/**
* Influences how much money can be stolen from a server when a script performs a hack against it.
*/
ScriptHackMoney: number;
/**
* Influences the growth percentage per cycle against a server.
*/
ServerGrowthRate: number;
/**
* Influences the maxmimum money that a server can grow to.
*/
ServerMaxMoney: number;
/**
* Influences the initial money that a server starts with.
*/
ServerStartingMoney: number;
/**
* Influences the initial security level (hackDifficulty) of a server.
*/
ServerStartingSecurity: number;
/**
* Influences the weaken amount per invocation against a server.
*/
ServerWeakenRate: number;
}
/**
* The multipliers that are influenced by current Bitnode progression.
*/
// tslint:disable-next-line:variable-name
export const BitNodeMultipliers: IBitNodeMultipliers = {
HackingLevelMultiplier: 1,
ServerGrowthRate: 1,
ServerMaxMoney: 1,
ServerStartingMoney: 1,
ServerStartingSecurity: 1,
ServerWeakenRate: 1,
CompanyWorkMoney: 1,
CrimeMoney: 1,
HacknetNodeMoney: 1,
ManualHackMoney: 1,
ScriptHackMoney: 1,
ClassGymExpGain: 1,
CompanyWorkExpGain: 1,
CrimeExpGain: 1,
FactionWorkExpGain: 1,
HackExpGain: 1,
FactionPassiveRepGain: 1,
FactionWorkRepGain: 1,
RepToDonateToFaction: 1,
AugmentationMoneyCost: 1,
AugmentationRepCost: 1,
InfiltrationMoney: 1,
InfiltrationRep: 1,
CorporationValuation: 1,
BladeburnerRank: 1,
BladeburnerSkillCost: 1,
};

@ -1,13 +1,13 @@
import {Augmentations, AugmentationNames} from "./Augmentations";
import {BitNodeMultipliers} from "./BitNode";
import {BitNodeMultipliers} from "./BitNodeMultipliers";
import {CONSTANTS} from "./Constants";
import {Engine} from "./engine";
import {Faction, Factions, factionExists,
joinFaction, displayFactionContent} from "./Faction";
import {Locations} from "./Location";
import {Locations} from "./Locations";
import {Player} from "./Player";
import {hackWorldDaemon, redPillFlag} from "./RedPill";
import {KEY} from "./Terminal";
import {KEY} from "../utils/helpers/keyCodes";
import {createProgressBarText} from "../utils/helpers/createProgressBarText";
import {dialogBoxCreate} from "../utils/DialogBox";
@ -20,6 +20,7 @@ import {appendLineBreaks} from "../utils/uiHelpers/app
import {clearObject} from "../utils/helpers/clearObject";
import {createElement} from "../utils/uiHelpers/createElement";
import {createPopup} from "../utils/uiHelpers/createPopup";
import {Page, routing} from "./ui/navigationTracking";
import {exceptionAlert} from "../utils/helpers/exceptionAlert";
import {formatNumber} from "../utils/StringHelperFunctions";
import {getRandomInt} from "../utils/helpers/getRandomInt";
@ -145,7 +146,7 @@ var consoleHelpText = {
//Keypresses for Console
$(document).keydown(function(event) {
if (Engine.currentPage === Engine.Page.Bladeburner) {
if (routing.isOn(Page.Bladeburner)) {
//if (DomElems.consoleInput && !event.ctrlKey && !event.shiftKey && !event.altKey) {
// DomElems.consoleInput.focus();
//}
@ -915,7 +916,7 @@ Bladeburner.prototype.process = function() {
}
}
if (Engine.currentPage === Engine.Page.Bladeburner) {
if (routing.isOn(Page.Bladeburner)) {
this.updateContent();
}
}
@ -1257,7 +1258,7 @@ Bladeburner.prototype.completeAction = function() {
return hackWorldDaemon(Player.bitNodeN);
}
if (Engine.currentPage === Engine.Page.Bladeburner) {
if (routing.isOn(Page.Bladeburner)) {
this.createActionAndSkillsContent();
}
@ -2194,7 +2195,7 @@ Bladeburner.prototype.updateContent = function() {
}
Bladeburner.prototype.updateOverviewContent = function() {
if (Engine.currentPage !== Engine.Page.Bladeburner) {return;}
if (!routing.isOn(Page.Bladeburner)) {return;}
DomElems.overviewRank.childNodes[0].nodeValue = "Rank: " + formatNumber(this.rank, 2);
DomElems.overviewStamina.innerText = "Stamina: " + formatNumber(this.stamina, 3) + " / " + formatNumber(this.maxStamina, 3);
DomElems.overviewGen1.innerHTML =
@ -3498,7 +3499,7 @@ Bladeburner.prototype.upgradeSkillNetscriptFn = function(skillName, workerScript
this.skillPoints -= cost;
this.upgradeSkill(skill);
if (Engine.currentPage === Engine.Page.Bladeburner && DomElems.currentTab.toLowerCase() === "skills") {
if (routing.isOn(Page.Bladeburner) && DomElems.currentTab.toLowerCase() === "skills") {
this.createActionAndSkillsContent();
}
if (workerScript.shouldLog("upgradeSkill")) {
@ -3620,7 +3621,7 @@ Bladeburner.prototype.joinBladeburnerFactionNetscriptFn = function(workerScript)
if (workerScript.shouldLog("joinBladeburnerFaction")) {
workerScript.log("Joined Bladeburners Faction");
}
if (Engine.currentPage === Engine.Page.Bladeburner) {
if (routing.isOn(Page.Bladeburner)) {
removeChildrenFromElement(DomElems.overviewDiv);
this.createOverviewContent();
}

@ -1,6 +1,5 @@
import {CONSTANTS} from "./Constants";
import {Locations} from "./Location";
import {Player} from "./Player";
import {Locations} from "./Locations";
import {Reviver, Generic_toJSON,
Generic_fromJSON} from "../utils/JSONReviver";

@ -1,8 +1,7 @@
import {BitNodeMultipliers} from "./BitNode";
import {Engine} from "./engine";
import {BitNodeMultipliers} from "./BitNodeMultipliers";
import {Factions} from "./Faction";
import {showLiterature} from "./Literature";
import {Locations} from "./Location";
import {Locations} from "./Locations";
import {Player} from "./Player";
import Decimal from "decimal.js";
@ -13,6 +12,7 @@ import {Reviver, Generic_toJSON,
import numeral from "numeral/min/numeral.min";
import {createElement} from "../utils/uiHelpers/createElement";
import {createPopup} from "../utils/uiHelpers/createPopup";
import {Page, routing} from "./ui/navigationTracking";
import {formatNumber, generateRandomString} from "../utils/StringHelperFunctions";
import {getRandomInt} from "../utils/helpers/getRandomInt";
import {isString} from "../utils/helpers/isString";
@ -3118,7 +3118,7 @@ Corporation.prototype.process = function() {
this.state.nextState();
if (Engine.currentPage === Engine.Page.Corporation) {this.updateUIContent();}
if (routing.isOn(Page.Corporation)) {this.updateUIContent();}
}
}

@ -1,7 +1,7 @@
import {Programs} from "./CreateProgram";
import {Player} from "./Player";
import {SpecialServerIps} from "./SpecialServerIps";
import {post} from "./Terminal";
import {post} from "./ui/postToTerminal";
import {isValidIPAddress} from "../utils/helpers/isValidIPAddress";
import {formatNumber} from "../utils/StringHelperFunctions";

@ -1,6 +1,6 @@
import {Augmentations, AugmentationNames,
PlayerOwnedAugmentation} from "./Augmentations";
import {BitNodeMultipliers} from "./BitNode";
import {BitNodeMultipliers} from "./BitNodeMultipliers";
import {CONSTANTS} from "./Constants";
import {Engine} from "./engine";
import {FactionInfos} from "./FactionInfo";
@ -9,6 +9,7 @@ import {HackingMission, setInMission} from "./Missions";
import {Player} from "./Player";
import {Settings} from "./Settings";
import {Page, routing} from "./ui/navigationTracking";
import {dialogBoxCreate} from "../utils/DialogBox";
import {factionInvitationBoxCreate} from "../utils/FactionInvitationBox";
import {removeChildrenFromElement} from "../utils/uiHelpers/removeChildrenFromElement";
@ -137,7 +138,7 @@ function inviteToFaction(faction) {
if (Settings.SuppressFactionInvites) {
faction.alreadyInvited = true;
Player.factionInvitations.push(faction.name);
if (Engine.currentPage === Engine.Page.Factions) {
if (routing.isOn(Page.Factions)) {
Engine.loadFactionsContent();
}
} else {

@ -64,166 +64,202 @@ class FactionInfo {
*/
// tslint:disable-next-line:variable-name
export const FactionInfos: IMap<FactionInfo> = {
// Endgame
Illuminati: new FactionInfo("Humanity never changes. No matter how civilized society becomes, it will eventually " +
"fall back into chaos. And from this chaos, we are the Invisible hand that guides them to order. ",
[], true, true, true, false),
// Endgame
Illuminati: new FactionInfo(
"Humanity never changes. No matter how civilized society becomes, it will eventually fall back into chaos. And " +
"from this chaos, we are the Invisible hand that guides them to order.",
[], true, true, true, false),
Daedalus: new FactionInfo("Yesterday we obeyed kings and bent our necks to emperors. Today we kneel only to truth.",
[], true, true, true, false),
Daedalus: new FactionInfo(
"Yesterday we obeyed kings and bent our necks to emperors. Today we kneel only to truth.",
[], true, true, true, false),
"The Covenant": new FactionInfo("Surrender yourself. Give up your empty individuality to become part of something " +
"great, something eternal. Become a slave. Submit your mind, body, and soul. Only " +
"then can you set yourself free.<br><br> Only then can you discover immortality.",
[], true, true, true, false),
"The Covenant": new FactionInfo(
"Surrender yourself. Give up your empty individuality to become part of something great, something eternal. " +
"Become a slave. Submit your mind, body, and soul. Only then can you set yourself free.<br>" +
"<br>" +
"Only then can you discover immortality.",
[], true, true, true, false),
// Megacorporations, each forms its own faction
ECorp: new FactionInfo("ECorp's mission is simple: to connect the world of today with the technology of tomorrow. " +
"With our wide range of Internet-related software and commercial hardware, ECorp makes " +
"the world's information universally accessible.",
[], true, true, true, true),
// Megacorporations, each forms its own faction
ECorp: new FactionInfo(
"ECorp's mission is simple: to connect the world of today with the technology of tomorrow. With our wide range " +
"of Internet-related software and commercial hardware, ECorp makes the world's information universally accessible.",
[], true, true, true, true),
MegaCorp: new FactionInfo("MegaCorp does things that others don't. We imagine. We create. We invent. We build " +
"things that others have never even dreamed of. Our work fills the world's needs for " +
"food, water, power, and transporation on an unprecendented scale, in ways that no " +
"other company can.<br><br>In our labs and factories and on the ground with customers, " +
"MegaCorp is ushering in a new era for the world.",
[], true, true, true, true),
MegaCorp: new FactionInfo(
"MegaCorp does things that others don't. We imagine. We create. We invent. We build things that others have " +
"never even dreamed of. Our work fills the world's needs for food, water, power, and transporation on an " +
"unprecendented scale, in ways that no other company can.<br>" +
"<br>" +
"In our labs and factories and on the ground with customers, MegaCorp is ushering in a new era for the world.",
[], true, true, true, true),
"Bachman & Associates": new FactionInfo("Where Law and Business meet - thats where we are. <br><br>" +
"Legal Insight - Business Instinct - Experience Innovation",
[], true, true, true, true),
"Bachman & Associates": new FactionInfo(
"Where Law and Business meet - thats where we are. <br>" +
"<br>" +
"Legal Insight - Business Instinct - Experience Innovation",
[], true, true, true, true),
"Blade Industries": new FactionInfo("Augmentation is salvation", [], true, true, true, true),
"Blade Industries": new FactionInfo(
"Augmentation is salvation",
[], true, true, true, true),
NWO: new FactionInfo("The human being does not truly desire freedom. It wants " +
"to be observed, understood, and judged. It wants to be given purpose and " +
"direction in its life. That is why humans created God. " +
"And that is why humans created civilization - " +
"not because of willingness, " +
"but because of a need to be incorporated into higher orders of structure and meaning.",
[], true, true, true, true),
NWO: new FactionInfo(
"The human being does not truly desire freedom. It wants to be observed, understood, and judged. It wants to be " +
"given purpose and direction in its life. That is why humans created God. And that is why humans created " +
"civilization - not because of willingness, but because of a need to be incorporated into higher orders of " +
"structure and meaning.",
[], true, true, true, true),
"Clarke Incorporated": new FactionInfo("Unlocking the power of the genome",
[], true, true, true, true),
"Clarke Incorporated": new FactionInfo(
"Unlocking the power of the genome",
[], true, true, true, true),
"OmniTek Incorporated": new FactionInfo("Simply put, our mission is to design and build robots that make a difference",
[], true, true, true, true),
"OmniTek Incorporated": new FactionInfo(
"Simply put, our mission is to design and build robots that make a difference",
[], true, true, true, true),
"Four Sigma": new FactionInfo("The scientific method is the best way to approach investing. Big strategies backed " +
"up with big data. Driven by deep learning and innovative ideas. And improved by iteration. That's Four Sigma.",
[], true, true, true, true),
"Four Sigma": new FactionInfo(
"The scientific method is the best way to approach investing. Big strategies backed up with big data. Driven by " +
"deep learning and innovative ideas. And improved by iteration. That's Four Sigma.",
[], true, true, true, true),
"KuaiGong International": new FactionInfo("Dream big. Work hard. Make history.",
[], true, true, true, true),
"KuaiGong International": new FactionInfo(
"Dream big. Work hard. Make history.",
[], true, true, true, true),
// Other Corporations
"Fulcrum Secret Technologies": new FactionInfo("The human organism has an innate desire to worship. " +
"That is why they created gods. If there were no gods, " +
"it would be necessary to create them. And now we can.",
[], true, true, false, true),
// Other Corporations
"Fulcrum Secret Technologies": new FactionInfo(
"The human organism has an innate desire to worship. That is why they created gods. If there were no gods, it " +
"would be necessary to create them. And now we can.",
[], true, true, false, true),
// Hacker groups
BitRunners: new FactionInfo("Our entire lives are controlled by bits. All of our actions, our thoughts, our " +
"personal information. It's all transformed into bits, stored in bits, communicated through bits. " +
"Its impossible for any person to move, to live, to operate at any level without the use of " +
"bits. And when a person moves, lives, and operates, they leave behind their bits, mere traces of " +
"seemingly meaningless fragments of information. But these bits can be reconstructed. " +
"Transformed. Used.<br><br>Those who run the bits, run the world",
[], true, true, false, false),
// Hacker groups
BitRunners: new FactionInfo(
"Our entire lives are controlled by bits. All of our actions, our thoughts, our personal information. It's all " +
"transformed into bits, stored in bits, communicated through bits. Its impossible for any person to move, to " +
"live, to operate at any level without the use of bits. And when a person moves, lives, and operates, they leave " +
"behind their bits, mere traces of seemingly meaningless fragments of information. But these bits can be " +
"reconstructed. Transformed. Used.<br>" +
"<br>" +
"Those who run the bits, run the world",
[], true, true, false, false),
"The Black Hand": new FactionInfo("The world, so afraid of strong government, now has no government. " +
"Only power - Digital power. Financial power. Technological power. And those at the top rule with " +
"an invisible hand. They built a society where the rich get richer, and everyone else suffers." +
"<br><br>So much pain. So many lives. Their darkness must end.",
[], true, true, true, false),
"The Black Hand": new FactionInfo(
"The world, so afraid of strong government, now has no government. Only power - Digital power. Financial power. " +
"Technological power. And those at the top rule with an invisible hand. They built a society where the rich get " +
"richer, and everyone else suffers.<br>" +
"<br>" +
"So much pain. So many lives. Their darkness must end.",
[], true, true, true, false),
NiteSec: new FactionInfo(
" __..__ <br>" +
" _.nITESECNIt. <br>" +
" .-'NITESECNITESEc. <br>" +
" .' NITESECNITESECn <br>" +
" / NITESECNITESEC; <br>" +
" : :NITESECNITESEC; <br>" +
" ; $ NITESECNITESECN <br>" +
" : _, ,N'ITESECNITESEC <br>" +
" : .+^^`, : `NITESECNIT <br>" +
" ) /), `-,-=,NITESECNI <br>" +
" / ^ ,-;|NITESECN; <br>" +
" / _.' '-';NITESECN <br>" +
" ( , ,-''`^NITE' <br>" +
" )` :`. .' <br>" +
" )-- ; `- / <br>" +
" \' _.-' : <br>" +
" ( _.-' \. \ <br>" +
" \------. \ \ <br>" +
" \. \ \ <br>" +
" \ _.nIt <br>" +
" \ _.nITESECNi <br>" +
" nITESECNIT^' \ <br>" +
" NITE^' ___ \ <br>" +
" / .gP''''Tp. \ <br>" +
" : d' . `b \ <br>" +
" ; d' o `b ; <br>" +
" / d; `b| <br>" +
" /, $; @ `: <br>" +
" /' $$ ; <br>" +
" .' $$b o | <br>" +
" .' d$$$; : <br>" +
" / .d$$$$; , ; <br>" +
" d .dNITESEC $ | <br>" +
" :bp.__.gNITESEC$$ :$ ; <br>" +
" NITESECNITESECNIT $$b : <br>",
[], true, true, false, false),
NiteSec: new FactionInfo(
" __..__ <br>" +
" _.nITESECNIt. <br>" +
" .-'NITESECNITESEc. <br>" +
" .' NITESECNITESECn <br>" +
" / NITESECNITESEC; <br>" +
" : :NITESECNITESEC; <br>" +
" ; $ NITESECNITESECN <br>" +
" : _, ,N'ITESECNITESEC <br>" +
" : .+^^`, : `NITESECNIT <br>" +
" ) /), `-,-=,NITESECNI <br>" +
" / ^ ,-;|NITESECN; <br>" +
" / _.' '-';NITESECN <br>" +
" ( , ,-''`^NITE' <br>" +
" )` :`. .' <br>" +
" )-- ; `- / <br>" +
" \' _.-' : <br>" +
" ( _.-' \. \ <br>" +
" \------. \ \ <br>" +
" \. \ \ <br>" +
" \ _.nIt <br>" +
" \ _.nITESECNi <br>" +
" nITESECNIT^' \ <br>" +
" NITE^' ___ \ <br>" +
" / .gP''''Tp. \ <br>" +
" : d' . `b \ <br>" +
" ; d' o `b ; <br>" +
" / d; `b| <br>" +
" /, $; @ `: <br>" +
" /' $$ ; <br>" +
" .' $$b o | <br>" +
" .' d$$$; : <br>" +
" / .d$$$$; , ; <br>" +
" d .dNITESEC $ | <br>" +
" :bp.__.gNITESEC$$ :$ ; <br>" +
" NITESECNITESECNIT $$b : <br>",
[], true, true, false, false),
// City factions, essentially governments
Aevum: new FactionInfo("The Silicon City",
["Chongqing", "New Tokyo", "Ishima", "Volhaven"], true, true, true, true),
Chongqing: new FactionInfo("Serve the people",
["Sector-12", "Aevum", "Volhaven"], true, true, true, true),
Ishima: new FactionInfo("The East Asian Order of the Future",
["Sector-12", "Aevum", "Volhaven"], true, true, true, true),
"New Tokyo": new FactionInfo("Asia's World City",
["Sector-12", "Aevum", "Volhaven"], true, true, true, true),
"Sector-12": new FactionInfo("The City of the Future",
["Chongqing", "New Tokyo", "Ishima", "Volhaven"], true, true, true, true),
Volhaven: new FactionInfo("Benefit, Honour, and Glory",
["Chongqing", "Sector-12", "New Tokyo", "Aevum", "Ishima"], true, true, true, true),
// City factions, essentially governments
Aevum: new FactionInfo(
"The Silicon City",
["Chongqing", "New Tokyo", "Ishima", "Volhaven"], true, true, true, true),
Chongqing: new FactionInfo(
"Serve the people",
["Sector-12", "Aevum", "Volhaven"], true, true, true, true),
Ishima: new FactionInfo(
"The East Asian Order of the Future",
["Sector-12", "Aevum", "Volhaven"], true, true, true, true),
"New Tokyo": new FactionInfo(
"Asia's World City",
["Sector-12", "Aevum", "Volhaven"], true, true, true, true),
"Sector-12": new FactionInfo(
"The City of the Future",
["Chongqing", "New Tokyo", "Ishima", "Volhaven"], true, true, true, true),
Volhaven: new FactionInfo(
"Benefit, Honour, and Glory",
["Chongqing", "Sector-12", "New Tokyo", "Aevum", "Ishima"], true, true, true, true),
// Criminal Organizations/Gangs
"Speakers for the Dead": new FactionInfo("It is better to reign in hell than to serve in heaven.",
[], true, true, true, true),
// Criminal Organizations/Gangs
"Speakers for the Dead": new FactionInfo(
"It is better to reign in hell than to serve in heaven.",
[], true, true, true, true),
"The Dark Army": new FactionInfo("The World doesn't care about right or wrong. It's all about power.",
[], true, true, true, false),
"The Dark Army": new FactionInfo(
"The World doesn't care about right or wrong. It's all about power.",
[], true, true, true, false),
"The Syndicate": new FactionInfo("Honor holds you back", [], true, true, true, true),
"The Syndicate": new FactionInfo(
"Honor holds you back",
[], true, true, true, true),
Silhouette: new FactionInfo("Corporations have filled the void of power left behind by the collapse of Western " +
"government. The issue is they've become so big that you don't know who they're working for. And " +
"if you're employed at one of these corporations, you don't even know who you're working for.\n\n" +
"That's terror. Terror, fear, and corruption. All born into the system, all propagated by the " +
"system.",
[], true, true, true, false),
Silhouette: new FactionInfo(
"Corporations have filled the void of power left behind by the collapse of Western government. The issue is " +
"they've become so big that you don't know who they're working for. And if you're employed at one of these " +
"corporations, you don't even know who you're working for.<br>" +
"<br>" +
"That's terror. Terror, fear, and corruption. All born into the system, all propagated by the system.",
[], true, true, true, false),
Tetrads: new FactionInfo("Following the Mandate of Heaven and Carrying out the Way", [], false, false, true, true),
Tetrads: new FactionInfo(
"Following the Mandate of Heaven and Carrying out the Way",
[], false, false, true, true),
"Slum Snakes": new FactionInfo("Slum Snakes rule!", [], false, false, true, true),
"Slum Snakes": new FactionInfo(
"Slum Snakes rule!",
[], false, false, true, true),
// Earlygame factions - factions the player will prestige with early on that don't belong in other categories.
Netburners: new FactionInfo("~~//*>H4CK|\|3T 8URN3R5**>?>\\~~", [], true, true, false, false),
// Earlygame factions - factions the player will prestige with early on that don't belong in other categories.
Netburners: new FactionInfo(
"~~//*>H4CK|\|3T 8URN3R5**>?>\\~~",
[], true, true, false, false),
"Tian Di Hui": new FactionInfo("Obey Heaven and Work Righteousness", [], true, true, false, true),
"Tian Di Hui": new FactionInfo(
"Obey Heaven and Work Righteousness",
[], true, true, false, true),
CyberSec: new FactionInfo("The Internet is the first thing that humanity has built that humanity doesnt " +
"understand, the largest experiment in anarchy that we have ever had. And as the world becomes " +
"increasingly dominated by the internet, society approaches the brink of total chaos. We serve only " +
"to protect society, to protect humanity, to protect the world from its imminent collapse.",
[], true, true, false, false),
CyberSec: new FactionInfo(
"The Internet is the first thing that humanity has built that humanity doesnt understand, the largest " +
"experiment in anarchy that we have ever had. And as the world becomes increasingly dominated by the internet, " +
"society approaches the brink of total chaos. We serve only to protect society, to protect humanity, to protect " +
"the world from its imminent collapse.",
[], true, true, false, false),
// Special Factions
Bladeburners: new FactionInfo("It's too bad they won't live. But then again, who does?<br><br>Note that for this " +
"faction, reputation can only be gained through Bladeburner actions. Completing " +
"Bladeburner contracts/operations will increase your reputation.",
[], false, false, false, false),
// Special Factions
Bladeburners: new FactionInfo(
"It's too bad they won't live. But then again, who does?<br><br>Note that for this faction, reputation can only " +
"be gained through Bladeburner actions. Completing Bladeburner contracts/operations will increase your reputation.",
[], false, false, false, false),
};

@ -9,6 +9,7 @@ import {Reviver, Generic_toJSON,
import {createAccordionElement} from "../utils/uiHelpers/createAccordionElement";
import {createElement} from "../utils/uiHelpers/createElement";
import {createPopup} from "../utils/uiHelpers/createPopup";
import {Page, routing} from "./ui/navigationTracking";
import numeral from "numeral/min/numeral.min";
import {formatNumber} from "../utils/StringHelperFunctions";
import {getRandomInt} from "../utils/helpers/getRandomInt";
@ -24,7 +25,7 @@ import {yesNoBoxCreate, yesNoTxtInpBoxCreate,
/* Gang.js */
//Switch between territory and management screen with 1 and 2
$(document).keydown(function(event) {
if (Engine.currentPage == Engine.Page.Gang && !yesNoBoxOpen) {
if (routing.isOn(Page.Gang) && !yesNoBoxOpen) {
if (gangMemberFilter != null && gangMemberFilter === document.activeElement) {return;}
if (event.keyCode === 49) {
if(gangTerritorySubpage.style.display === "block") {

@ -1,4 +1,4 @@
import {BitNodeMultipliers} from "./BitNode";
import {BitNodeMultipliers} from "./BitNodeMultipliers";
import {CONSTANTS} from "./Constants";
import {Engine} from "./engine";
import {iTutorialSteps, iTutorialNextStep,
@ -9,6 +9,7 @@ import {clearEventListeners} from "../utils/uiHelpers/clearEv
import {Reviver, Generic_toJSON,
Generic_fromJSON} from "../utils/JSONReviver";
import {createElement} from "../utils/uiHelpers/createElement";
import {Page, routing} from "./ui/navigationTracking";
import {formatNumber} from "../utils/StringHelperFunctions";
import {getElementById} from "../utils/uiHelpers/getElementById";
@ -273,7 +274,7 @@ function purchaseHacknet() {
Player.loseMoney(cost);
Player.hacknetNodes.push(node);
if (Engine.currentPage === Engine.Page.HacknetNodes) {
if (routing.isOn(Page.HacknetNodes)) {
displayHacknetNodesContent();
}
updateTotalHacknetProduction();

@ -1,4 +1,4 @@
import {BitNodeMultipliers} from "./BitNode";
import {BitNodeMultipliers} from "./BitNodeMultipliers";
import {CONSTANTS} from "./Constants";
import {Engine} from "./engine";
import {Player} from "./Player";

@ -7,6 +7,7 @@ import {Crimes} from "./Crimes";
import {Engine} from "./engine";
import {beginInfiltration} from "./Infiltration";
import {hasBladeburnerSF} from "./NetscriptFunctions";
import {Locations} from "./Locations";
import {Player} from "./Player";
import {Server, AllServers, AddToAllServers} from "./Server";
import {purchaseServer,
@ -25,95 +26,8 @@ import {yesNoBoxCreate, yesNoTxtInpBoxCreate,
yesNoTxtInpBoxGetInput, yesNoBoxClose,
yesNoTxtInpBoxClose} from "../utils/YesNoBox";
/* Display Location Content when visiting somewhere in the World*/
var Locations = {
//Cities
Aevum: "Aevum",
//AevumDesc: ""
Chongqing: "Chongqing",
Sector12: "Sector-12",
NewTokyo: "New Tokyo",
Ishima: "Ishima",
Volhaven: "Volhaven",
//Aevum Locations
AevumTravelAgency: "Aevum Travel Agency",
AevumSummitUniversity: "Summit University",
AevumECorp: "ECorp",
AevumBachmanAndAssociates: "Bachman & Associates",
AevumClarkeIncorporated: "Clarke Incorporated",
AevumFulcrumTechnologies: "Fulcrum Technologies",
AevumAeroCorp: "AeroCorp",
AevumGalacticCybersystems: "Galactic Cybersystems",
AevumWatchdogSecurity: "Watchdog Security",
AevumRhoConstruction: "Rho Construction",
AevumPolice: "Aevum Police Headquarters",
AevumNetLinkTechnologies: "NetLink Technologies",
AevumCrushFitnessGym: "Crush Fitness Gym",
AevumSnapFitnessGym: "Snap Fitness Gym",
AevumSlums: "Aevum Slums",
//Chongqing locations
ChongqingTravelAgency: "Chongqing Travel Agency",
ChongqingKuaiGongInternational: "KuaiGong International",
ChongqingSolarisSpaceSystems: "Solaris Space Systems",
ChongqingSlums: "Chongqing Slums",
//Sector 12
Sector12TravelAgency: "Sector-12 Travel Agency",
Sector12RothmanUniversity: "Rothman University",
Sector12MegaCorp: "MegaCorp",
Sector12BladeIndustries: "Blade Industries",
Sector12FourSigma: "Four Sigma",
Sector12IcarusMicrosystems: "Icarus Microsystems",
Sector12UniversalEnergy: "Universal Energy",
Sector12DeltaOne: "DeltaOne",
Sector12CIA: "Central Intelligence Agency",
Sector12NSA: "National Security Agency",
Sector12AlphaEnterprises: "Alpha Enterprises",
Sector12CarmichaelSecurity: "Carmichael Security",
Sector12FoodNStuff: "FoodNStuff",
Sector12JoesGuns: "Joe's Guns",
Sector12IronGym: "Iron Gym",
Sector12PowerhouseGym: "Powerhouse Gym",
Sector12Slums: "Sector-12 Slums",
Sector12CityHall: "Sector-12 City Hall",
//New Tokyo
NewTokyoTravelAgency: "New Tokyo Travel Agency",
NewTokyoDefComm: "DefComm",
NewTokyoVitaLife: "VitaLife",
NewTokyoGlobalPharmaceuticals: "Global Pharmaceuticals",
NewTokyoNoodleBar: "Noodle Bar",
NewTokyoSlums: "New Tokyo Slums",
//Ishima
IshimaTravelAgency: "Ishima Travel Agency",
IshimaStormTechnologies: "Storm Technologies",
IshimaNovaMedical: "Nova Medical",
IshimaOmegaSoftware: "Omega Software",
IshimaSlums: "Ishima Slums",
//Volhaven
VolhavenTravelAgency: "Volhaven Travel Agency",
VolhavenZBInstituteOfTechnology: "ZB Institute of Technology",
VolhavenOmniTekIncorporated: "OmniTek Incorporated",
VolhavenNWO: "NWO",
VolhavenHeliosLabs: "Helios Labs",
VolhavenOmniaCybersystems: "Omnia Cybersystems",
VolhavenLexoCorp: "LexoCorp",
VolhavenSysCoreSecurities: "SysCore Securities",
VolhavenCompuTek: "CompuTek",
VolhavenMilleniumFitnessGym: "Millenium Fitness Gym",
VolhavenSlums: "Volhaven Slums",
//Generic locations
Hospital: "Hospital",
WorldStockExchange: "World Stock Exchange",
}
function displayLocationContent() {
if (Engine.debug) {
if (Engine.Debug) {
console.log("displayLocationContent() called with location " + Player.location)
}
@ -2199,4 +2113,4 @@ function purchaseServerBoxCreate(ram, cost) {
"Please enter the server hostname below:<br>");
}
export {Locations, displayLocationContent, initLocationButtons};
export {displayLocationContent, initLocationButtons};

90
src/Locations.ts Normal file

@ -0,0 +1,90 @@
import { IMap } from "./types";
/**
* Display Location Content when visiting somewhere in the World
*/
// tslint:disable-next-line:variable-name
export const Locations: IMap<string> = {
// Cities
Aevum: "Aevum",
Chongqing: "Chongqing",
Ishima: "Ishima",
NewTokyo: "New Tokyo",
Sector12: "Sector-12",
Volhaven: "Volhaven",
// Aevum Locations
AevumAeroCorp: "AeroCorp",
AevumBachmanAndAssociates: "Bachman & Associates",
AevumClarkeIncorporated: "Clarke Incorporated",
AevumCrushFitnessGym: "Crush Fitness Gym",
AevumECorp: "ECorp",
AevumFulcrumTechnologies: "Fulcrum Technologies",
AevumGalacticCybersystems: "Galactic Cybersystems",
AevumNetLinkTechnologies: "NetLink Technologies",
AevumPolice: "Aevum Police Headquarters",
AevumRhoConstruction: "Rho Construction",
AevumSlums: "Aevum Slums",
AevumSnapFitnessGym: "Snap Fitness Gym",
AevumSummitUniversity: "Summit University",
AevumTravelAgency: "Aevum Travel Agency",
AevumWatchdogSecurity: "Watchdog Security",
// Chongqing locations
ChongqingKuaiGongInternational: "KuaiGong International",
ChongqingSlums: "Chongqing Slums",
ChongqingSolarisSpaceSystems: "Solaris Space Systems",
ChongqingTravelAgency: "Chongqing Travel Agency",
// Sector 12
Sector12AlphaEnterprises: "Alpha Enterprises",
Sector12BladeIndustries: "Blade Industries",
Sector12CIA: "Central Intelligence Agency",
Sector12CarmichaelSecurity: "Carmichael Security",
Sector12CityHall: "Sector-12 City Hall",
Sector12DeltaOne: "DeltaOne",
Sector12FoodNStuff: "FoodNStuff",
Sector12FourSigma: "Four Sigma",
Sector12IcarusMicrosystems: "Icarus Microsystems",
Sector12IronGym: "Iron Gym",
Sector12JoesGuns: "Joe's Guns",
Sector12MegaCorp: "MegaCorp",
Sector12NSA: "National Security Agency",
Sector12PowerhouseGym: "Powerhouse Gym",
Sector12RothmanUniversity: "Rothman University",
Sector12Slums: "Sector-12 Slums",
Sector12TravelAgency: "Sector-12 Travel Agency",
Sector12UniversalEnergy: "Universal Energy",
// New Tokyo
NewTokyoDefComm: "DefComm",
NewTokyoGlobalPharmaceuticals: "Global Pharmaceuticals",
NewTokyoNoodleBar: "Noodle Bar",
NewTokyoSlums: "New Tokyo Slums",
NewTokyoTravelAgency: "New Tokyo Travel Agency",
NewTokyoVitaLife: "VitaLife",
// Ishima
IshimaNovaMedical: "Nova Medical",
IshimaOmegaSoftware: "Omega Software",
IshimaSlums: "Ishima Slums",
IshimaStormTechnologies: "Storm Technologies",
IshimaTravelAgency: "Ishima Travel Agency",
// Volhaven
VolhavenCompuTek: "CompuTek",
VolhavenHeliosLabs: "Helios Labs",
VolhavenLexoCorp: "LexoCorp",
VolhavenMilleniumFitnessGym: "Millenium Fitness Gym",
VolhavenNWO: "NWO",
VolhavenOmniTekIncorporated: "OmniTek Incorporated",
VolhavenOmniaCybersystems: "Omnia Cybersystems",
VolhavenSlums: "Volhaven Slums",
VolhavenSysCoreSecurities: "SysCore Securities",
VolhavenTravelAgency: "Volhaven Travel Agency",
VolhavenZBInstituteOfTechnology: "ZB Institute of Technology",
// Generic locations
Hospital: "Hospital",
WorldStockExchange: "World Stock Exchange",
};

@ -1,4 +1,4 @@
import {BitNodeMultipliers} from "./BitNode";
import {BitNodeMultipliers} from "./BitNodeMultipliers";
import {CONSTANTS} from "./Constants";
import {Player} from "./Player";
import {Environment} from "./NetscriptEnvironment";

@ -13,12 +13,11 @@ import {Companies, Company, CompanyPosition,
import {CONSTANTS} from "./Constants";
import {Programs} from "./CreateProgram";
import {DarkWebItems} from "./DarkWeb";
import {Engine} from "./engine";
import {AllGangs} from "./Gang";
import {Factions, Faction, joinFaction,
factionExists, purchaseAugmentation} from "./Faction";
import {getCostOfNextHacknetNode, purchaseHacknet} from "./HacknetNode";
import {Locations} from "./Location";
import {Locations} from "./Locations";
import {Message, Messages} from "./Message";
import {inMission} from "./Missions";
import {Player} from "./Player";
@ -35,7 +34,7 @@ import {StockMarket, StockSymbols, SymbolToStockMap, initStockSymbols,
updateStockTicker, updateStockPlayerPosition,
Stock, shortStock, sellShort, OrderTypes,
PositionTypes, placeOrder, cancelOrder} from "./StockMarket";
import {post} from "./Terminal";
import {post} from "./ui/postToTerminal";
import {TextFile, getTextFile, createTextFile} from "./TextFile";
import {unknownBladeburnerActionErrorMessage,
@ -50,6 +49,7 @@ import {makeRuntimeRejectMsg, netscriptDelay, runScriptFromScript,
import {NetscriptPort} from "./NetscriptPort";
import Decimal from "decimal.js";
import {Page, routing} from "./ui/navigationTracking";
import {dialogBoxCreate} from "../utils/DialogBox";
import {isPowerOfTwo} from "../utils/helpers/isPowerOfTwo";
import {arrayToString} from "../utils/helpers/arrayToString";
@ -1415,7 +1415,7 @@ function NetscriptFunctions(workerScript) {
var newTotal = origTotal + totalPrice;
stock.playerShares += shares;
stock.playerAvgPx = newTotal / stock.playerShares;
if (Engine.currentPage == Engine.Page.StockMarket) {
if (routing.isOn(Page.StockMarket)) {
updateStockPlayerPosition(stock);
}
if (workerScript.disableLogs.ALL == null && workerScript.disableLogs.buyStock == null) {
@ -1456,7 +1456,7 @@ function NetscriptFunctions(workerScript) {
if (stock.playerShares == 0) {
stock.playerAvgPx = 0;
}
if (Engine.currentPage == Engine.Page.StockMarket) {
if (routing.isOn(Page.StockMarket)) {
updateStockPlayerPosition(stock);
}
if (workerScript.disableLogs.ALL == null && workerScript.disableLogs.sellStock == null) {
@ -3424,12 +3424,7 @@ function NetscriptFunctions(workerScript) {
}
updateDynamicRam("getCurrentAction", CONSTANTS.ScriptBladeburnerApiBaseRamCost / 4);
if (Player.bladeburner instanceof Bladeburner && (Player.bitNodeN === 7 || hasBladeburner2079SF)) {
let res = Player.bladeburner.getTypeAndNameFromActionId(Player.bladeburner.action);
if (res.type === "Idle" && res.name === "Idle") {
return null;
} else {
return res;
}
return Player.bladeburner.getTypeAndNameFromActionId(Player.bladeburner.action);
}
throw makeRuntimeRejectMsg(workerScript, "getCurrentAction() failed because you do not currently have access to the Bladeburner API. This is either because you are not currently employed " +
"at the Bladeburner division or because you do not have Source-File 7");

@ -1,7 +1,7 @@
import {Augmentations, applyAugmentation,
AugmentationNames,
PlayerOwnedAugmentation} from "./Augmentations";
import {BitNodes, BitNode, BitNodeMultipliers} from "./BitNode";
import {BitNodeMultipliers} from "./BitNodeMultipliers";
import {Company, Companies, getNextCompanyPosition,
getJobRequirementText, CompanyPosition,
CompanyPositions} from "./Company";
@ -13,7 +13,7 @@ import {Engine} from "./engine";
import {Factions, Faction,
displayFactionContent} from "./Faction";
import {Gang, resetGangs} from "./Gang";
import {Locations} from "./Location";
import {Locations} from "./Locations";
import {hasBn11SF, hasWallStreetSF,hasAISF} from "./NetscriptFunctions";
import {AllServers, Server, AddToAllServers} from "./Server";
import {SpecialServerIps, SpecialServerNames} from "./SpecialServerIps";

54
src/Prestige.js Normal file → Executable file

@ -109,17 +109,6 @@ function prestigeAugmentation() {
//Messages
initMessages();
//Reset Stock market
if (Player.hasWseAccount) {
initStockMarket();
initSymbolToStockMap();
}
setStockMarketContentCreated(false);
var stockMarketList = document.getElementById("stock-market-list");
while(stockMarketList.firstChild) {
stockMarketList.removeChild(stockMarketList.firstChild);
}
//Gang, in BitNode 2
if (Player.bitNodeN == 2 && Player.inGang()) {
var faction = Factions[Player.gang.facName];
@ -139,6 +128,17 @@ function prestigeAugmentation() {
Player.hasWseAccount = true;
Player.hasTixApiAccess = true;
}
//Reset Stock market
if (Player.hasWseAccount) {
initStockMarket();
initSymbolToStockMap();
}
setStockMarketContentCreated(false);
var stockMarketList = document.getElementById("stock-market-list");
while(stockMarketList.firstChild) {
stockMarketList.removeChild(stockMarketList.firstChild);
}
var mainMenu = document.getElementById("mainmenu-container");
mainMenu.style.visibility = "visible";
@ -241,22 +241,6 @@ function prestigeSourceFile() {
//Reinitialize Bit Node flags
initSingularitySFFlags();
//Reset Stock market, gang, and corporation
if (Player.hasWseAccount) {
initStockMarket();
initSymbolToStockMap();
}
setStockMarketContentCreated(false);
var stockMarketList = document.getElementById("stock-market-list");
while(stockMarketList.firstChild) {
stockMarketList.removeChild(stockMarketList.firstChild);
}
Player.gang = null;
deleteGangDisplayContent();
Player.corporation = null;
Player.bladeburner = null;
//BitNode 3: Corporatocracy
if (Player.bitNodeN === 3) {
Player.money = new Decimal(150e9);
@ -316,6 +300,22 @@ function prestigeSourceFile() {
Player.hasTixApiAccess = true;
}
//Reset Stock market, gang, and corporation
if (Player.hasWseAccount) {
initStockMarket();
initSymbolToStockMap();
}
setStockMarketContentCreated(false);
var stockMarketList = document.getElementById("stock-market-list");
while(stockMarketList.firstChild) {
stockMarketList.removeChild(stockMarketList.firstChild);
}
Player.gang = null;
deleteGangDisplayContent();
Player.corporation = null;
Player.bladeburner = null;
//Gain int exp
Player.gainIntelligenceExp(5);
}

@ -1,4 +1,4 @@
import {BitNode, BitNodes} from "./BitNode";
import {BitNodes} from "./BitNode";
import {Engine} from "./engine";
import {Player} from "./Player";
import {prestigeSourceFile} from "./Prestige";

@ -13,7 +13,7 @@ import {loadMessages, initMessages, Messages} from "./Message";
import {Player, loadPlayer} from "./Player";
import {loadAllRunningScripts} from "./Script";
import {AllServers, loadAllServers} from "./Server";
import {loadSettings, initSettings, Settings} from "./Settings";
import {Settings} from "./Settings";
import {loadSpecialServerIps, SpecialServerIps} from "./SpecialServerIps";
import {loadStockMarket, StockMarket} from "./StockMarket";
import {dialogBoxCreate} from "../utils/DialogBox";
@ -23,6 +23,7 @@ import {Reviver, Generic_toJSON,
Generic_fromJSON} from "../utils/JSONReviver";
import {createElement} from "../utils/uiHelpers/createElement";
import {createPopup} from "../utils/uiHelpers/createPopup";
import {createStatusText} from "./ui/createStatusText";
import {formatNumber} from "../utils/StringHelperFunctions";
import {removeElementById} from "../utils/uiHelpers/removeElementById";
@ -97,7 +98,7 @@ BitburnerSaveObject.prototype.saveGame = function(db) {
//console.log("Saved game to LocalStorage!");
} catch(e) {
if (e.code == 22) {
Engine.createStatusText("Save failed for localStorage! Check console(F12)");
createStatusText("Save failed for localStorage! Check console(F12)");
console.log("Failed to save game to localStorage because the size of the save file " +
"is too large. However, the game will still be saved to IndexedDb if your browser " +
"supports it. If you would like to save to localStorage as well, then " +
@ -106,7 +107,7 @@ BitburnerSaveObject.prototype.saveGame = function(db) {
}
}
Engine.createStatusText("Game saved!");
createStatusText("Game saved!");
}
function loadGame(saveString) {
@ -168,13 +169,13 @@ function loadGame(saveString) {
}
if (saveObj.hasOwnProperty("SettingsSave")) {
try {
loadSettings(saveObj.SettingsSave);
Settings.load(saveObj.SettingsSave);
} catch(e) {
console.log("ERROR: Failed to parse Settings. Re-initing default values");
initSettings();
Settings.init();
}
} else {
initSettings();
Settings.init();
}
if (saveObj.hasOwnProperty("FconfSettingsSave")) {
try {
@ -387,12 +388,12 @@ function loadImportedGame(saveObj, saveString) {
}
if (saveObj.hasOwnProperty("SettingsSave")) {
try {
loadSettings(saveObj.SettingsSave);
Settings.load(saveObj.SettingsSave);
} catch(e) {
initSettings();
Settings.init();
}
} else {
initSettings();
Settings.init();
}
if (saveObj.hasOwnProperty("FconfSettingsSave")) {
try {
@ -581,7 +582,7 @@ BitburnerSaveObject.prototype.deleteGame = function(db) {
request.onerror = function(e) {
console.log("Failed to delete save from indexedDb: " + e);
}
Engine.createStatusText("Game deleted!");
createStatusText("Game deleted!");
}
function createNewUpdateText() {

@ -29,10 +29,11 @@ import {addWorkerScript,
import {Player} from "./Player";
import {AllServers, processSingleServerGrowth} from "./Server";
import {Settings} from "./Settings";
import {post} from "./Terminal";
import {post} from "./ui/postToTerminal";
import {TextFile} from "./TextFile";
import {parse, Node} from "../utils/acorn";
import {Page, routing} from "./ui/navigationTracking";
import {dialogBoxCreate} from "../utils/DialogBox";
import {Reviver, Generic_toJSON,
Generic_fromJSON} from "../utils/JSONReviver";
@ -260,7 +261,7 @@ function updateScriptEditorContent() {
//Define key commands in script editor (ctrl o to save + close, etc.)
$(document).keydown(function(e) {
if (Settings.DisableHotkeys === true) {return;}
if (Engine.currentPage == Engine.Page.ScriptEditor) {
if (routing.isOn(Page.ScriptEditor)) {
//Ctrl + b
if (e.keyCode == 66 && (e.ctrlKey || e.metaKey)) {
e.preventDefault();
@ -364,7 +365,7 @@ function Script() {
//Get the script data from the Script Editor and save it to the object
Script.prototype.saveScript = function() {
if (Engine.currentPage == Engine.Page.ScriptEditor) {
if (routing.isOn(Page.ScriptEditor)) {
//Update code and filename
var editor = ace.edit('javascript-editor');
var code = editor.getValue();

@ -1,4 +1,4 @@
import {BitNodeMultipliers} from "./BitNode";
import {BitNodeMultipliers} from "./BitNodeMultipliers";
import {CONSTANTS} from "./Constants";
import {Programs} from "./CreateProgram";
import {Player} from "./Player";

122
src/Settings.ts Normal file

@ -0,0 +1,122 @@
import { ISelfInitializer, ISelfLoading } from "./types";
/**
* Represents the default settings the player could customize.
*/
interface IDefaultSettings {
/**
* How often the game should autosave the player's progress, in seconds.
*/
AutosaveInterval: number;
/**
* How many milliseconds between execution points for Netscript 1 statements.
*/
CodeInstructionRunTime: number;
/**
* Whether global keyboard shortcuts should be recognized throughout the game.
*/
DisableHotkeys: boolean;
/**
* Limit the number of log entries for each script being executed on each server.
*/
MaxLogCapacity: number;
/**
* Limit how many entries can be written to a Netscript Port before entries start to get pushed out.
*/
MaxPortCapacity: number;
/**
* Whether the player should be asked to confirm purchasing each and every augmentation.
*/
SuppressBuyAugmentationConfirmation: boolean;
/**
* Whether the user should be prompted to join each faction via a dialog box.
*/
SuppressFactionInvites: boolean;
/**
* Whether the user should be shown a dialog box whenever they receive a new message file.
*/
SuppressMessages: boolean;
/**
* Whether the user should be asked to confirm travelling between cities.
*/
SuppressTravelConfirmation: boolean;
}
/**
* Represents all possible settings the player wants to customize to their play style.
*/
interface ISettings extends IDefaultSettings {
/**
* The keybinding to use in the script editor.
* TODO: This should really be an enum of allowed values.
*/
EditorKeybinding: string;
/**
* The theme used in the script editor.
* TODO: This should really be an enum of allowed values.
*/
EditorTheme: string;
/**
* The CSS background theme color to apply across the game.
*/
ThemeBackgroundColor: string;
/**
* The CSS text theme color to apply across the game.
*/
ThemeFontColor: string;
/**
* The CSS foreground theme color to apply across the game.
*/
ThemeHighlightColor: string;
}
const defaultSettings: IDefaultSettings = {
AutosaveInterval: 60,
CodeInstructionRunTime: 50,
DisableHotkeys: false,
MaxLogCapacity: 50,
MaxPortCapacity: 50,
SuppressBuyAugmentationConfirmation: false,
SuppressFactionInvites: false,
SuppressMessages: false,
SuppressTravelConfirmation: false,
};
/**
* The current options the player has customized to their play style.
*/
// tslint:disable-next-line:variable-name
export const Settings: ISettings & ISelfInitializer & ISelfLoading = {
AutosaveInterval: defaultSettings.AutosaveInterval,
CodeInstructionRunTime: 25,
DisableHotkeys: defaultSettings.DisableHotkeys,
EditorKeybinding: "ace",
EditorTheme: "Monokai",
MaxLogCapacity: defaultSettings.MaxLogCapacity,
MaxPortCapacity: defaultSettings.MaxPortCapacity,
SuppressBuyAugmentationConfirmation: defaultSettings.SuppressBuyAugmentationConfirmation,
SuppressFactionInvites: defaultSettings.SuppressFactionInvites,
SuppressMessages: defaultSettings.SuppressMessages,
SuppressTravelConfirmation: defaultSettings.SuppressTravelConfirmation,
ThemeBackgroundColor: "#000000",
ThemeFontColor: "#66ff33",
ThemeHighlightColor: "#ffffff",
init() {
Object.assign(Settings, defaultSettings);
},
load(saveString: string) {
Object.assign(Settings, JSON.parse(saveString));
},
};

@ -1,5 +1,5 @@
import {Player} from "./Player";
import {BitNode, BitNodes} from "./BitNode";
import {BitNodes} from "./BitNode";
/* SourceFile.js */
//Each SourceFile corresponds to a BitNode with the same number

@ -1,6 +1,5 @@
import {CONSTANTS} from "./Constants";
import {Engine} from "./engine";
import {Locations} from "./Location";
import {Locations} from "./Locations";
import {hasWallStreetSF, wallStreetSFLvl} from "./NetscriptFunctions";
import {WorkerScript} from "./NetscriptWorker";
import {Player} from "./Player";
@ -9,6 +8,7 @@ import {dialogBoxCreate} from "../utils/DialogBox";
import {clearEventListeners} from "../utils/uiHelpers/clearEventListeners";
import {Reviver, Generic_toJSON,
Generic_fromJSON} from "../utils/JSONReviver";
import {Page, routing} from "./ui/navigationTracking";
import numeral from "numeral/min/numeral.min";
import {formatNumber} from "../utils/StringHelperFunctions";
import {getRandomInt} from "../utils/helpers/getRandomInt";
@ -593,7 +593,7 @@ function updateStockPrices() {
processOrders(stock, OrderTypes.LimitSell, PositionTypes.Long);
processOrders(stock, OrderTypes.StopBuy, PositionTypes.Long);
processOrders(stock, OrderTypes.StopSell, PositionTypes.Short);
if (Engine.currentPage == Engine.Page.StockMarket) {
if (routing.isOn(Page.StockMarket)) {
updateStockTicker(stock, true);
}
} else {
@ -602,7 +602,7 @@ function updateStockPrices() {
processOrders(stock, OrderTypes.LimitSell, PositionTypes.Short);
processOrders(stock, OrderTypes.StopBuy, PositionTypes.Short);
processOrders(stock, OrderTypes.StopSell, PositionTypes.Long);
if (Engine.currentPage == Engine.Page.StockMarket) {
if (routing.isOn(Page.StockMarket)) {
updateStockTicker(stock, false);
}
}
@ -1182,7 +1182,7 @@ function setStockTickerClickHandlers() {
//'increase' argument is a boolean indicating whether the price increased or decreased
function updateStockTicker(stock, increase) {
if (Engine.currentPage !== Engine.Page.StockMarket) {return;}
if (!routing.isOn(Page.StockMarket)) {return;}
if (!(stock instanceof Stock)) {
console.log("Invalid stock in updateStockTicker():");
console.log(stock);
@ -1207,7 +1207,7 @@ function updateStockTicker(stock, increase) {
}
function updateStockPlayerPosition(stock) {
if (Engine.currentPage !== Engine.Page.StockMarket) {return;}
if (!routing.isOn(Page.StockMarket)) {return;}
if (!(stock instanceof Stock)) {
console.log("Invalid stock in updateStockPlayerPosition():");
console.log(stock);
@ -1277,7 +1277,7 @@ function updateStockPlayerPosition(stock) {
}
function updateStockOrderList(stock) {
if (Engine.currentPage !== Engine.Page.StockMarket) {return;}
if (!routing.isOn(Page.StockMarket)) {return;}
var tickerId = "stock-market-ticker-" + stock.symbol;
var orderList = document.getElementById(tickerId + "-order-list");
if (orderList == null) {

@ -35,6 +35,8 @@ import {TextFile, getTextFile} from "./TextFile";
import {containsAllStrings, longestCommonStart,
formatNumber} from "../utils/StringHelperFunctions";
import {Page, routing} from "./ui/navigationTracking";
import {KEY} from "../utils/helpers/keyCodes";
import {addOffset} from "../utils/helpers/addOffset";
import {isString} from "../utils/helpers/isString";
import {arrayToString} from "../utils/helpers/arrayToString";
@ -43,70 +45,20 @@ import {logBoxCreate} from "../utils/LogBox";
import {yesNoBoxCreate,
yesNoBoxGetYesButton,
yesNoBoxGetNoButton, yesNoBoxClose} from "../utils/YesNoBox";
import {post, hackProgressBarPost,
hackProgressPost} from "./ui/postToTerminal";
import * as JSZip from 'jszip';
import * as FileSaver from 'file-saver';
/* Write text to terminal */
//If replace is true then spaces are replaced with "&nbsp;"
function post(input) {
$("#terminal-input").before('<tr class="posted"><td class="terminal-line" style="color: var(--my-font-color); background-color: var(--my-background-color); white-space:pre-wrap;">' + input + '</td></tr>');
updateTerminalScroll();
}
//Same thing as post but the td cells have ids so they can be animated for the hack progress bar
function hackProgressBarPost(input) {
$("#terminal-input").before('<tr class="posted"><td id="hack-progress-bar" style="color: var(--my-font-color); background-color: var(--my-background-color);">' + input + '</td></tr>');
updateTerminalScroll();
}
function hackProgressPost(input) {
$("#terminal-input").before('<tr class="posted"><td id="hack-progress" style="color: var(--my-font-color); background-color: var(--my-background-color);">' + input + '</td></tr>');
updateTerminalScroll();
}
//Scroll to the bottom of the terminal's 'text area'
function updateTerminalScroll() {
var element = document.getElementById("terminal-container");
element.scrollTop = element.scrollHeight;
}
function postNetburnerText() {
post("Bitburner v" + CONSTANTS.Version);
}
//Key Codes
var KEY = {
TAB: 9,
ENTER: 13,
CTRL: 17,
UPARROW: 38,
DOWNARROW: 40,
A: 65,
B: 66,
C: 67,
D: 68,
E: 69,
F: 70,
H: 72,
J: 74,
K: 75,
L: 76,
M: 77,
N: 78,
O: 79,
P: 80,
R: 82,
S: 83,
U: 85,
W: 87,
}
//Defines key commands in terminal
$(document).keydown(function(event) {
//Terminal
if (Engine.currentPage == Engine.Page.Terminal) {
if (routing.isOn(Page.Terminal)) {
var terminalInput = document.getElementById("terminal-input-text-box");
if (terminalInput != null && !event.ctrlKey && !event.shiftKey) {terminalInput.focus();}
@ -287,13 +239,13 @@ $(document).keydown(function(event) {
//Keep terminal in focus
let terminalCtrlPressed = false, shiftKeyPressed = false;
$(document).ready(function() {
if (Engine.currentPage === Engine.Page.Terminal) {
if (routing.isOn(Page.Terminal)) {
$('.terminal-input').focus();
}
});
$(document).keydown(function(e) {
if (Engine.currentPage == Engine.Page.Terminal) {
if (e.which == 17) {
if (routing.isOn(Page.Terminal)) {
if (e.which == KEY.CTRL) {
terminalCtrlPressed = true;
} else if (e.shiftKey) {
shiftKeyPressed = true;
@ -309,8 +261,8 @@ $(document).keydown(function(e) {
}
})
$(document).keyup(function(e) {
if (Engine.currentPage == Engine.Page.Terminal) {
if (e.which == 17) {
if (routing.isOn(Page.Terminal)) {
if (e.which == KEY.CTRL) {
terminalCtrlPressed = false;
}
if (e.shiftKey) {
@ -2105,4 +2057,4 @@ let Terminal = {
}
};
export {postNetburnerText, post, Terminal, KEY};
export {postNetburnerText, Terminal};

@ -33,8 +33,9 @@ import {displayFactionContent, joinFaction,
processPassiveFactionRepGain, Factions,
inviteToFaction, initFactions} from "./Faction";
import {FconfSettings} from "./Fconf";
import {Locations, displayLocationContent,
import {displayLocationContent,
initLocationButtons} from "./Location";
import {Locations} from "./Locations";
import {displayGangContent, updateGangContent,
Gang} from "./Gang";
import {displayHacknetNodesContent, processAllHacknetNodeEarnings,
@ -55,7 +56,8 @@ import {saveObject, loadGame} from "./SaveObject";
import {loadAllRunningScripts, scriptEditorInit,
updateScriptEditorContent} from "./Script";
import {AllServers, Server, initForeignServers} from "./Server";
import {Settings, setSettingsLabels} from "./Settings";
import {Settings} from "./Settings";
import {setSettingsLabels} from "./ui/setSettingsLabels";
import {initSourceFiles, SourceFiles,
PlayerOwnedSourceFile} from "./SourceFile";
import {SpecialServerIps, initSpecialServerIps} from "./SpecialServerIps";
@ -64,7 +66,9 @@ import {StockMarket, StockSymbols,
initSymbolToStockMap, stockMarketCycle,
updateStockPrices,
displayStockMarketContent} from "./StockMarket";
import {Terminal, postNetburnerText, post, KEY} from "./Terminal";
import {Terminal, postNetburnerText} from "./Terminal";
import {KEY} from "../utils/helpers/keyCodes";
import {Page, routing} from "./ui/navigationTracking";
// These should really be imported with the module that is presenting that UI, but because they very much depend on the
// cascade order, we'll pull them all in here.
@ -126,7 +130,7 @@ $(document).keydown(function(e) {
Engine.loadCreateProgramContent();
} else if (e.keyCode === KEY.F && e.altKey) {
//Overriden by Fconf
if (Engine.currentPage === Engine.Page.Terminal && FconfSettings.ENABLE_BASH_HOTKEYS) {
if (routing.isOn(Page.Terminal) && FconfSettings.ENABLE_BASH_HOTKEYS) {
return;
}
e.preventDefault();
@ -255,45 +259,15 @@ let Engine = {
characterInfo: null,
},
//Current page status
Page: {
Terminal: "Terminal",
CharacterInfo: "CharacterInfo",
ScriptEditor: "ScriptEditor",
ActiveScripts: "ActiveScripts",
HacknetNodes: "HacknetNodes",
World: "World",
CreateProgram: "CreateProgram",
Factions: "Factions",
Faction: "Faction",
Augmentations: "Augmentations",
Tutorial: "Tutorial",
DevMenu: "Dev Menu",
Location: "Location",
workInProgress: "WorkInProgress",
RedPill: "RedPill",
CinematicText: "CinematicText",
Infiltration: "Infiltration",
StockMarket: "StockMarket",
Gang: "Gang",
Mission: "Mission",
Corporation: "Corporation",
Bladeburner: "Bladeburner",
},
currentPage: null,
overview: new CharacterOverview(),
//Time variables (milliseconds unix epoch time)
_lastUpdate: new Date().getTime(),
_idleSpeed: 200, //Speed (in ms) at which the main loop is updated
/* Load content when a main menu button is clicked */
loadTerminalContent: function() {
Engine.hideAllContent();
Engine.Display.terminalContent.style.display = "block";
Engine.currentPage = Engine.Page.Terminal;
routing.navigateTo(Page.Terminal);
document.getElementById("terminal-menu-link").classList.add("active");
},
@ -301,7 +275,7 @@ let Engine = {
Engine.hideAllContent();
Engine.Display.characterContent.style.display = "block";
Engine.displayCharacterInfo();
Engine.currentPage = Engine.Page.CharacterInfo;
routing.navigateTo(Page.CharacterInfo);
document.getElementById("stats-menu-link").classList.add("active");
},
@ -315,7 +289,7 @@ let Engine = {
}
editor.focus();
updateScriptEditorContent();
Engine.currentPage = Engine.Page.ScriptEditor;
routing.navigateTo(Page.ScriptEditor);
document.getElementById("create-script-menu-link").classList.add("active");
},
@ -323,7 +297,7 @@ let Engine = {
Engine.hideAllContent();
Engine.Display.activeScriptsContent.style.display = "block";
updateActiveScriptsItems();
Engine.currentPage = Engine.Page.ActiveScripts;
routing.navigateTo(Page.ActiveScripts);
document.getElementById("active-scripts-menu-link").classList.add("active");
},
@ -331,7 +305,7 @@ let Engine = {
Engine.hideAllContent();
Engine.Display.hacknetNodesContent.style.display = "block";
displayHacknetNodesContent();
Engine.currentPage = Engine.Page.HacknetNodes;
routing.navigateTo(Page.HacknetNodes);
document.getElementById("hacknet-nodes-menu-link").classList.add("active");
},
@ -339,7 +313,7 @@ let Engine = {
Engine.hideAllContent();
Engine.Display.worldContent.style.display = "block";
Engine.displayWorldInfo();
Engine.currentPage = Engine.Page.World;
routing.navigateTo(Page.World);
document.getElementById("city-menu-link").classList.add("active");
},
@ -347,7 +321,7 @@ let Engine = {
Engine.hideAllContent();
Engine.Display.createProgramContent.style.display = "block";
displayCreateProgramContent();
Engine.currentPage = Engine.Page.CreateProgram;
routing.navigateTo(Page.CreateProgram);
document.getElementById("create-program-menu-link").classList.add("active");
},
@ -355,21 +329,21 @@ let Engine = {
Engine.hideAllContent();
Engine.Display.factionsContent.style.display = "block";
Engine.displayFactionsInfo();
Engine.currentPage = Engine.Page.Factions;
routing.navigateTo(Page.Factions);
document.getElementById("factions-menu-link").classList.add("active");
},
loadFactionContent: function() {
Engine.hideAllContent();
Engine.Display.factionContent.style.display = "block";
Engine.currentPage = Engine.Page.Faction;
routing.navigateTo(Page.Faction);
},
loadAugmentationsContent: function() {
Engine.hideAllContent();
Engine.Display.augmentationsContent.style.display = "block";
displayAugmentationsContent();
Engine.currentPage = Engine.Page.Augmentations;
routing.navigateTo(Page.Augmentations);
document.getElementById("augmentations-menu-link").classList.add("active");
},
@ -377,7 +351,7 @@ let Engine = {
Engine.hideAllContent();
Engine.Display.tutorialContent.style.display = "block";
Engine.displayTutorialContent();
Engine.currentPage = Engine.Page.Tutorial;
routing.navigateTo(Page.Tutorial);
document.getElementById("tutorial-menu-link").classList.add("active");
},
@ -385,7 +359,7 @@ let Engine = {
Engine.hideAllContent();
Engine.Display.devMenuContent.style.display = "block";
Engine.displayDevMenuContent();
Engine.currentPage = Engine.Page.DevMenu;
routing.navigateTo(Page.DevMenu);
document.getElementById("dev-menu-link").classList.add("active");
},
@ -393,7 +367,7 @@ let Engine = {
Engine.hideAllContent();
Engine.Display.locationContent.style.display = "block";
displayLocationContent();
Engine.currentPage = Engine.Page.Location;
routing.navigateTo(Page.Location);
},
loadTravelContent: function() {
@ -439,7 +413,7 @@ let Engine = {
//mainMenu.style.visibility = "hidden";
mainMenu.style.visibility = "hidden";
Engine.Display.workInProgressContent.style.display = "block";
Engine.currentPage = Engine.Page.WorkInProgress;
routing.navigateTo(Page.WorkInProgress);
},
loadRedPillContent: function() {
@ -447,7 +421,7 @@ let Engine = {
var mainMenu = document.getElementById("mainmenu-container");
mainMenu.style.visibility = "hidden";
Engine.Display.redPillContent.style.display = "block";
Engine.currentPage = Engine.Page.RedPill;
routing.navigateTo(Page.RedPill);
},
loadCinematicTextContent: function() {
@ -455,19 +429,19 @@ let Engine = {
var mainMenu = document.getElementById("mainmenu-container");
mainMenu.style.visibility = "hidden";
Engine.Display.cinematicTextContent.style.display = "block";
Engine.currentPage = Engine.Page.CinematicText;
routing.navigateTo(Page.CinematicText);
},
loadInfiltrationContent: function() {
Engine.hideAllContent();
Engine.Display.infiltrationContent.style.display = "block";
Engine.currentPage = Engine.Page.Infiltration;
routing.navigateTo(Page.Infiltration);
},
loadStockMarketContent: function() {
Engine.hideAllContent();
Engine.Display.stockMarketContent.style.display = "block";
Engine.currentPage = Engine.Page.StockMarket;
routing.navigateTo(Page.StockMarket);
displayStockMarketContent();
},
@ -475,10 +449,10 @@ let Engine = {
Engine.hideAllContent();
if (document.getElementById("gang-container") || Player.inGang()) {
displayGangContent();
Engine.currentPage = Engine.Page.Gang;
routing.navigateTo(Page.Gang);
} else {
Engine.loadTerminalContent();
Engine.currentPage = Engine.Page.Terminal;
routing.navigateTo(Page.Terminal);
}
},
@ -487,7 +461,7 @@ let Engine = {
document.getElementById("mainmenu-container").style.visibility = "hidden";
document.getElementById("character-overview-wrapper").style.visibility = "hidden";
Engine.Display.missionContent.style.display = "block";
Engine.currentPage = Engine.Page.Mission;
routing.navigateTo(Page.Mission);
},
loadCorporationContent: function() {
@ -495,7 +469,7 @@ let Engine = {
Engine.hideAllContent();
document.getElementById("character-overview-wrapper").style.visibility = "hidden";
Player.corporation.createUI();
Engine.currentPage = Engine.Page.Corporation;
routing.navigateTo(Page.Corporation);
}
},
@ -503,7 +477,7 @@ let Engine = {
if (Player.bladeburner instanceof Bladeburner) {
try {
Engine.hideAllContent();
Engine.currentPage = Engine.Page.Bladeburner;
routing.navigateTo(Page.Bladeburner);
Player.bladeburner.createContent();
} catch(e) {
exceptionAlert(e);
@ -1061,7 +1035,7 @@ let Engine = {
if (Engine.Counters.updateActiveScriptsDisplay <= 0) {
//Always update, but make the interval longer if the page isn't active
updateActiveScriptsItems();
if (Engine.currentPage === Engine.Page.ActiveScripts) {
if (routing.isOn(Page.ActiveScripts)) {
Engine.Counters.updateActiveScriptsDisplay = 5;
} else {
Engine.Counters.updateActiveScriptsDisplay = 10;
@ -1070,11 +1044,11 @@ let Engine = {
if (Engine.Counters.updateDisplays <= 0) {
Engine.displayCharacterOverviewInfo();
if (Engine.currentPage == Engine.Page.CharacterInfo) {
if (routing.isOn(Page.CharacterInfo)) {
Engine.displayCharacterInfo();
} else if (Engine.currentPage == Engine.Page.HacknetNodes) {
} else if (routing.isOn(Page.HacknetNodes)) {
updateHacknetNodesContent();
} else if (Engine.currentPage == Engine.Page.CreateProgram) {
} else if (routing.isOn(Page.CreateProgram)) {
displayCreateProgramContent();
}
@ -1086,16 +1060,16 @@ let Engine = {
}
if (Engine.Counters.updateDisplaysMed <= 0) {
if (Engine.currentPage === Engine.Page.Corporation) {
if (routing.isOn(Page.Corporation)) {
Player.corporation.updateUIContent();
}
Engine.Counters.updateDisplaysMed = 9;
}
if (Engine.Counters.updateDisplaysLong <= 0) {
if (Engine.currentPage === Engine.Page.Gang) {
if (routing.isOn(Page.Gang)) {
updateGangContent();
} else if (Engine.currentPage === Engine.Page.ScriptEditor) {
} else if (routing.isOn(Page.ScriptEditor)) {
updateScriptEditorContent();
}
Engine.Counters.updateDisplaysLong = 15;
@ -1210,23 +1184,6 @@ let Engine = {
}
},
_prevTimeout: null,
createStatusText: function(txt) {
if (Engine._prevTimeout != null) {
clearTimeout(Engine._prevTimeout);
Engine._prevTimeout = null;
}
var statusText = document.getElementById("status-text")
statusText.style.display = "inline-block";
statusText.setAttribute("class", "status-text");
statusText.innerHTML = txt;
Engine._prevTimeout = setTimeout(function() {
statusText.style.display = "none";
statusText.removeAttribute("class");
statusText.innerHTML = "";
}, 3000);
},
//Used when initializing a game
//elems should be an array of all DOM elements under the header
closeMainMenuHeader: function(elems) {
@ -1451,7 +1408,7 @@ let Engine = {
setDisplayElements: function() {
//Content elements
Engine.Display.terminalContent = document.getElementById("terminal-container");
Engine.currentPage = Engine.Page.Terminal;
routing.navigateTo(Page.Terminal);
Engine.Display.characterContent = document.getElementById("character-container");
Engine.Display.characterContent.style.display = "none";

@ -9,3 +9,29 @@ export type EqualityFunc<T> = (a: T, b: T) => boolean;
export interface IMap<T> {
[key: string]: T;
}
/**
* Performs some action, with no returned value.
*/
export type Action = () => void;
/**
* Contains a method to initialize itself to a known state.
*/
export interface ISelfInitializer {
/**
* Initialize/reset the object to a known, default state.
*/
init(): void;
}
/**
* Contains a method to repopulate itself based on a JSON string.
*/
export interface ISelfLoading {
/**
* Loads the save state onto the current object.
* @param saveState JSON string representing the save state.
*/
load(saveState: string): void;
}

@ -0,0 +1,27 @@
import { getElementById } from "../../utils/uiHelpers/getElementById";
import { Action } from "../types";
const threeSeconds: number = 3000;
let x: number | undefined;
/**
* Displays a status message to the player for approximately 3 seconds.
* @param text The status text to display
*/
export function createStatusText(text: string) {
if (x !== undefined) {
clearTimeout(x);
// Likely not needed due to clearTimeout, but just in case...
x = undefined;
}
const statusElement: HTMLElement = getElementById("status-text");
statusElement.classList.add("status-text");
statusElement.innerText = text;
const handler: Action = () => {
statusElement.classList.remove("status-text");
statusElement.innerText = "";
};
x = setTimeout(handler, threeSeconds);
}

@ -0,0 +1,146 @@
/**
* The full-screen page the player is currently be on.
* These pages are mutually exclusive.
*/
export enum Page {
/**
* (Default) The terminal is where the player issues all commands, executes scripts, etc.
*/
Terminal = "Terminal",
/**
* Displays most of the statistics about the player.
*/
CharacterInfo = "CharacterInfo",
/**
* The console for editing Netscript files.
*/
ScriptEditor = "ScriptEditor",
/**
* Monitor the scripts currently executing across the servers.
*/
ActiveScripts = "ActiveScripts",
/**
* View, purchase, and upgrade Hacknet nodes.
*/
HacknetNodes = "HacknetNodes",
/**
* View the city the player is currently in.
*/
World = "World",
/**
* The list of programs the player could potentially build.
*/
CreateProgram = "CreateProgram",
/**
* The list of all factions, and invites, available to the player.
*/
Factions = "Factions",
/**
* Information about a specific faction.
*/
Faction = "Faction",
/**
* The list of installed, and yet-to-be installed, augmentations the player has purchased.
*/
Augmentations = "Augmentations",
/**
* A collection of in-game material to learn about the game.
*/
Tutorial = "Tutorial",
/**
* A collection of items to manipulate the state of the game. Useful for development.
*/
DevMenu = "Dev Menu",
/**
* Information about the specific location the player at (job, company, etc.);
*/
Location = "Location",
/**
* A blocking page to show the player they are currently doing some action (building a program, working, etc.).
*/
workInProgress = "WorkInProgress",
/**
* A special screen to show the player they've reached a certain point in the game.
*/
RedPill = "RedPill",
/**
* A special screen to show the player they've reached a certain point in the game.
*/
CinematicText = "CinematicText",
/**
* Mini-game to infiltrate a company, gaining experience from successful progress.
*/
Infiltration = "Infiltration",
/**
* View the in-game stock market.
*/
StockMarket = "StockMarket",
/**
* Manage gang actions and members.
*/
Gang = "Gang",
/**
* Perform missions for a Faction.
*/
Mission = "Mission",
/**
* Manage a corporation.
*/
Corporation = "Corporation",
/**
* Manage special Bladeburner activities.
*/
Bladeburner = "Bladeburner",
}
/**
* This class keeps track of player navigation/routing within the game.
*/
class Routing {
/**
* Tracking the what page the user is currently on.
*/
private currentPage: Page | null = null;
/**
* Determines if the player is currently on the specified page.
* @param page The page to compare against the current state.
*/
isOn(page: Page) {
return this.currentPage === page;
}
/**
* Routes the player to the appropriate page.
* @param page The page to navigate to.
*/
navigateTo(page: Page) {
this.currentPage = page;
}
}
/**
* The routing instance for tracking page navigation.
*/
export const routing: Routing = new Routing();

40
src/ui/postToTerminal.ts Normal file

@ -0,0 +1,40 @@
import { getElementById } from "../../utils/uiHelpers/getElementById";
/**
* Adds some output to the terminal.
* @param input Text or HTML to output to the terminal
*/
export function post(input: string) {
postContent(input);
}
/**
* Adds some output to the terminal with an identifier of "hack-progress-bar"
* @param input Text or HTML to output to the terminal
*/
export function hackProgressBarPost(input: string) {
postContent(input, "hack-progress-bar");
}
/**
* Adds some output to the terminal with an identifier of "hack-progress"
* @param input Text or HTML to output to the terminal
*/
export function hackProgressPost(input: string) {
postContent(input, "hack-progress");
}
function postContent(input: string, id?: string) {
// tslint:disable-next-line:max-line-length
const style: string = `color: var(--my-font-color); background-color:var(--my-background-color);${id === undefined ? " white-space:pre-wrap;" : ""}`;
// tslint:disable-next-line:max-line-length
const content: string = `<tr class="posted"><td ${id === undefined ? 'class="terminal-line"' : `id="${id}"`} style="${style}">${input}</td></tr>`;
const inputElement: HTMLElement = getElementById("terminal-input");
inputElement.insertAdjacentHTML("beforebegin", content);
scrollTerminalToBottom();
}
function scrollTerminalToBottom() {
const container: HTMLElement = getElementById("terminal-container");
container.scrollTop = container.scrollHeight;
}

@ -1,38 +1,5 @@
import {Engine} from "./engine";
/* Settings.js */
let Settings = {
CodeInstructionRunTime: 25,
MaxLogCapacity: 50,
MaxPortCapacity: 50,
SuppressMessages: false,
SuppressFactionInvites: false,
SuppressTravelConfirmation: false,
SuppressBuyAugmentationConfirmation: false,
AutosaveInterval: 60,
DisableHotkeys: false,
ThemeHighlightColor: "#ffffff",
ThemeFontColor: "#66ff33",
ThemeBackgroundColor: "#000000",
EditorTheme: "Monokai",
EditorKeybinding: "ace",
}
function loadSettings(saveString) {
Settings = JSON.parse(saveString);
}
function initSettings() {
Settings.CodeInstructionRunTime = 50;
Settings.MaxLogCapacity = 50;
Settings.MaxPortCapacity = 50;
Settings.SuppressMessages = false;
Settings.SuppressFactionInvites = false;
Settings.SuppressTravelConfirmation = false;
Settings.SuppressBuyAugmentationConfirmation = false;
Settings.AutosaveInterval = 60;
Settings.DisableHotkeys = false;
}
import {Engine} from "../engine";
import {Settings} from "../Settings";
function setSettingsLabels() {
var nsExecTime = document.getElementById("settingsNSExecTimeRangeValLabel");
@ -126,4 +93,4 @@ function setSettingsLabels() {
}
}
export {Settings, initSettings, setSettingsLabels, loadSettings};
export { setSettingsLabels };

@ -1,7 +1,8 @@
import {Faction, joinFaction} from "../src/Faction";
import {joinFaction} from "../src/Faction";
import {Engine} from "../src/engine";
import {Player} from "../src/Player";
import {clearEventListeners} from "./uiHelpers/clearEventListeners";
import {Page, routing} from "../src/ui/navigationTracking";
/* Faction Invitation Pop-up box */
function factionInvitationBoxClose() {
@ -30,7 +31,7 @@ function factionInvitationBoxCreate(faction) {
faction.alreadyInvited = true;
Player.factionInvitations.push(faction.name);
if (Engine.currentPage === Engine.Page.Factions) {
if (routing.isOn(Page.Factions)) {
Engine.loadFactionsContent();
}
@ -45,7 +46,7 @@ function factionInvitationBoxCreate(faction) {
}
joinFaction(faction);
factionInvitationBoxClose();
if (Engine.currentPage === Engine.Page.Factions) {
if (routing.isOn(Page.Factions)) {
Engine.loadFactionsContent();
}
return false;

@ -1,4 +1,4 @@
import {BitNodeMultipliers} from "../src/BitNode";
import {BitNodeMultipliers} from "../src/BitNodeMultipliers";
import {CONSTANTS} from "../src/Constants";
import {Factions, Faction} from "../src/Faction";
import {Player} from "../src/Player";

30
utils/helpers/keyCodes.ts Normal file

@ -0,0 +1,30 @@
import { IMap } from "../../src/types";
/**
* Keyboard key codes
*/
export const KEY: IMap<number> = {
A: 65,
B: 66,
C: 67,
CTRL: 17,
D: 68,
DOWNARROW: 40,
E: 69,
ENTER: 13,
F: 70,
H: 72,
J: 74,
K: 75,
L: 76,
M: 77,
N: 78,
O: 79,
P: 80,
R: 82,
S: 83,
TAB: 9,
U: 85,
UPARROW: 38,
W: 87,
};

@ -4,5 +4,6 @@
*/
export function roundToTwo(decimal: number) {
const leftShift: number = Math.round(parseFloat(`${decimal}e+2`));
return +(`${leftShift}e-2`);
}

@ -27,18 +27,18 @@ interface IAccordionConfigurationParameters {
export function createAccordionElement(params: IAccordionConfigurationParameters) {
const liElem: HTMLLIElement = createElement("li") as HTMLLIElement;
const header: HTMLButtonElement = createElement("button", {
class: "accordion-header",
clickListener() {
this.classList.toggle("active");
const pnl: CSSStyleDeclaration = (this.nextElementSibling as HTMLDivElement).style;
pnl.display = pnl.display === "block" ? "none" : "block";
},
id: params.id !== undefined ? `${params.id}-hdr` : undefined,
class:"accordion-header",
innerHTML: params.hdrText,
}) as HTMLButtonElement;
const panel: HTMLDivElement = createElement("div", {
class: "accordion-panel",
id: params.id !== undefined ? `${params.id}-panel` : undefined,
class:"accordion-panel",
innerHTML: params.panelText,
}) as HTMLDivElement;

@ -10,7 +10,7 @@ export function createPopup(id: string, elems: HTMLElement[]) {
const container: HTMLDivElement = createElement("div", {
class: "popup-box-container",
display: "block",
id: id,
id,
}) as HTMLDivElement;
const content: HTMLElement = createElement("div", {
class: "popup-box-content",