mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2024-11-22 15:43:49 +01:00
Sleeve UI improvements.
This commit is contained in:
parent
29ea1281e0
commit
c9fe8d9b65
70
package-lock.json
generated
70
package-lock.json
generated
@ -1,11 +1,11 @@
|
||||
{
|
||||
"name": "bitburner",
|
||||
"version": "0.47.3",
|
||||
"version": "0.49.2",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"version": "0.47.3",
|
||||
"version": "0.49.2",
|
||||
"hasInstallScript": true,
|
||||
"license": "SEE LICENSE IN license.txt",
|
||||
"dependencies": {
|
||||
@ -38,6 +38,7 @@
|
||||
"numeral": "2.0.6",
|
||||
"react": "^16.8.3",
|
||||
"react-dom": "^16.8.3",
|
||||
"react-modal": "^3.12.1",
|
||||
"sprintf-js": "^1.1.1",
|
||||
"tapable": "^1.0.0",
|
||||
"uuid": "^3.2.1",
|
||||
@ -4571,6 +4572,11 @@
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/exenv": {
|
||||
"version": "1.2.2",
|
||||
"resolved": "https://registry.npmjs.org/exenv/-/exenv-1.2.2.tgz",
|
||||
"integrity": "sha1-KueOhdmJQVhnCwPUe+wfA72Ru50="
|
||||
},
|
||||
"node_modules/exit": {
|
||||
"version": "0.1.2",
|
||||
"resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz",
|
||||
@ -11779,6 +11785,29 @@
|
||||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.8.3.tgz",
|
||||
"integrity": "sha512-Y4rC1ZJmsxxkkPuMLwvKvlL1Zfpbcu+Bf4ZigkHup3v9EfdYhAlWAaVyA19olXq2o2mGn0w+dFKvk3pVVlYcIA=="
|
||||
},
|
||||
"node_modules/react-lifecycles-compat": {
|
||||
"version": "3.0.4",
|
||||
"resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz",
|
||||
"integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA=="
|
||||
},
|
||||
"node_modules/react-modal": {
|
||||
"version": "3.12.1",
|
||||
"resolved": "https://registry.npmjs.org/react-modal/-/react-modal-3.12.1.tgz",
|
||||
"integrity": "sha512-WGuXn7Fq31PbFJwtWmOk+jFtGC7E9tJVbFX0lts8ZoS5EPi9+WWylUJWLKKVm3H4GlQ7ZxY7R6tLlbSIBQ5oZA==",
|
||||
"dependencies": {
|
||||
"exenv": "^1.2.0",
|
||||
"prop-types": "^15.5.10",
|
||||
"react-lifecycles-compat": "^3.0.0",
|
||||
"warning": "^4.0.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "^0.14.0 || ^15.0.0 || ^16 || ^17",
|
||||
"react-dom": "^0.14.0 || ^15.0.0 || ^16 || ^17"
|
||||
}
|
||||
},
|
||||
"node_modules/readable-stream": {
|
||||
"version": "2.3.4",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.4.tgz",
|
||||
@ -15999,6 +16028,14 @@
|
||||
"xml-name-validator": "3.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/warning": {
|
||||
"version": "4.0.3",
|
||||
"resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz",
|
||||
"integrity": "sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==",
|
||||
"dependencies": {
|
||||
"loose-envify": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/watchpack": {
|
||||
"version": "1.6.0",
|
||||
"resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.6.0.tgz",
|
||||
@ -21422,6 +21459,11 @@
|
||||
"clone-regexp": "1.0.1"
|
||||
}
|
||||
},
|
||||
"exenv": {
|
||||
"version": "1.2.2",
|
||||
"resolved": "https://registry.npmjs.org/exenv/-/exenv-1.2.2.tgz",
|
||||
"integrity": "sha1-KueOhdmJQVhnCwPUe+wfA72Ru50="
|
||||
},
|
||||
"exit": {
|
||||
"version": "0.1.2",
|
||||
"resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz",
|
||||
@ -27426,6 +27468,22 @@
|
||||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.8.3.tgz",
|
||||
"integrity": "sha512-Y4rC1ZJmsxxkkPuMLwvKvlL1Zfpbcu+Bf4ZigkHup3v9EfdYhAlWAaVyA19olXq2o2mGn0w+dFKvk3pVVlYcIA=="
|
||||
},
|
||||
"react-lifecycles-compat": {
|
||||
"version": "3.0.4",
|
||||
"resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz",
|
||||
"integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA=="
|
||||
},
|
||||
"react-modal": {
|
||||
"version": "3.12.1",
|
||||
"resolved": "https://registry.npmjs.org/react-modal/-/react-modal-3.12.1.tgz",
|
||||
"integrity": "sha512-WGuXn7Fq31PbFJwtWmOk+jFtGC7E9tJVbFX0lts8ZoS5EPi9+WWylUJWLKKVm3H4GlQ7ZxY7R6tLlbSIBQ5oZA==",
|
||||
"requires": {
|
||||
"exenv": "^1.2.0",
|
||||
"prop-types": "^15.5.10",
|
||||
"react-lifecycles-compat": "^3.0.0",
|
||||
"warning": "^4.0.3"
|
||||
}
|
||||
},
|
||||
"readable-stream": {
|
||||
"version": "2.3.4",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.4.tgz",
|
||||
@ -31040,6 +31098,14 @@
|
||||
"xml-name-validator": "3.0.0"
|
||||
}
|
||||
},
|
||||
"warning": {
|
||||
"version": "4.0.3",
|
||||
"resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz",
|
||||
"integrity": "sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==",
|
||||
"requires": {
|
||||
"loose-envify": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"watchpack": {
|
||||
"version": "1.6.0",
|
||||
"resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.6.0.tgz",
|
||||
|
@ -35,6 +35,7 @@
|
||||
"numeral": "2.0.6",
|
||||
"react": "^16.8.3",
|
||||
"react-dom": "^16.8.3",
|
||||
"react-modal": "^3.12.1",
|
||||
"sprintf-js": "^1.1.1",
|
||||
"tapable": "^1.0.0",
|
||||
"uuid": "^3.2.1",
|
||||
|
@ -41,6 +41,9 @@ import { removeElementById } from "../../../utils/uiHelpers/removeElementById";
|
||||
|
||||
import { EarningsTableElement } from "./ui/EarningsTableElement";
|
||||
import { StatsElement } from "./ui/StatsElement";
|
||||
import { MoreStatsContent } from "./ui/MoreStatsContent";
|
||||
import { MoreEarningsContent } from "./ui/MoreEarningsContent";
|
||||
import * as React from "react";
|
||||
import * as ReactDOM from "react-dom";
|
||||
|
||||
// Object that keeps track of all DOM elements for the UI for a single Sleeve
|
||||
@ -100,8 +103,8 @@ export function createSleevesPage(p: IPlayer) {
|
||||
class: "sleeves-page-info",
|
||||
innerHTML: "<h1>Sleeves</h1>Duplicate Sleeves are MK-V Synthoids (synthetic androids) into which your " +
|
||||
"consciousness has been copied. In other words, these Synthoids contain " +
|
||||
"a perfect duplicate of your mind.<br><br>" +
|
||||
"Sleeves can be used to perform different tasks synchronously.<br><br>",
|
||||
"a perfect duplicate of your mind.<br /><br />" +
|
||||
"Sleeves can be used to perform different tasks synchronously.<br /><br />",
|
||||
});
|
||||
|
||||
UIElems.faqButton = createElement("button", {
|
||||
@ -163,7 +166,7 @@ export function clearSleevesPage() {
|
||||
}
|
||||
|
||||
for (const prop in UIElems) {
|
||||
(<any>UIElems)[prop] = null;
|
||||
(UIElems as any)[prop] = null;
|
||||
}
|
||||
|
||||
playerRef = null;
|
||||
@ -204,35 +207,7 @@ function createSleeveUi(sleeve: Sleeve, allSleeves: Sleeve[]): ISleeveUIElems {
|
||||
class: "std-button",
|
||||
innerText: "More Stats",
|
||||
clickListener: () => {
|
||||
dialogBoxCreate(
|
||||
[
|
||||
"<h2><u>Stats:</u></h2>",
|
||||
`Hacking: ${sleeve.hacking_skill} (${numeralWrapper.formatBigNumber(sleeve.hacking_exp)} exp)`,
|
||||
`Strength: ${sleeve.strength} (${numeralWrapper.formatBigNumber(sleeve.strength_exp)} exp)`,
|
||||
`Defense: ${sleeve.defense} (${numeralWrapper.formatBigNumber(sleeve.defense_exp)} exp)`,
|
||||
`Dexterity: ${sleeve.dexterity} (${numeralWrapper.formatBigNumber(sleeve.dexterity_exp)} exp)`,
|
||||
`Agility: ${sleeve.agility} (${numeralWrapper.formatBigNumber(sleeve.agility_exp)} exp)`,
|
||||
`Charisma: ${sleeve.charisma} (${numeralWrapper.formatBigNumber(sleeve.charisma_exp)} exp)<br>`,
|
||||
"<h2><u>Multipliers:</u></h2>",
|
||||
`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)}`,
|
||||
].join("<br>"), false
|
||||
);
|
||||
dialogBoxCreate(MoreStatsContent(sleeve));
|
||||
}
|
||||
});
|
||||
elems.travelButton = createElement("button", {
|
||||
@ -261,7 +236,7 @@ function createSleeveUi(sleeve: Sleeve, allSleeves: Sleeve[]): ISleeveUIElems {
|
||||
dialogBoxCreate("You cannot afford to have this sleeve travel to another city", false);
|
||||
return false;
|
||||
}
|
||||
sleeve.city = <CityName>cityName;
|
||||
sleeve.city = cityName as CityName;
|
||||
playerRef!.loseMoney(CONSTANTS.TravelCost);
|
||||
sleeve.resetTaskStatus();
|
||||
removeElementById(popupId);
|
||||
@ -332,34 +307,7 @@ function createSleeveUi(sleeve: Sleeve, allSleeves: Sleeve[]): ISleeveUIElems {
|
||||
class: "std-button",
|
||||
innerText: "More Earnings Info",
|
||||
clickListener: () => {
|
||||
dialogBoxCreate(
|
||||
[
|
||||
"<h2><u>Earnings for Current Task:</u></h2>",
|
||||
`Money: ${numeralWrapper.formatMoney(sleeve.earningsForTask.money)}`,
|
||||
`Hacking Exp: ${numeralWrapper.formatBigNumber(sleeve.earningsForTask.hack)}`,
|
||||
`Strength Exp: ${numeralWrapper.formatBigNumber(sleeve.earningsForTask.str)}`,
|
||||
`Defense Exp: ${numeralWrapper.formatBigNumber(sleeve.earningsForTask.def)}`,
|
||||
`Dexterity Exp: ${numeralWrapper.formatBigNumber(sleeve.earningsForTask.dex)}`,
|
||||
`Agility Exp: ${numeralWrapper.formatBigNumber(sleeve.earningsForTask.agi)}`,
|
||||
`Charisma Exp: ${numeralWrapper.formatBigNumber(sleeve.earningsForTask.cha)}<br>`,
|
||||
"<h2><u>Total Earnings for Host Consciousness:</u></h2>",
|
||||
`Money: ${numeralWrapper.formatMoney(sleeve.earningsForPlayer.money)}`,
|
||||
`Hacking Exp: ${numeralWrapper.formatBigNumber(sleeve.earningsForPlayer.hack)}`,
|
||||
`Strength Exp: ${numeralWrapper.formatBigNumber(sleeve.earningsForPlayer.str)}`,
|
||||
`Defense Exp: ${numeralWrapper.formatBigNumber(sleeve.earningsForPlayer.def)}`,
|
||||
`Dexterity Exp: ${numeralWrapper.formatBigNumber(sleeve.earningsForPlayer.dex)}`,
|
||||
`Agility Exp: ${numeralWrapper.formatBigNumber(sleeve.earningsForPlayer.agi)}`,
|
||||
`Charisma Exp: ${numeralWrapper.formatBigNumber(sleeve.earningsForPlayer.cha)}<br>`,
|
||||
"<h2><u>Total Earnings for Other Sleeves:</u></h2>",
|
||||
`Money: ${numeralWrapper.formatMoney(sleeve.earningsForSleeves.money)}`,
|
||||
`Hacking Exp: ${numeralWrapper.formatBigNumber(sleeve.earningsForSleeves.hack)}`,
|
||||
`Strength Exp: ${numeralWrapper.formatBigNumber(sleeve.earningsForSleeves.str)}`,
|
||||
`Defense Exp: ${numeralWrapper.formatBigNumber(sleeve.earningsForSleeves.def)}`,
|
||||
`Dexterity Exp: ${numeralWrapper.formatBigNumber(sleeve.earningsForSleeves.dex)}`,
|
||||
`Agility Exp: ${numeralWrapper.formatBigNumber(sleeve.earningsForSleeves.agi)}`,
|
||||
`Charisma Exp: ${numeralWrapper.formatBigNumber(sleeve.earningsForSleeves.cha)}`,
|
||||
].join("<br>"), false
|
||||
);
|
||||
dialogBoxCreate(MoreEarningsContent(sleeve));
|
||||
}
|
||||
});
|
||||
|
||||
@ -383,13 +331,13 @@ function updateSleeveUi(sleeve: Sleeve, elems: ISleeveUIElems) {
|
||||
|
||||
if (sleeve.currentTask === SleeveTaskType.Crime) {
|
||||
const data = [
|
||||
[`Money`, `${numeralWrapper.formatMoney(parseFloat(sleeve.currentTaskLocation))}`, `(on success)`],
|
||||
[`Hacking Exp`, `${numeralWrapper.format(sleeve.gainRatesForTask.hack, "0.00")}`, `(2x on success)`],
|
||||
[`Strength Exp`, `${numeralWrapper.format(sleeve.gainRatesForTask.str, "0.00")}`, `(2x on success)`],
|
||||
[`Defense Exp`, `${numeralWrapper.format(sleeve.gainRatesForTask.def, "0.00")}`, `(2x on success)`],
|
||||
[`Dexterity Exp`, `${numeralWrapper.format(sleeve.gainRatesForTask.dex, "0.00")}`, `(2x on success)`],
|
||||
[`Agility Exp`, `${numeralWrapper.format(sleeve.gainRatesForTask.agi, "0.00")}`, `(2x on success)`],
|
||||
[`Charisma Exp`, `${numeralWrapper.format(sleeve.gainRatesForTask.cha, "0.00")}`, `(2x on success)`]
|
||||
[`Money`, numeralWrapper.formatMoney(parseFloat(sleeve.currentTaskLocation)), `(on success)`],
|
||||
[`Hacking Exp`, numeralWrapper.format(sleeve.gainRatesForTask.hack, "0.00"), `(2x on success)`],
|
||||
[`Strength Exp`, numeralWrapper.format(sleeve.gainRatesForTask.str, "0.00"), `(2x on success)`],
|
||||
[`Defense Exp`, numeralWrapper.format(sleeve.gainRatesForTask.def, "0.00"), `(2x on success)`],
|
||||
[`Dexterity Exp`, numeralWrapper.format(sleeve.gainRatesForTask.dex, "0.00"), `(2x on success)`],
|
||||
[`Agility Exp`, numeralWrapper.format(sleeve.gainRatesForTask.agi, "0.00"), `(2x on success)`],
|
||||
[`Charisma Exp`, numeralWrapper.format(sleeve.gainRatesForTask.cha, "0.00"), `(2x on success)`]
|
||||
];
|
||||
ReactDOM.render(EarningsTableElement('Earnings (Pre-Synchronization)', data), elems.currentEarningsInfo!)
|
||||
|
@ -1,57 +0,0 @@
|
||||
export const SleeveFaq: string =
|
||||
[
|
||||
"<strong><u>How do Duplicate Sleeves work?</strong></u><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)?</strong></u><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><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."
|
||||
].join(" ");
|
80
src/PersonObjects/Sleeve/data/SleeveFaq.tsx
Normal file
80
src/PersonObjects/Sleeve/data/SleeveFaq.tsx
Normal file
@ -0,0 +1,80 @@
|
||||
import * as React from "react";
|
||||
|
||||
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>
|
||||
<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>
|
||||
<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,7 +2,7 @@ import * as React from "react";
|
||||
|
||||
export function EarningsTableElement(title: string, stats: any[][]): React.ReactElement {
|
||||
return (<>
|
||||
{title}
|
||||
<pre>{title}</pre>
|
||||
<table>
|
||||
<tbody>
|
||||
{stats.map((stat: any[], i: number) => <tr key={i}>
|
||||
|
41
src/PersonObjects/Sleeve/ui/MoreEarningsContent.tsx
Normal file
41
src/PersonObjects/Sleeve/ui/MoreEarningsContent.tsx
Normal file
@ -0,0 +1,41 @@
|
||||
import { Sleeve } from "../Sleeve";
|
||||
import { numeralWrapper } from "../../../ui/numeralFormat";
|
||||
import * as React from "react";
|
||||
import { StatsTable } from "../../../ui/React/StatsTable";
|
||||
|
||||
export function MoreEarningsContent(sleeve: Sleeve): React.ReactElement {
|
||||
let style = {}
|
||||
style = {textAlign: 'right'};
|
||||
return (<>
|
||||
{StatsTable([
|
||||
['Money ', numeralWrapper.formatMoney(sleeve.earningsForTask.money)],
|
||||
['Hacking Exp ', numeralWrapper.formatBigNumber(sleeve.earningsForTask.hack)],
|
||||
['Strength Exp ', numeralWrapper.formatBigNumber(sleeve.earningsForTask.str)],
|
||||
['Defense Exp ', numeralWrapper.formatBigNumber(sleeve.earningsForTask.def)],
|
||||
['Dexterity Exp ', numeralWrapper.formatBigNumber(sleeve.earningsForTask.dex)],
|
||||
['Agility Exp ', numeralWrapper.formatBigNumber(sleeve.earningsForTask.agi)],
|
||||
['Charisma Exp ', numeralWrapper.formatBigNumber(sleeve.earningsForTask.cha)],
|
||||
], 'Earnings for Current Task:')}
|
||||
<br />
|
||||
{StatsTable([
|
||||
['Money: ', numeralWrapper.formatMoney(sleeve.earningsForPlayer.money)],
|
||||
['Hacking Exp: ', numeralWrapper.formatBigNumber(sleeve.earningsForPlayer.hack)],
|
||||
['Strength Exp: ', numeralWrapper.formatBigNumber(sleeve.earningsForPlayer.str)],
|
||||
['Defense Exp: ', numeralWrapper.formatBigNumber(sleeve.earningsForPlayer.def)],
|
||||
['Dexterity Exp: ', numeralWrapper.formatBigNumber(sleeve.earningsForPlayer.dex)],
|
||||
['Agility Exp: ', numeralWrapper.formatBigNumber(sleeve.earningsForPlayer.agi)],
|
||||
['Charisma Exp: ', numeralWrapper.formatBigNumber(sleeve.earningsForPlayer.cha)],
|
||||
], 'Total Earnings for Host Consciousness:')}
|
||||
<br />
|
||||
{StatsTable([
|
||||
['Money: ', numeralWrapper.formatMoney(sleeve.earningsForSleeves.money)],
|
||||
['Hacking Exp: ', numeralWrapper.formatBigNumber(sleeve.earningsForSleeves.hack)],
|
||||
['Strength Exp: ', numeralWrapper.formatBigNumber(sleeve.earningsForSleeves.str)],
|
||||
['Defense Exp: ', numeralWrapper.formatBigNumber(sleeve.earningsForSleeves.def)],
|
||||
['Dexterity Exp: ', numeralWrapper.formatBigNumber(sleeve.earningsForSleeves.dex)],
|
||||
['Agility Exp: ', numeralWrapper.formatBigNumber(sleeve.earningsForSleeves.agi)],
|
||||
['Charisma Exp: ', numeralWrapper.formatBigNumber(sleeve.earningsForSleeves.cha)],
|
||||
], 'Total Earnings for Other Sleeves:')}
|
||||
<br />
|
||||
</>);
|
||||
}
|
39
src/PersonObjects/Sleeve/ui/MoreStatsContent.tsx
Normal file
39
src/PersonObjects/Sleeve/ui/MoreStatsContent.tsx
Normal file
@ -0,0 +1,39 @@
|
||||
import { Sleeve } from "../Sleeve";
|
||||
import { numeralWrapper } from "../../../ui/numeralFormat";
|
||||
import { StatsTable } from "../../../ui/React/StatsTable";
|
||||
import * as React from "react";
|
||||
|
||||
export function MoreStatsContent(sleeve: Sleeve): React.ReactElement {
|
||||
let style = {}
|
||||
style = {textAlign: 'right'};
|
||||
return (<>
|
||||
{StatsTable([
|
||||
['Hacking: ', sleeve.hacking_skill, `(${numeralWrapper.formatBigNumber(sleeve.hacking_exp)} exp)`],
|
||||
['Strength: ', sleeve.strength, `(${numeralWrapper.formatBigNumber(sleeve.strength_exp)} exp)`],
|
||||
['Defense: ', sleeve.defense, `(${numeralWrapper.formatBigNumber(sleeve.defense_exp)} exp)`],
|
||||
['Dexterity: ', sleeve.dexterity, `(${numeralWrapper.formatBigNumber(sleeve.dexterity_exp)} exp)`],
|
||||
['Agility: ', sleeve.agility, `(${numeralWrapper.formatBigNumber(sleeve.agility_exp)} exp)`],
|
||||
['Charisma: ', sleeve.charisma, `(${numeralWrapper.formatBigNumber(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:')}
|
||||
</>);
|
||||
}
|
24
src/ui/React/StatsTable.tsx
Normal file
24
src/ui/React/StatsTable.tsx
Normal file
@ -0,0 +1,24 @@
|
||||
import * as React from "react";
|
||||
|
||||
export function StatsTable(rows: any[][], title: string | null): React.ReactElement {
|
||||
let titleElem = <></>
|
||||
if (title) {
|
||||
titleElem = <><h2><u>{title}</u></h2><br /></>;
|
||||
}
|
||||
return (<>
|
||||
{titleElem}
|
||||
<table>
|
||||
<tbody>
|
||||
{rows.map((row: any[]) => {
|
||||
return <tr key={row[0]}>
|
||||
{row.map((elem: any, i: number) => {
|
||||
let style = {};
|
||||
if (i !== 0) style = {textAlign: 'right'};
|
||||
return <td key={i} style={style}>{elem}</td>
|
||||
})}
|
||||
</tr>
|
||||
})}
|
||||
</tbody>
|
||||
</table>
|
||||
</>);
|
||||
}
|
2
utils/DialogBox.d.ts
vendored
2
utils/DialogBox.d.ts
vendored
@ -1,2 +1,2 @@
|
||||
export function dialogBoxCreate(txt: string, preformatted?: boolean): void;
|
||||
export function dialogBoxCreate(txt: string | JSX.Element, preformatted?: boolean): void;
|
||||
export var dialogBoxOpened: boolean;
|
||||
|
@ -1,4 +1,7 @@
|
||||
import { KEY } from "./helpers/keyCodes";
|
||||
import { DialogBox } from "./ui/DialogBox";
|
||||
import React from "react";
|
||||
import ReactDOM from "react-dom";
|
||||
|
||||
/**
|
||||
* Create and display a pop-up dialog box.
|
||||
@ -41,32 +44,24 @@ document.addEventListener("keydown", function (event) {
|
||||
|
||||
let dialogBoxOpened = false;
|
||||
|
||||
|
||||
|
||||
function dialogBoxCreate(txt, preformatted=false) {
|
||||
var container = document.createElement("div");
|
||||
const container = document.createElement("div");
|
||||
container.setAttribute("class", "dialog-box-container");
|
||||
|
||||
var content = document.createElement("div");
|
||||
content.setAttribute("class", "dialog-box-content");
|
||||
|
||||
var closeButton = document.createElement("span");
|
||||
closeButton.setAttribute("class", "dialog-box-close-button");
|
||||
closeButton.innerHTML = "×"
|
||||
|
||||
var textE;
|
||||
if (preformatted) {
|
||||
// For text files as they are often computed data that
|
||||
// shouldn't be wrapped and should retain tabstops.
|
||||
textE = document.createElement("pre");
|
||||
textE.innerHTML = txt;
|
||||
} else {
|
||||
textE = document.createElement("p");
|
||||
textE.innerHTML = txt.replace(/(?:\r\n|\r|\n)/g, '<br>');
|
||||
let elem = txt;
|
||||
if (typeof txt === 'string') {
|
||||
if (preformatted) {
|
||||
// For text files as they are often computed data that
|
||||
// shouldn't be wrapped and should retain tabstops.
|
||||
elem = <pre dangerouslySetInnerHTML={{ __html: txt }} />
|
||||
} else {
|
||||
elem = <p dangerouslySetInnerHTML={{ __html: txt.replace(/(?:\r\n|\r|\n)/g, '<br />') }} />
|
||||
}
|
||||
}
|
||||
|
||||
content.appendChild(closeButton);
|
||||
content.appendChild(textE);
|
||||
container.appendChild(content);
|
||||
|
||||
ReactDOM.render(DialogBox(elem), container);
|
||||
document.body.appendChild(container);
|
||||
if (dialogBoxes.length >= 1) {
|
||||
container.style.visibility = "hidden";
|
8
utils/ui/DialogBox.tsx
Normal file
8
utils/ui/DialogBox.tsx
Normal file
@ -0,0 +1,8 @@
|
||||
import * as React from "react";
|
||||
|
||||
export function DialogBox(content: HTMLElement): React.ReactElement {
|
||||
return (<div className="dialog-box-content text">
|
||||
<span className="dialog-box-close-button ">×</span>
|
||||
{content}
|
||||
</div>);
|
||||
}
|
Loading…
Reference in New Issue
Block a user