mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2024-12-25 07:32:27 +01:00
Merge pull request #3544 from phyzical/feature/refactor-augmentation
REFACTOR: augmentation cost, rep cost and level to be calculated in place
This commit is contained in:
commit
44641fee07
@ -9,6 +9,18 @@ import { Money } from "../ui/React/Money";
|
|||||||
|
|
||||||
import { Generic_fromJSON, Generic_toJSON, Reviver } from "../utils/JSONReviver";
|
import { Generic_fromJSON, Generic_toJSON, Reviver } from "../utils/JSONReviver";
|
||||||
import { FactionNames } from "../Faction/data/FactionNames";
|
import { FactionNames } from "../Faction/data/FactionNames";
|
||||||
|
import { IPlayer } from "../PersonObjects/IPlayer";
|
||||||
|
import { AugmentationNames } from "./data/AugmentationNames";
|
||||||
|
import { CONSTANTS } from "../Constants";
|
||||||
|
import { StaticAugmentations } from "./StaticAugmentations";
|
||||||
|
import { BitNodeMultipliers } from "../BitNode/BitNodeMultipliers";
|
||||||
|
import { getBaseAugmentationPriceMultiplier, getGenericAugmentationPriceMultiplier } from "./AugmentationHelpers";
|
||||||
|
import { initSoAAugmentations } from "./data/AugmentationCreator";
|
||||||
|
|
||||||
|
export interface AugmentationCosts {
|
||||||
|
moneyCost: number;
|
||||||
|
repCost: number;
|
||||||
|
}
|
||||||
|
|
||||||
export interface IConstructorParams {
|
export interface IConstructorParams {
|
||||||
info: string | JSX.Element;
|
info: string | JSX.Element;
|
||||||
@ -410,10 +422,10 @@ function generateStatsDescription(mults: IMap<number>, programs?: string[], star
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class Augmentation {
|
export class Augmentation {
|
||||||
// How much money this costs to buy
|
// How much money this costs to buy before multipliers
|
||||||
baseCost = 0;
|
baseCost = 0;
|
||||||
|
|
||||||
// How much faction reputation is required to unlock this
|
// How much faction reputation is required to unlock this before multipliers
|
||||||
baseRepRequirement = 0;
|
baseRepRequirement = 0;
|
||||||
|
|
||||||
// Description of what this Aug is and what it does
|
// Description of what this Aug is and what it does
|
||||||
@ -425,9 +437,6 @@ export class Augmentation {
|
|||||||
// Any Augmentation not immediately available in BitNode-1 is special (e.g. Bladeburner augs)
|
// Any Augmentation not immediately available in BitNode-1 is special (e.g. Bladeburner augs)
|
||||||
isSpecial = false;
|
isSpecial = false;
|
||||||
|
|
||||||
// Augmentation level - for repeatable Augs like NeuroFlux Governor
|
|
||||||
level = 0;
|
|
||||||
|
|
||||||
// Name of Augmentation
|
// Name of Augmentation
|
||||||
name = "";
|
name = "";
|
||||||
|
|
||||||
@ -438,12 +447,6 @@ export class Augmentation {
|
|||||||
// The Player/Person classes
|
// The Player/Person classes
|
||||||
mults: IMap<number> = {};
|
mults: IMap<number> = {};
|
||||||
|
|
||||||
// Initial cost. Doesn't change when you purchase multiple Augmentation
|
|
||||||
startingCost = 0;
|
|
||||||
|
|
||||||
// Initial rep requirement. Doesn't change when you purchase multiple Augmentation
|
|
||||||
startingRepRequirement = 0;
|
|
||||||
|
|
||||||
// Factions that offer this aug.
|
// Factions that offer this aug.
|
||||||
factions: string[] = [];
|
factions: string[] = [];
|
||||||
|
|
||||||
@ -461,17 +464,15 @@ export class Augmentation {
|
|||||||
this.prereqs = params.prereqs ? params.prereqs : [];
|
this.prereqs = params.prereqs ? params.prereqs : [];
|
||||||
|
|
||||||
this.baseRepRequirement = params.repCost;
|
this.baseRepRequirement = params.repCost;
|
||||||
|
Object.freeze(this.baseRepRequirement);
|
||||||
this.baseCost = params.moneyCost;
|
this.baseCost = params.moneyCost;
|
||||||
this.startingCost = this.baseCost;
|
Object.freeze(this.baseCost);
|
||||||
this.startingRepRequirement = this.baseRepRequirement;
|
|
||||||
this.factions = params.factions;
|
this.factions = params.factions;
|
||||||
|
|
||||||
if (params.isSpecial) {
|
if (params.isSpecial) {
|
||||||
this.isSpecial = true;
|
this.isSpecial = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.level = 0;
|
|
||||||
|
|
||||||
// Set multipliers
|
// Set multipliers
|
||||||
if (params.hacking_mult) {
|
if (params.hacking_mult) {
|
||||||
this.mults.hacking_mult = params.hacking_mult;
|
this.mults.hacking_mult = params.hacking_mult;
|
||||||
@ -600,6 +601,61 @@ export class Augmentation {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getCost(player: IPlayer): AugmentationCosts {
|
||||||
|
const augmentationReference = StaticAugmentations[this.name];
|
||||||
|
let moneyCost = augmentationReference.baseCost;
|
||||||
|
let repCost = augmentationReference.baseRepRequirement;
|
||||||
|
|
||||||
|
if (augmentationReference.name === AugmentationNames.NeuroFluxGovernor) {
|
||||||
|
let nextLevel = this.getLevel(player);
|
||||||
|
--nextLevel;
|
||||||
|
const multiplier = Math.pow(CONSTANTS.NeuroFluxGovernorLevelMult, nextLevel);
|
||||||
|
repCost = augmentationReference.baseRepRequirement * multiplier * BitNodeMultipliers.AugmentationRepCost;
|
||||||
|
moneyCost = augmentationReference.baseCost * multiplier * BitNodeMultipliers.AugmentationMoneyCost;
|
||||||
|
|
||||||
|
for (let i = 0; i < player.queuedAugmentations.length; ++i) {
|
||||||
|
moneyCost *= getBaseAugmentationPriceMultiplier();
|
||||||
|
}
|
||||||
|
} else if (augmentationReference.factions.includes(FactionNames.ShadowsOfAnarchy)) {
|
||||||
|
const soaAugmentationNames = initSoAAugmentations().map((augmentation) => augmentation.name);
|
||||||
|
const soaMultiplier = Math.pow(
|
||||||
|
CONSTANTS.SoACostMult,
|
||||||
|
soaAugmentationNames.filter((augmentationName) => player.hasAugmentation(augmentationName)).length,
|
||||||
|
);
|
||||||
|
moneyCost = augmentationReference.baseCost * soaMultiplier;
|
||||||
|
if (soaAugmentationNames.find((augmentationName) => augmentationName === augmentationReference.name)) {
|
||||||
|
repCost = augmentationReference.baseRepRequirement * soaMultiplier;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
moneyCost =
|
||||||
|
augmentationReference.baseCost *
|
||||||
|
getGenericAugmentationPriceMultiplier() *
|
||||||
|
BitNodeMultipliers.AugmentationMoneyCost;
|
||||||
|
}
|
||||||
|
return { moneyCost, repCost };
|
||||||
|
}
|
||||||
|
|
||||||
|
getLevel(player: IPlayer): number {
|
||||||
|
// Get current Neuroflux level based on Player's augmentations
|
||||||
|
if (this.name === AugmentationNames.NeuroFluxGovernor) {
|
||||||
|
let currLevel = 0;
|
||||||
|
for (let i = 0; i < player.augmentations.length; ++i) {
|
||||||
|
if (player.augmentations[i].name === AugmentationNames.NeuroFluxGovernor) {
|
||||||
|
currLevel = player.augmentations[i].level;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Account for purchased but uninstalled Augmentations
|
||||||
|
for (let i = 0; i < player.queuedAugmentations.length; ++i) {
|
||||||
|
if (player.queuedAugmentations[i].name == AugmentationNames.NeuroFluxGovernor) {
|
||||||
|
++currLevel;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return currLevel + 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
// Adds this Augmentation to all Factions
|
// Adds this Augmentation to all Factions
|
||||||
addToAllFactions(): void {
|
addToAllFactions(): void {
|
||||||
for (const fac of Object.keys(Factions)) {
|
for (const fac of Object.keys(Factions)) {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { Augmentation } from "./Augmentation";
|
import { Augmentation } from "./Augmentation";
|
||||||
import { Augmentations } from "./Augmentations";
|
import { StaticAugmentations } from "./StaticAugmentations";
|
||||||
import { PlayerOwnedAugmentation, IPlayerOwnedAugmentation } from "./PlayerOwnedAugmentation";
|
import { PlayerOwnedAugmentation, IPlayerOwnedAugmentation } from "./PlayerOwnedAugmentation";
|
||||||
import { AugmentationNames } from "./data/AugmentationNames";
|
import { AugmentationNames } from "./data/AugmentationNames";
|
||||||
|
|
||||||
@ -20,30 +20,11 @@ import {
|
|||||||
initNeuroFluxGovernor,
|
initNeuroFluxGovernor,
|
||||||
initUnstableCircadianModulator,
|
initUnstableCircadianModulator,
|
||||||
} from "./data/AugmentationCreator";
|
} from "./data/AugmentationCreator";
|
||||||
import { BitNodeMultipliers } from "../BitNode/BitNodeMultipliers";
|
|
||||||
import { Router } from "../ui/GameRoot";
|
import { Router } from "../ui/GameRoot";
|
||||||
|
|
||||||
export function AddToAugmentations(aug: Augmentation): void {
|
export function AddToStaticAugmentations(aug: Augmentation): void {
|
||||||
const name = aug.name;
|
const name = aug.name;
|
||||||
Augmentations[name] = aug;
|
StaticAugmentations[name] = aug;
|
||||||
}
|
|
||||||
|
|
||||||
export function getNextNeuroFluxLevel(): number {
|
|
||||||
// Get current Neuroflux level based on Player's augmentations
|
|
||||||
let currLevel = 0;
|
|
||||||
for (let i = 0; i < Player.augmentations.length; ++i) {
|
|
||||||
if (Player.augmentations[i].name === AugmentationNames.NeuroFluxGovernor) {
|
|
||||||
currLevel = Player.augmentations[i].level;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Account for purchased but uninstalled Augmentations
|
|
||||||
for (let i = 0; i < Player.queuedAugmentations.length; ++i) {
|
|
||||||
if (Player.queuedAugmentations[i].name == AugmentationNames.NeuroFluxGovernor) {
|
|
||||||
++currLevel;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return currLevel + 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function createAugmentations(): void {
|
function createAugmentations(): void {
|
||||||
@ -67,96 +48,37 @@ function resetFactionAugmentations(): void {
|
|||||||
|
|
||||||
function initAugmentations(): void {
|
function initAugmentations(): void {
|
||||||
resetFactionAugmentations();
|
resetFactionAugmentations();
|
||||||
clearObject(Augmentations);
|
clearObject(StaticAugmentations);
|
||||||
createAugmentations();
|
createAugmentations();
|
||||||
updateAugmentationCosts();
|
|
||||||
Player.reapplyAllAugmentations();
|
Player.reapplyAllAugmentations();
|
||||||
}
|
}
|
||||||
|
|
||||||
function getBaseAugmentationPriceMultiplier(): number {
|
export function getBaseAugmentationPriceMultiplier(): number {
|
||||||
return CONSTANTS.MultipleAugMultiplier * [1, 0.96, 0.94, 0.93][Player.sourceFileLvl(11)];
|
return CONSTANTS.MultipleAugMultiplier * [1, 0.96, 0.94, 0.93][Player.sourceFileLvl(11)];
|
||||||
}
|
}
|
||||||
export function getGenericAugmentationPriceMultiplier(): number {
|
export function getGenericAugmentationPriceMultiplier(): number {
|
||||||
return Math.pow(getBaseAugmentationPriceMultiplier(), Player.queuedAugmentations.length);
|
return Math.pow(getBaseAugmentationPriceMultiplier(), Player.queuedAugmentations.length);
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateNeuroFluxGovernorCosts(neuroFluxGovernorAugmentation: Augmentation): void {
|
|
||||||
let nextLevel = getNextNeuroFluxLevel();
|
|
||||||
--nextLevel;
|
|
||||||
const multiplier = Math.pow(CONSTANTS.NeuroFluxGovernorLevelMult, nextLevel);
|
|
||||||
neuroFluxGovernorAugmentation.baseRepRequirement =
|
|
||||||
neuroFluxGovernorAugmentation.startingRepRequirement * multiplier * BitNodeMultipliers.AugmentationRepCost;
|
|
||||||
neuroFluxGovernorAugmentation.baseCost =
|
|
||||||
neuroFluxGovernorAugmentation.startingCost * multiplier * BitNodeMultipliers.AugmentationMoneyCost;
|
|
||||||
|
|
||||||
for (let i = 0; i < Player.queuedAugmentations.length; ++i) {
|
|
||||||
neuroFluxGovernorAugmentation.baseCost *= getBaseAugmentationPriceMultiplier();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function updateSoACosts(soaAugmentation: Augmentation): void {
|
|
||||||
const soaAugmentationNames = initSoAAugmentations().map((augmentation) => augmentation.name);
|
|
||||||
const soaAugCount = soaAugmentationNames.filter((augmentationName) =>
|
|
||||||
Player.hasAugmentation(augmentationName),
|
|
||||||
).length;
|
|
||||||
soaAugmentation.baseCost = soaAugmentation.startingCost * Math.pow(CONSTANTS.SoACostMult, soaAugCount);
|
|
||||||
if (soaAugmentationNames.find((augmentationName) => augmentationName === soaAugmentation.name)) {
|
|
||||||
soaAugmentation.baseRepRequirement =
|
|
||||||
soaAugmentation.startingRepRequirement * Math.pow(CONSTANTS.SoARepMult, soaAugCount);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function updateAugmentationCosts(): void {
|
|
||||||
for (const name of Object.keys(Augmentations)) {
|
|
||||||
if (Augmentations.hasOwnProperty(name)) {
|
|
||||||
const augmentationToUpdate = Augmentations[name];
|
|
||||||
if (augmentationToUpdate.name === AugmentationNames.NeuroFluxGovernor) {
|
|
||||||
updateNeuroFluxGovernorCosts(augmentationToUpdate);
|
|
||||||
} else if (augmentationToUpdate.factions.includes(FactionNames.ShadowsOfAnarchy)) {
|
|
||||||
updateSoACosts(augmentationToUpdate);
|
|
||||||
} else {
|
|
||||||
augmentationToUpdate.baseCost =
|
|
||||||
augmentationToUpdate.startingCost *
|
|
||||||
getGenericAugmentationPriceMultiplier() *
|
|
||||||
BitNodeMultipliers.AugmentationMoneyCost;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//Resets an Augmentation during (re-initizliation)
|
//Resets an Augmentation during (re-initizliation)
|
||||||
function resetAugmentation(aug: Augmentation): void {
|
function resetAugmentation(aug: Augmentation): void {
|
||||||
aug.addToFactions(aug.factions);
|
aug.addToFactions(aug.factions);
|
||||||
const name = aug.name;
|
const name = aug.name;
|
||||||
if (augmentationExists(name)) {
|
if (augmentationExists(name)) {
|
||||||
delete Augmentations[name];
|
delete StaticAugmentations[name];
|
||||||
}
|
}
|
||||||
AddToAugmentations(aug);
|
AddToStaticAugmentations(aug);
|
||||||
}
|
}
|
||||||
|
|
||||||
function applyAugmentation(aug: IPlayerOwnedAugmentation, reapply = false): void {
|
function applyAugmentation(aug: IPlayerOwnedAugmentation, reapply = false): void {
|
||||||
const augObj = Augmentations[aug.name];
|
const staticAugmentation = StaticAugmentations[aug.name];
|
||||||
|
|
||||||
// Apply multipliers
|
// Apply multipliers
|
||||||
for (const mult of Object.keys(augObj.mults)) {
|
for (const mult of Object.keys(staticAugmentation.mults)) {
|
||||||
const v = Player.getMult(mult) * augObj.mults[mult];
|
const v = Player.getMult(mult) * staticAugmentation.mults[mult];
|
||||||
Player.setMult(mult, v);
|
Player.setMult(mult, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Special logic for NeuroFlux Governor
|
|
||||||
if (aug.name === AugmentationNames.NeuroFluxGovernor) {
|
|
||||||
if (!reapply) {
|
|
||||||
Augmentations[aug.name].level = aug.level;
|
|
||||||
for (let i = 0; i < Player.augmentations.length; ++i) {
|
|
||||||
if (Player.augmentations[i].name == AugmentationNames.NeuroFluxGovernor) {
|
|
||||||
Player.augmentations[i].level = aug.level;
|
|
||||||
return;
|
|
||||||
// break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Special logic for Congruity Implant
|
// Special logic for Congruity Implant
|
||||||
if (aug.name === AugmentationNames.CongruityImplant && !reapply) {
|
if (aug.name === AugmentationNames.CongruityImplant && !reapply) {
|
||||||
Player.entropy = 0;
|
Player.entropy = 0;
|
||||||
@ -185,7 +107,7 @@ function installAugmentations(force?: boolean): boolean {
|
|||||||
}
|
}
|
||||||
for (let i = 0; i < Player.queuedAugmentations.length; ++i) {
|
for (let i = 0; i < Player.queuedAugmentations.length; ++i) {
|
||||||
const ownedAug = Player.queuedAugmentations[i];
|
const ownedAug = Player.queuedAugmentations[i];
|
||||||
const aug = Augmentations[ownedAug.name];
|
const aug = StaticAugmentations[ownedAug.name];
|
||||||
if (aug == null) {
|
if (aug == null) {
|
||||||
console.error(`Invalid augmentation: ${ownedAug.name}`);
|
console.error(`Invalid augmentation: ${ownedAug.name}`);
|
||||||
continue;
|
continue;
|
||||||
@ -215,7 +137,7 @@ function installAugmentations(force?: boolean): boolean {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function augmentationExists(name: string): boolean {
|
function augmentationExists(name: string): boolean {
|
||||||
return Augmentations.hasOwnProperty(name);
|
return StaticAugmentations.hasOwnProperty(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isRepeatableAug(aug: Augmentation): boolean {
|
export function isRepeatableAug(aug: Augmentation): boolean {
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { Augmentation } from "./Augmentation";
|
import { Augmentation } from "./Augmentation";
|
||||||
import { IMap } from "../types";
|
import { IMap } from "../types";
|
||||||
|
|
||||||
export const Augmentations: IMap<Augmentation> = {};
|
export const StaticAugmentations: IMap<Augmentation> = {};
|
@ -22,7 +22,7 @@ import { Settings } from "../../Settings/Settings";
|
|||||||
import { ConfirmationModal } from "../../ui/React/ConfirmationModal";
|
import { ConfirmationModal } from "../../ui/React/ConfirmationModal";
|
||||||
import { IPlayer } from "../../PersonObjects/IPlayer";
|
import { IPlayer } from "../../PersonObjects/IPlayer";
|
||||||
import { AugmentationNames } from "../data/AugmentationNames";
|
import { AugmentationNames } from "../data/AugmentationNames";
|
||||||
import { Augmentations } from "../Augmentations";
|
import { StaticAugmentations } from "../StaticAugmentations";
|
||||||
import { CONSTANTS } from "../../Constants";
|
import { CONSTANTS } from "../../Constants";
|
||||||
import { formatNumber } from "../../utils/StringHelperFunctions";
|
import { formatNumber } from "../../utils/StringHelperFunctions";
|
||||||
import { Info } from "@mui/icons-material";
|
import { Info } from "@mui/icons-material";
|
||||||
@ -39,7 +39,9 @@ const NeuroFluxDisplay = ({ player }: NFGDisplayProps): React.ReactElement => {
|
|||||||
<Typography variant="h5" color={Settings.theme.info}>
|
<Typography variant="h5" color={Settings.theme.info}>
|
||||||
NeuroFlux Governor - Level {level}
|
NeuroFlux Governor - Level {level}
|
||||||
</Typography>
|
</Typography>
|
||||||
<Typography color={Settings.theme.info}>{Augmentations[AugmentationNames.NeuroFluxGovernor].stats}</Typography>
|
<Typography color={Settings.theme.info}>
|
||||||
|
{StaticAugmentations[AugmentationNames.NeuroFluxGovernor].stats}
|
||||||
|
</Typography>
|
||||||
</Paper>
|
</Paper>
|
||||||
) : (
|
) : (
|
||||||
<></>
|
<></>
|
||||||
|
@ -13,7 +13,7 @@ import React, { useState } from "react";
|
|||||||
import { OwnedAugmentationsOrderSetting } from "../../Settings/SettingEnums";
|
import { OwnedAugmentationsOrderSetting } from "../../Settings/SettingEnums";
|
||||||
import { Settings } from "../../Settings/Settings";
|
import { Settings } from "../../Settings/Settings";
|
||||||
import { use } from "../../ui/Context";
|
import { use } from "../../ui/Context";
|
||||||
import { Augmentations } from "../Augmentations";
|
import { StaticAugmentations } from "../StaticAugmentations";
|
||||||
import { AugmentationNames } from "../data/AugmentationNames";
|
import { AugmentationNames } from "../data/AugmentationNames";
|
||||||
|
|
||||||
export function InstalledAugmentations(): React.ReactElement {
|
export function InstalledAugmentations(): React.ReactElement {
|
||||||
@ -77,7 +77,7 @@ export function InstalledAugmentations(): React.ReactElement {
|
|||||||
</Typography>
|
</Typography>
|
||||||
<Typography sx={{ maxHeight: 350, overflowY: "scroll" }}>
|
<Typography sx={{ maxHeight: 350, overflowY: "scroll" }}>
|
||||||
{(() => {
|
{(() => {
|
||||||
const aug = Augmentations[selectedAug.name];
|
const aug = StaticAugmentations[selectedAug.name];
|
||||||
|
|
||||||
const info = typeof aug.info === "string" ? <span>{aug.info}</span> : aug.info;
|
const info = typeof aug.info === "string" ? <span>{aug.info}</span> : aug.info;
|
||||||
const tooltip = (
|
const tooltip = (
|
||||||
|
@ -8,7 +8,7 @@ import { BitNodeMultipliers } from "../../BitNode/BitNodeMultipliers";
|
|||||||
import { Player } from "../../Player";
|
import { Player } from "../../Player";
|
||||||
import { Settings } from "../../Settings/Settings";
|
import { Settings } from "../../Settings/Settings";
|
||||||
import { numeralWrapper } from "../../ui/numeralFormat";
|
import { numeralWrapper } from "../../ui/numeralFormat";
|
||||||
import { Augmentations } from "../Augmentations";
|
import { StaticAugmentations } from "../StaticAugmentations";
|
||||||
|
|
||||||
interface IAugmentedStats {
|
interface IAugmentedStats {
|
||||||
[index: string]: number;
|
[index: string]: number;
|
||||||
@ -17,7 +17,7 @@ interface IAugmentedStats {
|
|||||||
function calculateAugmentedStats(): IAugmentedStats {
|
function calculateAugmentedStats(): IAugmentedStats {
|
||||||
const augP: IAugmentedStats = {};
|
const augP: IAugmentedStats = {};
|
||||||
for (const aug of Player.queuedAugmentations) {
|
for (const aug of Player.queuedAugmentations) {
|
||||||
const augObj = Augmentations[aug.name];
|
const augObj = StaticAugmentations[aug.name];
|
||||||
for (const mult of Object.keys(augObj.mults)) {
|
for (const mult of Object.keys(augObj.mults)) {
|
||||||
const v = augP[mult] ? augP[mult] : 1;
|
const v = augP[mult] ? augP[mult] : 1;
|
||||||
augP[mult] = v * augObj.mults[mult];
|
augP[mult] = v * augObj.mults[mult];
|
||||||
|
@ -5,15 +5,14 @@
|
|||||||
import { CheckBox, CheckBoxOutlineBlank, CheckCircle, Info, NewReleases, Report } from "@mui/icons-material";
|
import { CheckBox, CheckBoxOutlineBlank, CheckCircle, Info, NewReleases, Report } from "@mui/icons-material";
|
||||||
import { Box, Button, Container, Paper, Tooltip, Typography } from "@mui/material";
|
import { Box, Button, Container, Paper, Tooltip, Typography } from "@mui/material";
|
||||||
import React, { useState } from "react";
|
import React, { useState } from "react";
|
||||||
import { getNextNeuroFluxLevel } from "../AugmentationHelpers";
|
|
||||||
import { Faction } from "../../Faction/Faction";
|
import { Faction } from "../../Faction/Faction";
|
||||||
import { IPlayer } from "../../PersonObjects/IPlayer";
|
import { IPlayer } from "../../PersonObjects/IPlayer";
|
||||||
import { Settings } from "../../Settings/Settings";
|
import { Settings } from "../../Settings/Settings";
|
||||||
import { numeralWrapper } from "../../ui/numeralFormat";
|
import { numeralWrapper } from "../../ui/numeralFormat";
|
||||||
import { Augmentation } from "../Augmentation";
|
import { Augmentation } from "../Augmentation";
|
||||||
import { Augmentations } from "../Augmentations";
|
|
||||||
import { AugmentationNames } from "../data/AugmentationNames";
|
import { AugmentationNames } from "../data/AugmentationNames";
|
||||||
import { PurchaseAugmentationModal } from "./PurchaseAugmentationModal";
|
import { PurchaseAugmentationModal } from "./PurchaseAugmentationModal";
|
||||||
|
import { StaticAugmentations } from "../StaticAugmentations";
|
||||||
|
|
||||||
interface IPreReqsProps {
|
interface IPreReqsProps {
|
||||||
player: IPlayer;
|
player: IPlayer;
|
||||||
@ -160,10 +159,10 @@ interface IPurchasableAugProps {
|
|||||||
export function PurchasableAugmentation(props: IPurchasableAugProps): React.ReactElement {
|
export function PurchasableAugmentation(props: IPurchasableAugProps): React.ReactElement {
|
||||||
const [open, setOpen] = useState(false);
|
const [open, setOpen] = useState(false);
|
||||||
|
|
||||||
const aug = Augmentations[props.augName];
|
const aug = StaticAugmentations[props.augName];
|
||||||
|
const augCosts = aug.getCost(props.parent.player);
|
||||||
const cost = props.parent.sleeveAugs ? aug.startingCost : aug.baseCost;
|
const cost = props.parent.sleeveAugs ? aug.baseCost : augCosts.moneyCost;
|
||||||
|
const repCost = augCosts.repCost;
|
||||||
const info = typeof aug.info === "string" ? <span>{aug.info}</span> : aug.info;
|
const info = typeof aug.info === "string" ? <span>{aug.info}</span> : aug.info;
|
||||||
const description = (
|
const description = (
|
||||||
<>
|
<>
|
||||||
@ -205,7 +204,8 @@ export function PurchasableAugmentation(props: IPurchasableAugProps): React.Reac
|
|||||||
<>
|
<>
|
||||||
<Typography variant="h5">
|
<Typography variant="h5">
|
||||||
{props.augName}
|
{props.augName}
|
||||||
{props.augName === AugmentationNames.NeuroFluxGovernor && ` - Level ${getNextNeuroFluxLevel()}`}
|
{props.augName === AugmentationNames.NeuroFluxGovernor &&
|
||||||
|
` - Level ${aug.getLevel(props.parent.player)}`}
|
||||||
</Typography>
|
</Typography>
|
||||||
<Typography>{description}</Typography>
|
<Typography>{description}</Typography>
|
||||||
</>
|
</>
|
||||||
@ -222,7 +222,7 @@ export function PurchasableAugmentation(props: IPurchasableAugProps): React.Reac
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{aug.name}
|
{aug.name}
|
||||||
{aug.name === AugmentationNames.NeuroFluxGovernor && ` - Level ${getNextNeuroFluxLevel()}`}
|
{aug.name === AugmentationNames.NeuroFluxGovernor && ` - Level ${aug.getLevel(props.parent.player)}`}
|
||||||
</Typography>
|
</Typography>
|
||||||
{aug.factions.length === 1 && !props.parent.sleeveAugs && (
|
{aug.factions.length === 1 && !props.parent.sleeveAugs && (
|
||||||
<Exclusive player={props.parent.player} aug={aug} />
|
<Exclusive player={props.parent.player} aug={aug} />
|
||||||
@ -236,14 +236,14 @@ export function PurchasableAugmentation(props: IPurchasableAugProps): React.Reac
|
|||||||
{props.owned || (
|
{props.owned || (
|
||||||
<Box sx={{ display: "grid", alignItems: "center", justifyItems: "left" }}>
|
<Box sx={{ display: "grid", alignItems: "center", justifyItems: "left" }}>
|
||||||
<Requirement
|
<Requirement
|
||||||
fulfilled={aug.baseCost === 0 || props.parent.player.money > cost}
|
fulfilled={cost === 0 || props.parent.player.money > cost}
|
||||||
value={numeralWrapper.formatMoney(cost)}
|
value={numeralWrapper.formatMoney(cost)}
|
||||||
color={Settings.theme.money}
|
color={Settings.theme.money}
|
||||||
/>
|
/>
|
||||||
{props.parent.rep !== undefined && (
|
{props.parent.rep !== undefined && (
|
||||||
<Requirement
|
<Requirement
|
||||||
fulfilled={props.parent.rep >= aug.baseRepRequirement}
|
fulfilled={props.parent.rep >= repCost}
|
||||||
value={`${numeralWrapper.formatReputation(aug.baseRepRequirement)} rep`}
|
value={`${numeralWrapper.formatReputation(repCost)} rep`}
|
||||||
color={Settings.theme.rep}
|
color={Settings.theme.rep}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
@ -44,7 +44,7 @@ export function PurchaseAugmentationModal(props: IProps): React.ReactElement {
|
|||||||
<br />
|
<br />
|
||||||
<br />
|
<br />
|
||||||
Would you like to purchase the {props.aug.name} Augmentation for
|
Would you like to purchase the {props.aug.name} Augmentation for
|
||||||
<Money money={props.aug.baseCost} />?
|
<Money money={props.aug.getCost(player).moneyCost} />?
|
||||||
<br />
|
<br />
|
||||||
<br />
|
<br />
|
||||||
</Typography>
|
</Typography>
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
import { List, ListItemText, Paper, Tooltip, Typography } from "@mui/material";
|
import { List, ListItemText, Paper, Tooltip, Typography } from "@mui/material";
|
||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
import { Player } from "../../Player";
|
import { Player } from "../../Player";
|
||||||
import { Augmentations } from "../Augmentations";
|
import { StaticAugmentations } from "../StaticAugmentations";
|
||||||
import { AugmentationNames } from "../data/AugmentationNames";
|
import { AugmentationNames } from "../data/AugmentationNames";
|
||||||
|
|
||||||
export function PurchasedAugmentations(): React.ReactElement {
|
export function PurchasedAugmentations(): React.ReactElement {
|
||||||
@ -23,7 +23,7 @@ export function PurchasedAugmentations(): React.ReactElement {
|
|||||||
let displayName = ownedAug.name;
|
let displayName = ownedAug.name;
|
||||||
|
|
||||||
if (ownedAug.name === AugmentationNames.NeuroFluxGovernor && i !== nfgIndex) continue;
|
if (ownedAug.name === AugmentationNames.NeuroFluxGovernor && i !== nfgIndex) continue;
|
||||||
const aug = Augmentations[ownedAug.name];
|
const aug = StaticAugmentations[ownedAug.name];
|
||||||
|
|
||||||
let level = null;
|
let level = null;
|
||||||
if (ownedAug.name === AugmentationNames.NeuroFluxGovernor) {
|
if (ownedAug.name === AugmentationNames.NeuroFluxGovernor) {
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { Augmentations } from "../Augmentation/Augmentations";
|
import { StaticAugmentations } from "../Augmentation/StaticAugmentations";
|
||||||
import { Augmentation } from "../Augmentation/Augmentation";
|
import { Augmentation } from "../Augmentation/Augmentation";
|
||||||
import { PlayerOwnedAugmentation } from "../Augmentation/PlayerOwnedAugmentation";
|
import { PlayerOwnedAugmentation } from "../Augmentation/PlayerOwnedAugmentation";
|
||||||
import { AugmentationNames } from "../Augmentation/data/AugmentationNames";
|
import { AugmentationNames } from "../Augmentation/data/AugmentationNames";
|
||||||
@ -18,7 +18,6 @@ import {
|
|||||||
import { dialogBoxCreate } from "../ui/React/DialogBox";
|
import { dialogBoxCreate } from "../ui/React/DialogBox";
|
||||||
import { InvitationEvent } from "./ui/InvitationModal";
|
import { InvitationEvent } from "./ui/InvitationModal";
|
||||||
import { FactionNames } from "./data/FactionNames";
|
import { FactionNames } from "./data/FactionNames";
|
||||||
import { updateAugmentationCosts, getNextNeuroFluxLevel } from "../Augmentation/AugmentationHelpers";
|
|
||||||
import { SFC32RNG } from "../Casino/RNG";
|
import { SFC32RNG } from "../Casino/RNG";
|
||||||
|
|
||||||
export function inviteToFaction(faction: Faction): void {
|
export function inviteToFaction(faction: Faction): void {
|
||||||
@ -59,6 +58,7 @@ export function hasAugmentationPrereqs(aug: Augmentation): boolean {
|
|||||||
|
|
||||||
export function purchaseAugmentation(aug: Augmentation, fac: Faction, sing = false): string {
|
export function purchaseAugmentation(aug: Augmentation, fac: Faction, sing = false): string {
|
||||||
const hasPrereqs = hasAugmentationPrereqs(aug);
|
const hasPrereqs = hasAugmentationPrereqs(aug);
|
||||||
|
const augCosts = aug.getCost(Player);
|
||||||
if (!hasPrereqs) {
|
if (!hasPrereqs) {
|
||||||
const txt = `You must first purchase or install ${aug.prereqs
|
const txt = `You must first purchase or install ${aug.prereqs
|
||||||
.filter((req) => !Player.hasAugmentation(req))
|
.filter((req) => !Player.hasAugmentation(req))
|
||||||
@ -68,28 +68,26 @@ export function purchaseAugmentation(aug: Augmentation, fac: Faction, sing = fal
|
|||||||
} else {
|
} else {
|
||||||
dialogBoxCreate(txt);
|
dialogBoxCreate(txt);
|
||||||
}
|
}
|
||||||
} else if (aug.baseCost !== 0 && Player.money < aug.baseCost) {
|
} else if (augCosts.moneyCost !== 0 && Player.money < augCosts.moneyCost) {
|
||||||
const txt = "You don't have enough money to purchase " + aug.name;
|
const txt = "You don't have enough money to purchase " + aug.name;
|
||||||
if (sing) {
|
if (sing) {
|
||||||
return txt;
|
return txt;
|
||||||
}
|
}
|
||||||
dialogBoxCreate(txt);
|
dialogBoxCreate(txt);
|
||||||
} else if (fac.playerReputation < aug.baseRepRequirement) {
|
} else if (fac.playerReputation < augCosts.repCost) {
|
||||||
const txt = "You don't have enough faction reputation to purchase " + aug.name;
|
const txt = "You don't have enough faction reputation to purchase " + aug.name;
|
||||||
if (sing) {
|
if (sing) {
|
||||||
return txt;
|
return txt;
|
||||||
}
|
}
|
||||||
dialogBoxCreate(txt);
|
dialogBoxCreate(txt);
|
||||||
} else if (aug.baseCost === 0 || Player.money >= aug.baseCost) {
|
} else if (augCosts.moneyCost === 0 || Player.money >= augCosts.moneyCost) {
|
||||||
const queuedAugmentation = new PlayerOwnedAugmentation(aug.name);
|
const queuedAugmentation = new PlayerOwnedAugmentation(aug.name);
|
||||||
if (aug.name == AugmentationNames.NeuroFluxGovernor) {
|
if (aug.name == AugmentationNames.NeuroFluxGovernor) {
|
||||||
queuedAugmentation.level = getNextNeuroFluxLevel();
|
queuedAugmentation.level = aug.getLevel(Player);
|
||||||
}
|
}
|
||||||
Player.queuedAugmentations.push(queuedAugmentation);
|
Player.queuedAugmentations.push(queuedAugmentation);
|
||||||
|
|
||||||
Player.loseMoney(aug.baseCost, "augmentations");
|
Player.loseMoney(augCosts.moneyCost, "augmentations");
|
||||||
|
|
||||||
updateAugmentationCosts();
|
|
||||||
|
|
||||||
if (sing) {
|
if (sing) {
|
||||||
return "You purchased " + aug.name;
|
return "You purchased " + aug.name;
|
||||||
@ -141,14 +139,14 @@ export function processPassiveFactionRepGain(numCycles: number): void {
|
|||||||
export const getFactionAugmentationsFiltered = (player: IPlayer, faction: Faction): string[] => {
|
export const getFactionAugmentationsFiltered = (player: IPlayer, faction: Faction): string[] => {
|
||||||
// If player has a gang with this faction, return (almost) all augmentations
|
// If player has a gang with this faction, return (almost) all augmentations
|
||||||
if (player.hasGangWith(faction.name)) {
|
if (player.hasGangWith(faction.name)) {
|
||||||
let augs = Object.values(Augmentations);
|
let augs = Object.values(StaticAugmentations);
|
||||||
|
|
||||||
// Remove special augs
|
// Remove special augs
|
||||||
augs = augs.filter((a) => !a.isSpecial && a.name !== AugmentationNames.CongruityImplant);
|
augs = augs.filter((a) => !a.isSpecial && a.name !== AugmentationNames.CongruityImplant);
|
||||||
|
|
||||||
if (player.bitNodeN === 2) {
|
if (player.bitNodeN === 2) {
|
||||||
// TRP is not available outside of BN2 for Gangs
|
// TRP is not available outside of BN2 for Gangs
|
||||||
augs.push(Augmentations[AugmentationNames.TheRedPill]);
|
augs.push(StaticAugmentations[AugmentationNames.TheRedPill]);
|
||||||
}
|
}
|
||||||
|
|
||||||
const rng = SFC32RNG(`BN${player.bitNodeN}.${player.sourceFileLvl(player.bitNodeN)}`);
|
const rng = SFC32RNG(`BN${player.bitNodeN}.${player.sourceFileLvl(player.bitNodeN)}`);
|
||||||
|
@ -3,8 +3,9 @@
|
|||||||
*/
|
*/
|
||||||
import { Box, Button, Tooltip, Typography, Paper, Container } from "@mui/material";
|
import { Box, Button, Tooltip, Typography, Paper, Container } from "@mui/material";
|
||||||
import React, { useState } from "react";
|
import React, { useState } from "react";
|
||||||
|
|
||||||
|
import { StaticAugmentations } from "../../Augmentation/StaticAugmentations";
|
||||||
import { getGenericAugmentationPriceMultiplier } from "../../Augmentation/AugmentationHelpers";
|
import { getGenericAugmentationPriceMultiplier } from "../../Augmentation/AugmentationHelpers";
|
||||||
import { Augmentations } from "../../Augmentation/Augmentations";
|
|
||||||
import { AugmentationNames } from "../../Augmentation/data/AugmentationNames";
|
import { AugmentationNames } from "../../Augmentation/data/AugmentationNames";
|
||||||
import { PurchasableAugmentations } from "../../Augmentation/ui/PurchasableAugmentations";
|
import { PurchasableAugmentations } from "../../Augmentation/ui/PurchasableAugmentations";
|
||||||
import { PurchaseAugmentationsOrderSetting } from "../../Settings/SettingEnums";
|
import { PurchaseAugmentationsOrderSetting } from "../../Settings/SettingEnums";
|
||||||
@ -54,13 +55,13 @@ export function AugmentationsPage(props: IProps): React.ReactElement {
|
|||||||
function getAugsSortedByCost(): string[] {
|
function getAugsSortedByCost(): string[] {
|
||||||
const augs = getAugs();
|
const augs = getAugs();
|
||||||
augs.sort((augName1, augName2) => {
|
augs.sort((augName1, augName2) => {
|
||||||
const aug1 = Augmentations[augName1],
|
const aug1 = StaticAugmentations[augName1],
|
||||||
aug2 = Augmentations[augName2];
|
aug2 = StaticAugmentations[augName2];
|
||||||
if (aug1 == null || aug2 == null) {
|
if (aug1 == null || aug2 == null) {
|
||||||
throw new Error("Invalid Augmentation Names");
|
throw new Error("Invalid Augmentation Names");
|
||||||
}
|
}
|
||||||
|
|
||||||
return aug1.baseCost - aug2.baseCost;
|
return aug1.getCost(player).moneyCost - aug2.getCost(player).moneyCost;
|
||||||
});
|
});
|
||||||
|
|
||||||
return augs;
|
return augs;
|
||||||
@ -69,31 +70,32 @@ export function AugmentationsPage(props: IProps): React.ReactElement {
|
|||||||
function getAugsSortedByPurchasable(): string[] {
|
function getAugsSortedByPurchasable(): string[] {
|
||||||
const augs = getAugs();
|
const augs = getAugs();
|
||||||
function canBuy(augName: string): boolean {
|
function canBuy(augName: string): boolean {
|
||||||
const aug = Augmentations[augName];
|
const aug = StaticAugmentations[augName];
|
||||||
const repCost = aug.baseRepRequirement;
|
const augCosts = aug.getCost(player);
|
||||||
|
const repCost = augCosts.repCost;
|
||||||
const hasReq = props.faction.playerReputation >= repCost;
|
const hasReq = props.faction.playerReputation >= repCost;
|
||||||
const hasRep = hasAugmentationPrereqs(aug);
|
const hasRep = hasAugmentationPrereqs(aug);
|
||||||
const hasCost = aug.baseCost !== 0 && player.money > aug.baseCost;
|
const hasCost = augCosts.moneyCost !== 0 && player.money > augCosts.moneyCost;
|
||||||
return hasCost && hasReq && hasRep;
|
return hasCost && hasReq && hasRep;
|
||||||
}
|
}
|
||||||
const buy = augs.filter(canBuy).sort((augName1, augName2) => {
|
const buy = augs.filter(canBuy).sort((augName1, augName2) => {
|
||||||
const aug1 = Augmentations[augName1],
|
const aug1 = StaticAugmentations[augName1],
|
||||||
aug2 = Augmentations[augName2];
|
aug2 = StaticAugmentations[augName2];
|
||||||
if (aug1 == null || aug2 == null) {
|
if (aug1 == null || aug2 == null) {
|
||||||
throw new Error("Invalid Augmentation Names");
|
throw new Error("Invalid Augmentation Names");
|
||||||
}
|
}
|
||||||
|
|
||||||
return aug1.baseCost - aug2.baseCost;
|
return aug1.getCost(player).moneyCost - aug2.getCost(player).moneyCost;
|
||||||
});
|
});
|
||||||
const cantBuy = augs
|
const cantBuy = augs
|
||||||
.filter((aug) => !canBuy(aug))
|
.filter((aug) => !canBuy(aug))
|
||||||
.sort((augName1, augName2) => {
|
.sort((augName1, augName2) => {
|
||||||
const aug1 = Augmentations[augName1],
|
const aug1 = StaticAugmentations[augName1],
|
||||||
aug2 = Augmentations[augName2];
|
aug2 = StaticAugmentations[augName2];
|
||||||
if (aug1 == null || aug2 == null) {
|
if (aug1 == null || aug2 == null) {
|
||||||
throw new Error("Invalid Augmentation Names");
|
throw new Error("Invalid Augmentation Names");
|
||||||
}
|
}
|
||||||
return aug1.baseRepRequirement - aug2.baseRepRequirement;
|
return aug1.getCost(player).repCost - aug2.getCost(player).repCost;
|
||||||
});
|
});
|
||||||
|
|
||||||
return buy.concat(cantBuy);
|
return buy.concat(cantBuy);
|
||||||
@ -102,12 +104,12 @@ export function AugmentationsPage(props: IProps): React.ReactElement {
|
|||||||
function getAugsSortedByReputation(): string[] {
|
function getAugsSortedByReputation(): string[] {
|
||||||
const augs = getAugs();
|
const augs = getAugs();
|
||||||
augs.sort((augName1, augName2) => {
|
augs.sort((augName1, augName2) => {
|
||||||
const aug1 = Augmentations[augName1],
|
const aug1 = StaticAugmentations[augName1],
|
||||||
aug2 = Augmentations[augName2];
|
aug2 = StaticAugmentations[augName2];
|
||||||
if (aug1 == null || aug2 == null) {
|
if (aug1 == null || aug2 == null) {
|
||||||
throw new Error("Invalid Augmentation Names");
|
throw new Error("Invalid Augmentation Names");
|
||||||
}
|
}
|
||||||
return aug1.baseRepRequirement - aug2.baseRepRequirement;
|
return aug1.getCost(player).repCost - aug2.getCost(player).repCost;
|
||||||
});
|
});
|
||||||
|
|
||||||
return augs;
|
return augs;
|
||||||
@ -195,10 +197,11 @@ export function AugmentationsPage(props: IProps): React.ReactElement {
|
|||||||
ownedAugNames={owned}
|
ownedAugNames={owned}
|
||||||
player={player}
|
player={player}
|
||||||
canPurchase={(player, aug) => {
|
canPurchase={(player, aug) => {
|
||||||
|
const augCost = aug.getCost(player).moneyCost;
|
||||||
return (
|
return (
|
||||||
hasAugmentationPrereqs(aug) &&
|
hasAugmentationPrereqs(aug) &&
|
||||||
props.faction.playerReputation >= aug.baseRepRequirement &&
|
props.faction.playerReputation >= aug.baseRepRequirement &&
|
||||||
(aug.baseCost === 0 || player.money > aug.baseCost)
|
(augCost === 0 || player.money > augCost)
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
purchaseAugmentation={(player, aug, showModal) => {
|
purchaseAugmentation={(player, aug, showModal) => {
|
||||||
|
@ -16,12 +16,10 @@ import { BitNodeMultipliers } from "../../BitNode/BitNodeMultipliers";
|
|||||||
import { Faction } from "../Faction";
|
import { Faction } from "../Faction";
|
||||||
|
|
||||||
import { use } from "../../ui/Context";
|
import { use } from "../../ui/Context";
|
||||||
import { CreateGangModal } from "./CreateGangModal";
|
|
||||||
|
|
||||||
import { Box, Paper, Typography, Button, Tooltip } from "@mui/material";
|
import { Typography, Button } from "@mui/material";
|
||||||
import { CovenantPurchasesRoot } from "../../PersonObjects/Sleeve/ui/CovenantPurchasesRoot";
|
import { CovenantPurchasesRoot } from "../../PersonObjects/Sleeve/ui/CovenantPurchasesRoot";
|
||||||
import { FactionNames } from "../data/FactionNames";
|
import { FactionNames } from "../data/FactionNames";
|
||||||
import { GangConstants } from "../../Gang/data/Constants";
|
|
||||||
import { GangButton } from "./GangButton";
|
import { GangButton } from "./GangButton";
|
||||||
|
|
||||||
type IProps = {
|
type IProps = {
|
||||||
@ -30,7 +28,6 @@ type IProps = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Info text for all options on the UI
|
// Info text for all options on the UI
|
||||||
const gangInfo = "Create and manage a gang for this Faction. Gangs will earn you money and faction reputation";
|
|
||||||
const hackingContractsInfo =
|
const hackingContractsInfo =
|
||||||
"Complete hacking contracts for your faction. " +
|
"Complete hacking contracts for your faction. " +
|
||||||
"Your effectiveness, which determines how much " +
|
"Your effectiveness, which determines how much " +
|
||||||
|
166
src/Faction/ui/PurchaseableAugmentation.tsx
Normal file
166
src/Faction/ui/PurchaseableAugmentation.tsx
Normal file
@ -0,0 +1,166 @@
|
|||||||
|
/**
|
||||||
|
* React component for displaying a single augmentation for purchase through
|
||||||
|
* the faction UI
|
||||||
|
*/
|
||||||
|
import React, { useState } from "react";
|
||||||
|
|
||||||
|
import { hasAugmentationPrereqs, purchaseAugmentation } from "../FactionHelpers";
|
||||||
|
|
||||||
|
import { StaticAugmentations } from "../../Augmentation/StaticAugmentations";
|
||||||
|
import { AugmentationNames } from "../../Augmentation/data/AugmentationNames";
|
||||||
|
import { Faction } from "../Faction";
|
||||||
|
import { IPlayer } from "../../PersonObjects/IPlayer";
|
||||||
|
import { Settings } from "../../Settings/Settings";
|
||||||
|
import { Money } from "../../ui/React/Money";
|
||||||
|
import { Reputation } from "../../ui/React/Reputation";
|
||||||
|
|
||||||
|
import { Augmentation as AugFormat } from "../../ui/React/Augmentation";
|
||||||
|
import Button from "@mui/material/Button";
|
||||||
|
import Typography from "@mui/material/Typography";
|
||||||
|
import Tooltip from "@mui/material/Tooltip";
|
||||||
|
import Box from "@mui/material/Box";
|
||||||
|
import { TableCell } from "../../ui/React/Table";
|
||||||
|
import TableRow from "@mui/material/TableRow";
|
||||||
|
import { use } from "../../ui/Context";
|
||||||
|
import { PurchaseAugmentationModal } from "../../Augmentation/ui/PurchaseAugmentationModal";
|
||||||
|
|
||||||
|
interface IReqProps {
|
||||||
|
augName: string;
|
||||||
|
p: IPlayer;
|
||||||
|
hasReq: boolean;
|
||||||
|
rep: number;
|
||||||
|
hasRep: boolean;
|
||||||
|
cost: number;
|
||||||
|
hasCost: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
function Requirements(props: IReqProps): React.ReactElement {
|
||||||
|
const aug = StaticAugmentations[props.augName];
|
||||||
|
if (!props.hasReq) {
|
||||||
|
return (
|
||||||
|
<TableCell key={1} colSpan={2}>
|
||||||
|
<Typography color="error">
|
||||||
|
Requires{" "}
|
||||||
|
{aug.prereqs.map((aug, i) => (
|
||||||
|
<AugFormat key={i} name={aug} />
|
||||||
|
))}
|
||||||
|
</Typography>
|
||||||
|
</TableCell>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<React.Fragment key="f">
|
||||||
|
<TableCell key={1}>
|
||||||
|
<Typography>
|
||||||
|
<Money money={props.cost} player={props.p} />
|
||||||
|
</Typography>
|
||||||
|
</TableCell>
|
||||||
|
<TableCell key={2}>
|
||||||
|
<Typography color={props.hasRep ? "primary" : "error"}>
|
||||||
|
Requires <Reputation reputation={props.rep} /> faction reputation
|
||||||
|
</Typography>
|
||||||
|
</TableCell>
|
||||||
|
</React.Fragment>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IProps {
|
||||||
|
augName: string;
|
||||||
|
faction: Faction;
|
||||||
|
p: IPlayer;
|
||||||
|
rerender: () => void;
|
||||||
|
owned?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function PurchaseableAugmentation(props: IProps): React.ReactElement {
|
||||||
|
const player = use.Player();
|
||||||
|
const [open, setOpen] = useState(false);
|
||||||
|
const aug = StaticAugmentations[props.augName];
|
||||||
|
if (aug == null) throw new Error(`aug ${props.augName} does not exists`);
|
||||||
|
|
||||||
|
if (aug == null) {
|
||||||
|
console.error(
|
||||||
|
`Invalid Augmentation when trying to create PurchaseableAugmentation display element: ${props.augName}`,
|
||||||
|
);
|
||||||
|
return <></>;
|
||||||
|
}
|
||||||
|
|
||||||
|
const repCosts = aug.getCost(player);
|
||||||
|
const moneyCost = repCosts.moneyCost;
|
||||||
|
const repCost = repCosts.repCost;
|
||||||
|
const hasReq = hasAugmentationPrereqs(aug);
|
||||||
|
const hasRep = props.faction.playerReputation >= repCost;
|
||||||
|
const hasCost = moneyCost === 0 || props.p.money > moneyCost;
|
||||||
|
|
||||||
|
// Determine UI properties
|
||||||
|
const color: "error" | "primary" = !hasReq || !hasRep || !hasCost ? "error" : "primary";
|
||||||
|
|
||||||
|
// Determine button txt
|
||||||
|
let btnTxt = aug.name;
|
||||||
|
if (aug.name === AugmentationNames.NeuroFluxGovernor) {
|
||||||
|
btnTxt += ` - Level ${aug.getLevel(player)}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
let tooltip = <></>;
|
||||||
|
if (typeof aug.info === "string") {
|
||||||
|
tooltip = (
|
||||||
|
<>
|
||||||
|
<span>{aug.info}</span>
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
{aug.stats}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
} else
|
||||||
|
tooltip = (
|
||||||
|
<>
|
||||||
|
{aug.info}
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
{aug.stats}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
|
||||||
|
function handleClick(): void {
|
||||||
|
if (color === "error") return;
|
||||||
|
if (!Settings.SuppressBuyAugmentationConfirmation) {
|
||||||
|
setOpen(true);
|
||||||
|
} else {
|
||||||
|
purchaseAugmentation(aug, props.faction);
|
||||||
|
props.rerender();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<TableRow>
|
||||||
|
{!props.owned && (
|
||||||
|
<TableCell key={0}>
|
||||||
|
<Button onClick={handleClick} color={color}>
|
||||||
|
Buy
|
||||||
|
</Button>
|
||||||
|
<PurchaseAugmentationModal open={open} onClose={() => setOpen(false)} aug={aug} faction={props.faction} />
|
||||||
|
</TableCell>
|
||||||
|
)}
|
||||||
|
<TableCell key={1}>
|
||||||
|
<Box display="flex">
|
||||||
|
<Tooltip title={<Typography>{tooltip}</Typography>} placement="top">
|
||||||
|
<Typography>{btnTxt}</Typography>
|
||||||
|
</Tooltip>
|
||||||
|
</Box>
|
||||||
|
</TableCell>
|
||||||
|
{!props.owned && (
|
||||||
|
<Requirements
|
||||||
|
key={2}
|
||||||
|
augName={props.augName}
|
||||||
|
p={props.p}
|
||||||
|
cost={moneyCost}
|
||||||
|
rep={repCost}
|
||||||
|
hasReq={hasReq}
|
||||||
|
hasRep={hasRep}
|
||||||
|
hasCost={hasCost}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</TableRow>
|
||||||
|
);
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
import { Augmentations } from "../Augmentation/Augmentations";
|
import { StaticAugmentations } from "../Augmentation/StaticAugmentations";
|
||||||
import { hasAugmentationPrereqs } from "../Faction/FactionHelpers";
|
import { hasAugmentationPrereqs } from "../Faction/FactionHelpers";
|
||||||
import { CityName } from "../Locations/data/CityNames";
|
import { CityName } from "../Locations/data/CityNames";
|
||||||
import { getRamCost } from "../Netscript/RamCostGenerator";
|
import { getRamCost } from "../Netscript/RamCostGenerator";
|
||||||
@ -28,10 +28,10 @@ export function NetscriptGrafting(player: IPlayer, workerScript: WorkerScript, h
|
|||||||
updateRam("getAugmentationGraftPrice");
|
updateRam("getAugmentationGraftPrice");
|
||||||
const augName = helper.string("getAugmentationGraftPrice", "augName", _augName);
|
const augName = helper.string("getAugmentationGraftPrice", "augName", _augName);
|
||||||
checkGraftingAPIAccess("getAugmentationGraftPrice");
|
checkGraftingAPIAccess("getAugmentationGraftPrice");
|
||||||
if (!getGraftingAvailableAugs(player).includes(augName) || !Augmentations.hasOwnProperty(augName)) {
|
if (!getGraftingAvailableAugs(player).includes(augName) || !StaticAugmentations.hasOwnProperty(augName)) {
|
||||||
throw helper.makeRuntimeErrorMsg("grafting.getAugmentationGraftPrice", `Invalid aug: ${augName}`);
|
throw helper.makeRuntimeErrorMsg("grafting.getAugmentationGraftPrice", `Invalid aug: ${augName}`);
|
||||||
}
|
}
|
||||||
const graftableAug = new GraftableAugmentation(Augmentations[augName]);
|
const graftableAug = new GraftableAugmentation(StaticAugmentations[augName]);
|
||||||
return graftableAug.cost;
|
return graftableAug.cost;
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -39,10 +39,10 @@ export function NetscriptGrafting(player: IPlayer, workerScript: WorkerScript, h
|
|||||||
updateRam("getAugmentationGraftTime");
|
updateRam("getAugmentationGraftTime");
|
||||||
const augName = helper.string("getAugmentationGraftTime", "augName", _augName);
|
const augName = helper.string("getAugmentationGraftTime", "augName", _augName);
|
||||||
checkGraftingAPIAccess("getAugmentationGraftTime");
|
checkGraftingAPIAccess("getAugmentationGraftTime");
|
||||||
if (!getGraftingAvailableAugs(player).includes(augName) || !Augmentations.hasOwnProperty(augName)) {
|
if (!getGraftingAvailableAugs(player).includes(augName) || !StaticAugmentations.hasOwnProperty(augName)) {
|
||||||
throw helper.makeRuntimeErrorMsg("grafting.getAugmentationGraftTime", `Invalid aug: ${augName}`);
|
throw helper.makeRuntimeErrorMsg("grafting.getAugmentationGraftTime", `Invalid aug: ${augName}`);
|
||||||
}
|
}
|
||||||
const graftableAug = new GraftableAugmentation(Augmentations[augName]);
|
const graftableAug = new GraftableAugmentation(StaticAugmentations[augName]);
|
||||||
return calculateGraftingTimeWithBonus(player, graftableAug);
|
return calculateGraftingTimeWithBonus(player, graftableAug);
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -64,7 +64,7 @@ export function NetscriptGrafting(player: IPlayer, workerScript: WorkerScript, h
|
|||||||
"You must be in New Tokyo to begin grafting an Augmentation.",
|
"You must be in New Tokyo to begin grafting an Augmentation.",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (!getGraftingAvailableAugs(player).includes(augName) || !Augmentations.hasOwnProperty(augName)) {
|
if (!getGraftingAvailableAugs(player).includes(augName) || !StaticAugmentations.hasOwnProperty(augName)) {
|
||||||
workerScript.log("grafting.graftAugmentation", () => `Invalid aug: ${augName}`);
|
workerScript.log("grafting.graftAugmentation", () => `Invalid aug: ${augName}`);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -75,7 +75,7 @@ export function NetscriptGrafting(player: IPlayer, workerScript: WorkerScript, h
|
|||||||
workerScript.log("graftAugmentation", () => txt);
|
workerScript.log("graftAugmentation", () => txt);
|
||||||
}
|
}
|
||||||
|
|
||||||
const craftableAug = new GraftableAugmentation(Augmentations[augName]);
|
const craftableAug = new GraftableAugmentation(StaticAugmentations[augName]);
|
||||||
if (player.money < craftableAug.cost) {
|
if (player.money < craftableAug.cost) {
|
||||||
workerScript.log("grafting.graftAugmentation", () => `You don't have enough money to craft ${augName}`);
|
workerScript.log("grafting.graftAugmentation", () => `You don't have enough money to craft ${augName}`);
|
||||||
return false;
|
return false;
|
||||||
|
@ -3,7 +3,7 @@ import { IPlayer } from "../PersonObjects/IPlayer";
|
|||||||
import { purchaseAugmentation, joinFaction, getFactionAugmentationsFiltered } from "../Faction/FactionHelpers";
|
import { purchaseAugmentation, joinFaction, getFactionAugmentationsFiltered } from "../Faction/FactionHelpers";
|
||||||
import { startWorkerScript } from "../NetscriptWorker";
|
import { startWorkerScript } from "../NetscriptWorker";
|
||||||
import { Augmentation } from "../Augmentation/Augmentation";
|
import { Augmentation } from "../Augmentation/Augmentation";
|
||||||
import { Augmentations } from "../Augmentation/Augmentations";
|
import { StaticAugmentations } from "../Augmentation/StaticAugmentations";
|
||||||
import { augmentationExists, installAugmentations } from "../Augmentation/AugmentationHelpers";
|
import { augmentationExists, installAugmentations } from "../Augmentation/AugmentationHelpers";
|
||||||
import { AugmentationNames } from "../Augmentation/data/AugmentationNames";
|
import { AugmentationNames } from "../Augmentation/data/AugmentationNames";
|
||||||
import { killWorkerScript } from "../Netscript/killWorkerScript";
|
import { killWorkerScript } from "../Netscript/killWorkerScript";
|
||||||
@ -56,7 +56,7 @@ export function NetscriptSingularity(player: IPlayer, workerScript: WorkerScript
|
|||||||
throw _ctx.helper.makeRuntimeErrorMsg(`Invalid augmentation: '${name}'`);
|
throw _ctx.helper.makeRuntimeErrorMsg(`Invalid augmentation: '${name}'`);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Augmentations[name];
|
return StaticAugmentations[name];
|
||||||
};
|
};
|
||||||
|
|
||||||
const getFaction = function (_ctx: NetscriptContext, name: string): Faction {
|
const getFaction = function (_ctx: NetscriptContext, name: string): Faction {
|
||||||
@ -122,7 +122,7 @@ export function NetscriptSingularity(player: IPlayer, workerScript: WorkerScript
|
|||||||
_ctx.helper.checkSingularityAccess();
|
_ctx.helper.checkSingularityAccess();
|
||||||
const augName = _ctx.helper.string("augName", _augName);
|
const augName = _ctx.helper.string("augName", _augName);
|
||||||
const aug = getAugmentation(_ctx, augName);
|
const aug = getAugmentation(_ctx, augName);
|
||||||
return [aug.baseRepRequirement, aug.baseCost];
|
return [aug.getCost(player).moneyCost, aug.getCost(player).repCost];
|
||||||
},
|
},
|
||||||
getAugmentationPrereq: (_ctx: NetscriptContext) =>
|
getAugmentationPrereq: (_ctx: NetscriptContext) =>
|
||||||
function (_augName: unknown): string[] {
|
function (_augName: unknown): string[] {
|
||||||
@ -136,14 +136,14 @@ export function NetscriptSingularity(player: IPlayer, workerScript: WorkerScript
|
|||||||
_ctx.helper.checkSingularityAccess();
|
_ctx.helper.checkSingularityAccess();
|
||||||
const augName = _ctx.helper.string("augName", _augName);
|
const augName = _ctx.helper.string("augName", _augName);
|
||||||
const aug = getAugmentation(_ctx, augName);
|
const aug = getAugmentation(_ctx, augName);
|
||||||
return aug.baseCost;
|
return aug.getCost(player).moneyCost;
|
||||||
},
|
},
|
||||||
getAugmentationRepReq: (_ctx: NetscriptContext) =>
|
getAugmentationRepReq: (_ctx: NetscriptContext) =>
|
||||||
function (_augName: unknown): number {
|
function (_augName: unknown): number {
|
||||||
_ctx.helper.checkSingularityAccess();
|
_ctx.helper.checkSingularityAccess();
|
||||||
const augName = _ctx.helper.string("augName", _augName);
|
const augName = _ctx.helper.string("augName", _augName);
|
||||||
const aug = getAugmentation(_ctx, augName);
|
const aug = getAugmentation(_ctx, augName);
|
||||||
return aug.baseRepRequirement;
|
return aug.getCost(player).repCost;
|
||||||
},
|
},
|
||||||
getAugmentationStats: (_ctx: NetscriptContext) =>
|
getAugmentationStats: (_ctx: NetscriptContext) =>
|
||||||
function (_augName: unknown): AugmentationStats {
|
function (_augName: unknown): AugmentationStats {
|
||||||
@ -183,7 +183,7 @@ export function NetscriptSingularity(player: IPlayer, workerScript: WorkerScript
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fac.playerReputation < aug.baseRepRequirement) {
|
if (fac.playerReputation < aug.getCost(player).repCost) {
|
||||||
_ctx.log(() => `You do not have enough reputation with '${fac.name}'.`);
|
_ctx.log(() => `You do not have enough reputation with '${fac.name}'.`);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -1085,7 +1085,6 @@ export function NetscriptSingularity(player: IPlayer, workerScript: WorkerScript
|
|||||||
_ctx.log(() => `Invalid work type: '${type}`);
|
_ctx.log(() => `Invalid work type: '${type}`);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
|
||||||
},
|
},
|
||||||
getFactionRep: (_ctx: NetscriptContext) =>
|
getFactionRep: (_ctx: NetscriptContext) =>
|
||||||
function (_facName: unknown): number {
|
function (_facName: unknown): number {
|
||||||
|
@ -5,7 +5,7 @@ import { FactionWorkType } from "../Faction/FactionWorkTypeEnum";
|
|||||||
import { SleeveTaskType } from "../PersonObjects/Sleeve/SleeveTaskTypesEnum";
|
import { SleeveTaskType } from "../PersonObjects/Sleeve/SleeveTaskTypesEnum";
|
||||||
import { WorkerScript } from "../Netscript/WorkerScript";
|
import { WorkerScript } from "../Netscript/WorkerScript";
|
||||||
import { findSleevePurchasableAugs } from "../PersonObjects/Sleeve/SleeveHelpers";
|
import { findSleevePurchasableAugs } from "../PersonObjects/Sleeve/SleeveHelpers";
|
||||||
import { Augmentations } from "../Augmentation/Augmentations";
|
import { StaticAugmentations } from "../Augmentation/StaticAugmentations";
|
||||||
import { CityName } from "../Locations/data/CityNames";
|
import { CityName } from "../Locations/data/CityNames";
|
||||||
import { findCrime } from "../Crime/CrimeHelpers";
|
import { findCrime } from "../Crime/CrimeHelpers";
|
||||||
|
|
||||||
@ -286,7 +286,7 @@ export function NetscriptSleeve(player: IPlayer, workerScript: WorkerScript, hel
|
|||||||
const aug = purchasableAugs[i];
|
const aug = purchasableAugs[i];
|
||||||
augs.push({
|
augs.push({
|
||||||
name: aug.name,
|
name: aug.name,
|
||||||
cost: aug.startingCost,
|
cost: aug.baseCost,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -303,7 +303,7 @@ export function NetscriptSleeve(player: IPlayer, workerScript: WorkerScript, hel
|
|||||||
throw helper.makeRuntimeErrorMsg("sleeve.purchaseSleeveAug", `Sleeve shock too high: Sleeve ${sleeveNumber}`);
|
throw helper.makeRuntimeErrorMsg("sleeve.purchaseSleeveAug", `Sleeve shock too high: Sleeve ${sleeveNumber}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const aug = Augmentations[augName];
|
const aug = StaticAugmentations[augName];
|
||||||
if (!aug) {
|
if (!aug) {
|
||||||
throw helper.makeRuntimeErrorMsg("sleeve.purchaseSleeveAug", `Invalid aug: ${augName}`);
|
throw helper.makeRuntimeErrorMsg("sleeve.purchaseSleeveAug", `Invalid aug: ${augName}`);
|
||||||
}
|
}
|
||||||
|
@ -18,7 +18,7 @@ export class GraftableAugmentation {
|
|||||||
}
|
}
|
||||||
|
|
||||||
get cost(): number {
|
get cost(): number {
|
||||||
return this.augmentation.startingCost * CONSTANTS.AugmentationGraftingCostMult;
|
return this.augmentation.baseCost * CONSTANTS.AugmentationGraftingCostMult;
|
||||||
}
|
}
|
||||||
|
|
||||||
get time(): number {
|
get time(): number {
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
import { Augmentations } from "../../Augmentation/Augmentations";
|
import { StaticAugmentations } from "../../Augmentation/StaticAugmentations";
|
||||||
import { GraftableAugmentation } from "./GraftableAugmentation";
|
import { GraftableAugmentation } from "./GraftableAugmentation";
|
||||||
import { IPlayer } from "../IPlayer";
|
import { IPlayer } from "../IPlayer";
|
||||||
|
|
||||||
export const getGraftingAvailableAugs = (player: IPlayer): string[] => {
|
export const getGraftingAvailableAugs = (player: IPlayer): string[] => {
|
||||||
const augs: string[] = [];
|
const augs: string[] = [];
|
||||||
|
|
||||||
for (const [augName, aug] of Object.entries(Augmentations)) {
|
for (const [augName, aug] of Object.entries(StaticAugmentations)) {
|
||||||
if (aug.isSpecial) continue;
|
if (aug.isSpecial) continue;
|
||||||
augs.push(augName);
|
augs.push(augName);
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@ import { Construction, CheckBox, CheckBoxOutlineBlank } from "@mui/icons-materia
|
|||||||
import { Box, Button, Container, List, ListItemButton, Paper, Typography } from "@mui/material";
|
import { Box, Button, Container, List, ListItemButton, Paper, Typography } from "@mui/material";
|
||||||
import React, { useState, useEffect } from "react";
|
import React, { useState, useEffect } from "react";
|
||||||
import { Augmentation } from "../../../Augmentation/Augmentation";
|
import { Augmentation } from "../../../Augmentation/Augmentation";
|
||||||
import { Augmentations } from "../../../Augmentation/Augmentations";
|
import { StaticAugmentations } from "../../../Augmentation/StaticAugmentations";
|
||||||
import { AugmentationNames } from "../../../Augmentation/data/AugmentationNames";
|
import { AugmentationNames } from "../../../Augmentation/data/AugmentationNames";
|
||||||
import { CONSTANTS } from "../../../Constants";
|
import { CONSTANTS } from "../../../Constants";
|
||||||
import { hasAugmentationPrereqs } from "../../../Faction/FactionHelpers";
|
import { hasAugmentationPrereqs } from "../../../Faction/FactionHelpers";
|
||||||
@ -54,7 +54,7 @@ export const GraftingRoot = (): React.ReactElement => {
|
|||||||
const player = use.Player();
|
const player = use.Player();
|
||||||
const router = use.Router();
|
const router = use.Router();
|
||||||
|
|
||||||
for (const aug of Object.values(Augmentations)) {
|
for (const aug of Object.values(StaticAugmentations)) {
|
||||||
const name = aug.name;
|
const name = aug.name;
|
||||||
const graftableAug = new GraftableAugmentation(aug);
|
const graftableAug = new GraftableAugmentation(aug);
|
||||||
GraftableAugmentations[name] = graftableAug;
|
GraftableAugmentations[name] = graftableAug;
|
||||||
@ -62,6 +62,7 @@ export const GraftingRoot = (): React.ReactElement => {
|
|||||||
|
|
||||||
const [selectedAug, setSelectedAug] = useState(getGraftingAvailableAugs(player)[0]);
|
const [selectedAug, setSelectedAug] = useState(getGraftingAvailableAugs(player)[0]);
|
||||||
const [graftOpen, setGraftOpen] = useState(false);
|
const [graftOpen, setGraftOpen] = useState(false);
|
||||||
|
const selectedAugmentation = StaticAugmentations[selectedAug];
|
||||||
|
|
||||||
const setRerender = useState(false)[1];
|
const setRerender = useState(false)[1];
|
||||||
function rerender(): void {
|
function rerender(): void {
|
||||||
@ -148,22 +149,26 @@ export const GraftingRoot = (): React.ReactElement => {
|
|||||||
{/* Use formula so the displayed creation time is accurate to player bonus */}
|
{/* Use formula so the displayed creation time is accurate to player bonus */}
|
||||||
</Typography>
|
</Typography>
|
||||||
|
|
||||||
{Augmentations[selectedAug].prereqs.length > 0 && (
|
{selectedAugmentation.prereqs.length > 0 && (
|
||||||
<AugPreReqsChecklist player={player} aug={Augmentations[selectedAug]} />
|
<AugPreReqsChecklist player={player} aug={selectedAugmentation} />
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<br />
|
<br />
|
||||||
|
|
||||||
<Typography>
|
<Typography>
|
||||||
{(() => {
|
{(() => {
|
||||||
const aug = Augmentations[selectedAug];
|
const info =
|
||||||
|
typeof selectedAugmentation.info === "string" ? (
|
||||||
const info = typeof aug.info === "string" ? <span>{aug.info}</span> : aug.info;
|
<span>{selectedAugmentation.info}</span>
|
||||||
|
) : (
|
||||||
|
selectedAugmentation.info
|
||||||
|
);
|
||||||
const tooltip = (
|
const tooltip = (
|
||||||
<>
|
<>
|
||||||
{info}
|
{info}
|
||||||
<br />
|
<br />
|
||||||
<br />
|
<br />
|
||||||
{aug.stats}
|
{selectedAugmentation.stats}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
return tooltip;
|
return tooltip;
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
import { IPlayer } from "../IPlayer";
|
import { IPlayer } from "../IPlayer";
|
||||||
import { PlayerObject } from "./PlayerObject";
|
import { PlayerObject } from "./PlayerObject";
|
||||||
import { Augmentations } from "../../Augmentation/Augmentations";
|
|
||||||
import { applyAugmentation } from "../../Augmentation/AugmentationHelpers";
|
import { applyAugmentation } from "../../Augmentation/AugmentationHelpers";
|
||||||
import { PlayerOwnedAugmentation } from "../../Augmentation/PlayerOwnedAugmentation";
|
import { PlayerOwnedAugmentation } from "../../Augmentation/PlayerOwnedAugmentation";
|
||||||
import { AugmentationNames } from "../../Augmentation/data/AugmentationNames";
|
import { AugmentationNames } from "../../Augmentation/data/AugmentationNames";
|
||||||
@ -1367,7 +1366,7 @@ export function craftAugmentationWork(this: IPlayer, numCycles: number): boolean
|
|||||||
export function finishGraftAugmentationWork(this: IPlayer, cancelled: boolean, singularity = false): string {
|
export function finishGraftAugmentationWork(this: IPlayer, cancelled: boolean, singularity = false): string {
|
||||||
const augName = this.graftAugmentationName;
|
const augName = this.graftAugmentationName;
|
||||||
if (cancelled === false) {
|
if (cancelled === false) {
|
||||||
applyAugmentation(Augmentations[augName]);
|
applyAugmentation({ name: augName, level: 1 });
|
||||||
|
|
||||||
if (!this.hasAugmentation(AugmentationNames.CongruityImplant)) {
|
if (!this.hasAugmentation(AugmentationNames.CongruityImplant)) {
|
||||||
this.entropy += 1;
|
this.entropy += 1;
|
||||||
|
@ -686,7 +686,7 @@ export class Sleeve extends Person {
|
|||||||
}
|
}
|
||||||
|
|
||||||
tryBuyAugmentation(p: IPlayer, aug: Augmentation): boolean {
|
tryBuyAugmentation(p: IPlayer, aug: Augmentation): boolean {
|
||||||
if (!p.canAfford(aug.startingCost)) {
|
if (!p.canAfford(aug.baseCost)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -695,7 +695,7 @@ export class Sleeve extends Person {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
p.loseMoney(aug.startingCost, "sleeves");
|
p.loseMoney(aug.baseCost, "sleeves");
|
||||||
this.installAugmentation(aug);
|
this.installAugmentation(aug);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,7 @@ import { Sleeve } from "./Sleeve";
|
|||||||
import { IPlayer } from "../IPlayer";
|
import { IPlayer } from "../IPlayer";
|
||||||
|
|
||||||
import { Augmentation } from "../../Augmentation/Augmentation";
|
import { Augmentation } from "../../Augmentation/Augmentation";
|
||||||
import { Augmentations } from "../../Augmentation/Augmentations";
|
import { StaticAugmentations } from "../../Augmentation/StaticAugmentations";
|
||||||
import { Faction } from "../../Faction/Faction";
|
import { Faction } from "../../Faction/Faction";
|
||||||
import { Factions } from "../../Faction/Factions";
|
import { Factions } from "../../Faction/Factions";
|
||||||
|
|
||||||
@ -64,13 +64,13 @@ export function findSleevePurchasableAugs(sleeve: Sleeve, p: IPlayer): Augmentat
|
|||||||
if (p.inGang()) {
|
if (p.inGang()) {
|
||||||
const fac = p.getGangFaction();
|
const fac = p.getGangFaction();
|
||||||
|
|
||||||
for (const augName of Object.keys(Augmentations)) {
|
for (const augName of Object.keys(StaticAugmentations)) {
|
||||||
const aug = Augmentations[augName];
|
const aug = StaticAugmentations[augName];
|
||||||
if (!isAvailableForSleeve(aug)) {
|
if (!isAvailableForSleeve(aug)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fac.playerReputation > aug.baseRepRequirement) {
|
if (fac.playerReputation > aug.getCost(p).repCost) {
|
||||||
availableAugs.push(aug);
|
availableAugs.push(aug);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -89,12 +89,12 @@ export function findSleevePurchasableAugs(sleeve: Sleeve, p: IPlayer): Augmentat
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (const augName of fac.augmentations) {
|
for (const augName of fac.augmentations) {
|
||||||
const aug: Augmentation = Augmentations[augName];
|
const aug: Augmentation = StaticAugmentations[augName];
|
||||||
if (!isAvailableForSleeve(aug)) {
|
if (!isAvailableForSleeve(aug)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fac.playerReputation > aug.baseRepRequirement) {
|
if (fac.playerReputation > aug.getCost(p).repCost) {
|
||||||
availableAugs.push(aug);
|
availableAugs.push(aug);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -52,7 +52,7 @@ export function SleeveAugmentationsModal(props: IProps): React.ReactElement {
|
|||||||
ownedAugNames={ownedAugNames}
|
ownedAugNames={ownedAugNames}
|
||||||
player={player}
|
player={player}
|
||||||
canPurchase={(player, aug) => {
|
canPurchase={(player, aug) => {
|
||||||
return player.money > aug.startingCost;
|
return player.money > aug.baseCost;
|
||||||
}}
|
}}
|
||||||
purchaseAugmentation={(player, aug, _showModal) => {
|
purchaseAugmentation={(player, aug, _showModal) => {
|
||||||
props.sleeve.tryBuyAugmentation(player, aug);
|
props.sleeve.tryBuyAugmentation(player, aug);
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { FactionNames } from "./Faction/data/FactionNames";
|
import { FactionNames } from "./Faction/data/FactionNames";
|
||||||
import { CityName } from "./Locations/data/CityNames";
|
import { CityName } from "./Locations/data/CityNames";
|
||||||
import { Augmentations } from "./Augmentation/Augmentations";
|
import { StaticAugmentations } from "./Augmentation/StaticAugmentations";
|
||||||
import { augmentationExists, initAugmentations } from "./Augmentation/AugmentationHelpers";
|
import { augmentationExists, initAugmentations } from "./Augmentation/AugmentationHelpers";
|
||||||
import { AugmentationNames } from "./Augmentation/data/AugmentationNames";
|
import { AugmentationNames } from "./Augmentation/data/AugmentationNames";
|
||||||
import { initBitNodeMultipliers } from "./BitNode/BitNode";
|
import { initBitNodeMultipliers } from "./BitNode/BitNode";
|
||||||
@ -225,9 +225,9 @@ export function prestigeSourceFile(flume: boolean): void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Delete all Augmentations
|
// Delete all Augmentations
|
||||||
for (const name of Object.keys(Augmentations)) {
|
for (const name of Object.keys(StaticAugmentations)) {
|
||||||
if (Augmentations.hasOwnProperty(name)) {
|
if (StaticAugmentations.hasOwnProperty(name)) {
|
||||||
delete Augmentations[name];
|
delete StaticAugmentations[name];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,7 +4,6 @@ import ReactDOM from "react-dom";
|
|||||||
import { TTheme as Theme, ThemeEvents, refreshTheme } from "./Themes/ui/Theme";
|
import { TTheme as Theme, ThemeEvents, refreshTheme } from "./Themes/ui/Theme";
|
||||||
import { LoadingScreen } from "./ui/LoadingScreen";
|
import { LoadingScreen } from "./ui/LoadingScreen";
|
||||||
import { initElectron } from "./Electron";
|
import { initElectron } from "./Electron";
|
||||||
import { AlertEvents } from "./ui/React/AlertManager";
|
|
||||||
initElectron();
|
initElectron();
|
||||||
globalThis["React"] = React;
|
globalThis["React"] = React;
|
||||||
globalThis["ReactDOM"] = ReactDOM;
|
globalThis["ReactDOM"] = ReactDOM;
|
||||||
|
Loading…
Reference in New Issue
Block a user