From 2d374093922c0f0a19fff26df41f9f4e036605ab Mon Sep 17 00:00:00 2001 From: danielyxie Date: Tue, 14 May 2019 20:56:59 -0700 Subject: [PATCH] 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 ( + + ) +} 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}

} + panelContent={

{props.aug.info}

} + /> + ) +} diff --git a/src/ui/React/Popup.tsx b/src/ui/React/Popup.tsx index 2d84ad684..c296809bb 100644 --- a/src/ui/React/Popup.tsx +++ b/src/ui/React/Popup.tsx @@ -13,12 +13,10 @@ interface IProps { props: object; } -export class Popup extends React.Component { - render() { - return ( -
- {React.createElement(this.props.content, this.props.props)} -
- ) - } +export function Popup(props: IProps): React.ReactElement { + return ( +
+ {React.createElement(props.content, props.props)} +
+ ) } diff --git a/src/ui/React/StdButton.tsx b/src/ui/React/StdButton.tsx index d8bd957f4..89227f83b 100644 --- a/src/ui/React/StdButton.tsx +++ b/src/ui/React/StdButton.tsx @@ -5,6 +5,7 @@ import * as React from "react"; interface IStdButtonProps { + addClasses?: string; disabled?: boolean; id?: string; onClick?: (e: React.MouseEvent) => any; @@ -17,30 +18,32 @@ type IInnerHTMLMarkup = { __html: string; } -export class StdButton extends React.Component { - render() { - const hasTooltip = this.props.tooltip != null && this.props.tooltip !== ""; - let className = this.props.disabled ? "std-button-disabled" : "std-button"; - if (hasTooltip) { - className += " tooltip"; - } - - // Tooltip will be set using inner HTML - let tooltipMarkup: IInnerHTMLMarkup | null; - if (hasTooltip) { - tooltipMarkup = { - __html: this.props.tooltip! - } - } - - return ( - - ) +export function StdButton(props: IStdButtonProps): React.ReactElement { + const hasTooltip = props.tooltip != null && props.tooltip !== ""; + let className = props.disabled ? "std-button-disabled" : "std-button"; + if (hasTooltip) { + className += " tooltip"; } + + if (typeof props.addClasses === "string") { + className += ` ${props.addClasses}`; + } + + // Tooltip will be set using inner HTML + let tooltipMarkup: IInnerHTMLMarkup | null; + if (hasTooltip) { + tooltipMarkup = { + __html: props.tooltip! + } + } + + return ( + + ) }