mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2026-05-03 14:27:03 +02:00
prettify, sorry for the big ass commit
This commit is contained in:
+1023
-870
File diff suppressed because it is too large
Load Diff
@@ -2,7 +2,7 @@
|
||||
* Module for handling the UI for purchasing Sleeve Augmentations
|
||||
* This UI is a popup, not a full page
|
||||
*/
|
||||
import React from 'react';
|
||||
import React from "react";
|
||||
import { Sleeve } from "./Sleeve";
|
||||
import { findSleevePurchasableAugs } from "./SleeveHelpers";
|
||||
|
||||
@@ -20,106 +20,118 @@ import { createPopup } from "../../../utils/uiHelpers/createPopup";
|
||||
import { createPopupCloseButton } from "../../../utils/uiHelpers/createPopupCloseButton";
|
||||
import { removeElementById } from "../../../utils/uiHelpers/removeElementById";
|
||||
|
||||
import { renderToStaticMarkup } from "react-dom/server"
|
||||
import { renderToStaticMarkup } from "react-dom/server";
|
||||
|
||||
export function createSleevePurchaseAugsPopup(sleeve: Sleeve, p: IPlayer): void {
|
||||
// Array of all owned Augmentations. Names only
|
||||
const ownedAugNames: string[] = sleeve.augmentations.map((e) => {return e.name});
|
||||
export function createSleevePurchaseAugsPopup(
|
||||
sleeve: Sleeve,
|
||||
p: IPlayer,
|
||||
): void {
|
||||
// Array of all owned Augmentations. Names only
|
||||
const ownedAugNames: string[] = sleeve.augmentations.map((e) => {
|
||||
return e.name;
|
||||
});
|
||||
|
||||
// You can only purchase Augmentations that are actually available from
|
||||
// your factions. I.e. you must be in a faction that has the Augmentation
|
||||
// and you must also have enough rep in that faction in order to purchase it.
|
||||
const availableAugs = findSleevePurchasableAugs(sleeve, p);
|
||||
// You can only purchase Augmentations that are actually available from
|
||||
// your factions. I.e. you must be in a faction that has the Augmentation
|
||||
// and you must also have enough rep in that faction in order to purchase it.
|
||||
const availableAugs = findSleevePurchasableAugs(sleeve, p);
|
||||
|
||||
// Create popup
|
||||
const popupId = "purchase-sleeve-augs-popup";
|
||||
// Create popup
|
||||
const popupId = "purchase-sleeve-augs-popup";
|
||||
|
||||
// Close popup button
|
||||
const closeBtn = createPopupCloseButton(popupId, { innerText: "Cancel" });
|
||||
// Close popup button
|
||||
const closeBtn = createPopupCloseButton(popupId, { innerText: "Cancel" });
|
||||
|
||||
// General info about owned Augmentations
|
||||
const ownedAugsInfo = createElement("p", {
|
||||
display: "block",
|
||||
innerHTML: "Owned Augmentations:",
|
||||
// General info about owned Augmentations
|
||||
const ownedAugsInfo = createElement("p", {
|
||||
display: "block",
|
||||
innerHTML: "Owned Augmentations:",
|
||||
});
|
||||
|
||||
const popupElems: HTMLElement[] = [closeBtn, ownedAugsInfo];
|
||||
|
||||
// Show owned augmentations
|
||||
// First we'll make a div with a reduced width, so the tooltips don't go off
|
||||
// the edge of the popup
|
||||
const ownedAugsDiv = createElement("div", { width: "70%" });
|
||||
for (const ownedAug of ownedAugNames) {
|
||||
const aug: Augmentation | null = Augmentations[ownedAug];
|
||||
if (aug == null) {
|
||||
console.warn(`Invalid Augmentation: ${ownedAug}`);
|
||||
continue;
|
||||
}
|
||||
|
||||
let tooltip = aug.info;
|
||||
if (typeof tooltip !== "string") {
|
||||
tooltip = renderToStaticMarkup(tooltip);
|
||||
}
|
||||
tooltip += "<br /><br />";
|
||||
tooltip += renderToStaticMarkup(aug.stats);
|
||||
|
||||
ownedAugsDiv.appendChild(
|
||||
createElement("div", {
|
||||
class: "gang-owned-upgrade", // Reusing a class from the Gang UI
|
||||
innerText: ownedAug,
|
||||
tooltip: tooltip,
|
||||
}),
|
||||
);
|
||||
}
|
||||
popupElems.push(ownedAugsDiv);
|
||||
|
||||
// General info about buying Augmentations
|
||||
const info = createElement("p", {
|
||||
innerHTML: [
|
||||
`You can purchase Augmentations for your Duplicate Sleeves. These Augmentations`,
|
||||
`have the same effect as they would for you. You can only purchase Augmentations`,
|
||||
`that you have unlocked through Factions.<br><br>`,
|
||||
`When purchasing an Augmentation for a Duplicate Sleeve, they are immediately`,
|
||||
`installed. This means that the Duplicate Sleeve will immediately lose all of`,
|
||||
`its stat experience.`,
|
||||
].join(" "),
|
||||
});
|
||||
|
||||
popupElems.push(info);
|
||||
|
||||
for (const aug of availableAugs) {
|
||||
const div = createElement("div", {
|
||||
class: "cmpy-mgmt-upgrade-div", // We'll reuse this CSS class
|
||||
});
|
||||
|
||||
const popupElems: HTMLElement[] = [closeBtn, ownedAugsInfo];
|
||||
|
||||
// Show owned augmentations
|
||||
// First we'll make a div with a reduced width, so the tooltips don't go off
|
||||
// the edge of the popup
|
||||
const ownedAugsDiv = createElement("div", { width: "70%" });
|
||||
for (const ownedAug of ownedAugNames) {
|
||||
const aug: Augmentation | null = Augmentations[ownedAug];
|
||||
if (aug == null) {
|
||||
console.warn(`Invalid Augmentation: ${ownedAug}`);
|
||||
continue;
|
||||
}
|
||||
|
||||
let tooltip = aug.info;
|
||||
if(typeof tooltip !== 'string') {
|
||||
tooltip = renderToStaticMarkup(tooltip);
|
||||
}
|
||||
tooltip += "<br /><br />";
|
||||
tooltip += renderToStaticMarkup(aug.stats);
|
||||
|
||||
ownedAugsDiv.appendChild(createElement("div", {
|
||||
class: "gang-owned-upgrade", // Reusing a class from the Gang UI
|
||||
innerText: ownedAug,
|
||||
tooltip: tooltip,
|
||||
}))
|
||||
let info = aug.info;
|
||||
if (typeof info !== "string") {
|
||||
info = renderToStaticMarkup(info);
|
||||
}
|
||||
popupElems.push(ownedAugsDiv);
|
||||
info += "<br /><br />";
|
||||
info += renderToStaticMarkup(aug.stats);
|
||||
|
||||
// General info about buying Augmentations
|
||||
const info = createElement("p", {
|
||||
innerHTML:
|
||||
[
|
||||
`You can purchase Augmentations for your Duplicate Sleeves. These Augmentations`,
|
||||
`have the same effect as they would for you. You can only purchase Augmentations`,
|
||||
`that you have unlocked through Factions.<br><br>`,
|
||||
`When purchasing an Augmentation for a Duplicate Sleeve, they are immediately`,
|
||||
`installed. This means that the Duplicate Sleeve will immediately lose all of`,
|
||||
`its stat experience.`,
|
||||
div.appendChild(
|
||||
createElement("p", {
|
||||
fontSize: "12px",
|
||||
innerHTML: [
|
||||
`<h2>${aug.name}</h2><br>`,
|
||||
`Cost: ${renderToStaticMarkup(
|
||||
<Money money={aug.startingCost} player={p} />,
|
||||
)}<br><br>`,
|
||||
`${info}`,
|
||||
].join(" "),
|
||||
});
|
||||
padding: "2px",
|
||||
clickListener: () => {
|
||||
if (sleeve.tryBuyAugmentation(p, aug)) {
|
||||
dialogBoxCreate(
|
||||
`Installed ${aug.name} on Duplicate Sleeve!`,
|
||||
false,
|
||||
);
|
||||
removeElementById(popupId);
|
||||
createSleevePurchaseAugsPopup(sleeve, p);
|
||||
} else {
|
||||
dialogBoxCreate(`You cannot afford ${aug.name}`, false);
|
||||
}
|
||||
},
|
||||
}),
|
||||
);
|
||||
|
||||
popupElems.push(info);
|
||||
popupElems.push(div);
|
||||
}
|
||||
|
||||
for (const aug of availableAugs) {
|
||||
const div = createElement("div", {
|
||||
class: "cmpy-mgmt-upgrade-div", // We'll reuse this CSS class
|
||||
});
|
||||
|
||||
let info = aug.info;
|
||||
if(typeof info !== 'string') {
|
||||
info = renderToStaticMarkup(info);
|
||||
}
|
||||
info += "<br /><br />";
|
||||
info += renderToStaticMarkup(aug.stats);
|
||||
|
||||
div.appendChild(createElement("p", {
|
||||
fontSize: "12px",
|
||||
innerHTML:
|
||||
[
|
||||
`<h2>${aug.name}</h2><br>`,
|
||||
`Cost: ${renderToStaticMarkup(<Money money={aug.startingCost} player={p} />)}<br><br>`,
|
||||
`${info}`,
|
||||
].join(" "),
|
||||
padding: "2px",
|
||||
clickListener: () => {
|
||||
if (sleeve.tryBuyAugmentation(p, aug)) {
|
||||
dialogBoxCreate(`Installed ${aug.name} on Duplicate Sleeve!`, false);
|
||||
removeElementById(popupId);
|
||||
createSleevePurchaseAugsPopup(sleeve, p);
|
||||
} else {
|
||||
dialogBoxCreate(`You cannot afford ${aug.name}`, false);
|
||||
}
|
||||
},
|
||||
}));
|
||||
|
||||
popupElems.push(div);
|
||||
}
|
||||
|
||||
createPopup(popupId, popupElems);
|
||||
createPopup(popupId, popupElems);
|
||||
}
|
||||
|
||||
@@ -5,13 +5,15 @@
|
||||
import { IPlayer } from "../IPlayer";
|
||||
|
||||
import { CovenantPurchasesRoot } from "./ui/CovenantPurchasesRoot";
|
||||
import { createPopup,
|
||||
removePopup } from "../../ui/React/createPopup";
|
||||
import { createPopup, removePopup } from "../../ui/React/createPopup";
|
||||
|
||||
export const MaxSleevesFromCovenant = 5;
|
||||
export const BaseCostPerSleeve = 10e12;
|
||||
export const PopupId = "covenant-sleeve-purchases-popup";
|
||||
|
||||
export function createSleevePurchasesFromCovenantPopup(p: IPlayer): void {
|
||||
createPopup(PopupId, CovenantPurchasesRoot, { p: p, closeFn: () => removePopup(PopupId) });
|
||||
createPopup(PopupId, CovenantPurchasesRoot, {
|
||||
p: p,
|
||||
closeFn: () => removePopup(PopupId),
|
||||
});
|
||||
}
|
||||
|
||||
@@ -8,57 +8,80 @@ import { AugmentationNames } from "../../Augmentation/data/AugmentationNames";
|
||||
import { Faction } from "../../Faction/Faction";
|
||||
import { Factions } from "../../Faction/Factions";
|
||||
|
||||
export function findSleevePurchasableAugs(sleeve: Sleeve, p: IPlayer): Augmentation[] {
|
||||
// You can only purchase Augmentations that are actually available from
|
||||
// your factions. I.e. you must be in a faction that has the Augmentation
|
||||
// and you must also have enough rep in that faction in order to purchase it.
|
||||
export function findSleevePurchasableAugs(
|
||||
sleeve: Sleeve,
|
||||
p: IPlayer,
|
||||
): Augmentation[] {
|
||||
// You can only purchase Augmentations that are actually available from
|
||||
// your factions. I.e. you must be in a faction that has the Augmentation
|
||||
// and you must also have enough rep in that faction in order to purchase it.
|
||||
|
||||
const ownedAugNames: string[] = sleeve.augmentations.map((e) => {return e.name});
|
||||
const availableAugs: Augmentation[] = [];
|
||||
const ownedAugNames: string[] = sleeve.augmentations.map((e) => {
|
||||
return e.name;
|
||||
});
|
||||
const availableAugs: Augmentation[] = [];
|
||||
|
||||
// Helper function that helps filter out augs that are already owned
|
||||
// and augs that aren't allowed for sleeves
|
||||
function isAvailableForSleeve(aug: Augmentation): boolean {
|
||||
if (aug.name === AugmentationNames.NeuroFluxGovernor) { return false; }
|
||||
if (ownedAugNames.includes(aug.name)) { return false; }
|
||||
if (availableAugs.includes(aug)) { return false; }
|
||||
if (aug.isSpecial) { return false; }
|
||||
|
||||
return true;
|
||||
// Helper function that helps filter out augs that are already owned
|
||||
// and augs that aren't allowed for sleeves
|
||||
function isAvailableForSleeve(aug: Augmentation): boolean {
|
||||
if (aug.name === AugmentationNames.NeuroFluxGovernor) {
|
||||
return false;
|
||||
}
|
||||
if (ownedAugNames.includes(aug.name)) {
|
||||
return false;
|
||||
}
|
||||
if (availableAugs.includes(aug)) {
|
||||
return false;
|
||||
}
|
||||
if (aug.isSpecial) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// If player is in a gang, then we return all augs that the player
|
||||
// has enough reputation for (since that gang offers all augs)
|
||||
if (p.inGang()) {
|
||||
const fac = p.getGangFaction();
|
||||
return true;
|
||||
}
|
||||
|
||||
for (const augName in Augmentations) {
|
||||
const aug = Augmentations[augName];
|
||||
if (!isAvailableForSleeve(aug)) { continue; }
|
||||
// If player is in a gang, then we return all augs that the player
|
||||
// has enough reputation for (since that gang offers all augs)
|
||||
if (p.inGang()) {
|
||||
const fac = p.getGangFaction();
|
||||
|
||||
if (fac.playerReputation > aug.baseRepRequirement) {
|
||||
availableAugs.push(aug);
|
||||
}
|
||||
}
|
||||
for (const augName in Augmentations) {
|
||||
const aug = Augmentations[augName];
|
||||
if (!isAvailableForSleeve(aug)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
return availableAugs;
|
||||
}
|
||||
|
||||
for (const facName of p.factions) {
|
||||
if (facName === "Bladeburners") { continue; }
|
||||
if (facName === "Netburners") { continue; }
|
||||
const fac: Faction | null = Factions[facName];
|
||||
if (fac == null) { continue; }
|
||||
|
||||
for (const augName of fac.augmentations) {
|
||||
const aug: Augmentation = Augmentations[augName];
|
||||
if (!isAvailableForSleeve(aug)) { continue; }
|
||||
|
||||
if (fac.playerReputation > aug.baseRepRequirement) {
|
||||
availableAugs.push(aug);
|
||||
}
|
||||
}
|
||||
if (fac.playerReputation > aug.baseRepRequirement) {
|
||||
availableAugs.push(aug);
|
||||
}
|
||||
}
|
||||
|
||||
return availableAugs;
|
||||
}
|
||||
|
||||
for (const facName of p.factions) {
|
||||
if (facName === "Bladeburners") {
|
||||
continue;
|
||||
}
|
||||
if (facName === "Netburners") {
|
||||
continue;
|
||||
}
|
||||
const fac: Faction | null = Factions[facName];
|
||||
if (fac == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (const augName of fac.augmentations) {
|
||||
const aug: Augmentation = Augmentations[augName];
|
||||
if (!isAvailableForSleeve(aug)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (fac.playerReputation > aug.baseRepRequirement) {
|
||||
availableAugs.push(aug);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return availableAugs;
|
||||
}
|
||||
|
||||
@@ -2,13 +2,13 @@
|
||||
* Enum for different types of tasks that a Sleeve can perform
|
||||
*/
|
||||
export enum SleeveTaskType {
|
||||
// Same Order as selectable order in UI
|
||||
Idle,
|
||||
Company,
|
||||
Faction,
|
||||
Crime,
|
||||
Class,
|
||||
Gym,
|
||||
Recovery,
|
||||
Synchro,
|
||||
// Same Order as selectable order in UI
|
||||
Idle,
|
||||
Company,
|
||||
Faction,
|
||||
Crime,
|
||||
Class,
|
||||
Gym,
|
||||
Recovery,
|
||||
Synchro,
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,80 +1,116 @@
|
||||
import * as React from "react";
|
||||
|
||||
export const SleeveFaq = (<>
|
||||
<strong><u>How do Duplicate Sleeves work?</u></strong>
|
||||
export const SleeveFaq = (
|
||||
<>
|
||||
<strong>
|
||||
<u>How do Duplicate Sleeves work?</u>
|
||||
</strong>
|
||||
<br />
|
||||
Duplicate Sleeves are essentially clones. You can use them to perform any work type
|
||||
action, such as working for a company/faction or committing a crime.
|
||||
Having sleeves perform these tasks earns you money, experience, and reputation.
|
||||
<br /><br />
|
||||
Sleeves are their own individuals, which means they each have their own
|
||||
experience and stats.
|
||||
<br /><br />
|
||||
When a sleeve earns experience, it earns experience for itself, the player's
|
||||
original 'consciousness', as well as all of the player's other sleeves.
|
||||
<br /><br />
|
||||
|
||||
<strong><u>What is Synchronization (Sync)?</u></strong>
|
||||
Duplicate Sleeves are essentially clones. You can use them to perform any
|
||||
work type action, such as working for a company/faction or committing a
|
||||
crime. Having sleeves perform these tasks earns you money, experience, and
|
||||
reputation.
|
||||
<br />
|
||||
Synchronization is a measure of how aligned your consciousness is with
|
||||
that of your Duplicate Sleeves. It is a numerical value between 1 and 100, and
|
||||
it affects how much experience is earned when the sleeve is performing a task.
|
||||
<br /><br />
|
||||
Let N be the sleeve's synchronization. When the sleeve earns experience by performing a
|
||||
task, both the sleeve and the player's original host consciousness earn N%
|
||||
of the amount of experience normally earned by the task. All of the player's
|
||||
other sleeves earn ((N/100)^2 * 100)% of the experience.
|
||||
<br /><br />
|
||||
Synchronization can be increased by assigning sleeves to the 'Synchronize' task.
|
||||
<br /><br />
|
||||
|
||||
<strong><u>What is Shock?</u></strong>
|
||||
<br />
|
||||
Sleeve shock is a measure of how much trauma the sleeve has due to being placed in a new
|
||||
body. It is a numerical value between 0 and 99, where 99 indicates full shock and 0 indicates
|
||||
no shock. Shock affects the amount of experience earned by the sleeve.
|
||||
<br /><br />
|
||||
Sleeve shock slowly decreases over time. You can further increase the rate at which
|
||||
it decreases by assigning sleeves to the 'Shock Recovery' task.
|
||||
<br /><br />
|
||||
|
||||
<strong><u>Why can't I work for this company or faction?</u></strong>
|
||||
Sleeves are their own individuals, which means they each have their own
|
||||
experience and stats.
|
||||
<br />
|
||||
Only one of your sleeves can work for a given company/faction a time.
|
||||
To clarify further, if you have two sleeves they can work for two different
|
||||
companies, but they cannot both work for the same company.
|
||||
<br /><br />
|
||||
|
||||
<strong><u>Why did my Sleeve stop working?</u></strong>
|
||||
<br />
|
||||
Sleeves are subject to the same time restrictions as you. This means that
|
||||
they automatically stop working at a company after 8 hours, and stop working
|
||||
for a faction after 20 hours.
|
||||
<br /><br />
|
||||
|
||||
<strong><u>How do I buy Augmentations for my Sleeves?</u></strong>
|
||||
When a sleeve earns experience, it earns experience for itself, the player's
|
||||
original 'consciousness', as well as all of the player's other sleeves.
|
||||
<br />
|
||||
Your Sleeve needs to have a Shock of 0 in order for you to buy Augmentations
|
||||
for it.
|
||||
<br /><br />
|
||||
|
||||
<strong><u>Why can't I buy the X Augmentation for my sleeve?</u></strong>
|
||||
<br />
|
||||
Certain Augmentations, like Bladeburner-specific ones and NeuroFlux Governor,
|
||||
are not available for sleeves.
|
||||
<br /><br />
|
||||
|
||||
<strong><u>Do sleeves get reset when installing Augmentations or switching BitNodes?</u></strong><br />
|
||||
Sleeves are reset when switching BitNodes, but not when installing Augmentations.
|
||||
<br /><br />
|
||||
|
||||
<strong><u>What is Memory?</u></strong>
|
||||
<strong>
|
||||
<u>What is Synchronization (Sync)?</u>
|
||||
</strong>
|
||||
<br />
|
||||
Sleeve memory dictates what a sleeve's synchronization will be
|
||||
when its reset by switching BitNodes. For example, if a sleeve has a memory of 25,
|
||||
then when you switch BitNodes its synchronization will initially be set to 25, rather than 1.
|
||||
<br /><br />
|
||||
Memory can only be increased by purchasing upgrades from The Covenant. It is a
|
||||
persistent stat, meaning it never gets resets back to 1. The maximum possible
|
||||
value for a sleeve's memory is 100.
|
||||
</>);
|
||||
Synchronization is a measure of how aligned your consciousness is with that
|
||||
of your Duplicate Sleeves. It is a numerical value between 1 and 100, and it
|
||||
affects how much experience is earned when the sleeve is performing a task.
|
||||
<br />
|
||||
<br />
|
||||
Let N be the sleeve's synchronization. When the sleeve earns experience by
|
||||
performing a task, both the sleeve and the player's original host
|
||||
consciousness earn N% of the amount of experience normally earned by the
|
||||
task. All of the player's other sleeves earn ((N/100)^2 * 100)% of the
|
||||
experience.
|
||||
<br />
|
||||
<br />
|
||||
Synchronization can be increased by assigning sleeves to the 'Synchronize'
|
||||
task.
|
||||
<br />
|
||||
<br />
|
||||
<strong>
|
||||
<u>What is Shock?</u>
|
||||
</strong>
|
||||
<br />
|
||||
Sleeve shock is a measure of how much trauma the sleeve has due to being
|
||||
placed in a new body. It is a numerical value between 0 and 99, where 99
|
||||
indicates full shock and 0 indicates no shock. Shock affects the amount of
|
||||
experience earned by the sleeve.
|
||||
<br />
|
||||
<br />
|
||||
Sleeve shock slowly decreases over time. You can further increase the rate
|
||||
at which it decreases by assigning sleeves to the 'Shock Recovery' task.
|
||||
<br />
|
||||
<br />
|
||||
<strong>
|
||||
<u>Why can't I work for this company or faction?</u>
|
||||
</strong>
|
||||
<br />
|
||||
Only one of your sleeves can work for a given company/faction a time. To
|
||||
clarify further, if you have two sleeves they can work for two different
|
||||
companies, but they cannot both work for the same company.
|
||||
<br />
|
||||
<br />
|
||||
<strong>
|
||||
<u>Why did my Sleeve stop working?</u>
|
||||
</strong>
|
||||
<br />
|
||||
Sleeves are subject to the same time restrictions as you. This means that
|
||||
they automatically stop working at a company after 8 hours, and stop working
|
||||
for a faction after 20 hours.
|
||||
<br />
|
||||
<br />
|
||||
<strong>
|
||||
<u>How do I buy Augmentations for my Sleeves?</u>
|
||||
</strong>
|
||||
<br />
|
||||
Your Sleeve needs to have a Shock of 0 in order for you to buy Augmentations
|
||||
for it.
|
||||
<br />
|
||||
<br />
|
||||
<strong>
|
||||
<u>Why can't I buy the X Augmentation for my sleeve?</u>
|
||||
</strong>
|
||||
<br />
|
||||
Certain Augmentations, like Bladeburner-specific ones and NeuroFlux
|
||||
Governor, are not available for sleeves.
|
||||
<br />
|
||||
<br />
|
||||
<strong>
|
||||
<u>
|
||||
Do sleeves get reset when installing Augmentations or switching
|
||||
BitNodes?
|
||||
</u>
|
||||
</strong>
|
||||
<br />
|
||||
Sleeves are reset when switching BitNodes, but not when installing
|
||||
Augmentations.
|
||||
<br />
|
||||
<br />
|
||||
<strong>
|
||||
<u>What is Memory?</u>
|
||||
</strong>
|
||||
<br />
|
||||
Sleeve memory dictates what a sleeve's synchronization will be when its
|
||||
reset by switching BitNodes. For example, if a sleeve has a memory of 25,
|
||||
then when you switch BitNodes its synchronization will initially be set to
|
||||
25, rather than 1.
|
||||
<br />
|
||||
<br />
|
||||
Memory can only be increased by purchasing upgrades from The Covenant. It is
|
||||
a persistent stat, meaning it never gets resets back to 1. The maximum
|
||||
possible value for a sleeve's memory is 100.
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -2,92 +2,110 @@
|
||||
* Root React component for the popup that lets player purchase Duplicate
|
||||
* Sleeves and Sleeve-related upgrades from The Covenant
|
||||
*/
|
||||
import React, { useState } from 'react';
|
||||
import React, { useState } from "react";
|
||||
|
||||
import { CovenantSleeveUpgrades } from "./CovenantSleeveUpgrades";
|
||||
import { CovenantSleeveUpgrades } from "./CovenantSleeveUpgrades";
|
||||
|
||||
import { Sleeve } from "../Sleeve";
|
||||
import { BaseCostPerSleeve,
|
||||
MaxSleevesFromCovenant,
|
||||
PopupId } from "../SleeveCovenantPurchases";
|
||||
import { IPlayer } from "../../IPlayer";
|
||||
import { Sleeve } from "../Sleeve";
|
||||
import {
|
||||
BaseCostPerSleeve,
|
||||
MaxSleevesFromCovenant,
|
||||
PopupId,
|
||||
} from "../SleeveCovenantPurchases";
|
||||
import { IPlayer } from "../../IPlayer";
|
||||
|
||||
import { PopupCloseButton } from "../../../ui/React/PopupCloseButton";
|
||||
import { StdButton } from "../../../ui/React/StdButton";
|
||||
import { Money } from "../../../ui/React/Money";
|
||||
import { PopupCloseButton } from "../../../ui/React/PopupCloseButton";
|
||||
import { StdButton } from "../../../ui/React/StdButton";
|
||||
import { Money } from "../../../ui/React/Money";
|
||||
|
||||
import { dialogBoxCreate } from "../../../../utils/DialogBox";
|
||||
import { dialogBoxCreate } from "../../../../utils/DialogBox";
|
||||
|
||||
interface IProps {
|
||||
closeFn: () => void;
|
||||
p: IPlayer;
|
||||
closeFn: () => void;
|
||||
p: IPlayer;
|
||||
}
|
||||
|
||||
export function CovenantPurchasesRoot(props: IProps): React.ReactElement {
|
||||
const [update, setUpdate] = useState(0);
|
||||
const [update, setUpdate] = useState(0);
|
||||
|
||||
/**
|
||||
* Get the cost to purchase a new Duplicate Sleeve
|
||||
*/
|
||||
function purchaseCost(): number {
|
||||
return (props.p.sleevesFromCovenant + 1) * BaseCostPerSleeve;
|
||||
}
|
||||
/**
|
||||
* Get the cost to purchase a new Duplicate Sleeve
|
||||
*/
|
||||
function purchaseCost(): number {
|
||||
return (props.p.sleevesFromCovenant + 1) * BaseCostPerSleeve;
|
||||
}
|
||||
|
||||
/**
|
||||
* Force a rerender by just changing an arbitrary state value
|
||||
*/
|
||||
function rerender(): void {
|
||||
setUpdate(update + 1);
|
||||
}
|
||||
/**
|
||||
* Force a rerender by just changing an arbitrary state value
|
||||
*/
|
||||
function rerender(): void {
|
||||
setUpdate(update + 1);
|
||||
}
|
||||
|
||||
// Purchasing a new Duplicate Sleeve
|
||||
let purchaseDisabled = false;
|
||||
if (!props.p.canAfford(purchaseCost())) {
|
||||
purchaseDisabled = true;
|
||||
}
|
||||
if (props.p.sleevesFromCovenant >= MaxSleevesFromCovenant) {
|
||||
purchaseDisabled = true;
|
||||
}
|
||||
// Purchasing a new Duplicate Sleeve
|
||||
let purchaseDisabled = false;
|
||||
if (!props.p.canAfford(purchaseCost())) {
|
||||
purchaseDisabled = true;
|
||||
}
|
||||
if (props.p.sleevesFromCovenant >= MaxSleevesFromCovenant) {
|
||||
purchaseDisabled = true;
|
||||
}
|
||||
|
||||
function purchaseOnClick(): void {
|
||||
if (props.p.sleevesFromCovenant >= MaxSleevesFromCovenant) return;
|
||||
|
||||
if (props.p.canAfford(purchaseCost())) {
|
||||
props.p.loseMoney(purchaseCost());
|
||||
props.p.sleevesFromCovenant += 1;
|
||||
props.p.sleeves.push(new Sleeve(props.p));
|
||||
rerender();
|
||||
} else {
|
||||
dialogBoxCreate(`You cannot afford to purchase a Duplicate Sleeve`, false);
|
||||
}
|
||||
}
|
||||
function purchaseOnClick(): void {
|
||||
if (props.p.sleevesFromCovenant >= MaxSleevesFromCovenant) return;
|
||||
|
||||
// Purchasing Upgrades for Sleeves
|
||||
const upgradePanels = [];
|
||||
for (let i = 0; i < props.p.sleeves.length; ++i) {
|
||||
const sleeve = props.p.sleeves[i];
|
||||
upgradePanels.push(
|
||||
<CovenantSleeveUpgrades {...props} sleeve={sleeve} index={i} rerender={rerender} key={i} />,
|
||||
)
|
||||
if (props.p.canAfford(purchaseCost())) {
|
||||
props.p.loseMoney(purchaseCost());
|
||||
props.p.sleevesFromCovenant += 1;
|
||||
props.p.sleeves.push(new Sleeve(props.p));
|
||||
rerender();
|
||||
} else {
|
||||
dialogBoxCreate(
|
||||
`You cannot afford to purchase a Duplicate Sleeve`,
|
||||
false,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return (<div>
|
||||
<PopupCloseButton popup={PopupId} text={"Close"} />
|
||||
<p>
|
||||
Would you like to purchase an additional Duplicate Sleeve from The Covenant
|
||||
for <Money money={purchaseCost()} player={props.p} />?
|
||||
</p>
|
||||
<br />
|
||||
<p>
|
||||
These Duplicate Sleeves are permanent (they persist through BitNodes). You can
|
||||
purchase a total of {MaxSleevesFromCovenant} from The Covenant.
|
||||
</p>
|
||||
<StdButton disabled={purchaseDisabled} onClick={purchaseOnClick} text={"Purchase"} />
|
||||
<br /><br />
|
||||
<p>
|
||||
Here, you can also purchase upgrades for your Duplicate Sleeves. These upgrades
|
||||
are also permanent, meaning they persist across BitNodes.
|
||||
</p>
|
||||
{upgradePanels}
|
||||
</div>);
|
||||
// Purchasing Upgrades for Sleeves
|
||||
const upgradePanels = [];
|
||||
for (let i = 0; i < props.p.sleeves.length; ++i) {
|
||||
const sleeve = props.p.sleeves[i];
|
||||
upgradePanels.push(
|
||||
<CovenantSleeveUpgrades
|
||||
{...props}
|
||||
sleeve={sleeve}
|
||||
index={i}
|
||||
rerender={rerender}
|
||||
key={i}
|
||||
/>,
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<PopupCloseButton popup={PopupId} text={"Close"} />
|
||||
<p>
|
||||
Would you like to purchase an additional Duplicate Sleeve from The
|
||||
Covenant for <Money money={purchaseCost()} player={props.p} />?
|
||||
</p>
|
||||
<br />
|
||||
<p>
|
||||
These Duplicate Sleeves are permanent (they persist through BitNodes).
|
||||
You can purchase a total of {MaxSleevesFromCovenant} from The Covenant.
|
||||
</p>
|
||||
<StdButton
|
||||
disabled={purchaseDisabled}
|
||||
onClick={purchaseOnClick}
|
||||
text={"Purchase"}
|
||||
/>
|
||||
<br />
|
||||
<br />
|
||||
<p>
|
||||
Here, you can also purchase upgrades for your Duplicate Sleeves. These
|
||||
upgrades are also permanent, meaning they persist across BitNodes.
|
||||
</p>
|
||||
{upgradePanels}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -12,91 +12,116 @@ import { StdButton } from "../../../ui/React/StdButton";
|
||||
import { Money } from "../../../ui/React/Money";
|
||||
|
||||
interface IProps {
|
||||
index: number;
|
||||
p: IPlayer;
|
||||
rerender: () => void;
|
||||
sleeve: Sleeve;
|
||||
index: number;
|
||||
p: IPlayer;
|
||||
rerender: () => void;
|
||||
sleeve: Sleeve;
|
||||
}
|
||||
|
||||
interface IState {
|
||||
amt: number;
|
||||
amt: number;
|
||||
}
|
||||
|
||||
export class CovenantSleeveMemoryUpgrade extends React.Component<IProps, IState> {
|
||||
constructor(props: IProps) {
|
||||
super(props);
|
||||
export class CovenantSleeveMemoryUpgrade extends React.Component<
|
||||
IProps,
|
||||
IState
|
||||
> {
|
||||
constructor(props: IProps) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
amt: 1,
|
||||
}
|
||||
this.state = {
|
||||
amt: 1,
|
||||
};
|
||||
|
||||
this.changePurchaseAmount = this.changePurchaseAmount.bind(this);
|
||||
this.purchaseMemory = this.purchaseMemory.bind(this);
|
||||
this.changePurchaseAmount = this.changePurchaseAmount.bind(this);
|
||||
this.purchaseMemory = this.purchaseMemory.bind(this);
|
||||
}
|
||||
|
||||
changePurchaseAmount(e: React.ChangeEvent<HTMLInputElement>): void {
|
||||
let n: number = parseInt(e.target.value);
|
||||
|
||||
if (isNaN(n)) n = 1;
|
||||
const maxMemory = 100 - this.props.sleeve.memory;
|
||||
if (n > maxMemory) n = maxMemory;
|
||||
|
||||
this.setState({
|
||||
amt: n,
|
||||
});
|
||||
}
|
||||
|
||||
getPurchaseCost(): number {
|
||||
if (isNaN(this.state.amt)) {
|
||||
return Infinity;
|
||||
}
|
||||
|
||||
changePurchaseAmount(e: React.ChangeEvent<HTMLInputElement>): void {
|
||||
let n: number = parseInt(e.target.value);
|
||||
|
||||
if(isNaN(n)) n = 1;
|
||||
const maxMemory = 100 - this.props.sleeve.memory;
|
||||
if (n > maxMemory) n = maxMemory;
|
||||
|
||||
this.setState({
|
||||
amt: n,
|
||||
});
|
||||
const maxMemory = 100 - this.props.sleeve.memory;
|
||||
if (this.state.amt > maxMemory) {
|
||||
return Infinity;
|
||||
}
|
||||
|
||||
getPurchaseCost(): number {
|
||||
if (isNaN(this.state.amt)) { return Infinity; }
|
||||
return this.props.sleeve.getMemoryUpgradeCost(this.state.amt);
|
||||
}
|
||||
|
||||
const maxMemory = 100 - this.props.sleeve.memory;
|
||||
if (this.state.amt > maxMemory) { return Infinity; }
|
||||
purchaseMemory(): void {
|
||||
const cost = this.getPurchaseCost();
|
||||
if (this.props.p.canAfford(cost)) {
|
||||
this.props.sleeve.upgradeMemory(this.state.amt);
|
||||
this.props.p.loseMoney(cost);
|
||||
this.props.rerender();
|
||||
}
|
||||
}
|
||||
|
||||
return this.props.sleeve.getMemoryUpgradeCost(this.state.amt);
|
||||
render(): React.ReactNode {
|
||||
const inputId = `sleeve-${this.props.index}-memory-upgrade-input`;
|
||||
|
||||
// Memory cannot go above 100
|
||||
const maxMemory = 100 - this.props.sleeve.memory;
|
||||
|
||||
// Purchase button props
|
||||
const cost = this.getPurchaseCost();
|
||||
const purchaseBtnDisabled = !this.props.p.canAfford(cost);
|
||||
let purchaseBtnContent;
|
||||
if (isNaN(this.state.amt)) {
|
||||
purchaseBtnContent = <>Invalid value</>;
|
||||
} else if (this.state.amt > maxMemory) {
|
||||
purchaseBtnContent = <>Memory cannot exceed 100?</>;
|
||||
} else {
|
||||
purchaseBtnContent = (
|
||||
<>
|
||||
Purchase {this.state.amt} memory -{" "}
|
||||
<Money money={cost} player={this.props.p} />?
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
purchaseMemory(): void {
|
||||
const cost = this.getPurchaseCost();
|
||||
if (this.props.p.canAfford(cost)) {
|
||||
this.props.sleeve.upgradeMemory(this.state.amt);
|
||||
this.props.p.loseMoney(cost);
|
||||
this.props.rerender();
|
||||
}
|
||||
}
|
||||
return (
|
||||
<div>
|
||||
<h2>
|
||||
<u>Upgrade Memory</u>
|
||||
</h2>
|
||||
<p>
|
||||
Purchase a memory upgrade for your sleeve. Note that a sleeve's max
|
||||
memory is 100 (current:{" "}
|
||||
{numeralWrapper.formatSleeveMemory(this.props.sleeve.memory)})
|
||||
</p>
|
||||
|
||||
render(): React.ReactNode {
|
||||
const inputId = `sleeve-${this.props.index}-memory-upgrade-input`;
|
||||
|
||||
// Memory cannot go above 100
|
||||
const maxMemory = 100 - this.props.sleeve.memory;
|
||||
|
||||
// Purchase button props
|
||||
const cost = this.getPurchaseCost();
|
||||
const purchaseBtnDisabled = !this.props.p.canAfford(cost);
|
||||
let purchaseBtnContent;
|
||||
if (isNaN(this.state.amt)) {
|
||||
purchaseBtnContent = <>Invalid value</>;
|
||||
} else if (this.state.amt > maxMemory) {
|
||||
purchaseBtnContent = <>Memory cannot exceed 100?</>;
|
||||
} else {
|
||||
purchaseBtnContent = <>Purchase {this.state.amt} memory - <Money money={cost} player={this.props.p} />?</>;
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<h2><u>Upgrade Memory</u></h2>
|
||||
<p>
|
||||
Purchase a memory upgrade for your sleeve. Note that a sleeve's max memory
|
||||
is 100 (current: {numeralWrapper.formatSleeveMemory(this.props.sleeve.memory)})
|
||||
</p>
|
||||
|
||||
<label htmlFor={inputId}>
|
||||
Amount of memory to purchase (must be an integer):
|
||||
</label>
|
||||
<input className="text-input" id={inputId} onChange={this.changePurchaseAmount} type={"number"} value={this.state.amt} />
|
||||
<br />
|
||||
<StdButton disabled={purchaseBtnDisabled} onClick={this.purchaseMemory} text={purchaseBtnContent} />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
<label htmlFor={inputId}>
|
||||
Amount of memory to purchase (must be an integer):
|
||||
</label>
|
||||
<input
|
||||
className="text-input"
|
||||
id={inputId}
|
||||
onChange={this.changePurchaseAmount}
|
||||
type={"number"}
|
||||
value={this.state.amt}
|
||||
/>
|
||||
<br />
|
||||
<StdButton
|
||||
disabled={purchaseBtnDisabled}
|
||||
onClick={this.purchaseMemory}
|
||||
text={purchaseBtnContent}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,19 +10,19 @@ import { Sleeve } from "../Sleeve";
|
||||
import { IPlayer } from "../../IPlayer";
|
||||
|
||||
interface IProps {
|
||||
index: number;
|
||||
p: IPlayer;
|
||||
rerender: () => void;
|
||||
sleeve: Sleeve;
|
||||
index: number;
|
||||
p: IPlayer;
|
||||
rerender: () => void;
|
||||
sleeve: Sleeve;
|
||||
}
|
||||
|
||||
export class CovenantSleeveUpgrades extends React.Component<IProps, any> {
|
||||
render(): React.ReactNode {
|
||||
return (
|
||||
<div className={"bladeburner-action"}>
|
||||
<h1>Duplicate Sleeve {this.props.index}</h1>
|
||||
<CovenantSleeveMemoryUpgrade {...this.props} />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
render(): React.ReactNode {
|
||||
return (
|
||||
<div className={"bladeburner-action"}>
|
||||
<h1>Duplicate Sleeve {this.props.index}</h1>
|
||||
<CovenantSleeveMemoryUpgrade {...this.props} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,20 +1,31 @@
|
||||
import * as React from "react";
|
||||
|
||||
export function EarningsTableElement(title: string, stats: any[][]): React.ReactElement {
|
||||
return (<>
|
||||
<pre>{title}</pre>
|
||||
<table>
|
||||
<tbody>
|
||||
{stats.map((stat: any[], i: number) => <tr key={i}>
|
||||
{stat.map((s: any, i: number) => {
|
||||
let style = {};
|
||||
if(i !== 0) {
|
||||
style = {textAlign: "right"};
|
||||
}
|
||||
return <td style={style} key={i}>{s}</td>
|
||||
})}
|
||||
</tr>)}
|
||||
</tbody>
|
||||
</table>
|
||||
</>)
|
||||
export function EarningsTableElement(
|
||||
title: string,
|
||||
stats: any[][],
|
||||
): React.ReactElement {
|
||||
return (
|
||||
<>
|
||||
<pre>{title}</pre>
|
||||
<table>
|
||||
<tbody>
|
||||
{stats.map((stat: any[], i: number) => (
|
||||
<tr key={i}>
|
||||
{stat.map((s: any, i: number) => {
|
||||
let style = {};
|
||||
if (i !== 0) {
|
||||
style = { textAlign: "right" };
|
||||
}
|
||||
return (
|
||||
<td style={style} key={i}>
|
||||
{s}
|
||||
</td>
|
||||
);
|
||||
})}
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -5,36 +5,101 @@ import * as React from "react";
|
||||
import { StatsTable } from "../../../ui/React/StatsTable";
|
||||
|
||||
export function MoreEarningsContent(sleeve: Sleeve): React.ReactElement {
|
||||
return (<>
|
||||
{StatsTable([
|
||||
['Money ', <Money money={sleeve.earningsForTask.money} />],
|
||||
['Hacking Exp ', numeralWrapper.formatExp(sleeve.earningsForTask.hack)],
|
||||
['Strength Exp ', numeralWrapper.formatExp(sleeve.earningsForTask.str)],
|
||||
['Defense Exp ', numeralWrapper.formatExp(sleeve.earningsForTask.def)],
|
||||
['Dexterity Exp ', numeralWrapper.formatExp(sleeve.earningsForTask.dex)],
|
||||
['Agility Exp ', numeralWrapper.formatExp(sleeve.earningsForTask.agi)],
|
||||
['Charisma Exp ', numeralWrapper.formatExp(sleeve.earningsForTask.cha)],
|
||||
], 'Earnings for Current Task:')}
|
||||
<br />
|
||||
{StatsTable([
|
||||
['Money: ', <Money money={sleeve.earningsForPlayer.money} />],
|
||||
['Hacking Exp: ', numeralWrapper.formatExp(sleeve.earningsForPlayer.hack)],
|
||||
['Strength Exp: ', numeralWrapper.formatExp(sleeve.earningsForPlayer.str)],
|
||||
['Defense Exp: ', numeralWrapper.formatExp(sleeve.earningsForPlayer.def)],
|
||||
['Dexterity Exp: ', numeralWrapper.formatExp(sleeve.earningsForPlayer.dex)],
|
||||
['Agility Exp: ', numeralWrapper.formatExp(sleeve.earningsForPlayer.agi)],
|
||||
['Charisma Exp: ', numeralWrapper.formatExp(sleeve.earningsForPlayer.cha)],
|
||||
], 'Total Earnings for Host Consciousness:')}
|
||||
<br />
|
||||
{StatsTable([
|
||||
['Money: ', <Money money={sleeve.earningsForSleeves.money} />],
|
||||
['Hacking Exp: ', numeralWrapper.formatExp(sleeve.earningsForSleeves.hack)],
|
||||
['Strength Exp: ', numeralWrapper.formatExp(sleeve.earningsForSleeves.str)],
|
||||
['Defense Exp: ', numeralWrapper.formatExp(sleeve.earningsForSleeves.def)],
|
||||
['Dexterity Exp: ', numeralWrapper.formatExp(sleeve.earningsForSleeves.dex)],
|
||||
['Agility Exp: ', numeralWrapper.formatExp(sleeve.earningsForSleeves.agi)],
|
||||
['Charisma Exp: ', numeralWrapper.formatExp(sleeve.earningsForSleeves.cha)],
|
||||
], 'Total Earnings for Other Sleeves:')}
|
||||
<br />
|
||||
</>);
|
||||
}
|
||||
return (
|
||||
<>
|
||||
{StatsTable(
|
||||
[
|
||||
["Money ", <Money money={sleeve.earningsForTask.money} />],
|
||||
[
|
||||
"Hacking Exp ",
|
||||
numeralWrapper.formatExp(sleeve.earningsForTask.hack),
|
||||
],
|
||||
[
|
||||
"Strength Exp ",
|
||||
numeralWrapper.formatExp(sleeve.earningsForTask.str),
|
||||
],
|
||||
[
|
||||
"Defense Exp ",
|
||||
numeralWrapper.formatExp(sleeve.earningsForTask.def),
|
||||
],
|
||||
[
|
||||
"Dexterity Exp ",
|
||||
numeralWrapper.formatExp(sleeve.earningsForTask.dex),
|
||||
],
|
||||
[
|
||||
"Agility Exp ",
|
||||
numeralWrapper.formatExp(sleeve.earningsForTask.agi),
|
||||
],
|
||||
[
|
||||
"Charisma Exp ",
|
||||
numeralWrapper.formatExp(sleeve.earningsForTask.cha),
|
||||
],
|
||||
],
|
||||
"Earnings for Current Task:",
|
||||
)}
|
||||
<br />
|
||||
{StatsTable(
|
||||
[
|
||||
["Money: ", <Money money={sleeve.earningsForPlayer.money} />],
|
||||
[
|
||||
"Hacking Exp: ",
|
||||
numeralWrapper.formatExp(sleeve.earningsForPlayer.hack),
|
||||
],
|
||||
[
|
||||
"Strength Exp: ",
|
||||
numeralWrapper.formatExp(sleeve.earningsForPlayer.str),
|
||||
],
|
||||
[
|
||||
"Defense Exp: ",
|
||||
numeralWrapper.formatExp(sleeve.earningsForPlayer.def),
|
||||
],
|
||||
[
|
||||
"Dexterity Exp: ",
|
||||
numeralWrapper.formatExp(sleeve.earningsForPlayer.dex),
|
||||
],
|
||||
[
|
||||
"Agility Exp: ",
|
||||
numeralWrapper.formatExp(sleeve.earningsForPlayer.agi),
|
||||
],
|
||||
[
|
||||
"Charisma Exp: ",
|
||||
numeralWrapper.formatExp(sleeve.earningsForPlayer.cha),
|
||||
],
|
||||
],
|
||||
"Total Earnings for Host Consciousness:",
|
||||
)}
|
||||
<br />
|
||||
{StatsTable(
|
||||
[
|
||||
["Money: ", <Money money={sleeve.earningsForSleeves.money} />],
|
||||
[
|
||||
"Hacking Exp: ",
|
||||
numeralWrapper.formatExp(sleeve.earningsForSleeves.hack),
|
||||
],
|
||||
[
|
||||
"Strength Exp: ",
|
||||
numeralWrapper.formatExp(sleeve.earningsForSleeves.str),
|
||||
],
|
||||
[
|
||||
"Defense Exp: ",
|
||||
numeralWrapper.formatExp(sleeve.earningsForSleeves.def),
|
||||
],
|
||||
[
|
||||
"Dexterity Exp: ",
|
||||
numeralWrapper.formatExp(sleeve.earningsForSleeves.dex),
|
||||
],
|
||||
[
|
||||
"Agility Exp: ",
|
||||
numeralWrapper.formatExp(sleeve.earningsForSleeves.agi),
|
||||
],
|
||||
[
|
||||
"Charisma Exp: ",
|
||||
numeralWrapper.formatExp(sleeve.earningsForSleeves.cha),
|
||||
],
|
||||
],
|
||||
"Total Earnings for Other Sleeves:",
|
||||
)}
|
||||
<br />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -4,34 +4,117 @@ import { StatsTable } from "../../../ui/React/StatsTable";
|
||||
import * as React from "react";
|
||||
|
||||
export function MoreStatsContent(sleeve: Sleeve): React.ReactElement {
|
||||
return (<>
|
||||
{StatsTable([
|
||||
['Hacking: ', sleeve.hacking_skill, `(${numeralWrapper.formatExp(sleeve.hacking_exp)} exp)`],
|
||||
['Strength: ', sleeve.strength, `(${numeralWrapper.formatExp(sleeve.strength_exp)} exp)`],
|
||||
['Defense: ', sleeve.defense, `(${numeralWrapper.formatExp(sleeve.defense_exp)} exp)`],
|
||||
['Dexterity: ', sleeve.dexterity, `(${numeralWrapper.formatExp(sleeve.dexterity_exp)} exp)`],
|
||||
['Agility: ', sleeve.agility, `(${numeralWrapper.formatExp(sleeve.agility_exp)} exp)`],
|
||||
['Charisma: ', sleeve.charisma, `(${numeralWrapper.formatExp(sleeve.charisma_exp)} exp)`],
|
||||
], 'Stats:')}
|
||||
<br />
|
||||
{StatsTable([
|
||||
['Hacking Level multiplier: ', numeralWrapper.formatPercentage(sleeve.hacking_mult)],
|
||||
['Hacking Experience multiplier: ', numeralWrapper.formatPercentage(sleeve.hacking_exp_mult)],
|
||||
['Strength Level multiplier: ', numeralWrapper.formatPercentage(sleeve.strength_mult)],
|
||||
['Strength Experience multiplier: ', numeralWrapper.formatPercentage(sleeve.strength_exp_mult)],
|
||||
['Defense Level multiplier: ', numeralWrapper.formatPercentage(sleeve.defense_mult)],
|
||||
['Defense Experience multiplier: ', numeralWrapper.formatPercentage(sleeve.defense_exp_mult)],
|
||||
['Dexterity Level multiplier: ', numeralWrapper.formatPercentage(sleeve.dexterity_mult)],
|
||||
['Dexterity Experience multiplier: ', numeralWrapper.formatPercentage(sleeve.dexterity_exp_mult)],
|
||||
['Agility Level multiplier: ', numeralWrapper.formatPercentage(sleeve.agility_mult)],
|
||||
['Agility Experience multiplier: ', numeralWrapper.formatPercentage(sleeve.agility_exp_mult)],
|
||||
['Charisma Level multiplier: ', numeralWrapper.formatPercentage(sleeve.charisma_mult)],
|
||||
['Charisma Experience multiplier: ', numeralWrapper.formatPercentage(sleeve.charisma_exp_mult)],
|
||||
['Faction Reputation Gain multiplier: ', numeralWrapper.formatPercentage(sleeve.faction_rep_mult)],
|
||||
['Company Reputation Gain multiplier: ', numeralWrapper.formatPercentage(sleeve.company_rep_mult)],
|
||||
['Salary multiplier: ', numeralWrapper.formatPercentage(sleeve.work_money_mult)],
|
||||
['Crime Money multiplier: ', numeralWrapper.formatPercentage(sleeve.crime_money_mult)],
|
||||
['Crime Success multiplier: ', numeralWrapper.formatPercentage(sleeve.crime_success_mult)],
|
||||
], 'Multipliers:')}
|
||||
</>);
|
||||
}
|
||||
return (
|
||||
<>
|
||||
{StatsTable(
|
||||
[
|
||||
[
|
||||
"Hacking: ",
|
||||
sleeve.hacking_skill,
|
||||
`(${numeralWrapper.formatExp(sleeve.hacking_exp)} exp)`,
|
||||
],
|
||||
[
|
||||
"Strength: ",
|
||||
sleeve.strength,
|
||||
`(${numeralWrapper.formatExp(sleeve.strength_exp)} exp)`,
|
||||
],
|
||||
[
|
||||
"Defense: ",
|
||||
sleeve.defense,
|
||||
`(${numeralWrapper.formatExp(sleeve.defense_exp)} exp)`,
|
||||
],
|
||||
[
|
||||
"Dexterity: ",
|
||||
sleeve.dexterity,
|
||||
`(${numeralWrapper.formatExp(sleeve.dexterity_exp)} exp)`,
|
||||
],
|
||||
[
|
||||
"Agility: ",
|
||||
sleeve.agility,
|
||||
`(${numeralWrapper.formatExp(sleeve.agility_exp)} exp)`,
|
||||
],
|
||||
[
|
||||
"Charisma: ",
|
||||
sleeve.charisma,
|
||||
`(${numeralWrapper.formatExp(sleeve.charisma_exp)} exp)`,
|
||||
],
|
||||
],
|
||||
"Stats:",
|
||||
)}
|
||||
<br />
|
||||
{StatsTable(
|
||||
[
|
||||
[
|
||||
"Hacking Level multiplier: ",
|
||||
numeralWrapper.formatPercentage(sleeve.hacking_mult),
|
||||
],
|
||||
[
|
||||
"Hacking Experience multiplier: ",
|
||||
numeralWrapper.formatPercentage(sleeve.hacking_exp_mult),
|
||||
],
|
||||
[
|
||||
"Strength Level multiplier: ",
|
||||
numeralWrapper.formatPercentage(sleeve.strength_mult),
|
||||
],
|
||||
[
|
||||
"Strength Experience multiplier: ",
|
||||
numeralWrapper.formatPercentage(sleeve.strength_exp_mult),
|
||||
],
|
||||
[
|
||||
"Defense Level multiplier: ",
|
||||
numeralWrapper.formatPercentage(sleeve.defense_mult),
|
||||
],
|
||||
[
|
||||
"Defense Experience multiplier: ",
|
||||
numeralWrapper.formatPercentage(sleeve.defense_exp_mult),
|
||||
],
|
||||
[
|
||||
"Dexterity Level multiplier: ",
|
||||
numeralWrapper.formatPercentage(sleeve.dexterity_mult),
|
||||
],
|
||||
[
|
||||
"Dexterity Experience multiplier: ",
|
||||
numeralWrapper.formatPercentage(sleeve.dexterity_exp_mult),
|
||||
],
|
||||
[
|
||||
"Agility Level multiplier: ",
|
||||
numeralWrapper.formatPercentage(sleeve.agility_mult),
|
||||
],
|
||||
[
|
||||
"Agility Experience multiplier: ",
|
||||
numeralWrapper.formatPercentage(sleeve.agility_exp_mult),
|
||||
],
|
||||
[
|
||||
"Charisma Level multiplier: ",
|
||||
numeralWrapper.formatPercentage(sleeve.charisma_mult),
|
||||
],
|
||||
[
|
||||
"Charisma Experience multiplier: ",
|
||||
numeralWrapper.formatPercentage(sleeve.charisma_exp_mult),
|
||||
],
|
||||
[
|
||||
"Faction Reputation Gain multiplier: ",
|
||||
numeralWrapper.formatPercentage(sleeve.faction_rep_mult),
|
||||
],
|
||||
[
|
||||
"Company Reputation Gain multiplier: ",
|
||||
numeralWrapper.formatPercentage(sleeve.company_rep_mult),
|
||||
],
|
||||
[
|
||||
"Salary multiplier: ",
|
||||
numeralWrapper.formatPercentage(sleeve.work_money_mult),
|
||||
],
|
||||
[
|
||||
"Crime Money multiplier: ",
|
||||
numeralWrapper.formatPercentage(sleeve.crime_money_mult),
|
||||
],
|
||||
[
|
||||
"Crime Success multiplier: ",
|
||||
numeralWrapper.formatPercentage(sleeve.crime_success_mult),
|
||||
],
|
||||
],
|
||||
"Multipliers:",
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -3,56 +3,79 @@ import { numeralWrapper } from "../../../ui/numeralFormat";
|
||||
import * as React from "react";
|
||||
|
||||
export function StatsElement(sleeve: Sleeve): React.ReactElement {
|
||||
let style = {};
|
||||
style = { textAlign: "right" };
|
||||
return (<>
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td className="character-hp-cell">HP: </td>
|
||||
<td className="character-hp-cell" style={style}>{numeralWrapper.formatHp(sleeve.hp)} / {numeralWrapper.formatHp(sleeve.max_hp)}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>City: </td>
|
||||
<td style={style}>{sleeve.city}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="character-hack-cell">Hacking: </td>
|
||||
<td className="character-hack-cell" style={style}>{numeralWrapper.formatSkill(sleeve.hacking_skill)}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="character-combat-cell">Strength: </td>
|
||||
<td className="character-combat-cell" style={style}>{numeralWrapper.formatSkill(sleeve.strength)}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="character-combat-cell">Defense: </td>
|
||||
<td className="character-combat-cell" style={style}>{numeralWrapper.formatSkill(sleeve.defense)}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="character-combat-cell">Dexterity: </td>
|
||||
<td className="character-combat-cell" style={style}>{numeralWrapper.formatSkill(sleeve.dexterity)}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="character-combat-cell">Agility: </td>
|
||||
<td className="character-combat-cell" style={style}>{numeralWrapper.formatSkill(sleeve.agility)}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="character-cha-cell">Charisma: </td>
|
||||
<td className="character-cha-cell" style={style}>{numeralWrapper.formatSkill(sleeve.charisma)}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="character-int-cell">Shock: </td>
|
||||
<td className="character-int-cell" style={style}>{numeralWrapper.formatSleeveShock(100 - sleeve.shock)}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="character-int-cell">Sync: </td>
|
||||
<td className="character-int-cell" style={style}>{numeralWrapper.formatSleeveSynchro(sleeve.sync)}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="character-int-cell">Memory: </td>
|
||||
<td className="character-int-cell" style={style}>{numeralWrapper.formatSleeveMemory(sleeve.memory)}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</>)
|
||||
let style = {};
|
||||
style = { textAlign: "right" };
|
||||
return (
|
||||
<>
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td className="character-hp-cell">HP: </td>
|
||||
<td className="character-hp-cell" style={style}>
|
||||
{numeralWrapper.formatHp(sleeve.hp)} /{" "}
|
||||
{numeralWrapper.formatHp(sleeve.max_hp)}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>City: </td>
|
||||
<td style={style}>{sleeve.city}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="character-hack-cell">Hacking: </td>
|
||||
<td className="character-hack-cell" style={style}>
|
||||
{numeralWrapper.formatSkill(sleeve.hacking_skill)}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="character-combat-cell">Strength: </td>
|
||||
<td className="character-combat-cell" style={style}>
|
||||
{numeralWrapper.formatSkill(sleeve.strength)}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="character-combat-cell">Defense: </td>
|
||||
<td className="character-combat-cell" style={style}>
|
||||
{numeralWrapper.formatSkill(sleeve.defense)}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="character-combat-cell">Dexterity: </td>
|
||||
<td className="character-combat-cell" style={style}>
|
||||
{numeralWrapper.formatSkill(sleeve.dexterity)}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="character-combat-cell">Agility: </td>
|
||||
<td className="character-combat-cell" style={style}>
|
||||
{numeralWrapper.formatSkill(sleeve.agility)}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="character-cha-cell">Charisma: </td>
|
||||
<td className="character-cha-cell" style={style}>
|
||||
{numeralWrapper.formatSkill(sleeve.charisma)}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="character-int-cell">Shock: </td>
|
||||
<td className="character-int-cell" style={style}>
|
||||
{numeralWrapper.formatSleeveShock(100 - sleeve.shock)}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="character-int-cell">Sync: </td>
|
||||
<td className="character-int-cell" style={style}>
|
||||
{numeralWrapper.formatSleeveSynchro(sleeve.sync)}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="character-int-cell">Memory: </td>
|
||||
<td className="character-int-cell" style={style}>
|
||||
{numeralWrapper.formatSleeveMemory(sleeve.memory)}
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user