chore: improve LiteSortie handling at week rollover (#1735)
WorldState now provides the upcoming LiteSortie if relevant and the boss is derived from the sortieId so completing it at rollover should work as expected. Reviewed-on: OpenWF/SpaceNinjaServer#1735 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
							
								
									7040d422a2
								
							
						
					
					
						commit
						c2a633b549
					
				@ -53,7 +53,7 @@ import conservationAnimals from "@/static/fixed_responses/conservationAnimals.js
 | 
			
		||||
import { getInfNodes } from "@/src/helpers/nemesisHelpers";
 | 
			
		||||
import { Loadout } from "../models/inventoryModels/loadoutModel";
 | 
			
		||||
import { ILoadoutConfigDatabase } from "../types/saveLoadoutTypes";
 | 
			
		||||
import { getWorldState } from "./worldStateService";
 | 
			
		||||
import { getLiteSortie, getWorldState, idToWeek } from "./worldStateService";
 | 
			
		||||
import { config } from "./configService";
 | 
			
		||||
 | 
			
		||||
const getRotations = (rewardInfo: IRewardInfo, tierOverride?: number): number[] => {
 | 
			
		||||
@ -990,11 +990,7 @@ function getRandomMissionDrops(
 | 
			
		||||
        if (sortieId == "Lite") {
 | 
			
		||||
            sortieId = arr[2];
 | 
			
		||||
 | 
			
		||||
            // TODO: Some way to get from sortieId to reward to make this faster + more reliable at week rollover.
 | 
			
		||||
            const boss = getWorldState().LiteSorties[0].Boss as
 | 
			
		||||
                | "SORTIE_BOSS_AMAR"
 | 
			
		||||
                | "SORTIE_BOSS_NIRA"
 | 
			
		||||
                | "SORTIE_BOSS_BOREAL";
 | 
			
		||||
            const boss = getLiteSortie(idToWeek(sortieId)).Boss;
 | 
			
		||||
            let crystalType = {
 | 
			
		||||
                SORTIE_BOSS_AMAR: "/Lotus/StoreItems/Types/Gameplay/NarmerSorties/ArchonCrystalAmar",
 | 
			
		||||
                SORTIE_BOSS_NIRA: "/Lotus/StoreItems/Types/Gameplay/NarmerSorties/ArchonCrystalNira",
 | 
			
		||||
 | 
			
		||||
@ -4,7 +4,14 @@ import { unixTimesInMs } from "@/src/constants/timeConstants";
 | 
			
		||||
import { config } from "@/src/services/configService";
 | 
			
		||||
import { CRng } from "@/src/services/rngService";
 | 
			
		||||
import { eMissionType, ExportNightwave, ExportRegions } from "warframe-public-export-plus";
 | 
			
		||||
import { ICalendarDay, ICalendarSeason, ISeasonChallenge, ISortie, IWorldState } from "../types/worldStateTypes";
 | 
			
		||||
import {
 | 
			
		||||
    ICalendarDay,
 | 
			
		||||
    ICalendarSeason,
 | 
			
		||||
    ILiteSortie,
 | 
			
		||||
    ISeasonChallenge,
 | 
			
		||||
    ISortie,
 | 
			
		||||
    IWorldState
 | 
			
		||||
} from "../types/worldStateTypes";
 | 
			
		||||
 | 
			
		||||
const sortieBosses = [
 | 
			
		||||
    "SORTIE_BOSS_HYENA",
 | 
			
		||||
@ -941,65 +948,9 @@ export const getWorldState = (buildLabel?: string): IWorldState => {
 | 
			
		||||
    pushSortieIfRelevant(worldState.Sorties, day);
 | 
			
		||||
 | 
			
		||||
    // Archon Hunt cycling every week
 | 
			
		||||
    // TODO: Handle imminent rollover
 | 
			
		||||
    {
 | 
			
		||||
        const boss = ["SORTIE_BOSS_AMAR", "SORTIE_BOSS_NIRA", "SORTIE_BOSS_BOREAL"][week % 3];
 | 
			
		||||
        const showdownNode = ["SolNode99", "SolNode53", "SolNode24"][week % 3];
 | 
			
		||||
        const systemIndex = [3, 4, 2][week % 3]; // Mars, Jupiter, Earth
 | 
			
		||||
 | 
			
		||||
        const nodes: string[] = [];
 | 
			
		||||
        for (const [key, value] of Object.entries(ExportRegions)) {
 | 
			
		||||
            if (
 | 
			
		||||
                value.systemIndex === systemIndex &&
 | 
			
		||||
                value.factionIndex !== undefined &&
 | 
			
		||||
                value.factionIndex < 2 &&
 | 
			
		||||
                value.name.indexOf("Archwing") == -1 &&
 | 
			
		||||
                value.missionIndex != 0 // Exclude MT_ASSASSINATION
 | 
			
		||||
            ) {
 | 
			
		||||
                nodes.push(key);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        const rng = new CRng(week);
 | 
			
		||||
        const firstNodeIndex = rng.randomInt(0, nodes.length - 1);
 | 
			
		||||
        const firstNode = nodes[firstNodeIndex];
 | 
			
		||||
        nodes.splice(firstNodeIndex, 1);
 | 
			
		||||
        worldState.LiteSorties.push({
 | 
			
		||||
            _id: {
 | 
			
		||||
                $oid: Math.trunc(weekStart / 1000).toString(16) + "5e23a244740a190c"
 | 
			
		||||
            },
 | 
			
		||||
            Activation: { $date: { $numberLong: weekStart.toString() } },
 | 
			
		||||
            Expiry: { $date: { $numberLong: weekEnd.toString() } },
 | 
			
		||||
            Reward: "/Lotus/Types/Game/MissionDecks/ArchonSortieRewards",
 | 
			
		||||
            Seed: week,
 | 
			
		||||
            Boss: boss,
 | 
			
		||||
            Missions: [
 | 
			
		||||
                {
 | 
			
		||||
                    missionType: rng.randomElement([
 | 
			
		||||
                        "MT_INTEL",
 | 
			
		||||
                        "MT_MOBILE_DEFENSE",
 | 
			
		||||
                        "MT_EXTERMINATION",
 | 
			
		||||
                        "MT_SABOTAGE",
 | 
			
		||||
                        "MT_RESCUE"
 | 
			
		||||
                    ]),
 | 
			
		||||
                    node: firstNode
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                    missionType: rng.randomElement([
 | 
			
		||||
                        "MT_DEFENSE",
 | 
			
		||||
                        "MT_TERRITORY",
 | 
			
		||||
                        "MT_ARTIFACT",
 | 
			
		||||
                        "MT_EXCAVATE",
 | 
			
		||||
                        "MT_SURVIVAL"
 | 
			
		||||
                    ]),
 | 
			
		||||
                    node: rng.randomElement(nodes)
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                    missionType: "MT_ASSASSINATION",
 | 
			
		||||
                    node: showdownNode
 | 
			
		||||
                }
 | 
			
		||||
            ]
 | 
			
		||||
        });
 | 
			
		||||
    worldState.LiteSorties.push(getLiteSortie(week));
 | 
			
		||||
    if (isBeforeNextExpectedWorldStateRefresh(weekEnd)) {
 | 
			
		||||
        worldState.LiteSorties.push(getLiteSortie(week + 1));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Circuit choices cycling every week
 | 
			
		||||
@ -1071,3 +1022,70 @@ export const getWorldState = (buildLabel?: string): IWorldState => {
 | 
			
		||||
 | 
			
		||||
    return worldState;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const idToWeek = (id: string): number => {
 | 
			
		||||
    return (parseInt(id.substring(0, 8), 16) * 1000 - EPOCH) / 604800000;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const getLiteSortie = (week: number): ILiteSortie => {
 | 
			
		||||
    const boss = (["SORTIE_BOSS_AMAR", "SORTIE_BOSS_NIRA", "SORTIE_BOSS_BOREAL"] as const)[week % 3];
 | 
			
		||||
    const showdownNode = ["SolNode99", "SolNode53", "SolNode24"][week % 3];
 | 
			
		||||
    const systemIndex = [3, 4, 2][week % 3]; // Mars, Jupiter, Earth
 | 
			
		||||
 | 
			
		||||
    const nodes: string[] = [];
 | 
			
		||||
    for (const [key, value] of Object.entries(ExportRegions)) {
 | 
			
		||||
        if (
 | 
			
		||||
            value.systemIndex === systemIndex &&
 | 
			
		||||
            value.factionIndex !== undefined &&
 | 
			
		||||
            value.factionIndex < 2 &&
 | 
			
		||||
            value.name.indexOf("Archwing") == -1 &&
 | 
			
		||||
            value.missionIndex != 0 // Exclude MT_ASSASSINATION
 | 
			
		||||
        ) {
 | 
			
		||||
            nodes.push(key);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const rng = new CRng(week);
 | 
			
		||||
    const firstNodeIndex = rng.randomInt(0, nodes.length - 1);
 | 
			
		||||
    const firstNode = nodes[firstNodeIndex];
 | 
			
		||||
    nodes.splice(firstNodeIndex, 1);
 | 
			
		||||
 | 
			
		||||
    const weekStart = EPOCH + week * 604800000;
 | 
			
		||||
    const weekEnd = weekStart + 604800000;
 | 
			
		||||
    return {
 | 
			
		||||
        _id: {
 | 
			
		||||
            $oid: Math.trunc(weekStart / 1000).toString(16) + "5e23a244740a190c"
 | 
			
		||||
        },
 | 
			
		||||
        Activation: { $date: { $numberLong: weekStart.toString() } },
 | 
			
		||||
        Expiry: { $date: { $numberLong: weekEnd.toString() } },
 | 
			
		||||
        Reward: "/Lotus/Types/Game/MissionDecks/ArchonSortieRewards",
 | 
			
		||||
        Seed: week,
 | 
			
		||||
        Boss: boss,
 | 
			
		||||
        Missions: [
 | 
			
		||||
            {
 | 
			
		||||
                missionType: rng.randomElement([
 | 
			
		||||
                    "MT_INTEL",
 | 
			
		||||
                    "MT_MOBILE_DEFENSE",
 | 
			
		||||
                    "MT_EXTERMINATION",
 | 
			
		||||
                    "MT_SABOTAGE",
 | 
			
		||||
                    "MT_RESCUE"
 | 
			
		||||
                ]),
 | 
			
		||||
                node: firstNode
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                missionType: rng.randomElement([
 | 
			
		||||
                    "MT_DEFENSE",
 | 
			
		||||
                    "MT_TERRITORY",
 | 
			
		||||
                    "MT_ARTIFACT",
 | 
			
		||||
                    "MT_EXCAVATE",
 | 
			
		||||
                    "MT_SURVIVAL"
 | 
			
		||||
                ]),
 | 
			
		||||
                node: rng.randomElement(nodes)
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                missionType: "MT_ASSASSINATION",
 | 
			
		||||
                node: showdownNode
 | 
			
		||||
            }
 | 
			
		||||
        ]
 | 
			
		||||
    };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@ -103,7 +103,7 @@ export interface ILiteSortie {
 | 
			
		||||
    Expiry: IMongoDate;
 | 
			
		||||
    Reward: "/Lotus/Types/Game/MissionDecks/ArchonSortieRewards";
 | 
			
		||||
    Seed: number;
 | 
			
		||||
    Boss: string; // "SORTIE_BOSS_AMAR" | "SORTIE_BOSS_NIRA" | "SORTIE_BOSS_BOREAL"
 | 
			
		||||
    Boss: "SORTIE_BOSS_AMAR" | "SORTIE_BOSS_NIRA" | "SORTIE_BOSS_BOREAL";
 | 
			
		||||
    Missions: {
 | 
			
		||||
        missionType: string;
 | 
			
		||||
        node: string;
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user