forked from OpenWF/SpaceNinjaServer
		
	feat: tactical alerts (#2607)
Includes all `Tactical Alerts` since Star Chart 3.0 with exception: `Snowday Showdown` `Wolf Hunt (2019)` (couldn't find corresponded `EventNode` for that) `Void Corruption` (that's goes into `Alerts`) All `Warframe's Anniversary` Re #1103 Co-authored-by: Sainan <63328889+Sainan@users.noreply.github.com> Reviewed-on: OpenWF/SpaceNinjaServer#2607 Reviewed-by: Sainan <63328889+sainan@users.noreply.github.com> Co-authored-by: AMelonInsideLemon <166175391+AMelonInsideLemon@users.noreply.github.com> Co-committed-by: AMelonInsideLemon <166175391+AMelonInsideLemon@users.noreply.github.com>
This commit is contained in:
		
							parent
							
								
									9cc0c76ef5
								
							
						
					
					
						commit
						fd2ec696a0
					
				@ -71,10 +71,19 @@
 | 
			
		||||
    "affinityBoost": false,
 | 
			
		||||
    "resourceBoost": false,
 | 
			
		||||
    "tennoLiveRelay": false,
 | 
			
		||||
    "wolfHunt": false,
 | 
			
		||||
    "longShadow": false,
 | 
			
		||||
    "hallowedFlame": false,
 | 
			
		||||
    "hallowedNightmares": false,
 | 
			
		||||
    "hallowedNightmaresRewardsOverride": 0,
 | 
			
		||||
    "proxyRebellion": false,
 | 
			
		||||
    "proxyRebellionRewardsOverride": 0,
 | 
			
		||||
    "galleonOfGhouls": 0,
 | 
			
		||||
    "ghoulEmergenceOverride": null,
 | 
			
		||||
    "plagueStarOverride": null,
 | 
			
		||||
    "starDaysOverride": null,
 | 
			
		||||
    "dogDaysOverride": null,
 | 
			
		||||
    "dogDaysRewardsOverride": null,
 | 
			
		||||
    "eidolonOverride": "",
 | 
			
		||||
    "vallisOverride": "",
 | 
			
		||||
    "duviriOverride": "",
 | 
			
		||||
 | 
			
		||||
@ -13,7 +13,8 @@ import {
 | 
			
		||||
    addItems,
 | 
			
		||||
    combineInventoryChanges,
 | 
			
		||||
    getEffectiveAvatarImageType,
 | 
			
		||||
    getInventory
 | 
			
		||||
    getInventory,
 | 
			
		||||
    updateCurrency
 | 
			
		||||
} from "@/src/services/inventoryService";
 | 
			
		||||
import { logger } from "@/src/utils/logger";
 | 
			
		||||
import { ExportFlavour } from "warframe-public-export-plus";
 | 
			
		||||
@ -100,6 +101,9 @@ export const inboxController: RequestHandler = async (req, res) => {
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        if (message.RegularCredits) {
 | 
			
		||||
            updateCurrency(inventory, -message.RegularCredits, false, inventoryChanges);
 | 
			
		||||
        }
 | 
			
		||||
        await inventory.save();
 | 
			
		||||
        res.json({ InventoryChanges: inventoryChanges });
 | 
			
		||||
    } else if (latestClientMessageId) {
 | 
			
		||||
 | 
			
		||||
@ -47,6 +47,7 @@ export interface IMessage {
 | 
			
		||||
    acceptAction?: string;
 | 
			
		||||
    declineAction?: string;
 | 
			
		||||
    hasAccountAction?: boolean;
 | 
			
		||||
    RegularCredits?: number;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface Arg {
 | 
			
		||||
@ -139,7 +140,8 @@ const messageSchema = new Schema<IMessageDatabase>(
 | 
			
		||||
        contextInfo: String,
 | 
			
		||||
        acceptAction: String,
 | 
			
		||||
        declineAction: String,
 | 
			
		||||
        hasAccountAction: Boolean
 | 
			
		||||
        hasAccountAction: Boolean,
 | 
			
		||||
        RegularCredits: Number
 | 
			
		||||
    },
 | 
			
		||||
    { id: false }
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
@ -83,10 +83,19 @@ export interface IConfig {
 | 
			
		||||
        resourceBoost?: boolean;
 | 
			
		||||
        tennoLiveRelay?: boolean;
 | 
			
		||||
        baroTennoConRelay?: boolean;
 | 
			
		||||
        wolfHunt?: boolean;
 | 
			
		||||
        longShadow?: boolean;
 | 
			
		||||
        hallowedFlame?: boolean;
 | 
			
		||||
        hallowedNightmares?: boolean;
 | 
			
		||||
        hallowedNightmaresRewardsOverride?: number;
 | 
			
		||||
        proxyRebellion?: boolean;
 | 
			
		||||
        proxyRebellionRewardsOverride?: number;
 | 
			
		||||
        galleonOfGhouls?: number;
 | 
			
		||||
        ghoulEmergenceOverride?: boolean;
 | 
			
		||||
        plagueStarOverride?: boolean;
 | 
			
		||||
        starDaysOverride?: boolean;
 | 
			
		||||
        dogDaysOverride?: boolean;
 | 
			
		||||
        dogDaysRewardsOverride?: number;
 | 
			
		||||
        eidolonOverride?: string;
 | 
			
		||||
        vallisOverride?: string;
 | 
			
		||||
        duviriOverride?: string;
 | 
			
		||||
 | 
			
		||||
@ -50,7 +50,7 @@ import { getEntriesUnsafe } from "@/src/utils/ts-utils";
 | 
			
		||||
import { handleStoreItemAcquisition } from "@/src/services/purchaseService";
 | 
			
		||||
import { IMissionCredits, IMissionReward } from "@/src/types/missionTypes";
 | 
			
		||||
import { crackRelic } from "@/src/helpers/relicHelper";
 | 
			
		||||
import { createMessage } from "@/src/services/inboxService";
 | 
			
		||||
import { createMessage, IMessageCreationTemplate } from "@/src/services/inboxService";
 | 
			
		||||
import kuriaMessage50 from "@/static/fixed_responses/kuriaMessages/fiftyPercent.json";
 | 
			
		||||
import kuriaMessage75 from "@/static/fixed_responses/kuriaMessages/seventyFivePercent.json";
 | 
			
		||||
import kuriaMessage100 from "@/static/fixed_responses/kuriaMessages/oneHundredPercent.json";
 | 
			
		||||
@ -624,36 +624,92 @@ export const addMissionInventoryUpdates = async (
 | 
			
		||||
                    if (goal && goal.Personal) {
 | 
			
		||||
                        inventory.PersonalGoalProgress ??= [];
 | 
			
		||||
                        const goalProgress = inventory.PersonalGoalProgress.find(x => x.goalId.equals(goal._id.$oid));
 | 
			
		||||
                        if (goalProgress) {
 | 
			
		||||
                            goalProgress.Best = Math.max(goalProgress.Best, uploadProgress.Best);
 | 
			
		||||
                            goalProgress.Count += uploadProgress.Count;
 | 
			
		||||
                        } else {
 | 
			
		||||
                        if (!goalProgress) {
 | 
			
		||||
                            inventory.PersonalGoalProgress.push({
 | 
			
		||||
                                Best: uploadProgress.Best,
 | 
			
		||||
                                Count: uploadProgress.Count,
 | 
			
		||||
                                Tag: goal.Tag,
 | 
			
		||||
                                goalId: new Types.ObjectId(goal._id.$oid)
 | 
			
		||||
                            });
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        const currentNode = inventoryUpdates.RewardInfo!.node;
 | 
			
		||||
                        let currentMissionKey;
 | 
			
		||||
                        if (currentNode == goal.Node) {
 | 
			
		||||
                            currentMissionKey = goal.MissionKeyName;
 | 
			
		||||
                        } else if (goal.ConcurrentNodes && goal.ConcurrentMissionKeyNames) {
 | 
			
		||||
                            for (let i = 0; i < goal.ConcurrentNodes.length; i++) {
 | 
			
		||||
                                if (currentNode == goal.ConcurrentNodes[i]) {
 | 
			
		||||
                                    currentMissionKey = goal.ConcurrentMissionKeyNames[i];
 | 
			
		||||
                                    break;
 | 
			
		||||
                                }
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                        if (currentMissionKey && currentMissionKey in goalMessagesByKey) {
 | 
			
		||||
                            const totalCount = (goalProgress?.Count ?? 0) + uploadProgress.Count;
 | 
			
		||||
                            let reward;
 | 
			
		||||
 | 
			
		||||
                            if (goal.InterimGoals && goal.InterimRewards) {
 | 
			
		||||
                                for (let i = 0; i < goal.InterimGoals.length; i++) {
 | 
			
		||||
                                    if (
 | 
			
		||||
                                goal.Reward &&
 | 
			
		||||
                                goal.Reward.items &&
 | 
			
		||||
                                goal.MissionKeyName &&
 | 
			
		||||
                                goal.MissionKeyName in goalMessagesByKey
 | 
			
		||||
                                        goal.InterimGoals[i] &&
 | 
			
		||||
                                        goal.InterimGoals[i] <= totalCount &&
 | 
			
		||||
                                        (!goalProgress || goalProgress.Count < goal.InterimGoals[i]) &&
 | 
			
		||||
                                        goal.InterimRewards[i]
 | 
			
		||||
                                    ) {
 | 
			
		||||
                                        reward = goal.InterimRewards[i];
 | 
			
		||||
                                        break;
 | 
			
		||||
                                    }
 | 
			
		||||
                                }
 | 
			
		||||
                            }
 | 
			
		||||
                            if (
 | 
			
		||||
                                !reward &&
 | 
			
		||||
                                goal.Goal &&
 | 
			
		||||
                                goal.Goal <= totalCount &&
 | 
			
		||||
                                (!goalProgress || goalProgress.Count < goal.Goal) &&
 | 
			
		||||
                                goal.Reward
 | 
			
		||||
                            ) {
 | 
			
		||||
                                reward = goal.Reward;
 | 
			
		||||
                            }
 | 
			
		||||
                            if (
 | 
			
		||||
                                !reward &&
 | 
			
		||||
                                goal.BonusGoal &&
 | 
			
		||||
                                goal.BonusGoal <= totalCount &&
 | 
			
		||||
                                (!goalProgress || goalProgress.Count < goal.BonusGoal) &&
 | 
			
		||||
                                goal.BonusReward
 | 
			
		||||
                            ) {
 | 
			
		||||
                                reward = goal.BonusReward;
 | 
			
		||||
                            }
 | 
			
		||||
                            if (reward) {
 | 
			
		||||
                                if (currentMissionKey in goalMessagesByKey) {
 | 
			
		||||
                                    // Send reward via inbox
 | 
			
		||||
                                const info = goalMessagesByKey[goal.MissionKeyName];
 | 
			
		||||
                                await createMessage(inventory.accountOwnerId, [
 | 
			
		||||
                                    {
 | 
			
		||||
                                    const info = goalMessagesByKey[currentMissionKey];
 | 
			
		||||
                                    const message: IMessageCreationTemplate = {
 | 
			
		||||
                                        sndr: info.sndr,
 | 
			
		||||
                                        msg: info.msg,
 | 
			
		||||
                                        att: goal.Reward.items.map(x => (isStoreItem(x) ? fromStoreItem(x) : x)),
 | 
			
		||||
                                        sub: info.sub,
 | 
			
		||||
                                        icon: info.icon,
 | 
			
		||||
                                        highPriority: true
 | 
			
		||||
                                    };
 | 
			
		||||
 | 
			
		||||
                                    if (reward.items) {
 | 
			
		||||
                                        message.att = reward.items.map(x => (isStoreItem(x) ? fromStoreItem(x) : x));
 | 
			
		||||
                                    }
 | 
			
		||||
                                ]);
 | 
			
		||||
                                    if (reward.countedItems) {
 | 
			
		||||
                                        message.countedAtt = reward.countedItems;
 | 
			
		||||
                                    }
 | 
			
		||||
                                    if (reward.credits) {
 | 
			
		||||
                                        message.RegularCredits = reward.credits;
 | 
			
		||||
                                    }
 | 
			
		||||
 | 
			
		||||
                                    await createMessage(inventory.accountOwnerId, [message]);
 | 
			
		||||
                                }
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        if (goalProgress) {
 | 
			
		||||
                            goalProgress.Best = Math.max(goalProgress.Best, uploadProgress.Best);
 | 
			
		||||
                            goalProgress.Count += uploadProgress.Count;
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
@ -1011,8 +1067,16 @@ export const addMissionRewards = async (
 | 
			
		||||
 | 
			
		||||
    if (rewardInfo.goalId) {
 | 
			
		||||
        const goal = getWorldState().Goals.find(x => x._id.$oid == rewardInfo.goalId);
 | 
			
		||||
        if (goal?.MissionKeyName) {
 | 
			
		||||
            levelKeyName = goal.MissionKeyName;
 | 
			
		||||
        if (goal) {
 | 
			
		||||
            if (rewardInfo.node == goal.Node && goal.MissionKeyName) levelKeyName = goal.MissionKeyName;
 | 
			
		||||
            if (goal.ConcurrentNodes && goal.ConcurrentMissionKeyNames) {
 | 
			
		||||
                for (let i = 0; i < goal.ConcurrentNodes.length && i < goal.ConcurrentMissionKeyNames.length; i++) {
 | 
			
		||||
                    if (rewardInfo.node == goal.ConcurrentNodes[i]) {
 | 
			
		||||
                        levelKeyName = goal.ConcurrentMissionKeyNames[i];
 | 
			
		||||
                        break;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -2149,5 +2213,143 @@ const goalMessagesByKey: Record<string, { sndr: string; msg: string; sub: string
 | 
			
		||||
        msg: "/Lotus/Language/Messages/GalleonRobbery2025RewardMsgC",
 | 
			
		||||
        sub: "/Lotus/Language/Messages/GalleonRobbery2025MissionTitleC",
 | 
			
		||||
        icon: "/Lotus/Interface/Icons/Npcs/VayHekPortrait.png"
 | 
			
		||||
    },
 | 
			
		||||
    "/Lotus/Types/Keys/TacAlertKeyWaterFightA": {
 | 
			
		||||
        sndr: "/Lotus/Language/Bosses/BossKelaDeThaym",
 | 
			
		||||
        msg: "/Lotus/Language/Inbox/WaterFightRewardMsgA",
 | 
			
		||||
        sub: "/Lotus/Language/Inbox/WaterFightRewardSubjectA",
 | 
			
		||||
        icon: "/Lotus/Interface/Icons/Npcs/Grineer/KelaDeThaym.png"
 | 
			
		||||
    },
 | 
			
		||||
    "/Lotus/Types/Keys/TacAlertKeyWaterFightB": {
 | 
			
		||||
        sndr: "/Lotus/Language/Bosses/BossKelaDeThaym",
 | 
			
		||||
        msg: "/Lotus/Language/Inbox/WaterFightRewardMsgB",
 | 
			
		||||
        sub: "/Lotus/Language/Inbox/WaterFightRewardSubjectB",
 | 
			
		||||
        icon: "/Lotus/Interface/Icons/Npcs/Grineer/KelaDeThaym.png"
 | 
			
		||||
    },
 | 
			
		||||
    "/Lotus/Types/Keys/TacAlertKeyWaterFightC": {
 | 
			
		||||
        sndr: "/Lotus/Language/Bosses/BossKelaDeThaym",
 | 
			
		||||
        msg: "/Lotus/Language/Inbox/WaterFightRewardMsgC",
 | 
			
		||||
        sub: "/Lotus/Language/Inbox/WaterFightRewardSubjectC",
 | 
			
		||||
        icon: "/Lotus/Interface/Icons/Npcs/Grineer/KelaDeThaym.png"
 | 
			
		||||
    },
 | 
			
		||||
    "/Lotus/Types/Keys/TacAlertKeyWaterFightD": {
 | 
			
		||||
        sndr: "/Lotus/Language/Bosses/BossKelaDeThaym",
 | 
			
		||||
        msg: "/Lotus/Language/Inbox/WaterFightRewardMsgD",
 | 
			
		||||
        sub: "/Lotus/Language/Inbox/WaterFightRewardSubjectD",
 | 
			
		||||
        icon: "/Lotus/Interface/Icons/Npcs/Grineer/KelaDeThaym.png"
 | 
			
		||||
    },
 | 
			
		||||
    "/Lotus/Types/Keys/WolfTacAlertReduxA": {
 | 
			
		||||
        sndr: "/Lotus/Language/Bosses/NoraNight",
 | 
			
		||||
        msg: "/Lotus/Language/Inbox/WolfTacAlertBody",
 | 
			
		||||
        sub: "/Lotus/Language/Inbox/WolfTacAlertTitle",
 | 
			
		||||
        icon: "/Lotus/Interface/Icons/Npcs/Seasonal/NoraNight.png"
 | 
			
		||||
    },
 | 
			
		||||
    "/Lotus/Types/Keys/WolfTacAlertReduxB": {
 | 
			
		||||
        sndr: "/Lotus/Language/Bosses/NoraNight",
 | 
			
		||||
        msg: "/Lotus/Language/Inbox/WolfTacAlertBody",
 | 
			
		||||
        sub: "/Lotus/Language/Inbox/WolfTacAlertTitle",
 | 
			
		||||
        icon: "/Lotus/Interface/Icons/Npcs/Seasonal/NoraNight.png"
 | 
			
		||||
    },
 | 
			
		||||
    "/Lotus/Types/Keys/WolfTacAlertReduxD": {
 | 
			
		||||
        sndr: "/Lotus/Language/Bosses/NoraNight",
 | 
			
		||||
        msg: "/Lotus/Language/Inbox/WolfTacAlertBody",
 | 
			
		||||
        sub: "/Lotus/Language/Inbox/WolfTacAlertTitle",
 | 
			
		||||
        icon: "/Lotus/Interface/Icons/Npcs/Seasonal/NoraNight.png"
 | 
			
		||||
    },
 | 
			
		||||
    "/Lotus/Types/Keys/WolfTacAlertReduxC": {
 | 
			
		||||
        sndr: "/Lotus/Language/Bosses/NoraNight",
 | 
			
		||||
        msg: "/Lotus/Language/Inbox/WolfTacAlertBody",
 | 
			
		||||
        sub: "/Lotus/Language/Inbox/WolfTacAlertTitle",
 | 
			
		||||
        icon: "/Lotus/Interface/Icons/Npcs/Seasonal/NoraNight.png"
 | 
			
		||||
    },
 | 
			
		||||
    "/Lotus/Types/Keys/LanternEndlessEventKeyA": {
 | 
			
		||||
        sndr: "/Lotus/Language/Bosses/Lotus",
 | 
			
		||||
        msg: "/Lotus/Language/G1Quests/GenericEventRewardMsgDesc",
 | 
			
		||||
        sub: "/Lotus/Language/G1Quests/GenericTacAlertRewardMsgTitle",
 | 
			
		||||
        icon: "/Lotus/Interface/Icons/Npcs/LotusVamp_d.png"
 | 
			
		||||
    },
 | 
			
		||||
    "/Lotus/Types/Keys/LanternEndlessEventKeyB": {
 | 
			
		||||
        sndr: "/Lotus/Language/Bosses/Lotus",
 | 
			
		||||
        msg: "/Lotus/Language/G1Quests/GenericEventRewardMsgDesc",
 | 
			
		||||
        sub: "/Lotus/Language/G1Quests/GenericTacAlertRewardMsgTitle",
 | 
			
		||||
        icon: "/Lotus/Interface/Icons/Npcs/LotusVamp_d.png"
 | 
			
		||||
    },
 | 
			
		||||
    "/Lotus/Types/Keys/LanternEndlessEventKeyD": {
 | 
			
		||||
        sndr: "/Lotus/Language/Bosses/Lotus",
 | 
			
		||||
        msg: "/Lotus/Language/G1Quests/GenericEventRewardMsgDesc",
 | 
			
		||||
        sub: "/Lotus/Language/G1Quests/GenericTacAlertRewardMsgTitle",
 | 
			
		||||
        icon: "/Lotus/Interface/Icons/Npcs/LotusVamp_d.png"
 | 
			
		||||
    },
 | 
			
		||||
    "/Lotus/Types/Keys/LanternEndlessEventKeyC": {
 | 
			
		||||
        sndr: "/Lotus/Language/Bosses/Lotus",
 | 
			
		||||
        msg: "/Lotus/Language/G1Quests/GenericEventRewardMsgDesc",
 | 
			
		||||
        sub: "/Lotus/Language/G1Quests/GenericTacAlertRewardMsgTitle",
 | 
			
		||||
        icon: "/Lotus/Interface/Icons/Npcs/LotusVamp_d.png"
 | 
			
		||||
    },
 | 
			
		||||
    "/Lotus/Types/Keys/TacAlertKeyHalloween": {
 | 
			
		||||
        sndr: "/Lotus/Language/Bosses/Lotus",
 | 
			
		||||
        msg: "/Lotus/Language/G1Quests/TacAlertHalloweenRewardsBonusBody",
 | 
			
		||||
        sub: "/Lotus/Language/G1Quests/TacAlertHalloweenRewardsBonusTitle",
 | 
			
		||||
        icon: "/Lotus/Interface/Icons/Npcs/LotusVamp_d.png"
 | 
			
		||||
    },
 | 
			
		||||
    "/Lotus/Types/Keys/TacAlertKeyHalloweenBonus": {
 | 
			
		||||
        sndr: "/Lotus/Language/Bosses/Lotus",
 | 
			
		||||
        msg: "/Lotus/Language/G1Quests/TacAlertHalloweenRewardsBody",
 | 
			
		||||
        sub: "/Lotus/Language/G1Quests/TacAlertHalloweenRewardsTitle",
 | 
			
		||||
        icon: "/Lotus/Interface/Icons/Npcs/LotusVamp_d.png"
 | 
			
		||||
    },
 | 
			
		||||
    "/Lotus/Types/Keys/TacAlertKeyHalloweenTimeAttack": {
 | 
			
		||||
        sndr: "/Lotus/Language/Bosses/Lotus",
 | 
			
		||||
        msg: "/Lotus/Language/G1Quests/TacAlertHalloweenRewardsBody",
 | 
			
		||||
        sub: "/Lotus/Language/G1Quests/TacAlertHalloweenRewardsTitle",
 | 
			
		||||
        icon: "/Lotus/Interface/Icons/Npcs/LotusVamp_d.png"
 | 
			
		||||
    },
 | 
			
		||||
    "/Lotus/Types/Keys/TacAlertKeyProxyRebellionOne": {
 | 
			
		||||
        sndr: "/Lotus/Language/Bosses/Lotus",
 | 
			
		||||
        msg: "/Lotus/Language/G1Quests/RazorbackArmadaRewardBody",
 | 
			
		||||
        sub: "/Lotus/Language/G1Quests/GenericTacAlertSmallRewardMsgTitle",
 | 
			
		||||
        icon: "/Lotus/Interface/Icons/Npcs/Lotus_d.png"
 | 
			
		||||
    },
 | 
			
		||||
    "/Lotus/Types/Keys/TacAlertKeyProxyRebellionTwo": {
 | 
			
		||||
        sndr: "/Lotus/Language/Bosses/Lotus",
 | 
			
		||||
        msg: "/Lotus/Language/G1Quests/RazorbackArmadaRewardBody",
 | 
			
		||||
        sub: "/Lotus/Language/G1Quests/GenericTacAlertSmallRewardMsgTitle",
 | 
			
		||||
        icon: "/Lotus/Interface/Icons/Npcs/Lotus_d.png"
 | 
			
		||||
    },
 | 
			
		||||
    "/Lotus/Types/Keys/TacAlertKeyProxyRebellionThree": {
 | 
			
		||||
        sndr: "/Lotus/Language/Bosses/Lotus",
 | 
			
		||||
        msg: "/Lotus/Language/G1Quests/RazorbackArmadaRewardBody",
 | 
			
		||||
        sub: "/Lotus/Language/G1Quests/GenericTacAlertSmallRewardMsgTitle",
 | 
			
		||||
        icon: "/Lotus/Interface/Icons/Npcs/Lotus_d.png"
 | 
			
		||||
    },
 | 
			
		||||
    "/Lotus/Types/Keys/TacAlertKeyProxyRebellionFour": {
 | 
			
		||||
        sndr: "/Lotus/Language/Bosses/Lotus",
 | 
			
		||||
        msg: "/Lotus/Language/G1Quests/GenericTacAlertBadgeRewardMsgDesc",
 | 
			
		||||
        sub: "/Lotus/Language/G1Quests/GenericTacAlertBadgeRewardMsgTitle",
 | 
			
		||||
        icon: "/Lotus/Interface/Icons/Npcs/Lotus_d.png"
 | 
			
		||||
    },
 | 
			
		||||
    "/Lotus/Types/Keys/TacAlertKeyProjectNightwatchEasy": {
 | 
			
		||||
        sndr: "/Lotus/Language/Bosses/Lotus",
 | 
			
		||||
        msg: "/Lotus/Language/G1Quests/ProjectNightwatchRewardMsgA",
 | 
			
		||||
        sub: "/Lotus/Language/G1Quests/ProjectNightwatchTacAlertMissionOneTitle",
 | 
			
		||||
        icon: "/Lotus/Interface/Icons/Npcs/Lotus_d.png"
 | 
			
		||||
    },
 | 
			
		||||
    "/Lotus/Types/Keys/TacAlertKeyProjectNightwatch": {
 | 
			
		||||
        sndr: "/Lotus/Language/Bosses/Lotus",
 | 
			
		||||
        msg: "/Lotus/Language/G1Quests/ProjectNightwatchTacAlertMissionRewardBody",
 | 
			
		||||
        sub: "/Lotus/Language/G1Quests/ProjectNightwatchTacAlertMissionTwoTitle",
 | 
			
		||||
        icon: "/Lotus/Interface/Icons/Npcs/Lotus_d.png"
 | 
			
		||||
    },
 | 
			
		||||
    "/Lotus/Types/Keys/TacAlertKeyProjectNightwatchHard": {
 | 
			
		||||
        sndr: "/Lotus/Language/Bosses/Lotus",
 | 
			
		||||
        msg: "/Lotus/Language/G1Quests/ProjectNightwatchTacAlertMissionRewardBody",
 | 
			
		||||
        sub: "/Lotus/Language/G1Quests/ProjectNightwatchTacAlertMissionThreeTitle",
 | 
			
		||||
        icon: "/Lotus/Interface/Icons/Npcs/Lotus_d.png"
 | 
			
		||||
    },
 | 
			
		||||
    "/Lotus/Types/Keys/TacAlertKeyProjectNightwatchBonus": {
 | 
			
		||||
        sndr: "/Lotus/Language/Bosses/Lotus",
 | 
			
		||||
        msg: "/Lotus/Language/G1Quests/ProjectNightwatchTacAlertMissionRewardBody",
 | 
			
		||||
        sub: "/Lotus/Language/G1Quests/ProjectNightwatchTacAlertMissionFourTitle",
 | 
			
		||||
        icon: "/Lotus/Interface/Icons/Npcs/Lotus_d.png"
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@ -1392,6 +1392,7 @@ export const getWorldState = (buildLabel?: string): IWorldState => {
 | 
			
		||||
        Sorties: [],
 | 
			
		||||
        LiteSorties: [],
 | 
			
		||||
        ActiveMissions: [],
 | 
			
		||||
        FlashSales: [],
 | 
			
		||||
        GlobalUpgrades: [],
 | 
			
		||||
        Invasions: [],
 | 
			
		||||
        VoidTraders: [],
 | 
			
		||||
@ -1401,7 +1402,15 @@ export const getWorldState = (buildLabel?: string): IWorldState => {
 | 
			
		||||
        EndlessXpChoices: [],
 | 
			
		||||
        KnownCalendarSeasons: [],
 | 
			
		||||
        ...staticWorldState,
 | 
			
		||||
        SyndicateMissions: [...staticWorldState.SyndicateMissions]
 | 
			
		||||
        SyndicateMissions: [...staticWorldState.SyndicateMissions],
 | 
			
		||||
        InGameMarket: {
 | 
			
		||||
            LandingPage: {
 | 
			
		||||
                Categories: staticWorldState.InGameMarket.LandingPage.Categories.map(c => ({
 | 
			
		||||
                    ...c,
 | 
			
		||||
                    Items: [...c.Items]
 | 
			
		||||
                }))
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    // Old versions seem to really get hung up on not being able to load these.
 | 
			
		||||
@ -1526,7 +1535,7 @@ export const getWorldState = (buildLabel?: string): IWorldState => {
 | 
			
		||||
            Personal: true,
 | 
			
		||||
            Bounty: true,
 | 
			
		||||
            ClampNodeScores: true,
 | 
			
		||||
            Node: "EventNode28",
 | 
			
		||||
            Node: "EventNode28", // Incompatible with Wolf Hunt (2025)
 | 
			
		||||
            MissionKeyName: "/Lotus/Types/Keys/GalleonRobberyAlertB",
 | 
			
		||||
            Desc: "/Lotus/Language/Events/GalleonRobberyEventMissionTitle",
 | 
			
		||||
            Icon: "/Lotus/Interface/Icons/Player/GalleonRobberiesEvent.png",
 | 
			
		||||
@ -1629,6 +1638,634 @@ export const getWorldState = (buildLabel?: string): IWorldState => {
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const firstAugustWeekday = new Date(Date.UTC(date.getUTCFullYear(), 7, 1)).getUTCDay();
 | 
			
		||||
    const firstAugustWednesdayOffset = (3 - firstAugustWeekday + 7) % 7;
 | 
			
		||||
    const dogDaysStart = Date.UTC(date.getUTCFullYear(), 7, 1 + firstAugustWednesdayOffset, 15);
 | 
			
		||||
 | 
			
		||||
    const firstSeptemberWeekday = new Date(Date.UTC(date.getUTCFullYear(), 8, 1)).getUTCDay();
 | 
			
		||||
    const firstSeptemberWednesdayOffset = (3 - firstSeptemberWeekday + 7) % 7;
 | 
			
		||||
    const dogDaysEnd = Date.UTC(date.getUTCFullYear(), 8, 1 + firstSeptemberWednesdayOffset, 15);
 | 
			
		||||
 | 
			
		||||
    const isDogDaysActive = timeMs >= dogDaysStart && timeMs < dogDaysEnd;
 | 
			
		||||
    if (config.worldState?.dogDaysOverride ?? isDogDaysActive) {
 | 
			
		||||
        const activationTimeStamp = config.worldState?.dogDaysOverride ? "1699372800000" : dogDaysStart.toString();
 | 
			
		||||
        const expiryTimeStamp = config.worldState?.dogDaysOverride ? "2000000000000" : dogDaysEnd.toString();
 | 
			
		||||
        const rewards = [
 | 
			
		||||
            [
 | 
			
		||||
                {
 | 
			
		||||
                    credits: 50000,
 | 
			
		||||
                    items: ["/Lotus/StoreItems/Upgrades/Skins/Weapons/Redeemer/RedeemerRelayWaterSkin"]
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                    credits: 50000,
 | 
			
		||||
                    items: ["/Lotus/StoreItems/Types/Items/MiscItems/PhotoboothTileHydroidRelay"]
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                    credits: 50000,
 | 
			
		||||
                    items: ["/Lotus/StoreItems/Types/Items/ShipDecos/RelayHydroidBobbleHead"]
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                    items: [
 | 
			
		||||
                        "/Lotus/StoreItems/Types/Items/MiscItems/OrokinReactor",
 | 
			
		||||
                        "/Lotus/StoreItems/Upgrades/Skins/Clan/BountyHunterBadgeItem"
 | 
			
		||||
                    ]
 | 
			
		||||
                }
 | 
			
		||||
            ],
 | 
			
		||||
            [
 | 
			
		||||
                {
 | 
			
		||||
                    credits: 50000,
 | 
			
		||||
                    items: ["/Lotus/StoreItems/Upgrades/Skins/Sigils/DogDays2023ASigil"],
 | 
			
		||||
                    countedItems: [
 | 
			
		||||
                        {
 | 
			
		||||
                            ItemType: "/Lotus/Types/Items/MiscItems/WaterFightBucks",
 | 
			
		||||
                            ItemCount: 25
 | 
			
		||||
                        }
 | 
			
		||||
                    ]
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                    credits: 50000,
 | 
			
		||||
                    items: ["/Lotus/StoreItems/Types/Items/ShipDecos/Plushies/PlushyBeachKavat"],
 | 
			
		||||
                    countedItems: [
 | 
			
		||||
                        {
 | 
			
		||||
                            ItemType: "/Lotus/Types/Items/MiscItems/WaterFightBucks",
 | 
			
		||||
                            ItemCount: 50
 | 
			
		||||
                        }
 | 
			
		||||
                    ]
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                    credits: 50000,
 | 
			
		||||
                    items: ["/Lotus/StoreItems/Types/Items/ShipDecos/Plushies/PlushyRucksackKubrow"],
 | 
			
		||||
                    countedItems: [
 | 
			
		||||
                        {
 | 
			
		||||
                            ItemType: "/Lotus/Types/Items/MiscItems/WaterFightBucks",
 | 
			
		||||
                            ItemCount: 75
 | 
			
		||||
                        }
 | 
			
		||||
                    ]
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                    items: ["/Lotus/StoreItems/Types/Items/ShipDecos/LisetPropCleaningDroneBeachcomber"],
 | 
			
		||||
                    countedItems: [
 | 
			
		||||
                        {
 | 
			
		||||
                            ItemType: "/Lotus/Types/Items/MiscItems/WaterFightBucks",
 | 
			
		||||
                            ItemCount: 100
 | 
			
		||||
                        }
 | 
			
		||||
                    ]
 | 
			
		||||
                }
 | 
			
		||||
            ],
 | 
			
		||||
            [
 | 
			
		||||
                {
 | 
			
		||||
                    credits: 50000,
 | 
			
		||||
                    items: ["/Lotus/StoreItems/Types/StoreItems/AvatarImages/Seasonal/AvatarImageDogDays2024Glyph"],
 | 
			
		||||
                    countedItems: [
 | 
			
		||||
                        {
 | 
			
		||||
                            ItemType: "/Lotus/Types/Items/MiscItems/WaterFightBucks",
 | 
			
		||||
                            ItemCount: 25
 | 
			
		||||
                        }
 | 
			
		||||
                    ]
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                    credits: 50000,
 | 
			
		||||
                    items: ["/Lotus/StoreItems/Types/Items/ShipDecos/DogDays2024Poster"],
 | 
			
		||||
                    countedItems: [
 | 
			
		||||
                        {
 | 
			
		||||
                            ItemType: "/Lotus/Types/Items/MiscItems/WaterFightBucks",
 | 
			
		||||
                            ItemCount: 50
 | 
			
		||||
                        }
 | 
			
		||||
                    ]
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                    credits: 50000,
 | 
			
		||||
                    items: ["/Lotus/StoreItems/Upgrades/Skins/Clan/DogDaysKubrowBadgeItem"],
 | 
			
		||||
                    countedItems: [
 | 
			
		||||
                        {
 | 
			
		||||
                            ItemType: "/Lotus/Types/Items/MiscItems/WaterFightBucks",
 | 
			
		||||
                            ItemCount: 75
 | 
			
		||||
                        }
 | 
			
		||||
                    ]
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                    items: ["/Lotus/StoreItems/Types/Items/ShipDecos/DogDays2024LisetPropCleaningDroneBeachcomber"],
 | 
			
		||||
                    countedItems: [
 | 
			
		||||
                        {
 | 
			
		||||
                            ItemType: "/Lotus/Types/Items/MiscItems/WaterFightBucks",
 | 
			
		||||
                            ItemCount: 100
 | 
			
		||||
                        }
 | 
			
		||||
                    ]
 | 
			
		||||
                }
 | 
			
		||||
            ],
 | 
			
		||||
            [
 | 
			
		||||
                {
 | 
			
		||||
                    credits: 50000,
 | 
			
		||||
                    items: ["/Lotus/StoreItems/Types/StoreItems/AvatarImages/AvatarImageDogDaysHydroidGlyph"],
 | 
			
		||||
                    countedItems: [
 | 
			
		||||
                        {
 | 
			
		||||
                            ItemType: "/Lotus/Types/Items/MiscItems/WaterFightBucks",
 | 
			
		||||
                            ItemCount: 25
 | 
			
		||||
                        }
 | 
			
		||||
                    ]
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                    credits: 50000,
 | 
			
		||||
                    items: ["/Lotus/StoreItems/Types/StoreItems/AvatarImages/AvatarImageDogDaysLokiGlyph"],
 | 
			
		||||
                    countedItems: [
 | 
			
		||||
                        {
 | 
			
		||||
                            ItemType: "/Lotus/Types/Items/MiscItems/WaterFightBucks",
 | 
			
		||||
                            ItemCount: 50
 | 
			
		||||
                        }
 | 
			
		||||
                    ]
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                    credits: 50000,
 | 
			
		||||
                    items: ["/Lotus/StoreItems/Types/StoreItems/AvatarImages/AvatarImageDogDaysNovaGlyph"],
 | 
			
		||||
                    countedItems: [
 | 
			
		||||
                        {
 | 
			
		||||
                            ItemType: "/Lotus/Types/Items/MiscItems/WaterFightBucks",
 | 
			
		||||
                            ItemCount: 75
 | 
			
		||||
                        }
 | 
			
		||||
                    ]
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                    credits: 50000,
 | 
			
		||||
                    items: ["/Lotus/StoreItems/Types/StoreItems/AvatarImages/AvatarImageDogDaysValkyrGlyph"],
 | 
			
		||||
                    countedItems: [
 | 
			
		||||
                        {
 | 
			
		||||
                            ItemType: "/Lotus/Types/Items/MiscItems/WaterFightBucks",
 | 
			
		||||
                            ItemCount: 100
 | 
			
		||||
                        }
 | 
			
		||||
                    ]
 | 
			
		||||
                }
 | 
			
		||||
            ]
 | 
			
		||||
        ];
 | 
			
		||||
 | 
			
		||||
        const year = config.worldState?.dogDaysRewardsOverride ?? 3;
 | 
			
		||||
 | 
			
		||||
        worldState.Goals.push({
 | 
			
		||||
            _id: {
 | 
			
		||||
                $oid: ((dogDaysStart / 1000) & 0xffffffff).toString(16).padStart(8, "0") + "c57487c3768936df"
 | 
			
		||||
            },
 | 
			
		||||
            Activation: { $date: { $numberLong: activationTimeStamp } },
 | 
			
		||||
            Expiry: { $date: { $numberLong: expiryTimeStamp } },
 | 
			
		||||
            Count: 0,
 | 
			
		||||
            Goal: 100,
 | 
			
		||||
            InterimGoals: [25, 50],
 | 
			
		||||
            BonusGoal: 200,
 | 
			
		||||
            Success: 0,
 | 
			
		||||
            Personal: true,
 | 
			
		||||
            Bounty: true,
 | 
			
		||||
            ClampNodeScores: true,
 | 
			
		||||
            Node: "EventNode25", // Incompatible with Hallowed Flame, Hallowed Nightmares
 | 
			
		||||
            ConcurrentMissionKeyNames: [
 | 
			
		||||
                "/Lotus/Types/Keys/TacAlertKeyWaterFightB",
 | 
			
		||||
                "/Lotus/Types/Keys/TacAlertKeyWaterFightC",
 | 
			
		||||
                "/Lotus/Types/Keys/TacAlertKeyWaterFightD"
 | 
			
		||||
            ],
 | 
			
		||||
            ConcurrentNodeReqs: [25, 50, 100],
 | 
			
		||||
            ConcurrentNodes: ["EventNode24", "EventNode34", "EventNode35"], // Incompatible with Hallowed Flame, Hallowed Nightmares
 | 
			
		||||
            MissionKeyName: "/Lotus/Types/Keys/TacAlertKeyWaterFightA",
 | 
			
		||||
            Faction: "FC_CORPUS",
 | 
			
		||||
            Desc: "/Lotus/Language/Alerts/TacAlertWaterFight",
 | 
			
		||||
            Icon: "/Lotus/Interface/Icons/StoreIcons/Emblems/SplashEventIcon.png",
 | 
			
		||||
            Tag: "WaterFight",
 | 
			
		||||
            InterimRewards: rewards[year].slice(0, 2),
 | 
			
		||||
            Reward: rewards[year][2],
 | 
			
		||||
            BonusReward: rewards[year][3],
 | 
			
		||||
            ScoreVar: "Team1Score",
 | 
			
		||||
            NightLevel: "/Lotus/Levels/GrineerBeach/GrineerBeachEventNight.level"
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        const baseStoreItem = {
 | 
			
		||||
            ShowInMarket: true,
 | 
			
		||||
            HideFromMarket: false,
 | 
			
		||||
            SupporterPack: false,
 | 
			
		||||
            Discount: 0,
 | 
			
		||||
            BogoBuy: 0,
 | 
			
		||||
            BogoGet: 0,
 | 
			
		||||
            StartDate: { $date: { $numberLong: activationTimeStamp } },
 | 
			
		||||
            EndDate: { $date: { $numberLong: expiryTimeStamp } },
 | 
			
		||||
            ProductExpiryOverride: { $date: { $numberLong: expiryTimeStamp } }
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        const storeItems = [
 | 
			
		||||
            {
 | 
			
		||||
                TypeName: "/Lotus/Types/StoreItems/Packages/WaterFightNoggleBundle",
 | 
			
		||||
                PremiumOverride: 240,
 | 
			
		||||
                RegularOverride: 0
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                TypeName: "/Lotus/Types/Items/ShipDecos/Events/WFBeastMasterBobbleHead",
 | 
			
		||||
                PremiumOverride: 35,
 | 
			
		||||
                RegularOverride: 0
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                TypeName: "/Lotus/Types/Items/ShipDecos/Events/WFChargerBobbleHead",
 | 
			
		||||
                PremiumOverride: 35,
 | 
			
		||||
                RegularOverride: 0
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                TypeName: "/Lotus/Types/Items/ShipDecos/Events/WFEngineerBobbleHead",
 | 
			
		||||
                PremiumOverride: 35,
 | 
			
		||||
                RegularOverride: 0
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                TypeName: "/Lotus/Types/Items/ShipDecos/Events/WFGruntBobbleHead",
 | 
			
		||||
                PremiumOverride: 35,
 | 
			
		||||
                RegularOverride: 0
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                TypeName: "/Lotus/Types/StoreItems/AvatarImages/ImagePopsicleGrineerPurple",
 | 
			
		||||
                PremiumOverride: 0,
 | 
			
		||||
                RegularOverride: 1
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                TypeName: "/Lotus/Types/Items/ShipDecos/Events/WFHealerBobbleHead",
 | 
			
		||||
                PremiumOverride: 35,
 | 
			
		||||
                RegularOverride: 0
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                TypeName: "/Lotus/Types/Items/ShipDecos/Events/WFHeavyBobbleHead",
 | 
			
		||||
                PremiumOverride: 35,
 | 
			
		||||
                RegularOverride: 0
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                TypeName: "/Lotus/Types/Items/ShipDecos/Events/WFHellionBobbleHead",
 | 
			
		||||
                PremiumOverride: 35,
 | 
			
		||||
                RegularOverride: 0
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                TypeName: "/Lotus/Types/Items/ShipDecos/Events/WFSniperBobbleHead",
 | 
			
		||||
                PremiumOverride: 35,
 | 
			
		||||
                RegularOverride: 0
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                TypeName: "/Lotus/Types/Items/ShipDecos/Events/WFTankBobbleHead",
 | 
			
		||||
                PremiumOverride: 35,
 | 
			
		||||
                RegularOverride: 0
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                TypeName: "/Lotus/Types/StoreItems/SuitCustomizations/ColourPickerRollers",
 | 
			
		||||
                PremiumOverride: 75,
 | 
			
		||||
                RegularOverride: 0
 | 
			
		||||
            }
 | 
			
		||||
        ];
 | 
			
		||||
 | 
			
		||||
        worldState.FlashSales.push(...storeItems.map(item => ({ ...baseStoreItem, ...item })));
 | 
			
		||||
 | 
			
		||||
        const seasonalItems = storeItems.map(item => item.TypeName);
 | 
			
		||||
 | 
			
		||||
        const seasonalCategory = worldState.InGameMarket.LandingPage.Categories.find(c => c.CategoryName == "SEASONAL");
 | 
			
		||||
 | 
			
		||||
        if (seasonalCategory) {
 | 
			
		||||
            seasonalCategory.Items ??= [];
 | 
			
		||||
            seasonalCategory.Items.push(...seasonalItems);
 | 
			
		||||
        } else {
 | 
			
		||||
            worldState.InGameMarket.LandingPage.Categories.push({
 | 
			
		||||
                CategoryName: "SEASONAL",
 | 
			
		||||
                Name: "/Lotus/Language/Store/SeasonalCategoryTitle",
 | 
			
		||||
                Icon: "seasonal",
 | 
			
		||||
                AddToMenu: true,
 | 
			
		||||
                Items: seasonalItems
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (config.worldState?.wolfHunt) {
 | 
			
		||||
        worldState.Goals.push({
 | 
			
		||||
            _id: {
 | 
			
		||||
                $oid: "67ed7672798d6466172e3b9d"
 | 
			
		||||
            },
 | 
			
		||||
            Activation: {
 | 
			
		||||
                $date: {
 | 
			
		||||
                    $numberLong: "1743616800000"
 | 
			
		||||
                }
 | 
			
		||||
            },
 | 
			
		||||
            Expiry: {
 | 
			
		||||
                $date: {
 | 
			
		||||
                    $numberLong: "2000000000000"
 | 
			
		||||
                }
 | 
			
		||||
            },
 | 
			
		||||
            Count: 0,
 | 
			
		||||
            Goal: 3,
 | 
			
		||||
            InterimGoals: [1, 2],
 | 
			
		||||
            BonusGoal: 4,
 | 
			
		||||
            Success: 0,
 | 
			
		||||
            Personal: true,
 | 
			
		||||
            Bounty: true,
 | 
			
		||||
            ClampNodeScores: true,
 | 
			
		||||
            Node: "EventNode29",
 | 
			
		||||
            ConcurrentMissionKeyNames: [
 | 
			
		||||
                "/Lotus/Types/Keys/WolfTacAlertReduxB",
 | 
			
		||||
                "/Lotus/Types/Keys/WolfTacAlertReduxC",
 | 
			
		||||
                "/Lotus/Types/Keys/WolfTacAlertReduxD"
 | 
			
		||||
            ],
 | 
			
		||||
            ConcurrentNodeReqs: [1, 2, 3],
 | 
			
		||||
            ConcurrentNodes: ["EventNode28", "EventNode39", "EventNode40"], // Incompatible with Galleon Of Ghouls
 | 
			
		||||
            MissionKeyName: "/Lotus/Types/Keys/WolfTacAlertReduxA",
 | 
			
		||||
            Faction: "FC_GRINEER",
 | 
			
		||||
            Desc: "/Lotus/Language/Alerts/WolfAlert",
 | 
			
		||||
            Icon: "/Lotus/Interface/Icons/Npcs/Seasonal/WolfStalker.png",
 | 
			
		||||
            Tag: "WolfHuntRedux",
 | 
			
		||||
            InterimRewards: [
 | 
			
		||||
                {
 | 
			
		||||
                    credits: 50000,
 | 
			
		||||
                    items: ["/Lotus/StoreItems/Types/Recipes/Weapons/WeaponParts/ThrowingHammerHandle"]
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                    credits: 50000,
 | 
			
		||||
                    items: ["/Lotus/StoreItems/Types/Recipes/Weapons/WeaponParts/ThrowingHammerHead"]
 | 
			
		||||
                }
 | 
			
		||||
            ],
 | 
			
		||||
            Reward: {
 | 
			
		||||
                credits: 50000,
 | 
			
		||||
                items: ["/Lotus/StoreItems/Types/Recipes/Weapons/WeaponParts/ThrowingHammerMotor"]
 | 
			
		||||
            },
 | 
			
		||||
            BonusReward: {
 | 
			
		||||
                credits: 50000,
 | 
			
		||||
                items: [
 | 
			
		||||
                    "/Lotus/StoreItems/Types/Recipes/Weapons/ThrowingHammerBlueprint",
 | 
			
		||||
                    "/Lotus/StoreItems/Types/Items/MiscItems/OrokinCatalyst",
 | 
			
		||||
                    "/Lotus/StoreItems/Upgrades/Skins/Clan/BountyHunterBadgeItem"
 | 
			
		||||
                ]
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (config.worldState?.hallowedFlame) {
 | 
			
		||||
        worldState.Goals.push(
 | 
			
		||||
            {
 | 
			
		||||
                _id: { $oid: "5db305403d34b5158873519a" },
 | 
			
		||||
                Activation: { $date: { $numberLong: "1699372800000" } },
 | 
			
		||||
                Expiry: { $date: { $numberLong: "2000000000000" } },
 | 
			
		||||
                Count: 0,
 | 
			
		||||
                Goal: 3,
 | 
			
		||||
                InterimGoals: [1, 2],
 | 
			
		||||
                Success: 0,
 | 
			
		||||
                Personal: true,
 | 
			
		||||
                Bounty: true,
 | 
			
		||||
                ClampNodeScores: true,
 | 
			
		||||
                Node: "EventNode24", // Incompatible with Hallowed Nightmares, Dog Days
 | 
			
		||||
                ConcurrentMissionKeyNames: [
 | 
			
		||||
                    "/Lotus/Types/Keys/LanternEndlessEventKeyB",
 | 
			
		||||
                    "/Lotus/Types/Keys/LanternEndlessEventKeyC"
 | 
			
		||||
                ],
 | 
			
		||||
                ConcurrentNodeReqs: [1, 2],
 | 
			
		||||
                ConcurrentNodes: ["EventNode25", "EventNode34"], // Incompatible with Hallowed Nightmares, Dog Days
 | 
			
		||||
                MissionKeyName: "/Lotus/Types/Keys/LanternEndlessEventKeyA",
 | 
			
		||||
                Faction: "FC_INFESTATION",
 | 
			
		||||
                Desc: "/Lotus/Language/Events/TacAlertHalloweenLantern",
 | 
			
		||||
                Icon: "/Lotus/Interface/Icons/JackOLanternColour.png",
 | 
			
		||||
                Tag: "Halloween19",
 | 
			
		||||
                InterimRewards: [
 | 
			
		||||
                    { items: ["/Lotus/StoreItems/Types/Items/MiscItems/OrokinCatalyst"] },
 | 
			
		||||
                    { items: ["/Lotus/StoreItems/Types/Items/MiscItems/Forma"] }
 | 
			
		||||
                ],
 | 
			
		||||
                Reward: {
 | 
			
		||||
                    items: ["/Lotus/StoreItems/Types/Items/MiscItems/FormaAura"]
 | 
			
		||||
                }
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                _id: { $oid: "5db3054a3d34b5158873519c" },
 | 
			
		||||
                Activation: { $date: { $numberLong: "1699372800000" } },
 | 
			
		||||
                Expiry: { $date: { $numberLong: "2000000000000" } },
 | 
			
		||||
                Count: 0,
 | 
			
		||||
                Goal: 900,
 | 
			
		||||
                Success: 0,
 | 
			
		||||
                Personal: true,
 | 
			
		||||
                Bounty: true,
 | 
			
		||||
                Best: true,
 | 
			
		||||
                ClampNodeScores: true,
 | 
			
		||||
                Node: "EventNode35",
 | 
			
		||||
                MissionKeyName: "/Lotus/Types/Keys/LanternEndlessEventKeyD",
 | 
			
		||||
                Faction: "FC_INFESTATION",
 | 
			
		||||
                Desc: "/Lotus/Language/Events/TacAlertHalloweenLanternEndless",
 | 
			
		||||
                Icon: "/Lotus/Interface/Icons/JackOLanternColour.png",
 | 
			
		||||
                Tag: "Halloween19Endless",
 | 
			
		||||
                PrereqGoalTags: ["Halloween19"],
 | 
			
		||||
                Reward: {
 | 
			
		||||
                    items: [
 | 
			
		||||
                        "/Lotus/StoreItems/Upgrades/Skins/Effects/BatsEphemera",
 | 
			
		||||
                        "/Lotus/StoreItems/Upgrades/Skins/Clan/BountyHunterBadgeItem"
 | 
			
		||||
                    ]
 | 
			
		||||
                },
 | 
			
		||||
                ScoreVar: "EndlessMissionTimeElapsed",
 | 
			
		||||
                ScoreMaxTag: "Halloween19ScoreMax"
 | 
			
		||||
            }
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (config.worldState?.hallowedNightmares) {
 | 
			
		||||
        const rewards = [
 | 
			
		||||
            // 2018
 | 
			
		||||
            [
 | 
			
		||||
                {
 | 
			
		||||
                    items: ["/Lotus/StoreItems/Upgrades/Skins/Sigils/DotD2016Sigil"]
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                    items: ["/Lotus/StoreItems/Upgrades/Skins/Halloween/HalloweenDread"]
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                    items: ["/Lotus/StoreItems/Types/Items/MiscItems/OrokinReactor"]
 | 
			
		||||
                }
 | 
			
		||||
            ],
 | 
			
		||||
            // 2016
 | 
			
		||||
            [
 | 
			
		||||
                {
 | 
			
		||||
                    items: ["/Lotus/StoreItems/Upgrades/Skins/Sigils/OrokinCatalyst"]
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                    items: ["/Lotus/StoreItems/Upgrades/Skins/Sigils/DotD2016Sigil"]
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                    items: [
 | 
			
		||||
                        "/Lotus/StoreItems/Types/Items/MiscItems/OrokinReactor",
 | 
			
		||||
                        "/Lotus/StoreItems/Upgrades/Skins/Clan/BountyHunterBadgeItem"
 | 
			
		||||
                    ]
 | 
			
		||||
                }
 | 
			
		||||
            ],
 | 
			
		||||
            // 2015
 | 
			
		||||
            [
 | 
			
		||||
                {
 | 
			
		||||
                    items: ["/Lotus/StoreItems/Upgrades/Skins/Sigils/OrokinCatalyst"]
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                    items: ["/Lotus/StoreItems/Upgrades/Skins/Clan/BountyHunterBadgeItem"]
 | 
			
		||||
                }
 | 
			
		||||
            ]
 | 
			
		||||
        ];
 | 
			
		||||
        const year = config.worldState.hallowedNightmaresRewardsOverride ?? 0;
 | 
			
		||||
 | 
			
		||||
        worldState.Goals.push({
 | 
			
		||||
            _id: { $oid: "5bc9e8f7972d7d184c8398c9" },
 | 
			
		||||
            Activation: { $date: { $numberLong: "1539972000000" } },
 | 
			
		||||
            Expiry: { $date: { $numberLong: "2000000000000" } },
 | 
			
		||||
            Count: 0,
 | 
			
		||||
            InterimGoals: [1],
 | 
			
		||||
            Goal: 2,
 | 
			
		||||
            Success: 0,
 | 
			
		||||
            Personal: true,
 | 
			
		||||
            Bounty: true,
 | 
			
		||||
            Tag: "Halloween",
 | 
			
		||||
            Faction: "FC_INFESTATION",
 | 
			
		||||
            Desc: "/Lotus/Language/G1Quests/TacAlertHalloweenTitle",
 | 
			
		||||
            ToolTip: "/Lotus/Language/G1Quests/TacAlertHalloweenToolTip",
 | 
			
		||||
            Icon: "/Lotus/Interface/Icons/JackOLanternColour.png",
 | 
			
		||||
            ClampNodeScores: true,
 | 
			
		||||
            Node: "EventNode2",
 | 
			
		||||
            MissionKeyName: "/Lotus/Types/Keys/TacAlertKeyHalloween",
 | 
			
		||||
            ConcurrentMissionKeyNames: ["/Lotus/Types/Keys/TacAlertKeyHalloweenBonus"],
 | 
			
		||||
            ConcurrentNodeReqs: [1],
 | 
			
		||||
            ConcurrentNodes: ["EventNode24"], // Incompatible with Hallowed Flame, Dog Days
 | 
			
		||||
            InterimRewards: [rewards[year][0]],
 | 
			
		||||
            Reward: rewards[year][1]
 | 
			
		||||
        });
 | 
			
		||||
        if (year != 2) {
 | 
			
		||||
            worldState.Goals.push({
 | 
			
		||||
                _id: { $oid: "5bca18b1e12d9e14a0b6ad27" },
 | 
			
		||||
                Activation: { $date: { $numberLong: "1539972000000" } },
 | 
			
		||||
                Expiry: { $date: { $numberLong: "2000000000000" } },
 | 
			
		||||
                Count: 0,
 | 
			
		||||
                Goal: 666,
 | 
			
		||||
                Success: 0,
 | 
			
		||||
                Personal: true,
 | 
			
		||||
                Bounty: true,
 | 
			
		||||
                Best: true,
 | 
			
		||||
                Tag: "Halloween",
 | 
			
		||||
                PrereqGoalTags: ["Halloween"],
 | 
			
		||||
                Faction: "FC_INFESTATION",
 | 
			
		||||
                Desc: "Hallowed Nightmares - Time Attack",
 | 
			
		||||
                ToolTip: "/Lotus/Language/G1Quests/TacAlertHalloweenToolTip",
 | 
			
		||||
                Icon: "/Lotus/Interface/Icons/JackOLanternColour.png",
 | 
			
		||||
                ClampNodeScores: true,
 | 
			
		||||
                Node: "EventNode25", // Incompatible with Hallowed Flame, Dog Days
 | 
			
		||||
                MissionKeyName: "/Lotus/Types/Keys/TacAlertKeyHalloweenTimeAttack",
 | 
			
		||||
                ScoreVar: "TimeAttackScore",
 | 
			
		||||
                ScoreMaxTag: "Halloween16",
 | 
			
		||||
                Reward: rewards[year][2]
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (config.worldState?.proxyRebellion) {
 | 
			
		||||
        const rewards = [
 | 
			
		||||
            // 2019
 | 
			
		||||
            [
 | 
			
		||||
                {
 | 
			
		||||
                    credits: 50000,
 | 
			
		||||
                    items: ["/Lotus/StoreItems/Types/Items/MiscItems/UtilityUnlocker"]
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                    credits: 50000,
 | 
			
		||||
                    items: ["/Lotus/StoreItems/Upgrades/Mods/Randomized/RawPistolRandomMod"]
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                    credits: 50000,
 | 
			
		||||
                    items: ["/Lotus/Types/StoreItems/Packages/EventCatalystReactorBundle"]
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                    items: [
 | 
			
		||||
                        "/Lotus/StoreItems/Upgrades/Skins/Scarves/HornSkullScarf",
 | 
			
		||||
                        "/Lotus/StoreItems/Upgrades/Skins/Clan/BountyHunterBadgeItem"
 | 
			
		||||
                    ]
 | 
			
		||||
                }
 | 
			
		||||
            ],
 | 
			
		||||
            // 2018
 | 
			
		||||
            [
 | 
			
		||||
                {
 | 
			
		||||
                    credits: 50000,
 | 
			
		||||
                    items: ["/Lotus/StoreItems/Upgrades/Mods/FusionBundles/NightwatchFusionBundle"]
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                    credits: 50000,
 | 
			
		||||
                    items: ["/Lotus/StoreItems/Types/Items/MiscItems/UtilityUnlocker"]
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                    credits: 50000,
 | 
			
		||||
                    items: ["/Lotus/Types/StoreItems/Packages/EventCatalystReactorBundle"]
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                    items: [
 | 
			
		||||
                        "/Lotus/StoreItems/Upgrades/Skins/Sigils/EnergySigilA",
 | 
			
		||||
                        "/Lotus/StoreItems/Upgrades/Skins/Clan/BountyHunterBadgeItem"
 | 
			
		||||
                    ]
 | 
			
		||||
                }
 | 
			
		||||
            ]
 | 
			
		||||
        ];
 | 
			
		||||
        const year = config.worldState.proxyRebellionRewardsOverride ?? 0;
 | 
			
		||||
 | 
			
		||||
        worldState.Goals.push({
 | 
			
		||||
            _id: { $oid: "5b5743ac972d7d3ed0517b0d" },
 | 
			
		||||
            Activation: { $date: { $numberLong: "1532714400000" } },
 | 
			
		||||
            Expiry: { $date: { $numberLong: "2000000000000" } },
 | 
			
		||||
            Count: 0,
 | 
			
		||||
            Goal: 3,
 | 
			
		||||
            InterimGoals: [1, 2],
 | 
			
		||||
            BonusGoal: 4,
 | 
			
		||||
            Success: 0,
 | 
			
		||||
            Personal: true,
 | 
			
		||||
            Bounty: true,
 | 
			
		||||
            ClampNodeScores: true,
 | 
			
		||||
            Node: "EventNode18",
 | 
			
		||||
            ConcurrentMissionKeyNames: [
 | 
			
		||||
                "/Lotus/Types/Keys/TacAlertKeyProxyRebellionTwo",
 | 
			
		||||
                "/Lotus/Types/Keys/TacAlertKeyProxyRebellionThree",
 | 
			
		||||
                "/Lotus/Types/Keys/TacAlertKeyProxyRebellionFour"
 | 
			
		||||
            ],
 | 
			
		||||
            ConcurrentNodeReqs: [1, 2, 3],
 | 
			
		||||
            ConcurrentNodes: ["EventNode7", "EventNode4", "EventNode17"],
 | 
			
		||||
            MissionKeyName: "/Lotus/Types/Keys/TacAlertKeyProxyRebellionOne",
 | 
			
		||||
            Faction: "FC_CORPUS",
 | 
			
		||||
            Desc: "/Lotus/Language/Alerts/TacAlertProxyRebellion",
 | 
			
		||||
            Icon: "/Lotus/Materials/Emblems/BountyBadge_e.png",
 | 
			
		||||
            Tag: "ProxyRebellion",
 | 
			
		||||
            InterimRewards: rewards[year].slice(0, 2),
 | 
			
		||||
            Reward: rewards[year][2],
 | 
			
		||||
            BonusReward: rewards[year][3]
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (config.worldState?.longShadow) {
 | 
			
		||||
        worldState.Goals.push({
 | 
			
		||||
            _id: { $oid: "5bc9e8f7272d5d184c8398c9" },
 | 
			
		||||
            Activation: { $date: { $numberLong: "1539972000000" } },
 | 
			
		||||
            Expiry: { $date: { $numberLong: "2000000000000" } },
 | 
			
		||||
            Count: 0,
 | 
			
		||||
            InterimGoals: [1, 2],
 | 
			
		||||
            Goal: 3,
 | 
			
		||||
            BonusGoal: 4,
 | 
			
		||||
            Success: 0,
 | 
			
		||||
            Personal: true,
 | 
			
		||||
            Bounty: true,
 | 
			
		||||
            Tag: "NightwatchTacAlert",
 | 
			
		||||
            Faction: "FC_GRINEER",
 | 
			
		||||
            Desc: "/Lotus/Language/G1Quests/ProjectNightwatchTacAlertTitle",
 | 
			
		||||
            Icon: "/Lotus/Materials/Emblems/BountyBadge_e.png",
 | 
			
		||||
            ClampNodeScores: true,
 | 
			
		||||
            Node: "EventNode9",
 | 
			
		||||
            MissionKeyName: "/Lotus/Types/Keys/TacAlertKeyProjectNightwatchEasy",
 | 
			
		||||
            ConcurrentMissionKeyNames: [
 | 
			
		||||
                "/Lotus/Types/Keys/TacAlertKeyProjectNightwatch",
 | 
			
		||||
                "/Lotus/Types/Keys/TacAlertKeyProjectNightwatchHard",
 | 
			
		||||
                "/Lotus/Types/Keys/TacAlertKeyProjectNightwatchBonus"
 | 
			
		||||
            ],
 | 
			
		||||
            ConcurrentNodeReqs: [1, 2, 3],
 | 
			
		||||
            ConcurrentNodes: ["SolNode136", "EventNode3", "EventNode0"],
 | 
			
		||||
            InterimRewards: [
 | 
			
		||||
                {
 | 
			
		||||
                    credits: 50000,
 | 
			
		||||
                    countedItems: [
 | 
			
		||||
                        { ItemType: "/Lotus/Upgrades/Mods/FusionBundles/RareFusionBundle", ItemCount: 10 } // Not sure about that
 | 
			
		||||
                    ]
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                    items: ["/Lotus/StoreItems/Types/Items/MiscItems/UtilityUnlocker"]
 | 
			
		||||
                }
 | 
			
		||||
            ],
 | 
			
		||||
            Reward: {
 | 
			
		||||
                items: ["/Lotus/Types/StoreItems/Packages/EventCatalystReactorBundle"]
 | 
			
		||||
            },
 | 
			
		||||
            BonusReward: { items: ["/Lotus/StoreItems/Upgrades/Skins/Clan/BountyHunterBadgeItem"] }
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Nightwave Challenges
 | 
			
		||||
    const nightwaveSyndicateTag = getNightwaveSyndicateTag(buildLabel);
 | 
			
		||||
    if (nightwaveSyndicateTag) {
 | 
			
		||||
 | 
			
		||||
@ -5,12 +5,14 @@ export interface IWorldState {
 | 
			
		||||
    Version: number; // for goals
 | 
			
		||||
    BuildLabel: string;
 | 
			
		||||
    Time: number;
 | 
			
		||||
    InGameMarket: IInGameMarket;
 | 
			
		||||
    Goals: IGoal[];
 | 
			
		||||
    Alerts: [];
 | 
			
		||||
    Sorties: ISortie[];
 | 
			
		||||
    LiteSorties: ILiteSortie[];
 | 
			
		||||
    SyndicateMissions: ISyndicateMissionInfo[];
 | 
			
		||||
    ActiveMissions: IFissure[];
 | 
			
		||||
    FlashSales: IFlashSale[];
 | 
			
		||||
    GlobalUpgrades: IGlobalUpgrade[];
 | 
			
		||||
    Invasions: IInvasion[];
 | 
			
		||||
    NodeOverrides: INodeOverride[];
 | 
			
		||||
@ -39,10 +41,13 @@ export interface IGoal {
 | 
			
		||||
    Expiry: IMongoDate;
 | 
			
		||||
    Count?: number;
 | 
			
		||||
    Goal?: number;
 | 
			
		||||
    InterimGoals?: number[];
 | 
			
		||||
    BonusGoal?: number;
 | 
			
		||||
    HealthPct?: number;
 | 
			
		||||
    Success?: number;
 | 
			
		||||
    Personal?: boolean;
 | 
			
		||||
    Bounty?: boolean;
 | 
			
		||||
    Best?: boolean;
 | 
			
		||||
    Bounty?: boolean; // Tactical Alert
 | 
			
		||||
    Faction?: string;
 | 
			
		||||
    ClampNodeScores?: boolean;
 | 
			
		||||
    Desc: string;
 | 
			
		||||
@ -51,18 +56,28 @@ export interface IGoal {
 | 
			
		||||
    InstructionalItem?: string;
 | 
			
		||||
    Icon: string;
 | 
			
		||||
    Tag: string;
 | 
			
		||||
    PrereqGoalTags?: string[];
 | 
			
		||||
    Node?: string;
 | 
			
		||||
    VictimNode?: string;
 | 
			
		||||
    ConcurrentMissionKeyNames?: string[];
 | 
			
		||||
    ConcurrentNodeReqs?: number[];
 | 
			
		||||
    ConcurrentNodes?: string[];
 | 
			
		||||
    RegionIdx?: number;
 | 
			
		||||
    Regions?: number[];
 | 
			
		||||
    MissionKeyName?: string;
 | 
			
		||||
    Reward?: IMissionReward;
 | 
			
		||||
    InterimRewards?: IMissionReward[];
 | 
			
		||||
    BonusReward?: IMissionReward;
 | 
			
		||||
 | 
			
		||||
    JobAffiliationTag?: string;
 | 
			
		||||
    Jobs?: ISyndicateJob[];
 | 
			
		||||
    PreviousJobs?: ISyndicateJob[];
 | 
			
		||||
    JobCurrentVersion?: IOid;
 | 
			
		||||
    JobPreviousVersion?: IOid;
 | 
			
		||||
 | 
			
		||||
    ScoreVar?: string;
 | 
			
		||||
    ScoreMaxTag?: string;
 | 
			
		||||
    NightLevel?: string;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface ISyndicateJob {
 | 
			
		||||
@ -321,6 +336,37 @@ export type TCircuitGameMode =
 | 
			
		||||
    | "Assassination"
 | 
			
		||||
    | "Alchemy";
 | 
			
		||||
 | 
			
		||||
export interface IFlashSale {
 | 
			
		||||
    TypeName: string;
 | 
			
		||||
    ShowInMarket: boolean;
 | 
			
		||||
    HideFromMarket: boolean;
 | 
			
		||||
    SupporterPack: boolean;
 | 
			
		||||
    Discount: number;
 | 
			
		||||
    BogoBuy: number;
 | 
			
		||||
    BogoGet: number;
 | 
			
		||||
    PremiumOverride: number;
 | 
			
		||||
    RegularOverride: number;
 | 
			
		||||
    ProductExpiryOverride?: IMongoDate;
 | 
			
		||||
    StartDate: IMongoDate;
 | 
			
		||||
    EndDate: IMongoDate;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface IInGameMarket {
 | 
			
		||||
    LandingPage: ILandingPage;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface ILandingPage {
 | 
			
		||||
    Categories: IGameMarketCategory[];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface IGameMarketCategory {
 | 
			
		||||
    CategoryName: string;
 | 
			
		||||
    Name: string;
 | 
			
		||||
    Icon: string;
 | 
			
		||||
    AddToMenu?: boolean;
 | 
			
		||||
    Items?: string[];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface ITmp {
 | 
			
		||||
    cavabegin: string;
 | 
			
		||||
    PurchasePlatformLockEnabled: boolean; // Seems unused
 | 
			
		||||
 | 
			
		||||
@ -937,8 +937,57 @@
 | 
			
		||||
                                    <input class="form-check-input" type="checkbox" id="worldState.varziaFullyStocked" />
 | 
			
		||||
                                    <label class="form-check-label" for="worldState.varziaFullyStocked" data-loc="worldState_varziaFullyStocked"></label>
 | 
			
		||||
                                </div>
 | 
			
		||||
                                <div class="form-check">
 | 
			
		||||
                                    <input class="form-check-input" type="checkbox" id="worldState.wolfHunt" />
 | 
			
		||||
                                    <label class="form-check-label" for="worldState.wolfHunt" data-loc="worldState_wolfHunt"></label>
 | 
			
		||||
                                    <abbr data-loc-inc="worldState_galleonOfGhouls"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640"><path d="M320 576C461.4 576 576 461.4 576 320C576 178.6 461.4 64 320 64C178.6 64 64 178.6 64 320C64 461.4 178.6 576 320 576zM320 200C333.3 200 344 210.7 344 224L344 336C344 349.3 333.3 360 320 360C306.7 360 296 349.3 296 336L296 224C296 210.7 306.7 200 320 200zM293.3 416C292.7 406.1 297.6 396.7 306.1 391.5C314.6 386.4 325.3 386.4 333.8 391.5C342.3 396.7 347.2 406.1 346.6 416C347.2 425.9 342.3 435.3 333.8 440.5C325.3 445.6 314.6 445.6 306.1 440.5C297.6 435.3 292.7 425.9 293.3 416z"/></svg></abbr>
 | 
			
		||||
                                </div>
 | 
			
		||||
                                <div class="form-check">
 | 
			
		||||
                                    <input class="form-check-input" type="checkbox" id="worldState.longShadow" />
 | 
			
		||||
                                    <label class="form-check-label" for="worldState.longShadow" data-loc="worldState_longShadow"></label>
 | 
			
		||||
                                </div>
 | 
			
		||||
                                <div class="form-check">
 | 
			
		||||
                                    <input class="form-check-input" type="checkbox" id="worldState.hallowedFlame" />
 | 
			
		||||
                                    <label class="form-check-label" for="worldState.hallowedFlame" data-loc="worldState_hallowedFlame"></label>
 | 
			
		||||
                                    <abbr data-loc-inc="worldState_hallowedNightmares|worldState_dogDays"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640"><path d="M320 576C461.4 576 576 461.4 576 320C576 178.6 461.4 64 320 64C178.6 64 64 178.6 64 320C64 461.4 178.6 576 320 576zM320 200C333.3 200 344 210.7 344 224L344 336C344 349.3 333.3 360 320 360C306.7 360 296 349.3 296 336L296 224C296 210.7 306.7 200 320 200zM293.3 416C292.7 406.1 297.6 396.7 306.1 391.5C314.6 386.4 325.3 386.4 333.8 391.5C342.3 396.7 347.2 406.1 346.6 416C347.2 425.9 342.3 435.3 333.8 440.5C325.3 445.6 314.6 445.6 306.1 440.5C297.6 435.3 292.7 425.9 293.3 416z"/></svg></abbr>
 | 
			
		||||
                                </div>
 | 
			
		||||
                                <div class="form-group mt-2 d-flex gap-2">
 | 
			
		||||
                                    <div class="flex-fill">
 | 
			
		||||
                                        <label class="form-label" for="worldState.hallowedNightmares" data-loc="worldState_hallowedNightmares"></label>
 | 
			
		||||
                                        <abbr data-loc-inc="worldState_hallowedFlame|worldState_dogDays"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640"><path d="M320 576C461.4 576 576 461.4 576 320C576 178.6 461.4 64 320 64C178.6 64 64 178.6 64 320C64 461.4 178.6 576 320 576zM320 200C333.3 200 344 210.7 344 224L344 336C344 349.3 333.3 360 320 360C306.7 360 296 349.3 296 336L296 224C296 210.7 306.7 200 320 200zM293.3 416C292.7 406.1 297.6 396.7 306.1 391.5C314.6 386.4 325.3 386.4 333.8 391.5C342.3 396.7 347.2 406.1 346.6 416C347.2 425.9 342.3 435.3 333.8 440.5C325.3 445.6 314.6 445.6 306.1 440.5C297.6 435.3 292.7 425.9 293.3 416z"/></svg></abbr>
 | 
			
		||||
                                        <select class="form-control" id="worldState.hallowedNightmares" data-default="false">
 | 
			
		||||
                                            <option value="true" data-loc="enabled"></option>
 | 
			
		||||
                                            <option value="false" data-loc="disabled"></option>
 | 
			
		||||
                                        </select>
 | 
			
		||||
                                    </div>
 | 
			
		||||
                                    <div class="flex-fill">
 | 
			
		||||
                                        <label class="form-label" for="worldState.hallowedNightmaresRewardsOverride" data-loc="worldState_hallowedNightmaresRewards"></label>
 | 
			
		||||
                                        <select class="form-control" id="worldState.hallowedNightmaresRewardsOverride" data-default="0">
 | 
			
		||||
                                                <option value="0" data-loc="worldState_from_year" data-loc-year="2018"></option>
 | 
			
		||||
                                                <option value="1" data-loc="worldState_from_year" data-loc-year="2016"></option>
 | 
			
		||||
                                                <option value="2" data-loc="worldState_from_year" data-loc-year="2015"></option>
 | 
			
		||||
                                        </select>
 | 
			
		||||
                                    </div>
 | 
			
		||||
                                </div>
 | 
			
		||||
                                <div class="form-group mt-2 d-flex gap-2">
 | 
			
		||||
                                    <div class="flex-fill">
 | 
			
		||||
                                        <label class="form-label" for="worldState.proxyRebellion" data-loc="worldState_proxyRebellion"></label>
 | 
			
		||||
                                        <select class="form-control" id="worldState.proxyRebellion" data-default="false">
 | 
			
		||||
                                            <option value="true" data-loc="enabled"></option>
 | 
			
		||||
                                            <option value="false" data-loc="disabled"></option>
 | 
			
		||||
                                        </select>
 | 
			
		||||
                                    </div>
 | 
			
		||||
                                    <div class="flex-fill">
 | 
			
		||||
                                        <label class="form-label" for="worldState.proxyRebellionRewardsOverride" data-loc="worldState_proxyRebellionRewards"></label>
 | 
			
		||||
                                        <select class="form-control" id="worldState.proxyRebellionRewardsOverride" data-default="0">
 | 
			
		||||
                                            <option value="0" data-loc="worldState_from_year" data-loc-year="2019"></option>
 | 
			
		||||
                                            <option value="1" data-loc="worldState_from_year" data-loc-year="2018"></option>
 | 
			
		||||
                                        </select>
 | 
			
		||||
                                    </div>
 | 
			
		||||
                                </div>
 | 
			
		||||
                                <div class="form-group mt-2">
 | 
			
		||||
                                    <label class="form-label" for="worldState.galleonOfGhouls" data-loc="worldState_galleonOfGhouls"></label>
 | 
			
		||||
                                    <abbr data-loc-inc="worldState_wolfHunt"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640"><path d="M320 576C461.4 576 576 461.4 576 320C576 178.6 461.4 64 320 64C178.6 64 64 178.6 64 320C64 461.4 178.6 576 320 576zM320 200C333.3 200 344 210.7 344 224L344 336C344 349.3 333.3 360 320 360C306.7 360 296 349.3 296 336L296 224C296 210.7 306.7 200 320 200zM293.3 416C292.7 406.1 297.6 396.7 306.1 391.5C314.6 386.4 325.3 386.4 333.8 391.5C342.3 396.7 347.2 406.1 346.6 416C347.2 425.9 342.3 435.3 333.8 440.5C325.3 445.6 314.6 445.6 306.1 440.5C297.6 435.3 292.7 425.9 293.3 416z"/></svg></abbr>
 | 
			
		||||
                                    <select class="form-control" id="worldState.galleonOfGhouls" data-default="0">
 | 
			
		||||
                                        <option value="0" data-loc="disabled"></option>
 | 
			
		||||
                                        <option value="1" data-loc="worldState_we1"></option>
 | 
			
		||||
@ -970,6 +1019,27 @@
 | 
			
		||||
                                        <option value="false" data-loc="disabled"></option>
 | 
			
		||||
                                    </select>
 | 
			
		||||
                                </div>
 | 
			
		||||
                                <div class="form-group mt-2 d-flex gap-2">
 | 
			
		||||
                                    <div class="flex-fill">
 | 
			
		||||
                                        <label class="form-label" for="worldState.dogDaysOverride" data-loc="worldState_dogDays"></label>
 | 
			
		||||
                                        <abbr data-loc-inc="worldState_hallowedFlame|worldState_hallowedNightmares"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640"><path d="M320 576C461.4 576 576 461.4 576 320C576 178.6 461.4 64 320 64C178.6 64 64 178.6 64 320C64 461.4 178.6 576 320 576zM320 200C333.3 200 344 210.7 344 224L344 336C344 349.3 333.3 360 320 360C306.7 360 296 349.3 296 336L296 224C296 210.7 306.7 200 320 200zM293.3 416C292.7 406.1 297.6 396.7 306.1 391.5C314.6 386.4 325.3 386.4 333.8 391.5C342.3 396.7 347.2 406.1 346.6 416C347.2 425.9 342.3 435.3 333.8 440.5C325.3 445.6 314.6 445.6 306.1 440.5C297.6 435.3 292.7 425.9 293.3 416z"/></svg></abbr>
 | 
			
		||||
                                        <select class="form-control" id="worldState.dogDaysOverride" data-default="null">
 | 
			
		||||
                                            <option value="null" data-loc="normal"></option>
 | 
			
		||||
                                            <option value="true" data-loc="enabled"></option>
 | 
			
		||||
                                            <option value="false" data-loc="disabled"></option>
 | 
			
		||||
                                        </select>
 | 
			
		||||
                                    </div>
 | 
			
		||||
                                    <div class="flex-fill">
 | 
			
		||||
                                        <label class="form-label" for="worldState.dogDaysRewardsOverride" data-loc="worldState_dogDaysRewards"></label>
 | 
			
		||||
                                        <select class="form-control" id="worldState.dogDaysRewardsOverride" data-default="null">
 | 
			
		||||
                                            <option value="null" data-loc="normal"></option>
 | 
			
		||||
                                            <option value="3" data-loc="worldState_from_year" data-loc-year="2025"></option>
 | 
			
		||||
                                            <option value="2" data-loc="worldState_from_year" data-loc-year="2024"></option>
 | 
			
		||||
                                            <option value="1" data-loc="worldState_from_year" data-loc-year="2023"></option>
 | 
			
		||||
                                            <option value="0" data-loc="worldState_pre_year" data-loc-year="2023"></option>
 | 
			
		||||
                                        </select>
 | 
			
		||||
                                    </div>
 | 
			
		||||
                                </div>
 | 
			
		||||
                                <div class="form-group mt-2">
 | 
			
		||||
                                    <label class="form-label" for="worldState.eidolonOverride" data-loc="worldState_eidolonOverride"></label>
 | 
			
		||||
                                    <select class="form-control" id="worldState.eidolonOverride" data-default="">
 | 
			
		||||
 | 
			
		||||
@ -202,6 +202,17 @@ function updateLocElements() {
 | 
			
		||||
    document.querySelectorAll("[data-loc-placeholder]").forEach(elm => {
 | 
			
		||||
        elm.placeholder = loc(elm.getAttribute("data-loc-placeholder"));
 | 
			
		||||
    });
 | 
			
		||||
    document.querySelectorAll("[data-loc-inc]").forEach(elm => {
 | 
			
		||||
        const incWith = elm
 | 
			
		||||
            .getAttribute("data-loc-inc")
 | 
			
		||||
            .split("|")
 | 
			
		||||
            .map(key => loc(key))
 | 
			
		||||
            .join(", ");
 | 
			
		||||
        elm.title = `${loc("worldState_incompatibleWith")} ${incWith}`;
 | 
			
		||||
    });
 | 
			
		||||
    document.querySelectorAll("[data-loc-year]").forEach(elm => {
 | 
			
		||||
        elm.innerHTML = elm.innerHTML.replace("|YEAR|", elm.getAttribute("data-loc-year"));
 | 
			
		||||
    });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function setActiveLanguage(lang) {
 | 
			
		||||
 | 
			
		||||
@ -29,9 +29,12 @@ body:not(.logged-in) .user-dropdown {
 | 
			
		||||
    display: none;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
td.text-end > a > svg {
 | 
			
		||||
/* font awesome icons */
 | 
			
		||||
svg {
 | 
			
		||||
    fill: currentColor;
 | 
			
		||||
    height: 1em;
 | 
			
		||||
}
 | 
			
		||||
td.text-end > a > svg {
 | 
			
		||||
    margin-left: 0.5em;
 | 
			
		||||
    margin-bottom: 4px; /* to centre the icon */
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -248,6 +248,18 @@ dict = {
 | 
			
		||||
    worldState_galleonOfGhouls: `Galeone der Ghule`,
 | 
			
		||||
    worldState_ghoulEmergence: `Ghul Ausrottung`,
 | 
			
		||||
    worldState_plagueStar: `Plagenstern`,
 | 
			
		||||
    worldState_dogDays: `Hitzefrei`,
 | 
			
		||||
    worldState_dogDaysRewards: `[UNTRANSLATED] Dog Days Rewards`,
 | 
			
		||||
    worldState_wolfHunt: `Wolfsjagd (2025)`,
 | 
			
		||||
    worldState_longShadow: `Lange Schatten`,
 | 
			
		||||
    worldState_hallowedFlame: `Geweihte Flamme`,
 | 
			
		||||
    worldState_hallowedNightmares: `Geweihte Albträume`,
 | 
			
		||||
    worldState_hallowedNightmaresRewards: `[UNTRANSLATED] Hallowed Nightmares Rewards`,
 | 
			
		||||
    worldState_proxyRebellion: `Proxy-Rebellion`,
 | 
			
		||||
    worldState_proxyRebellionRewards: `[UNTRANSLATED] Proxy Rebellion Rewards`,
 | 
			
		||||
    worldState_from_year: `[UNTRANSLATED] from |YEAR|`,
 | 
			
		||||
    worldState_pre_year: `[UNTRANSLATED] pre |YEAR|`,
 | 
			
		||||
    worldState_incompatibleWith: `[UNTRANSLATED] Incompatible with:`,
 | 
			
		||||
    enabled: `Aktiviert`,
 | 
			
		||||
    disabled: `Deaktiviert`,
 | 
			
		||||
    worldState_we1: `Wochenende 1`,
 | 
			
		||||
 | 
			
		||||
@ -247,6 +247,18 @@ dict = {
 | 
			
		||||
    worldState_galleonOfGhouls: `Galleon of Ghouls`,
 | 
			
		||||
    worldState_ghoulEmergence: `Ghoul Purge`,
 | 
			
		||||
    worldState_plagueStar: `Plague Star`,
 | 
			
		||||
    worldState_dogDays: `Dog Days`,
 | 
			
		||||
    worldState_dogDaysRewards: `Dog Days Rewards`,
 | 
			
		||||
    worldState_wolfHunt: `Wolf Hunt (2025)`,
 | 
			
		||||
    worldState_longShadow: `Long Shadow`,
 | 
			
		||||
    worldState_hallowedFlame: `Hallowed Flame`,
 | 
			
		||||
    worldState_hallowedNightmares: `Hallowed Nightmares`,
 | 
			
		||||
    worldState_hallowedNightmaresRewards: `Hallowed Nightmares Rewards`,
 | 
			
		||||
    worldState_proxyRebellion: `Proxy Rebellion`,
 | 
			
		||||
    worldState_proxyRebellionRewards: `Proxy Rebellion Rewards`,
 | 
			
		||||
    worldState_from_year: `from |YEAR|`,
 | 
			
		||||
    worldState_pre_year: `pre |YEAR|`,
 | 
			
		||||
    worldState_incompatibleWith: `Incompatible with:`,
 | 
			
		||||
    enabled: `Enabled`,
 | 
			
		||||
    disabled: `Disabled`,
 | 
			
		||||
    worldState_we1: `Weekend 1`,
 | 
			
		||||
 | 
			
		||||
@ -248,6 +248,18 @@ dict = {
 | 
			
		||||
    worldState_galleonOfGhouls: `Galeón de Gules`,
 | 
			
		||||
    worldState_ghoulEmergence: `Purga de Gules`,
 | 
			
		||||
    worldState_plagueStar: `Estrella Infestada`,
 | 
			
		||||
    worldState_dogDays: `Canícula`,
 | 
			
		||||
    worldState_dogDaysRewards: `[UNTRANSLATED] Dog Days Rewards`,
 | 
			
		||||
    worldState_wolfHunt: `Cacería del Lobo (2025)`,
 | 
			
		||||
    worldState_longShadow: `Sombra Prolongada`,
 | 
			
		||||
    worldState_hallowedFlame: `Llama Sagrada`,
 | 
			
		||||
    worldState_hallowedNightmares: `Pesadillas sagradas`,
 | 
			
		||||
    worldState_hallowedNightmaresRewards: `[UNTRANSLATED] Hallowed Nightmares Rewards`,
 | 
			
		||||
    worldState_proxyRebellion: `Rebelión Proxy`,
 | 
			
		||||
    worldState_proxyRebellionRewards: `[UNTRANSLATED] Proxy Rebellion Rewards`,
 | 
			
		||||
    worldState_from_year: `[UNTRANSLATED] from |YEAR|`,
 | 
			
		||||
    worldState_pre_year: `[UNTRANSLATED] pre |YEAR|`,
 | 
			
		||||
    worldState_incompatibleWith: `[UNTRANSLATED] Incompatible with:`,
 | 
			
		||||
    enabled: `Activado`,
 | 
			
		||||
    disabled: `Desactivado`,
 | 
			
		||||
    worldState_we1: `Semana 1`,
 | 
			
		||||
 | 
			
		||||
@ -248,6 +248,18 @@ dict = {
 | 
			
		||||
    worldState_galleonOfGhouls: `Galion des Goules`,
 | 
			
		||||
    worldState_ghoulEmergence: `Purge des Goules`,
 | 
			
		||||
    worldState_plagueStar: `Fléau Céleste`,
 | 
			
		||||
    worldState_dogDays: `Bataille d'Eau`,
 | 
			
		||||
    worldState_dogDaysRewards: `[UNTRANSLATED] Dog Days Rewards`,
 | 
			
		||||
    worldState_wolfHunt: `Chasse au Loup (2025)`,
 | 
			
		||||
    worldState_longShadow: `La Propagation des Ombres`,
 | 
			
		||||
    worldState_hallowedFlame: `Flamme Hantée`,
 | 
			
		||||
    worldState_hallowedNightmares: `Cauchemars Hantés`,
 | 
			
		||||
    worldState_hallowedNightmaresRewards: `[UNTRANSLATED] Hallowed Nightmares Rewards`,
 | 
			
		||||
    worldState_proxyRebellion: `Rébellion Proxy`,
 | 
			
		||||
    worldState_proxyRebellionRewards: `[UNTRANSLATED] Proxy Rebellion Rewards`,
 | 
			
		||||
    worldState_from_year: `[UNTRANSLATED] from |YEAR|`,
 | 
			
		||||
    worldState_pre_year: `[UNTRANSLATED] pre |YEAR|`,
 | 
			
		||||
    worldState_incompatibleWith: `[UNTRANSLATED] Incompatible with:`,
 | 
			
		||||
    enabled: `Activé`,
 | 
			
		||||
    disabled: `Désactivé`,
 | 
			
		||||
    worldState_we1: `Weekend 1`,
 | 
			
		||||
 | 
			
		||||
@ -248,6 +248,18 @@ dict = {
 | 
			
		||||
    worldState_galleonOfGhouls: `Галеон Гулей`,
 | 
			
		||||
    worldState_ghoulEmergence: `Избавление от гулей`,
 | 
			
		||||
    worldState_plagueStar: `Чумная звезда`,
 | 
			
		||||
    worldState_dogDays: `Знойные дни`,
 | 
			
		||||
    worldState_dogDaysRewards: `Награды Знойных дней`,
 | 
			
		||||
    worldState_wolfHunt: `Волчья Охота (2025)`,
 | 
			
		||||
    worldState_longShadow: `Длинная Тень`,
 | 
			
		||||
    worldState_hallowedFlame: `Священное пламя`,
 | 
			
		||||
    worldState_hallowedNightmares: `Священные Кошмары`,
 | 
			
		||||
    worldState_hallowedNightmaresRewards: `Награды Священных Кошмаров`,
 | 
			
		||||
    worldState_proxyRebellion: `Восстание Роботов`,
 | 
			
		||||
    worldState_proxyRebellionRewards: `Награды Восстания Роботов`,
 | 
			
		||||
    worldState_from_year: `из |YEAR|`,
 | 
			
		||||
    worldState_pre_year: `до |YEAR|`,
 | 
			
		||||
    worldState_incompatibleWith: `Несовместимо с:`,
 | 
			
		||||
    enabled: `Включено`,
 | 
			
		||||
    disabled: `Отключено`,
 | 
			
		||||
    worldState_we1: `Выходные 1`,
 | 
			
		||||
 | 
			
		||||
@ -248,6 +248,18 @@ dict = {
 | 
			
		||||
    worldState_galleonOfGhouls: `Гульський Галеон`,
 | 
			
		||||
    worldState_ghoulEmergence: `Зачищення від гулів`,
 | 
			
		||||
    worldState_plagueStar: `Морова зірка`,
 | 
			
		||||
    worldState_dogDays: `Спекотні дні`,
 | 
			
		||||
    worldState_dogDaysRewards: `[UNTRANSLATED] Dog Days Rewards`,
 | 
			
		||||
    worldState_wolfHunt: `Полювання на Вовка (2025)`,
 | 
			
		||||
    worldState_longShadow: `Довга тінь`,
 | 
			
		||||
    worldState_hallowedFlame: `Священне полум'я`,
 | 
			
		||||
    worldState_hallowedNightmares: `Священні жахіття`,
 | 
			
		||||
    worldState_hallowedNightmaresRewards: `[UNTRANSLATED] Hallowed Nightmares Rewards`,
 | 
			
		||||
    worldState_proxyRebellion: `Повстання роботів`,
 | 
			
		||||
    worldState_proxyRebellionRewards: `[UNTRANSLATED] Proxy Rebellion Rewards`,
 | 
			
		||||
    worldState_from_year: `[UNTRANSLATED] from |YEAR|`,
 | 
			
		||||
    worldState_pre_year: `[UNTRANSLATED] pre |YEAR|`,
 | 
			
		||||
    worldState_incompatibleWith: `[UNTRANSLATED] Incompatible with:`,
 | 
			
		||||
    enabled: `Увімкнено`,
 | 
			
		||||
    disabled: `Вимкнено`,
 | 
			
		||||
    worldState_we1: `Вихідні 1`,
 | 
			
		||||
 | 
			
		||||
@ -248,6 +248,18 @@ dict = {
 | 
			
		||||
    worldState_galleonOfGhouls: `战术警报:尸鬼的帆船战舰`,
 | 
			
		||||
    worldState_ghoulEmergence: `尸鬼净化`,
 | 
			
		||||
    worldState_plagueStar: `瘟疫之星`,
 | 
			
		||||
    worldState_dogDays: `三伏天`,
 | 
			
		||||
    worldState_dogDaysRewards: `[UNTRANSLATED] Dog Days Rewards`,
 | 
			
		||||
    worldState_wolfHunt: `恶狼狩猎 (2025)`,
 | 
			
		||||
    worldState_longShadow: `暗夜长影`,
 | 
			
		||||
    worldState_hallowedFlame: `万圣之焰`,
 | 
			
		||||
    worldState_hallowedNightmares: `万圣噩梦`,
 | 
			
		||||
    worldState_hallowedNightmaresRewards: `[UNTRANSLATED] Hallowed Nightmares Rewards`,
 | 
			
		||||
    worldState_proxyRebellion: `机械叛乱`,
 | 
			
		||||
    worldState_proxyRebellionRewards: `[UNTRANSLATED] Proxy Rebellion Rewards`,
 | 
			
		||||
    worldState_from_year: `[UNTRANSLATED] from |YEAR|`,
 | 
			
		||||
    worldState_pre_year: `[UNTRANSLATED] pre |YEAR|`,
 | 
			
		||||
    worldState_incompatibleWith: `[UNTRANSLATED] Incompatible with:`,
 | 
			
		||||
    enabled: `启用`,
 | 
			
		||||
    disabled: `关闭/取消配置`,
 | 
			
		||||
    worldState_we1: `活动阶段:第一周`,
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user