Update infiltrators

This commit is contained in:
Olivier Gagnon 2022-04-22 15:30:49 -04:00
parent adbd6c3486
commit 9fdfb77dd4
30 changed files with 163 additions and 308 deletions

@ -348,15 +348,15 @@ function generateStatsDescription(mults: IMap<number>, programs?: string[], star
desc = ( desc = (
<> <>
{desc} {desc}
<br />+{f(mults.infiltration_base_rep_increase - 1)} Infiltration {FactionNames.Infiltrators} Reputation base <br />+{f(mults.infiltration_base_rep_increase - 1)} Infiltration {FactionNames.ShadowsOfAnarchy} Reputation
reward base reward
</> </>
); );
if (mults.infiltration_rep_mult) if (mults.infiltration_rep_mult)
desc = ( desc = (
<> <>
{desc} {desc}
<br />+{f(mults.infiltration_rep_mult - 1)} Infiltration {FactionNames.Infiltrators} Reputation reward <br />+{f(mults.infiltration_rep_mult - 1)} Infiltration {FactionNames.ShadowsOfAnarchy} Reputation reward
</> </>
); );
if (mults.infiltration_trade_mult) if (mults.infiltration_trade_mult)

@ -16,7 +16,7 @@ import {
initBladeburnerAugmentations, initBladeburnerAugmentations,
initChurchOfTheMachineGodAugmentations, initChurchOfTheMachineGodAugmentations,
initGeneralAugmentations, initGeneralAugmentations,
initInfiltratorsAugmentations, initSoAAugmentations,
initNeuroFluxGovernor, initNeuroFluxGovernor,
initUnstableCircadianModulator, initUnstableCircadianModulator,
} from "./data/AugmentationCreator"; } from "./data/AugmentationCreator";
@ -51,7 +51,7 @@ function createAugmentations(): void {
initNeuroFluxGovernor(), initNeuroFluxGovernor(),
initUnstableCircadianModulator(), initUnstableCircadianModulator(),
...initGeneralAugmentations(), ...initGeneralAugmentations(),
...initInfiltratorsAugmentations(), ...initSoAAugmentations(),
...(factionExists(FactionNames.Bladeburners) ? initBladeburnerAugmentations() : []), ...(factionExists(FactionNames.Bladeburners) ? initBladeburnerAugmentations() : []),
...(factionExists(FactionNames.ChurchOfTheMachineGod) ? initChurchOfTheMachineGodAugmentations() : []), ...(factionExists(FactionNames.ChurchOfTheMachineGod) ? initChurchOfTheMachineGodAugmentations() : []),
].map(resetAugmentation); ].map(resetAugmentation);
@ -94,13 +94,15 @@ function updateNeuroFluxGovernorCosts(neuroFluxGovernorAugmentation: Augmentatio
} }
} }
function updateInfiltratorCosts(infiltratorAugmentation: Augmentation): void { function updateSoACosts(soaAugmentation: Augmentation): void {
const infiltratorAugmentationNames = initInfiltratorsAugmentations().map((augmentation) => augmentation.name); const soaAugmentationNames = initSoAAugmentations().map((augmentation) => augmentation.name);
const infiltratorMultiplier = const soaAugCount = soaAugmentationNames.filter((augmentationName) =>
infiltratorAugmentationNames.filter((augmentationName) => Player.hasAugmentation(augmentationName)).length + 1; Player.hasAugmentation(augmentationName),
infiltratorAugmentation.baseCost = Math.pow(infiltratorAugmentation.startingCost * 1000, infiltratorMultiplier); ).length;
if (infiltratorAugmentationNames.find((augmentationName) => augmentationName === infiltratorAugmentation.name)) { soaAugmentation.baseCost = soaAugmentation.startingCost * Math.pow(CONSTANTS.SoACostMult, soaAugCount);
infiltratorAugmentation.baseRepRequirement = infiltratorAugmentation.startingRepRequirement * infiltratorMultiplier; if (soaAugmentationNames.find((augmentationName) => augmentationName === soaAugmentation.name)) {
soaAugmentation.baseRepRequirement =
soaAugmentation.startingRepRequirement * Math.pow(CONSTANTS.SoARepMult, soaAugCount);
} }
} }
@ -110,8 +112,8 @@ export function updateAugmentationCosts(): void {
const augmentationToUpdate = Augmentations[name]; const augmentationToUpdate = Augmentations[name];
if (augmentationToUpdate.name === AugmentationNames.NeuroFluxGovernor) { if (augmentationToUpdate.name === AugmentationNames.NeuroFluxGovernor) {
updateNeuroFluxGovernorCosts(augmentationToUpdate); updateNeuroFluxGovernorCosts(augmentationToUpdate);
} else if (augmentationToUpdate.factions.includes(FactionNames.Infiltrators)) { } else if (augmentationToUpdate.factions.includes(FactionNames.ShadowsOfAnarchy)) {
updateInfiltratorCosts(augmentationToUpdate); updateSoACosts(augmentationToUpdate);
} else { } else {
augmentationToUpdate.baseCost = augmentationToUpdate.baseCost =
augmentationToUpdate.startingCost * augmentationToUpdate.startingCost *

@ -96,159 +96,96 @@ function getRandomBonus(): any {
return bonuses[Math.floor(bonuses.length * randomNumber.random())]; return bonuses[Math.floor(bonuses.length * randomNumber.random())];
} }
export const initInfiltratorsAugmentations = (): Augmentation[] => [ export const initSoAAugmentations = (): Augmentation[] => [
new Augmentation({ new Augmentation({
name: AugmentationNames.BionicFingers, name: AugmentationNames.WKSharmonizer,
repCost: 15e1, repCost: 1e4,
moneyCost: 1e6, moneyCost: 1e6,
infiltration_base_rep_increase: 5,
info: info:
"This state of the art augmentation removes the need for bones and tendons in your fingers, " + `A copy of the WKS harmonizer from the MIA leader of the ${FactionNames.ShadowsOfAnarchy} ` +
"with this you will have the dexterity equal to the best rubik's cube player in the world. ", "injects *Γ-based cells that provides general enhancement to the body.",
factions: [FactionNames.Infiltrators], stats: (
<>
This augmentation makes many aspect of infiltration easier and more productive. Such as increased timer,
rewards, reduced damage taken, etc.
</>
),
factions: [FactionNames.ShadowsOfAnarchy],
}), }),
new Augmentation({ new Augmentation({
name: AugmentationNames.CorporationManagementImplant, name: AugmentationNames.MightOfAres,
repCost: 25e1, repCost: 1e4,
moneyCost: 1e6,
infiltration_rep_mult: 2.5,
info:
"As time went on corporations realized that managers were redundant if they could be replaced by AI chips " +
"implanted directly in the brain, and so this implant was developed which could analyse the users brain " +
"to find the perfect tone and sounding voice to increase productivity of the user to maximum profits.",
factions: [FactionNames.Infiltrators],
}),
new Augmentation({
name: AugmentationNames.TranslationCircuit,
repCost: 5e2,
moneyCost: 1e6,
infiltration_trade_mult: 1.5,
info:
"A state of the art circuit module that manipulates the users voice to suit the needs of the situation, " +
"allowing the people listening to feel more persuaded by whats said due to the voice being auto translated " +
"to the listeners accent and language.",
factions: [FactionNames.Infiltrators],
}),
new Augmentation({
name: AugmentationNames.GoldenSuiteCase,
repCost: 5e2,
moneyCost: 1e6,
infiltration_sell_mult: 1.5,
info:
"Some say too much money is a curse, those people clearly have never owned a golden suitcase. it might be " +
"a bit heavier but it sure does make anything inside it look a lot more valuable.",
factions: [FactionNames.Infiltrators],
}),
new Augmentation({
name: AugmentationNames.TimeDilationInjection,
repCost: 5e2,
moneyCost: 1e6,
infiltration_timer_mult: 1.3,
info:
"Injected directly into the user eyes, as the serum seeps into the brain via the optic nerves perception " +
"of time begins to slow down allowing you to take more time to do things than the average person",
factions: [FactionNames.Infiltrators],
}),
new Augmentation({
name: AugmentationNames.BitaniumArmorAlloy,
repCost: 5e2,
moneyCost: 1e6,
infiltration_damage_reduction_mult: 0.7,
info:
`Deep in the mines of ${CityName.Ishima} miners found a strange new material, now known as bitanium. After ` +
"many iterations of experimenting it was found to be exceptional at increasing ones armor at absorbing " +
"blunt damage when used as an alloy with almost any other metal you can think of.",
factions: [FactionNames.Infiltrators],
}),
new Augmentation({
name: AugmentationNames.PythiasBrainStem,
repCost: 1e2,
moneyCost: 1e6, moneyCost: 1e6,
info: info:
"You found an old jar apparently containing the brain stem of one of the most famous " + "Extra-occular neurons taken from old martial art master. Injecting the user the ability to " +
"fortune tellers in the world, installing this augmentation will apparently connect the synapses reactivating " + "predict enemy attack before they even know it themself.",
"the magic this man once shared with the world ",
stats: ( stats: (
<>This augmentation makes the Slash minigame easier by showing you via an indictor when the slash in coming.</> <>This augmentation makes the Slash minigame easier by showing you via an indictor when the slash in coming.</>
), ),
factions: [FactionNames.Infiltrators], factions: [FactionNames.ShadowsOfAnarchy],
}), }),
new Augmentation({ new Augmentation({
name: AugmentationNames.IntellisenseModule, name: AugmentationNames.WisdomOfAthena,
repCost: 1e2, repCost: 1e4,
moneyCost: 1e6, moneyCost: 1e6,
info: info: "A connective brain implant to SASHA that focuses in pattern recognition and predictive templating.",
"A brain implant with AI power that focuses in auto linting and intellisense, which " +
"provides the ability to perform code completion better than any existing " +
"IDE environment on the market to date.",
stats: <>This augmentation makes the Bracket minigame easier by removing all '[' ']'.</>, stats: <>This augmentation makes the Bracket minigame easier by removing all '[' ']'.</>,
factions: [FactionNames.Infiltrators], factions: [FactionNames.ShadowsOfAnarchy],
}), }),
new Augmentation({ new Augmentation({
name: AugmentationNames.RearViewMirrorShoulderAttachment, name: AugmentationNames.ChaosOfDionysus,
repCost: 1e2, repCost: 1e4,
moneyCost: 1e6, moneyCost: 1e6,
info: "Never again will you need to turn your head to see whats behind you.", info: "Opto-occipito implant to process visual signal before brain interpretation.",
stats: <>This augmentation makes the Backwards minigame easier by making the words no longer backwards.</>, stats: <>This augmentation makes the Backwards minigame easier by flipping the words.</>,
factions: [FactionNames.Infiltrators], factions: [FactionNames.ShadowsOfAnarchy],
}), }),
new Augmentation({ new Augmentation({
name: AugmentationNames.KyberCrystalInjection, name: AugmentationNames.BeautyOfAphrodite,
repCost: 1e2, repCost: 1e4,
moneyCost: 1e6, moneyCost: 1e6,
info: info:
"A weird looking shiny crystal which is crushed down and turned into a thick syrup, " + "Pheromone extruder injected in the thoracodorsal nerve. Emits pleasing scent guaranteed to " +
"most people think its all homeopathic but there are a few that believe when injected people will " + "make conversational partners more agreeable.",
"believe what you say with one wave of the hand ",
stats: <>This augmentation makes the Bribe minigame easier by indicating the incorrect paths.</>, stats: <>This augmentation makes the Bribe minigame easier by indicating the incorrect paths.</>,
factions: [FactionNames.Infiltrators], factions: [FactionNames.ShadowsOfAnarchy],
}), }),
new Augmentation({ new Augmentation({
name: AugmentationNames.DyslexiaModule, name: AugmentationNames.TrickeryOfHermes,
repCost: 1e2, repCost: 1e4,
moneyCost: 1e6, moneyCost: 1e6,
info: info: "Penta-dynamo-neurovascular-valve inserted in the carpal ligament, enhances dexterity.",
"A module initially developed to reverse the affliction of dyslexia, But during human trials it was found " +
"to actually cause dyslexia, despite the fact scientists decided to sell it anyway. Who would want " +
"to install something like that... i guess it has the added benefit of qualifying for a disability card",
stats: <>This augmentation makes the Cheat Code minigame easier by allowing the opposite character.</>, stats: <>This augmentation makes the Cheat Code minigame easier by allowing the opposite character.</>,
factions: [FactionNames.Infiltrators], factions: [FactionNames.ShadowsOfAnarchy],
}), }),
new Augmentation({ new Augmentation({
name: AugmentationNames.CyberDecoder, name: AugmentationNames.FloodOfPoseidon,
repCost: 1e2, repCost: 1e4,
moneyCost: 1e6, moneyCost: 1e6,
info: info: "Transtinatium VVD reticulator used in optico-sterbing recognition.",
"A cool looking do hickey that oddly resembles Keanu Reeves face, " +
"it has a usb cable that looks like it plugs into something.",
stats: <>This augmentation makes the Symbol matching minigame easier by indicating the correct choice.</>, stats: <>This augmentation makes the Symbol matching minigame easier by indicating the correct choice.</>,
factions: [FactionNames.Infiltrators], factions: [FactionNames.ShadowsOfAnarchy],
}), }),
new Augmentation({ new Augmentation({
name: AugmentationNames.MineDetectionArmAttachment, name: AugmentationNames.HuntOfArtemis,
repCost: 1e2, repCost: 1e4,
moneyCost: 1e6, moneyCost: 1e6,
info: info: "magneto-turboencabulator based on technology by Micha Eike Siemon, increases the users electro-magnetic sensitivity.",
"You stumble across an old mine detection arm attachment at an army surplus store, " +
"on the side is inscribed 'X(' i wonder what happened to the original owner, " +
"its a bit beaten up but looks like it should still do the job.",
stats: ( stats: (
<> <>
This augmentation makes the Minesweeper minigame easier by showing the location of all mines and keeping their This augmentation makes the Minesweeper minigame easier by showing the location of all mines and keeping their
position. position.
</> </>
), ),
factions: [FactionNames.Infiltrators], factions: [FactionNames.ShadowsOfAnarchy],
}), }),
new Augmentation({ new Augmentation({
name: AugmentationNames.SecurityWireContacts, name: AugmentationNames.KnowledgeOfApollo,
repCost: 1e2, repCost: 1e4,
moneyCost: 1e6, moneyCost: 1e6,
info: info: "Neodynic retention fjengeln spoofer using -φ karmions, net positive effect on implantees delta wave.",
"This augment is a set of contacts for your eyes when installed allows for the user to see which" +
"wires are conducting security related information",
stats: <>This augmentation makes the Wire Cutting minigame easier by indicating the incorrect wires.</>, stats: <>This augmentation makes the Wire Cutting minigame easier by indicating the incorrect wires.</>,
factions: [FactionNames.Infiltrators], factions: [FactionNames.ShadowsOfAnarchy],
}), }),
]; ];
@ -2095,7 +2032,7 @@ export function initNeuroFluxGovernor(): Augmentation {
work_money_mult: 1.01 + donationBonus, work_money_mult: 1.01 + donationBonus,
factions: Object.values(FactionNames).filter( factions: Object.values(FactionNames).filter(
(factionName) => (factionName) =>
![FactionNames.Infiltrators, FactionNames.Bladeburners, FactionNames.ChurchOfTheMachineGod].includes( ![FactionNames.ShadowsOfAnarchy, FactionNames.Bladeburners, FactionNames.ChurchOfTheMachineGod].includes(
factionName, factionName,
), ),
), ),

@ -114,22 +114,27 @@ export enum AugmentationNames {
StaneksGift2 = "Stanek's Gift - Awakening", StaneksGift2 = "Stanek's Gift - Awakening",
StaneksGift3 = "Stanek's Gift - Serenity", StaneksGift3 = "Stanek's Gift - Serenity",
/*
MightOfAres = "Might of Ares", // slash
WisdomOfAthena = "Wisdom of Athena", // bracket
TrickeryOfHermes = "Trickery of Hermes", // cheatcode
BeautyOfAphrodite = "Beauty of Aphrodite", // bribe
ChaosOfDionysus = "Chaos of Dionysus", // reverse
FloodOfPoseidon = "Flood of Poseidon", // hex
HuntOfArtemis = "Hunt of Artemis", // mine
KnowledgeOfApollo = "Knowledge of Apollo", // wire
*/
// Infiltrators MiniGames // Infiltrators MiniGames
PythiasBrainStem = "Pythia's Brain Stem", MightOfAres = "SoA - Might of Ares", // slash
IntellisenseModule = "Intellisense Module", WisdomOfAthena = "SoA - Wisdom of Athena", // bracket
DyslexiaModule = "Dyslexia Module", TrickeryOfHermes = "SoA - Trickery of Hermes", // cheatcode
KyberCrystalInjection = "Kyber Crystal Injection", BeautyOfAphrodite = "SoA - Beauty of Aphrodite", // bribe
RearViewMirrorShoulderAttachment = "Rear View Mirror Shoulder Attachment", ChaosOfDionysus = "SoA - Chaos of Dionysus", // reverse
CyberDecoder = "Cyber Decoder", FloodOfPoseidon = "SoA - Flood of Poseidon", // hex
MineDetectionArmAttachment = "Mine Detection Arm Attachment", HuntOfArtemis = "SoA - Hunt of Artemis", // mine
SecurityWireContacts = "Security Wire Contacts", KnowledgeOfApollo = "SoA - Knowledge of Apollo", // wire
// Infiltrators general WKSharmonizer = "SoA - phyzical WKS harmonizer",
BionicFingers = "Bionic Fingers",
CorporationManagementImplant = "Corporation Management Implant",
TranslationCircuit = "Translation Circuit",
GoldenSuiteCase = "Golden Suite Case",
TimeDilationInjection = "Time Dilation Injection",
BitaniumArmorAlloy = "Bitanium Armor Alloy",
//Wasteland Augs //Wasteland Augs
//PepBoy: "P.E.P-Boy", Plasma Energy Projection System //PepBoy: "P.E.P-Boy", Plasma Energy Projection System

@ -254,41 +254,6 @@ export function PlayerMultipliers(): React.ReactElement {
); );
} }
rightColData.push(
...[
[
"Infiltrator Rep reward",
Player.infiltration_rep_mult,
Player.infiltration_rep_mult * mults.infiltration_rep_mult,
1,
],
[
"Infiltration sell",
Player.infiltration_sell_mult,
Player.infiltration_sell_mult * mults.infiltration_sell_mult,
1,
],
[
"Infiltration trade",
Player.infiltration_trade_mult,
Player.infiltration_trade_mult * mults.infiltration_trade_mult,
1,
],
[
"Infiltration minigame timer",
Player.infiltration_timer_mult,
Player.infiltration_timer_mult * mults.infiltration_timer_mult,
1,
],
[
"Infiltration minigame damage reduction",
Player.infiltration_damage_reduction_mult,
-1 * (1 - Player.infiltration_damage_reduction_mult * mults.infiltration_damage_reduction_mult),
1,
],
].map((data): MultiplierListItemData => (data as any).concat([Settings.theme.primary])),
);
const hasLeftImprovements = +!!(leftColData.filter((item) => item[2] !== 0).length > 0), const hasLeftImprovements = +!!(leftColData.filter((item) => item[2] !== 0).length > 0),
hasRightImprovements = +!!(rightColData.filter((item) => item[2] !== 0).length > 0); hasRightImprovements = +!!(rightColData.filter((item) => item[2] !== 0).length > 0);

@ -112,6 +112,8 @@ export const CONSTANTS: {
CodingContractBaseMoneyGain: number; CodingContractBaseMoneyGain: number;
AugmentationGraftingCostMult: number; AugmentationGraftingCostMult: number;
AugmentationGraftingTimeBase: number; AugmentationGraftingTimeBase: number;
SoACostMult: number;
SoARepMult: number;
EntropyEffect: number; EntropyEffect: number;
TotalNumBitNodes: number; TotalNumBitNodes: number;
Donations: number; // number of blood/plasma/palette donation the dev have verified., boosts NFG Donations: number; // number of blood/plasma/palette donation the dev have verified., boosts NFG
@ -281,6 +283,10 @@ export const CONSTANTS: {
AugmentationGraftingCostMult: 3, AugmentationGraftingCostMult: 3,
AugmentationGraftingTimeBase: 3600000, AugmentationGraftingTimeBase: 3600000,
// SoA mults
SoACostMult: 7,
SoARepMult: 1.3,
// Value raised to the number of entropy stacks, then multiplied to player multipliers // Value raised to the number of entropy stacks, then multiplied to player multipliers
EntropyEffect: 0.98, EntropyEffect: 0.98,

@ -3,6 +3,7 @@ import { IMap } from "../types";
import { FactionNames } from "./data/FactionNames"; import { FactionNames } from "./data/FactionNames";
import { use } from "../ui/Context"; import { use } from "../ui/Context";
import { Option } from "./ui/Option"; import { Option } from "./ui/Option";
import { Typography } from "@mui/material";
interface FactionInfoParams { interface FactionInfoParams {
infoText?: JSX.Element; infoText?: JSX.Element;
@ -511,51 +512,17 @@ export const FactionInfos: IMap<FactionInfo> = {
); );
}, },
}), }),
// prettier-ignore [FactionNames.ShadowsOfAnarchy]: new FactionInfo({
[FactionNames.Infiltrators]: new FactionInfo({ infoText: (
infoText:(<> <>
{".,=,.==.²=.'=,.=░.==.:=,,▄▓▓▓▓▓▓▓▓▓╬░.==.²!.,=,.=⌐.==.!=,.=,.==.²=.,=,.==.²=.!=,"}<br /> The government is ruled by the corporations that we have allowed to consume it. To release the world from its
{"'¡»⌐^»∩^:»^:=^`=∩':+]▄▄▓▓▓▓▓▓▓▓▓▓▓▓▓▒^»∩^»=^:»^²»⌐^»∩^:=^`»^`»∩^:»^¡»^`»⌐'»÷'\»'"}<br /> shackles, the gods grant us their strength.
{"░░_|░_'░⌐_░∩`|▒▄▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓░░`,░``░∩`»░_|░¬`░⌐_░░`'PHYZ|C@L`»░_!░⌐`░░_|"}<br /> </>
{".,=,.»\.²=,,[▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓█▓▒╦╔░¡_²².,=,,=:.==_!²,,=,_==,W@Z,=,,=\.!=./²,"}<br /> ),
{"'`»^^»∩':»')▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓████▒▐▒Ü▒^»=^¡»^^»⌐'»∩':»^`»^'=^:=^H3R3^»∩^:»':=^"}<br /> special: true,
{"░∩`:░_'░⌐`░▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓█████ÑÜP╩Ü╙░`_░∩`|░`:░_`░∩`|∩`:░_`░⌐_░░`|░`,░⌐`░∩`»"}<br /> keepOnInstall: true,
{".,=,,==_²=,▀▓▓▓▓▓▓▓▓▓▓▓▓▓▓██▌Ñ▓██ÑÜÜ▒Ü▒░_»=,,=,.==_»=,!=,,=,_==,»░,,=,,==_»=,!=,"}<br /> assignment: (): React.ReactElement => {
{"'`=^^=∩^:»^:»└'µ╫█████████╬▓▓▓██Ññ▒NÜÜ▒╠^»=':=^^=∩^»=^:=^`=⌐^»»':»`¡»^`=∩^:=^\»'"}<br /> return <Typography>{FactionNames.ShadowsOfAnarchy} can only gain reputation by infiltrating.</Typography>;
{"░░`:░_,░⌐`=∩`|░_¡█╬▀███▓╬╬▀▓▓▀Ñ▒ÄÜ╟ñÜÜ╠D░¬_░░_|=_!░_`░⌐`=∩_:░_'░⌐_░░`!=`┌░__░∩_»"}<br /> },
{".,=,.==.!=,,=,.=░╠████Ñ▒▒ÄÜñÜÜÖ╠╩Ü║Üû╠╙».»░.:=,.=⌐.==.!=,,=,.==.!=.,=,_==.»=.!=,"}<br /> }),
{"^`»^`»∩`:»'\»^^»⌐^╚╬▒Ü▒▒▒ÜÜ▒╚╩▒▒RÖÜ╠╠▒∩∩';╓';»^'»⌐`»»^:»^^»⌐^»∩':»^¡»''»∩`:»^\»^"}<br />
{"░░ :░ '░⌐_░░_|░`!░`╙▒▒╠╠ÜÉ▒╚Ö╠╠╠╠╟╬╠╠╠╬╬▓▓█▓▓▓▓▓▌▄▒,,░⌐_|░_:░`,░⌐`░░ |░ '░_`░∩_|"}<br />
{".,=,.=».!=,,=,.=░.==.└╙╙╜╚╩╩╙╙Ü7┘,░╚╬╠╬▓████▓▓▓▓▓█▓▓▓▓▓▓▓▓▓▓▒==,²».,»,,=░.!=.!=,"}<br />
{"'^»⌐^»∩^:÷^\»^^»⌐'»»^:»^^»⌐^»∩^:»'`║██████████████▓████████▓▓m»'»»^¡»^^»∩^»»^\»^"}<br />
{"░∩`!░_'░⌐`░░`|░,;░__░⌐`░░`|░-'░⌐`░µ▓█████████████▓▓▓▓▀▀╫▓███▓▌`░⌐_░░`|░`!░⌐`░∩`|"}<br />
{"_,=,_²».:=:▒▒╠▒▒╠╠▒▒,:=,,=⌐_»░_:=,▓██████████████▓▓▓▓▒!=,███▓▓░_»=_,=,_=░_!░.'=,"}<br />
{"▒╙R▓▓▄▄╣▓▓▓▓▓▓▓▓▓╬╬╠▒╠▄▄▄µ∩'»=]▄▄▓████Ñ»╙▀███████▓▓▓▓Ñ:»^╫█▓▓▓H`:='`=^`=∩`»=`\=^"}<br />
{"Ü⌐»╙▓▓▓▓▓▓╬▌╠╬▒╬╬╬╠╠Ö╣▓▓▓▓▓▓▓▓██▓███▀U``░``╫███████▓▓Ñ⌐_=╫█▓▓▓Ñ░_`░░_|░_┌░``░░_»"}<br />
{"|░::╟▓▓▀╚╙░/=,,╙░░╙░,⌡╩▀▓█████████▓╙,,==_²²╫███████▓▓░!=,╙╬╩▒▒▒╦╦░,,=,_=\.²=.!=,"}<br />
{"^'ܵÅÑ»`:='\=^^»⌐^»=':÷^^=^┴╚╢▀▀▀╙`»^'=∩`:»║██████▓▓▌^:»'╔╠▒▒▒▒▒▒▒╠M≡╦`»⌐'»=^╒»`"}<br />
{"░░_|░_'░⌐`░░_»░`!░¬`░▄▄▄▌▄▄▄▄▄▄╥,░░_:░`,░,╫███████▓▓Ü░⌐`=╠▒▒▒▒▒▒╠╠╩░`»╝╦:░_`░∩`»"}<br />
{"_,»,_!\_!=,,=,_»░_²1████████████████▓▄▓▓▄▓█████▓▓▓▓Ñ»_!=,7╝╬╚╝╩╩░ù,,»,,╫▒,²»_!=,"}<br />
{"'¡»^^»∩^:÷^\»^^»⌐^»=████████████████████████████▓▓Ñ»∩':»^^»╬^÷∩^:»^¡÷^║╣ÜR≈»^\÷^"}<br />
{"░░`|░¬'░⌐`░░`|░`:░``╫███████▀▀██████████████████▓▀░¬`░⌐`|░`╠╣╣░▒░_▒╥║╬╣▒╙Ü^=░░`|"}<br />
{"_,=,_»░_²=,,=,_=░_==|██████░==_╙╩▀██████████████Ñ⌐_!=_:=,_░╟%╩╬╟╣╣╣╬Ñ╣Φ╬»_²=┐╟╣╓"}<br />
{"`¡»^^»∩^»»^\»^^»⌐^»»[█████▓^»∩'»:^)▓██████████▀┴=⌐`»='»»^`»╠^»╠╬╠n╬╬▒^[╠∩^»»^:=^"}<br />
{"░∩`:░_'░⌐`░∩_»░_:░¬_▐██████▒``░⌐`▄█████████▓Ñ`»░`!░_`░⌐_|∩|╬░``╠⌐_░╠_»░╚Ü░_`░⌐`|"}<br />
{",,=,,==_²=.,=,,=░,==╫██████▒==,²▓███████▓╨░,,=,_=⌐,=»,!=,,=╠░»=╬==.╠Ü,_=╢,!=,!=,"}<br />
{"^¡÷^^»∩^:='\»^^»⌐^»»███████^»»^╫██████▄┐':»':=^^»⌐`»»^\=^░╬Ü'»┐╬░»''╢^^»∩Φ░»^\»^"}<br />
{"░=`!░`¡░⌐`░░`|░`:░,███████▓░_`▓███████▌'░¬`░░`|░ ¡░``░⌐`|╝╨|░``╬H_░û╬▒░`:╟╬^░∩_»"}<br />
{",_=,,»»_!»,,░╓▄▄▓▓█████████,=»,╙▀███████▌▄».,=,_=⌐_»»_²=,,=,,²=╚ÑÜ,,╚Ñ_=»_!=.!»_"}<br />
{"^^»^^»∩^:Φ███████████████▌╜^»»':»^¡╬▓██████▄░»^^»⌐'»»':»^^»''»»^»»^¡»^^»⌐':»'\»^"}<br />
{"░∩`:░`'░⌐╨████████████████:░``░⌐`░░`|░▀██████▓▄░`:░_`░░`»░`:░``░⌐`░░`|░`,░⌐`░░`|"}<br />
{"_,=,,==_!=,,=,_»=_==_²ù││ù,_==_!=,,=,,=░████████▄░_»»_!=,_=░_==_»»_,=,,=░_»=,'»,"}<br />
{"^¡»^^»∩^:=^\=^^»⌐^»»^:»^^=^^»∩^:=^`='^;▄▓████████▌^»»^:=^`»⌐^»»^»»^¡»^^»∩^:=^\»^"}<br />
{"░∩`!=_'░⌐`░∩`|░`!░``░⌐`|░`|░`'░⌐`░µ▄▓███████████▄¡░_`░⌐`|░`!░_`░⌐`░∩`|░_¡░⌐`░░`|"}<br />
{"################################################################################"}<br /><br />
Experts in getting in and out in plain sight<br /><br />
Some some speculate that the oceans movies are documentaries based on this group<br /><br />
Some members are even rumored to be able to pick locks like the fonz, one hit and it will swing open ayeeeee<br /><br />
Note that for this faction, reputation can only be gained by performing infiltration tasks</>),
special: true,
keepOnInstall: true,
}),
}; };

@ -32,5 +32,5 @@ export enum FactionNames {
CyberSec = "CyberSec", CyberSec = "CyberSec",
Bladeburners = "Bladeburners", Bladeburners = "Bladeburners",
ChurchOfTheMachineGod = "Church of the Machine God", ChurchOfTheMachineGod = "Church of the Machine God",
Infiltrators = "The Infiltrators", ShadowsOfAnarchy = "Shadows of Anarchy",
} }

@ -166,7 +166,7 @@ export function AugmentationsPage(props: IProps): React.ReactElement {
); );
} }
const multiplierComponent = const multiplierComponent =
props.faction.name !== FactionNames.Infiltrators ? ( props.faction.name !== FactionNames.ShadowsOfAnarchy ? (
<Typography> <Typography>
Price multiplier: x {numeralWrapper.formatMultiplier(getGenericAugmentationPriceMultiplier())} Price multiplier: x {numeralWrapper.formatMultiplier(getGenericAugmentationPriceMultiplier())}
</Typography> </Typography>

@ -1,6 +1,8 @@
import { IPlayer } from "../../PersonObjects/IPlayer"; import { IPlayer } from "../../PersonObjects/IPlayer";
import { BitNodeMultipliers } from "../../BitNode/BitNodeMultipliers"; import { BitNodeMultipliers } from "../../BitNode/BitNodeMultipliers";
import { LocationsMetadata } from "../../Locations/data/LocationsMetadata"; import { LocationsMetadata } from "../../Locations/data/LocationsMetadata";
import { AugmentationNames } from "../../Augmentation/data/AugmentationNames";
import { Faction } from "../../Faction/Faction";
export function calculateSellInformationCashReward( export function calculateSellInformationCashReward(
player: IPlayer, player: IPlayer,
@ -15,7 +17,7 @@ export function calculateSellInformationCashReward(
Math.pow(difficulty, 3) * Math.pow(difficulty, 3) *
3e3 * 3e3 *
levelBonus * levelBonus *
player.infiltration_sell_mult * (player.hasAugmentation(AugmentationNames.WKSharmonizer) ? 1.5 : 1) *
BitNodeMultipliers.InfiltrationMoney BitNodeMultipliers.InfiltrationMoney
); );
} }
@ -33,17 +35,17 @@ export function calculateTradeInformationRepReward(
Math.pow(difficulty, 3) * Math.pow(difficulty, 3) *
3e3 * 3e3 *
levelBonus * levelBonus *
player.infiltration_sell_mult * (player.hasAugmentation(AugmentationNames.WKSharmonizer) ? 1.5 : 1) *
BitNodeMultipliers.InfiltrationMoney BitNodeMultipliers.InfiltrationMoney
); );
} }
export function calculateInfiltratorsRepReward(player: IPlayer, difficulty: number): number { export function calculateInfiltratorsRepReward(player: IPlayer, faction: Faction, difficulty: number): number {
const maxStartingSecurityLevel = LocationsMetadata.reduce((acc, data): number => { const maxStartingSecurityLevel = LocationsMetadata.reduce((acc, data): number => {
const startingSecurityLevel = data.infiltrationData?.startingSecurityLevel || 0; const startingSecurityLevel = data.infiltrationData?.startingSecurityLevel || 0;
return acc > startingSecurityLevel ? acc : startingSecurityLevel; return acc > startingSecurityLevel ? acc : startingSecurityLevel;
}, 0); }, 0);
const baseRepGain = (difficulty / maxStartingSecurityLevel) * 10; const baseRepGain = (difficulty / maxStartingSecurityLevel) * 5000;
return (baseRepGain + player.infiltration_base_rep_increase) * player.infiltration_rep_mult; return baseRepGain * (player.hasAugmentation(AugmentationNames.WKSharmonizer) ? 2 : 1) * (1 + faction.favor / 100);
} }

@ -36,7 +36,7 @@ export function BackwardGame(props: IMinigameProps): React.ReactElement {
const timer = difficulty.timer; const timer = difficulty.timer;
const [answer] = useState(makeAnswer(difficulty)); const [answer] = useState(makeAnswer(difficulty));
const [guess, setGuess] = useState(""); const [guess, setGuess] = useState("");
const hasAugment = Player.hasAugmentation(AugmentationNames.RearViewMirrorShoulderAttachment, true); const hasAugment = Player.hasAugmentation(AugmentationNames.ChaosOfDionysus, true);
function press(this: Document, event: KeyboardEvent): void { function press(this: Document, event: KeyboardEvent): void {
event.preventDefault(); event.preventDefault();

@ -33,7 +33,7 @@ const difficulties: {
function generateLeftSide(difficulty: Difficulty): string { function generateLeftSide(difficulty: Difficulty): string {
let str = ""; let str = "";
const options = [KEY.OPEN_BRACKET, KEY.LESS_THAN, KEY.OPEN_PARENTHESIS, KEY.OPEN_BRACE]; const options = [KEY.OPEN_BRACKET, KEY.LESS_THAN, KEY.OPEN_PARENTHESIS, KEY.OPEN_BRACE];
if (Player.hasAugmentation(AugmentationNames.IntellisenseModule, true)) { if (Player.hasAugmentation(AugmentationNames.WisdomOfAthena, true)) {
options.splice(0, 1); options.splice(0, 1);
} }
const length = random(difficulty.min, difficulty.max); const length = random(difficulty.min, difficulty.max);

@ -47,7 +47,7 @@ export function BribeGame(props: IMinigameProps): React.ReactElement {
let upColor = defaultColor; let upColor = defaultColor;
let downColor = defaultColor; let downColor = defaultColor;
let choiceColor = defaultColor; let choiceColor = defaultColor;
const hasAugment = Player.hasAugmentation(AugmentationNames.KyberCrystalInjection, true); const hasAugment = Player.hasAugmentation(AugmentationNames.BeautyOfAphrodite, true);
if (hasAugment) { if (hasAugment) {
const upIndex = index + 1 >= choices.length ? 0 : index + 1; const upIndex = index + 1 >= choices.length ? 0 : index + 1;

@ -42,7 +42,7 @@ export function CheatCodeGame(props: IMinigameProps): React.ReactElement {
const timer = difficulty.timer; const timer = difficulty.timer;
const [code] = useState(generateCode(difficulty)); const [code] = useState(generateCode(difficulty));
const [index, setIndex] = useState(0); const [index, setIndex] = useState(0);
const hasAugment = Player.hasAugmentation(AugmentationNames.DyslexiaModule, true); const hasAugment = Player.hasAugmentation(AugmentationNames.TrickeryOfHermes, true);
function press(this: Document, event: KeyboardEvent): void { function press(this: Document, event: KeyboardEvent): void {
event.preventDefault(); event.preventDefault();

@ -40,7 +40,7 @@ export function Cyberpunk2077Game(props: IMinigameProps): React.ReactElement {
const [currentAnswerIndex, setCurrentAnswerIndex] = useState(0); const [currentAnswerIndex, setCurrentAnswerIndex] = useState(0);
const [pos, setPos] = useState([0, 0]); const [pos, setPos] = useState([0, 0]);
const hasAugment = Player.hasAugmentation(AugmentationNames.CyberDecoder, true); const hasAugment = Player.hasAugmentation(AugmentationNames.FloodOfPoseidon, true);
function press(this: Document, event: KeyboardEvent): void { function press(this: Document, event: KeyboardEvent): void {
event.preventDefault(); event.preventDefault();
const move = [0, 0]; const move = [0, 0];

@ -13,6 +13,7 @@ import { MinesweeperGame } from "./MinesweeperGame";
import { WireCuttingGame } from "./WireCuttingGame"; import { WireCuttingGame } from "./WireCuttingGame";
import { Victory } from "./Victory"; import { Victory } from "./Victory";
import Typography from "@mui/material/Typography"; import Typography from "@mui/material/Typography";
import { AugmentationNames } from "../../Augmentation/data/AugmentationNames";
interface IProps { interface IProps {
StartingDifficulty: number; StartingDifficulty: number;
@ -93,7 +94,7 @@ export function Game(props: IProps): React.ReactElement {
// it's clear they're not meant to // it's clear they're not meant to
const damage = options?.automated const damage = options?.automated
? player.hp ? player.hp
: props.StartingDifficulty * 3 * player.infiltration_damage_reduction_mult; : props.StartingDifficulty * 3 * (player.hasAugmentation(AugmentationNames.WKSharmonizer) ? 0.5 : 1);
if (player.takeDamage(damage)) { if (player.takeDamage(damage)) {
router.toCity(); router.toCity();
return; return;
@ -112,7 +113,16 @@ export function Game(props: IProps): React.ReactElement {
stageComponent = <Countdown onFinish={() => setStage(Stage.Minigame)} />; stageComponent = <Countdown onFinish={() => setStage(Stage.Minigame)} />;
break; break;
case Stage.Minigame: { case Stage.Minigame: {
const MiniGame = minigames[gameIds.id]; /**
*
BackwardGame,
BribeGame,
CheatCodeGame,
Cyberpunk2077Game,
MinesweeperGame,
WireCuttingGame,
*/
const MiniGame = WireCuttingGame; // minigames[gameIds.id];
stageComponent = <MiniGame onSuccess={success} onFailure={failure} difficulty={props.Difficulty + level / 50} />; stageComponent = <MiniGame onSuccess={success} onFailure={failure} difficulty={props.Difficulty + level / 50} />;
break; break;
} }

@ -4,6 +4,7 @@ import withStyles from "@mui/styles/withStyles";
import { Theme } from "@mui/material/styles"; import { Theme } from "@mui/material/styles";
import Grid from "@mui/material/Grid"; import Grid from "@mui/material/Grid";
import { use } from "../../ui/Context"; import { use } from "../../ui/Context";
import { AugmentationNames } from "../../Augmentation/data/AugmentationNames";
const TimerProgress = withStyles((theme: Theme) => ({ const TimerProgress = withStyles((theme: Theme) => ({
root: { root: {
@ -23,7 +24,7 @@ interface IProps {
export function GameTimer(props: IProps): React.ReactElement { export function GameTimer(props: IProps): React.ReactElement {
const player = use.Player(); const player = use.Player();
const [v, setV] = useState(100); const [v, setV] = useState(100);
const totalMillis = player.infiltration_timer_mult * props.millis; const totalMillis = (player.hasAugmentation(AugmentationNames.WKSharmonizer) ? 1.3 : 1) * props.millis;
const tick = 200; const tick = 200;
useEffect(() => { useEffect(() => {

@ -38,7 +38,7 @@ export function MinesweeperGame(props: IMinigameProps): React.ReactElement {
const [answer, setAnswer] = useState(generateEmptyField(difficulty)); const [answer, setAnswer] = useState(generateEmptyField(difficulty));
const [pos, setPos] = useState([0, 0]); const [pos, setPos] = useState([0, 0]);
const [memoryPhase, setMemoryPhase] = useState(true); const [memoryPhase, setMemoryPhase] = useState(true);
const hasAugment = Player.hasAugmentation(AugmentationNames.MineDetectionArmAttachment, true); const hasAugment = Player.hasAugmentation(AugmentationNames.HuntOfArtemis, true);
function press(this: Document, event: KeyboardEvent): void { function press(this: Document, event: KeyboardEvent): void {
event.preventDefault(); event.preventDefault();
if (memoryPhase) return; if (memoryPhase) return;

@ -40,7 +40,7 @@ export function SlashGame(props: IMinigameProps): React.ReactElement {
props.onSuccess(); props.onSuccess();
} }
} }
const hasAugment = Player.hasAugmentation(AugmentationNames.PythiasBrainStem, true); const hasAugment = Player.hasAugmentation(AugmentationNames.MightOfAres, true);
const phaseZeroTime = Math.random() * 3250 + 1500 - (250 + difficulty.window); const phaseZeroTime = Math.random() * 3250 + 1500 - (250 + difficulty.window);
const phaseOneTime = 250; const phaseOneTime = 250;
const timeUntilAttacking = phaseZeroTime + phaseOneTime; const timeUntilAttacking = phaseZeroTime + phaseOneTime;

@ -15,6 +15,7 @@ import {
calculateSellInformationCashReward, calculateSellInformationCashReward,
calculateTradeInformationRepReward, calculateTradeInformationRepReward,
} from "../formulas/victory"; } from "../formulas/victory";
import { inviteToFaction } from "../../Faction/FactionHelpers";
interface IProps { interface IProps {
StartingDifficulty: number; StartingDifficulty: number;
@ -33,12 +34,12 @@ export function Victory(props: IProps): React.ReactElement {
router.toCity(); router.toCity();
} }
const soa = Factions[FactionNames.ShadowsOfAnarchy];
const repGain = calculateTradeInformationRepReward(player, props.Reward, props.MaxLevel, props.StartingDifficulty); const repGain = calculateTradeInformationRepReward(player, props.Reward, props.MaxLevel, props.StartingDifficulty);
const moneyGain = calculateSellInformationCashReward(player, props.Reward, props.MaxLevel, props.StartingDifficulty); const moneyGain = calculateSellInformationCashReward(player, props.Reward, props.MaxLevel, props.StartingDifficulty);
const infiltrationRepGain = calculateInfiltratorsRepReward(player, props.StartingDifficulty); const infiltrationRepGain = calculateInfiltratorsRepReward(player, soa, props.StartingDifficulty);
const infiltratorFaction = Factions[FactionNames.Infiltrators]; const isMemberOfInfiltrators = player.factions.includes(FactionNames.ShadowsOfAnarchy);
const isMemberOfInfiltrators = infiltratorFaction && infiltratorFaction.isMember;
function sell(): void { function sell(): void {
handleInfiltrators(); handleInfiltrators();
@ -58,9 +59,9 @@ export function Victory(props: IProps): React.ReactElement {
} }
function handleInfiltrators(): void { function handleInfiltrators(): void {
player.hasCompletedAnInfiltration = true; inviteToFaction(Factions[FactionNames.ShadowsOfAnarchy]);
if (isMemberOfInfiltrators) { if (isMemberOfInfiltrators) {
infiltratorFaction.playerReputation += infiltrationRepGain; soa.playerReputation += infiltrationRepGain;
} }
} }
@ -75,7 +76,7 @@ export function Victory(props: IProps): React.ReactElement {
You{" "} You{" "}
{isMemberOfInfiltrators ? ( {isMemberOfInfiltrators ? (
<> <>
have gained {formatNumber(infiltrationRepGain, 2)} rep for {FactionNames.Infiltrators} and{" "} have gained {formatNumber(infiltrationRepGain, 2)} rep for {FactionNames.ShadowsOfAnarchy} and{" "}
</> </>
) : ( ) : (
<></> <></>

@ -64,10 +64,10 @@ export function WireCuttingGame(props: IMinigameProps): React.ReactElement {
const [wires] = useState(generateWires(difficulty)); const [wires] = useState(generateWires(difficulty));
const [cutWires, setCutWires] = useState(new Array(wires.length).fill(false)); const [cutWires, setCutWires] = useState(new Array(wires.length).fill(false));
const [questions] = useState(generateQuestion(wires, difficulty)); const [questions] = useState(generateQuestion(wires, difficulty));
const hasAugment = Player.hasAugmentation(AugmentationNames.SecurityWireContacts, true); const hasAugment = Player.hasAugmentation(AugmentationNames.KnowledgeOfApollo, true);
function checkWire(wireNum: number): boolean { function checkWire(wireNum: number): boolean {
return !questions.some((q) => q.shouldCut(wires[wireNum - 1], wireNum - 1)); return questions.some((q) => q.shouldCut(wires[wireNum - 1], wireNum - 1));
} }
useEffect(() => { useEffect(() => {
@ -110,9 +110,15 @@ export function WireCuttingGame(props: IMinigameProps): React.ReactElement {
<Typography key={i}>{question.toString()}</Typography> <Typography key={i}>{question.toString()}</Typography>
))} ))}
<Typography> <Typography>
{new Array(wires.length).fill(0).map((_, i) => ( {new Array(wires.length).fill(0).map((_, i) => {
<span key={i}>&nbsp;{i + 1}&nbsp;&nbsp;&nbsp;&nbsp;</span> const isCorrectWire = checkWire(i + 1);
))} const color = hasAugment && !isCorrectWire ? Settings.theme.disabled : Settings.theme.primary;
return (
<span key={i} style={{ color: color }}>
&nbsp;{i + 1}&nbsp;&nbsp;&nbsp;&nbsp;
</span>
);
})}
</Typography> </Typography>
{new Array(8).fill(0).map((_, i) => ( {new Array(8).fill(0).map((_, i) => (
<div key={i}> <div key={i}>

@ -2492,12 +2492,6 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
bladeburner_stamina_gain_mult: Player.bladeburner_stamina_gain_mult, bladeburner_stamina_gain_mult: Player.bladeburner_stamina_gain_mult,
bladeburner_analysis_mult: Player.bladeburner_analysis_mult, bladeburner_analysis_mult: Player.bladeburner_analysis_mult,
bladeburner_success_chance_mult: Player.bladeburner_success_chance_mult, bladeburner_success_chance_mult: Player.bladeburner_success_chance_mult,
infiltration_base_rep_increase: Player.infiltration_base_rep_increase,
infiltration_rep_mult: Player.infiltration_rep_mult,
infiltration_trade_mult: Player.infiltration_trade_mult,
infiltration_sell_mult: Player.infiltration_sell_mult,
infiltration_timer_mult: Player.infiltration_timer_mult,
infiltration_damage_reduction_mult: Player.infiltration_damage_reduction_mult,
bitNodeN: Player.bitNodeN, bitNodeN: Player.bitNodeN,
totalPlaytime: Player.totalPlaytime, totalPlaytime: Player.totalPlaytime,
playtimeSinceLastAug: Player.playtimeSinceLastAug, playtimeSinceLastAug: Player.playtimeSinceLastAug,

@ -16,6 +16,8 @@ import {
calculateSellInformationCashReward, calculateSellInformationCashReward,
calculateTradeInformationRepReward, calculateTradeInformationRepReward,
} from "../Infiltration/formulas/victory"; } from "../Infiltration/formulas/victory";
import { FactionNames } from "../Faction/data/FactionNames";
import { Factions } from "../Faction/Factions";
export function NetscriptInfiltration( export function NetscriptInfiltration(
player: IPlayer, player: IPlayer,
@ -47,7 +49,7 @@ export function NetscriptInfiltration(
reward: { reward: {
tradeRep: calculateTradeInformationRepReward(player, reward, maxLevel, difficulty), tradeRep: calculateTradeInformationRepReward(player, reward, maxLevel, difficulty),
sellCash: calculateSellInformationCashReward(player, reward, maxLevel, difficulty), sellCash: calculateSellInformationCashReward(player, reward, maxLevel, difficulty),
infiltratorRep: calculateInfiltratorsRepReward(player, difficulty), infiltratorRep: calculateInfiltratorsRepReward(player, Factions[FactionNames.ShadowsOfAnarchy], difficulty),
}, },
difficulty: difficulty, difficulty: difficulty,
}; };

@ -73,7 +73,6 @@ export interface IPlayer {
terminalCommandHistory: string[]; terminalCommandHistory: string[];
lastUpdate: number; lastUpdate: number;
totalPlaytime: number; totalPlaytime: number;
hasCompletedAnInfiltration: boolean;
// Stats // Stats
hacking: number; hacking: number;
@ -124,12 +123,6 @@ export interface IPlayer {
bladeburner_stamina_gain_mult: number; bladeburner_stamina_gain_mult: number;
bladeburner_analysis_mult: number; bladeburner_analysis_mult: number;
bladeburner_success_chance_mult: number; bladeburner_success_chance_mult: number;
infiltration_base_rep_increase: number;
infiltration_rep_mult: number;
infiltration_trade_mult: number;
infiltration_sell_mult: number;
infiltration_timer_mult: number;
infiltration_damage_reduction_mult: number;
createProgramReqLvl: number; createProgramReqLvl: number;
factionWorkType: string; factionWorkType: string;

@ -83,7 +83,6 @@ export class PlayerObject implements IPlayer {
lastUpdate: number; lastUpdate: number;
lastSave: number; lastSave: number;
totalPlaytime: number; totalPlaytime: number;
hasCompletedAnInfiltration: boolean;
// Stats // Stats
hacking: number; hacking: number;
@ -134,12 +133,6 @@ export class PlayerObject implements IPlayer {
bladeburner_stamina_gain_mult: number; bladeburner_stamina_gain_mult: number;
bladeburner_analysis_mult: number; bladeburner_analysis_mult: number;
bladeburner_success_chance_mult: number; bladeburner_success_chance_mult: number;
infiltration_base_rep_increase: number;
infiltration_rep_mult: number;
infiltration_trade_mult: number;
infiltration_sell_mult: number;
infiltration_timer_mult: number;
infiltration_damage_reduction_mult: number;
createProgramReqLvl: number; createProgramReqLvl: number;
factionWorkType: string; factionWorkType: string;
@ -472,13 +465,6 @@ export class PlayerObject implements IPlayer {
this.bladeburner_analysis_mult = 1; //Field Analysis Onl; this.bladeburner_analysis_mult = 1; //Field Analysis Onl;
this.bladeburner_success_chance_mult = 1; this.bladeburner_success_chance_mult = 1;
this.infiltration_base_rep_increase = 0;
this.infiltration_rep_mult = 1;
this.infiltration_trade_mult = 1;
this.infiltration_sell_mult = 1;
this.infiltration_timer_mult = 1;
this.infiltration_damage_reduction_mult = 1;
// Sleeves & Re-sleeving // Sleeves & Re-sleeving
this.sleeves = []; this.sleeves = [];
this.sleevesFromCovenant = 0; // # of Duplicate sleeves purchased from the covenan; this.sleevesFromCovenant = 0; // # of Duplicate sleeves purchased from the covenan;
@ -491,7 +477,6 @@ export class PlayerObject implements IPlayer {
this.lastUpdate = 0; this.lastUpdate = 0;
this.lastSave = 0; this.lastSave = 0;
this.totalPlaytime = 0; this.totalPlaytime = 0;
this.hasCompletedAnInfiltration = false;
this.playtimeSinceLastAug = 0; this.playtimeSinceLastAug = 0;
this.playtimeSinceLastBitnode = 0; this.playtimeSinceLastBitnode = 0;

@ -7,7 +7,7 @@ import { Augmentation } from "../../Augmentation/Augmentation";
import { calculateEntropy } from "../Grafting/EntropyAccumulation"; import { calculateEntropy } from "../Grafting/EntropyAccumulation";
export function hasAugmentation(this: IPlayer, aug: string | Augmentation, includeQueued = false): boolean { export function hasAugmentation(this: IPlayer, aug: string | Augmentation, ignoreQueued = false): boolean {
const augName: string = aug instanceof Augmentation ? aug.name : aug; const augName: string = aug instanceof Augmentation ? aug.name : aug;
for (const owned of this.augmentations) { for (const owned of this.augmentations) {
@ -16,7 +16,7 @@ export function hasAugmentation(this: IPlayer, aug: string | Augmentation, inclu
} }
} }
if (!includeQueued) { if (!ignoreQueued) {
for (const owned of this.queuedAugmentations) { for (const owned of this.queuedAugmentations) {
if (owned.name === augName) { if (owned.name === augName) {
return true; return true;

@ -160,7 +160,6 @@ export function prestigeAugmentation(this: PlayerObject): void {
this.workChaExpGained = 0; this.workChaExpGained = 0;
this.workRepGained = 0; this.workRepGained = 0;
this.workMoneyGained = 0; this.workMoneyGained = 0;
this.hasCompletedAnInfiltration = false;
this.timeWorked = 0; this.timeWorked = 0;
@ -313,13 +312,6 @@ export function resetMultipliers(this: IPlayer): void {
this.bladeburner_stamina_gain_mult = 1; this.bladeburner_stamina_gain_mult = 1;
this.bladeburner_analysis_mult = 1; this.bladeburner_analysis_mult = 1;
this.bladeburner_success_chance_mult = 1; this.bladeburner_success_chance_mult = 1;
this.infiltration_base_rep_increase = 0;
this.infiltration_rep_mult = 1;
this.infiltration_trade_mult = 1;
this.infiltration_sell_mult = 1;
this.infiltration_timer_mult = 1;
this.infiltration_damage_reduction_mult = 1;
} }
export function hasProgram(this: IPlayer, programName: string): boolean { export function hasProgram(this: IPlayer, programName: string): boolean {
@ -2151,12 +2143,6 @@ export function checkForFactionInvitations(this: IPlayer): Faction[] {
return allCompanies.includes(companyName) && getCompanyRep(companyName) > repNeeded; return allCompanies.includes(companyName) && getCompanyRep(companyName) > repNeeded;
} }
//Infiltrators
const InfiltratorsFac = Factions[FactionNames.Infiltrators];
if (this.hasCompletedAnInfiltration && !InfiltratorsFac.isMember && !InfiltratorsFac.alreadyInvited) {
invitedFactions.push(InfiltratorsFac);
}
//Illuminati //Illuminati
const illuminatiFac = Factions[FactionNames.Illuminati]; const illuminatiFac = Factions[FactionNames.Illuminati];
if ( if (

@ -56,7 +56,7 @@ function possibleJobs(player: IPlayer, sleeve: Sleeve): string[] {
function possibleFactions(player: IPlayer, sleeve: Sleeve): string[] { function possibleFactions(player: IPlayer, sleeve: Sleeve): string[] {
// Array of all factions that other sleeves are working for // Array of all factions that other sleeves are working for
const forbiddenFactions = [FactionNames.Bladeburners as string, FactionNames.Infiltrators as string]; const forbiddenFactions = [FactionNames.Bladeburners as string, FactionNames.ShadowsOfAnarchy as string];
if (player.gang) { if (player.gang) {
forbiddenFactions.push(player.gang.facName); forbiddenFactions.push(player.gang.facName);
} }

@ -24,6 +24,8 @@ import { SxProps } from "@mui/system";
import { PlayerObject } from "./PersonObjects/Player/PlayerObject"; import { PlayerObject } from "./PersonObjects/Player/PlayerObject";
import { pushGameSaved } from "./Electron"; import { pushGameSaved } from "./Electron";
import { defaultMonacoTheme } from "./ScriptEditor/ui/themes"; import { defaultMonacoTheme } from "./ScriptEditor/ui/themes";
import { FactionNames } from "./Faction/data/FactionNames";
import { Faction } from "./Faction/Faction";
/* SaveObject.js /* SaveObject.js
* Defines the object used to save/load games * Defines the object used to save/load games
@ -398,6 +400,9 @@ function evaluateVersionCompatibility(ver: string | number): void {
if (ver < 15) { if (ver < 15) {
(Settings as any).EditorTheme = { ...defaultMonacoTheme }; (Settings as any).EditorTheme = { ...defaultMonacoTheme };
} }
if (ver < 16) {
Factions[FactionNames.ShadowsOfAnarchy] = new Faction(FactionNames.ShadowsOfAnarchy);
}
} }
} }

@ -495,18 +495,6 @@ export function CharacterStats(): React.ReactElement {
noMargin noMargin
/> />
)} )}
{player.factions.includes(FactionNames.Infiltrators) && (
<MultiplierTable
color={Settings.theme.primary}
rows={[
["Infiltrator Rep reward", player.infiltration_rep_mult],
["Infiltration sell", player.infiltration_sell_mult],
["Infiltration trade", player.infiltration_trade_mult],
["Infiltration minigame timer", player.infiltration_timer_mult],
["Infiltration minigame damage reduction", -1 * (1 - player.infiltration_damage_reduction_mult)],
]}
/>
)}
</Box> </Box>
</Box> </Box>
</Paper> </Paper>