From 58e38faad676292a096d2c1823a330303a73fa11 Mon Sep 17 00:00:00 2001 From: Olivier Gagnon Date: Sun, 7 Mar 2021 15:58:52 -0500 Subject: [PATCH] Character percentages are aligned, server and hacknet limit are displayed, if the player has SF5 the reduces stats are shown. --- doc/Stats | 0 src/Constants.ts | 2 + src/engine.jsx | 4 +- src/ui/CharacterInfo.tsx | 238 +++++++++++++++++++++++++++++++++ src/ui/displayCharacterInfo.ts | 157 ---------------------- 5 files changed, 242 insertions(+), 159 deletions(-) create mode 100644 doc/Stats create mode 100644 src/ui/CharacterInfo.tsx delete mode 100644 src/ui/displayCharacterInfo.ts diff --git a/doc/Stats b/doc/Stats new file mode 100644 index 000000000..e69de29bb diff --git a/src/Constants.ts b/src/Constants.ts index f802ee97a..55e54ea35 100644 --- a/src/Constants.ts +++ b/src/Constants.ts @@ -254,5 +254,7 @@ export let CONSTANTS: IMap = { * minor formatting under Hacking>Active Scripts * typo in BN12 description * BN12 now reduces contract money + * Character>Stats percentages are aligned, server and hacknet limit are + displayed, if the player has SF5 the reduces stats are shown. ` } diff --git a/src/engine.jsx b/src/engine.jsx index b5d725494..997f25b41 100644 --- a/src/engine.jsx +++ b/src/engine.jsx @@ -86,7 +86,7 @@ import { } from "./PersonObjects/Resleeving/ResleevingUI"; import { createStatusText } from "./ui/createStatusText"; -import { displayCharacterInfo } from "./ui/displayCharacterInfo"; +import { CharacterInfo } from "./ui/CharacterInfo"; import { Page, routing } from "./ui/navigationTracking"; import { numeralWrapper } from "./ui/numeralFormat"; import { setSettingsLabels } from "./ui/setSettingsLabels"; @@ -567,7 +567,7 @@ const Engine = { /// Display character info updateCharacterInfo: function() { - displayCharacterInfo(Engine.Display.characterInfo, Player); + ReactDOM.render(CharacterInfo(Player), Engine.Display.characterInfo) }, // TODO Refactor this into Faction implementation diff --git a/src/ui/CharacterInfo.tsx b/src/ui/CharacterInfo.tsx new file mode 100644 index 000000000..b50dc5607 --- /dev/null +++ b/src/ui/CharacterInfo.tsx @@ -0,0 +1,238 @@ +import * as React from "react"; + +import { numeralWrapper } from "../ui/numeralFormat"; +import { BitNodes } from "../BitNode/BitNode"; +import { IPlayer } from "../PersonObjects/IPlayer"; +import { MoneySourceTracker } from "../utils/MoneySourceTracker"; +import { dialogBoxCreate } from "../../utils/DialogBox"; +import { convertTimeMsToTimeElapsedString } from "../../utils/StringHelperFunctions"; +import { BitNodeMultipliers } from "../BitNode/BitNodeMultipliers"; +import { SourceFileFlags } from "../SourceFile/SourceFileFlags"; +import { getPurchaseServerLimit } from "../Server/ServerPurchases"; +import { MaxNumberHacknetServers } from "../Hacknet/HacknetServer"; + + +export function CharacterInfo(p: IPlayer): React.ReactElement { + function LastEmployer(): React.ReactElement { + if (p.companyName) { + return <>Employer at which you last worked: {p.companyName}
; + } + return <>; + } + function LastJob(): React.ReactElement { + if (p.companyName !== "") { + return <>Job you last worked: {p.jobs[p.companyName]}
; + } + return <>; + } + function Employers(): React.ReactElement { + if (p.jobs && Object.keys(p.jobs).length !== 0) + return <> + All Employers:
+

+ + return <>; + } + + function convertMoneySourceTrackerToString(src: MoneySourceTracker): string { + let parts: string[] = [`Total: ${numeralWrapper.formatMoney(src.total)}`]; + if (src.bladeburner) { parts.push(`Bladeburner: ${numeralWrapper.formatMoney(src.bladeburner)}`) }; + if (src.codingcontract) { parts.push(`Coding Contracts: ${numeralWrapper.formatMoney(src.codingcontract)}`) }; + if (src.work) { parts.push(`Company Work: ${numeralWrapper.formatMoney(src.work)}`) }; + if (src.corporation) { parts.push(`Corporation: ${numeralWrapper.formatMoney(src.corporation)}`) }; + if (src.crime) { parts.push(`Crimes: ${numeralWrapper.formatMoney(src.crime)}`) }; + if (src.gang) { parts.push(`Gang: ${numeralWrapper.formatMoney(src.gang)}`) }; + if (src.hacking) { parts.push(`Hacking: ${numeralWrapper.formatMoney(src.hacking)}`) }; + if (src.hacknetnode) { parts.push(`Hacknet Nodes: ${numeralWrapper.formatMoney(src.hacknetnode)}`) }; + if (src.hospitalization) { parts.push(`Hospitalization: ${numeralWrapper.formatMoney(src.hospitalization)}`) }; + if (src.infiltration) { parts.push(`Infiltration: ${numeralWrapper.formatMoney(src.infiltration)}`) }; + if (src.stock) { parts.push(`Stock Market: ${numeralWrapper.formatMoney(src.stock)}`) }; + + return parts.join("
"); + } + + function openMoneyModal() { + let txt: string = "Money earned since you last installed Augmentations:
" + + convertMoneySourceTrackerToString(p.moneySourceA); + if (p.sourceFiles.length !== 0) { + txt += "

Money earned in this BitNode:
" + + convertMoneySourceTrackerToString(p.moneySourceB); + } + + dialogBoxCreate(txt, false); + } + + function Intelligence(): React.ReactElement { + if (p.intelligence > 0) { + return + Intelligence: + {(p.intelligence).toLocaleString()} + ; + } + return <>; + } + + function MultiplierTable(props: any): React.ReactElement { + function bn5Stat(r: any) { + if(SourceFileFlags[5] > 0 && r.length > 2 && r[1] != r[2]) { + return ({numeralWrapper.formatPercentage(r[2])}) + } + return undefined; + } + return <> + + + {props.rows.map((r: any) => + + + {bn5Stat(r)} + )} + +
{r[0]} multiplier: {numeralWrapper.formatPercentage(r[1])}
+ + } + + function BitNodeTimeText(): React.ReactElement { + if(p.sourceFiles.length > 0) { + return <> + Time played since last Bitnode destroyed: {convertTimeMsToTimeElapsedString(p.playtimeSinceLastBitnode)} +
+ + } + return <> + } + + function CurrentBitNode(): React.ReactElement { + if(p.sourceFiles.length > 0) { + + const index = "BitNode" + p.bitNodeN; + return <> + Current BitNode: {p.bitNodeN} ({BitNodes[index].name})

+
+ {BitNodes[index].info.split("
").map((t, i) =>
+ {t}
+
)} +
+ + } + + return <> + } + + return ( +
+            General
+            

+ Current City: {p.city}
+ + + + Money: {numeralWrapper.formatMoney(p.money.toNumber())} +

+ Stats + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Hacking:{p.hacking_skill.toLocaleString()}({numeralWrapper.format(p.hacking_exp, '0.000a')} exp)
Strength:{p.strength.toLocaleString()}({numeralWrapper.format(p.strength_exp, '0.000a')} exp)
Defense:{p.defense.toLocaleString()}({numeralWrapper.format(p.defense_exp, '0.000a')} exp)
Dexterity:{p.dexterity.toLocaleString()}({numeralWrapper.format(p.dexterity_exp, '0.000a')} exp)
Agility:{p.agility.toLocaleString()}({numeralWrapper.format(p.agility_exp, '0.000a')} exp)
Charisma:{p.charisma.toLocaleString()}({numeralWrapper.format(p.charisma_exp, '0.000a')} exp)
+
+
+
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +

+ + Misc.

+ Servers owned: {p.purchasedServers.length} / {getPurchaseServerLimit()}
+ Hacknet Nodes owned: {p.hacknetNodes.length} / {MaxNumberHacknetServers}
+ Augmentations installed: {p.augmentations.length}
+ Time played since last Augmentation: {convertTimeMsToTimeElapsedString(p.playtimeSinceLastAug)}
+ + Time played: {convertTimeMsToTimeElapsedString(p.totalPlaytime)}
+ +
+ +
+ ) +} \ No newline at end of file diff --git a/src/ui/displayCharacterInfo.ts b/src/ui/displayCharacterInfo.ts deleted file mode 100644 index e0b32457b..000000000 --- a/src/ui/displayCharacterInfo.ts +++ /dev/null @@ -1,157 +0,0 @@ -// Displays character info on a given element. This is used to create & update -// the 'Stats' page from the main menu -import { BitNodes } from "../BitNode/BitNode"; -import { IPlayer } from "../PersonObjects/IPlayer"; - -import { numeralWrapper } from "../ui/numeralFormat"; -import { MoneySourceTracker } from "../utils/MoneySourceTracker"; - -import { dialogBoxCreate } from "../../utils/DialogBox"; -import { convertTimeMsToTimeElapsedString } from "../../utils/StringHelperFunctions"; - -import { createElement } from "../../utils/uiHelpers/createElement"; -import { removeChildrenFromElement } from "../../utils/uiHelpers/removeChildrenFromElement"; - -export function displayCharacterInfo(elem: HTMLElement, p: IPlayer) { - removeChildrenFromElement(elem); - - let companyPosition = ""; - if (p.companyName !== "") { - companyPosition = p.jobs[p.companyName]; - } - - var intText = ""; - if (p.intelligence > 0) { - intText = 'Intelligence: ' + (p.intelligence).toLocaleString() + '
'; - } - - let bitNodeTimeText = ""; - if(p.sourceFiles.length > 0) { - bitNodeTimeText = 'Time played since last Bitnode destroyed: ' + convertTimeMsToTimeElapsedString(p.playtimeSinceLastBitnode) + '
'; - } - - const unlockedBitnodes: boolean = p.sourceFiles.length !== 0; - - // General info - elem.appendChild(createElement("pre", { - display: "block", - innerHTML: - 'General

' + - 'Current City: ' + p.city + '

' + - `Employer at which you last worked: ${p.companyName}
` + - `Job you last worked: ${companyPosition}
` + - `All Employers: ${Object.keys(p.jobs).join(", ")}

` - })); - - // Money, and a button to show money breakdown - elem.appendChild(createElement("pre", { - display: "inline-block", - innerHTML: 'Money: ' + numeralWrapper.formatMoney(p.money.toNumber()) + '


', - margin: "6px", - })); - - function convertMoneySourceTrackerToString(src: MoneySourceTracker): string { - let parts: string[] = [`Total: ${numeralWrapper.formatMoney(src.total)}`]; - if (src.bladeburner) { parts.push(`Bladeburner: ${numeralWrapper.formatMoney(src.bladeburner)}`) }; - if (src.codingcontract) { parts.push(`Coding Contracts: ${numeralWrapper.formatMoney(src.codingcontract)}`) }; - if (src.work) { parts.push(`Company Work: ${numeralWrapper.formatMoney(src.work)}`) }; - if (src.corporation) { parts.push(`Corporation: ${numeralWrapper.formatMoney(src.corporation)}`) }; - if (src.crime) { parts.push(`Crimes: ${numeralWrapper.formatMoney(src.crime)}`) }; - if (src.gang) { parts.push(`Gang: ${numeralWrapper.formatMoney(src.gang)}`) }; - if (src.hacking) { parts.push(`Hacking: ${numeralWrapper.formatMoney(src.hacking)}`) }; - if (src.hacknetnode) { parts.push(`Hacknet Nodes: ${numeralWrapper.formatMoney(src.hacknetnode)}`) }; - if (src.hospitalization) { parts.push(`Hospitalization: ${numeralWrapper.formatMoney(src.hospitalization)}`) }; - if (src.infiltration) { parts.push(`Infiltration: ${numeralWrapper.formatMoney(src.infiltration)}`) }; - if (src.stock) { parts.push(`Stock Market: ${numeralWrapper.formatMoney(src.stock)}`) }; - - return parts.join("
"); - } - - elem.appendChild(createElement("button", { - class: "popup-box-button", - display: "inline-block", - float: "none", - innerText: "Money Statistics & Breakdown", - clickListener: () => { - let txt: string = "Money earned since you last installed Augmentations:
" + - convertMoneySourceTrackerToString(p.moneySourceA); - if (unlockedBitnodes) { - txt += "

Money earned in this BitNode:
" + - convertMoneySourceTrackerToString(p.moneySourceB); - } - - dialogBoxCreate(txt, false); - } - })); - - // Stats and multiplier - elem.appendChild(createElement("pre", { - display: "block", - innerHTML: - 'Stats

' + - 'Hacking Level: ' + (p.hacking_skill).toLocaleString() + - ' (' + numeralWrapper.format(p.hacking_exp, '(0.000a)') + ' experience)
' + - 'Strength: ' + (p.strength).toLocaleString() + - ' (' + numeralWrapper.format(p.strength_exp, '(0.000a)') + ' experience)
' + - 'Defense: ' + (p.defense).toLocaleString() + - ' (' + numeralWrapper.format(p.defense_exp, '(0.000a)') + ' experience)
' + - 'Dexterity: ' + (p.dexterity).toLocaleString() + - ' (' + numeralWrapper.format(p.dexterity_exp, '(0.000a)') + ' experience)
' + - 'Agility: ' + (p.agility).toLocaleString() + - ' (' + numeralWrapper.format(p.agility_exp, '(0.000a)') + ' experience)
' + - 'Charisma: ' + (p.charisma).toLocaleString() + - ' (' + numeralWrapper.format(p.charisma_exp, '(0.000a)') + ' experience)
' + - intText + '

' + - 'Multipliers

' + - 'Hacking Chance multiplier: ' + numeralWrapper.formatPercentage(p.hacking_chance_mult) + '
' + - 'Hacking Speed multiplier: ' + numeralWrapper.formatPercentage(p.hacking_speed_mult) + '
' + - 'Hacking Money multiplier: ' + numeralWrapper.formatPercentage(p.hacking_money_mult) + '
' + - 'Hacking Growth multiplier: ' + numeralWrapper.formatPercentage(p.hacking_grow_mult) + '

' + - 'Hacking Level multiplier: ' + numeralWrapper.formatPercentage(p.hacking_mult) + '
' + - 'Hacking Experience multiplier: ' + numeralWrapper.formatPercentage(p.hacking_exp_mult) + '

' + - 'Strength Level multiplier: ' + numeralWrapper.formatPercentage(p.strength_mult) + '
' + - 'Strength Experience multiplier: ' + numeralWrapper.formatPercentage(p.strength_exp_mult) + '

' + - 'Defense Level multiplier: ' + numeralWrapper.formatPercentage(p.defense_mult) + '
' + - 'Defense Experience multiplier: ' + numeralWrapper.formatPercentage(p.defense_exp_mult) + '

' + - 'Dexterity Level multiplier: ' + numeralWrapper.formatPercentage(p.dexterity_mult) + '
' + - 'Dexterity Experience multiplier: ' + numeralWrapper.formatPercentage(p.dexterity_exp_mult) + '

' + - 'Agility Level multiplier: ' + numeralWrapper.formatPercentage(p.agility_mult) + '
' + - 'Agility Experience multiplier: ' + numeralWrapper.formatPercentage(p.agility_exp_mult) + '

' + - 'Charisma Level multiplier: ' + numeralWrapper.formatPercentage(p.charisma_mult) + '
' + - 'Charisma Experience multiplier: ' + numeralWrapper.formatPercentage(p.charisma_exp_mult) + '

' + - 'Hacknet Node production multiplier: ' + numeralWrapper.formatPercentage(p.hacknet_node_money_mult) + '
' + - 'Hacknet Node purchase cost multiplier: ' + numeralWrapper.formatPercentage(p.hacknet_node_purchase_cost_mult) + '
' + - 'Hacknet Node RAM upgrade cost multiplier: ' + numeralWrapper.formatPercentage(p.hacknet_node_ram_cost_mult) + '
' + - 'Hacknet Node Core purchase cost multiplier: ' + numeralWrapper.formatPercentage(p.hacknet_node_core_cost_mult) + '
' + - 'Hacknet Node level upgrade cost multiplier: ' + numeralWrapper.formatPercentage(p.hacknet_node_level_cost_mult) + '

' + - 'Company reputation gain multiplier: ' + numeralWrapper.formatPercentage(p.company_rep_mult) + '
' + - 'Faction reputation gain multiplier: ' + numeralWrapper.formatPercentage(p.faction_rep_mult) + '
' + - 'Salary multiplier: ' + numeralWrapper.formatPercentage(p.work_money_mult) + '
' + - 'Crime success multiplier: ' + numeralWrapper.formatPercentage(p.crime_success_mult) + '
' + - 'Crime money multiplier: ' + numeralWrapper.formatPercentage(p.crime_money_mult) + '


' + - 'Misc

' + - 'Servers owned: ' + p.purchasedServers.length + '
' + - 'Hacknet Nodes owned: ' + p.hacknetNodes.length + '
' + - 'Augmentations installed: ' + p.augmentations.length + '
' + - 'Time played since last Augmentation: ' + convertTimeMsToTimeElapsedString(p.playtimeSinceLastAug) + '
' + - bitNodeTimeText + - 'Time played: ' + convertTimeMsToTimeElapsedString(p.totalPlaytime), - })); - - // BitNode information, if player has gotten that far - if (unlockedBitnodes) { - var index = "BitNode" + p.bitNodeN; - - elem.appendChild(createElement("p", { - width:"60%", - innerHTML: - "
Current BitNode: " + p.bitNodeN + " (" + BitNodes[index].name + ")

", - })); - - elem.appendChild(createElement("p", { - width:"60%", fontSize: "13px", marginLeft:"4%", - innerHTML:BitNodes[index].info, - })) - } - -}