mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2026-05-05 07:07:50 +02:00
TYPESAFETY: Strict internal typing for AugmentationName (#608)
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
import type { AugmentationName } from "@enums";
|
||||
import { FactionInfo, FactionInfos } from "./FactionInfo";
|
||||
import { favorToRep, repToFavor } from "./formulas/favor";
|
||||
import { Generic_fromJSON, Generic_toJSON, IReviverValue, constructorsForReviver } from "../utils/JSONReviver";
|
||||
import { getEnumHelper } from "../utils/EnumHelper";
|
||||
|
||||
export class Faction {
|
||||
/**
|
||||
@@ -10,7 +12,7 @@ export class Faction {
|
||||
alreadyInvited = false;
|
||||
|
||||
/** Holds names of all augmentations that this Faction offers */
|
||||
augmentations: string[] = [];
|
||||
augmentations: AugmentationName[] = [];
|
||||
|
||||
/** Amount of favor the player has with this faction. */
|
||||
favor = 0;
|
||||
@@ -67,7 +69,11 @@ export class Faction {
|
||||
|
||||
/** Initializes a Faction object from a JSON save state. */
|
||||
static fromJSON(value: IReviverValue): Faction {
|
||||
return Generic_fromJSON(Faction, value.data);
|
||||
const faction = Generic_fromJSON(Faction, value.data);
|
||||
// Remove invalid augs from faction. Augs are repopulated with correct augs during any reset.
|
||||
const augHelper = getEnumHelper("AugmentationName");
|
||||
faction.augmentations = faction.augmentations.filter((augName) => augHelper.isMember(augName));
|
||||
return faction;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { StaticAugmentations } from "../Augmentation/StaticAugmentations";
|
||||
import { Augmentations } from "../Augmentation/Augmentations";
|
||||
import { Augmentation } from "../Augmentation/Augmentation";
|
||||
import { PlayerOwnedAugmentation } from "../Augmentation/PlayerOwnedAugmentation";
|
||||
import { AugmentationName, FactionName } from "@enums";
|
||||
import { BitNodeMultipliers } from "../BitNode/BitNodeMultipliers";
|
||||
import { currentNodeMults } from "../BitNode/BitNodeMultipliers";
|
||||
|
||||
import { Faction } from "./Faction";
|
||||
import { Factions } from "./Factions";
|
||||
@@ -18,6 +18,7 @@ import { dialogBoxCreate } from "../ui/React/DialogBox";
|
||||
import { InvitationEvent } from "./ui/InvitationModal";
|
||||
import { SFC32RNG } from "../Casino/RNG";
|
||||
import { isFactionWork } from "../Work/FactionWork";
|
||||
import { getAugCost } from "../Augmentation/AugmentationHelpers";
|
||||
|
||||
export function inviteToFaction(faction: Faction): void {
|
||||
Player.receiveInvite(faction.name);
|
||||
@@ -55,7 +56,7 @@ export function hasAugmentationPrereqs(aug: Augmentation): boolean {
|
||||
|
||||
export function purchaseAugmentation(aug: Augmentation, fac: Faction, sing = false): string {
|
||||
const hasPrereqs = hasAugmentationPrereqs(aug);
|
||||
const augCosts = aug.getCost();
|
||||
const augCosts = getAugCost(aug);
|
||||
if (!hasPrereqs) {
|
||||
const txt = `You must first purchase or install ${aug.prereqs
|
||||
.filter((req) => !Player.hasAugmentation(req))
|
||||
@@ -127,21 +128,21 @@ export function processPassiveFactionRepGain(numCycles: number): void {
|
||||
const fRep = getFactionFieldWorkRepGain(Player, faction.favor);
|
||||
const rate = Math.max(hRep * favorMult, sRep * favorMult, fRep * favorMult, 1 / 120);
|
||||
|
||||
faction.playerReputation += rate * numCycles * Player.mults.faction_rep * BitNodeMultipliers.FactionPassiveRepGain;
|
||||
faction.playerReputation += rate * numCycles * Player.mults.faction_rep * currentNodeMults.FactionPassiveRepGain;
|
||||
}
|
||||
}
|
||||
|
||||
export const getFactionAugmentationsFiltered = (faction: Faction): string[] => {
|
||||
export const getFactionAugmentationsFiltered = (faction: Faction): AugmentationName[] => {
|
||||
// If player has a gang with this faction, return (almost) all augmentations
|
||||
if (Player.hasGangWith(faction.name)) {
|
||||
let augs = Object.values(StaticAugmentations);
|
||||
let augs = Object.values(Augmentations);
|
||||
|
||||
// Remove special augs
|
||||
augs = augs.filter((a) => !a.isSpecial && a.name !== AugmentationName.CongruityImplant);
|
||||
|
||||
if (Player.bitNodeN === 2) {
|
||||
// TRP is not available outside of BN2 for Gangs
|
||||
augs.push(StaticAugmentations[AugmentationName.TheRedPill]);
|
||||
augs.push(Augmentations[AugmentationName.TheRedPill]);
|
||||
}
|
||||
|
||||
const rng = SFC32RNG(`BN${Player.bitNodeN}.${Player.sourceFileLvl(Player.bitNodeN)}`);
|
||||
@@ -156,7 +157,7 @@ export const getFactionAugmentationsFiltered = (faction: Faction): string[] => {
|
||||
return true;
|
||||
}
|
||||
|
||||
return rng() >= 1 - BitNodeMultipliers.GangUniqueAugs;
|
||||
return rng() >= 1 - currentNodeMults.GangUniqueAugs;
|
||||
};
|
||||
augs = augs.filter(uniqueFilter);
|
||||
|
||||
|
||||
@@ -6,6 +6,8 @@ import { Faction } from "./Faction";
|
||||
import { FactionInfos } from "./FactionInfo";
|
||||
|
||||
import { Reviver } from "../utils/JSONReviver";
|
||||
import { getRecordValues } from "../Types/Record";
|
||||
import { Augmentations, initCircadianModulator } from "../Augmentation/Augmentations";
|
||||
|
||||
export let Factions: Record<string, Faction> = {};
|
||||
|
||||
@@ -47,4 +49,16 @@ function resetFaction(newFactionObject: Faction): void {
|
||||
delete Factions[factionName];
|
||||
}
|
||||
AddToFactions(newFactionObject);
|
||||
// All factions are added, this is a good place to add augs back to factions.
|
||||
initCircadianModulator();
|
||||
for (const aug of getRecordValues(Augmentations)) {
|
||||
for (const factionName of aug.factions) {
|
||||
const faction = Factions[factionName];
|
||||
if (!faction) {
|
||||
console.error(`Faction ${factionName} did not exist while adding augs to factions`);
|
||||
continue;
|
||||
}
|
||||
faction.augmentations.push(aug.name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { CONSTANTS } from "../../Constants";
|
||||
import { BitNodeMultipliers } from "../../BitNode/BitNodeMultipliers";
|
||||
import { currentNodeMults } from "../../BitNode/BitNodeMultipliers";
|
||||
import { Person as IPerson } from "@nsdefs";
|
||||
|
||||
export function repFromDonation(amt: number, person: IPerson): number {
|
||||
return (amt / CONSTANTS.DonateMoneyToRepDivisor) * person.mults.faction_rep * BitNodeMultipliers.FactionWorkRepGain;
|
||||
return (amt / CONSTANTS.DonateMoneyToRepDivisor) * person.mults.faction_rep * currentNodeMults.FactionWorkRepGain;
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { Box, Button, Tooltip, Typography, Paper, Container } from "@mui/material";
|
||||
import React from "react";
|
||||
|
||||
import { StaticAugmentations } from "../../Augmentation/StaticAugmentations";
|
||||
import { getGenericAugmentationPriceMultiplier } from "../../Augmentation/AugmentationHelpers";
|
||||
import { Augmentations } from "../../Augmentation/Augmentations";
|
||||
import { getAugCost, getGenericAugmentationPriceMultiplier } from "../../Augmentation/AugmentationHelpers";
|
||||
import { AugmentationName, FactionName } from "@enums";
|
||||
import { PurchasableAugmentations } from "../../Augmentation/ui/PurchasableAugmentations";
|
||||
import { PurchaseAugmentationsOrderSetting } from "../../Settings/SettingEnums";
|
||||
@@ -25,11 +25,11 @@ interface IProps {
|
||||
export function AugmentationsPage(props: IProps): React.ReactElement {
|
||||
const rerender = useRerender();
|
||||
|
||||
function getAugs(): string[] {
|
||||
function getAugs(): AugmentationName[] {
|
||||
return getFactionAugmentationsFiltered(props.faction);
|
||||
}
|
||||
|
||||
function getAugsSorted(): string[] {
|
||||
function getAugsSorted(): AugmentationName[] {
|
||||
switch (Settings.PurchaseAugmentationsOrder) {
|
||||
case PurchaseAugmentationsOrderSetting.Cost: {
|
||||
return getAugsSortedByCost();
|
||||
@@ -45,26 +45,26 @@ export function AugmentationsPage(props: IProps): React.ReactElement {
|
||||
}
|
||||
}
|
||||
|
||||
function getAugsSortedByCost(): string[] {
|
||||
function getAugsSortedByCost(): AugmentationName[] {
|
||||
const augs = getAugs();
|
||||
augs.sort((augName1, augName2) => {
|
||||
const aug1 = StaticAugmentations[augName1],
|
||||
aug2 = StaticAugmentations[augName2];
|
||||
const aug1 = Augmentations[augName1],
|
||||
aug2 = Augmentations[augName2];
|
||||
if (aug1 == null || aug2 == null) {
|
||||
throw new Error("Invalid Augmentation Names");
|
||||
}
|
||||
|
||||
return aug1.getCost().moneyCost - aug2.getCost().moneyCost;
|
||||
return getAugCost(aug1).moneyCost - getAugCost(aug2).moneyCost;
|
||||
});
|
||||
|
||||
return augs;
|
||||
}
|
||||
|
||||
function getAugsSortedByPurchasable(): string[] {
|
||||
function getAugsSortedByPurchasable(): AugmentationName[] {
|
||||
const augs = getAugs();
|
||||
function canBuy(augName: string): boolean {
|
||||
const aug = StaticAugmentations[augName];
|
||||
const augCosts = aug.getCost();
|
||||
function canBuy(augName: AugmentationName): boolean {
|
||||
const aug = Augmentations[augName];
|
||||
const augCosts = getAugCost(aug);
|
||||
const repCost = augCosts.repCost;
|
||||
const hasReq = props.faction.playerReputation >= repCost;
|
||||
const hasRep = hasAugmentationPrereqs(aug);
|
||||
@@ -72,43 +72,43 @@ export function AugmentationsPage(props: IProps): React.ReactElement {
|
||||
return hasCost && hasReq && hasRep;
|
||||
}
|
||||
const buy = augs.filter(canBuy).sort((augName1, augName2) => {
|
||||
const aug1 = StaticAugmentations[augName1],
|
||||
aug2 = StaticAugmentations[augName2];
|
||||
const aug1 = Augmentations[augName1],
|
||||
aug2 = Augmentations[augName2];
|
||||
if (aug1 == null || aug2 == null) {
|
||||
throw new Error("Invalid Augmentation Names");
|
||||
}
|
||||
|
||||
return aug1.getCost().moneyCost - aug2.getCost().moneyCost;
|
||||
return getAugCost(aug1).moneyCost - getAugCost(aug2).moneyCost;
|
||||
});
|
||||
const cantBuy = augs
|
||||
.filter((aug) => !canBuy(aug))
|
||||
.sort((augName1, augName2) => {
|
||||
const aug1 = StaticAugmentations[augName1],
|
||||
aug2 = StaticAugmentations[augName2];
|
||||
const aug1 = Augmentations[augName1],
|
||||
aug2 = Augmentations[augName2];
|
||||
if (aug1 == null || aug2 == null) {
|
||||
throw new Error("Invalid Augmentation Names");
|
||||
}
|
||||
return aug1.getCost().repCost - aug2.getCost().repCost;
|
||||
return getAugCost(aug1).repCost - getAugCost(aug2).repCost;
|
||||
});
|
||||
|
||||
return buy.concat(cantBuy);
|
||||
}
|
||||
|
||||
function getAugsSortedByReputation(): string[] {
|
||||
function getAugsSortedByReputation(): AugmentationName[] {
|
||||
const augs = getAugs();
|
||||
augs.sort((augName1, augName2) => {
|
||||
const aug1 = StaticAugmentations[augName1],
|
||||
aug2 = StaticAugmentations[augName2];
|
||||
const aug1 = Augmentations[augName1],
|
||||
aug2 = Augmentations[augName2];
|
||||
if (aug1 == null || aug2 == null) {
|
||||
throw new Error("Invalid Augmentation Names");
|
||||
}
|
||||
return aug1.getCost().repCost - aug2.getCost().repCost;
|
||||
return getAugCost(aug1).repCost - getAugCost(aug2).repCost;
|
||||
});
|
||||
|
||||
return augs;
|
||||
}
|
||||
|
||||
function getAugsSortedByDefault(): string[] {
|
||||
function getAugsSortedByDefault(): AugmentationName[] {
|
||||
return getAugs();
|
||||
}
|
||||
|
||||
@@ -123,7 +123,7 @@ export function AugmentationsPage(props: IProps): React.ReactElement {
|
||||
aug === AugmentationName.NeuroFluxGovernor ||
|
||||
(!Player.augmentations.some((a) => a.name === aug) && !Player.queuedAugmentations.some((a) => a.name === aug)),
|
||||
);
|
||||
const owned = augs.filter((aug: string) => !purchasable.includes(aug));
|
||||
const owned = augs.filter((aug) => !purchasable.includes(aug));
|
||||
|
||||
const multiplierComponent =
|
||||
props.faction.name !== FactionName.ShadowsOfAnarchy ? (
|
||||
@@ -213,7 +213,7 @@ export function AugmentationsPage(props: IProps): React.ReactElement {
|
||||
augNames={purchasable}
|
||||
ownedAugNames={owned}
|
||||
canPurchase={(aug) => {
|
||||
const costs = aug.getCost();
|
||||
const costs = getAugCost(aug);
|
||||
return (
|
||||
hasAugmentationPrereqs(aug) &&
|
||||
props.faction.playerReputation >= costs.repCost &&
|
||||
|
||||
@@ -12,7 +12,7 @@ import { Option } from "./Option";
|
||||
|
||||
import { CONSTANTS } from "../../Constants";
|
||||
|
||||
import { BitNodeMultipliers } from "../../BitNode/BitNodeMultipliers";
|
||||
import { currentNodeMults } from "../../BitNode/BitNodeMultipliers";
|
||||
import { Faction } from "../Faction";
|
||||
|
||||
import { Router } from "../../ui/GameRoot";
|
||||
@@ -107,7 +107,7 @@ function MainPage({ faction, rerender, onAugmentations }: IMainProps): React.Rea
|
||||
|
||||
// Flags for whether special options (gang, sleeve purchases, donate, etc.)
|
||||
// should be shown
|
||||
const favorToDonate = Math.floor(CONSTANTS.BaseFavorToDonate * BitNodeMultipliers.RepToDonateToFaction);
|
||||
const favorToDonate = Math.floor(CONSTANTS.BaseFavorToDonate * currentNodeMults.RepToDonateToFaction);
|
||||
const canDonate = faction.favor >= favorToDonate;
|
||||
|
||||
const canPurchaseSleeves = faction.name === FactionName.TheCovenant && Player.bitNodeN === 10;
|
||||
|
||||
Reference in New Issue
Block a user