fix: better handling of assassination missions in sorties (#1930)
All checks were successful
Build Docker image / docker (push) Successful in 37s
Build / build (push) Successful in 1m36s

Closes #1918

Reviewed-on: #1930
Co-authored-by: Sainan <63328889+Sainan@users.noreply.github.com>
Co-committed-by: Sainan <63328889+Sainan@users.noreply.github.com>
This commit is contained in:
Sainan 2025-04-30 13:28:34 -07:00 committed by Sainan
parent ed54e00a03
commit 7d02906656
2 changed files with 29 additions and 36 deletions

View File

@ -6,7 +6,7 @@ export interface IRngResult {
probability: number; probability: number;
} }
export const getRandomElement = <T>(arr: T[]): T | undefined => { export const getRandomElement = <T>(arr: readonly T[]): T | undefined => {
return arr[Math.floor(Math.random() * arr.length)]; return arr[Math.floor(Math.random() * arr.length)];
}; };
@ -113,7 +113,7 @@ export class CRng {
return min; return min;
} }
randomElement<T>(arr: T[]): T | undefined { randomElement<T>(arr: readonly T[]): T | undefined {
return arr[Math.floor(this.random() * arr.length)]; return arr[Math.floor(this.random() * arr.length)];
} }
@ -145,7 +145,7 @@ export class SRng {
return min; return min;
} }
randomElement<T>(arr: T[]): T | undefined { randomElement<T>(arr: readonly T[]): T | undefined {
return arr[this.randomInt(0, arr.length - 1)]; return arr[this.randomInt(0, arr.length - 1)];
} }

View File

@ -33,9 +33,11 @@ const sortieBosses = [
"SORTIE_BOSS_LEPHANTIS", "SORTIE_BOSS_LEPHANTIS",
"SORTIE_BOSS_INFALAD", "SORTIE_BOSS_INFALAD",
"SORTIE_BOSS_CORRUPTED_VOR" "SORTIE_BOSS_CORRUPTED_VOR"
]; ] as const;
const sortieBossToFaction: Record<string, string> = { type TSortieBoss = (typeof sortieBosses)[number];
const sortieBossToFaction: Record<TSortieBoss, string> = {
SORTIE_BOSS_HYENA: "FC_CORPUS", SORTIE_BOSS_HYENA: "FC_CORPUS",
SORTIE_BOSS_KELA: "FC_GRINEER", SORTIE_BOSS_KELA: "FC_GRINEER",
SORTIE_BOSS_VOR: "FC_GRINEER", SORTIE_BOSS_VOR: "FC_GRINEER",
@ -74,21 +76,22 @@ const sortieFactionToSpecialMissionTileset: Record<string, string> = {
FC_INFESTATION: "CorpusShipTileset" FC_INFESTATION: "CorpusShipTileset"
}; };
const sortieBossNode: Record<string, string> = { const sortieBossNode: Record<Exclude<TSortieBoss, "SORTIE_BOSS_CORRUPTED_VOR">, string> = {
SORTIE_BOSS_HYENA: "SolNode127",
SORTIE_BOSS_KELA: "SolNode193",
SORTIE_BOSS_VOR: "SolNode108",
SORTIE_BOSS_RUK: "SolNode32",
SORTIE_BOSS_HEK: "SolNode24",
SORTIE_BOSS_KRIL: "SolNode99",
SORTIE_BOSS_TYL: "SolNode105",
SORTIE_BOSS_JACKAL: "SolNode104",
SORTIE_BOSS_ALAD: "SolNode53", SORTIE_BOSS_ALAD: "SolNode53",
SORTIE_BOSS_AMBULAS: "SolNode51", SORTIE_BOSS_AMBULAS: "SolNode51",
SORTIE_BOSS_NEF: "SettlementNode20", SORTIE_BOSS_HEK: "SolNode24",
SORTIE_BOSS_RAPTOR: "SolNode210", SORTIE_BOSS_HYENA: "SolNode127",
SORTIE_BOSS_INFALAD: "SolNode166",
SORTIE_BOSS_JACKAL: "SolNode104",
SORTIE_BOSS_KELA: "SolNode193",
SORTIE_BOSS_KRIL: "SolNode99",
SORTIE_BOSS_LEPHANTIS: "SolNode712", SORTIE_BOSS_LEPHANTIS: "SolNode712",
SORTIE_BOSS_INFALAD: "SolNode705" SORTIE_BOSS_NEF: "SettlementNode20",
SORTIE_BOSS_PHORID: "SolNode171",
SORTIE_BOSS_RAPTOR: "SolNode210",
SORTIE_BOSS_RUK: "SolNode32",
SORTIE_BOSS_TYL: "SolNode105",
SORTIE_BOSS_VOR: "SolNode108"
}; };
const eidolonJobs = [ const eidolonJobs = [
@ -270,6 +273,7 @@ const pushSortieIfRelevant = (worldState: IWorldState, day: number): void => {
key in sortieTilesets key in sortieTilesets
) { ) {
if ( if (
value.missionIndex != 0 && // Assassination will be decided independently
value.missionIndex != 5 && // Sorties do not have capture missions value.missionIndex != 5 && // Sorties do not have capture missions
!availableMissionIndexes.includes(value.missionIndex) !availableMissionIndexes.includes(value.missionIndex)
) { ) {
@ -310,28 +314,17 @@ const pushSortieIfRelevant = (worldState: IWorldState, day: number): void => {
sortieFactionToSpecialMissionTileset[sortieBossToFaction[boss]] sortieFactionToSpecialMissionTileset[sortieBossToFaction[boss]]
); );
if (i == 2 && rng.randomInt(0, 2) == 2) { if (i == 2 && boss != "SORTIE_BOSS_CORRUPTED_VOR" && rng.randomInt(0, 2) == 2) {
const filteredModifiers = modifiers.filter(mod => mod !== "SORTIE_MODIFIER_MELEE_ONLY"); const filteredModifiers = modifiers.filter(mod => mod !== "SORTIE_MODIFIER_MELEE_ONLY");
const modifierType = rng.randomElement(filteredModifiers)!; const modifierType = rng.randomElement(filteredModifiers)!;
if (boss == "SORTIE_BOSS_PHORID") { selectedNodes.push({
selectedNodes.push({ missionType: "MT_ASSASSINATION",
missionType: "MT_ASSASSINATION", modifierType,
modifierType, node: sortieBossNode[boss],
node, tileset: sortieTilesets[sortieBossNode[boss] as keyof typeof sortieTilesets]
tileset: sortieTilesets[node as keyof typeof sortieTilesets] });
}); continue;
nodes.splice(randomIndex, 1);
continue;
} else if (sortieBossNode[boss]) {
selectedNodes.push({
missionType: "MT_ASSASSINATION",
modifierType,
node: sortieBossNode[boss],
tileset: sortieTilesets[sortieBossNode[boss] as keyof typeof sortieTilesets]
});
continue;
}
} }
const missionType = eMissionType[missionIndex].tag; const missionType = eMissionType[missionIndex].tag;