bitburner-src/src/Faction/FactionHelpers.tsx
hydroflame 44641fee07
Merge pull request #3544 from phyzical/feature/refactor-augmentation
REFACTOR:  augmentation cost, rep cost and level to be calculated in place
2022-05-04 12:08:24 -04:00

173 lines
6.4 KiB
TypeScript

import { StaticAugmentations } from "../Augmentation/StaticAugmentations";
import { Augmentation } from "../Augmentation/Augmentation";
import { PlayerOwnedAugmentation } from "../Augmentation/PlayerOwnedAugmentation";
import { AugmentationNames } from "../Augmentation/data/AugmentationNames";
import { BitNodeMultipliers } from "../BitNode/BitNodeMultipliers";
import { Faction } from "./Faction";
import { Factions } from "./Factions";
import { Player } from "../Player";
import { IPlayer } from "../PersonObjects/IPlayer";
import { Settings } from "../Settings/Settings";
import {
getHackingWorkRepGain,
getFactionSecurityWorkRepGain,
getFactionFieldWorkRepGain,
} from "../PersonObjects/formulas/reputation";
import { dialogBoxCreate } from "../ui/React/DialogBox";
import { InvitationEvent } from "./ui/InvitationModal";
import { FactionNames } from "./data/FactionNames";
import { SFC32RNG } from "../Casino/RNG";
export function inviteToFaction(faction: Faction): void {
Player.receiveInvite(faction.name);
faction.alreadyInvited = true;
if (!Settings.SuppressFactionInvites) {
InvitationEvent.emit(faction);
}
}
export function joinFaction(faction: Faction): void {
if (faction.isMember) return;
faction.isMember = true;
Player.factions.push(faction.name);
const allFactions = Object.values(FactionNames).map((faction) => faction as string);
Player.factions.sort((a, b) => allFactions.indexOf(a) - allFactions.indexOf(b));
const factionInfo = faction.getInfo();
//Determine what factions you are banned from now that you have joined this faction
for (const enemy of factionInfo.enemies) {
if (Factions[enemy] instanceof Faction) {
Factions[enemy].isBanned = true;
}
}
for (let i = 0; i < Player.factionInvitations.length; ++i) {
if (Player.factionInvitations[i] == faction.name || Factions[Player.factionInvitations[i]].isBanned) {
Player.factionInvitations.splice(i, 1);
i--;
}
}
}
//Returns a boolean indicating whether the player has the prerequisites for the
//specified Augmentation
export function hasAugmentationPrereqs(aug: Augmentation): boolean {
return aug.prereqs.every((aug) => Player.hasAugmentation(aug));
}
export function purchaseAugmentation(aug: Augmentation, fac: Faction, sing = false): string {
const hasPrereqs = hasAugmentationPrereqs(aug);
const augCosts = aug.getCost(Player);
if (!hasPrereqs) {
const txt = `You must first purchase or install ${aug.prereqs
.filter((req) => !Player.hasAugmentation(req))
.join(",")} before you can purchase this one.`;
if (sing) {
return txt;
} else {
dialogBoxCreate(txt);
}
} else if (augCosts.moneyCost !== 0 && Player.money < augCosts.moneyCost) {
const txt = "You don't have enough money to purchase " + aug.name;
if (sing) {
return txt;
}
dialogBoxCreate(txt);
} else if (fac.playerReputation < augCosts.repCost) {
const txt = "You don't have enough faction reputation to purchase " + aug.name;
if (sing) {
return txt;
}
dialogBoxCreate(txt);
} else if (augCosts.moneyCost === 0 || Player.money >= augCosts.moneyCost) {
const queuedAugmentation = new PlayerOwnedAugmentation(aug.name);
if (aug.name == AugmentationNames.NeuroFluxGovernor) {
queuedAugmentation.level = aug.getLevel(Player);
}
Player.queuedAugmentations.push(queuedAugmentation);
Player.loseMoney(augCosts.moneyCost, "augmentations");
if (sing) {
return "You purchased " + aug.name;
} else if (!Settings.SuppressBuyAugmentationConfirmation) {
dialogBoxCreate(
"You purchased " +
aug.name +
". Its enhancements will not take " +
"effect until they are installed. To install your augmentations, go to the " +
"'Augmentations' tab on the left-hand navigation menu. Purchasing additional " +
"augmentations will now be more expensive.",
);
}
} else {
dialogBoxCreate(
"Hmm, something went wrong when trying to purchase an Augmentation. " +
"Please report this to the game developer with an explanation of how to " +
"reproduce this.",
);
}
return "";
}
export function processPassiveFactionRepGain(numCycles: number): void {
for (const name of Object.keys(Factions)) {
if (name === Player.currentWorkFactionName) continue;
if (!Factions.hasOwnProperty(name)) continue;
const faction = Factions[name];
if (!faction.isMember) continue;
// No passive rep for special factions
const info = faction.getInfo();
if (!info.offersWork()) continue;
// No passive rep for gangs.
if (Player.getGangName() === name) continue;
// 0 favor = 1%/s
// 50 favor = 6%/s
// 100 favor = 11%/s
const favorMult = Math.min(0.1, faction.favor / 1000 + 0.01);
// Find the best of all possible favor gain, minimum 1 rep / 2 minute.
const hRep = getHackingWorkRepGain(Player, faction);
const sRep = getFactionSecurityWorkRepGain(Player, faction);
const fRep = getFactionFieldWorkRepGain(Player, faction);
const rate = Math.max(hRep * favorMult, sRep * favorMult, fRep * favorMult, 1 / 120);
faction.playerReputation += rate * numCycles * Player.faction_rep_mult * BitNodeMultipliers.FactionPassiveRepGain;
}
}
export const getFactionAugmentationsFiltered = (player: IPlayer, faction: Faction): string[] => {
// If player has a gang with this faction, return (almost) all augmentations
if (player.hasGangWith(faction.name)) {
let augs = Object.values(StaticAugmentations);
// Remove special augs
augs = augs.filter((a) => !a.isSpecial && a.name !== AugmentationNames.CongruityImplant);
if (player.bitNodeN === 2) {
// TRP is not available outside of BN2 for Gangs
augs.push(StaticAugmentations[AugmentationNames.TheRedPill]);
}
const rng = SFC32RNG(`BN${player.bitNodeN}.${player.sourceFileLvl(player.bitNodeN)}`);
// Remove faction-unique augs that don't belong to this faction
const uniqueFilter = (a: Augmentation): boolean => {
// Keep all the non-unique one
if (a.factions.length > 1) {
return true;
}
// Keep all the ones that this faction has anyway.
if (faction.augmentations.includes(a.name)) {
return true;
}
return rng() >= 1 - BitNodeMultipliers.GangUniqueAugs;
};
augs = augs.filter(uniqueFilter);
return augs.map((a) => a.name);
}
return faction.augmentations.slice();
};