diff --git a/src/DevMenu/ui/FactionsDev.tsx b/src/DevMenu/ui/FactionsDev.tsx index d47fb5869..4baaeda53 100644 --- a/src/DevMenu/ui/FactionsDev.tsx +++ b/src/DevMenu/ui/FactionsDev.tsx @@ -143,12 +143,12 @@ export function FactionsDev(): React.ReactElement { value={selectedFaction.name} startAdornment={ <> - + - + diff --git a/src/Faction/FactionHelpers.tsx b/src/Faction/FactionHelpers.tsx index 1b709c02b..6436a6ecb 100644 --- a/src/Faction/FactionHelpers.tsx +++ b/src/Faction/FactionHelpers.tsx @@ -3,7 +3,7 @@ import type { Faction } from "./Faction"; import { Augmentations } from "../Augmentation/Augmentations"; import { PlayerOwnedAugmentation } from "../Augmentation/PlayerOwnedAugmentation"; -import { AugmentationName, FactionName } from "@enums"; +import { AugmentationName } from "@enums"; import { currentNodeMults } from "../BitNode/BitNodeMultipliers"; import { Player } from "@player"; @@ -20,7 +20,7 @@ import { InvitationEvent } from "./ui/InvitationModal"; import { SFC32RNG } from "../Casino/RNG"; import { isFactionWork } from "../Work/FactionWork"; import { getAugCost } from "../Augmentation/AugmentationHelpers"; -import { createEnumKeyedRecord, getRecordKeys } from "../Types/Record"; +import { getRecordKeys } from "../Types/Record"; export function inviteToFaction(faction: Faction): void { if (faction.alreadyInvited || faction.isMember) return; @@ -34,23 +34,18 @@ export function inviteToFaction(faction: Faction): void { export function joinFaction(faction: Faction): void { if (faction.isMember) return; faction.isMember = true; - Player.factions.push(faction.name); - let i = 0; - const factionIndexes = createEnumKeyedRecord(FactionName, (__) => i++); - Player.factions.sort((a, b) => factionIndexes[a] - factionIndexes[b]); - const factionInfo = faction.getInfo(); + // Add this faction to player's faction list, keeping it in standard order + Player.factions = getRecordKeys(Factions).filter((facName) => Factions[facName].isMember); - //Determine what factions you are banned from now that you have joined this faction - for (const enemy of factionInfo.enemies) { + // Ban player from this faction's enemies + for (const enemy of faction.getInfo().enemies) { if (Factions[enemy]) Factions[enemy].isBanned = true; Player.factionRumors.delete(enemy); } - 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--; - } - } + // Remove invalid invites and rumors + Player.factionInvitations = Player.factionInvitations.filter((factionName) => { + return !Factions[factionName].isMember && !Factions[factionName].isBanned; + }); Player.factionRumors.delete(faction.name); } diff --git a/src/Faction/FactionInfo.tsx b/src/Faction/FactionInfo.tsx index 89fa1201f..12568c233 100644 --- a/src/Faction/FactionInfo.tsx +++ b/src/Faction/FactionInfo.tsx @@ -430,6 +430,25 @@ export const FactionInfos: Record = { keepOnInstall: false, }), + [FactionName.CyberSec]: new FactionInfo({ + infoText: ( + <> + The Internet is the first thing that was built that we don't fully understand, the largest experiment in anarchy + that we have ever had. And as the world becomes increasingly dominated by it, society approaches the brink of + total chaos. We serve only to protect society, to protect humanity, to protect the world from imminent collapse. + + ), + rumorText: ( + <> + A hacking group known as {FactionName.CyberSec} will invite you to join them if you demonstrate your hacking + skills on their server. + + ), + inviteReqs: [haveBackdooredServer(SpecialServers.CyberSecServer)], + rumorReqs: [haveFile(MessageFilename.CyberSecTest)], + offerHackingWork: true, + }), + // City factions, essentially governments [FactionName.Aevum]: new FactionInfo({ infoText: <>The Silicon City., @@ -631,25 +650,6 @@ export const FactionInfos: Record = { offerSecurityWork: true, }), - [FactionName.CyberSec]: new FactionInfo({ - infoText: ( - <> - The Internet is the first thing that was built that we don't fully understand, the largest experiment in anarchy - that we have ever had. And as the world becomes increasingly dominated by it, society approaches the brink of - total chaos. We serve only to protect society, to protect humanity, to protect the world from imminent collapse. - - ), - rumorText: ( - <> - A hacking group known as {FactionName.CyberSec} will invite you to join them if you demonstrate your hacking - skills on their server. - - ), - inviteReqs: [haveBackdooredServer(SpecialServers.CyberSecServer)], - rumorReqs: [haveFile(MessageFilename.CyberSecTest)], - offerHackingWork: true, - }), - // Special Factions [FactionName.Bladeburners]: new FactionInfo({ infoText: ( diff --git a/src/Faction/ui/FactionsRoot.tsx b/src/Faction/ui/FactionsRoot.tsx index f72776ea1..4f43ce46d 100644 --- a/src/Faction/ui/FactionsRoot.tsx +++ b/src/Faction/ui/FactionsRoot.tsx @@ -209,16 +209,16 @@ export function FactionsRoot(): React.ReactElement { const theme = useTheme(); const rerender = useRerender(200); useEffect(() => { - Player.factionInvitations.forEach((faction) => { - InvitationsSeen.add(faction); + Player.factionInvitations.forEach((factionName) => { + InvitationsSeen.add(factionName); }); }, []); - const allFactions = Object.values(FactionName).map((faction) => faction as string); - const allJoinedFactions = [...Player.factions].map((facName) => Factions[facName]).filter((faction) => !!faction); - allJoinedFactions.sort((a, b) => allFactions.indexOf(a.name) - allFactions.indexOf(b.name)); - - const invitations = Player.factionInvitations.map((facName) => Factions[facName]).filter((faction) => !!faction); + // Display joined factions in the standard order + const joinedFactions = Object.values(Factions).filter((faction) => faction.isMember); + // Display invitations and rumors in the order they were received + const invitedFactions = Player.factionInvitations.map((facName) => Factions[facName]).filter((faction) => !!faction); + const rumoredFactions = [...Player.factionRumors].map((facName) => Factions[facName]).filter((faction) => !!faction); return ( @@ -241,7 +241,7 @@ export function FactionsRoot(): React.ReactElement { display="grid" sx={{ gap: 1, - gridTemplateColumns: (invitations.length > 0 ? "1fr " : "") + "2fr", + gridTemplateColumns: (invitedFactions.length > 0 ? "1fr " : "") + "2fr", [theme.breakpoints.down("lg")]: { gridTemplateColumns: "1fr", "& > span:nth-of-type(1)": { order: 1 } }, gridTemplateRows: "minmax(0, 1fr)", "& > span > .MuiBox-root": { @@ -251,35 +251,22 @@ export function FactionsRoot(): React.ReactElement { }, }} > - - {invitations.length > 0 && ( + + {invitedFactions.length > 0 && ( <> Faction Invitations - {invitations.map((faction) => ( + {invitedFactions.map((faction) => ( ))} )} - - {Player.factionRumors.size > 0 && ( - <> - - Rumors - -
- {[...Player.factionRumors].map((factionName) => ( - - ))} -
- - )}
- + {Player.inGang() && ( <> @@ -294,8 +281,8 @@ export function FactionsRoot(): React.ReactElement { Your Factions - {allJoinedFactions.length > 0 ? ( - allJoinedFactions.map((faction) => { + {joinedFactions.length > 0 ? ( + joinedFactions.map((faction) => { if (Player.getGangName() === faction.name) return null; return ; }) @@ -305,6 +292,20 @@ export function FactionsRoot(): React.ReactElement { + + {rumoredFactions.length > 0 && ( + <> + + Rumors + + + {rumoredFactions.map((faction) => ( + + ))} + + + )} +
); } diff --git a/src/PersonObjects/Player/PlayerObjectGeneralMethods.ts b/src/PersonObjects/Player/PlayerObjectGeneralMethods.ts index 9a04d836b..5a3290bf4 100644 --- a/src/PersonObjects/Player/PlayerObjectGeneralMethods.ts +++ b/src/PersonObjects/Player/PlayerObjectGeneralMethods.ts @@ -171,7 +171,8 @@ export function prestigeSourceFile(this: PlayerObject): void { export function receiveInvite(this: PlayerObject, factionName: FactionName): void { const faction = Factions[factionName]; - if (faction.alreadyInvited || faction.isMember || faction.isBanned) return; + if (this.factionInvitations.includes(factionName) || faction.alreadyInvited || faction.isMember || faction.isBanned) + return; this.factionInvitations.push(factionName); this.factionRumors.delete(factionName); faction.discovery = FactionDiscovery.known; diff --git a/src/Prestige.ts b/src/Prestige.ts index fa5cff3ea..71614d784 100755 --- a/src/Prestige.ts +++ b/src/Prestige.ts @@ -35,13 +35,13 @@ export function prestigeAugmentation(): void { initBitNodeMultipliers(); // Maintain invites to factions with the 'keepOnInstall' flag, and rumors about others - const maintainInvites = []; - const maintainRumors = []; + const maintainInvites = new Set(); + const maintainRumors = new Set(); for (const facName of [...Player.factions, ...Player.factionInvitations]) { if (Factions[facName].getInfo().keep) { - maintainInvites.push(facName); + maintainInvites.add(facName); } else { - maintainRumors.push(facName); + maintainRumors.add(facName); } } @@ -92,8 +92,10 @@ export function prestigeAugmentation(): void { // Recalculate the bonus for circadian modulator aug initCircadianModulator(); - Player.factionInvitations = Player.factionInvitations.concat(maintainInvites); - for (const factionName of maintainInvites) Factions[factionName].alreadyInvited = true; + Player.factionInvitations = Player.factionInvitations.concat([...maintainInvites]); + for (const factionName of maintainInvites) { + Factions[factionName].alreadyInvited = true; + } Player.reapplyAllAugmentations(); Player.reapplyAllSourceFiles(); Player.hp.current = Player.hp.max;