mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2026-04-24 18:22:58 +02:00
fix sleeve memory bug
This commit is contained in:
@@ -146,10 +146,7 @@ export interface IPlayer {
|
||||
getGangFaction(): Faction;
|
||||
getGangName(): string;
|
||||
getHomeComputer(): Server;
|
||||
getNextCompanyPosition(
|
||||
company: Company,
|
||||
entryPosType: CompanyPosition,
|
||||
): CompanyPosition;
|
||||
getNextCompanyPosition(company: Company, entryPosType: CompanyPosition): CompanyPosition;
|
||||
getUpgradeHomeRamCost(): number;
|
||||
gotoLocation(to: LocationName): boolean;
|
||||
hasCorporation(): boolean;
|
||||
|
||||
@@ -114,9 +114,7 @@ export abstract class Person {
|
||||
applyAugmentation(aug: Augmentation): void {
|
||||
for (const mult in aug.mults) {
|
||||
if ((this as any)[mult] == null) {
|
||||
console.warn(
|
||||
`Augmentation has unrecognized multiplier property: ${mult}`,
|
||||
);
|
||||
console.warn(`Augmentation has unrecognized multiplier property: ${mult}`);
|
||||
} else {
|
||||
(this as any)[mult] *= aug.mults[mult];
|
||||
}
|
||||
@@ -153,9 +151,7 @@ export abstract class Person {
|
||||
* when doing Hacking Work for a faction
|
||||
*/
|
||||
getFactionHackingWorkRepGain(): number {
|
||||
return (
|
||||
(this.hacking_skill / CONSTANTS.MaxSkillLevel) * this.faction_rep_mult
|
||||
);
|
||||
return (this.hacking_skill / CONSTANTS.MaxSkillLevel) * this.faction_rep_mult;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -207,56 +203,32 @@ export abstract class Person {
|
||||
updateStatLevels(): void {
|
||||
this.hacking_skill = Math.max(
|
||||
1,
|
||||
Math.floor(
|
||||
this.calculateStat(
|
||||
this.hacking_exp,
|
||||
this.hacking_mult * BitNodeMultipliers.HackingLevelMultiplier,
|
||||
),
|
||||
),
|
||||
Math.floor(this.calculateStat(this.hacking_exp, this.hacking_mult * BitNodeMultipliers.HackingLevelMultiplier)),
|
||||
);
|
||||
this.strength = Math.max(
|
||||
1,
|
||||
Math.floor(
|
||||
this.calculateStat(
|
||||
this.strength_exp,
|
||||
this.strength_mult * BitNodeMultipliers.StrengthLevelMultiplier,
|
||||
),
|
||||
this.calculateStat(this.strength_exp, this.strength_mult * BitNodeMultipliers.StrengthLevelMultiplier),
|
||||
),
|
||||
);
|
||||
this.defense = Math.max(
|
||||
1,
|
||||
Math.floor(
|
||||
this.calculateStat(
|
||||
this.defense_exp,
|
||||
this.defense_mult * BitNodeMultipliers.DefenseLevelMultiplier,
|
||||
),
|
||||
),
|
||||
Math.floor(this.calculateStat(this.defense_exp, this.defense_mult * BitNodeMultipliers.DefenseLevelMultiplier)),
|
||||
);
|
||||
this.dexterity = Math.max(
|
||||
1,
|
||||
Math.floor(
|
||||
this.calculateStat(
|
||||
this.dexterity_exp,
|
||||
this.dexterity_mult * BitNodeMultipliers.DexterityLevelMultiplier,
|
||||
),
|
||||
this.calculateStat(this.dexterity_exp, this.dexterity_mult * BitNodeMultipliers.DexterityLevelMultiplier),
|
||||
),
|
||||
);
|
||||
this.agility = Math.max(
|
||||
1,
|
||||
Math.floor(
|
||||
this.calculateStat(
|
||||
this.agility_exp,
|
||||
this.agility_mult * BitNodeMultipliers.AgilityLevelMultiplier,
|
||||
),
|
||||
),
|
||||
Math.floor(this.calculateStat(this.agility_exp, this.agility_mult * BitNodeMultipliers.AgilityLevelMultiplier)),
|
||||
);
|
||||
this.charisma = Math.max(
|
||||
1,
|
||||
Math.floor(
|
||||
this.calculateStat(
|
||||
this.charisma_exp,
|
||||
this.charisma_mult * BitNodeMultipliers.CharismaLevelMultiplier,
|
||||
),
|
||||
this.calculateStat(this.charisma_exp, this.charisma_mult * BitNodeMultipliers.CharismaLevelMultiplier),
|
||||
),
|
||||
);
|
||||
|
||||
|
||||
@@ -9,11 +9,7 @@ import { HashManager } from "../../Hacknet/HashManager";
|
||||
import { CityName } from "../../Locations/data/CityNames";
|
||||
|
||||
import { MoneySourceTracker } from "../../utils/MoneySourceTracker";
|
||||
import {
|
||||
Reviver,
|
||||
Generic_toJSON,
|
||||
Generic_fromJSON,
|
||||
} from "../../../utils/JSONReviver";
|
||||
import { Reviver, Generic_toJSON, Generic_fromJSON } from "../../../utils/JSONReviver";
|
||||
|
||||
import Decimal from "decimal.js";
|
||||
|
||||
|
||||
@@ -5,10 +5,7 @@ import { IPlayer } from "../IPlayer";
|
||||
|
||||
import { Augmentation } from "../../Augmentation/Augmentation";
|
||||
|
||||
export function hasAugmentation(
|
||||
this: IPlayer,
|
||||
aug: string | Augmentation,
|
||||
): boolean {
|
||||
export function hasAugmentation(this: IPlayer, aug: string | Augmentation): boolean {
|
||||
const augName: string = aug instanceof Augmentation ? aug.name : aug;
|
||||
|
||||
for (const owned of this.augmentations) {
|
||||
|
||||
@@ -6,12 +6,7 @@ export function canAccessBladeburner() {
|
||||
return false;
|
||||
}
|
||||
|
||||
return (
|
||||
this.bitNodeN === 6 ||
|
||||
this.bitNodeN === 7 ||
|
||||
SourceFileFlags[6] > 0 ||
|
||||
SourceFileFlags[7] > 0
|
||||
);
|
||||
return this.bitNodeN === 6 || this.bitNodeN === 7 || SourceFileFlags[6] > 0 || SourceFileFlags[7] > 0;
|
||||
}
|
||||
|
||||
export function inBladeburner() {
|
||||
|
||||
@@ -14,9 +14,7 @@ export function canAccessGang() {
|
||||
return false;
|
||||
}
|
||||
|
||||
return (
|
||||
this.karma <= BitNodeMultipliers.GangKarmaRequirement * GangKarmaRequirement
|
||||
);
|
||||
return this.karma <= BitNodeMultipliers.GangKarmaRequirement * GangKarmaRequirement;
|
||||
}
|
||||
|
||||
export function getGangFaction() {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -8,11 +8,7 @@ import { CONSTANTS } from "../../Constants";
|
||||
import { BitNodeMultipliers } from "../../BitNode/BitNodeMultipliers";
|
||||
import { Server } from "../../Server/Server";
|
||||
import { HacknetServer } from "../../Hacknet/HacknetServer";
|
||||
import {
|
||||
AddToAllServers,
|
||||
AllServers,
|
||||
createUniqueRandomIp,
|
||||
} from "../../Server/AllServers";
|
||||
import { AddToAllServers, AllServers, createUniqueRandomIp } from "../../Server/AllServers";
|
||||
import { SpecialServerIps } from "../../Server/SpecialServerIps";
|
||||
|
||||
export function hasTorRouter(this: IPlayer): boolean {
|
||||
@@ -35,11 +31,7 @@ export function getUpgradeHomeRamCost(this: IPlayer): number {
|
||||
//Calculate cost
|
||||
//Have cost increase by some percentage each time RAM has been upgraded
|
||||
const mult = Math.pow(1.58, numUpgrades);
|
||||
const cost =
|
||||
currentRam *
|
||||
CONSTANTS.BaseCostFor1GBOfRamHome *
|
||||
mult *
|
||||
BitNodeMultipliers.HomeComputerRamCost;
|
||||
const cost = currentRam * CONSTANTS.BaseCostFor1GBOfRamHome * mult * BitNodeMultipliers.HomeComputerRamCost;
|
||||
return cost;
|
||||
}
|
||||
|
||||
|
||||
@@ -7,11 +7,7 @@ import { Person } from "../Person";
|
||||
import { Augmentation } from "../../Augmentation/Augmentation";
|
||||
import { Augmentations } from "../../Augmentation/Augmentations";
|
||||
|
||||
import {
|
||||
Generic_fromJSON,
|
||||
Generic_toJSON,
|
||||
Reviver,
|
||||
} from "../../../utils/JSONReviver";
|
||||
import { Generic_fromJSON, Generic_toJSON, Reviver } from "../../../utils/JSONReviver";
|
||||
|
||||
export class Resleeve extends Person {
|
||||
constructor() {
|
||||
@@ -37,22 +33,15 @@ export class Resleeve extends Person {
|
||||
// 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];
|
||||
const aug: Augmentation | null = Augmentations[this.augmentations[i].name];
|
||||
if (aug == null) {
|
||||
console.error(
|
||||
`Could not find Augmentation ${this.augmentations[i].name}`,
|
||||
);
|
||||
console.error(`Could not find Augmentation ${this.augmentations[i].name}`);
|
||||
continue;
|
||||
}
|
||||
totalAugmentationCost += aug.startingCost;
|
||||
}
|
||||
|
||||
return (
|
||||
totalExp * CostPerExp +
|
||||
totalAugmentationCost *
|
||||
Math.pow(NumAugsExponent, this.augmentations.length)
|
||||
);
|
||||
return totalExp * CostPerExp + totalAugmentationCost * Math.pow(NumAugsExponent, this.augmentations.length);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -15,10 +15,7 @@ import { IPlayer } from "../IPlayer";
|
||||
|
||||
import { Augmentation } from "../../Augmentation/Augmentation";
|
||||
import { Augmentations } from "../../Augmentation/Augmentations";
|
||||
import {
|
||||
IPlayerOwnedAugmentation,
|
||||
PlayerOwnedAugmentation,
|
||||
} from "../../Augmentation/PlayerOwnedAugmentation";
|
||||
import { IPlayerOwnedAugmentation, PlayerOwnedAugmentation } from "../../Augmentation/PlayerOwnedAugmentation";
|
||||
import { AugmentationNames } from "../../Augmentation/data/AugmentationNames";
|
||||
|
||||
import { getRandomInt } from "../../../utils/helpers/getRandomInt";
|
||||
@@ -67,9 +64,7 @@ export function purchaseResleeve(r: Resleeve, p: IPlayer): boolean {
|
||||
|
||||
if (
|
||||
p.augmentations.filter((e: IPlayerOwnedAugmentation) => {
|
||||
return (
|
||||
e.name !== AugmentationNames.NeuroFluxGovernor && e.name === name
|
||||
);
|
||||
return e.name !== AugmentationNames.NeuroFluxGovernor && e.name === name;
|
||||
}).length >= 1
|
||||
) {
|
||||
p.queuedAugmentations.splice(i, 1);
|
||||
@@ -110,10 +105,7 @@ export function generateResleeves(): Resleeve[] {
|
||||
const randKey: string = augKeys[randIndex];
|
||||
|
||||
// Forbidden augmentations
|
||||
if (
|
||||
randKey === AugmentationNames.TheRedPill ||
|
||||
randKey === AugmentationNames.NeuroFluxGovernor
|
||||
) {
|
||||
if (randKey === AugmentationNames.TheRedPill || randKey === AugmentationNames.NeuroFluxGovernor) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
@@ -119,39 +119,15 @@ export function createResleevesPage(p: IPlayer): void {
|
||||
}
|
||||
|
||||
UIElems.sortSelector.add(createOptionElement("Cost", SortOption.Cost));
|
||||
UIElems.sortSelector.add(
|
||||
createOptionElement("Hacking Level", SortOption.Hacking),
|
||||
);
|
||||
UIElems.sortSelector.add(
|
||||
createOptionElement("Strength Level", SortOption.Strength),
|
||||
);
|
||||
UIElems.sortSelector.add(
|
||||
createOptionElement("Defense Level", SortOption.Defense),
|
||||
);
|
||||
UIElems.sortSelector.add(
|
||||
createOptionElement("Dexterity Level", SortOption.Dexterity),
|
||||
);
|
||||
UIElems.sortSelector.add(
|
||||
createOptionElement("Agility Level", SortOption.Agility),
|
||||
);
|
||||
UIElems.sortSelector.add(
|
||||
createOptionElement("Charisma Level", SortOption.Charisma),
|
||||
);
|
||||
UIElems.sortSelector.add(
|
||||
createOptionElement(
|
||||
"Average Combat Stats",
|
||||
SortOption.AverageCombatStats,
|
||||
),
|
||||
);
|
||||
UIElems.sortSelector.add(
|
||||
createOptionElement("Average Stats", SortOption.AverageAllStats),
|
||||
);
|
||||
UIElems.sortSelector.add(
|
||||
createOptionElement(
|
||||
"Number of Augmentations",
|
||||
SortOption.TotalNumAugmentations,
|
||||
),
|
||||
);
|
||||
UIElems.sortSelector.add(createOptionElement("Hacking Level", SortOption.Hacking));
|
||||
UIElems.sortSelector.add(createOptionElement("Strength Level", SortOption.Strength));
|
||||
UIElems.sortSelector.add(createOptionElement("Defense Level", SortOption.Defense));
|
||||
UIElems.sortSelector.add(createOptionElement("Dexterity Level", SortOption.Dexterity));
|
||||
UIElems.sortSelector.add(createOptionElement("Agility Level", SortOption.Agility));
|
||||
UIElems.sortSelector.add(createOptionElement("Charisma Level", SortOption.Charisma));
|
||||
UIElems.sortSelector.add(createOptionElement("Average Combat Stats", SortOption.AverageCombatStats));
|
||||
UIElems.sortSelector.add(createOptionElement("Average Stats", SortOption.AverageAllStats));
|
||||
UIElems.sortSelector.add(createOptionElement("Number of Augmentations", SortOption.TotalNumAugmentations));
|
||||
|
||||
UIElems.resleeveList = createElement("ul");
|
||||
UIElems.sortSelector.onchange = () => {
|
||||
@@ -202,40 +178,16 @@ export function createResleevesPage(p: IPlayer): void {
|
||||
break;
|
||||
case SortOption.AverageCombatStats:
|
||||
p.resleeves.sort((a, b) => {
|
||||
const aAvg = getAverage(
|
||||
a.strength,
|
||||
a.defense,
|
||||
a.dexterity,
|
||||
a.agility,
|
||||
);
|
||||
const bAvg = getAverage(
|
||||
b.strength,
|
||||
b.defense,
|
||||
b.dexterity,
|
||||
b.agility,
|
||||
);
|
||||
const aAvg = getAverage(a.strength, a.defense, a.dexterity, a.agility);
|
||||
const bAvg = getAverage(b.strength, b.defense, b.dexterity, b.agility);
|
||||
|
||||
return aAvg - bAvg;
|
||||
});
|
||||
break;
|
||||
case SortOption.AverageAllStats:
|
||||
p.resleeves.sort((a, b) => {
|
||||
const aAvg = getAverage(
|
||||
a.hacking_skill,
|
||||
a.strength,
|
||||
a.defense,
|
||||
a.dexterity,
|
||||
a.agility,
|
||||
a.charisma,
|
||||
);
|
||||
const bAvg = getAverage(
|
||||
b.hacking_skill,
|
||||
b.strength,
|
||||
b.defense,
|
||||
b.dexterity,
|
||||
b.agility,
|
||||
b.charisma,
|
||||
);
|
||||
const aAvg = getAverage(a.hacking_skill, a.strength, a.defense, a.dexterity, a.agility, a.charisma);
|
||||
const bAvg = getAverage(b.hacking_skill, b.strength, b.defense, b.dexterity, b.agility, b.charisma);
|
||||
|
||||
return aAvg - bAvg;
|
||||
});
|
||||
@@ -253,18 +205,13 @@ export function createResleevesPage(p: IPlayer): void {
|
||||
break;
|
||||
}
|
||||
|
||||
if (UIElems.resleeveList == null)
|
||||
throw new Error("UIElems.resleeveList is null in sortSelector.click()");
|
||||
if (UIElems.resleeves == null)
|
||||
throw new Error("UIElems.resleeves is null in sortSelector.click()");
|
||||
if (UIElems.resleeveList == null) throw new Error("UIElems.resleeveList is null in sortSelector.click()");
|
||||
if (UIElems.resleeves == null) throw new Error("UIElems.resleeves is null in sortSelector.click()");
|
||||
|
||||
// Create UI for all Resleeves
|
||||
for (const resleeve of p.resleeves) {
|
||||
const resleeveUi = createResleeveUi(resleeve);
|
||||
if (resleeveUi.container == null)
|
||||
throw new Error(
|
||||
"resleeveUi.container is null in sortSelector.click()",
|
||||
);
|
||||
if (resleeveUi.container == null) throw new Error("resleeveUi.container is null in sortSelector.click()");
|
||||
UIElems.resleeveList.appendChild(resleeveUi.container);
|
||||
UIElems.resleeves.push(resleeveUi);
|
||||
}
|
||||
@@ -278,10 +225,7 @@ export function createResleevesPage(p: IPlayer): void {
|
||||
UIElems.container.appendChild(UIElems.resleeveList);
|
||||
|
||||
const container = document.getElementById("entire-game-container");
|
||||
if (container == null)
|
||||
throw new Error(
|
||||
"Could not find entire-game-container in createResleevesPage()",
|
||||
);
|
||||
if (container == null) throw new Error("Could not find entire-game-container in createResleevesPage()");
|
||||
container.appendChild(UIElems.container);
|
||||
} catch (e) {
|
||||
exceptionAlert(e);
|
||||
@@ -331,24 +275,24 @@ function createResleeveUi(resleeve: Resleeve): IResleeveUIElems {
|
||||
elems.stats = createElement("p", {
|
||||
class: "resleeve-stats-text",
|
||||
innerHTML:
|
||||
`Hacking: ${numeralWrapper.formatSkill(
|
||||
resleeve.hacking_skill,
|
||||
)} (${numeralWrapper.formatExp(resleeve.hacking_exp)} exp)<br />` +
|
||||
`Strength: ${numeralWrapper.formatSkill(
|
||||
resleeve.strength,
|
||||
)} (${numeralWrapper.formatExp(resleeve.strength_exp)} exp)<br />` +
|
||||
`Defense: ${numeralWrapper.formatSkill(
|
||||
resleeve.defense,
|
||||
)} (${numeralWrapper.formatExp(resleeve.defense_exp)} exp)<br />` +
|
||||
`Dexterity: ${numeralWrapper.formatSkill(
|
||||
resleeve.dexterity,
|
||||
)} (${numeralWrapper.formatExp(resleeve.dexterity_exp)} exp)<br />` +
|
||||
`Agility: ${numeralWrapper.formatSkill(
|
||||
resleeve.agility,
|
||||
)} (${numeralWrapper.formatExp(resleeve.agility_exp)} exp)<br />` +
|
||||
`Charisma: ${numeralWrapper.formatSkill(
|
||||
resleeve.charisma,
|
||||
)} (${numeralWrapper.formatExp(resleeve.charisma_exp)} exp)<br />` +
|
||||
`Hacking: ${numeralWrapper.formatSkill(resleeve.hacking_skill)} (${numeralWrapper.formatExp(
|
||||
resleeve.hacking_exp,
|
||||
)} exp)<br />` +
|
||||
`Strength: ${numeralWrapper.formatSkill(resleeve.strength)} (${numeralWrapper.formatExp(
|
||||
resleeve.strength_exp,
|
||||
)} exp)<br />` +
|
||||
`Defense: ${numeralWrapper.formatSkill(resleeve.defense)} (${numeralWrapper.formatExp(
|
||||
resleeve.defense_exp,
|
||||
)} exp)<br />` +
|
||||
`Dexterity: ${numeralWrapper.formatSkill(resleeve.dexterity)} (${numeralWrapper.formatExp(
|
||||
resleeve.dexterity_exp,
|
||||
)} exp)<br />` +
|
||||
`Agility: ${numeralWrapper.formatSkill(resleeve.agility)} (${numeralWrapper.formatExp(
|
||||
resleeve.agility_exp,
|
||||
)} exp)<br />` +
|
||||
`Charisma: ${numeralWrapper.formatSkill(resleeve.charisma)} (${numeralWrapper.formatExp(
|
||||
resleeve.charisma_exp,
|
||||
)} exp)<br />` +
|
||||
`# Augmentations: ${resleeve.augmentations.length}`,
|
||||
});
|
||||
elems.multipliersButton = createElement("button", {
|
||||
@@ -358,72 +302,28 @@ function createResleeveUi(resleeve: Resleeve): IResleeveUIElems {
|
||||
dialogBoxCreate(
|
||||
[
|
||||
"<h2><u>Total Multipliers:</u></h2>",
|
||||
`Hacking Level multiplier: ${numeralWrapper.formatPercentage(
|
||||
resleeve.hacking_mult,
|
||||
)}`,
|
||||
`Hacking Experience multiplier: ${numeralWrapper.formatPercentage(
|
||||
resleeve.hacking_exp_mult,
|
||||
)}`,
|
||||
`Strength Level multiplier: ${numeralWrapper.formatPercentage(
|
||||
resleeve.strength_mult,
|
||||
)}`,
|
||||
`Strength Experience multiplier: ${numeralWrapper.formatPercentage(
|
||||
resleeve.strength_exp_mult,
|
||||
)}`,
|
||||
`Defense Level multiplier: ${numeralWrapper.formatPercentage(
|
||||
resleeve.defense_mult,
|
||||
)}`,
|
||||
`Defense Experience multiplier: ${numeralWrapper.formatPercentage(
|
||||
resleeve.defense_exp_mult,
|
||||
)}`,
|
||||
`Dexterity Level multiplier: ${numeralWrapper.formatPercentage(
|
||||
resleeve.dexterity_mult,
|
||||
)}`,
|
||||
`Dexterity Experience multiplier: ${numeralWrapper.formatPercentage(
|
||||
resleeve.dexterity_exp_mult,
|
||||
)}`,
|
||||
`Agility Level multiplier: ${numeralWrapper.formatPercentage(
|
||||
resleeve.agility_mult,
|
||||
)}`,
|
||||
`Agility Experience multiplier: ${numeralWrapper.formatPercentage(
|
||||
resleeve.agility_exp_mult,
|
||||
)}`,
|
||||
`Charisma Level multiplier: ${numeralWrapper.formatPercentage(
|
||||
resleeve.charisma_mult,
|
||||
)}`,
|
||||
`Charisma Experience multiplier: ${numeralWrapper.formatPercentage(
|
||||
resleeve.charisma_exp_mult,
|
||||
)}`,
|
||||
`Hacking Chance multiplier: ${numeralWrapper.formatPercentage(
|
||||
resleeve.hacking_chance_mult,
|
||||
)}`,
|
||||
`Hacking Speed multiplier: ${numeralWrapper.formatPercentage(
|
||||
resleeve.hacking_speed_mult,
|
||||
)}`,
|
||||
`Hacking Money multiplier: ${numeralWrapper.formatPercentage(
|
||||
resleeve.hacking_money_mult,
|
||||
)}`,
|
||||
`Hacking Growth multiplier: ${numeralWrapper.formatPercentage(
|
||||
resleeve.hacking_grow_mult,
|
||||
)}`,
|
||||
`Salary multiplier: ${numeralWrapper.formatPercentage(
|
||||
resleeve.work_money_mult,
|
||||
)}`,
|
||||
`Company Reputation Gain multiplier: ${numeralWrapper.formatPercentage(
|
||||
resleeve.company_rep_mult,
|
||||
)}`,
|
||||
`Faction Reputation Gain multiplier: ${numeralWrapper.formatPercentage(
|
||||
resleeve.faction_rep_mult,
|
||||
)}`,
|
||||
`Crime Money multiplier: ${numeralWrapper.formatPercentage(
|
||||
resleeve.crime_money_mult,
|
||||
)}`,
|
||||
`Crime Success multiplier: ${numeralWrapper.formatPercentage(
|
||||
resleeve.crime_success_mult,
|
||||
)}`,
|
||||
`Hacknet Income multiplier: ${numeralWrapper.formatPercentage(
|
||||
resleeve.hacknet_node_money_mult,
|
||||
)}`,
|
||||
`Hacking Level multiplier: ${numeralWrapper.formatPercentage(resleeve.hacking_mult)}`,
|
||||
`Hacking Experience multiplier: ${numeralWrapper.formatPercentage(resleeve.hacking_exp_mult)}`,
|
||||
`Strength Level multiplier: ${numeralWrapper.formatPercentage(resleeve.strength_mult)}`,
|
||||
`Strength Experience multiplier: ${numeralWrapper.formatPercentage(resleeve.strength_exp_mult)}`,
|
||||
`Defense Level multiplier: ${numeralWrapper.formatPercentage(resleeve.defense_mult)}`,
|
||||
`Defense Experience multiplier: ${numeralWrapper.formatPercentage(resleeve.defense_exp_mult)}`,
|
||||
`Dexterity Level multiplier: ${numeralWrapper.formatPercentage(resleeve.dexterity_mult)}`,
|
||||
`Dexterity Experience multiplier: ${numeralWrapper.formatPercentage(resleeve.dexterity_exp_mult)}`,
|
||||
`Agility Level multiplier: ${numeralWrapper.formatPercentage(resleeve.agility_mult)}`,
|
||||
`Agility Experience multiplier: ${numeralWrapper.formatPercentage(resleeve.agility_exp_mult)}`,
|
||||
`Charisma Level multiplier: ${numeralWrapper.formatPercentage(resleeve.charisma_mult)}`,
|
||||
`Charisma Experience multiplier: ${numeralWrapper.formatPercentage(resleeve.charisma_exp_mult)}`,
|
||||
`Hacking Chance multiplier: ${numeralWrapper.formatPercentage(resleeve.hacking_chance_mult)}`,
|
||||
`Hacking Speed multiplier: ${numeralWrapper.formatPercentage(resleeve.hacking_speed_mult)}`,
|
||||
`Hacking Money multiplier: ${numeralWrapper.formatPercentage(resleeve.hacking_money_mult)}`,
|
||||
`Hacking Growth multiplier: ${numeralWrapper.formatPercentage(resleeve.hacking_grow_mult)}`,
|
||||
`Salary multiplier: ${numeralWrapper.formatPercentage(resleeve.work_money_mult)}`,
|
||||
`Company Reputation Gain multiplier: ${numeralWrapper.formatPercentage(resleeve.company_rep_mult)}`,
|
||||
`Faction Reputation Gain multiplier: ${numeralWrapper.formatPercentage(resleeve.faction_rep_mult)}`,
|
||||
`Crime Money multiplier: ${numeralWrapper.formatPercentage(resleeve.crime_money_mult)}`,
|
||||
`Crime Success multiplier: ${numeralWrapper.formatPercentage(resleeve.crime_success_mult)}`,
|
||||
`Hacknet Income multiplier: ${numeralWrapper.formatPercentage(resleeve.hacknet_node_money_mult)}`,
|
||||
`Hacknet Purchase Cost multiplier: ${numeralWrapper.formatPercentage(
|
||||
resleeve.hacknet_node_purchase_cost_mult,
|
||||
)}`,
|
||||
@@ -481,16 +381,13 @@ function createResleeveUi(resleeve: Resleeve): IResleeveUIElems {
|
||||
});
|
||||
elems.costText = createElement("p", {
|
||||
innerHTML:
|
||||
`It costs ${renderToStaticMarkup(
|
||||
<Money money={cost} player={playerRef} />,
|
||||
)} ` + `to purchase this Sleeve.`,
|
||||
`It costs ${renderToStaticMarkup(<Money money={cost} player={playerRef} />)} ` + `to purchase this Sleeve.`,
|
||||
});
|
||||
elems.buyButton = createElement("button", {
|
||||
class: "std-button",
|
||||
innerText: "Purchase",
|
||||
clickListener: () => {
|
||||
if (playerRef == null)
|
||||
throw new Error("playerRef is null in buyButton.click()");
|
||||
if (playerRef == null) throw new Error("playerRef is null in buyButton.click()");
|
||||
if (purchaseResleeve(resleeve, playerRef)) {
|
||||
dialogBoxCreate(
|
||||
<>
|
||||
@@ -514,8 +411,7 @@ function createResleeveUi(resleeve: Resleeve): IResleeveUIElems {
|
||||
}
|
||||
|
||||
function updateAugDescription(elems: IResleeveUIElems): void {
|
||||
if (elems.augDescription == null)
|
||||
throw new Error("elems.augDescription is null in updateAugDescription()");
|
||||
if (elems.augDescription == null) throw new Error("elems.augDescription is null in updateAugDescription()");
|
||||
const augName: string = getSelectValue(elems.augSelector);
|
||||
const aug: Augmentation | null = Augmentations[augName];
|
||||
if (aug == null) {
|
||||
|
||||
@@ -32,11 +32,7 @@ import { FactionWorkType } from "../../Faction/FactionWorkTypeEnum";
|
||||
import { CityName } from "../../Locations/data/CityNames";
|
||||
import { LocationName } from "../../Locations/data/LocationNames";
|
||||
|
||||
import {
|
||||
Generic_fromJSON,
|
||||
Generic_toJSON,
|
||||
Reviver,
|
||||
} from "../../../utils/JSONReviver";
|
||||
import { Generic_fromJSON, Generic_toJSON, Reviver } from "../../../utils/JSONReviver";
|
||||
|
||||
export class Sleeve extends Person {
|
||||
/**
|
||||
@@ -158,32 +154,13 @@ export class Sleeve extends Person {
|
||||
this.resetTaskStatus();
|
||||
}
|
||||
|
||||
this.gainRatesForTask.hack =
|
||||
crime.hacking_exp *
|
||||
this.hacking_exp_mult *
|
||||
BitNodeMultipliers.CrimeExpGain;
|
||||
this.gainRatesForTask.str =
|
||||
crime.strength_exp *
|
||||
this.strength_exp_mult *
|
||||
BitNodeMultipliers.CrimeExpGain;
|
||||
this.gainRatesForTask.def =
|
||||
crime.defense_exp *
|
||||
this.defense_exp_mult *
|
||||
BitNodeMultipliers.CrimeExpGain;
|
||||
this.gainRatesForTask.dex =
|
||||
crime.dexterity_exp *
|
||||
this.dexterity_exp_mult *
|
||||
BitNodeMultipliers.CrimeExpGain;
|
||||
this.gainRatesForTask.agi =
|
||||
crime.agility_exp *
|
||||
this.agility_exp_mult *
|
||||
BitNodeMultipliers.CrimeExpGain;
|
||||
this.gainRatesForTask.cha =
|
||||
crime.charisma_exp *
|
||||
this.charisma_exp_mult *
|
||||
BitNodeMultipliers.CrimeExpGain;
|
||||
this.gainRatesForTask.money =
|
||||
crime.money * this.crime_money_mult * BitNodeMultipliers.CrimeMoney;
|
||||
this.gainRatesForTask.hack = crime.hacking_exp * this.hacking_exp_mult * BitNodeMultipliers.CrimeExpGain;
|
||||
this.gainRatesForTask.str = crime.strength_exp * this.strength_exp_mult * BitNodeMultipliers.CrimeExpGain;
|
||||
this.gainRatesForTask.def = crime.defense_exp * this.defense_exp_mult * BitNodeMultipliers.CrimeExpGain;
|
||||
this.gainRatesForTask.dex = crime.dexterity_exp * this.dexterity_exp_mult * BitNodeMultipliers.CrimeExpGain;
|
||||
this.gainRatesForTask.agi = crime.agility_exp * this.agility_exp_mult * BitNodeMultipliers.CrimeExpGain;
|
||||
this.gainRatesForTask.cha = crime.charisma_exp * this.charisma_exp_mult * BitNodeMultipliers.CrimeExpGain;
|
||||
this.gainRatesForTask.money = crime.money * this.crime_money_mult * BitNodeMultipliers.CrimeMoney;
|
||||
|
||||
this.currentTaskLocation = String(this.gainRatesForTask.money);
|
||||
|
||||
@@ -204,9 +181,7 @@ export class Sleeve extends Person {
|
||||
if (this.currentTaskTime >= this.currentTaskMaxTime) {
|
||||
const crime: Crime | null = Crimes[this.crimeType];
|
||||
if (!(crime instanceof Crime)) {
|
||||
console.error(
|
||||
`Invalid data stored in sleeve.crimeType: ${this.crimeType}`,
|
||||
);
|
||||
console.error(`Invalid data stored in sleeve.crimeType: ${this.crimeType}`);
|
||||
this.resetTaskStatus();
|
||||
return retValue;
|
||||
}
|
||||
@@ -214,9 +189,7 @@ export class Sleeve extends Person {
|
||||
// Success
|
||||
const successGainRates: ITaskTracker = createTaskTracker();
|
||||
|
||||
const keysForIteration: (keyof ITaskTracker)[] = Object.keys(
|
||||
successGainRates,
|
||||
) as (keyof ITaskTracker)[];
|
||||
const keysForIteration: (keyof ITaskTracker)[] = Object.keys(successGainRates) as (keyof ITaskTracker)[];
|
||||
for (let i = 0; i < keysForIteration.length; ++i) {
|
||||
const key = keysForIteration[i];
|
||||
successGainRates[key] = this.gainRatesForTask[key] * 2;
|
||||
@@ -246,12 +219,7 @@ export class Sleeve extends Person {
|
||||
* Earn experience for any stats (supports multiple)
|
||||
* This function also handles experience propogating to Player and other sleeves
|
||||
*/
|
||||
gainExperience(
|
||||
p: IPlayer,
|
||||
exp: ITaskTracker,
|
||||
numCycles = 1,
|
||||
fromOtherSleeve = false,
|
||||
): ITaskTracker {
|
||||
gainExperience(p: IPlayer, exp: ITaskTracker, numCycles = 1, fromOtherSleeve = false): ITaskTracker {
|
||||
// If the experience is coming from another sleeve, it is not multiplied by anything.
|
||||
// Also the player does not earn anything
|
||||
if (fromOtherSleeve) {
|
||||
@@ -405,41 +373,26 @@ export class Sleeve extends Person {
|
||||
|
||||
switch (this.factionWorkType) {
|
||||
case FactionWorkType.Hacking:
|
||||
return (
|
||||
this.getFactionHackingWorkRepGain() * (this.shock / 100) * favorMult
|
||||
);
|
||||
return this.getFactionHackingWorkRepGain() * (this.shock / 100) * favorMult;
|
||||
case FactionWorkType.Field:
|
||||
return (
|
||||
this.getFactionFieldWorkRepGain() * (this.shock / 100) * favorMult
|
||||
);
|
||||
return this.getFactionFieldWorkRepGain() * (this.shock / 100) * favorMult;
|
||||
case FactionWorkType.Security:
|
||||
return (
|
||||
this.getFactionSecurityWorkRepGain() *
|
||||
(this.shock / 100) *
|
||||
favorMult
|
||||
);
|
||||
return this.getFactionSecurityWorkRepGain() * (this.shock / 100) * favorMult;
|
||||
default:
|
||||
console.warn(
|
||||
`Invalid Sleeve.factionWorkType property in Sleeve.getRepGain(): ${this.factionWorkType}`,
|
||||
);
|
||||
console.warn(`Invalid Sleeve.factionWorkType property in Sleeve.getRepGain(): ${this.factionWorkType}`);
|
||||
return 0;
|
||||
}
|
||||
} else if (this.currentTask === SleeveTaskType.Company) {
|
||||
const companyName: string = this.currentTaskLocation;
|
||||
const company: Company | null = Companies[companyName];
|
||||
if (company == null) {
|
||||
console.error(
|
||||
`Invalid company found when trying to calculate rep gain: ${companyName}`,
|
||||
);
|
||||
console.error(`Invalid company found when trying to calculate rep gain: ${companyName}`);
|
||||
return 0;
|
||||
}
|
||||
|
||||
const companyPosition: CompanyPosition | null =
|
||||
CompanyPositions[p.jobs[companyName]];
|
||||
const companyPosition: CompanyPosition | null = CompanyPositions[p.jobs[companyName]];
|
||||
if (companyPosition == null) {
|
||||
console.error(
|
||||
`Invalid company position name found when trying to calculate rep gain: ${p.jobs[companyName]}`,
|
||||
);
|
||||
console.error(`Invalid company position name found when trying to calculate rep gain: ${p.jobs[companyName]}`);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -455,9 +408,7 @@ export class Sleeve extends Person {
|
||||
|
||||
return jobPerformance * this.company_rep_mult * favorMult;
|
||||
} else {
|
||||
console.warn(
|
||||
`Sleeve.getRepGain() called for invalid task type: ${this.currentTask}`,
|
||||
);
|
||||
console.warn(`Sleeve.getRepGain() called for invalid task type: ${this.currentTask}`);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -527,10 +478,7 @@ export class Sleeve extends Person {
|
||||
|
||||
let time = this.storedCycles * CONSTANTS.MilliPerCycle;
|
||||
let cyclesUsed = this.storedCycles;
|
||||
if (
|
||||
this.currentTaskMaxTime !== 0 &&
|
||||
this.currentTaskTime + time > this.currentTaskMaxTime
|
||||
) {
|
||||
if (this.currentTaskMaxTime !== 0 && this.currentTaskTime + time > this.currentTaskMaxTime) {
|
||||
time = this.currentTaskMaxTime - this.currentTaskTime;
|
||||
cyclesUsed = Math.floor(time / CONSTANTS.MilliPerCycle);
|
||||
|
||||
@@ -562,9 +510,7 @@ export class Sleeve extends Person {
|
||||
// Gain faction reputation
|
||||
const fac: Faction = Factions[this.currentTaskLocation];
|
||||
if (!(fac instanceof Faction)) {
|
||||
console.error(
|
||||
`Invalid faction for Sleeve task: ${this.currentTaskLocation}`,
|
||||
);
|
||||
console.error(`Invalid faction for Sleeve task: ${this.currentTaskLocation}`);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -577,9 +523,7 @@ export class Sleeve extends Person {
|
||||
|
||||
const company: Company = Companies[this.currentTaskLocation];
|
||||
if (!(company instanceof Company)) {
|
||||
console.error(
|
||||
`Invalid company for Sleeve task: ${this.currentTaskLocation}`,
|
||||
);
|
||||
console.error(`Invalid company for Sleeve task: ${this.currentTaskLocation}`);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -590,19 +534,13 @@ export class Sleeve extends Person {
|
||||
this.shock = Math.min(100, this.shock + 0.0002 * cyclesUsed);
|
||||
break;
|
||||
case SleeveTaskType.Synchro:
|
||||
this.sync = Math.min(
|
||||
100,
|
||||
this.sync + p.getIntelligenceBonus(0.5) * 0.0002 * cyclesUsed,
|
||||
);
|
||||
this.sync = Math.min(100, this.sync + p.getIntelligenceBonus(0.5) * 0.0002 * cyclesUsed);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (
|
||||
this.currentTaskMaxTime !== 0 &&
|
||||
this.currentTaskTime >= this.currentTaskMaxTime
|
||||
) {
|
||||
if (this.currentTaskMaxTime !== 0 && this.currentTaskTime >= this.currentTaskMaxTime) {
|
||||
if (this.currentTask === SleeveTaskType.Crime) {
|
||||
retValue = this.finishTask(p);
|
||||
} else {
|
||||
@@ -658,11 +596,7 @@ export class Sleeve extends Person {
|
||||
/**
|
||||
* Take a course at a university
|
||||
*/
|
||||
takeUniversityCourse(
|
||||
p: IPlayer,
|
||||
universityName: string,
|
||||
className: string,
|
||||
): boolean {
|
||||
takeUniversityCourse(p: IPlayer, universityName: string, className: string): boolean {
|
||||
if (this.currentTask !== SleeveTaskType.Idle) {
|
||||
this.finishTask(p);
|
||||
} else {
|
||||
@@ -703,24 +637,19 @@ export class Sleeve extends Person {
|
||||
case "study computer science":
|
||||
break;
|
||||
case "data structures":
|
||||
this.gainRatesForTask.money =
|
||||
-1 * (CONSTANTS.ClassDataStructuresBaseCost * costMult);
|
||||
this.gainRatesForTask.money = -1 * (CONSTANTS.ClassDataStructuresBaseCost * costMult);
|
||||
break;
|
||||
case "networks":
|
||||
this.gainRatesForTask.money =
|
||||
-1 * (CONSTANTS.ClassNetworksBaseCost * costMult);
|
||||
this.gainRatesForTask.money = -1 * (CONSTANTS.ClassNetworksBaseCost * costMult);
|
||||
break;
|
||||
case "algorithms":
|
||||
this.gainRatesForTask.money =
|
||||
-1 * (CONSTANTS.ClassAlgorithmsBaseCost * costMult);
|
||||
this.gainRatesForTask.money = -1 * (CONSTANTS.ClassAlgorithmsBaseCost * costMult);
|
||||
break;
|
||||
case "management":
|
||||
this.gainRatesForTask.money =
|
||||
-1 * (CONSTANTS.ClassManagementBaseCost * costMult);
|
||||
this.gainRatesForTask.money = -1 * (CONSTANTS.ClassManagementBaseCost * costMult);
|
||||
break;
|
||||
case "leadership":
|
||||
this.gainRatesForTask.money =
|
||||
-1 * (CONSTANTS.ClassLeadershipBaseCost * costMult);
|
||||
this.gainRatesForTask.money = -1 * (CONSTANTS.ClassLeadershipBaseCost * costMult);
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
@@ -777,39 +706,22 @@ export class Sleeve extends Person {
|
||||
switch (this.className.toLowerCase()) {
|
||||
case "study computer science":
|
||||
this.gainRatesForTask.hack =
|
||||
CONSTANTS.ClassStudyComputerScienceBaseExp *
|
||||
totalExpMult *
|
||||
this.hacking_exp_mult;
|
||||
CONSTANTS.ClassStudyComputerScienceBaseExp * totalExpMult * this.hacking_exp_mult;
|
||||
break;
|
||||
case "data structures":
|
||||
this.gainRatesForTask.hack =
|
||||
CONSTANTS.ClassDataStructuresBaseExp *
|
||||
totalExpMult *
|
||||
this.hacking_exp_mult;
|
||||
this.gainRatesForTask.hack = CONSTANTS.ClassDataStructuresBaseExp * totalExpMult * this.hacking_exp_mult;
|
||||
break;
|
||||
case "networks":
|
||||
this.gainRatesForTask.hack =
|
||||
CONSTANTS.ClassNetworksBaseExp *
|
||||
totalExpMult *
|
||||
this.hacking_exp_mult;
|
||||
this.gainRatesForTask.hack = CONSTANTS.ClassNetworksBaseExp * totalExpMult * this.hacking_exp_mult;
|
||||
break;
|
||||
case "algorithms":
|
||||
this.gainRatesForTask.hack =
|
||||
CONSTANTS.ClassAlgorithmsBaseExp *
|
||||
totalExpMult *
|
||||
this.hacking_exp_mult;
|
||||
this.gainRatesForTask.hack = CONSTANTS.ClassAlgorithmsBaseExp * totalExpMult * this.hacking_exp_mult;
|
||||
break;
|
||||
case "management":
|
||||
this.gainRatesForTask.cha =
|
||||
CONSTANTS.ClassManagementBaseExp *
|
||||
totalExpMult *
|
||||
this.charisma_exp_mult;
|
||||
this.gainRatesForTask.cha = CONSTANTS.ClassManagementBaseExp * totalExpMult * this.charisma_exp_mult;
|
||||
break;
|
||||
case "leadership":
|
||||
this.gainRatesForTask.cha =
|
||||
CONSTANTS.ClassLeadershipBaseExp *
|
||||
totalExpMult *
|
||||
this.charisma_exp_mult;
|
||||
this.gainRatesForTask.cha = CONSTANTS.ClassLeadershipBaseExp * totalExpMult * this.charisma_exp_mult;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -846,25 +758,19 @@ export class Sleeve extends Person {
|
||||
const totalExpMultiplier = p.hashManager.getTrainingMult() * expMult;
|
||||
const sanitizedStat: string = this.gymStatType.toLowerCase();
|
||||
if (sanitizedStat.includes("str")) {
|
||||
this.gainRatesForTask.str =
|
||||
baseGymExp * totalExpMultiplier * this.strength_exp_mult;
|
||||
this.gainRatesForTask.str = baseGymExp * totalExpMultiplier * this.strength_exp_mult;
|
||||
} else if (sanitizedStat.includes("def")) {
|
||||
this.gainRatesForTask.def =
|
||||
baseGymExp * totalExpMultiplier * this.defense_exp_mult;
|
||||
this.gainRatesForTask.def = baseGymExp * totalExpMultiplier * this.defense_exp_mult;
|
||||
} else if (sanitizedStat.includes("dex")) {
|
||||
this.gainRatesForTask.dex =
|
||||
baseGymExp * totalExpMultiplier * this.dexterity_exp_mult;
|
||||
this.gainRatesForTask.dex = baseGymExp * totalExpMultiplier * this.dexterity_exp_mult;
|
||||
} else if (sanitizedStat.includes("agi")) {
|
||||
this.gainRatesForTask.agi =
|
||||
baseGymExp * totalExpMultiplier * this.agility_exp_mult;
|
||||
this.gainRatesForTask.agi = baseGymExp * totalExpMultiplier * this.agility_exp_mult;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
console.warn(
|
||||
`Sleeve.updateTaskGainRates() called for unexpected task type ${this.currentTask}`,
|
||||
);
|
||||
console.warn(`Sleeve.updateTaskGainRates() called for unexpected task type ${this.currentTask}`);
|
||||
}
|
||||
|
||||
upgradeMemory(n: number): void {
|
||||
@@ -881,10 +787,7 @@ export class Sleeve extends Person {
|
||||
* Returns boolean indicating success
|
||||
*/
|
||||
workForCompany(p: IPlayer, companyName: string): boolean {
|
||||
if (
|
||||
!(Companies[companyName] instanceof Company) ||
|
||||
p.jobs[companyName] == null
|
||||
) {
|
||||
if (!(Companies[companyName] instanceof Company) || p.jobs[companyName] == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -895,8 +798,7 @@ export class Sleeve extends Person {
|
||||
}
|
||||
|
||||
const company: Company | null = Companies[companyName];
|
||||
const companyPosition: CompanyPosition | null =
|
||||
CompanyPositions[p.jobs[companyName]];
|
||||
const companyPosition: CompanyPosition | null = CompanyPositions[p.jobs[companyName]];
|
||||
if (company == null) {
|
||||
return false;
|
||||
}
|
||||
@@ -954,10 +856,7 @@ export class Sleeve extends Person {
|
||||
if (factionName === "") {
|
||||
return false;
|
||||
}
|
||||
if (
|
||||
!(Factions[factionName] instanceof Faction) ||
|
||||
!p.factions.includes(factionName)
|
||||
) {
|
||||
if (!(Factions[factionName] instanceof Faction) || !p.factions.includes(factionName)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -976,40 +875,28 @@ export class Sleeve extends Person {
|
||||
return false;
|
||||
}
|
||||
this.factionWorkType = FactionWorkType.Hacking;
|
||||
this.gainRatesForTask.hack =
|
||||
0.15 * this.hacking_exp_mult * BitNodeMultipliers.FactionWorkExpGain;
|
||||
this.gainRatesForTask.hack = 0.15 * this.hacking_exp_mult * BitNodeMultipliers.FactionWorkExpGain;
|
||||
} else if (sanitizedWorkType.includes("field")) {
|
||||
if (!factionInfo.offerFieldWork) {
|
||||
return false;
|
||||
}
|
||||
this.factionWorkType = FactionWorkType.Field;
|
||||
this.gainRatesForTask.hack =
|
||||
0.1 * this.hacking_exp_mult * BitNodeMultipliers.FactionWorkExpGain;
|
||||
this.gainRatesForTask.str =
|
||||
0.1 * this.strength_exp_mult * BitNodeMultipliers.FactionWorkExpGain;
|
||||
this.gainRatesForTask.def =
|
||||
0.1 * this.defense_exp_mult * BitNodeMultipliers.FactionWorkExpGain;
|
||||
this.gainRatesForTask.dex =
|
||||
0.1 * this.dexterity_exp_mult * BitNodeMultipliers.FactionWorkExpGain;
|
||||
this.gainRatesForTask.agi =
|
||||
0.1 * this.agility_exp_mult * BitNodeMultipliers.FactionWorkExpGain;
|
||||
this.gainRatesForTask.cha =
|
||||
0.1 * this.charisma_exp_mult * BitNodeMultipliers.FactionWorkExpGain;
|
||||
this.gainRatesForTask.hack = 0.1 * this.hacking_exp_mult * BitNodeMultipliers.FactionWorkExpGain;
|
||||
this.gainRatesForTask.str = 0.1 * this.strength_exp_mult * BitNodeMultipliers.FactionWorkExpGain;
|
||||
this.gainRatesForTask.def = 0.1 * this.defense_exp_mult * BitNodeMultipliers.FactionWorkExpGain;
|
||||
this.gainRatesForTask.dex = 0.1 * this.dexterity_exp_mult * BitNodeMultipliers.FactionWorkExpGain;
|
||||
this.gainRatesForTask.agi = 0.1 * this.agility_exp_mult * BitNodeMultipliers.FactionWorkExpGain;
|
||||
this.gainRatesForTask.cha = 0.1 * this.charisma_exp_mult * BitNodeMultipliers.FactionWorkExpGain;
|
||||
} else if (sanitizedWorkType.includes("security")) {
|
||||
if (!factionInfo.offerSecurityWork) {
|
||||
return false;
|
||||
}
|
||||
this.factionWorkType = FactionWorkType.Security;
|
||||
this.gainRatesForTask.hack =
|
||||
0.1 * this.hacking_exp_mult * BitNodeMultipliers.FactionWorkExpGain;
|
||||
this.gainRatesForTask.str =
|
||||
0.15 * this.strength_exp_mult * BitNodeMultipliers.FactionWorkExpGain;
|
||||
this.gainRatesForTask.def =
|
||||
0.15 * this.defense_exp_mult * BitNodeMultipliers.FactionWorkExpGain;
|
||||
this.gainRatesForTask.dex =
|
||||
0.15 * this.dexterity_exp_mult * BitNodeMultipliers.FactionWorkExpGain;
|
||||
this.gainRatesForTask.agi =
|
||||
0.15 * this.agility_exp_mult * BitNodeMultipliers.FactionWorkExpGain;
|
||||
this.gainRatesForTask.hack = 0.1 * this.hacking_exp_mult * BitNodeMultipliers.FactionWorkExpGain;
|
||||
this.gainRatesForTask.str = 0.15 * this.strength_exp_mult * BitNodeMultipliers.FactionWorkExpGain;
|
||||
this.gainRatesForTask.def = 0.15 * this.defense_exp_mult * BitNodeMultipliers.FactionWorkExpGain;
|
||||
this.gainRatesForTask.dex = 0.15 * this.dexterity_exp_mult * BitNodeMultipliers.FactionWorkExpGain;
|
||||
this.gainRatesForTask.agi = 0.15 * this.agility_exp_mult * BitNodeMultipliers.FactionWorkExpGain;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -22,10 +22,7 @@ import { removeElementById } from "../../../utils/uiHelpers/removeElementById";
|
||||
|
||||
import { renderToStaticMarkup } from "react-dom/server";
|
||||
|
||||
export function createSleevePurchaseAugsPopup(
|
||||
sleeve: Sleeve,
|
||||
p: IPlayer,
|
||||
): void {
|
||||
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;
|
||||
@@ -109,18 +106,13 @@ export function createSleevePurchaseAugsPopup(
|
||||
fontSize: "12px",
|
||||
innerHTML: [
|
||||
`<h2>${aug.name}</h2><br>`,
|
||||
`Cost: ${renderToStaticMarkup(
|
||||
<Money money={aug.startingCost} player={p} />,
|
||||
)}<br><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,
|
||||
);
|
||||
dialogBoxCreate(`Installed ${aug.name} on Duplicate Sleeve!`, false);
|
||||
removeElementById(popupId);
|
||||
createSleevePurchaseAugsPopup(sleeve, p);
|
||||
} else {
|
||||
|
||||
@@ -8,10 +8,7 @@ import { AugmentationNames } from "../../Augmentation/data/AugmentationNames";
|
||||
import { Faction } from "../../Faction/Faction";
|
||||
import { Factions } from "../../Faction/Factions";
|
||||
|
||||
export function findSleevePurchasableAugs(
|
||||
sleeve: Sleeve,
|
||||
p: IPlayer,
|
||||
): Augmentation[] {
|
||||
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.
|
||||
|
||||
@@ -136,8 +136,7 @@ export function createSleevesPage(p: IPlayer): void {
|
||||
// Create UI modules for all Sleeve
|
||||
for (const sleeve of p.sleeves) {
|
||||
const sleeveUi = createSleeveUi(sleeve, p.sleeves);
|
||||
if (sleeveUi.container == null)
|
||||
throw new Error("sleeveUi.container is null in createSleevesPage()");
|
||||
if (sleeveUi.container == null) throw new Error("sleeveUi.container is null in createSleevesPage()");
|
||||
UIElems.sleeveList.appendChild(sleeveUi.container);
|
||||
UIElems.sleeves.push(sleeveUi);
|
||||
}
|
||||
@@ -148,8 +147,7 @@ export function createSleevesPage(p: IPlayer): void {
|
||||
UIElems.container.appendChild(UIElems.sleeveList);
|
||||
|
||||
const container = document.getElementById("entire-game-container");
|
||||
if (container === null)
|
||||
throw new Error("entire-game-container not found in createSleevesPage()");
|
||||
if (container === null) throw new Error("entire-game-container not found in createSleevesPage()");
|
||||
container.appendChild(UIElems.container);
|
||||
} catch (e) {
|
||||
exceptionAlert(e);
|
||||
@@ -161,10 +159,8 @@ export function updateSleevesPage(): void {
|
||||
if (!routing.isOn(Page.Sleeves)) {
|
||||
return;
|
||||
}
|
||||
if (playerRef === null)
|
||||
throw new Error("playerRef is null in updateSleevesPage()");
|
||||
if (UIElems.sleeves === null)
|
||||
throw new Error("UIElems.sleeves is null in updateSleevesPage()");
|
||||
if (playerRef === null) throw new Error("playerRef is null in updateSleevesPage()");
|
||||
if (UIElems.sleeves === null) throw new Error("UIElems.sleeves is null in updateSleevesPage()");
|
||||
|
||||
try {
|
||||
for (let i = 0; i < playerRef.sleeves.length; ++i) {
|
||||
@@ -240,9 +236,7 @@ function createSleeveUi(sleeve: Sleeve, allSleeves: Sleeve[]): ISleeveUIElems {
|
||||
if (playerRef === null) return;
|
||||
const popupId = "sleeve-travel-popup";
|
||||
const popupArguments: HTMLElement[] = [];
|
||||
popupArguments.push(
|
||||
createPopupCloseButton(popupId, { class: "std-button" }),
|
||||
);
|
||||
popupArguments.push(createPopupCloseButton(popupId, { class: "std-button" }));
|
||||
popupArguments.push(
|
||||
createElement("p", {
|
||||
innerHTML:
|
||||
@@ -266,15 +260,9 @@ function createSleeveUi(sleeve: Sleeve, allSleeves: Sleeve[]): ISleeveUIElems {
|
||||
class: "cmpy-mgmt-find-employee-option",
|
||||
innerText: cityName,
|
||||
clickListener: () => {
|
||||
if (playerRef == null)
|
||||
throw new Error(
|
||||
"playerRef is null in popupArguments.click()",
|
||||
);
|
||||
if (playerRef == null) throw new Error("playerRef is null in popupArguments.click()");
|
||||
if (!playerRef.canAfford(CONSTANTS.TravelCost)) {
|
||||
dialogBoxCreate(
|
||||
"You cannot afford to have this sleeve travel to another city",
|
||||
false,
|
||||
);
|
||||
dialogBoxCreate("You cannot afford to have this sleeve travel to another city", false);
|
||||
return false;
|
||||
}
|
||||
sleeve.city = cityName as CityName;
|
||||
@@ -298,8 +286,7 @@ function createSleeveUi(sleeve: Sleeve, allSleeves: Sleeve[]): ISleeveUIElems {
|
||||
display: "block",
|
||||
innerText: "Manage Augmentations",
|
||||
clickListener: () => {
|
||||
if (playerRef == null)
|
||||
throw new Error("playerRef is null in purchaseAugsButton.click()");
|
||||
if (playerRef == null) throw new Error("playerRef is null in purchaseAugsButton.click()");
|
||||
createSleevePurchaseAugsPopup(sleeve, playerRef);
|
||||
},
|
||||
});
|
||||
@@ -384,58 +371,24 @@ function updateSleeveUi(sleeve: Sleeve, elems: ISleeveUIElems): void {
|
||||
if (!routing.isOn(Page.Sleeves)) {
|
||||
return;
|
||||
}
|
||||
if (playerRef == null)
|
||||
throw new Error("playerRef is null in updateSleeveUi()");
|
||||
if (elems.taskProgressBar == null)
|
||||
throw new Error("elems.taskProgressBar is null");
|
||||
if (playerRef == null) throw new Error("playerRef is null in updateSleeveUi()");
|
||||
if (elems.taskProgressBar == null) throw new Error("elems.taskProgressBar is null");
|
||||
if (elems.stats == null) throw new Error("elems.stats is null");
|
||||
if (elems.currentEarningsInfo == null)
|
||||
throw new Error("elems.currentEarningsInfo is null");
|
||||
if (elems.currentEarningsInfo == null) throw new Error("elems.currentEarningsInfo is null");
|
||||
|
||||
ReactDOM.render(StatsElement(sleeve), elems.stats);
|
||||
|
||||
if (sleeve.currentTask === SleeveTaskType.Crime) {
|
||||
const data = [
|
||||
[
|
||||
`Money`,
|
||||
<Money money={parseFloat(sleeve.currentTaskLocation)} />,
|
||||
`(on success)`,
|
||||
],
|
||||
[
|
||||
`Hacking Exp`,
|
||||
numeralWrapper.formatExp(sleeve.gainRatesForTask.hack),
|
||||
`(2x on success)`,
|
||||
],
|
||||
[
|
||||
`Strength Exp`,
|
||||
numeralWrapper.formatExp(sleeve.gainRatesForTask.str),
|
||||
`(2x on success)`,
|
||||
],
|
||||
[
|
||||
`Defense Exp`,
|
||||
numeralWrapper.formatExp(sleeve.gainRatesForTask.def),
|
||||
`(2x on success)`,
|
||||
],
|
||||
[
|
||||
`Dexterity Exp`,
|
||||
numeralWrapper.formatExp(sleeve.gainRatesForTask.dex),
|
||||
`(2x on success)`,
|
||||
],
|
||||
[
|
||||
`Agility Exp`,
|
||||
numeralWrapper.formatExp(sleeve.gainRatesForTask.agi),
|
||||
`(2x on success)`,
|
||||
],
|
||||
[
|
||||
`Charisma Exp`,
|
||||
numeralWrapper.formatExp(sleeve.gainRatesForTask.cha),
|
||||
`(2x on success)`,
|
||||
],
|
||||
[`Money`, <Money money={parseFloat(sleeve.currentTaskLocation)} />, `(on success)`],
|
||||
[`Hacking Exp`, numeralWrapper.formatExp(sleeve.gainRatesForTask.hack), `(2x on success)`],
|
||||
[`Strength Exp`, numeralWrapper.formatExp(sleeve.gainRatesForTask.str), `(2x on success)`],
|
||||
[`Defense Exp`, numeralWrapper.formatExp(sleeve.gainRatesForTask.def), `(2x on success)`],
|
||||
[`Dexterity Exp`, numeralWrapper.formatExp(sleeve.gainRatesForTask.dex), `(2x on success)`],
|
||||
[`Agility Exp`, numeralWrapper.formatExp(sleeve.gainRatesForTask.agi), `(2x on success)`],
|
||||
[`Charisma Exp`, numeralWrapper.formatExp(sleeve.gainRatesForTask.cha), `(2x on success)`],
|
||||
];
|
||||
ReactDOM.render(
|
||||
EarningsTableElement("Earnings (Pre-Synchronization)", data),
|
||||
elems.currentEarningsInfo,
|
||||
);
|
||||
ReactDOM.render(EarningsTableElement("Earnings (Pre-Synchronization)", data), elems.currentEarningsInfo);
|
||||
|
||||
elems.taskProgressBar.innerText = createProgressBarText({
|
||||
progress: sleeve.currentTaskTime / sleeve.currentTaskMaxTime,
|
||||
@@ -444,42 +397,18 @@ function updateSleeveUi(sleeve: Sleeve, elems: ISleeveUIElems): void {
|
||||
} else {
|
||||
const data = [
|
||||
[`Money:`, MoneyRate(5 * sleeve.gainRatesForTask.money)],
|
||||
[
|
||||
`Hacking Exp:`,
|
||||
`${numeralWrapper.formatExp(5 * sleeve.gainRatesForTask.hack)} / s`,
|
||||
],
|
||||
[
|
||||
`Strength Exp:`,
|
||||
`${numeralWrapper.formatExp(5 * sleeve.gainRatesForTask.str)} / s`,
|
||||
],
|
||||
[
|
||||
`Defense Exp:`,
|
||||
`${numeralWrapper.formatExp(5 * sleeve.gainRatesForTask.def)} / s`,
|
||||
],
|
||||
[
|
||||
`Dexterity Exp:`,
|
||||
`${numeralWrapper.formatExp(5 * sleeve.gainRatesForTask.dex)} / s`,
|
||||
],
|
||||
[
|
||||
`Agility Exp:`,
|
||||
`${numeralWrapper.formatExp(5 * sleeve.gainRatesForTask.agi)} / s`,
|
||||
],
|
||||
[
|
||||
`Charisma Exp:`,
|
||||
`${numeralWrapper.formatExp(5 * sleeve.gainRatesForTask.cha)} / s`,
|
||||
],
|
||||
[`Hacking Exp:`, `${numeralWrapper.formatExp(5 * sleeve.gainRatesForTask.hack)} / s`],
|
||||
[`Strength Exp:`, `${numeralWrapper.formatExp(5 * sleeve.gainRatesForTask.str)} / s`],
|
||||
[`Defense Exp:`, `${numeralWrapper.formatExp(5 * sleeve.gainRatesForTask.def)} / s`],
|
||||
[`Dexterity Exp:`, `${numeralWrapper.formatExp(5 * sleeve.gainRatesForTask.dex)} / s`],
|
||||
[`Agility Exp:`, `${numeralWrapper.formatExp(5 * sleeve.gainRatesForTask.agi)} / s`],
|
||||
[`Charisma Exp:`, `${numeralWrapper.formatExp(5 * sleeve.gainRatesForTask.cha)} / s`],
|
||||
];
|
||||
if (
|
||||
sleeve.currentTask === SleeveTaskType.Company ||
|
||||
sleeve.currentTask === SleeveTaskType.Faction
|
||||
) {
|
||||
if (sleeve.currentTask === SleeveTaskType.Company || sleeve.currentTask === SleeveTaskType.Faction) {
|
||||
const repGain: number = sleeve.getRepGain(playerRef);
|
||||
data.push([`Reputation:`, ReputationRate(5 * repGain)]);
|
||||
}
|
||||
ReactDOM.render(
|
||||
EarningsTableElement("Earnings (Pre-Synchronization)", data),
|
||||
elems.currentEarningsInfo,
|
||||
);
|
||||
ReactDOM.render(EarningsTableElement("Earnings (Pre-Synchronization)", data), elems.currentEarningsInfo);
|
||||
|
||||
elems.taskProgressBar.innerText = "";
|
||||
}
|
||||
@@ -494,19 +423,10 @@ const universitySelectorOptions: string[] = [
|
||||
"Leadership",
|
||||
];
|
||||
|
||||
const gymSelectorOptions: string[] = [
|
||||
"Train Strength",
|
||||
"Train Defense",
|
||||
"Train Dexterity",
|
||||
"Train Agility",
|
||||
];
|
||||
const gymSelectorOptions: string[] = ["Train Strength", "Train Defense", "Train Dexterity", "Train Agility"];
|
||||
|
||||
// Whenever a new task is selected, the "details" selector must update accordingly
|
||||
function updateSleeveTaskSelector(
|
||||
sleeve: Sleeve,
|
||||
elems: ISleeveUIElems,
|
||||
allSleeves: Sleeve[],
|
||||
): void {
|
||||
function updateSleeveTaskSelector(sleeve: Sleeve, elems: ISleeveUIElems, allSleeves: Sleeve[]): void {
|
||||
if (playerRef == null) {
|
||||
throw new Error(`playerRef is null in updateSleeveTaskSelector()`);
|
||||
}
|
||||
@@ -543,9 +463,7 @@ function updateSleeveTaskSelector(
|
||||
// Reset Selectors
|
||||
removeChildrenFromElement(elems.taskDetailsSelector);
|
||||
removeChildrenFromElement(elems.taskDetailsSelector2);
|
||||
elems.taskDetailsSelector2 = clearEventListeners(
|
||||
elems.taskDetailsSelector2,
|
||||
) as HTMLSelectElement;
|
||||
elems.taskDetailsSelector2 = clearEventListeners(elems.taskDetailsSelector2) as HTMLSelectElement;
|
||||
|
||||
const value: string = getSelectValue(elems.taskSelector);
|
||||
switch (value) {
|
||||
@@ -585,23 +503,18 @@ function updateSleeveTaskSelector(
|
||||
|
||||
// The available faction work types depends on the faction
|
||||
elems.taskDetailsSelector.addEventListener("change", () => {
|
||||
if (elems.taskDetailsSelector2 === null)
|
||||
throw new Error("elems.taskDetailsSelector2 is null");
|
||||
if (elems.taskDetailsSelector2 === null) throw new Error("elems.taskDetailsSelector2 is null");
|
||||
const facName = getSelectValue(elems.taskDetailsSelector);
|
||||
const faction: Faction | null = Factions[facName];
|
||||
if (faction == null) {
|
||||
console.warn(
|
||||
`Invalid faction name when trying to update Sleeve Task Selector: ${facName}`,
|
||||
);
|
||||
console.warn(`Invalid faction name when trying to update Sleeve Task Selector: ${facName}`);
|
||||
return;
|
||||
}
|
||||
const facInfo = faction.getInfo();
|
||||
removeChildrenFromElement(elems.taskDetailsSelector2);
|
||||
let numOptionsAdded = 0;
|
||||
if (facInfo.offerHackingWork) {
|
||||
elems.taskDetailsSelector2.add(
|
||||
createOptionElement("Hacking Contracts"),
|
||||
);
|
||||
elems.taskDetailsSelector2.add(createOptionElement("Hacking Contracts"));
|
||||
if (sleeve.factionWorkType === FactionWorkType.Hacking) {
|
||||
elems.taskDetailsSelector2.selectedIndex = numOptionsAdded;
|
||||
}
|
||||
@@ -652,9 +565,7 @@ function updateSleeveTaskSelector(
|
||||
case "Take University Course":
|
||||
// First selector has class type
|
||||
for (let i = 0; i < universitySelectorOptions.length; ++i) {
|
||||
elems.taskDetailsSelector.add(
|
||||
createOptionElement(universitySelectorOptions[i]),
|
||||
);
|
||||
elems.taskDetailsSelector.add(createOptionElement(universitySelectorOptions[i]));
|
||||
|
||||
// Set initial value
|
||||
if (sleeve.className === universitySelectorOptions[i]) {
|
||||
@@ -665,39 +576,26 @@ function updateSleeveTaskSelector(
|
||||
// Second selector has which university
|
||||
switch (sleeve.city) {
|
||||
case CityName.Aevum:
|
||||
elems.taskDetailsSelector2.add(
|
||||
createOptionElement(LocationName.AevumSummitUniversity),
|
||||
);
|
||||
elems.taskDetailsSelector2.add(createOptionElement(LocationName.AevumSummitUniversity));
|
||||
break;
|
||||
case CityName.Sector12:
|
||||
elems.taskDetailsSelector2.add(
|
||||
createOptionElement(LocationName.Sector12RothmanUniversity),
|
||||
);
|
||||
elems.taskDetailsSelector2.add(createOptionElement(LocationName.Sector12RothmanUniversity));
|
||||
break;
|
||||
case CityName.Volhaven:
|
||||
elems.taskDetailsSelector2.add(
|
||||
createOptionElement(LocationName.VolhavenZBInstituteOfTechnology),
|
||||
);
|
||||
elems.taskDetailsSelector2.add(createOptionElement(LocationName.VolhavenZBInstituteOfTechnology));
|
||||
break;
|
||||
default:
|
||||
elems.taskDetailsSelector2.add(
|
||||
createOptionElement("No university available in city!"),
|
||||
);
|
||||
elems.taskDetailsSelector2.add(createOptionElement("No university available in city!"));
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case "Workout at Gym":
|
||||
// First selector has what stat is being trained
|
||||
for (let i = 0; i < gymSelectorOptions.length; ++i) {
|
||||
elems.taskDetailsSelector.add(
|
||||
createOptionElement(gymSelectorOptions[i]),
|
||||
);
|
||||
elems.taskDetailsSelector.add(createOptionElement(gymSelectorOptions[i]));
|
||||
|
||||
// Set initial value
|
||||
if (
|
||||
sleeve.gymStatType ===
|
||||
gymSelectorOptions[i].substring(6, 9).toLowerCase()
|
||||
) {
|
||||
if (sleeve.gymStatType === gymSelectorOptions[i].substring(6, 9).toLowerCase()) {
|
||||
elems.taskDetailsSelector.selectedIndex = i;
|
||||
}
|
||||
}
|
||||
@@ -706,50 +604,32 @@ function updateSleeveTaskSelector(
|
||||
// In this switch statement we also set the initial value of the second selector
|
||||
switch (sleeve.city) {
|
||||
case CityName.Aevum:
|
||||
elems.taskDetailsSelector2.add(
|
||||
createOptionElement(LocationName.AevumCrushFitnessGym),
|
||||
);
|
||||
elems.taskDetailsSelector2.add(
|
||||
createOptionElement(LocationName.AevumSnapFitnessGym),
|
||||
);
|
||||
elems.taskDetailsSelector2.add(createOptionElement(LocationName.AevumCrushFitnessGym));
|
||||
elems.taskDetailsSelector2.add(createOptionElement(LocationName.AevumSnapFitnessGym));
|
||||
|
||||
// Set initial value
|
||||
if (
|
||||
sleeve.currentTaskLocation === LocationName.AevumCrushFitnessGym
|
||||
) {
|
||||
if (sleeve.currentTaskLocation === LocationName.AevumCrushFitnessGym) {
|
||||
elems.taskDetailsSelector2.selectedIndex = 0;
|
||||
} else if (
|
||||
sleeve.currentTaskLocation === LocationName.AevumSnapFitnessGym
|
||||
) {
|
||||
} else if (sleeve.currentTaskLocation === LocationName.AevumSnapFitnessGym) {
|
||||
elems.taskDetailsSelector2.selectedIndex = 1;
|
||||
}
|
||||
break;
|
||||
case CityName.Sector12:
|
||||
elems.taskDetailsSelector2.add(
|
||||
createOptionElement(LocationName.Sector12IronGym),
|
||||
);
|
||||
elems.taskDetailsSelector2.add(
|
||||
createOptionElement(LocationName.Sector12PowerhouseGym),
|
||||
);
|
||||
elems.taskDetailsSelector2.add(createOptionElement(LocationName.Sector12IronGym));
|
||||
elems.taskDetailsSelector2.add(createOptionElement(LocationName.Sector12PowerhouseGym));
|
||||
|
||||
// Set initial value
|
||||
if (sleeve.currentTaskLocation === LocationName.Sector12IronGym) {
|
||||
elems.taskDetailsSelector2.selectedIndex = 0;
|
||||
} else if (
|
||||
sleeve.currentTaskLocation === LocationName.Sector12PowerhouseGym
|
||||
) {
|
||||
} else if (sleeve.currentTaskLocation === LocationName.Sector12PowerhouseGym) {
|
||||
elems.taskDetailsSelector2.selectedIndex = 1;
|
||||
}
|
||||
break;
|
||||
case CityName.Volhaven:
|
||||
elems.taskDetailsSelector2.add(
|
||||
createOptionElement(LocationName.VolhavenMilleniumFitnessGym),
|
||||
);
|
||||
elems.taskDetailsSelector2.add(createOptionElement(LocationName.VolhavenMilleniumFitnessGym));
|
||||
break;
|
||||
default:
|
||||
elems.taskDetailsSelector2.add(
|
||||
createOptionElement("No gym available in city!"),
|
||||
);
|
||||
elems.taskDetailsSelector2.add(createOptionElement("No gym available in city!"));
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -771,8 +651,7 @@ function setSleeveTask(sleeve: Sleeve, elems: ISleeveUIElems): boolean {
|
||||
if (playerRef == null) {
|
||||
throw new Error("playerRef is null in Sleeve UI's setSleeveTask()");
|
||||
}
|
||||
if (elems.taskDescription == null)
|
||||
throw new Error("elems.taskDescription is null");
|
||||
if (elems.taskDescription == null) throw new Error("elems.taskDescription is null");
|
||||
|
||||
const taskValue: string = getSelectValue(elems.taskSelector);
|
||||
const detailValue: string = getSelectValue(elems.taskDetailsSelector);
|
||||
@@ -806,9 +685,7 @@ function setSleeveTask(sleeve: Sleeve, elems: ISleeveUIElems): boolean {
|
||||
res = sleeve.synchronize(playerRef);
|
||||
break;
|
||||
default:
|
||||
console.error(
|
||||
`Invalid/Unrecognized taskValue in setSleeveTask(): ${taskValue}`,
|
||||
);
|
||||
console.error(`Invalid/Unrecognized taskValue in setSleeveTask(): ${taskValue}`);
|
||||
}
|
||||
|
||||
if (res) {
|
||||
@@ -820,8 +697,7 @@ function setSleeveTask(sleeve: Sleeve, elems: ISleeveUIElems): boolean {
|
||||
"Failed to assign sleeve to task. This is most likely because the selected faction does not offer the selected work type.";
|
||||
break;
|
||||
default:
|
||||
elems.taskDescription.innerText =
|
||||
"Failed to assign sleeve to task. Invalid choice(s).";
|
||||
elems.taskDescription.innerText = "Failed to assign sleeve to task. Invalid choice(s).";
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -845,10 +721,7 @@ function setSleeveTask(sleeve: Sleeve, elems: ISleeveUIElems): boolean {
|
||||
}
|
||||
}
|
||||
|
||||
function updateSleeveTaskDescription(
|
||||
sleeve: Sleeve,
|
||||
elems: ISleeveUIElems,
|
||||
): void {
|
||||
function updateSleeveTaskDescription(sleeve: Sleeve, elems: ISleeveUIElems): void {
|
||||
try {
|
||||
if (playerRef == null) {
|
||||
throw new Error("playerRef is null in Sleeve UI's setSleeveTask()");
|
||||
@@ -857,8 +730,7 @@ function updateSleeveTaskDescription(
|
||||
const taskValue: string = getSelectValue(elems.taskSelector);
|
||||
const detailValue: string = getSelectValue(elems.taskDetailsSelector);
|
||||
const detailValue2: string = getSelectValue(elems.taskDetailsSelector2);
|
||||
if (elems.taskDescription == null)
|
||||
throw new Error("elems.taskDescription should not be null");
|
||||
if (elems.taskDescription == null) throw new Error("elems.taskDescription should not be null");
|
||||
|
||||
switch (taskValue) {
|
||||
case "------":
|
||||
@@ -873,9 +745,7 @@ function updateSleeveTaskDescription(
|
||||
case "Commit Crime":
|
||||
elems.taskDescription.innerText = `This sleeve is currently attempting to ${
|
||||
Crimes[detailValue].type
|
||||
} (Success Rate: ${numeralWrapper.formatPercentage(
|
||||
Crimes[detailValue].successRate(sleeve),
|
||||
)}).`;
|
||||
} (Success Rate: ${numeralWrapper.formatPercentage(Crimes[detailValue].successRate(sleeve))}).`;
|
||||
break;
|
||||
case "Take University Course":
|
||||
elems.taskDescription.innerText = `This sleeve is currently studying/taking a course at ${sleeve.currentTaskLocation}.`;
|
||||
@@ -894,9 +764,7 @@ function updateSleeveTaskDescription(
|
||||
"This causes the Sleeve's synchronization to increase.";
|
||||
break;
|
||||
default:
|
||||
console.error(
|
||||
`Invalid/Unrecognized taskValue in updateSleeveTaskDescription(): ${taskValue}`,
|
||||
);
|
||||
console.error(`Invalid/Unrecognized taskValue in updateSleeveTaskDescription(): ${taskValue}`);
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(`Exception caught in updateSleeveTaskDescription(): ${e}`);
|
||||
|
||||
@@ -6,111 +6,95 @@ export const SleeveFaq = (
|
||||
<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
|
||||
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.
|
||||
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.
|
||||
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'
|
||||
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
|
||||
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.
|
||||
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.
|
||||
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.
|
||||
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.
|
||||
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.
|
||||
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>
|
||||
<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.
|
||||
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.
|
||||
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.
|
||||
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.
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -7,11 +7,7 @@ import React, { useState } from "react";
|
||||
import { CovenantSleeveUpgrades } from "./CovenantSleeveUpgrades";
|
||||
|
||||
import { Sleeve } from "../Sleeve";
|
||||
import {
|
||||
BaseCostPerSleeve,
|
||||
MaxSleevesFromCovenant,
|
||||
PopupId,
|
||||
} from "../SleeveCovenantPurchases";
|
||||
import { BaseCostPerSleeve, MaxSleevesFromCovenant, PopupId } from "../SleeveCovenantPurchases";
|
||||
import { IPlayer } from "../../IPlayer";
|
||||
|
||||
import { PopupCloseButton } from "../../../ui/React/PopupCloseButton";
|
||||
@@ -60,10 +56,7 @@ export function CovenantPurchasesRoot(props: IProps): React.ReactElement {
|
||||
props.p.sleeves.push(new Sleeve(props.p));
|
||||
rerender();
|
||||
} else {
|
||||
dialogBoxCreate(
|
||||
`You cannot afford to purchase a Duplicate Sleeve`,
|
||||
false,
|
||||
);
|
||||
dialogBoxCreate(`You cannot afford to purchase a Duplicate Sleeve`, false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -71,39 +64,27 @@ export function CovenantPurchasesRoot(props: IProps): React.ReactElement {
|
||||
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}
|
||||
/>,
|
||||
);
|
||||
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} />?
|
||||
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.
|
||||
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"}
|
||||
/>
|
||||
<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.
|
||||
Here, you can also purchase upgrades for your Duplicate Sleeves. These upgrades are also permanent, meaning they
|
||||
persist across BitNodes.
|
||||
</p>
|
||||
{upgradePanels}
|
||||
</div>
|
||||
|
||||
@@ -22,10 +22,7 @@ interface IState {
|
||||
amt: number;
|
||||
}
|
||||
|
||||
export class CovenantSleeveMemoryUpgrade extends React.Component<
|
||||
IProps,
|
||||
IState
|
||||
> {
|
||||
export class CovenantSleeveMemoryUpgrade extends React.Component<IProps, IState> {
|
||||
constructor(props: IProps) {
|
||||
super(props);
|
||||
|
||||
@@ -88,8 +85,7 @@ export class CovenantSleeveMemoryUpgrade extends React.Component<
|
||||
} else {
|
||||
purchaseBtnContent = (
|
||||
<>
|
||||
Purchase {this.state.amt} memory -{" "}
|
||||
<Money money={cost} player={this.props.p} />?
|
||||
Purchase {this.state.amt} memory - <Money money={cost} player={this.props.p} />?
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -100,14 +96,11 @@ export class CovenantSleeveMemoryUpgrade extends React.Component<
|
||||
<u>Upgrade Memory</u>
|
||||
</h2>
|
||||
<p>
|
||||
Purchase a memory upgrade for your sleeve. Note that a sleeve's max
|
||||
memory is 100 (current:{" "}
|
||||
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>
|
||||
<label htmlFor={inputId}>Amount of memory to purchase (must be an integer):</label>
|
||||
<input
|
||||
className="text-input"
|
||||
id={inputId}
|
||||
@@ -116,11 +109,7 @@ export class CovenantSleeveMemoryUpgrade extends React.Component<
|
||||
value={this.state.amt}
|
||||
/>
|
||||
<br />
|
||||
<StdButton
|
||||
disabled={purchaseBtnDisabled}
|
||||
onClick={this.purchaseMemory}
|
||||
text={purchaseBtnContent}
|
||||
/>
|
||||
<StdButton disabled={purchaseBtnDisabled} onClick={this.purchaseMemory} text={purchaseBtnContent} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
import * as React from "react";
|
||||
|
||||
export function EarningsTableElement(
|
||||
title: string,
|
||||
stats: any[][],
|
||||
): React.ReactElement {
|
||||
export function EarningsTableElement(title: string, stats: any[][]): React.ReactElement {
|
||||
return (
|
||||
<>
|
||||
<pre>{title}</pre>
|
||||
|
||||
@@ -10,30 +10,12 @@ export function MoreEarningsContent(sleeve: Sleeve): React.ReactElement {
|
||||
{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),
|
||||
],
|
||||
["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:",
|
||||
)}
|
||||
@@ -41,30 +23,12 @@ export function MoreEarningsContent(sleeve: Sleeve): React.ReactElement {
|
||||
{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),
|
||||
],
|
||||
["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:",
|
||||
)}
|
||||
@@ -72,30 +36,12 @@ export function MoreEarningsContent(sleeve: Sleeve): React.ReactElement {
|
||||
{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),
|
||||
],
|
||||
["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:",
|
||||
)}
|
||||
|
||||
@@ -8,110 +8,35 @@ export function MoreStatsContent(sleeve: Sleeve): React.ReactElement {
|
||||
<>
|
||||
{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)`,
|
||||
],
|
||||
["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),
|
||||
],
|
||||
["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:",
|
||||
)}
|
||||
|
||||
@@ -12,8 +12,7 @@ export function StatsElement(sleeve: Sleeve): React.ReactElement {
|
||||
<tr>
|
||||
<td className="character-hp-cell">HP: </td>
|
||||
<td className="character-hp-cell" style={style}>
|
||||
{numeralWrapper.formatHp(sleeve.hp)} /{" "}
|
||||
{numeralWrapper.formatHp(sleeve.max_hp)}
|
||||
{numeralWrapper.formatHp(sleeve.hp)} / {numeralWrapper.formatHp(sleeve.max_hp)}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
export function calculateIntelligenceBonus(
|
||||
intelligence: number,
|
||||
weight = 1,
|
||||
): number {
|
||||
export function calculateIntelligenceBonus(intelligence: number, weight = 1): number {
|
||||
return 1 + (weight * Math.pow(intelligence, 0.8)) / 600;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user