mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2025-01-08 22:37:37 +01:00
Remove resleeving from code
This commit is contained in:
parent
a70969df14
commit
c33c23700e
@ -3,7 +3,6 @@
|
||||
* Used because at the time of implementation, the PlayerObject
|
||||
* cant be converted to TypeScript.
|
||||
*/
|
||||
import { Resleeve } from "./Resleeving/Resleeve";
|
||||
import { Sleeve } from "./Sleeve/Sleeve";
|
||||
|
||||
import { IMap } from "../types";
|
||||
@ -65,7 +64,6 @@ export interface IPlayer {
|
||||
playtimeSinceLastBitnode: number;
|
||||
purchasedServers: any[];
|
||||
queuedAugmentations: IPlayerOwnedAugmentation[];
|
||||
resleeves: Resleeve[];
|
||||
scriptProdSinceLastAug: number;
|
||||
sleeves: Sleeve[];
|
||||
sleevesFromCovenant: number;
|
||||
|
@ -6,7 +6,6 @@ import * as generalMethods from "./PlayerObjectGeneralMethods";
|
||||
import * as serverMethods from "./PlayerObjectServerMethods";
|
||||
|
||||
import { IMap } from "../../types";
|
||||
import { Resleeve } from "../Resleeving/Resleeve";
|
||||
import { Sleeve } from "../Sleeve/Sleeve";
|
||||
import { IPlayerOwnedSourceFile } from "../../SourceFile/PlayerOwnedSourceFile";
|
||||
import { Exploit } from "../../Exploits/Exploit";
|
||||
@ -72,7 +71,6 @@ export class PlayerObject implements IPlayer {
|
||||
playtimeSinceLastBitnode: number;
|
||||
purchasedServers: any[];
|
||||
queuedAugmentations: IPlayerOwnedAugmentation[];
|
||||
resleeves: Resleeve[];
|
||||
scriptProdSinceLastAug: number;
|
||||
sleeves: Sleeve[];
|
||||
sleevesFromCovenant: number;
|
||||
@ -465,7 +463,6 @@ export class PlayerObject implements IPlayer {
|
||||
|
||||
// Sleeves & Re-sleeving
|
||||
this.sleeves = [];
|
||||
this.resleeves = [];
|
||||
this.sleevesFromCovenant = 0; // # of Duplicate sleeves purchased from the covenan;
|
||||
//bitnode
|
||||
this.bitNodeN = 1;
|
||||
|
@ -121,8 +121,6 @@ export function prestigeAugmentation(this: PlayerObject): void {
|
||||
|
||||
this.queuedAugmentations = [];
|
||||
|
||||
this.resleeves = [];
|
||||
|
||||
const numSleeves = Math.min(3, SourceFileFlags[10] + (this.bitNodeN === 10 ? 1 : 0)) + this.sleevesFromCovenant;
|
||||
if (this.sleeves.length > numSleeves) this.sleeves.length = numSleeves;
|
||||
for (let i = this.sleeves.length; i < numSleeves; i++) {
|
||||
|
@ -1,10 +0,0 @@
|
||||
Implements the Re-sleeving feature, which allows players to purchase a new body
|
||||
that comes with pre-existing Augmentations and experience. Note that purchasing
|
||||
a new body causes you to lose all of your old Augmentations and experience
|
||||
|
||||
This feature is introduced in BitNode-10, and destroying BitNode-10 allows
|
||||
the user to use it in other BitNodes (provided that they purchase the required
|
||||
cortical stack Augmentation)
|
||||
|
||||
While they are based on the same concept, this feature is different than the
|
||||
"Duplicate Sleeve" mechanic (which is referred to as just "Sleeve" in the source code).
|
@ -1,63 +0,0 @@
|
||||
/**
|
||||
* Implements the Resleeve class, which defines a new body
|
||||
* that the player can "re-sleeve" into.
|
||||
*/
|
||||
import { Person } from "../Person";
|
||||
|
||||
import { Augmentation } from "../../Augmentation/Augmentation";
|
||||
import { Augmentations } from "../../Augmentation/Augmentations";
|
||||
|
||||
import { Generic_fromJSON, Generic_toJSON, Reviver } from "../../utils/JSONReviver";
|
||||
|
||||
export class Resleeve extends Person {
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
|
||||
getCost(): number {
|
||||
// Each experience point adds this to the cost
|
||||
const CostPerExp = 25e3;
|
||||
|
||||
// Final cost is multiplied by this constant ^ # Augs
|
||||
const NumAugsExponent = 1.2;
|
||||
|
||||
// Get total exp in this re-sleeve
|
||||
const totalExp: number =
|
||||
this.hacking_exp +
|
||||
this.strength_exp +
|
||||
this.defense_exp +
|
||||
this.dexterity_exp +
|
||||
this.agility_exp +
|
||||
this.charisma_exp;
|
||||
|
||||
// Get total base Augmentation cost for this re-sleeve
|
||||
let totalAugmentationCost = 0;
|
||||
for (let i = 0; i < this.augmentations.length; ++i) {
|
||||
const aug: Augmentation | null = Augmentations[this.augmentations[i].name];
|
||||
if (aug == null) {
|
||||
console.error(`Could not find Augmentation ${this.augmentations[i].name}`);
|
||||
continue;
|
||||
}
|
||||
totalAugmentationCost += aug.startingCost;
|
||||
}
|
||||
|
||||
return totalExp * CostPerExp + totalAugmentationCost * Math.pow(NumAugsExponent, this.augmentations.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Serialize the current object to a JSON save state.
|
||||
*/
|
||||
toJSON(): any {
|
||||
return Generic_toJSON("Resleeve", this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initiatizes a Resleeve object from a JSON save state.
|
||||
*/
|
||||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
|
||||
static fromJSON(value: any): Resleeve {
|
||||
return Generic_fromJSON(Resleeve, value.data);
|
||||
}
|
||||
}
|
||||
|
||||
Reviver.constructors.Resleeve = Resleeve;
|
@ -1,133 +0,0 @@
|
||||
/**
|
||||
* Implements the Re-sleeving mechanic for BitNode-10.
|
||||
* This allows the player to purchase and "use" new sleeves at VitaLife.
|
||||
* These new sleeves come with different starting experience and Augmentations
|
||||
* The cost of these new sleeves scales based on the exp and Augs.
|
||||
*
|
||||
* Note that this is different from the "Sleeve mechanic". The "Sleeve" mechanic
|
||||
* provides new sleeves, essentially clones. This Re-sleeving mechanic lets
|
||||
* the player purchase a new body with pre-existing Augmentations and experience
|
||||
*
|
||||
* As of right now, this feature is only available in BitNode 10
|
||||
*/
|
||||
import { Resleeve } from "./Resleeve";
|
||||
import { IPlayer } from "../IPlayer";
|
||||
|
||||
import { Augmentation } from "../../Augmentation/Augmentation";
|
||||
import { Augmentations } from "../../Augmentation/Augmentations";
|
||||
import { IPlayerOwnedAugmentation, PlayerOwnedAugmentation } from "../../Augmentation/PlayerOwnedAugmentation";
|
||||
import { AugmentationNames } from "../../Augmentation/data/AugmentationNames";
|
||||
|
||||
import { getRandomInt } from "../../utils/helpers/getRandomInt";
|
||||
|
||||
// Executes the actual re-sleeve when one is purchased
|
||||
export function purchaseResleeve(r: Resleeve, p: IPlayer): boolean {
|
||||
const cost: number = r.getCost();
|
||||
if (!p.canAfford(cost)) {
|
||||
return false;
|
||||
}
|
||||
p.loseMoney(cost, "other");
|
||||
|
||||
// Set the player's exp
|
||||
p.hacking_exp = r.hacking_exp;
|
||||
p.strength_exp = r.strength_exp;
|
||||
p.defense_exp = r.defense_exp;
|
||||
p.dexterity_exp = r.dexterity_exp;
|
||||
p.agility_exp = r.agility_exp;
|
||||
p.charisma_exp = r.charisma_exp;
|
||||
|
||||
// Reset Augmentation "owned" data
|
||||
for (const augKey of Object.keys(Augmentations)) {
|
||||
Augmentations[augKey].owned = false;
|
||||
}
|
||||
|
||||
// Clear all of the player's augmentations, except the NeuroFlux Governor
|
||||
// which is kept
|
||||
for (let i = p.augmentations.length - 1; i >= 0; --i) {
|
||||
if (p.augmentations[i].name !== AugmentationNames.NeuroFluxGovernor) {
|
||||
p.augmentations.splice(i, 1);
|
||||
} else {
|
||||
// NeuroFlux Governor
|
||||
Augmentations[AugmentationNames.NeuroFluxGovernor].owned = true;
|
||||
}
|
||||
}
|
||||
|
||||
for (let i = 0; i < r.augmentations.length; ++i) {
|
||||
p.augmentations.push(new PlayerOwnedAugmentation(r.augmentations[i].name));
|
||||
Augmentations[r.augmentations[i].name].owned = true;
|
||||
}
|
||||
|
||||
// The player's purchased Augmentations should remain the same, but any purchased
|
||||
// Augmentations that are given by the resleeve should be removed so there are no duplicates
|
||||
for (let i = p.queuedAugmentations.length - 1; i >= 0; --i) {
|
||||
const name: string = p.queuedAugmentations[i].name;
|
||||
|
||||
if (
|
||||
p.augmentations.filter((e: IPlayerOwnedAugmentation) => {
|
||||
return e.name !== AugmentationNames.NeuroFluxGovernor && e.name === name;
|
||||
}).length >= 1
|
||||
) {
|
||||
p.queuedAugmentations.splice(i, 1);
|
||||
}
|
||||
}
|
||||
|
||||
p.reapplyAllAugmentations(true);
|
||||
p.reapplyAllSourceFiles(); //Multipliers get reset, so have to re-process source files too
|
||||
return true;
|
||||
}
|
||||
|
||||
// Creates all of the Re-sleeves that will be available for purchase at VitaLife
|
||||
export function generateResleeves(): Resleeve[] {
|
||||
const NumResleeves = 40; // Total number of Resleeves to generate
|
||||
|
||||
const ret: Resleeve[] = [];
|
||||
for (let i = 0; i < NumResleeves; ++i) {
|
||||
// i will be a number indicating how "powerful" the Re-sleeve should be
|
||||
const r: Resleeve = new Resleeve();
|
||||
|
||||
// Generate experience
|
||||
const expMult: number = 5 * i + 1;
|
||||
r.hacking_exp = expMult * getRandomInt(1000, 5000);
|
||||
r.strength_exp = expMult * getRandomInt(1000, 5000);
|
||||
r.defense_exp = expMult * getRandomInt(1000, 5000);
|
||||
r.dexterity_exp = expMult * getRandomInt(1000, 5000);
|
||||
r.agility_exp = expMult * getRandomInt(1000, 5000);
|
||||
r.charisma_exp = expMult * getRandomInt(1000, 5000);
|
||||
|
||||
// Generate Augs
|
||||
// Augmentation prequisites will be ignored for this
|
||||
const baseNumAugs: number = Math.max(2, Math.ceil((i + 3) / 2));
|
||||
const numAugs: number = getRandomInt(baseNumAugs, baseNumAugs + 2);
|
||||
const augKeys: string[] = Object.keys(Augmentations);
|
||||
for (let a = 0; a < numAugs; ++a) {
|
||||
// Get a random aug
|
||||
const randIndex: number = getRandomInt(0, augKeys.length - 1);
|
||||
const randKey: string = augKeys[randIndex];
|
||||
|
||||
// Forbidden augmentations
|
||||
const forbidden = [
|
||||
AugmentationNames.TheRedPill,
|
||||
AugmentationNames.NeuroFluxGovernor,
|
||||
AugmentationNames.StaneksGift1,
|
||||
AugmentationNames.StaneksGift2,
|
||||
AugmentationNames.StaneksGift3,
|
||||
];
|
||||
if (forbidden.includes(randKey)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const randAug: Augmentation | null = Augmentations[randKey];
|
||||
if (randAug === null) throw new Error(`null augmentation: ${randKey}`);
|
||||
r.augmentations.push({ name: randAug.name, level: 1 });
|
||||
r.applyAugmentation(Augmentations[randKey]);
|
||||
r.updateStatLevels();
|
||||
|
||||
// Remove Augmentation so that there are no duplicates
|
||||
augKeys.splice(randIndex, 1);
|
||||
}
|
||||
|
||||
ret.push(r);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
@ -1,166 +0,0 @@
|
||||
import React, { useState } from "react";
|
||||
import { IPlayer } from "../../IPlayer";
|
||||
import { Resleeve } from "../Resleeve";
|
||||
import { Augmentations } from "../../../Augmentation/Augmentations";
|
||||
import { purchaseResleeve } from "../Resleeving";
|
||||
import { Money } from "../../../ui/React/Money";
|
||||
|
||||
import { numeralWrapper } from "../../../ui/numeralFormat";
|
||||
import { dialogBoxCreate } from "../../../ui/React/DialogBox";
|
||||
|
||||
import Typography from "@mui/material/Typography";
|
||||
import Paper from "@mui/material/Paper";
|
||||
import Button from "@mui/material/Button";
|
||||
import Select, { SelectChangeEvent } from "@mui/material/Select";
|
||||
import MenuItem from "@mui/material/MenuItem";
|
||||
import Grid from "@mui/material/Grid";
|
||||
|
||||
interface IProps {
|
||||
resleeve: Resleeve;
|
||||
player: IPlayer;
|
||||
}
|
||||
|
||||
export function ResleeveElem(props: IProps): React.ReactElement {
|
||||
const [aug, setAug] = useState(props.resleeve.augmentations[0].name);
|
||||
|
||||
function openStats(): void {
|
||||
dialogBoxCreate(
|
||||
<>
|
||||
<Typography variant="h5" color="primary">
|
||||
Total Multipliers:
|
||||
</Typography>
|
||||
<Typography>
|
||||
Hacking Level multiplier: {numeralWrapper.formatPercentage(props.resleeve.hacking_mult)}
|
||||
<br />
|
||||
Hacking Experience multiplier: {numeralWrapper.formatPercentage(props.resleeve.hacking_exp_mult)}
|
||||
<br />
|
||||
Strength Level multiplier: {numeralWrapper.formatPercentage(props.resleeve.strength_mult)}
|
||||
<br />
|
||||
Strength Experience multiplier: {numeralWrapper.formatPercentage(props.resleeve.strength_exp_mult)}
|
||||
<br />
|
||||
Defense Level multiplier: {numeralWrapper.formatPercentage(props.resleeve.defense_mult)}
|
||||
<br />
|
||||
Defense Experience multiplier: {numeralWrapper.formatPercentage(props.resleeve.defense_exp_mult)}
|
||||
<br />
|
||||
Dexterity Level multiplier: {numeralWrapper.formatPercentage(props.resleeve.dexterity_mult)}
|
||||
<br />
|
||||
Dexterity Experience multiplier: {numeralWrapper.formatPercentage(props.resleeve.dexterity_exp_mult)}
|
||||
<br />
|
||||
Agility Level multiplier: {numeralWrapper.formatPercentage(props.resleeve.agility_mult)}
|
||||
<br />
|
||||
Agility Experience multiplier: {numeralWrapper.formatPercentage(props.resleeve.agility_exp_mult)}
|
||||
<br />
|
||||
Charisma Level multiplier: {numeralWrapper.formatPercentage(props.resleeve.charisma_mult)}
|
||||
<br />
|
||||
Charisma Experience multiplier: {numeralWrapper.formatPercentage(props.resleeve.charisma_exp_mult)}
|
||||
<br />
|
||||
Hacking Chance multiplier: {numeralWrapper.formatPercentage(props.resleeve.hacking_chance_mult)}
|
||||
<br />
|
||||
Hacking Speed multiplier: {numeralWrapper.formatPercentage(props.resleeve.hacking_speed_mult)}
|
||||
<br />
|
||||
Hacking Money multiplier: {numeralWrapper.formatPercentage(props.resleeve.hacking_money_mult)}
|
||||
<br />
|
||||
Hacking Growth multiplier: {numeralWrapper.formatPercentage(props.resleeve.hacking_grow_mult)}
|
||||
<br />
|
||||
Salary multiplier: {numeralWrapper.formatPercentage(props.resleeve.work_money_mult)}
|
||||
<br />
|
||||
Company Reputation Gain multiplier: {numeralWrapper.formatPercentage(props.resleeve.company_rep_mult)}
|
||||
<br />
|
||||
Faction Reputation Gain multiplier: {numeralWrapper.formatPercentage(props.resleeve.faction_rep_mult)}
|
||||
<br />
|
||||
Crime Money multiplier: {numeralWrapper.formatPercentage(props.resleeve.crime_money_mult)}
|
||||
<br />
|
||||
Crime Success multiplier: {numeralWrapper.formatPercentage(props.resleeve.crime_success_mult)}
|
||||
<br />
|
||||
Hacknet Income multiplier: {numeralWrapper.formatPercentage(props.resleeve.hacknet_node_money_mult)}
|
||||
<br />
|
||||
Hacknet Purchase Cost multiplier:
|
||||
{numeralWrapper.formatPercentage(props.resleeve.hacknet_node_purchase_cost_mult)}
|
||||
<br />
|
||||
Hacknet Level Upgrade Cost multiplier:
|
||||
{numeralWrapper.formatPercentage(props.resleeve.hacknet_node_level_cost_mult)}
|
||||
<br />
|
||||
Hacknet Ram Upgrade Cost multiplier:
|
||||
{numeralWrapper.formatPercentage(props.resleeve.hacknet_node_ram_cost_mult)}
|
||||
<br />
|
||||
Hacknet Core Upgrade Cost multiplier:
|
||||
{numeralWrapper.formatPercentage(props.resleeve.hacknet_node_core_cost_mult)}
|
||||
<br />
|
||||
Bladeburner Max Stamina multiplier:
|
||||
{numeralWrapper.formatPercentage(props.resleeve.bladeburner_max_stamina_mult)}
|
||||
<br />
|
||||
Bladeburner Stamina Gain multiplier:
|
||||
{numeralWrapper.formatPercentage(props.resleeve.bladeburner_stamina_gain_mult)}
|
||||
<br />
|
||||
Bladeburner Field Analysis multiplier:
|
||||
{numeralWrapper.formatPercentage(props.resleeve.bladeburner_analysis_mult)}
|
||||
<br />
|
||||
Bladeburner Success Chance multiplier:
|
||||
{numeralWrapper.formatPercentage(props.resleeve.bladeburner_success_chance_mult)}
|
||||
</Typography>
|
||||
</>,
|
||||
);
|
||||
}
|
||||
|
||||
function onAugChange(event: SelectChangeEvent<string>): void {
|
||||
setAug(event.target.value);
|
||||
}
|
||||
|
||||
const currentAug = Augmentations[aug];
|
||||
const cost = props.resleeve.getCost();
|
||||
|
||||
function purchase(): void {
|
||||
if (!purchaseResleeve(props.resleeve, props.player)) return;
|
||||
dialogBoxCreate(
|
||||
<>
|
||||
You re-sleeved for <Money money={cost} />!
|
||||
</>,
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<Paper sx={{ my: 1 }}>
|
||||
<Grid container>
|
||||
<Grid item xs={3}>
|
||||
<Typography>
|
||||
Hacking: {numeralWrapper.formatSkill(props.resleeve.hacking)} (
|
||||
{numeralWrapper.formatExp(props.resleeve.hacking_exp)} exp)
|
||||
<br />
|
||||
Strength: {numeralWrapper.formatSkill(props.resleeve.strength)} (
|
||||
{numeralWrapper.formatExp(props.resleeve.strength_exp)} exp)
|
||||
<br />
|
||||
Defense: {numeralWrapper.formatSkill(props.resleeve.defense)} (
|
||||
{numeralWrapper.formatExp(props.resleeve.defense_exp)} exp)
|
||||
<br />
|
||||
Dexterity: {numeralWrapper.formatSkill(props.resleeve.dexterity)} (
|
||||
{numeralWrapper.formatExp(props.resleeve.dexterity_exp)} exp)
|
||||
<br />
|
||||
Agility: {numeralWrapper.formatSkill(props.resleeve.agility)} (
|
||||
{numeralWrapper.formatExp(props.resleeve.agility_exp)} exp)
|
||||
<br />
|
||||
Charisma: {numeralWrapper.formatSkill(props.resleeve.charisma)} (
|
||||
{numeralWrapper.formatExp(props.resleeve.charisma_exp)} exp)
|
||||
<br /># Augmentations: {props.resleeve.augmentations.length}
|
||||
</Typography>
|
||||
<Button onClick={openStats}>Multipliers</Button>
|
||||
</Grid>
|
||||
<Grid item xs={6}>
|
||||
<Select value={aug} onChange={onAugChange}>
|
||||
{props.resleeve.augmentations.map((aug) => (
|
||||
<MenuItem key={aug.name} value={aug.name}>
|
||||
{aug.name}
|
||||
</MenuItem>
|
||||
))}
|
||||
</Select>
|
||||
<Typography>{currentAug !== undefined && currentAug.info}</Typography>
|
||||
</Grid>
|
||||
<Grid item xs={3}>
|
||||
<Typography>
|
||||
It costs <Money money={cost} player={props.player} /> to purchase this Sleeve.
|
||||
</Typography>
|
||||
<Button onClick={purchase}>Purchase</Button>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Paper>
|
||||
);
|
||||
}
|
@ -1,124 +0,0 @@
|
||||
import React, { useState } from "react";
|
||||
|
||||
import { generateResleeves } from "../Resleeving";
|
||||
import { Resleeve } from "../Resleeve";
|
||||
import { ResleeveElem } from "./ResleeveElem";
|
||||
import { use } from "../../../ui/Context";
|
||||
import Typography from "@mui/material/Typography";
|
||||
import Select, { SelectChangeEvent } from "@mui/material/Select";
|
||||
import MenuItem from "@mui/material/MenuItem";
|
||||
import Box from "@mui/material/Box";
|
||||
|
||||
const SortOption: {
|
||||
[key: string]: string | undefined;
|
||||
Cost: string;
|
||||
Hacking: string;
|
||||
Strength: string;
|
||||
Defense: string;
|
||||
Dexterity: string;
|
||||
Agility: string;
|
||||
Charisma: string;
|
||||
AverageCombatStats: string;
|
||||
AverageAllStats: string;
|
||||
TotalNumAugmentations: string;
|
||||
} = {
|
||||
Cost: "Cost",
|
||||
Hacking: "Hacking Level",
|
||||
Strength: "Strength Level",
|
||||
Defense: "Defense Level",
|
||||
Dexterity: "Dexterity Level",
|
||||
Agility: "Agility Level",
|
||||
Charisma: "Charisma Level",
|
||||
AverageCombatStats: "Average Combat Stats",
|
||||
AverageAllStats: "Average Stats",
|
||||
TotalNumAugmentations: "Number of Augmentations",
|
||||
};
|
||||
|
||||
// Helper function for averaging
|
||||
function getAverage(...values: number[]): number {
|
||||
let sum = 0;
|
||||
for (let i = 0; i < values.length; ++i) {
|
||||
sum += values[i];
|
||||
}
|
||||
|
||||
return sum / values.length;
|
||||
}
|
||||
|
||||
const SortFunctions: {
|
||||
[key: string]: ((a: Resleeve, b: Resleeve) => number) | undefined;
|
||||
Cost: (a: Resleeve, b: Resleeve) => number;
|
||||
Hacking: (a: Resleeve, b: Resleeve) => number;
|
||||
Strength: (a: Resleeve, b: Resleeve) => number;
|
||||
Defense: (a: Resleeve, b: Resleeve) => number;
|
||||
Dexterity: (a: Resleeve, b: Resleeve) => number;
|
||||
Agility: (a: Resleeve, b: Resleeve) => number;
|
||||
Charisma: (a: Resleeve, b: Resleeve) => number;
|
||||
AverageCombatStats: (a: Resleeve, b: Resleeve) => number;
|
||||
AverageAllStats: (a: Resleeve, b: Resleeve) => number;
|
||||
TotalNumAugmentations: (a: Resleeve, b: Resleeve) => number;
|
||||
} = {
|
||||
Cost: (a: Resleeve, b: Resleeve): number => a.getCost() - b.getCost(),
|
||||
Hacking: (a: Resleeve, b: Resleeve): number => a.hacking - b.hacking,
|
||||
Strength: (a: Resleeve, b: Resleeve): number => a.strength - b.strength,
|
||||
Defense: (a: Resleeve, b: Resleeve): number => a.defense - b.defense,
|
||||
Dexterity: (a: Resleeve, b: Resleeve): number => a.dexterity - b.dexterity,
|
||||
Agility: (a: Resleeve, b: Resleeve): number => a.agility - b.agility,
|
||||
Charisma: (a: Resleeve, b: Resleeve): number => a.charisma - b.charisma,
|
||||
AverageCombatStats: (a: Resleeve, b: Resleeve): number =>
|
||||
getAverage(a.strength, a.defense, a.dexterity, a.agility) -
|
||||
getAverage(b.strength, b.defense, b.dexterity, b.agility),
|
||||
AverageAllStats: (a: Resleeve, b: Resleeve): number =>
|
||||
getAverage(a.hacking, a.strength, a.defense, a.dexterity, a.agility, a.charisma) -
|
||||
getAverage(b.hacking, b.strength, b.defense, b.dexterity, b.agility, b.charisma),
|
||||
TotalNumAugmentations: (a: Resleeve, b: Resleeve): number => a.augmentations.length - b.augmentations.length,
|
||||
};
|
||||
|
||||
export function ResleeveRoot(): React.ReactElement {
|
||||
const player = use.Player();
|
||||
const [sort, setSort] = useState(SortOption.Cost);
|
||||
// Randomly create all Resleeves if they dont already exist
|
||||
if (player.resleeves.length === 0) {
|
||||
player.resleeves = generateResleeves();
|
||||
}
|
||||
|
||||
function onSortChange(event: SelectChangeEvent<string>): void {
|
||||
setSort(event.target.value);
|
||||
}
|
||||
|
||||
const sortFunction = SortFunctions[sort];
|
||||
if (sortFunction === undefined) throw new Error(`sort function '${sort}' is undefined`);
|
||||
player.resleeves.sort(sortFunction);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Typography>
|
||||
Re-sleeving is the process of digitizing and transferring your consciousness into a new human body, or 'sleeve'.
|
||||
Here at VitaLife, you can purchase new specially-engineered bodies for the re-sleeve process. Many of these
|
||||
bodies even come with genetic and cybernetic Augmentations!
|
||||
<br />
|
||||
<br />
|
||||
Re-sleeving will change your experience for every stat. It will also REMOVE all of your currently-installed
|
||||
Augmentations, and replace them with the ones provided by the purchased sleeve. However, Augmentations that you
|
||||
have purchased but not installed will NOT be removed. If you have purchased an Augmentation and then re-sleeve
|
||||
into a body which already has that Augmentation, it will be removed (since you cannot have duplicate
|
||||
Augmentations).
|
||||
<br />
|
||||
<br />
|
||||
NOTE: The stats and multipliers displayed on this page do NOT include your bonuses from Source-File.
|
||||
</Typography>
|
||||
<Box display="flex" alignItems="center">
|
||||
<Typography>Sort By: </Typography>
|
||||
<Select value={sort} onChange={onSortChange}>
|
||||
{Object.keys(SortOption).map((opt) => (
|
||||
<MenuItem key={opt} value={opt}>
|
||||
{SortOption[opt]}
|
||||
</MenuItem>
|
||||
))}
|
||||
</Select>
|
||||
</Box>
|
||||
{player.resleeves.map((resleeve, i) => (
|
||||
<ResleeveElem key={i} player={player} resleeve={resleeve} />
|
||||
))}
|
||||
</>
|
||||
);
|
||||
}
|
Loading…
Reference in New Issue
Block a user