fix: restrict sortie mission types based on what the tileset supports (#2003)
Closes #2000 Reviewed-on: #2003 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:
parent
58549c1488
commit
e545ecf767
@ -1,11 +1,12 @@
|
|||||||
import staticWorldState from "@/static/fixed_responses/worldState/worldState.json";
|
import staticWorldState from "@/static/fixed_responses/worldState/worldState.json";
|
||||||
import sortieTilesets from "@/static/fixed_responses/worldState/sortieTilesets.json";
|
import sortieTilesets from "@/static/fixed_responses/worldState/sortieTilesets.json";
|
||||||
|
import sortieTilesetMissions from "@/static/fixed_responses/worldState/sortieTilesetMissions.json";
|
||||||
import syndicateMissions from "@/static/fixed_responses/worldState/syndicateMissions.json";
|
import syndicateMissions from "@/static/fixed_responses/worldState/syndicateMissions.json";
|
||||||
import { buildConfig } from "@/src/services/buildConfigService";
|
import { buildConfig } from "@/src/services/buildConfigService";
|
||||||
import { unixTimesInMs } from "@/src/constants/timeConstants";
|
import { unixTimesInMs } from "@/src/constants/timeConstants";
|
||||||
import { config } from "@/src/services/configService";
|
import { config } from "@/src/services/configService";
|
||||||
import { CRng } from "@/src/services/rngService";
|
import { CRng } from "@/src/services/rngService";
|
||||||
import { eMissionType, ExportNightwave, ExportRegions, IRegion } from "warframe-public-export-plus";
|
import { ExportNightwave, ExportRegions, IRegion } from "warframe-public-export-plus";
|
||||||
import {
|
import {
|
||||||
ICalendarDay,
|
ICalendarDay,
|
||||||
ICalendarEvent,
|
ICalendarEvent,
|
||||||
@ -72,12 +73,6 @@ const sortieFactionToFactionIndexes: Record<string, number[]> = {
|
|||||||
FC_OROKIN: [3]
|
FC_OROKIN: [3]
|
||||||
};
|
};
|
||||||
|
|
||||||
const sortieFactionToSpecialMissionTileset: Record<string, string> = {
|
|
||||||
FC_GRINEER: "GrineerGalleonTileset",
|
|
||||||
FC_CORPUS: "CorpusShipTileset",
|
|
||||||
FC_INFESTATION: "CorpusShipTileset"
|
|
||||||
};
|
|
||||||
|
|
||||||
const sortieBossNode: Record<Exclude<TSortieBoss, "SORTIE_BOSS_CORRUPTED_VOR">, string> = {
|
const sortieBossNode: Record<Exclude<TSortieBoss, "SORTIE_BOSS_CORRUPTED_VOR">, string> = {
|
||||||
SORTIE_BOSS_ALAD: "SolNode53",
|
SORTIE_BOSS_ALAD: "SolNode53",
|
||||||
SORTIE_BOSS_AMBULAS: "SolNode51",
|
SORTIE_BOSS_AMBULAS: "SolNode51",
|
||||||
@ -217,6 +212,27 @@ const pushSyndicateMissions = (
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
type TSortieTileset = keyof typeof sortieTilesetMissions;
|
||||||
|
|
||||||
|
const pushTilesetModifiers = (modifiers: string[], tileset: TSortieTileset): void => {
|
||||||
|
switch (tileset) {
|
||||||
|
case "GrineerForestTileset":
|
||||||
|
modifiers.push("SORTIE_MODIFIER_HAZARD_FOG");
|
||||||
|
break;
|
||||||
|
case "CorpusShipTileset":
|
||||||
|
case "GrineerGalleonTileset":
|
||||||
|
case "InfestedCorpusShipTileset":
|
||||||
|
modifiers.push("SORTIE_MODIFIER_HAZARD_MAGNETIC");
|
||||||
|
modifiers.push("SORTIE_MODIFIER_HAZARD_FIRE");
|
||||||
|
modifiers.push("SORTIE_MODIFIER_HAZARD_ICE");
|
||||||
|
break;
|
||||||
|
case "CorpusIcePlanetTileset":
|
||||||
|
case "CorpusIcePlanetTilesetCaves":
|
||||||
|
modifiers.push("SORTIE_MODIFIER_HAZARD_COLD");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
export const getSortie = (day: number): ISortie => {
|
export const getSortie = (day: number): ISortie => {
|
||||||
const seed = new CRng(day).randomInt(0, 0xffff);
|
const seed = new CRng(day).randomInt(0, 0xffff);
|
||||||
const rng = new CRng(seed);
|
const rng = new CRng(seed);
|
||||||
@ -224,54 +240,22 @@ export const getSortie = (day: number): ISortie => {
|
|||||||
const boss = rng.randomElement(sortieBosses)!;
|
const boss = rng.randomElement(sortieBosses)!;
|
||||||
|
|
||||||
const nodes: string[] = [];
|
const nodes: string[] = [];
|
||||||
const availableMissionIndexes: number[] = [];
|
|
||||||
for (const [key, value] of Object.entries(ExportRegions)) {
|
for (const [key, value] of Object.entries(ExportRegions)) {
|
||||||
if (
|
if (
|
||||||
sortieFactionToSystemIndexes[sortieBossToFaction[boss]].includes(value.systemIndex) &&
|
sortieFactionToSystemIndexes[sortieBossToFaction[boss]].includes(value.systemIndex) &&
|
||||||
sortieFactionToFactionIndexes[sortieBossToFaction[boss]].includes(value.factionIndex!) &&
|
sortieFactionToFactionIndexes[sortieBossToFaction[boss]].includes(value.factionIndex!) &&
|
||||||
key in sortieTilesets
|
key in sortieTilesets
|
||||||
) {
|
) {
|
||||||
if (
|
|
||||||
value.missionIndex != 0 && // Assassination will be decided independently
|
|
||||||
value.missionIndex != 5 && // Sorties do not have capture missions
|
|
||||||
!availableMissionIndexes.includes(value.missionIndex)
|
|
||||||
) {
|
|
||||||
availableMissionIndexes.push(value.missionIndex);
|
|
||||||
}
|
|
||||||
nodes.push(key);
|
nodes.push(key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const specialMissionTypes = [1, 3, 5, 9];
|
|
||||||
if (!(sortieBossToFaction[boss] in sortieFactionToSpecialMissionTileset)) {
|
|
||||||
for (const missionType of specialMissionTypes) {
|
|
||||||
const i = availableMissionIndexes.indexOf(missionType);
|
|
||||||
if (i != -1) {
|
|
||||||
availableMissionIndexes.splice(i, 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const selectedNodes: ISortieMission[] = [];
|
const selectedNodes: ISortieMission[] = [];
|
||||||
const missionTypes = new Set();
|
const missionTypes = new Set();
|
||||||
|
|
||||||
for (let i = 0; i < 3; i++) {
|
for (let i = 0; i < 3; i++) {
|
||||||
let randomIndex;
|
const randomIndex = rng.randomInt(0, nodes.length - 1);
|
||||||
let node;
|
const node = nodes[randomIndex];
|
||||||
let missionIndex;
|
|
||||||
do {
|
|
||||||
randomIndex = rng.randomInt(0, nodes.length - 1);
|
|
||||||
node = nodes[randomIndex];
|
|
||||||
|
|
||||||
missionIndex = ExportRegions[node].missionIndex;
|
|
||||||
if (missionIndex != 28) {
|
|
||||||
missionIndex = rng.randomElement(availableMissionIndexes)!;
|
|
||||||
}
|
|
||||||
} while (
|
|
||||||
specialMissionTypes.indexOf(missionIndex) != -1 &&
|
|
||||||
sortieTilesets[node as keyof typeof sortieTilesets] !=
|
|
||||||
sortieFactionToSpecialMissionTileset[sortieBossToFaction[boss]]
|
|
||||||
);
|
|
||||||
|
|
||||||
const modifiers = [
|
const modifiers = [
|
||||||
"SORTIE_MODIFIER_LOW_ENERGY",
|
"SORTIE_MODIFIER_LOW_ENERGY",
|
||||||
@ -294,28 +278,10 @@ export const getSortie = (day: number): ISortie => {
|
|||||||
"SORTIE_MODIFIER_RIFLE_ONLY",
|
"SORTIE_MODIFIER_RIFLE_ONLY",
|
||||||
"SORTIE_MODIFIER_BOW_ONLY"
|
"SORTIE_MODIFIER_BOW_ONLY"
|
||||||
];
|
];
|
||||||
const pushTilesetModifiers = (tileset: string): void => {
|
|
||||||
switch (tileset) {
|
|
||||||
case "GrineerForestTileset":
|
|
||||||
modifiers.push("SORTIE_MODIFIER_HAZARD_FOG");
|
|
||||||
break;
|
|
||||||
case "CorpusShipTileset":
|
|
||||||
case "GrineerGalleonTileset":
|
|
||||||
case "InfestedCorpusShipTileset":
|
|
||||||
modifiers.push("SORTIE_MODIFIER_HAZARD_MAGNETIC");
|
|
||||||
modifiers.push("SORTIE_MODIFIER_HAZARD_FIRE");
|
|
||||||
modifiers.push("SORTIE_MODIFIER_HAZARD_ICE");
|
|
||||||
break;
|
|
||||||
case "CorpusIcePlanetTileset":
|
|
||||||
case "CorpusIcePlanetTilesetCaves":
|
|
||||||
modifiers.push("SORTIE_MODIFIER_HAZARD_COLD");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
if (i == 2 && boss != "SORTIE_BOSS_CORRUPTED_VOR" && rng.randomInt(0, 2) == 2) {
|
if (i == 2 && boss != "SORTIE_BOSS_CORRUPTED_VOR" && rng.randomInt(0, 2) == 2) {
|
||||||
const tileset = sortieTilesets[sortieBossNode[boss] as keyof typeof sortieTilesets];
|
const tileset = sortieTilesets[sortieBossNode[boss] as keyof typeof sortieTilesets] as TSortieTileset;
|
||||||
pushTilesetModifiers(tileset);
|
pushTilesetModifiers(modifiers, tileset);
|
||||||
|
|
||||||
const modifierType = rng.randomElement(modifiers)!;
|
const modifierType = rng.randomElement(modifiers)!;
|
||||||
|
|
||||||
@ -328,9 +294,12 @@ export const getSortie = (day: number): ISortie => {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
const missionType = eMissionType[missionIndex].tag;
|
const tileset = sortieTilesets[node as keyof typeof sortieTilesets] as TSortieTileset;
|
||||||
|
pushTilesetModifiers(modifiers, tileset);
|
||||||
|
|
||||||
if (missionTypes.has(missionType)) {
|
const missionType = rng.randomElement(sortieTilesetMissions[tileset])!;
|
||||||
|
|
||||||
|
if (missionTypes.has(missionType) || missionType == "MT_ASSASSINATION") {
|
||||||
i--;
|
i--;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -349,9 +318,6 @@ export const getSortie = (day: number): ISortie => {
|
|||||||
modifiers.push("SORTIE_MODIFIER_SHIELDS");
|
modifiers.push("SORTIE_MODIFIER_SHIELDS");
|
||||||
}
|
}
|
||||||
|
|
||||||
const tileset = sortieTilesets[node as keyof typeof sortieTilesets];
|
|
||||||
pushTilesetModifiers(tileset);
|
|
||||||
|
|
||||||
const modifierType = rng.randomElement(modifiers)!;
|
const modifierType = rng.randomElement(modifiers)!;
|
||||||
|
|
||||||
selectedNodes.push({
|
selectedNodes.push({
|
||||||
|
45
static/fixed_responses/worldState/sortieTilesetMissions.json
Normal file
45
static/fixed_responses/worldState/sortieTilesetMissions.json
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
{
|
||||||
|
"CorpusGasCityTileset": ["MT_ARTIFACT", "MT_ASSASSINATION", "MT_DEFENSE", "MT_EXTERMINATION", "MT_INTEL", "MT_MOBILE_DEFENSE", "MT_RESCUE", "MT_SABOTAGE", "MT_SURVIVAL", "MT_TERRITORY"],
|
||||||
|
"CorpusIcePlanetTileset": ["MT_ASSASSINATION", "MT_DEFENSE", "MT_EXCAVATE", "MT_INTEL", "MT_MOBILE_DEFENSE", "MT_RESCUE", "MT_RETRIEVAL", "MT_TERRITORY"],
|
||||||
|
"CorpusIcePlanetTilesetCaves": ["MT_EXTERMINATION", "MT_INTEL"],
|
||||||
|
"CorpusOutpostTileset": [
|
||||||
|
"MT_ARTIFACT",
|
||||||
|
"MT_ASSASSINATION",
|
||||||
|
"MT_DEFENSE",
|
||||||
|
"MT_EXCAVATE",
|
||||||
|
"MT_EXTERMINATION",
|
||||||
|
"MT_INTEL",
|
||||||
|
"MT_MOBILE_DEFENSE",
|
||||||
|
"MT_RESCUE",
|
||||||
|
"MT_SABOTAGE",
|
||||||
|
"MT_SURVIVAL",
|
||||||
|
"MT_TERRITORY"
|
||||||
|
],
|
||||||
|
"CorpusShipTileset": ["MT_ARTIFACT", "MT_ASSASSINATION", "MT_DEFENSE", "MT_EXTERMINATION", "MT_INTEL", "MT_MOBILE_DEFENSE", "MT_RESCUE", "MT_SABOTAGE", "MT_SURVIVAL", "MT_TERRITORY"],
|
||||||
|
"EidolonTileset": ["MT_LANDSCAPE"],
|
||||||
|
"GrineerAsteroidTileset": ["MT_ASSASSINATION", "MT_DEFENSE", "MT_EVACUATION", "MT_EXTERMINATION", "MT_INTEL", "MT_MOBILE_DEFENSE", "MT_RESCUE", "MT_SURVIVAL", "MT_TERRITORY"],
|
||||||
|
"GrineerForestTileset": ["MT_ASSASSINATION", "MT_EXTERMINATION", "MT_INTEL", "MT_MOBILE_DEFENSE", "MT_TERRITORY"],
|
||||||
|
"GrineerFortressTileset": ["MT_ARTIFACT", "MT_ASSAULT", "MT_INTEL", "MT_MOBILE_DEFENSE", "MT_RESCUE", "MT_SURVIVAL"],
|
||||||
|
"GrineerGalleonTileset": [
|
||||||
|
"MT_ARTIFACT",
|
||||||
|
"MT_ASSASSINATION",
|
||||||
|
"MT_DEFENSE",
|
||||||
|
"MT_EVACUATION",
|
||||||
|
"MT_EXTERMINATION",
|
||||||
|
"MT_INTEL",
|
||||||
|
"MT_MOBILE_DEFENSE",
|
||||||
|
"MT_RESCUE",
|
||||||
|
"MT_SABOTAGE",
|
||||||
|
"MT_SURVIVAL",
|
||||||
|
"MT_TERRITORY"
|
||||||
|
],
|
||||||
|
"GrineerOceanTileset": ["MT_DEFENSE", "MT_EXTERMINATION", "MT_INTEL", "MT_MOBILE_DEFENSE", "MT_RESCUE", "MT_SABOTAGE", "MT_SURVIVAL", "MT_TERRITORY"],
|
||||||
|
"GrineerOceanTilesetAnywhere": ["MT_ASSASSINATION"],
|
||||||
|
"GrineerSettlementTileset": ["MT_ASSASSINATION", "MT_DEFENSE", "MT_EXTERMINATION", "MT_INTEL", "MT_MOBILE_DEFENSE", "MT_RESCUE", "MT_SABOTAGE", "MT_TERRITORY"],
|
||||||
|
"GrineerShipyardsTileset": ["MT_DEFENSE", "MT_EXTERMINATION", "MT_INTEL", "MT_MOBILE_DEFENSE", "MT_RESCUE", "MT_RETRIEVAL", "MT_TERRITORY"],
|
||||||
|
"InfestedCorpusShipTileset": ["MT_ASSASSINATION", "MT_HIVE", "MT_MOBILE_DEFENSE", "MT_RESCUE"],
|
||||||
|
"OrokinDerelictTileset": ["MT_ARTIFACT", "MT_ASSASSINATION", "MT_DEFENSE", "MT_EXTERMINATION", "MT_MOBILE_DEFENSE", "MT_SABOTAGE", "MT_SURVIVAL"],
|
||||||
|
"OrokinMoonTilesetCorpus": ["MT_ARTIFACT", "MT_DEFENSE", "MT_EXTERMINATION", "MT_MOBILE_DEFENSE", "MT_RESCUE", "MT_SURVIVAL"],
|
||||||
|
"OrokinMoonTilesetGrineer": ["MT_DEFENSE", "MT_EXTERMINATION", "MT_MOBILE_DEFENSE", "MT_RESCUE", "MT_SURVIVAL"],
|
||||||
|
"OrokinVoidTileset": ["MT_DEFENSE", "MT_EXTERMINATION", "MT_MOBILE_DEFENSE", "MT_SABOTAGE", "MT_SURVIVAL", "MT_TERRITORY"]
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user