forked from OpenWF/SpaceNinjaServer
		
	fix: restrict sortie mission types based on what the tileset supports (#2003)
Closes #2000 Reviewed-on: OpenWF/SpaceNinjaServer#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 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 { buildConfig } from "@/src/services/buildConfigService";
 | 
			
		||||
import { unixTimesInMs } from "@/src/constants/timeConstants";
 | 
			
		||||
import { config } from "@/src/services/configService";
 | 
			
		||||
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 {
 | 
			
		||||
    ICalendarDay,
 | 
			
		||||
    ICalendarEvent,
 | 
			
		||||
@ -72,12 +73,6 @@ const sortieFactionToFactionIndexes: Record<string, number[]> = {
 | 
			
		||||
    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> = {
 | 
			
		||||
    SORTIE_BOSS_ALAD: "SolNode53",
 | 
			
		||||
    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 => {
 | 
			
		||||
    const seed = new CRng(day).randomInt(0, 0xffff);
 | 
			
		||||
    const rng = new CRng(seed);
 | 
			
		||||
@ -224,54 +240,22 @@ export const getSortie = (day: number): ISortie => {
 | 
			
		||||
    const boss = rng.randomElement(sortieBosses)!;
 | 
			
		||||
 | 
			
		||||
    const nodes: string[] = [];
 | 
			
		||||
    const availableMissionIndexes: number[] = [];
 | 
			
		||||
    for (const [key, value] of Object.entries(ExportRegions)) {
 | 
			
		||||
        if (
 | 
			
		||||
            sortieFactionToSystemIndexes[sortieBossToFaction[boss]].includes(value.systemIndex) &&
 | 
			
		||||
            sortieFactionToFactionIndexes[sortieBossToFaction[boss]].includes(value.factionIndex!) &&
 | 
			
		||||
            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);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    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 missionTypes = new Set();
 | 
			
		||||
 | 
			
		||||
    for (let i = 0; i < 3; i++) {
 | 
			
		||||
        let randomIndex;
 | 
			
		||||
        let node;
 | 
			
		||||
        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 randomIndex = rng.randomInt(0, nodes.length - 1);
 | 
			
		||||
        const node = nodes[randomIndex];
 | 
			
		||||
 | 
			
		||||
        const modifiers = [
 | 
			
		||||
            "SORTIE_MODIFIER_LOW_ENERGY",
 | 
			
		||||
@ -294,28 +278,10 @@ export const getSortie = (day: number): ISortie => {
 | 
			
		||||
            "SORTIE_MODIFIER_RIFLE_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) {
 | 
			
		||||
            const tileset = sortieTilesets[sortieBossNode[boss] as keyof typeof sortieTilesets];
 | 
			
		||||
            pushTilesetModifiers(tileset);
 | 
			
		||||
            const tileset = sortieTilesets[sortieBossNode[boss] as keyof typeof sortieTilesets] as TSortieTileset;
 | 
			
		||||
            pushTilesetModifiers(modifiers, tileset);
 | 
			
		||||
 | 
			
		||||
            const modifierType = rng.randomElement(modifiers)!;
 | 
			
		||||
 | 
			
		||||
@ -328,9 +294,12 @@ export const getSortie = (day: number): ISortie => {
 | 
			
		||||
            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--;
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
@ -349,9 +318,6 @@ export const getSortie = (day: number): ISortie => {
 | 
			
		||||
            modifiers.push("SORTIE_MODIFIER_SHIELDS");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        const tileset = sortieTilesets[node as keyof typeof sortieTilesets];
 | 
			
		||||
        pushTilesetModifiers(tileset);
 | 
			
		||||
 | 
			
		||||
        const modifierType = rng.randomElement(modifiers)!;
 | 
			
		||||
 | 
			
		||||
        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