From 2d374093922c0f0a19fff26df41f9f4e036605ab Mon Sep 17 00:00:00 2001
From: danielyxie
Date: Tue, 14 May 2019 20:56:59 -0700
Subject: [PATCH 1/9] Refactored SourceFile-related code to TypeScript
---
css/augmentations.scss | 27 ++
css/menupages.scss | 46 ----
src/Augmentation/AugmentationHelpers.js | 12 -
.../ui/InstalledAugmentations.tsx | 40 +++
.../InstalledAugmentationsAndSourceFiles.tsx | 56 ++++
src/Augmentation/ui/ListConfiguration.tsx | 5 +
src/Augmentation/ui/OwnedSourceFiles.tsx | 40 +++
.../ui/PurchasedAugmentations.tsx | 30 ++
src/Augmentation/ui/Root.tsx | 72 +++++
src/PersonObjects/IPlayer.ts | 4 +
.../Player/PlayerObjectGeneralMethods.js | 3 +-
src/RedPill.js | 5 +-
src/SourceFile.js | 256 ------------------
src/SourceFile/SourceFile.ts | 21 ++
src/SourceFile/SourceFiles.ts | 64 +++++
src/SourceFile/applySourceFile.ts | 176 ++++++++++++
src/engine.jsx | 11 +-
src/engineStyle.js | 1 +
src/ui/React/AugmentationAccordion.tsx | 33 +++
src/ui/React/Popup.tsx | 14 +-
src/ui/React/StdButton.tsx | 53 ++--
21 files changed, 608 insertions(+), 361 deletions(-)
create mode 100644 css/augmentations.scss
create mode 100644 src/Augmentation/ui/InstalledAugmentations.tsx
create mode 100644 src/Augmentation/ui/InstalledAugmentationsAndSourceFiles.tsx
create mode 100644 src/Augmentation/ui/ListConfiguration.tsx
create mode 100644 src/Augmentation/ui/OwnedSourceFiles.tsx
create mode 100644 src/Augmentation/ui/PurchasedAugmentations.tsx
create mode 100644 src/Augmentation/ui/Root.tsx
delete mode 100644 src/SourceFile.js
create mode 100644 src/SourceFile/SourceFile.ts
create mode 100644 src/SourceFile/SourceFiles.ts
create mode 100644 src/SourceFile/applySourceFile.ts
create mode 100644 src/ui/React/AugmentationAccordion.tsx
diff --git a/css/augmentations.scss b/css/augmentations.scss
new file mode 100644
index 000000000..eb7fd3722
--- /dev/null
+++ b/css/augmentations.scss
@@ -0,0 +1,27 @@
+/**
+ * Styling for the Augmentations UI. This is the page that displays all of the
+ * player's owned and purchased Augmentations and Source-Files. It also allows
+ * the player to install Augmentations
+ */
+@import "theme";
+
+#augmentations-container {
+ position: fixed;
+ padding-top: 10px;
+}
+
+.augmentations-list {
+ button,
+ div {
+ color: var(--my-font-color);
+ text-decoration: none;
+ }
+
+ button {
+ padding: 2px 5px;
+ }
+
+ div {
+ padding: 6px;
+ }
+}
diff --git a/css/menupages.scss b/css/menupages.scss
index 0c8e55033..b0b45c723 100644
--- a/css/menupages.scss
+++ b/css/menupages.scss
@@ -185,19 +185,6 @@
width: 70%;
}
-#faction-donate-amount-txt,
-#faction-donate-input {
- padding: 6px;
- margin: 6px;
- display: inline-block;
- color: var(--my-font-color);
- background-color: #000;
-}
-
-#faction-donate-amount-txt {
- width: 50%;
-}
-
#faction-container p,
#faction-container pre {
padding: 4px 6px;
@@ -213,45 +200,12 @@
word-wrap: break-word; /* Internet Explorer 5.5+ */
}
-/* Faction Augmentations */
-#faction-augmentations-container {
- position: fixed;
- padding-top: 10px;
-
- p, a, ul, h1 {
- margin: 8px;
- padding: 4px;
- }
-}
-
/* World */
#world-container li {
margin: 0 0 15px 0;
list-style-type: none;
}
-/* Augmentations */
-#augmentations-container {
- position: fixed;
- padding-top: 10px;
-}
-
-.augmentations-list {
- button,
- div {
- color: var(--my-font-color);
- text-decoration: none;
- }
-
- button {
- padding: 2px 5px;
- }
-
- div {
- padding: 6px;
- }
-}
-
/* Tutorial */
#tutorial-container {
position: fixed;
diff --git a/src/Augmentation/AugmentationHelpers.js b/src/Augmentation/AugmentationHelpers.js
index 7110b70c8..9c6809344 100644
--- a/src/Augmentation/AugmentationHelpers.js
+++ b/src/Augmentation/AugmentationHelpers.js
@@ -17,7 +17,6 @@ import { Server } from "../Server/Server";
import { OwnedAugmentationsOrderSetting } from "../Settings/SettingEnums";
import { Settings } from "../Settings/Settings";
-import { SourceFiles } from "../SourceFile";
import { dialogBoxCreate } from "../../utils/DialogBox";
import { createAccordionElement } from "../../utils/uiHelpers/createAccordionElement";
import { Reviver, Generic_toJSON,
@@ -2041,17 +2040,6 @@ function applyAugmentation(aug, reapply=false) {
}
}
- /*
- if (aug.name === AugmentationNames.NeuroFluxGovernor) {
- for (var i = 0; i < Player.augmentations.length; ++i) {
- if (Player.augmentations[i].name == AugmentationNames.NeuroFluxGovernor) {
- //Already have this aug, just upgrade the level
- return;
- }
- }
- }
- */
-
// Push onto Player's Augmentation list
if (!reapply) {
var ownedAug = new PlayerOwnedAugmentation(aug.name);
diff --git a/src/Augmentation/ui/InstalledAugmentations.tsx b/src/Augmentation/ui/InstalledAugmentations.tsx
new file mode 100644
index 000000000..84d8cb2ea
--- /dev/null
+++ b/src/Augmentation/ui/InstalledAugmentations.tsx
@@ -0,0 +1,40 @@
+/**
+ * React Component for displaying a list of the player's installed Augmentations
+ * on the Augmentations UI
+ */
+import * as React from "react";
+
+import { Player } from "../../Player";
+import { Augmentations } from "../../Augmentation/Augmentations";
+import { AugmentationNames } from "../../Augmentation/data/AugmentationNames";
+import { Settings } from "../../Settings/Settings";
+import { OwnedAugmentationsOrderSetting } from "../../Settings/SettingEnums";
+
+import { AugmentationAccordion } from "../../ui/React/AugmentationAccordion";
+
+export function InstalledAugmentations(): React.ReactElement {
+ const sourceAugs = Player.augmentations.slice();
+
+ if (Settings.OwnedAugmentationsOrder === OwnedAugmentationsOrderSetting.Alphabetically) {
+ sourceAugs.sort((aug1, aug2) => {
+ return aug1.name <= aug2.name ? -1 : 1;
+ });
+ }
+
+ const augs = sourceAugs.map((e) => {
+ const aug = Augmentations[e.name];
+
+ let level = null;
+ if (e.name === AugmentationNames.NeuroFluxGovernor) {
+ level = e.level;
+ }
+
+ return (
+
+ )
+ });
+
+ return (
+
{augs}
+ )
+}
diff --git a/src/Augmentation/ui/InstalledAugmentationsAndSourceFiles.tsx b/src/Augmentation/ui/InstalledAugmentationsAndSourceFiles.tsx
new file mode 100644
index 000000000..39bac22e6
--- /dev/null
+++ b/src/Augmentation/ui/InstalledAugmentationsAndSourceFiles.tsx
@@ -0,0 +1,56 @@
+/**
+ * React Component for displaying all of the player's installed Augmentations and
+ * Source-Files.
+ *
+ * It also contains 'configuration' buttons that allow you to change how the
+ * Augs/SF's are displayed
+ */
+import * as React from "react";
+
+import { Settings } from "../../Settings/Settings";
+import { OwnedAugmentationsOrderSetting } from "../../Settings/SettingEnums";
+
+type IProps = {
+
+}
+
+type IState = {
+ rerenderFlag: boolean;
+}
+
+export class InstalledAugmentationsAndSourceFiles extends React.Component {
+ constructor(props: IProps) {
+ super(props);
+
+ this.state = {
+ rerenderFlag: false,
+ }
+
+ this.sortByAcquirementTime = this.sortByAcquirementTime.bind(this);
+ this.sortInOrder = this.sortInOrder.bind(this);
+ }
+
+ rerender() {
+ this.setState((prevState) => {
+ return {
+ rerenderFlag: !prevState.rerenderFlag,
+ }
+ });
+ }
+
+ sortByAcquirementTime() {
+ Settings.OwnedAugmentationsOrder = OwnedAugmentationsOrderSetting.AcquirementTime;
+ this.rerender();
+ }
+
+ sortInOrder() {
+ Settings.OwnedAugmentationsOrder = OwnedAugmentationsOrderSetting.Alphabetically
+ this.rerender();
+ }
+
+ render() {
+ return (
+
+ )
+ }
+}
diff --git a/src/Augmentation/ui/ListConfiguration.tsx b/src/Augmentation/ui/ListConfiguration.tsx
new file mode 100644
index 000000000..ef1368b8f
--- /dev/null
+++ b/src/Augmentation/ui/ListConfiguration.tsx
@@ -0,0 +1,5 @@
+/**
+ * React Component for configuring the way installed augmentations and
+ * Source-Files are displayed in the Augmentations UI
+ */
+import * as React from "react";
diff --git a/src/Augmentation/ui/OwnedSourceFiles.tsx b/src/Augmentation/ui/OwnedSourceFiles.tsx
new file mode 100644
index 000000000..24107bcdf
--- /dev/null
+++ b/src/Augmentation/ui/OwnedSourceFiles.tsx
@@ -0,0 +1,40 @@
+/**
+ * React Component for displaying a list of the player's Source-Files
+ * on the Augmentations UI
+ */
+import * as React from "react";
+
+import { Player } from "../../Player";
+import { Augmentations } from "../../Augmentation/Augmentations";
+import { AugmentationNames } from "../../Augmentation/data/AugmentationNames";
+import { Settings } from "../../Settings/Settings";
+import { OwnedAugmentationsOrderSetting } from "../../Settings/SettingEnums";
+
+import { AugmentationAccordion } from "../../ui/React/AugmentationAccordion";
+
+export function OwnedSourceFiles(): React.ReactElement {
+ const sourceAugs = Player.augmentations.slice();
+
+ if (Settings.OwnedAugmentationsOrder === OwnedAugmentationsOrderSetting.Alphabetically) {
+ sourceAugs.sort((aug1, aug2) => {
+ return aug1.name <= aug2.name ? -1 : 1;
+ });
+ }
+
+ const augs = sourceAugs.map((e) => {
+ const aug = Augmentations[e.name];
+
+ let level = null;
+ if (e.name === AugmentationNames.NeuroFluxGovernor) {
+ level = e.level;
+ }
+
+ return (
+
+ )
+ });
+
+ return (
+
{augs}
+ )
+}
diff --git a/src/Augmentation/ui/PurchasedAugmentations.tsx b/src/Augmentation/ui/PurchasedAugmentations.tsx
new file mode 100644
index 000000000..bd966dfe5
--- /dev/null
+++ b/src/Augmentation/ui/PurchasedAugmentations.tsx
@@ -0,0 +1,30 @@
+/**
+ * React component for displaying all of the player's purchased (but not installed)
+ * Augmentations on the Augmentations UI.
+ */
+import * as React from "react";
+
+import { Augmentations } from "../../Augmentation/Augmentations";
+import { AugmentationNames } from "../../Augmentation/data/AugmentationNames";
+import { Player } from "../../Player";
+
+import { AugmentationAccordion } from "../../ui/React/AugmentationAccordion";
+
+export function PurchasedAugmentations(): React.ReactElement {
+ const augs: React.ReactElement[] = [];
+ for (const ownedAug of Player.queuedAugmentations) {
+ const aug = Augmentations[ownedAug.name];
+ let level = null;
+ if (ownedAug.name === AugmentationNames.NeuroFluxGovernor) {
+ level = ownedAug.level;
+ }
+
+ augs.push(
+
+ )
+ }
+
+ return (
+
{augs}
+ )
+}
diff --git a/src/Augmentation/ui/Root.tsx b/src/Augmentation/ui/Root.tsx
new file mode 100644
index 000000000..565267f31
--- /dev/null
+++ b/src/Augmentation/ui/Root.tsx
@@ -0,0 +1,72 @@
+/**
+ * Root React component for the Augmentations UI page that display all of your
+ * owned and purchased Augmentations and Source-Files.
+ */
+import * as React from "react";
+
+import { Augmentations } from "../../Augmentation/Augmentations";
+import { Player } from "../../Player";
+
+import { StdButton } from "../../ui/React/StdButton";
+
+type IProps = {
+ exportGameFn: () => void;
+ installAugmentationsFn: () => void;
+}
+
+type IState = {
+
+}
+
+export class AugmentationsRoot extends React.Component {
+ constructor(props: IProps) {
+ super(props);
+ }
+
+ render() {
+ return (
+
+
Purchased Augmentations
+
+ Below is a list of all Augmentations you have purchased but not
+ yet installed. Click the button below to install them.
+
+
+ WARNING: Installing your Augmentations resets most of your progress,
+ including:
+
+
- Stats/Skill levels and Experience
+
- Money
+
- Scripts on every computer but your home computer
+
- Purchased servers
+
- Hacknet Nodes
+
- Faction/Company reputation
+
- Stocks
+
+ Installing Augmentations lets you start over with the perks and
+ benefits granted by all of the Augmentations you have ever
+ installed. Also, you will keep any scripts and RAM/Core upgrades
+ on your home computer (but you will lose all programs besides
+ NUKE.exe)
+
+
+
+
+
+
+
+
+
+
+ )
+ }
+}
diff --git a/src/PersonObjects/IPlayer.ts b/src/PersonObjects/IPlayer.ts
index be95132c8..09146f514 100644
--- a/src/PersonObjects/IPlayer.ts
+++ b/src/PersonObjects/IPlayer.ts
@@ -101,6 +101,10 @@ export interface IPlayer {
work_money_mult: number;
crime_success_mult: number;
crime_money_mult: number;
+ bladeburner_max_stamina_mult: number;
+ bladeburner_stamina_gain_mult: number;
+ bladeburner_analysis_mult: number;
+ bladeburner_success_chance_mult: number;
// Methods
applyForAgentJob(sing?: boolean): boolean | void;
diff --git a/src/PersonObjects/Player/PlayerObjectGeneralMethods.js b/src/PersonObjects/Player/PlayerObjectGeneralMethods.js
index c263175d5..385c836cf 100644
--- a/src/PersonObjects/Player/PlayerObjectGeneralMethods.js
+++ b/src/PersonObjects/Player/PlayerObjectGeneralMethods.js
@@ -36,7 +36,8 @@ import {
import { safetlyCreateUniqueServer } from "../../Server/ServerHelpers";
import { Settings } from "../../Settings/Settings";
import { SpecialServerIps, SpecialServerNames } from "../../Server/SpecialServerIps";
-import { SourceFiles, applySourceFile } from "../../SourceFile";
+import { applySourceFile } from "../../SourceFile/applySourceFile";
+import { SourceFiles } from "../../SourceFile/SourceFiles";
import { SourceFileFlags } from "../../SourceFile/SourceFileFlags";
import Decimal from "decimal.js";
diff --git a/src/RedPill.js b/src/RedPill.js
index 23a56ccfe..c4cebac46 100644
--- a/src/RedPill.js
+++ b/src/RedPill.js
@@ -5,7 +5,7 @@ import { BitNodes } from "./BitNode/BitNode";
import { Engine } from "./engine";
import { Player } from "./Player";
import { prestigeSourceFile } from "./Prestige";
-import { SourceFiles, SourceFile } from "./SourceFile";
+import { SourceFiles } from "./SourceFile/SourceFiles";
import { PlayerOwnedSourceFile } from "./SourceFile/PlayerOwnedSourceFile";
import { Terminal } from "./Terminal";
import { setTimeoutRef } from "./utils/SetTimeoutRef";
@@ -20,9 +20,6 @@ import {
import { clearEventListeners } from "../utils/uiHelpers/clearEventListeners";
import { removeChildrenFromElement } from "../utils/uiHelpers/removeChildrenFromElement";
-
-
-
// Returns promise
function writeRedPillLine(line) {
return new Promise(function(resolve, reject) {
diff --git a/src/SourceFile.js b/src/SourceFile.js
deleted file mode 100644
index 7c9219562..000000000
--- a/src/SourceFile.js
+++ /dev/null
@@ -1,256 +0,0 @@
-import { Player } from "./Player";
-import { BitNodes } from "./BitNode/BitNode";
-
-// Each SourceFile corresponds to a BitNode with the same number
-function SourceFile(number, info="") {
- var bitnodeKey = "BitNode" + number;
- var bitnode = BitNodes[bitnodeKey];
- if (bitnode == null) {
- throw new Error("Invalid Bit Node for this Source File");
- }
-
- this.n = number;
- this.name = "Source-File " + number + ": " + bitnode.name;
- this.lvl = 1;
- this.info = info;
- this.owned = false;
-}
-
-let SourceFiles = {};
-function initSourceFiles() {
- SourceFiles = {};
- SourceFiles["SourceFile1"] = new SourceFile(1, "This Source-File lets the player start with 32GB of RAM on his/her " +
- "home computer. It also increases all of the player's multipliers by:
" +
- "Level 1: 16% " +
- "Level 2: 24% " +
- "Level 3: 28%");
- SourceFiles["SourceFile2"] = new SourceFile(2, "This Source-File allows you to form gangs in other BitNodes " +
- "once your karma decreases to a certain value. It also increases the player's " +
- "crime success rate, crime money, and charisma multipliers by:
" +
- "Level 1: 24% " +
- "Level 2: 36% " +
- "Level 3: 42%");
- SourceFiles["SourceFile3"] = new SourceFile(3,"This Source-File lets you create corporations on other BitNodes (although " +
- "some BitNodes will disable this mechanic). This Source-File also increases your charisma and company salary multipliers by: " +
- "Level 1: 8% " +
- "Level 2: 12% " +
- "Level 3: 14%");
- SourceFiles["SourceFile4"] = new SourceFile(4, "This Source-File lets you access and use the Singularity Functions in every BitNode. Every " +
- "level of this Source-File opens up more of the Singularity Functions you can use.");
- SourceFiles["SourceFile5"] = new SourceFile(5, "This Source-File grants a special new stat called Intelligence. Intelligence " +
- "is unique because it is permanent and persistent (it never gets reset back to 1). However, " +
- "gaining Intelligence experience is much slower than other stats, and it is also hidden (you won't " +
- "know when you gain experience and how much). Higher Intelligence levels will boost your production " +
- "for many actions in the game. In addition, this Source-File will unlock the getBitNodeMultipliers() " +
- "Netscript function, and will raise all of your hacking-related multipliers by:
" +
- "Level 1: 8% " +
- "Level 2: 12% " +
- "Level 3: 14%");
- SourceFiles["SourceFile6"] = new SourceFile(6, "This Source-File allows you to access the NSA's Bladeburner Division in other " +
- "BitNodes. In addition, this Source-File will raise both the level and experience gain rate of all your combat stats by:
" +
- "Level 1: 8% " +
- "Level 2: 12% " +
- "Level 3: 14%");
- SourceFiles["SourceFile7"] = new SourceFile(7, "This Source-File allows you to access the Bladeburner Netscript API in other " +
- "BitNodes. In addition, this Source-File will increase all of your Bladeburner multipliers by:
" +
- "Level 1: 8% " +
- "Level 2: 12% " +
- "Level 3: 14%");
- SourceFiles["SourceFile8"] = new SourceFile(8, "This Source-File grants the following benefits:
" +
- "Level 1: Permanent access to WSE and TIX API " +
- "Level 2: Ability to short stocks in other BitNodes " +
- "Level 3: Ability to use limit/stop orders in other BitNodes
" +
- "This Source-File also increases your hacking growth multipliers by: " +
- " Level 1: 12% Level 2: 18% Level 3: 21%");
- SourceFiles["SourceFile9"] = new SourceFile(9, "This Source-File grants the following benefits:
" +
- "Level 1: Permanently unlocks the Hacknet Server in other BitNodes " +
- "Level 2: You start with 128GB of RAM on your home computer when entering a new BitNode " +
- "Level 3: Grants a highly-upgraded Hacknet Server when entering a new BitNode
" +
- "(Note that the Level 3 effect of this Source-File only applies when entering a new BitNode, NOT " +
- "when installing Augmentations)");
- SourceFiles["SourceFile10"] = new SourceFile(10, "This Source-File unlocks Sleeve technology in other BitNodes. Each level of this " +
- "Source-File also grants you a Duplicate Sleeve");
- SourceFiles["SourceFile11"] = new SourceFile(11, "This Source-File makes it so that company favor increases BOTH the player's salary and reputation gain rate " +
- "at that company by 1% per favor (rather than just the reputation gain). This Source-File also " +
- " increases the player's company salary and reputation gain multipliers by:
" +
- "Level 1: 32% " +
- "Level 2: 48% " +
- "Level 3: 56% ");
- SourceFiles["SourceFile12"] = new SourceFile(12, "This Source-File increases all your multipliers by 1% per level. This effect is multiplicative with itself. " +
- "In other words, level N of this Source-File will result in a multiplier of 1.01^N (or 0.99^N for multipliers that decrease)");
-}
-
-// Takes in a PlayerOwnedSourceFile as the "srcFile" argument
-function applySourceFile(srcFile) {
- var srcFileKey = "SourceFile" + srcFile.n;
- var sourceFileObject = SourceFiles[srcFileKey];
- if (sourceFileObject == null) {
- console.log("ERROR: Invalid source file number: " + srcFile.n);
- return;
- }
-
- switch(srcFile.n) {
- case 1: // The Source Genesis
- var mult = 0;
- for (var i = 0; i < srcFile.lvl; ++i) {
- mult += (16 / (Math.pow(2, i)));
- }
- var incMult = 1 + (mult / 100);
- var decMult = 1 - (mult / 100);
- Player.hacking_chance_mult *= incMult;
- Player.hacking_speed_mult *= incMult;
- Player.hacking_money_mult *= incMult;
- Player.hacking_grow_mult *= incMult;
- Player.hacking_mult *= incMult;
- Player.strength_mult *= incMult;
- Player.defense_mult *= incMult;
- Player.dexterity_mult *= incMult;
- Player.agility_mult *= incMult;
- Player.charisma_mult *= incMult;
- Player.hacking_exp_mult *= incMult;
- Player.strength_exp_mult *= incMult;
- Player.defense_exp_mult *= incMult;
- Player.dexterity_exp_mult *= incMult;
- Player.agility_exp_mult *= incMult;
- Player.charisma_exp_mult *= incMult;
- Player.company_rep_mult *= incMult;
- Player.faction_rep_mult *= incMult;
- Player.crime_money_mult *= incMult;
- Player.crime_success_mult *= incMult;
- Player.hacknet_node_money_mult *= incMult;
- Player.hacknet_node_purchase_cost_mult *= decMult;
- Player.hacknet_node_ram_cost_mult *= decMult;
- Player.hacknet_node_core_cost_mult *= decMult;
- Player.hacknet_node_level_cost_mult *= decMult;
- Player.work_money_mult *= incMult;
- break;
- case 2: // Rise of the Underworld
- var mult = 0;
- for (var i = 0; i < srcFile.lvl; ++i) {
- mult += (24 / (Math.pow(2, i)));
- }
- var incMult = 1 + (mult / 100);
- Player.crime_money_mult *= incMult;
- Player.crime_success_mult *= incMult;
- Player.charisma_mult *= incMult;
- break;
- case 3: // Corporatocracy
- var mult = 0;
- for (var i = 0; i < srcFile.lvl; ++i) {
- mult += (8 / (Math.pow(2, i)));
- }
- var incMult = 1 + (mult / 100);
- Player.charisma_mult *= incMult;
- Player.work_money_mult *= incMult;
- break;
- case 4: // The Singularity
- // No effects, just gives access to Singularity functions
- break;
- case 5: // Artificial Intelligence
- var mult = 0;
- for (var i = 0; i < srcFile.lvl; ++i) {
- mult += (8 / (Math.pow(2, i)));
- }
- var incMult = 1 + (mult / 100);
- Player.hacking_chance_mult *= incMult;
- Player.hacking_speed_mult *= incMult;
- Player.hacking_money_mult *= incMult;
- Player.hacking_grow_mult *= incMult;
- Player.hacking_mult *= incMult;
- Player.hacking_exp_mult *= incMult;
- break;
- case 6: // Bladeburner
- var mult = 0;
- for (var i = 0; i < srcFile.lvl; ++i) {
- mult += (8 / (Math.pow(2, i)));
- }
- var incMult = 1 + (mult / 100);
- Player.strength_exp_mult *= incMult;
- Player.defense_exp_mult *= incMult;
- Player.dexterity_exp_mult *= incMult;
- Player.agility_exp_mult *= incMult;
- Player.strength_mult *= incMult;
- Player.defense_mult *= incMult;
- Player.dexterity_mult *= incMult;
- Player.agility_mult *= incMult;
- break;
- case 7: // Bladeburner 2079
- var mult = 0;
- for (var i = 0; i < srcFile.lvl; ++i) {
- mult += (8 / (Math.pow(2, i)));
- }
- var incMult = 1 + (mult / 100);
- Player.bladeburner_max_stamina_mult *= incMult;
- Player.bladeburner_stamina_gain_mult *= incMult;
- Player.bladeburner_analysis_mult *= incMult;
- Player.bladeburner_success_chance_mult *= incMult;
- break;
- case 8: // Ghost of Wall Street
- var mult = 0;
- for (var i = 0; i < srcFile.lvl; ++i) {
- mult += (12 / (Math.pow(2, i)));
- }
- var incMult = 1 + (mult / 100);
- Player.hacking_grow_mult *= incMult;
- break;
- case 9: // Hacktocracy
- // This has non-multiplier effects
- break;
- case 10: // Digital Carbon
- // No effects, just grants sleeves
- break;
- case 11: // The Big Crash
- var mult = 0;
- for (var i = 0; i < srcFile.lvl; ++i) {
- mult += (32 / (Math.pow(2, i)));
- }
- var incMult = 1 + (mult / 100);
- Player.work_money_mult *= incMult;
- Player.company_rep_mult *= incMult;
- break;
- case 12: // The Recursion
- var inc = Math.pow(1.01, srcFile.lvl);
- var dec = Math.pow(0.99, srcFile.lvl);
-
- Player.hacking_chance_mult *= inc;
- Player.hacking_speed_mult *= inc;
- Player.hacking_money_mult *= inc;
- Player.hacking_grow_mult *= inc;
- Player.hacking_mult *= inc;
-
- Player.strength_mult *= inc;
- Player.defense_mult *= inc;
- Player.dexterity_mult *= inc;
- Player.agility_mult *= inc;
- Player.charisma_mult *= inc;
-
- Player.hacking_exp_mult *= inc;
- Player.strength_exp_mult *= inc;
- Player.defense_exp_mult *= inc;
- Player.dexterity_exp_mult *= inc;
- Player.agility_exp_mult *= inc;
- Player.charisma_exp_mult *= inc;
-
- Player.company_rep_mult *= inc;
- Player.faction_rep_mult *= inc;
-
- Player.crime_money_mult *= inc;
- Player.crime_success_mult *= inc;
-
- Player.hacknet_node_money_mult *= inc;
- Player.hacknet_node_purchase_cost_mult *= dec;
- Player.hacknet_node_ram_cost_mult *= dec;
- Player.hacknet_node_core_cost_mult *= dec;
- Player.hacknet_node_level_cost_mult *= dec;
-
- Player.work_money_mult *= inc;
- break;
- default:
- console.log("ERROR: Invalid source file number: " + srcFile.n);
- break;
- }
-
- sourceFileObject.owned = true;
-}
-
-export {SourceFiles, applySourceFile, initSourceFiles};
diff --git a/src/SourceFile/SourceFile.ts b/src/SourceFile/SourceFile.ts
new file mode 100644
index 000000000..96290507a
--- /dev/null
+++ b/src/SourceFile/SourceFile.ts
@@ -0,0 +1,21 @@
+import { BitNodes } from "../BitNode/BitNode";
+
+export class SourceFile {
+ info: string;
+ lvl: number = 1;
+ n: number;
+ name: string;
+ owned: boolean = false;
+
+ constructor(number: number, info: string="") {
+ const bitnodeKey = "BitNode" + number;
+ const bitnode = BitNodes[bitnodeKey];
+ if (bitnode == null) {
+ throw new Error("Invalid Bit Node for this Source File");
+ }
+
+ this.n = number;
+ this.name = `Source-File ${number}: ${bitnode.name}`
+ this.info = info;
+ }
+}
diff --git a/src/SourceFile/SourceFiles.ts b/src/SourceFile/SourceFiles.ts
new file mode 100644
index 000000000..bc35dcba8
--- /dev/null
+++ b/src/SourceFile/SourceFiles.ts
@@ -0,0 +1,64 @@
+import { SourceFile } from "./SourceFile";
+import { IMap } from "../types";
+
+export const SourceFiles: IMap = {};
+
+SourceFiles["SourceFile1"] = new SourceFile(1, "This Source-File lets the player start with 32GB of RAM on his/her " +
+ "home computer. It also increases all of the player's multipliers by:
" +
+ "Level 1: 16% " +
+ "Level 2: 24% " +
+ "Level 3: 28%");
+SourceFiles["SourceFile2"] = new SourceFile(2, "This Source-File allows you to form gangs in other BitNodes " +
+ "once your karma decreases to a certain value. It also increases the player's " +
+ "crime success rate, crime money, and charisma multipliers by:
" +
+ "Level 1: 24% " +
+ "Level 2: 36% " +
+ "Level 3: 42%");
+SourceFiles["SourceFile3"] = new SourceFile(3,"This Source-File lets you create corporations on other BitNodes (although " +
+ "some BitNodes will disable this mechanic). This Source-File also increases your charisma and company salary multipliers by: " +
+ "Level 1: 8% " +
+ "Level 2: 12% " +
+ "Level 3: 14%");
+SourceFiles["SourceFile4"] = new SourceFile(4, "This Source-File lets you access and use the Singularity Functions in every BitNode. Every " +
+ "level of this Source-File opens up more of the Singularity Functions you can use.");
+SourceFiles["SourceFile5"] = new SourceFile(5, "This Source-File grants a special new stat called Intelligence. Intelligence " +
+ "is unique because it is permanent and persistent (it never gets reset back to 1). However, " +
+ "gaining Intelligence experience is much slower than other stats, and it is also hidden (you won't " +
+ "know when you gain experience and how much). Higher Intelligence levels will boost your production " +
+ "for many actions in the game. In addition, this Source-File will unlock the getBitNodeMultipliers() " +
+ "Netscript function, and will raise all of your hacking-related multipliers by:
" +
+ "Level 1: 8% " +
+ "Level 2: 12% " +
+ "Level 3: 14%");
+SourceFiles["SourceFile6"] = new SourceFile(6, "This Source-File allows you to access the NSA's Bladeburner Division in other " +
+ "BitNodes. In addition, this Source-File will raise both the level and experience gain rate of all your combat stats by:
" +
+ "Level 1: 8% " +
+ "Level 2: 12% " +
+ "Level 3: 14%");
+SourceFiles["SourceFile7"] = new SourceFile(7, "This Source-File allows you to access the Bladeburner Netscript API in other " +
+ "BitNodes. In addition, this Source-File will increase all of your Bladeburner multipliers by:
" +
+ "Level 1: 8% " +
+ "Level 2: 12% " +
+ "Level 3: 14%");
+SourceFiles["SourceFile8"] = new SourceFile(8, "This Source-File grants the following benefits:
" +
+ "Level 1: Permanent access to WSE and TIX API " +
+ "Level 2: Ability to short stocks in other BitNodes " +
+ "Level 3: Ability to use limit/stop orders in other BitNodes
" +
+ "This Source-File also increases your hacking growth multipliers by: " +
+ " Level 1: 12% Level 2: 18% Level 3: 21%");
+SourceFiles["SourceFile9"] = new SourceFile(9, "This Source-File grants the following benefits:
" +
+ "Level 1: Permanently unlocks the Hacknet Server in other BitNodes " +
+ "Level 2: You start with 128GB of RAM on your home computer when entering a new BitNode " +
+ "Level 3: Grants a highly-upgraded Hacknet Server when entering a new BitNode
" +
+ "(Note that the Level 3 effect of this Source-File only applies when entering a new BitNode, NOT " +
+ "when installing Augmentations)");
+SourceFiles["SourceFile10"] = new SourceFile(10, "This Source-File unlocks Sleeve technology in other BitNodes. Each level of this " +
+ "Source-File also grants you a Duplicate Sleeve");
+SourceFiles["SourceFile11"] = new SourceFile(11, "This Source-File makes it so that company favor increases BOTH the player's salary and reputation gain rate " +
+ "at that company by 1% per favor (rather than just the reputation gain). This Source-File also " +
+ " increases the player's company salary and reputation gain multipliers by:
" +
+ "Level 1: 32% " +
+ "Level 2: 48% " +
+ "Level 3: 56% ");
+SourceFiles["SourceFile12"] = new SourceFile(12, "This Source-File increases all your multipliers by 1% per level. This effect is multiplicative with itself. " +
+ "In other words, level N of this Source-File will result in a multiplier of 1.01^N (or 0.99^N for multipliers that decrease)");
diff --git a/src/SourceFile/applySourceFile.ts b/src/SourceFile/applySourceFile.ts
new file mode 100644
index 000000000..e38b014ec
--- /dev/null
+++ b/src/SourceFile/applySourceFile.ts
@@ -0,0 +1,176 @@
+import { PlayerOwnedSourceFile } from "./PlayerOwnedSourceFile";
+import { SourceFiles } from "./SourceFiles";
+
+import { Player } from "../Player";
+
+export function applySourceFile(srcFile: PlayerOwnedSourceFile) {
+ const srcFileKey = "SourceFile" + srcFile.n;
+ const sourceFileObject = SourceFiles[srcFileKey];
+ if (sourceFileObject == null) {
+ console.error(`Invalid source file number: ${srcFile.n}`);
+ return;
+ }
+
+ switch (srcFile.n) {
+ case 1: // The Source Genesis
+ var mult = 0;
+ for (var i = 0; i < srcFile.lvl; ++i) {
+ mult += (16 / (Math.pow(2, i)));
+ }
+ var incMult = 1 + (mult / 100);
+ var decMult = 1 - (mult / 100);
+ Player.hacking_chance_mult *= incMult;
+ Player.hacking_speed_mult *= incMult;
+ Player.hacking_money_mult *= incMult;
+ Player.hacking_grow_mult *= incMult;
+ Player.hacking_mult *= incMult;
+ Player.strength_mult *= incMult;
+ Player.defense_mult *= incMult;
+ Player.dexterity_mult *= incMult;
+ Player.agility_mult *= incMult;
+ Player.charisma_mult *= incMult;
+ Player.hacking_exp_mult *= incMult;
+ Player.strength_exp_mult *= incMult;
+ Player.defense_exp_mult *= incMult;
+ Player.dexterity_exp_mult *= incMult;
+ Player.agility_exp_mult *= incMult;
+ Player.charisma_exp_mult *= incMult;
+ Player.company_rep_mult *= incMult;
+ Player.faction_rep_mult *= incMult;
+ Player.crime_money_mult *= incMult;
+ Player.crime_success_mult *= incMult;
+ Player.hacknet_node_money_mult *= incMult;
+ Player.hacknet_node_purchase_cost_mult *= decMult;
+ Player.hacknet_node_ram_cost_mult *= decMult;
+ Player.hacknet_node_core_cost_mult *= decMult;
+ Player.hacknet_node_level_cost_mult *= decMult;
+ Player.work_money_mult *= incMult;
+ break;
+ case 2: // Rise of the Underworld
+ var mult = 0;
+ for (var i = 0; i < srcFile.lvl; ++i) {
+ mult += (24 / (Math.pow(2, i)));
+ }
+ var incMult = 1 + (mult / 100);
+ Player.crime_money_mult *= incMult;
+ Player.crime_success_mult *= incMult;
+ Player.charisma_mult *= incMult;
+ break;
+ case 3: // Corporatocracy
+ var mult = 0;
+ for (var i = 0; i < srcFile.lvl; ++i) {
+ mult += (8 / (Math.pow(2, i)));
+ }
+ var incMult = 1 + (mult / 100);
+ Player.charisma_mult *= incMult;
+ Player.work_money_mult *= incMult;
+ break;
+ case 4: // The Singularity
+ // No effects, just gives access to Singularity functions
+ break;
+ case 5: // Artificial Intelligence
+ var mult = 0;
+ for (var i = 0; i < srcFile.lvl; ++i) {
+ mult += (8 / (Math.pow(2, i)));
+ }
+ var incMult = 1 + (mult / 100);
+ Player.hacking_chance_mult *= incMult;
+ Player.hacking_speed_mult *= incMult;
+ Player.hacking_money_mult *= incMult;
+ Player.hacking_grow_mult *= incMult;
+ Player.hacking_mult *= incMult;
+ Player.hacking_exp_mult *= incMult;
+ break;
+ case 6: // Bladeburner
+ var mult = 0;
+ for (var i = 0; i < srcFile.lvl; ++i) {
+ mult += (8 / (Math.pow(2, i)));
+ }
+ var incMult = 1 + (mult / 100);
+ Player.strength_exp_mult *= incMult;
+ Player.defense_exp_mult *= incMult;
+ Player.dexterity_exp_mult *= incMult;
+ Player.agility_exp_mult *= incMult;
+ Player.strength_mult *= incMult;
+ Player.defense_mult *= incMult;
+ Player.dexterity_mult *= incMult;
+ Player.agility_mult *= incMult;
+ break;
+ case 7: // Bladeburner 2079
+ var mult = 0;
+ for (var i = 0; i < srcFile.lvl; ++i) {
+ mult += (8 / (Math.pow(2, i)));
+ }
+ var incMult = 1 + (mult / 100);
+ Player.bladeburner_max_stamina_mult *= incMult;
+ Player.bladeburner_stamina_gain_mult *= incMult;
+ Player.bladeburner_analysis_mult *= incMult;
+ Player.bladeburner_success_chance_mult *= incMult;
+ break;
+ case 8: // Ghost of Wall Street
+ var mult = 0;
+ for (var i = 0; i < srcFile.lvl; ++i) {
+ mult += (12 / (Math.pow(2, i)));
+ }
+ var incMult = 1 + (mult / 100);
+ Player.hacking_grow_mult *= incMult;
+ break;
+ case 9: // Hacktocracy
+ // This has non-multiplier effects
+ break;
+ case 10: // Digital Carbon
+ // No effects, just grants sleeves
+ break;
+ case 11: // The Big Crash
+ var mult = 0;
+ for (var i = 0; i < srcFile.lvl; ++i) {
+ mult += (32 / (Math.pow(2, i)));
+ }
+ var incMult = 1 + (mult / 100);
+ Player.work_money_mult *= incMult;
+ Player.company_rep_mult *= incMult;
+ break;
+ case 12: // The Recursion
+ var inc = Math.pow(1.01, srcFile.lvl);
+ var dec = Math.pow(0.99, srcFile.lvl);
+
+ Player.hacking_chance_mult *= inc;
+ Player.hacking_speed_mult *= inc;
+ Player.hacking_money_mult *= inc;
+ Player.hacking_grow_mult *= inc;
+ Player.hacking_mult *= inc;
+
+ Player.strength_mult *= inc;
+ Player.defense_mult *= inc;
+ Player.dexterity_mult *= inc;
+ Player.agility_mult *= inc;
+ Player.charisma_mult *= inc;
+
+ Player.hacking_exp_mult *= inc;
+ Player.strength_exp_mult *= inc;
+ Player.defense_exp_mult *= inc;
+ Player.dexterity_exp_mult *= inc;
+ Player.agility_exp_mult *= inc;
+ Player.charisma_exp_mult *= inc;
+
+ Player.company_rep_mult *= inc;
+ Player.faction_rep_mult *= inc;
+
+ Player.crime_money_mult *= inc;
+ Player.crime_success_mult *= inc;
+
+ Player.hacknet_node_money_mult *= inc;
+ Player.hacknet_node_purchase_cost_mult *= dec;
+ Player.hacknet_node_ram_cost_mult *= dec;
+ Player.hacknet_node_core_cost_mult *= dec;
+ Player.hacknet_node_level_cost_mult *= dec;
+
+ Player.work_money_mult *= inc;
+ break;
+ default:
+ console.log("ERROR: Invalid source file number: " + srcFile.n);
+ break;
+ }
+
+ sourceFileObject.owned = true;
+}
diff --git a/src/engine.jsx b/src/engine.jsx
index e86bbcdfb..488c21eb6 100644
--- a/src/engine.jsx
+++ b/src/engine.jsx
@@ -13,7 +13,6 @@ import {
PlayerOwnedAugmentation
} from "./Augmentation/AugmentationHelpers";
import { AugmentationNames } from "./Augmentation/data/AugmentationNames";
-
import {
BitNodes,
initBitNodes,
@@ -54,14 +53,14 @@ import {
updateOnlineScriptTimes,
} from "./NetscriptWorker";
import { Player } from "./Player";
-import { prestigeAugmentation, prestigeSourceFile } from "./Prestige";
+import { prestigeAugmentation } from "./Prestige";
import { Programs } from "./Programs/Programs";
import {
displayCreateProgramContent,
getNumAvailableCreateProgram,
initCreateProgramButtons
} from "./Programs/ProgramHelpers";
-import { redPillFlag, hackWorldDaemon } from "./RedPill";
+import { redPillFlag } from "./RedPill";
import { saveObject, loadGame } from "./SaveObject";
import {
getCurrentEditor,
@@ -69,10 +68,7 @@ import {
updateScriptEditorContent
} from "./Script/ScriptHelpers";
import { AllServers, initForeignServers } from "./Server/AllServers";
-
-import { Server } from "./Server/Server";
import { Settings } from "./Settings/Settings";
-import { initSourceFiles, SourceFiles } from "./SourceFile";
import { updateSourceFileFlags } from "./SourceFile/SourceFileFlags";
import {
SpecialServerIps,
@@ -87,7 +83,6 @@ import {
displayStockMarketContent
} from "./StockMarket/StockMarket";
import { Terminal, postNetburnerText } from "./Terminal";
-
import { Sleeve } from "./PersonObjects/Sleeve/Sleeve";
import {
clearSleevesPage,
@@ -1045,7 +1040,6 @@ const Engine = {
if (loadGame(saveString)) {
initBitNodes();
initBitNodeMultipliers(Player);
- initSourceFiles();
Engine.setDisplayElements(); // Sets variables for important DOM elements
Engine.init(); // Initialize buttons, work, etc.
initAugmentations(); // Also calls Player.reapplyAllAugmentations()
@@ -1168,7 +1162,6 @@ const Engine = {
console.log("Initializing new game");
initBitNodes();
initBitNodeMultipliers(Player);
- initSourceFiles();
initSpecialServerIps();
Engine.setDisplayElements(); // Sets variables for important DOM elements
Engine.start(); // Run main game loop and Scripts loop
diff --git a/src/engineStyle.js b/src/engineStyle.js
index df9dd7250..c297b37cc 100644
--- a/src/engineStyle.js
+++ b/src/engineStyle.js
@@ -11,6 +11,7 @@ import "../css/scripteditor.scss";
import "../css/codemirror-overrides.scss";
import "../css/hacknetnodes.scss";
import "../css/menupages.scss";
+import "../css/augmentations.scss";
import "../css/redpill.scss";
import "../css/stockmarket.scss";
import "../css/workinprogress.scss";
diff --git a/src/ui/React/AugmentationAccordion.tsx b/src/ui/React/AugmentationAccordion.tsx
new file mode 100644
index 000000000..430a9800c
--- /dev/null
+++ b/src/ui/React/AugmentationAccordion.tsx
@@ -0,0 +1,33 @@
+/**
+ * React Component for displaying a single Augmentation as an accordion.
+ *
+ * The header of the accordion contains the Augmentation's name (and level, if
+ * applicable), and the accordion's panel contains the Augmentation's level.
+ */
+import * as React from "react";
+
+import { Accordion } from "./Accordion";
+
+import { Augmentation } from "../../Augmentation/Augmentation";
+import { AugmentationNames } from "../../Augmentation/data/AugmentationNames";
+
+type IProps = {
+ aug: Augmentation,
+ level?: number | string | null,
+}
+
+export function AugmentationAccordion(props: IProps): React.ReactElement {
+ let displayName = props.aug.name;
+ if (props.level != null) {
+ if (props.aug.name === AugmentationNames.NeuroFluxGovernor) {
+ displayName += (` - Level ${props.level}`)
+ }
+ }
+
+ return (
+ {displayName}
)
}
diff --git a/src/Augmentation/ui/Root.tsx b/src/Augmentation/ui/Root.tsx
index 565267f31..10e733556 100644
--- a/src/Augmentation/ui/Root.tsx
+++ b/src/Augmentation/ui/Root.tsx
@@ -4,9 +4,11 @@
*/
import * as React from "react";
-import { Augmentations } from "../../Augmentation/Augmentations";
-import { Player } from "../../Player";
+import { InstalledAugmentationsAndSourceFiles } from "./InstalledAugmentationsAndSourceFiles";
+import { PlayerMultipliers } from "./PlayerMultipliers";
+import { PurchasedAugmentations } from "./PurchasedAugmentations";
+import { Player } from "../../Player";
import { StdButton } from "../../ui/React/StdButton";
type IProps = {
@@ -25,7 +27,7 @@ export class AugmentationsRoot extends React.Component {
render() {
return (
-
+
Purchased Augmentations
Below is a list of all Augmentations you have purchased but not
@@ -34,14 +36,14 @@ export class AugmentationsRoot extends React.Component {
WARNING: Installing your Augmentations resets most of your progress,
including:
-
+
- Stats/Skill levels and Experience
- Money
- Scripts on every computer but your home computer
- Purchased servers
- Hacknet Nodes
- Faction/Company reputation
-
- Stocks
+
- Stocks
Installing Augmentations lets you start over with the perks and
benefits granted by all of the Augmentations you have ever
@@ -62,10 +64,19 @@ export class AugmentationsRoot extends React.Component {
text="Backup Save (Export)"
tooltip="It's always a good idea to backup/export your save!"
/>
+
-
+
Installed Augmentations
+
+ {
+ `List of all Augmentations ${Player.sourceFiles.length > 0 ? "and Source Files " : ""} ` +
+ `that have been installed. You have gained the effects of these.`
+ }
+
+
-
+
+
)
}
diff --git a/src/BitNode/BitNode.ts b/src/BitNode/BitNode.ts
index a4803866a..7f443c14a 100644
--- a/src/BitNode/BitNode.ts
+++ b/src/BitNode/BitNode.ts
@@ -25,235 +25,232 @@ class BitNode {
}
-export let BitNodes: IMap = {};
+export const BitNodes: IMap = {};
-export function initBitNodes() {
- BitNodes = {};
- BitNodes["BitNode1"] = new BitNode(1, "Source Genesis", "The original BitNode",
- "The first BitNode created by the Enders to imprison the minds of humans. It became " +
- "the prototype and testing-grounds for all of the BitNodes that followed.
" +
- "This is the first BitNode that you play through. It has no special " +
- "modifications or mechanics.
" +
- "Destroying this BitNode will give you Source-File 1, or if you already have " +
- "this Source-File it will upgrade its level up to a maximum of 3. This Source-File " +
- "lets the player start with 32GB of RAM on his/her home computer when entering a " +
- "new BitNode, and also increases all of the player's multipliers by:
" +
- "Level 1: 16% " +
- "Level 2: 24% " +
- "Level 3: 28%");
- BitNodes["BitNode2"] = new BitNode(2, "Rise of the Underworld", "From the shadows, they rose", //Gangs
- "From the shadows, they rose.
Organized crime groups quickly filled the void of power " +
- "left behind from the collapse of Western government in the 2050s. As society and civlization broke down, " +
- "people quickly succumbed to the innate human impulse of evil and savagery. The organized crime " +
- "factions quickly rose to the top of the modern world.
" +
- "In this BitNode:
" +
- "Your hacking level is reduced by 20% " +
- "The growth rate and maximum amount of money available on servers are significantly decreased " +
- "The amount of money gained from crimes and Infiltration is tripled " +
- "Certain Factions (Slum Snakes, Tetrads, The Syndicate, The Dark Army, Speakers for the Dead, " +
- "NiteSec, The Black Hand) give the player the ability to form and manage their own gangs. These gangs " +
- "will earn the player money and reputation with the corresponding Faction " +
- "Every Augmentation in the game will be available through the Factions listed above " +
- "For every Faction NOT listed above, reputation gains are halved " +
- "You will no longer gain passive reputation with Factions
" +
- "Destroying this BitNode will give you Source-File 2, or if you already have this Source-File it will " +
- "upgrade its level up to a maximum of 3. This Source-File allows you to form gangs in other BitNodes " +
- "once your karma decreases to a certain value. " +
- "It also increases the player's crime success rate, crime money, and charisma multipliers by:
" +
- "Level 1: 24% " +
- "Level 2: 36% " +
- "Level 3: 42%");
- BitNodes["BitNode3"] = new BitNode(3, "Corporatocracy", "The Price of Civilization",
- "Our greatest illusion is that a healthy society can revolve around a " +
- "single-minded pursuit of wealth.
" +
- "Sometime in the early 21st century economic and political globalization turned " +
- "the world into a corporatocracy, and it never looked back. Now, the privileged " +
- "elite will happily bankrupt their own countrymen, decimate their own community, " +
- "and evict their neighbors from houses in their desperate bid to increase their wealth.
" +
- "In this BitNode you can create and manage your own corporation. Running a successful corporation " +
- "has the potential of generating massive profits. All other forms of income are reduced by 75%. Furthermore:
" +
- "The price and reputation cost of all Augmentations is tripled " +
- "The starting and maximum amount of money on servers is reduced by 75% " +
- "Server growth rate is reduced by 80% " +
- "You now only need 75 favour with a faction in order to donate to it, rather than 150
" +
- "Destroying this BitNode will give you Source-File 3, or if you already have this Source-File it will " +
- "upgrade its level up to a maximum of 3. This Source-File lets you create corporations on other BitNodes (although " +
- "some BitNodes will disable this mechanic). This Source-File also increases your charisma and company salary multipliers by: " +
- "Level 1: 8% " +
- "Level 2: 12% " +
- "Level 3: 14%");
- BitNodes["BitNode4"] = new BitNode(4, "The Singularity", "The Man and the Machine",
- "The Singularity has arrived. The human race is gone, replaced " +
- "by artificially superintelligent beings that are more machine than man.
" +
- "In this BitNode, progressing is significantly harder. Experience gain rates " +
- "for all stats are reduced. Most methods of earning money will now give significantly less.
" +
- "In this BitNode you will gain access to a new set of Netscript Functions known as Singularity Functions. " +
- "These functions allow you to control most aspects of the game through scripts, including working for factions/companies, " +
- "purchasing/installing Augmentations, and creating programs.
" +
- "Destroying this BitNode will give you Source-File 4, or if you already have this Source-File it will " +
- "upgrade its level up to a maximum of 3. This Source-File lets you access and use the Singularity " +
- "Functions in other BitNodes. Each level of this Source-File will open up more Singularity Functions " +
- "that you can use.");
- BitNodes["BitNode5"] = new BitNode(5, "Artificial Intelligence", "Posthuman",
- "They said it couldn't be done. They said the human brain, " +
- "along with its consciousness and intelligence, couldn't be replicated. They said the complexity " +
- "of the brain results from unpredictable, nonlinear interactions that couldn't be modeled " +
- "by 1's and 0's. They were wrong.
" +
- "In this BitNode:
" +
- "The base security level of servers is doubled " +
- "The starting money on servers is halved, but the maximum money remains the same " +
- "Most methods of earning money now give significantly less " +
- "Infiltration gives 50% more reputation and money " +
- "Corporations have 50% lower valuations and are therefore less profitable " +
- "Augmentations are more expensive " +
- "Hacking experience gain rates are reduced
" +
- "Destroying this BitNode will give you Source-File 5, or if you already have this Source-File it will " +
- "upgrade its level up to a maximum of 3. This Source-File grants you a special new stat called Intelligence. " +
- "Intelligence is unique because it is permanent and persistent (it never gets reset back to 1). However " +
- "gaining Intelligence experience is much slower than other stats, and it is also hidden (you won't know " +
- "when you gain experience and how much). Higher Intelligence levels will boost your production for many actions " +
- "in the game.
" +
- "In addition, this Source-File will unlock the getBitNodeMultipliers() Netscript function, " +
- "and will also raise all of your hacking-related multipliers by:
" +
- "Level 1: 8% " +
- "Level 2: 12% " +
- "Level 3: 14%");
- BitNodes["BitNode6"] = new BitNode(6, "Bladeburners", "Like Tears in Rain",
- "In the middle of the 21st century, OmniTek Incorporated began designing and manufacturing advanced synthetic " +
- "androids, or Synthoids for short. They achieved a major technological breakthrough in the sixth generation " +
- "of their Synthoid design, called MK-VI, by developing a hyperintelligent AI. Many argue that this was " +
- "the first sentient AI ever created. This resulted in Synthoid models that were stronger, faster, and more intelligent " +
- "than the humans that had created them.
" +
- "In this BitNode you will be able to access the Bladeburner Division at the NSA, which provides a new mechanic " +
- "for progression. Furthermore:
" +
- "Hacking and Hacknet Nodes will be less profitable " +
- "Your hacking level is reduced by 65% " +
- "Hacking experience gain from scripts is reduced by 75% " +
- "Corporations have 80% lower valuations and are therefore less profitable " +
- "Working for companies is 50% less profitable " +
- "Crimes and Infiltration are 25% less profitable
" +
- "Destroying this BitNode will give you Source-File 6, or if you already have this Source-File it will upgrade " +
- "its level up to a maximum of 3. This Source-File allows you to access the NSA's Bladeburner Division in other " +
- "BitNodes. In addition, this Source-File will raise both the level and experience gain rate of all your combat stats by:
" +
- "Level 1: 8% " +
- "Level 2: 12% " +
- "Level 3: 14%");
- BitNodes["BitNode7"] = new BitNode(7, "Bladeburners 2079", "More human than humans",
- "In the middle of the 21st century, you were doing cutting-edge work at OmniTek Incorporated as part of the AI design team " +
- "for advanced synthetic androids, or Synthoids for short. You helped achieve a major technological " +
- "breakthrough in the sixth generation of the company's Synthoid design, called MK-VI, by developing a hyperintelligent AI. " +
- "Many argue that this was the first sentient AI ever created. This resulted in Synthoid models that were stronger, faster, " +
- "and more intelligent than the humans that had created them.
" +
- "In this BitNode you will be able to access the Bladeburner API, which allows you to access Bladeburner " +
- "functionality through Netscript. Furthermore:
" +
- "The rank you gain from Bladeburner contracts/operations is reduced by 40% " +
- "Bladeburner skills cost twice as many skill points " +
- "Augmentations are 3x more expensive " +
- "Hacking and Hacknet Nodes will be significantly less profitable " +
- "Your hacking level is reduced by 65% " +
- "Hacking experience gain from scripts is reduced by 75% " +
- "Corporations have 80% lower valuations and are therefore less profitable " +
- "Working for companies is 50% less profitable " +
- "Crimes and Infiltration are 25% less profitable
" +
- "Destroying this BitNode will give you Source-File 7, or if you already have this Source-File it will upgrade " +
- "its level up to a maximum of 3. This Source-File allows you to access the Bladeburner Netscript API in other " +
- "BitNodes. In addition, this Source-File will increase all of your Bladeburner multipliers by:
" +
- "Level 1: 8% " +
- "Level 2: 12% " +
- "Level 3: 14%");
- BitNodes["BitNode8"] = new BitNode(8, "Ghost of Wall Street", "Money never sleeps",
- "You are trying to make a name for yourself as an up-and-coming hedge fund manager on Wall Street.
" +
- "In this BitNode:
" +
- "You start with $250 million " +
- "The only way to earn money is by trading on the stock market " +
- "You start with a WSE membership and access to the TIX API " +
- "You are able to short stocks and place different types of orders (limit/stop) " +
- "You can immediately donate to factions to gain reputation
" +
- "Destroying this BitNode will give you Source-File 8, or if you already have this Source-File it will " +
- "upgrade its level up to a maximum of 3. This Source-File grants the following benefits:
" +
- "Level 1: Permanent access to WSE and TIX API " +
- "Level 2: Ability to short stocks in other BitNodes " +
- "Level 3: Ability to use limit/stop orders in other BitNodes
" +
- "This Source-File also increases your hacking growth multipliers by: " +
- " Level 1: 12% Level 2: 18% Level 3: 21%");
- BitNodes["BitNode9"] = new BitNode(9, "Hacktocracy", "Hacknet Unleashed",
- "When Fulcrum Technologies released their open-source Linux distro Chapeau, it quickly " +
- "became the OS of choice for the underground hacking community. Chapeau became especially notorious for " +
- "powering the Hacknet, a global, decentralized network used for nefarious purposes. Fulcrum quickly " +
- "abandoned the project and dissociated themselves from it.
" +
- "This BitNode unlocks the Hacknet Server, an upgraded version of the Hacknet Node. Hacknet Servers generate " +
- "hashes, which can be spent on a variety of different upgrades.
" +
- "In this BitNode:
" +
- "Your stats are significantly decreased " +
- "You cannnot purchase additional servers " +
- "Hacking is significantly less profitable
" +
- "Destroying this BitNode will give you Source-File 9, or if you already have this Source-File it will " +
- "upgrade its level up to a maximum of 3. This Source-File grants the following benefits:
" +
- "Level 1: Permanently unlocks the Hacknet Server in other BitNodes " +
- "Level 2: You start with 128GB of RAM on your home computer when entering a new BitNode " +
- "Level 3: Grants a highly-upgraded Hacknet Server when entering a new BitNode
" +
- "(Note that the Level 3 effect of this Source-File only applies when entering a new BitNode, NOT " +
- "when installing Augmentations)");
- BitNodes["BitNode10"] = new BitNode(10, "Digital Carbon", "Your body is not who you are",
- "In 2084, VitaLife unveiled to the world the Persona Core, a technology that allowed people " +
- "to digitize their consciousness. Their consciousness could then be transferred into Synthoids " +
- "or other bodies by trasmitting the digitized data. Human bodies became nothing more than 'sleeves' for the " +
- "human consciousness. Mankind had finally achieved immortality - at least for those that could afford it.
" +
- "This BitNode unlocks Sleeve technology. Sleeve technology allows you to:
" +
- "1. Re-sleeve: Purchase and transfer your consciousness into a new body " +
- "2. Duplicate Sleeves: Duplicate your consciousness into Synthoids, allowing you to perform different tasks synchronously
" +
- "In this BitNode:
" +
- "Your stats are significantly decreased " +
- "All methods of gaining money are half as profitable (except Stock Market) " +
- "Purchased servers are more expensive, have less max RAM, and a lower maximum limit " +
- "Augmentations are 5x as expensive and require twice as much reputation
" +
- "Destroying this BitNode will give you Source-File 10, or if you already have this Source-File it will " +
- "upgrade its level up to a maximum of 3. This Source-File unlocks Sleeve technology in other BitNodes. " +
- "Each level of this Source-File also grants you a Duplicate Sleeve");
- BitNodes["BitNode11"] = new BitNode(11, "The Big Crash", "Okay. Sell it all.",
- "The 2050s was defined by the massive amounts of violent civil unrest and anarchic rebellion that rose all around the world. It was this period " +
- "of disorder that eventually lead to the governmental reformation of many global superpowers, most notably " +
- "the USA and China. But just as the world was slowly beginning to recover from these dark times, financial catastrophe hit.
" +
- "In many countries, the high cost of trying to deal with the civil disorder bankrupted the governments. In all of this chaos and confusion, hackers " +
- "were able to steal billions of dollars from the world's largest electronic banks, prompting an international banking crisis as " +
- "governments were unable to bail out insolvent banks. Now, the world is slowly crumbling in the middle of the biggest economic crisis of all time.
" +
- "In this BitNode:
" +
- "Your hacking stat and experience gain are halved " +
- "The starting and maximum amount of money available on servers is significantly decreased " +
- "The growth rate of servers is significantly reduced " +
- "Weakening a server is twice as effective " +
- "Company wages are decreased by 50% " +
- "Corporation valuations are 99% lower and are therefore significantly less profitable " +
- "Hacknet Node production is significantly decreased " +
- "Crime and Infiltration are more lucrative " +
- "Augmentations are twice as expensive
" +
- "Destroying this BitNode will give you Source-File 11, or if you already have this Source-File it will " +
- "upgrade its level up to a maximum of 3. This Source-File makes it so that company favor increases BOTH " +
- "the player's salary and reputation gain rate at that company by 1% per favor (rather than just the reputation gain). " +
- "This Source-File also increases the player's company salary and reputation gain multipliers by:
" +
- "Level 1: 32% " +
- "Level 2: 48% " +
- "Level 3: 56%");
- BitNodes["BitNode12"] = new BitNode(12, "The Recursion", "Repeat.",
- "To iterate is human, to recurse divine.
" +
- "Every time this BitNode is destroyed, it becomes slightly harder. Destroying this BitNode will give your Souce-File 12, or " +
- "if you already have this Source-File it will upgrade its level. There is no maximum level for Source-File 12. Each level " +
- "of Source-File 12 will increase all of your multipliers by 1%. This effect is multiplicative with itself. " +
- "In other words, level N of this Source-File will result in a multiplier of 1.01^N (or 0.99^N for multipliers that decrease)");
- //Books: Frontera, Shiner
- BitNodes["BitNode13"] = new BitNode(13, "fOS", "COMING SOON"); //Unlocks the new game mode and the rest of the BitNodes
- BitNodes["BitNode14"] = new BitNode(14, "", "COMING SOON");
- BitNodes["BitNode15"] = new BitNode(15, "", "COMING SOON");
- BitNodes["BitNode16"] = new BitNode(16, "", "COMING SOON");
- BitNodes["BitNode17"] = new BitNode(17, "", "COMING SOON");
- BitNodes["BitNode18"] = new BitNode(18, "", "COMING SOON");
- BitNodes["BitNode19"] = new BitNode(19, "", "COMING SOON");
- BitNodes["BitNode20"] = new BitNode(20, "", "COMING SOON");
- BitNodes["BitNode21"] = new BitNode(21, "", "COMING SOON");
- BitNodes["BitNode22"] = new BitNode(22, "", "COMING SOON");
- BitNodes["BitNode23"] = new BitNode(23, "", "COMING SOON");
- BitNodes["BitNode24"] = new BitNode(24, "", "COMING SOON");
-}
+BitNodes["BitNode1"] = new BitNode(1, "Source Genesis", "The original BitNode",
+ "The first BitNode created by the Enders to imprison the minds of humans. It became " +
+ "the prototype and testing-grounds for all of the BitNodes that followed.
" +
+ "This is the first BitNode that you play through. It has no special " +
+ "modifications or mechanics.
" +
+ "Destroying this BitNode will give you Source-File 1, or if you already have " +
+ "this Source-File it will upgrade its level up to a maximum of 3. This Source-File " +
+ "lets the player start with 32GB of RAM on his/her home computer when entering a " +
+ "new BitNode, and also increases all of the player's multipliers by:
" +
+ "Level 1: 16% " +
+ "Level 2: 24% " +
+ "Level 3: 28%");
+BitNodes["BitNode2"] = new BitNode(2, "Rise of the Underworld", "From the shadows, they rose", //Gangs
+ "From the shadows, they rose.
Organized crime groups quickly filled the void of power " +
+ "left behind from the collapse of Western government in the 2050s. As society and civlization broke down, " +
+ "people quickly succumbed to the innate human impulse of evil and savagery. The organized crime " +
+ "factions quickly rose to the top of the modern world.
" +
+ "In this BitNode:
" +
+ "Your hacking level is reduced by 20% " +
+ "The growth rate and maximum amount of money available on servers are significantly decreased " +
+ "The amount of money gained from crimes and Infiltration is tripled " +
+ "Certain Factions (Slum Snakes, Tetrads, The Syndicate, The Dark Army, Speakers for the Dead, " +
+ "NiteSec, The Black Hand) give the player the ability to form and manage their own gangs. These gangs " +
+ "will earn the player money and reputation with the corresponding Faction " +
+ "Every Augmentation in the game will be available through the Factions listed above " +
+ "For every Faction NOT listed above, reputation gains are halved " +
+ "You will no longer gain passive reputation with Factions
" +
+ "Destroying this BitNode will give you Source-File 2, or if you already have this Source-File it will " +
+ "upgrade its level up to a maximum of 3. This Source-File allows you to form gangs in other BitNodes " +
+ "once your karma decreases to a certain value. " +
+ "It also increases the player's crime success rate, crime money, and charisma multipliers by:
" +
+ "Level 1: 24% " +
+ "Level 2: 36% " +
+ "Level 3: 42%");
+BitNodes["BitNode3"] = new BitNode(3, "Corporatocracy", "The Price of Civilization",
+ "Our greatest illusion is that a healthy society can revolve around a " +
+ "single-minded pursuit of wealth.
" +
+ "Sometime in the early 21st century economic and political globalization turned " +
+ "the world into a corporatocracy, and it never looked back. Now, the privileged " +
+ "elite will happily bankrupt their own countrymen, decimate their own community, " +
+ "and evict their neighbors from houses in their desperate bid to increase their wealth.
" +
+ "In this BitNode you can create and manage your own corporation. Running a successful corporation " +
+ "has the potential of generating massive profits. All other forms of income are reduced by 75%. Furthermore:
" +
+ "The price and reputation cost of all Augmentations is tripled " +
+ "The starting and maximum amount of money on servers is reduced by 75% " +
+ "Server growth rate is reduced by 80% " +
+ "You now only need 75 favour with a faction in order to donate to it, rather than 150
" +
+ "Destroying this BitNode will give you Source-File 3, or if you already have this Source-File it will " +
+ "upgrade its level up to a maximum of 3. This Source-File lets you create corporations on other BitNodes (although " +
+ "some BitNodes will disable this mechanic). This Source-File also increases your charisma and company salary multipliers by: " +
+ "Level 1: 8% " +
+ "Level 2: 12% " +
+ "Level 3: 14%");
+BitNodes["BitNode4"] = new BitNode(4, "The Singularity", "The Man and the Machine",
+ "The Singularity has arrived. The human race is gone, replaced " +
+ "by artificially superintelligent beings that are more machine than man.
" +
+ "In this BitNode, progressing is significantly harder. Experience gain rates " +
+ "for all stats are reduced. Most methods of earning money will now give significantly less.
" +
+ "In this BitNode you will gain access to a new set of Netscript Functions known as Singularity Functions. " +
+ "These functions allow you to control most aspects of the game through scripts, including working for factions/companies, " +
+ "purchasing/installing Augmentations, and creating programs.
" +
+ "Destroying this BitNode will give you Source-File 4, or if you already have this Source-File it will " +
+ "upgrade its level up to a maximum of 3. This Source-File lets you access and use the Singularity " +
+ "Functions in other BitNodes. Each level of this Source-File will open up more Singularity Functions " +
+ "that you can use.");
+BitNodes["BitNode5"] = new BitNode(5, "Artificial Intelligence", "Posthuman",
+ "They said it couldn't be done. They said the human brain, " +
+ "along with its consciousness and intelligence, couldn't be replicated. They said the complexity " +
+ "of the brain results from unpredictable, nonlinear interactions that couldn't be modeled " +
+ "by 1's and 0's. They were wrong.
" +
+ "In this BitNode:
" +
+ "The base security level of servers is doubled " +
+ "The starting money on servers is halved, but the maximum money remains the same " +
+ "Most methods of earning money now give significantly less " +
+ "Infiltration gives 50% more reputation and money " +
+ "Corporations have 50% lower valuations and are therefore less profitable " +
+ "Augmentations are more expensive " +
+ "Hacking experience gain rates are reduced
" +
+ "Destroying this BitNode will give you Source-File 5, or if you already have this Source-File it will " +
+ "upgrade its level up to a maximum of 3. This Source-File grants you a special new stat called Intelligence. " +
+ "Intelligence is unique because it is permanent and persistent (it never gets reset back to 1). However " +
+ "gaining Intelligence experience is much slower than other stats, and it is also hidden (you won't know " +
+ "when you gain experience and how much). Higher Intelligence levels will boost your production for many actions " +
+ "in the game.
" +
+ "In addition, this Source-File will unlock the getBitNodeMultipliers() Netscript function, " +
+ "and will also raise all of your hacking-related multipliers by:
" +
+ "Level 1: 8% " +
+ "Level 2: 12% " +
+ "Level 3: 14%");
+BitNodes["BitNode6"] = new BitNode(6, "Bladeburners", "Like Tears in Rain",
+ "In the middle of the 21st century, OmniTek Incorporated began designing and manufacturing advanced synthetic " +
+ "androids, or Synthoids for short. They achieved a major technological breakthrough in the sixth generation " +
+ "of their Synthoid design, called MK-VI, by developing a hyperintelligent AI. Many argue that this was " +
+ "the first sentient AI ever created. This resulted in Synthoid models that were stronger, faster, and more intelligent " +
+ "than the humans that had created them.
" +
+ "In this BitNode you will be able to access the Bladeburner Division at the NSA, which provides a new mechanic " +
+ "for progression. Furthermore:
" +
+ "Hacking and Hacknet Nodes will be less profitable " +
+ "Your hacking level is reduced by 65% " +
+ "Hacking experience gain from scripts is reduced by 75% " +
+ "Corporations have 80% lower valuations and are therefore less profitable " +
+ "Working for companies is 50% less profitable " +
+ "Crimes and Infiltration are 25% less profitable
" +
+ "Destroying this BitNode will give you Source-File 6, or if you already have this Source-File it will upgrade " +
+ "its level up to a maximum of 3. This Source-File allows you to access the NSA's Bladeburner Division in other " +
+ "BitNodes. In addition, this Source-File will raise both the level and experience gain rate of all your combat stats by:
" +
+ "Level 1: 8% " +
+ "Level 2: 12% " +
+ "Level 3: 14%");
+BitNodes["BitNode7"] = new BitNode(7, "Bladeburners 2079", "More human than humans",
+ "In the middle of the 21st century, you were doing cutting-edge work at OmniTek Incorporated as part of the AI design team " +
+ "for advanced synthetic androids, or Synthoids for short. You helped achieve a major technological " +
+ "breakthrough in the sixth generation of the company's Synthoid design, called MK-VI, by developing a hyperintelligent AI. " +
+ "Many argue that this was the first sentient AI ever created. This resulted in Synthoid models that were stronger, faster, " +
+ "and more intelligent than the humans that had created them.
" +
+ "In this BitNode you will be able to access the Bladeburner API, which allows you to access Bladeburner " +
+ "functionality through Netscript. Furthermore:
" +
+ "The rank you gain from Bladeburner contracts/operations is reduced by 40% " +
+ "Bladeburner skills cost twice as many skill points " +
+ "Augmentations are 3x more expensive " +
+ "Hacking and Hacknet Nodes will be significantly less profitable " +
+ "Your hacking level is reduced by 65% " +
+ "Hacking experience gain from scripts is reduced by 75% " +
+ "Corporations have 80% lower valuations and are therefore less profitable " +
+ "Working for companies is 50% less profitable " +
+ "Crimes and Infiltration are 25% less profitable
" +
+ "Destroying this BitNode will give you Source-File 7, or if you already have this Source-File it will upgrade " +
+ "its level up to a maximum of 3. This Source-File allows you to access the Bladeburner Netscript API in other " +
+ "BitNodes. In addition, this Source-File will increase all of your Bladeburner multipliers by:
" +
+ "Level 1: 8% " +
+ "Level 2: 12% " +
+ "Level 3: 14%");
+BitNodes["BitNode8"] = new BitNode(8, "Ghost of Wall Street", "Money never sleeps",
+ "You are trying to make a name for yourself as an up-and-coming hedge fund manager on Wall Street.
" +
+ "In this BitNode:
" +
+ "You start with $250 million " +
+ "The only way to earn money is by trading on the stock market " +
+ "You start with a WSE membership and access to the TIX API " +
+ "You are able to short stocks and place different types of orders (limit/stop) " +
+ "You can immediately donate to factions to gain reputation
" +
+ "Destroying this BitNode will give you Source-File 8, or if you already have this Source-File it will " +
+ "upgrade its level up to a maximum of 3. This Source-File grants the following benefits:
" +
+ "Level 1: Permanent access to WSE and TIX API " +
+ "Level 2: Ability to short stocks in other BitNodes " +
+ "Level 3: Ability to use limit/stop orders in other BitNodes
" +
+ "This Source-File also increases your hacking growth multipliers by: " +
+ " Level 1: 12% Level 2: 18% Level 3: 21%");
+BitNodes["BitNode9"] = new BitNode(9, "Hacktocracy", "Hacknet Unleashed",
+ "When Fulcrum Technologies released their open-source Linux distro Chapeau, it quickly " +
+ "became the OS of choice for the underground hacking community. Chapeau became especially notorious for " +
+ "powering the Hacknet, a global, decentralized network used for nefarious purposes. Fulcrum quickly " +
+ "abandoned the project and dissociated themselves from it.
" +
+ "This BitNode unlocks the Hacknet Server, an upgraded version of the Hacknet Node. Hacknet Servers generate " +
+ "hashes, which can be spent on a variety of different upgrades.
" +
+ "In this BitNode:
" +
+ "Your stats are significantly decreased " +
+ "You cannnot purchase additional servers " +
+ "Hacking is significantly less profitable
" +
+ "Destroying this BitNode will give you Source-File 9, or if you already have this Source-File it will " +
+ "upgrade its level up to a maximum of 3. This Source-File grants the following benefits:
" +
+ "Level 1: Permanently unlocks the Hacknet Server in other BitNodes " +
+ "Level 2: You start with 128GB of RAM on your home computer when entering a new BitNode " +
+ "Level 3: Grants a highly-upgraded Hacknet Server when entering a new BitNode
" +
+ "(Note that the Level 3 effect of this Source-File only applies when entering a new BitNode, NOT " +
+ "when installing Augmentations)");
+BitNodes["BitNode10"] = new BitNode(10, "Digital Carbon", "Your body is not who you are",
+ "In 2084, VitaLife unveiled to the world the Persona Core, a technology that allowed people " +
+ "to digitize their consciousness. Their consciousness could then be transferred into Synthoids " +
+ "or other bodies by trasmitting the digitized data. Human bodies became nothing more than 'sleeves' for the " +
+ "human consciousness. Mankind had finally achieved immortality - at least for those that could afford it.
" +
+ "This BitNode unlocks Sleeve technology. Sleeve technology allows you to:
" +
+ "1. Re-sleeve: Purchase and transfer your consciousness into a new body " +
+ "2. Duplicate Sleeves: Duplicate your consciousness into Synthoids, allowing you to perform different tasks synchronously
" +
+ "In this BitNode:
" +
+ "Your stats are significantly decreased " +
+ "All methods of gaining money are half as profitable (except Stock Market) " +
+ "Purchased servers are more expensive, have less max RAM, and a lower maximum limit " +
+ "Augmentations are 5x as expensive and require twice as much reputation
" +
+ "Destroying this BitNode will give you Source-File 10, or if you already have this Source-File it will " +
+ "upgrade its level up to a maximum of 3. This Source-File unlocks Sleeve technology in other BitNodes. " +
+ "Each level of this Source-File also grants you a Duplicate Sleeve");
+BitNodes["BitNode11"] = new BitNode(11, "The Big Crash", "Okay. Sell it all.",
+ "The 2050s was defined by the massive amounts of violent civil unrest and anarchic rebellion that rose all around the world. It was this period " +
+ "of disorder that eventually lead to the governmental reformation of many global superpowers, most notably " +
+ "the USA and China. But just as the world was slowly beginning to recover from these dark times, financial catastrophe hit.
" +
+ "In many countries, the high cost of trying to deal with the civil disorder bankrupted the governments. In all of this chaos and confusion, hackers " +
+ "were able to steal billions of dollars from the world's largest electronic banks, prompting an international banking crisis as " +
+ "governments were unable to bail out insolvent banks. Now, the world is slowly crumbling in the middle of the biggest economic crisis of all time.
" +
+ "In this BitNode:
" +
+ "Your hacking stat and experience gain are halved " +
+ "The starting and maximum amount of money available on servers is significantly decreased " +
+ "The growth rate of servers is significantly reduced " +
+ "Weakening a server is twice as effective " +
+ "Company wages are decreased by 50% " +
+ "Corporation valuations are 99% lower and are therefore significantly less profitable " +
+ "Hacknet Node production is significantly decreased " +
+ "Crime and Infiltration are more lucrative " +
+ "Augmentations are twice as expensive
" +
+ "Destroying this BitNode will give you Source-File 11, or if you already have this Source-File it will " +
+ "upgrade its level up to a maximum of 3. This Source-File makes it so that company favor increases BOTH " +
+ "the player's salary and reputation gain rate at that company by 1% per favor (rather than just the reputation gain). " +
+ "This Source-File also increases the player's company salary and reputation gain multipliers by:
" +
+ "Level 1: 32% " +
+ "Level 2: 48% " +
+ "Level 3: 56%");
+BitNodes["BitNode12"] = new BitNode(12, "The Recursion", "Repeat.",
+ "To iterate is human, to recurse divine.
" +
+ "Every time this BitNode is destroyed, it becomes slightly harder. Destroying this BitNode will give your Souce-File 12, or " +
+ "if you already have this Source-File it will upgrade its level. There is no maximum level for Source-File 12. Each level " +
+ "of Source-File 12 will increase all of your multipliers by 1%. This effect is multiplicative with itself. " +
+ "In other words, level N of this Source-File will result in a multiplier of 1.01^N (or 0.99^N for multipliers that decrease)");
+// Books: Frontera, Shiner
+BitNodes["BitNode13"] = new BitNode(13, "fOS", "COMING SOON"); //Unlocks the new game mode and the rest of the BitNodes
+BitNodes["BitNode14"] = new BitNode(14, "", "COMING SOON");
+BitNodes["BitNode15"] = new BitNode(15, "", "COMING SOON");
+BitNodes["BitNode16"] = new BitNode(16, "", "COMING SOON");
+BitNodes["BitNode17"] = new BitNode(17, "", "COMING SOON");
+BitNodes["BitNode18"] = new BitNode(18, "", "COMING SOON");
+BitNodes["BitNode19"] = new BitNode(19, "", "COMING SOON");
+BitNodes["BitNode20"] = new BitNode(20, "", "COMING SOON");
+BitNodes["BitNode21"] = new BitNode(21, "", "COMING SOON");
+BitNodes["BitNode22"] = new BitNode(22, "", "COMING SOON");
+BitNodes["BitNode23"] = new BitNode(23, "", "COMING SOON");
+BitNodes["BitNode24"] = new BitNode(24, "", "COMING SOON");
export function initBitNodeMultipliers(p: IPlayer) {
if (p.bitNodeN == null) {
diff --git a/src/engine.jsx b/src/engine.jsx
index 488c21eb6..57f397c8d 100644
--- a/src/engine.jsx
+++ b/src/engine.jsx
@@ -15,7 +15,6 @@ import {
import { AugmentationNames } from "./Augmentation/data/AugmentationNames";
import {
BitNodes,
- initBitNodes,
initBitNodeMultipliers
} from "./BitNode/BitNode";
import { Bladeburner } from "./Bladeburner";
@@ -310,8 +309,8 @@ const Engine = {
loadAugmentationsContent: function() {
Engine.hideAllContent();
Engine.Display.augmentationsContent.style.display = "block";
- displayAugmentationsContent(Engine.Display.augmentationsContent);
routing.navigateTo(Page.Augmentations);
+ displayAugmentationsContent(Engine.Display.augmentationsContent);
MainMenuLinks.Augmentations.classList.add("active");
},
@@ -488,13 +487,20 @@ const Engine = {
Engine.Display.activeScriptsContent.style.display = "none";
clearHacknetNodesUI();
Engine.Display.createProgramContent.style.display = "none";
+
Engine.Display.factionsContent.style.display = "none";
- ReactDOM.unmountComponentAtNode(Engine.Display.factionContent);
+
Engine.Display.factionContent.style.display = "none";
+ ReactDOM.unmountComponentAtNode(Engine.Display.factionContent);
+
Engine.Display.augmentationsContent.style.display = "none";
+ ReactDOM.unmountComponentAtNode(Engine.Display.augmentationsContent);
+
Engine.Display.tutorialContent.style.display = "none";
+
Engine.Display.locationContent.style.display = "none";
ReactDOM.unmountComponentAtNode(Engine.Display.locationContent);
+
Engine.Display.workInProgressContent.style.display = "none";
Engine.Display.redPillContent.style.display = "none";
Engine.Display.cinematicTextContent.style.display = "none";
@@ -1038,7 +1044,6 @@ const Engine = {
// Load game from save or create new game
if (loadGame(saveString)) {
- initBitNodes();
initBitNodeMultipliers(Player);
Engine.setDisplayElements(); // Sets variables for important DOM elements
Engine.init(); // Initialize buttons, work, etc.
@@ -1160,7 +1165,6 @@ const Engine = {
} else {
// No save found, start new game
console.log("Initializing new game");
- initBitNodes();
initBitNodeMultipliers(Player);
initSpecialServerIps();
Engine.setDisplayElements(); // Sets variables for important DOM elements
diff --git a/src/ui/React/Accordion.tsx b/src/ui/React/Accordion.tsx
index b7d382fe5..5833f29f7 100644
--- a/src/ui/React/Accordion.tsx
+++ b/src/ui/React/Accordion.tsx
@@ -45,12 +45,12 @@ export class Accordion extends React.Component {
render() {
return (
-
-
-
-
+ <>
+
+
+ >
)
}
}
diff --git a/src/ui/React/AugmentationAccordion.tsx b/src/ui/React/AugmentationAccordion.tsx
index 430a9800c..98b95f8f1 100644
--- a/src/ui/React/AugmentationAccordion.tsx
+++ b/src/ui/React/AugmentationAccordion.tsx
@@ -2,7 +2,7 @@
* React Component for displaying a single Augmentation as an accordion.
*
* The header of the accordion contains the Augmentation's name (and level, if
- * applicable), and the accordion's panel contains the Augmentation's level.
+ * applicable), and the accordion's panel contains the Augmentation's description.
*/
import * as React from "react";
@@ -26,8 +26,8 @@ export function AugmentationAccordion(props: IProps): React.ReactElement {
return (
{displayName}}
- panelContent={
{props.aug.info}
}
+ headerContent={<>{displayName}>}
+ panelContent={}
/>
)
}
diff --git a/src/ui/React/SourceFileAccordion.tsx b/src/ui/React/SourceFileAccordion.tsx
new file mode 100644
index 000000000..2f5172e36
--- /dev/null
+++ b/src/ui/React/SourceFileAccordion.tsx
@@ -0,0 +1,35 @@
+/**
+ * React Component for displaying a single Source-File as an accordion.
+ *
+ * The header of the accordion contains the Source-Files's name and level,
+ * and the accordion's panel contains the Source-File's description.
+ */
+import * as React from "react";
+
+import { Accordion } from "./Accordion";
+
+import { SourceFile } from "../../SourceFile/SourceFile";
+
+type IProps = {
+ level: number,
+ sf: SourceFile,
+}
+
+export function SourceFileAccordion(props: IProps): React.ReactElement {
+ const maxLevel = props.sf.n === 3 ? "∞" : "3";
+
+ return (
+
+ {props.sf.name}
+
+ {`Level ${props.level} / ${maxLevel}`}
+ >
+ }
+ panelContent={
+
+ }
+ />
+ )
+}
From b1248521f3ecb3c88d96e5e3b2e8d0025432a062 Mon Sep 17 00:00:00 2001
From: danielyxie
Date: Wed, 15 May 2019 00:37:11 -0700
Subject: [PATCH 3/9] Removed unused imports in engine
---
src/engine.jsx | 19 +++----------------
1 file changed, 3 insertions(+), 16 deletions(-)
diff --git a/src/engine.jsx b/src/engine.jsx
index 57f397c8d..1e8e8731b 100644
--- a/src/engine.jsx
+++ b/src/engine.jsx
@@ -1,27 +1,22 @@
import {
- formatNumber,
convertTimeMsToTimeElapsedString,
replaceAt
} from "../utils/StringHelperFunctions";
-import { loxBoxCreate, logBoxUpdateText, logBoxOpened } from "../utils/LogBox";
+import { logBoxUpdateText, logBoxOpened } from "../utils/LogBox";
import { updateActiveScriptsItems } from "./ActiveScriptsUI";
import { Augmentations } from "./Augmentation/Augmentations";
import {
- installAugmentations,
initAugmentations,
displayAugmentationsContent,
- PlayerOwnedAugmentation
} from "./Augmentation/AugmentationHelpers";
import { AugmentationNames } from "./Augmentation/data/AugmentationNames";
import {
- BitNodes,
initBitNodeMultipliers
} from "./BitNode/BitNode";
import { Bladeburner } from "./Bladeburner";
import { CharacterOverviewComponent } from "./ui/React/CharacterOverview";
import { cinematicTextFlag } from "./CinematicText";
import { generateRandomContract } from "./CodingContractGenerator";
-import { CompanyPositions } from "./Company/CompanyPositions";
import { initCompanies } from "./Company/Companies";
import { Corporation } from "./Corporation/Corporation";
import { CONSTANTS } from "./Constants";
@@ -53,7 +48,6 @@ import {
} from "./NetscriptWorker";
import { Player } from "./Player";
import { prestigeAugmentation } from "./Prestige";
-import { Programs } from "./Programs/Programs";
import {
displayCreateProgramContent,
getNumAvailableCreateProgram,
@@ -66,16 +60,11 @@ import {
scriptEditorInit,
updateScriptEditorContent
} from "./Script/ScriptHelpers";
-import { AllServers, initForeignServers } from "./Server/AllServers";
+import { initForeignServers } from "./Server/AllServers";
import { Settings } from "./Settings/Settings";
import { updateSourceFileFlags } from "./SourceFile/SourceFileFlags";
+import { initSpecialServerIps } from "./Server/SpecialServerIps";
import {
- SpecialServerIps,
- initSpecialServerIps
-} from "./Server/SpecialServerIps";
-import {
- StockMarket,
- SymbolToStockMap,
initSymbolToStockMap,
stockMarketCycle,
processStockPrices,
@@ -103,9 +92,7 @@ import { initializeMainMenuLinks, MainMenuLinks } from "./ui/MainMenu/Links";
import { dialogBoxCreate } from "../utils/DialogBox";
import { gameOptionsBoxClose, gameOptionsBoxOpen } from "../utils/GameOptions";
-import { getRandomInt } from "../utils/helpers/getRandomInt";
import { removeChildrenFromElement } from "../utils/uiHelpers/removeChildrenFromElement";
-import { clearEventListeners } from "../utils/uiHelpers/clearEventListeners";
import { createElement } from "../utils/uiHelpers/createElement";
import { exceptionAlert } from "../utils/helpers/exceptionAlert";
import { removeLoadingScreen } from "../utils/uiHelpers/removeLoadingScreen";
From 42804b0cd3a0110d7d76c465c44298381e595dfb Mon Sep 17 00:00:00 2001
From: danielyxie
Date: Wed, 15 May 2019 23:05:36 -0700
Subject: [PATCH 4/9] Refactored 'workerScripts' array and killWorkerScript()
fn to be their own modules in TypeScript
---
css/activescripts.scss | 119 +++++++++++++++++
css/menupages.scss | 120 -----------------
src/Netscript/WorkerScript.ts | 5 +
src/Netscript/WorkerScripts.ts | 6 +
src/Netscript/killWorkerScript.ts | 123 ++++++++++++++++++
src/NetscriptEvaluator.js | 12 --
src/NetscriptFunctions.js | 4 +-
src/NetscriptWorker.js | 68 +---------
src/Terminal.js | 3 +-
src/engine.jsx | 5 +
src/engineStyle.js | 1 +
src/ui/ActiveScripts/Root.tsx | 31 +++++
.../ActiveScripts/WorkerScriptAccordion.tsx | 40 ++++++
src/ui/React/Accordion.tsx | 23 +++-
src/utils/EventEmitter.ts | 50 +++++++
utils/LogBox.js | 6 +-
16 files changed, 413 insertions(+), 203 deletions(-)
create mode 100644 css/activescripts.scss
create mode 100644 src/Netscript/WorkerScripts.ts
create mode 100644 src/Netscript/killWorkerScript.ts
create mode 100644 src/ui/ActiveScripts/Root.tsx
create mode 100644 src/ui/ActiveScripts/WorkerScriptAccordion.tsx
create mode 100644 src/utils/EventEmitter.ts
diff --git a/css/activescripts.scss b/css/activescripts.scss
new file mode 100644
index 000000000..82b7ae7b9
--- /dev/null
+++ b/css/activescripts.scss
@@ -0,0 +1,119 @@
+@import "theme";
+
+.active-scripts-list {
+ list-style-type: none;
+}
+
+#active-scripts-container {
+ position: fixed;
+ padding-top: 10px;
+
+ > p {
+ width: 70%;
+ margin: 6px;
+ padding: 4px;
+ }
+}
+
+.active-scripts-server-header {
+ background-color: #444;
+ font-size: $defaultFontSize * 1.25;
+ color: #fff;
+ margin: 6px 6px 0 6px;
+ padding: 6px;
+ cursor: pointer;
+ width: 60%;
+ text-align: left;
+ border: none;
+ outline: none;
+}
+
+.active-scripts-server-header.active,
+.active-scripts-server-header:hover {
+ background-color: #555;
+}
+
+.active-scripts-server-header.active:hover {
+ background-color: #666;
+}
+
+.active-scripts-server-header:after {
+ content: '\02795'; /* "plus" sign (+) */
+ font-size: $defaultFontSize * 0.8125;
+ color: #fff;
+ float: right;
+ margin-left: 5px;
+}
+
+.active-scripts-server-header.active:after {
+ content: "\2796"; /* "minus" sign (-) */
+ font-size: $defaultFontSize * 0.8125;
+ color: #fff;
+ float: right;
+ margin-left: 5px;
+}
+
+.active-scripts-server-panel {
+ margin: 0 6px 6px 6px;
+ padding: 0 6px 6px 6px;
+ width: 55%;
+ margin-left: 5%;
+ display: none;
+}
+
+.active-scripts-server-panel div,
+.active-scripts-server-panel ul,
+.active-scripts-server-panel ul > li {
+ background-color: #555;
+}
+
+.active-scripts-script-header {
+ background-color: #555;
+ color: var(--my-font-color);
+ padding: 4px 25px 4px 10px;
+ cursor: pointer;
+ width: auto;
+ text-align: left;
+ border: none;
+ outline: none;
+ position: relative;
+
+ &:after {
+ content: '\02795'; /* "plus" sign (+) */
+ font-size: $defaultFontSize * 0.8125;
+ float: right;
+ margin-left: 5px;
+ color: transparent;
+ text-shadow: 0 0 0 var(--my-font-color);
+ position: absolute;
+ bottom: 4px;
+ }
+
+ &.active:after {
+ content: "\2796"; /* "minus" sign (-) */
+ }
+
+ &:hover,
+ &.active:hover {
+ background-color: #666;
+ }
+
+ &.active {
+ background-color: #555;
+ }
+}
+
+.active-scripts-script-panel {
+ padding: 0 18px;
+ background-color: #555;
+ width: auto;
+ display: none;
+ margin-bottom: 6px;
+
+ p, h2, ul, li {
+ background-color: #555;
+ width: auto;
+ color: #fff;
+ margin-left: 5%;
+ }
+}
diff --git a/css/menupages.scss b/css/menupages.scss
index b0b45c723..2c94436de 100644
--- a/css/menupages.scss
+++ b/css/menupages.scss
@@ -18,126 +18,6 @@
position: fixed;
}
-/* Active scripts */
-.active-scripts-list {
- list-style-type: none;
-}
-
-#active-scripts-container {
- position: fixed;
- padding-top: 10px;
-}
-
-#active-scripts-text,
-#active-scripts-total-prod {
- width: 70%;
- margin: 6px;
- padding: 4px;
-}
-
-.active-scripts-server-header {
- background-color: #444;
- font-size: $defaultFontSize * 1.25;
- color: #fff;
- margin: 6px 6px 0 6px;
- padding: 6px;
- cursor: pointer;
- width: 60%;
- text-align: left;
- border: none;
- outline: none;
-}
-
-.active-scripts-server-header.active,
-.active-scripts-server-header:hover {
- background-color: #555;
-}
-
-.active-scripts-server-header.active:hover {
- background-color: #666;
-}
-
-.active-scripts-server-header:after {
- content: '\02795'; /* "plus" sign (+) */
- font-size: $defaultFontSize * 0.8125;
- color: #fff;
- float: right;
- margin-left: 5px;
-}
-
-.active-scripts-server-header.active:after {
- content: "\2796"; /* "minus" sign (-) */
- font-size: $defaultFontSize * 0.8125;
- color: #fff;
- float: right;
- margin-left: 5px;
-}
-
-.active-scripts-server-panel {
- margin: 0 6px 6px 6px;
- padding: 0 6px 6px 6px;
- width: 55%;
- margin-left: 5%;
- display: none;
-}
-
-.active-scripts-server-panel div,
-.active-scripts-server-panel ul,
-.active-scripts-server-panel ul > li {
- background-color: #555;
-}
-
-.active-scripts-script-header {
- background-color: #555;
- color: var(--my-font-color);
- padding: 4px 25px 4px 10px;
- cursor: pointer;
- width: auto;
- text-align: left;
- border: none;
- outline: none;
- position: relative;
-
- &:after {
- content: '\02795'; /* "plus" sign (+) */
- font-size: $defaultFontSize * 0.8125;
- float: right;
- margin-left: 5px;
- color: transparent;
- text-shadow: 0 0 0 var(--my-font-color);
- position: absolute;
- bottom: 4px;
- }
-
- &.active:after {
- content: "\2796"; /* "minus" sign (-) */
- }
-
- &:hover,
- &.active:hover {
- background-color: #666;
- }
-
- &.active {
- background-color: #555;
- }
-}
-
-.active-scripts-script-panel {
- padding: 0 18px;
- background-color: #555;
- width: auto;
- display: none;
- margin-bottom: 6px;
-
- p, h2, ul, li {
- background-color: #555;
- width: auto;
- color: #fff;
- margin-left: 5%;
- }
-}
-
/* World */
#world-container {
position: fixed;
diff --git a/src/Netscript/WorkerScript.ts b/src/Netscript/WorkerScript.ts
index 2549c06e0..6b99c43d5 100644
--- a/src/Netscript/WorkerScript.ts
+++ b/src/Netscript/WorkerScript.ts
@@ -32,6 +32,11 @@ export class WorkerScript {
*/
delay: number | null = null;
+ /**
+ * Holds the Promise resolve() function for when the script is "blocked" by an async op
+ */
+ delayResolve?: () => void;
+
/**
* Stores names of all functions that have logging disabled
*/
diff --git a/src/Netscript/WorkerScripts.ts b/src/Netscript/WorkerScripts.ts
new file mode 100644
index 000000000..50515f413
--- /dev/null
+++ b/src/Netscript/WorkerScripts.ts
@@ -0,0 +1,6 @@
+/**
+ * Global pool of all active scripts (scripts that are currently running)
+ */
+import { WorkerScript } from "./WorkerScript";
+
+export const workerScripts: WorkerScript[] = [];
diff --git a/src/Netscript/killWorkerScript.ts b/src/Netscript/killWorkerScript.ts
new file mode 100644
index 000000000..ee60576f8
--- /dev/null
+++ b/src/Netscript/killWorkerScript.ts
@@ -0,0 +1,123 @@
+/**
+ * Function that stops an active script (represented by a WorkerScript object)
+ * and removes it from the global pool of active scripts.
+ */
+import { WorkerScript } from "./WorkerScript";
+import { workerScripts } from "./WorkerScripts";
+
+import { RunningScript } from "../Script/RunningScript";
+import { AllServers } from "../Server/AllServers";
+
+import { compareArrays } from "../../utils/helpers/compareArrays";
+import { roundToTwo } from "../../utils/helpers/roundToTwo";
+
+export function killWorkerScript(runningScriptObj: RunningScript, serverIp: string): boolean;
+export function killWorkerScript(workerScript: WorkerScript): boolean;
+export function killWorkerScript(script: RunningScript | WorkerScript, serverIp?: string): boolean {
+ if (script instanceof WorkerScript) {
+ script.env.stopFlag = true;
+ killNetscriptDelay(script);
+ removeWorkerScript(script);
+
+ return true;
+ } else if (script instanceof RunningScript && typeof serverIp === "string") {
+ for (let i = 0; i < workerScripts.length; i++) {
+ if (workerScripts[i].name == script.filename && workerScripts[i].serverIp == serverIp &&
+ compareArrays(workerScripts[i].args, script.args)) {
+ workerScripts[i].env.stopFlag = true;
+ killNetscriptDelay(workerScripts[i]);
+ removeWorkerScript(workerScripts[i]);
+
+ return true;
+ }
+ }
+
+ return false;
+ } else {
+ return false;
+ }
+}
+
+/**
+ * Helper function that removes the script being killed from the global pool.
+ * Also handles other cleanup-time operations
+ *
+ * @param {WorkerScript | number} - Identifier for WorkerScript. Either the object itself, or
+ * its index in the global workerScripts array
+ */
+function removeWorkerScript(id: WorkerScript | number): void {
+ // Get a reference to the WorkerScript and its index in the global pool
+ let workerScript: WorkerScript;
+ let index: number | null = null;
+
+ if (typeof id === "number") {
+ if (id < 0 || id >= workerScripts.length) {
+ console.error(`Too high of an index passed into removeWorkerScript(): ${id}`);
+ return;
+ }
+
+ workerScript = workerScripts[id];
+ index = id;
+ } else if (id instanceof WorkerScript) {
+ workerScript = id;
+ for (let i = 0; i < workerScripts.length; ++i) {
+ if (workerScripts[i] == id) {
+ index = i;
+ break;
+ }
+ }
+
+ if (index == null) {
+ console.error(`Could not find WorkerScript in global pool:`);
+ console.error(workerScript);
+ }
+ } else {
+ console.error(`Invalid argument passed into removeWorkerScript(): ${id}`);
+ return;
+ }
+
+ const ip = workerScript.serverIp;
+ const name = workerScript.name;
+
+ // Get the server on which the script runs
+ const server = AllServers[ip];
+ if (server == null) {
+ console.error(`Could not find server on which this script is running: ${ip}`);
+ return;
+ }
+
+ // Recalculate ram used on that server
+ server.ramUsed = roundToTwo(server.ramUsed - workerScript.ramUsage);
+ if (server.ramUsed < 0) {
+ console.warn(`Server RAM usage went negative (if it's due to floating pt imprecision, it's okay): ${server.ramUsed}`);
+ server.ramUsed = 0;
+ }
+
+ // Delete the RunningScript object from that server
+ for (let i = 0; i < server.runningScripts.length; ++i) {
+ const runningScript = server.runningScripts[i];
+ if (runningScript.filename === name && compareArrays(runningScript.args, workerScript.args)) {
+ server.runningScripts.splice(i, 1);
+ break;
+ }
+ }
+
+ // Delete script from global pool (workerScripts)
+ workerScripts.splice(index, 1);
+}
+
+/**
+ * Helper function that interrupts a script's delay if it is in the middle of a
+ * timed, blocked operation (like hack(), sleep(), etc.). This allows scripts to
+ * be killed immediately even if they're in the middle of one of those long operations
+ */
+function killNetscriptDelay(workerScript: WorkerScript) {
+ if (workerScript instanceof WorkerScript) {
+ if (workerScript.delay) {
+ clearTimeout(workerScript.delay);
+ if (workerScript.delayResolve) {
+ workerScript.delayResolve();
+ }
+ }
+ }
+}
diff --git a/src/NetscriptEvaluator.js b/src/NetscriptEvaluator.js
index cad189a8e..323919ad4 100644
--- a/src/NetscriptEvaluator.js
+++ b/src/NetscriptEvaluator.js
@@ -1,21 +1,9 @@
-import { WorkerScript } from "./Netscript/WorkerScript";
-import { getServer } from "./Server/ServerHelpers";
-
import { setTimeoutRef } from "./utils/SetTimeoutRef";
import { parse, Node } from "../utils/acorn";
import { isValidIPAddress } from "../utils/helpers/isValidIPAddress";
import { isString } from "../utils/helpers/isString";
-export function killNetscriptDelay(workerScript) {
- if (workerScript instanceof WorkerScript) {
- if (workerScript.delay) {
- clearTimeout(workerScript.delay);
- workerScript.delayResolve();
- }
- }
-}
-
export function netscriptDelay(time, workerScript) {
return new Promise(function(resolve, reject) {
workerScript.delay = setTimeoutRef(() => {
diff --git a/src/NetscriptFunctions.js b/src/NetscriptFunctions.js
index 308054333..e41ff542c 100644
--- a/src/NetscriptFunctions.js
+++ b/src/NetscriptFunctions.js
@@ -120,11 +120,11 @@ import {
} from "./NetscriptBladeburner";
import * as nsGang from "./NetscriptGang";
import {
- workerScripts,
- killWorkerScript,
NetscriptPorts,
runScriptFromScript,
} from "./NetscriptWorker";
+import { killWorkerScript } from "./Netscript/killWorkerScript";
+import { workerScripts } from "./Netscript/WorkerScripts";
import {
makeRuntimeRejectMsg,
netscriptDelay,
diff --git a/src/NetscriptWorker.js b/src/NetscriptWorker.js
index 9c519e8b1..e5548ee57 100644
--- a/src/NetscriptWorker.js
+++ b/src/NetscriptWorker.js
@@ -3,6 +3,7 @@
* that allows for scripts to run
*/
import { WorkerScript } from "./Netscript/WorkerScript";
+import { workerScripts } from "./Netscript/WorkerScripts";
import {
addActiveScriptsItem,
@@ -15,7 +16,6 @@ import { Interpreter } from "./JSInterpreter";
import {
isScriptErrorMessage,
makeRuntimeRejectMsg,
- killNetscriptDelay
} from "./NetscriptEvaluator";
import { NetscriptFunctions } from "./NetscriptFunctions";
import { executeJSScript } from "./NetscriptJSEvaluator";
@@ -29,6 +29,7 @@ import {
} from "./Script/ScriptHelpers";
import { AllServers } from "./Server/AllServers";
import { Settings } from "./Settings/Settings";
+import { EventEmitter } from "./utils/EventEmitter";
import { setTimeoutRef } from "./utils/SetTimeoutRef";
import { generate } from "escodegen";
@@ -42,14 +43,15 @@ import { isString } from "../utils/StringHelperFunctions";
const walk = require("acorn/dist/walk");
-//Array containing all scripts that are running across all servers, to easily run them all
-export const workerScripts = [];
-
+// Netscript Ports are instantiated here
export const NetscriptPorts = [];
for (var i = 0; i < CONSTANTS.NumNetscriptPorts; ++i) {
NetscriptPorts.push(new NetscriptPort());
}
+// WorkerScript-related event emitter. Used for the UI
+export const WorkerScriptEventEmitter = new EventEmitter();
+
export function prestigeWorkerScripts() {
for (var i = 0; i < workerScripts.length; ++i) {
deleteActiveScriptsItem(workerScripts[i]);
@@ -415,46 +417,6 @@ function processNetscript1Imports(code, workerScript) {
// Loop through workerScripts and run every script that is not currently running
export function runScriptsLoop() {
- let scriptDeleted = false;
-
- // Delete any scripts that finished or have been killed. Loop backwards bc removing items screws up indexing
- for (let i = workerScripts.length - 1; i >= 0; i--) {
- if (workerScripts[i].running == false && workerScripts[i].env.stopFlag == true) {
- scriptDeleted = true;
- // Delete script from the runningScripts array on its host serverIp
- const ip = workerScripts[i].serverIp;
- const name = workerScripts[i].name;
-
- // Recalculate ram used
- AllServers[ip].ramUsed = 0;
- for (let j = 0; j < workerScripts.length; j++) {
- if (workerScripts[j].serverIp !== ip) {
- continue;
- }
- if (j === i) { // not this one
- continue;
- }
- AllServers[ip].ramUsed += workerScripts[j].ramUsage;
- }
-
- // Delete script from Active Scripts
- deleteActiveScriptsItem(workerScripts[i]);
-
- for (let j = 0; j < AllServers[ip].runningScripts.length; j++) {
- if (AllServers[ip].runningScripts[j].filename == name &&
- compareArrays(AllServers[ip].runningScripts[j].args, workerScripts[i].args)) {
- AllServers[ip].runningScripts.splice(j, 1);
- break;
- }
- }
-
- // Delete script from workerScripts
- workerScripts.splice(i, 1);
- }
- }
- if (scriptDeleted) { updateActiveScriptsItems(); } // Force Update
-
-
// Run any scripts that haven't been started
for (let i = 0; i < workerScripts.length; i++) {
// If it isn't running, start the script
@@ -520,24 +482,6 @@ export function runScriptsLoop() {
setTimeoutRef(runScriptsLoop, 3e3);
}
-/**
- * Queues a script to be killed by setting its stop flag to true. This
- * kills and timed/blocking Netscript functions (like hack(), sleep(), etc.) and
- * prevents any further execution of Netscript functions.
- * The runScriptsLoop() handles the actual deletion of the WorkerScript
- */
-export function killWorkerScript(runningScriptObj, serverIp) {
- for (var i = 0; i < workerScripts.length; i++) {
- if (workerScripts[i].name == runningScriptObj.filename && workerScripts[i].serverIp == serverIp &&
- compareArrays(workerScripts[i].args, runningScriptObj.args)) {
- workerScripts[i].env.stopFlag = true;
- killNetscriptDelay(workerScripts[i]);
- return true;
- }
- }
- return false;
-}
-
/**
* Given a RunningScript object, queues that script to be run
*/
diff --git a/src/Terminal.js b/src/Terminal.js
index b88832954..12e150742 100644
--- a/src/Terminal.js
+++ b/src/Terminal.js
@@ -53,7 +53,8 @@ import {
import { showLiterature } from "./Literature";
import { Message } from "./Message/Message";
import { showMessage } from "./Message/MessageHelpers";
-import { killWorkerScript, addWorkerScript } from "./NetscriptWorker";
+import { addWorkerScript } from "./NetscriptWorker";
+import { killWorkerScript } from "./Netscript/killWorkerScript";
import { Player } from "./Player";
import { hackWorldDaemon } from "./RedPill";
import { RunningScript } from "./Script/RunningScript";
diff --git a/src/engine.jsx b/src/engine.jsx
index 1e8e8731b..28518e377 100644
--- a/src/engine.jsx
+++ b/src/engine.jsx
@@ -1,3 +1,8 @@
+/**
+ * Game engine. Handles the main game loop as well as the main UI pages
+ *
+ * TODO: Separate UI functionality into its own component
+ */
import {
convertTimeMsToTimeElapsedString,
replaceAt
diff --git a/src/engineStyle.js b/src/engineStyle.js
index c297b37cc..f9895a77a 100644
--- a/src/engineStyle.js
+++ b/src/engineStyle.js
@@ -9,6 +9,7 @@ import "../css/characteroverview.scss";
import "../css/terminal.scss";
import "../css/scripteditor.scss";
import "../css/codemirror-overrides.scss";
+import "../css/activescripts.scss";
import "../css/hacknetnodes.scss";
import "../css/menupages.scss";
import "../css/augmentations.scss";
diff --git a/src/ui/ActiveScripts/Root.tsx b/src/ui/ActiveScripts/Root.tsx
new file mode 100644
index 000000000..aecacb192
--- /dev/null
+++ b/src/ui/ActiveScripts/Root.tsx
@@ -0,0 +1,31 @@
+/**
+ * Root React Component for the "Active Scripts" UI page. This page displays
+ * and provides information about all of the player's scripts that are currently running
+ */
+import * as React from "react";
+
+import { WorkerScript } from "../../Netscript/WorkerScript";
+
+type IProps = {
+ workerScripts: WorkerScript[];
+}
+
+export class ActiveScriptsRoot extends React.Component {
+ constructor(props: IProps) {
+ super(props);
+ }
+
+ render() {
+ return (
+ <>
+
+ This page displays a list of all of your scripts that are currently
+ running across every machine. It also provides information about each
+ script's production. The scripts are categorized by the hostname of
+ the servers on which they are running.
+
+
+ >
+ )
+ }
+}
diff --git a/src/ui/ActiveScripts/WorkerScriptAccordion.tsx b/src/ui/ActiveScripts/WorkerScriptAccordion.tsx
new file mode 100644
index 000000000..117c2b045
--- /dev/null
+++ b/src/ui/ActiveScripts/WorkerScriptAccordion.tsx
@@ -0,0 +1,40 @@
+/**
+ * React Component for displaying a single WorkerScript's info as an
+ * Accordion element
+ */
+import * as React from "react";
+
+import { Accordion } from "../React/Accordion";
+
+import { WorkerScript } from "../../Netscript/WorkerScript";
+
+import { arrayToString } from "../../../utils/helpers/arrayToString";
+
+type IProps = {
+ workerScript: WorkerScript;
+}
+
+export function WorkerScriptAccordion(props: IProps): React.ReactElement {
+
+
+ return (
+
+ >
+ }
+ panelClass="active-scripts-script-panel"
+ panelContent={
+ <>
+