mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2024-12-20 05:05:47 +01:00
FACTIONS: fix unstable display order (#920)
This commit is contained in:
parent
34cc0441c2
commit
7fc46649f9
@ -143,12 +143,12 @@ export function FactionsDev(): React.ReactElement {
|
|||||||
value={selectedFaction.name}
|
value={selectedFaction.name}
|
||||||
startAdornment={
|
startAdornment={
|
||||||
<>
|
<>
|
||||||
<Tooltip title={`Hear rumor about ${selectedFaction}`}>
|
<Tooltip title={`Hear rumor about ${selectedFaction.name}`}>
|
||||||
<IconButton onClick={receiveRumor} size="large">
|
<IconButton onClick={receiveRumor} size="large">
|
||||||
<ChatIcon />
|
<ChatIcon />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
<Tooltip title={`Receive invitation to ${selectedFaction}`}>
|
<Tooltip title={`Receive invitation to ${selectedFaction.name}`}>
|
||||||
<IconButton onClick={receiveInvite} size="large">
|
<IconButton onClick={receiveInvite} size="large">
|
||||||
<ReplyIcon />
|
<ReplyIcon />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
|
@ -3,7 +3,7 @@ import type { Faction } from "./Faction";
|
|||||||
|
|
||||||
import { Augmentations } from "../Augmentation/Augmentations";
|
import { Augmentations } from "../Augmentation/Augmentations";
|
||||||
import { PlayerOwnedAugmentation } from "../Augmentation/PlayerOwnedAugmentation";
|
import { PlayerOwnedAugmentation } from "../Augmentation/PlayerOwnedAugmentation";
|
||||||
import { AugmentationName, FactionName } from "@enums";
|
import { AugmentationName } from "@enums";
|
||||||
import { currentNodeMults } from "../BitNode/BitNodeMultipliers";
|
import { currentNodeMults } from "../BitNode/BitNodeMultipliers";
|
||||||
|
|
||||||
import { Player } from "@player";
|
import { Player } from "@player";
|
||||||
@ -20,7 +20,7 @@ import { InvitationEvent } from "./ui/InvitationModal";
|
|||||||
import { SFC32RNG } from "../Casino/RNG";
|
import { SFC32RNG } from "../Casino/RNG";
|
||||||
import { isFactionWork } from "../Work/FactionWork";
|
import { isFactionWork } from "../Work/FactionWork";
|
||||||
import { getAugCost } from "../Augmentation/AugmentationHelpers";
|
import { getAugCost } from "../Augmentation/AugmentationHelpers";
|
||||||
import { createEnumKeyedRecord, getRecordKeys } from "../Types/Record";
|
import { getRecordKeys } from "../Types/Record";
|
||||||
|
|
||||||
export function inviteToFaction(faction: Faction): void {
|
export function inviteToFaction(faction: Faction): void {
|
||||||
if (faction.alreadyInvited || faction.isMember) return;
|
if (faction.alreadyInvited || faction.isMember) return;
|
||||||
@ -34,23 +34,18 @@ export function inviteToFaction(faction: Faction): void {
|
|||||||
export function joinFaction(faction: Faction): void {
|
export function joinFaction(faction: Faction): void {
|
||||||
if (faction.isMember) return;
|
if (faction.isMember) return;
|
||||||
faction.isMember = true;
|
faction.isMember = true;
|
||||||
Player.factions.push(faction.name);
|
// Add this faction to player's faction list, keeping it in standard order
|
||||||
let i = 0;
|
Player.factions = getRecordKeys(Factions).filter((facName) => Factions[facName].isMember);
|
||||||
const factionIndexes = createEnumKeyedRecord(FactionName, (__) => i++);
|
|
||||||
Player.factions.sort((a, b) => factionIndexes[a] - factionIndexes[b]);
|
|
||||||
const factionInfo = faction.getInfo();
|
|
||||||
|
|
||||||
//Determine what factions you are banned from now that you have joined this faction
|
// Ban player from this faction's enemies
|
||||||
for (const enemy of factionInfo.enemies) {
|
for (const enemy of faction.getInfo().enemies) {
|
||||||
if (Factions[enemy]) Factions[enemy].isBanned = true;
|
if (Factions[enemy]) Factions[enemy].isBanned = true;
|
||||||
Player.factionRumors.delete(enemy);
|
Player.factionRumors.delete(enemy);
|
||||||
}
|
}
|
||||||
for (let i = 0; i < Player.factionInvitations.length; ++i) {
|
// Remove invalid invites and rumors
|
||||||
if (Player.factionInvitations[i] == faction.name || Factions[Player.factionInvitations[i]].isBanned) {
|
Player.factionInvitations = Player.factionInvitations.filter((factionName) => {
|
||||||
Player.factionInvitations.splice(i, 1);
|
return !Factions[factionName].isMember && !Factions[factionName].isBanned;
|
||||||
i--;
|
});
|
||||||
}
|
|
||||||
}
|
|
||||||
Player.factionRumors.delete(faction.name);
|
Player.factionRumors.delete(faction.name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -430,6 +430,25 @@ export const FactionInfos: Record<FactionName, FactionInfo> = {
|
|||||||
keepOnInstall: false,
|
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
|
// City factions, essentially governments
|
||||||
[FactionName.Aevum]: new FactionInfo({
|
[FactionName.Aevum]: new FactionInfo({
|
||||||
infoText: <>The Silicon City.</>,
|
infoText: <>The Silicon City.</>,
|
||||||
@ -631,25 +650,6 @@ export const FactionInfos: Record<FactionName, FactionInfo> = {
|
|||||||
offerSecurityWork: true,
|
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
|
// Special Factions
|
||||||
[FactionName.Bladeburners]: new FactionInfo({
|
[FactionName.Bladeburners]: new FactionInfo({
|
||||||
infoText: (
|
infoText: (
|
||||||
|
@ -209,16 +209,16 @@ export function FactionsRoot(): React.ReactElement {
|
|||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
const rerender = useRerender(200);
|
const rerender = useRerender(200);
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
Player.factionInvitations.forEach((faction) => {
|
Player.factionInvitations.forEach((factionName) => {
|
||||||
InvitationsSeen.add(faction);
|
InvitationsSeen.add(factionName);
|
||||||
});
|
});
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const allFactions = Object.values(FactionName).map((faction) => faction as string);
|
// Display joined factions in the standard order
|
||||||
const allJoinedFactions = [...Player.factions].map((facName) => Factions[facName]).filter((faction) => !!faction);
|
const joinedFactions = Object.values(Factions).filter((faction) => faction.isMember);
|
||||||
allJoinedFactions.sort((a, b) => allFactions.indexOf(a.name) - allFactions.indexOf(b.name));
|
// Display invitations and rumors in the order they were received
|
||||||
|
const invitedFactions = Player.factionInvitations.map((facName) => Factions[facName]).filter((faction) => !!faction);
|
||||||
const invitations = Player.factionInvitations.map((facName) => Factions[facName]).filter((faction) => !!faction);
|
const rumoredFactions = [...Player.factionRumors].map((facName) => Factions[facName]).filter((faction) => !!faction);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Container disableGutters maxWidth="lg" sx={{ mx: 0, mb: 10 }}>
|
<Container disableGutters maxWidth="lg" sx={{ mx: 0, mb: 10 }}>
|
||||||
@ -241,7 +241,7 @@ export function FactionsRoot(): React.ReactElement {
|
|||||||
display="grid"
|
display="grid"
|
||||||
sx={{
|
sx={{
|
||||||
gap: 1,
|
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 } },
|
[theme.breakpoints.down("lg")]: { gridTemplateColumns: "1fr", "& > span:nth-of-type(1)": { order: 1 } },
|
||||||
gridTemplateRows: "minmax(0, 1fr)",
|
gridTemplateRows: "minmax(0, 1fr)",
|
||||||
"& > span > .MuiBox-root": {
|
"& > span > .MuiBox-root": {
|
||||||
@ -251,35 +251,22 @@ export function FactionsRoot(): React.ReactElement {
|
|||||||
},
|
},
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<span>
|
<span className="factions-invites">
|
||||||
{invitations.length > 0 && (
|
{invitedFactions.length > 0 && (
|
||||||
<>
|
<>
|
||||||
<Typography variant="h5" color="primary">
|
<Typography variant="h5" color="primary">
|
||||||
Faction Invitations
|
Faction Invitations
|
||||||
</Typography>
|
</Typography>
|
||||||
<Box>
|
<Box>
|
||||||
{invitations.map((faction) => (
|
{invitedFactions.map((faction) => (
|
||||||
<FactionElement key={faction.name} faction={faction} rerender={rerender} />
|
<FactionElement key={faction.name} faction={faction} rerender={rerender} />
|
||||||
))}
|
))}
|
||||||
</Box>
|
</Box>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{Player.factionRumors.size > 0 && (
|
|
||||||
<>
|
|
||||||
<Typography variant="h5" color="primary">
|
|
||||||
Rumors
|
|
||||||
</Typography>
|
|
||||||
<div style={{ display: "grid", gap: 1, gridAutoRows: "minmax(70px, auto)" }}>
|
|
||||||
{[...Player.factionRumors].map((factionName) => (
|
|
||||||
<FactionElement key={factionName} faction={Factions[factionName]} rerender={rerender} />
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
<span>
|
<span className="factions-joined">
|
||||||
{Player.inGang() && (
|
{Player.inGang() && (
|
||||||
<>
|
<>
|
||||||
<Typography variant="h5" color="primary">
|
<Typography variant="h5" color="primary">
|
||||||
@ -294,8 +281,8 @@ export function FactionsRoot(): React.ReactElement {
|
|||||||
Your Factions
|
Your Factions
|
||||||
</Typography>
|
</Typography>
|
||||||
<Box>
|
<Box>
|
||||||
{allJoinedFactions.length > 0 ? (
|
{joinedFactions.length > 0 ? (
|
||||||
allJoinedFactions.map((faction) => {
|
joinedFactions.map((faction) => {
|
||||||
if (Player.getGangName() === faction.name) return null;
|
if (Player.getGangName() === faction.name) return null;
|
||||||
return <FactionElement key={faction.name} faction={faction} rerender={rerender} />;
|
return <FactionElement key={faction.name} faction={faction} rerender={rerender} />;
|
||||||
})
|
})
|
||||||
@ -305,6 +292,20 @@ export function FactionsRoot(): React.ReactElement {
|
|||||||
</Box>
|
</Box>
|
||||||
</span>
|
</span>
|
||||||
</Box>
|
</Box>
|
||||||
|
<span className="factions-rumors">
|
||||||
|
{rumoredFactions.length > 0 && (
|
||||||
|
<>
|
||||||
|
<Typography variant="h5" color="primary">
|
||||||
|
Rumors
|
||||||
|
</Typography>
|
||||||
|
<Box style={{ display: "grid", gap: 1, gridAutoRows: "minmax(70px, auto)" }}>
|
||||||
|
{rumoredFactions.map((faction) => (
|
||||||
|
<FactionElement key={faction.name} faction={faction} rerender={rerender} />
|
||||||
|
))}
|
||||||
|
</Box>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</span>
|
||||||
</Container>
|
</Container>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -171,7 +171,8 @@ export function prestigeSourceFile(this: PlayerObject): void {
|
|||||||
|
|
||||||
export function receiveInvite(this: PlayerObject, factionName: FactionName): void {
|
export function receiveInvite(this: PlayerObject, factionName: FactionName): void {
|
||||||
const faction = Factions[factionName];
|
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.factionInvitations.push(factionName);
|
||||||
this.factionRumors.delete(factionName);
|
this.factionRumors.delete(factionName);
|
||||||
faction.discovery = FactionDiscovery.known;
|
faction.discovery = FactionDiscovery.known;
|
||||||
|
@ -35,13 +35,13 @@ export function prestigeAugmentation(): void {
|
|||||||
initBitNodeMultipliers();
|
initBitNodeMultipliers();
|
||||||
|
|
||||||
// Maintain invites to factions with the 'keepOnInstall' flag, and rumors about others
|
// Maintain invites to factions with the 'keepOnInstall' flag, and rumors about others
|
||||||
const maintainInvites = [];
|
const maintainInvites = new Set<FactionName>();
|
||||||
const maintainRumors = [];
|
const maintainRumors = new Set<FactionName>();
|
||||||
for (const facName of [...Player.factions, ...Player.factionInvitations]) {
|
for (const facName of [...Player.factions, ...Player.factionInvitations]) {
|
||||||
if (Factions[facName].getInfo().keep) {
|
if (Factions[facName].getInfo().keep) {
|
||||||
maintainInvites.push(facName);
|
maintainInvites.add(facName);
|
||||||
} else {
|
} else {
|
||||||
maintainRumors.push(facName);
|
maintainRumors.add(facName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -92,8 +92,10 @@ export function prestigeAugmentation(): void {
|
|||||||
// Recalculate the bonus for circadian modulator aug
|
// Recalculate the bonus for circadian modulator aug
|
||||||
initCircadianModulator();
|
initCircadianModulator();
|
||||||
|
|
||||||
Player.factionInvitations = Player.factionInvitations.concat(maintainInvites);
|
Player.factionInvitations = Player.factionInvitations.concat([...maintainInvites]);
|
||||||
for (const factionName of maintainInvites) Factions[factionName].alreadyInvited = true;
|
for (const factionName of maintainInvites) {
|
||||||
|
Factions[factionName].alreadyInvited = true;
|
||||||
|
}
|
||||||
Player.reapplyAllAugmentations();
|
Player.reapplyAllAugmentations();
|
||||||
Player.reapplyAllSourceFiles();
|
Player.reapplyAllSourceFiles();
|
||||||
Player.hp.current = Player.hp.max;
|
Player.hp.current = Player.hp.max;
|
||||||
|
Loading…
Reference in New Issue
Block a user