chore(webui): update Spanish translation #1702
@ -33,6 +33,7 @@
 | 
				
			|||||||
  "noArgonCrystalDecay": false,
 | 
					  "noArgonCrystalDecay": false,
 | 
				
			||||||
  "noMasteryRankUpCooldown": false,
 | 
					  "noMasteryRankUpCooldown": false,
 | 
				
			||||||
  "noVendorPurchaseLimits": true,
 | 
					  "noVendorPurchaseLimits": true,
 | 
				
			||||||
 | 
					  "noDeathMarks": false,
 | 
				
			||||||
  "noKimCooldowns": false,
 | 
					  "noKimCooldowns": false,
 | 
				
			||||||
  "instantResourceExtractorDrones": false,
 | 
					  "instantResourceExtractorDrones": false,
 | 
				
			||||||
  "noResourceExtractorDronesDamage": false,
 | 
					  "noResourceExtractorDronesDamage": false,
 | 
				
			||||||
 | 
				
			|||||||
@ -1,33 +1,64 @@
 | 
				
			|||||||
import { addCrewShipSalvagedWeaponSkin, addCrewShipRawSalvage, getInventory } from "@/src/services/inventoryService";
 | 
					import {
 | 
				
			||||||
 | 
					    addCrewShipSalvagedWeaponSkin,
 | 
				
			||||||
 | 
					    addCrewShipRawSalvage,
 | 
				
			||||||
 | 
					    getInventory,
 | 
				
			||||||
 | 
					    addEquipment
 | 
				
			||||||
 | 
					} from "@/src/services/inventoryService";
 | 
				
			||||||
import { getAccountIdForRequest } from "@/src/services/loginService";
 | 
					import { getAccountIdForRequest } from "@/src/services/loginService";
 | 
				
			||||||
import { RequestHandler } from "express";
 | 
					import { RequestHandler } from "express";
 | 
				
			||||||
import { ICrewShipComponentFingerprint } from "@/src/types/inventoryTypes/inventoryTypes";
 | 
					import { ICrewShipComponentFingerprint, IInnateDamageFingerprint } from "@/src/types/inventoryTypes/inventoryTypes";
 | 
				
			||||||
import { ExportCustoms } from "warframe-public-export-plus";
 | 
					import { ExportCustoms, ExportRailjackWeapons, ExportUpgrades } from "warframe-public-export-plus";
 | 
				
			||||||
import { getJSONfromString } from "@/src/helpers/stringHelpers";
 | 
					import { getJSONfromString } from "@/src/helpers/stringHelpers";
 | 
				
			||||||
import { IInventoryChanges } from "@/src/types/purchaseTypes";
 | 
					import { IInventoryChanges } from "@/src/types/purchaseTypes";
 | 
				
			||||||
import { getRandomInt } from "@/src/services/rngService";
 | 
					import { getRandomInt } from "@/src/services/rngService";
 | 
				
			||||||
 | 
					import { IFingerprintStat } from "@/src/helpers/rivenHelper";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const crewShipIdentifySalvageController: RequestHandler = async (req, res) => {
 | 
					export const crewShipIdentifySalvageController: RequestHandler = async (req, res) => {
 | 
				
			||||||
    const accountId = await getAccountIdForRequest(req);
 | 
					    const accountId = await getAccountIdForRequest(req);
 | 
				
			||||||
    const inventory = await getInventory(accountId, "CrewShipSalvagedWeaponSkins CrewShipRawSalvage");
 | 
					    const inventory = await getInventory(
 | 
				
			||||||
 | 
					        accountId,
 | 
				
			||||||
 | 
					        "CrewShipSalvagedWeaponSkins CrewShipSalvagedWeapons CrewShipRawSalvage"
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
    const payload = getJSONfromString<ICrewShipIdentifySalvageRequest>(String(req.body));
 | 
					    const payload = getJSONfromString<ICrewShipIdentifySalvageRequest>(String(req.body));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const meta = ExportCustoms[payload.ItemType];
 | 
					    const inventoryChanges: IInventoryChanges = {};
 | 
				
			||||||
    let upgradeFingerprint: ICrewShipComponentFingerprint = { compat: payload.ItemType, buffs: [] };
 | 
					    if (payload.ItemType in ExportCustoms) {
 | 
				
			||||||
    if (meta.subroutines) {
 | 
					        const meta = ExportCustoms[payload.ItemType];
 | 
				
			||||||
        upgradeFingerprint = {
 | 
					        let upgradeFingerprint: ICrewShipComponentFingerprint = { compat: payload.ItemType, buffs: [] };
 | 
				
			||||||
            SubroutineIndex: getRandomInt(0, meta.subroutines.length - 1),
 | 
					        if (meta.subroutines) {
 | 
				
			||||||
            ...upgradeFingerprint
 | 
					            upgradeFingerprint = {
 | 
				
			||||||
        };
 | 
					                SubroutineIndex: getRandomInt(0, meta.subroutines.length - 1),
 | 
				
			||||||
 | 
					                ...upgradeFingerprint
 | 
				
			||||||
 | 
					            };
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        for (const upgrade of meta.randomisedUpgrades!) {
 | 
				
			||||||
 | 
					            upgradeFingerprint.buffs.push({ Tag: upgrade.tag, Value: Math.trunc(Math.random() * 0x40000000) });
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        addCrewShipSalvagedWeaponSkin(
 | 
				
			||||||
 | 
					            inventory,
 | 
				
			||||||
 | 
					            payload.ItemType,
 | 
				
			||||||
 | 
					            JSON.stringify(upgradeFingerprint),
 | 
				
			||||||
 | 
					            inventoryChanges
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        const meta = ExportRailjackWeapons[payload.ItemType];
 | 
				
			||||||
 | 
					        const upgradeType = meta.defaultUpgrades![0].ItemType;
 | 
				
			||||||
 | 
					        const upgradeMeta = ExportUpgrades[upgradeType];
 | 
				
			||||||
 | 
					        const buffs: IFingerprintStat[] = [];
 | 
				
			||||||
 | 
					        for (const buff of upgradeMeta.upgradeEntries!) {
 | 
				
			||||||
 | 
					            buffs.push({
 | 
				
			||||||
 | 
					                Tag: buff.tag,
 | 
				
			||||||
 | 
					                Value: Math.trunc(Math.random() * 0x40000000)
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        addEquipment(inventory, "CrewShipSalvagedWeapons", payload.ItemType, undefined, inventoryChanges, {
 | 
				
			||||||
 | 
					            UpgradeType: upgradeType,
 | 
				
			||||||
 | 
					            UpgradeFingerprint: JSON.stringify({
 | 
				
			||||||
 | 
					                compat: payload.ItemType,
 | 
				
			||||||
 | 
					                buffs
 | 
				
			||||||
 | 
					            } satisfies IInnateDamageFingerprint)
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    for (const upgrade of meta.randomisedUpgrades!) {
 | 
					 | 
				
			||||||
        upgradeFingerprint.buffs.push({ Tag: upgrade.tag, Value: Math.trunc(Math.random() * 0x40000000) });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    const inventoryChanges: IInventoryChanges = addCrewShipSalvagedWeaponSkin(
 | 
					 | 
				
			||||||
        inventory,
 | 
					 | 
				
			||||||
        payload.ItemType,
 | 
					 | 
				
			||||||
        JSON.stringify(upgradeFingerprint)
 | 
					 | 
				
			||||||
    );
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    inventoryChanges.CrewShipRawSalvage = [
 | 
					    inventoryChanges.CrewShipRawSalvage = [
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
 | 
				
			|||||||
@ -15,6 +15,7 @@ import { ExportDojoRecipes } from "warframe-public-export-plus";
 | 
				
			|||||||
import { getAccountIdForRequest } from "@/src/services/loginService";
 | 
					import { getAccountIdForRequest } from "@/src/services/loginService";
 | 
				
			||||||
import {
 | 
					import {
 | 
				
			||||||
    addCrewShipWeaponSkin,
 | 
					    addCrewShipWeaponSkin,
 | 
				
			||||||
 | 
					    addEquipment,
 | 
				
			||||||
    addItem,
 | 
					    addItem,
 | 
				
			||||||
    addMiscItems,
 | 
					    addMiscItems,
 | 
				
			||||||
    addRecipes,
 | 
					    addRecipes,
 | 
				
			||||||
@ -382,18 +383,31 @@ interface IGuildTechContributeRequest {
 | 
				
			|||||||
const claimSalvagedComponent = (inventory: TInventoryDatabaseDocument, itemId: string): IInventoryChanges => {
 | 
					const claimSalvagedComponent = (inventory: TInventoryDatabaseDocument, itemId: string): IInventoryChanges => {
 | 
				
			||||||
    // delete personal tech project
 | 
					    // delete personal tech project
 | 
				
			||||||
    const personalTechProjectIndex = inventory.PersonalTechProjects.findIndex(x => x.CategoryItemId?.equals(itemId));
 | 
					    const personalTechProjectIndex = inventory.PersonalTechProjects.findIndex(x => x.CategoryItemId?.equals(itemId));
 | 
				
			||||||
    if (personalTechProjectIndex != -1) {
 | 
					    const personalTechProject = inventory.PersonalTechProjects[personalTechProjectIndex];
 | 
				
			||||||
        inventory.PersonalTechProjects.splice(personalTechProjectIndex, 1);
 | 
					    inventory.PersonalTechProjects.splice(personalTechProjectIndex, 1);
 | 
				
			||||||
    }
 | 
					
 | 
				
			||||||
 | 
					    const category = personalTechProject.ProductCategory! as "CrewShipWeapons" | "CrewShipWeaponSkins";
 | 
				
			||||||
 | 
					    const salvageCategory = category == "CrewShipWeapons" ? "CrewShipSalvagedWeapons" : "CrewShipSalvagedWeaponSkins";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // find salved part & delete it
 | 
					    // find salved part & delete it
 | 
				
			||||||
    const crewShipSalvagedWeaponSkinsIndex = inventory.CrewShipSalvagedWeaponSkins.findIndex(x => x._id.equals(itemId));
 | 
					    const salvageIndex = inventory[salvageCategory].findIndex(x => x._id.equals(itemId));
 | 
				
			||||||
    const crewShipWeaponSkin = inventory.CrewShipSalvagedWeaponSkins[crewShipSalvagedWeaponSkinsIndex];
 | 
					    const salvageItem = inventory[category][salvageIndex];
 | 
				
			||||||
    inventory.CrewShipSalvagedWeaponSkins.splice(crewShipSalvagedWeaponSkinsIndex, 1);
 | 
					    inventory[salvageCategory].splice(salvageIndex, 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // add final item
 | 
					    // add final item
 | 
				
			||||||
    const inventoryChanges = {
 | 
					    const inventoryChanges = {
 | 
				
			||||||
        ...addCrewShipWeaponSkin(inventory, crewShipWeaponSkin.ItemType, crewShipWeaponSkin.UpgradeFingerprint),
 | 
					        ...(category == "CrewShipWeaponSkins"
 | 
				
			||||||
 | 
					            ? addCrewShipWeaponSkin(inventory, salvageItem.ItemType, salvageItem.UpgradeFingerprint)
 | 
				
			||||||
 | 
					            : addEquipment(
 | 
				
			||||||
 | 
					                  inventory,
 | 
				
			||||||
 | 
					                  category,
 | 
				
			||||||
 | 
					                  salvageItem.ItemType,
 | 
				
			||||||
 | 
					                  undefined,
 | 
				
			||||||
 | 
					                  {},
 | 
				
			||||||
 | 
					                  {
 | 
				
			||||||
 | 
					                      UpgradeFingerprint: salvageItem.UpgradeFingerprint
 | 
				
			||||||
 | 
					                  }
 | 
				
			||||||
 | 
					              )),
 | 
				
			||||||
        ...occupySlot(inventory, InventorySlot.RJ_COMPONENT_AND_ARMAMENTS, false)
 | 
					        ...occupySlot(inventory, InventorySlot.RJ_COMPONENT_AND_ARMAMENTS, false)
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -7,16 +7,18 @@ import {
 | 
				
			|||||||
    addMiscItems,
 | 
					    addMiscItems,
 | 
				
			||||||
    addConsumables,
 | 
					    addConsumables,
 | 
				
			||||||
    freeUpSlot,
 | 
					    freeUpSlot,
 | 
				
			||||||
    combineInventoryChanges
 | 
					    combineInventoryChanges,
 | 
				
			||||||
 | 
					    addCrewShipRawSalvage
 | 
				
			||||||
} from "@/src/services/inventoryService";
 | 
					} from "@/src/services/inventoryService";
 | 
				
			||||||
import { InventorySlot } from "@/src/types/inventoryTypes/inventoryTypes";
 | 
					import { InventorySlot } from "@/src/types/inventoryTypes/inventoryTypes";
 | 
				
			||||||
import { ExportDojoRecipes } from "warframe-public-export-plus";
 | 
					import { ExportDojoRecipes } from "warframe-public-export-plus";
 | 
				
			||||||
import { IInventoryChanges } from "@/src/types/purchaseTypes";
 | 
					import { IInventoryChanges } from "@/src/types/purchaseTypes";
 | 
				
			||||||
 | 
					import { TInventoryDatabaseDocument } from "@/src/models/inventoryModels/inventoryModel";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const sellController: RequestHandler = async (req, res) => {
 | 
					export const sellController: RequestHandler = async (req, res) => {
 | 
				
			||||||
    const payload = JSON.parse(String(req.body)) as ISellRequest;
 | 
					    const payload = JSON.parse(String(req.body)) as ISellRequest;
 | 
				
			||||||
    const accountId = await getAccountIdForRequest(req);
 | 
					    const accountId = await getAccountIdForRequest(req);
 | 
				
			||||||
    const requiredFields = new Set();
 | 
					    const requiredFields = new Set<keyof TInventoryDatabaseDocument>();
 | 
				
			||||||
    if (payload.SellCurrency == "SC_RegularCredits") {
 | 
					    if (payload.SellCurrency == "SC_RegularCredits") {
 | 
				
			||||||
        requiredFields.add("RegularCredits");
 | 
					        requiredFields.add("RegularCredits");
 | 
				
			||||||
    } else if (payload.SellCurrency == "SC_FusionPoints") {
 | 
					    } else if (payload.SellCurrency == "SC_FusionPoints") {
 | 
				
			||||||
@ -25,7 +27,7 @@ export const sellController: RequestHandler = async (req, res) => {
 | 
				
			|||||||
        requiredFields.add("MiscItems");
 | 
					        requiredFields.add("MiscItems");
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    for (const key of Object.keys(payload.Items)) {
 | 
					    for (const key of Object.keys(payload.Items)) {
 | 
				
			||||||
        requiredFields.add(key);
 | 
					        requiredFields.add(key as keyof TInventoryDatabaseDocument);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    if (requiredFields.has("Upgrades")) {
 | 
					    if (requiredFields.has("Upgrades")) {
 | 
				
			||||||
        requiredFields.add("RawUpgrades");
 | 
					        requiredFields.add("RawUpgrades");
 | 
				
			||||||
@ -51,8 +53,15 @@ export const sellController: RequestHandler = async (req, res) => {
 | 
				
			|||||||
    if (payload.Items.Hoverboards) {
 | 
					    if (payload.Items.Hoverboards) {
 | 
				
			||||||
        requiredFields.add(InventorySlot.SPACESUITS);
 | 
					        requiredFields.add(InventorySlot.SPACESUITS);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    if (payload.Items.CrewShipWeapons) {
 | 
					    if (payload.Items.CrewShipWeapons || payload.Items.CrewShipWeaponSkins) {
 | 
				
			||||||
        requiredFields.add(InventorySlot.RJ_COMPONENT_AND_ARMAMENTS);
 | 
					        requiredFields.add(InventorySlot.RJ_COMPONENT_AND_ARMAMENTS);
 | 
				
			||||||
 | 
					        requiredFields.add("CrewShipRawSalvage");
 | 
				
			||||||
 | 
					        if (payload.Items.CrewShipWeapons) {
 | 
				
			||||||
 | 
					            requiredFields.add("CrewShipSalvagedWeapons");
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        if (payload.Items.CrewShipWeaponSkins) {
 | 
				
			||||||
 | 
					            requiredFields.add("CrewShipSalvagedWeaponSkins");
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    const inventory = await getInventory(accountId, Array.from(requiredFields).join(" "));
 | 
					    const inventory = await getInventory(accountId, Array.from(requiredFields).join(" "));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -76,7 +85,7 @@ export const sellController: RequestHandler = async (req, res) => {
 | 
				
			|||||||
            }
 | 
					            }
 | 
				
			||||||
        ]);
 | 
					        ]);
 | 
				
			||||||
    } else if (payload.SellCurrency == "SC_Resources") {
 | 
					    } else if (payload.SellCurrency == "SC_Resources") {
 | 
				
			||||||
        // Will add appropriate MiscItems from CrewShipWeapons
 | 
					        // Will add appropriate MiscItems from CrewShipWeapons or CrewShipWeaponSkins
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
        throw new Error("Unknown SellCurrency: " + payload.SellCurrency);
 | 
					        throw new Error("Unknown SellCurrency: " + payload.SellCurrency);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -157,19 +166,51 @@ export const sellController: RequestHandler = async (req, res) => {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
    if (payload.Items.CrewShipWeapons) {
 | 
					    if (payload.Items.CrewShipWeapons) {
 | 
				
			||||||
        payload.Items.CrewShipWeapons.forEach(sellItem => {
 | 
					        payload.Items.CrewShipWeapons.forEach(sellItem => {
 | 
				
			||||||
            const index = inventory.CrewShipWeapons.findIndex(x => x._id.equals(sellItem.String));
 | 
					            if (sellItem.String[0] == "/") {
 | 
				
			||||||
            if (index != -1) {
 | 
					                addCrewShipRawSalvage(inventory, [
 | 
				
			||||||
                const itemType = inventory.CrewShipWeapons[index].ItemType;
 | 
					                    {
 | 
				
			||||||
                const recipe = Object.values(ExportDojoRecipes.fabrications).find(x => x.resultType == itemType)!;
 | 
					                        ItemType: sellItem.String,
 | 
				
			||||||
                const miscItemChanges = recipe.ingredients.map(x => ({
 | 
					                        ItemCount: sellItem.Count * -1
 | 
				
			||||||
                    ItemType: x.ItemType,
 | 
					                    }
 | 
				
			||||||
                    ItemCount: Math.trunc(x.ItemCount * 0.8)
 | 
					                ]);
 | 
				
			||||||
                }));
 | 
					            } else {
 | 
				
			||||||
                addMiscItems(inventory, miscItemChanges);
 | 
					                const index = inventory.CrewShipWeapons.findIndex(x => x._id.equals(sellItem.String));
 | 
				
			||||||
                combineInventoryChanges(inventoryChanges, { MiscItems: miscItemChanges });
 | 
					                if (index != -1) {
 | 
				
			||||||
 | 
					                    if (payload.SellCurrency == "SC_Resources") {
 | 
				
			||||||
                inventory.CrewShipWeapons.splice(index, 1);
 | 
					                        refundPartialBuildCosts(inventory, inventory.CrewShipWeapons[index].ItemType, inventoryChanges);
 | 
				
			||||||
                freeUpSlot(inventory, InventorySlot.RJ_COMPONENT_AND_ARMAMENTS);
 | 
					                    }
 | 
				
			||||||
 | 
					                    inventory.CrewShipWeapons.splice(index, 1);
 | 
				
			||||||
 | 
					                    freeUpSlot(inventory, InventorySlot.RJ_COMPONENT_AND_ARMAMENTS);
 | 
				
			||||||
 | 
					                } else {
 | 
				
			||||||
 | 
					                    inventory.CrewShipSalvagedWeapons.pull({ _id: sellItem.String });
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (payload.Items.CrewShipWeaponSkins) {
 | 
				
			||||||
 | 
					        payload.Items.CrewShipWeaponSkins.forEach(sellItem => {
 | 
				
			||||||
 | 
					            if (sellItem.String[0] == "/") {
 | 
				
			||||||
 | 
					                addCrewShipRawSalvage(inventory, [
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        ItemType: sellItem.String,
 | 
				
			||||||
 | 
					                        ItemCount: sellItem.Count * -1
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                ]);
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                const index = inventory.CrewShipWeaponSkins.findIndex(x => x._id.equals(sellItem.String));
 | 
				
			||||||
 | 
					                if (index != -1) {
 | 
				
			||||||
 | 
					                    if (payload.SellCurrency == "SC_Resources") {
 | 
				
			||||||
 | 
					                        refundPartialBuildCosts(
 | 
				
			||||||
 | 
					                            inventory,
 | 
				
			||||||
 | 
					                            inventory.CrewShipWeaponSkins[index].ItemType,
 | 
				
			||||||
 | 
					                            inventoryChanges
 | 
				
			||||||
 | 
					                        );
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    inventory.CrewShipWeaponSkins.splice(index, 1);
 | 
				
			||||||
 | 
					                    freeUpSlot(inventory, InventorySlot.RJ_COMPONENT_AND_ARMAMENTS);
 | 
				
			||||||
 | 
					                } else {
 | 
				
			||||||
 | 
					                    inventory.CrewShipSalvagedWeaponSkins.pull({ _id: sellItem.String });
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -243,6 +284,7 @@ interface ISellRequest {
 | 
				
			|||||||
        Hoverboards?: ISellItem[];
 | 
					        Hoverboards?: ISellItem[];
 | 
				
			||||||
        Drones?: ISellItem[];
 | 
					        Drones?: ISellItem[];
 | 
				
			||||||
        CrewShipWeapons?: ISellItem[];
 | 
					        CrewShipWeapons?: ISellItem[];
 | 
				
			||||||
 | 
					        CrewShipWeaponSkins?: ISellItem[];
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
    SellPrice: number;
 | 
					    SellPrice: number;
 | 
				
			||||||
    SellCurrency:
 | 
					    SellCurrency:
 | 
				
			||||||
@ -259,3 +301,33 @@ interface ISellItem {
 | 
				
			|||||||
    String: string; // oid or uniqueName
 | 
					    String: string; // oid or uniqueName
 | 
				
			||||||
    Count: number;
 | 
					    Count: number;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const refundPartialBuildCosts = (
 | 
				
			||||||
 | 
					    inventory: TInventoryDatabaseDocument,
 | 
				
			||||||
 | 
					    itemType: string,
 | 
				
			||||||
 | 
					    inventoryChanges: IInventoryChanges
 | 
				
			||||||
 | 
					): void => {
 | 
				
			||||||
 | 
					    // House versions
 | 
				
			||||||
 | 
					    const research = Object.values(ExportDojoRecipes.research).find(x => x.resultType == itemType);
 | 
				
			||||||
 | 
					    if (research) {
 | 
				
			||||||
 | 
					        const miscItemChanges = research.ingredients.map(x => ({
 | 
				
			||||||
 | 
					            ItemType: x.ItemType,
 | 
				
			||||||
 | 
					            ItemCount: Math.trunc(x.ItemCount * 0.8)
 | 
				
			||||||
 | 
					        }));
 | 
				
			||||||
 | 
					        addMiscItems(inventory, miscItemChanges);
 | 
				
			||||||
 | 
					        combineInventoryChanges(inventoryChanges, { MiscItems: miscItemChanges });
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Sigma versions
 | 
				
			||||||
 | 
					    const recipe = Object.values(ExportDojoRecipes.fabrications).find(x => x.resultType == itemType);
 | 
				
			||||||
 | 
					    if (recipe) {
 | 
				
			||||||
 | 
					        const miscItemChanges = recipe.ingredients.map(x => ({
 | 
				
			||||||
 | 
					            ItemType: x.ItemType,
 | 
				
			||||||
 | 
					            ItemCount: Math.trunc(x.ItemCount * 0.8)
 | 
				
			||||||
 | 
					        }));
 | 
				
			||||||
 | 
					        addMiscItems(inventory, miscItemChanges);
 | 
				
			||||||
 | 
					        combineInventoryChanges(inventoryChanges, { MiscItems: miscItemChanges });
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
				
			|||||||
@ -51,7 +51,7 @@ export const syndicateSacrificeController: RequestHandler = async (request, resp
 | 
				
			|||||||
    syndicate.Title ??= 0;
 | 
					    syndicate.Title ??= 0;
 | 
				
			||||||
    syndicate.Title += 1;
 | 
					    syndicate.Title += 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (syndicate.Title > 0 && manifest.favours.length != 0) {
 | 
					    if (syndicate.Title > 0 && manifest.favours.find(x => x.rankUpReward && x.requiredLevel == syndicate.Title)) {
 | 
				
			||||||
        syndicate.FreeFavorsEarned ??= [];
 | 
					        syndicate.FreeFavorsEarned ??= [];
 | 
				
			||||||
        if (!syndicate.FreeFavorsEarned.includes(syndicate.Title)) {
 | 
					        if (!syndicate.FreeFavorsEarned.includes(syndicate.Title)) {
 | 
				
			||||||
            syndicate.FreeFavorsEarned.push(syndicate.Title);
 | 
					            syndicate.FreeFavorsEarned.push(syndicate.Title);
 | 
				
			||||||
 | 
				
			|||||||
@ -86,7 +86,9 @@ import {
 | 
				
			|||||||
    IWeeklyMission,
 | 
					    IWeeklyMission,
 | 
				
			||||||
    ILockedWeaponGroupDatabase,
 | 
					    ILockedWeaponGroupDatabase,
 | 
				
			||||||
    IPersonalTechProjectDatabase,
 | 
					    IPersonalTechProjectDatabase,
 | 
				
			||||||
    IPersonalTechProjectClient
 | 
					    IPersonalTechProjectClient,
 | 
				
			||||||
 | 
					    ILastSortieRewardDatabase,
 | 
				
			||||||
 | 
					    ILastSortieRewardClient
 | 
				
			||||||
} from "../../types/inventoryTypes/inventoryTypes";
 | 
					} from "../../types/inventoryTypes/inventoryTypes";
 | 
				
			||||||
import { IOid } from "../../types/commonTypes";
 | 
					import { IOid } from "../../types/commonTypes";
 | 
				
			||||||
import {
 | 
					import {
 | 
				
			||||||
@ -1202,6 +1204,28 @@ const alignmentSchema = new Schema<IAlignment>(
 | 
				
			|||||||
    { _id: false }
 | 
					    { _id: false }
 | 
				
			||||||
);
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const lastSortieRewardSchema = new Schema<ILastSortieRewardDatabase>(
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        SortieId: Schema.Types.ObjectId,
 | 
				
			||||||
 | 
					        StoreItem: String,
 | 
				
			||||||
 | 
					        Manifest: String
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    { _id: false }
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					lastSortieRewardSchema.set("toJSON", {
 | 
				
			||||||
 | 
					    virtuals: true,
 | 
				
			||||||
 | 
					    transform(_doc, obj) {
 | 
				
			||||||
 | 
					        const db = obj as ILastSortieRewardDatabase;
 | 
				
			||||||
 | 
					        const client = obj as ILastSortieRewardClient;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        client.SortieId = toOid(db.SortieId);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        delete obj._id;
 | 
				
			||||||
 | 
					        delete obj.__v;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const lockedWeaponGroupSchema = new Schema<ILockedWeaponGroupDatabase>(
 | 
					const lockedWeaponGroupSchema = new Schema<ILockedWeaponGroupDatabase>(
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        s: Schema.Types.ObjectId,
 | 
					        s: Schema.Types.ObjectId,
 | 
				
			||||||
@ -1419,7 +1443,8 @@ const inventorySchema = new Schema<IInventoryDatabase, InventoryDocumentProps>(
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        //https://warframe.fandom.com/wiki/Sortie
 | 
					        //https://warframe.fandom.com/wiki/Sortie
 | 
				
			||||||
        CompletedSorties: [String],
 | 
					        CompletedSorties: [String],
 | 
				
			||||||
        LastSortieReward: [Schema.Types.Mixed],
 | 
					        LastSortieReward: { type: [lastSortieRewardSchema], default: undefined },
 | 
				
			||||||
 | 
					        LastLiteSortieReward: { type: [lastSortieRewardSchema], default: undefined },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Resource Extractor Drones
 | 
					        // Resource Extractor Drones
 | 
				
			||||||
        Drones: [droneSchema],
 | 
					        Drones: [droneSchema],
 | 
				
			||||||
 | 
				
			|||||||
@ -39,6 +39,7 @@ interface IConfig {
 | 
				
			|||||||
    noArgonCrystalDecay?: boolean;
 | 
					    noArgonCrystalDecay?: boolean;
 | 
				
			||||||
    noMasteryRankUpCooldown?: boolean;
 | 
					    noMasteryRankUpCooldown?: boolean;
 | 
				
			||||||
    noVendorPurchaseLimits?: boolean;
 | 
					    noVendorPurchaseLimits?: boolean;
 | 
				
			||||||
 | 
					    noDeathMarks?: boolean;
 | 
				
			||||||
    noKimCooldowns?: boolean;
 | 
					    noKimCooldowns?: boolean;
 | 
				
			||||||
    instantResourceExtractorDrones?: boolean;
 | 
					    instantResourceExtractorDrones?: boolean;
 | 
				
			||||||
    noResourceExtractorDronesDamage?: boolean;
 | 
					    noResourceExtractorDronesDamage?: boolean;
 | 
				
			||||||
 | 
				
			|||||||
@ -1083,7 +1083,7 @@ export const addEquipment = (
 | 
				
			|||||||
            Configs: [],
 | 
					            Configs: [],
 | 
				
			||||||
            XP: 0,
 | 
					            XP: 0,
 | 
				
			||||||
            ModularParts: modularParts,
 | 
					            ModularParts: modularParts,
 | 
				
			||||||
            IsNew: category != "CrewShipWeapons" ? true : undefined
 | 
					            IsNew: category != "CrewShipWeapons" && category != "CrewShipSalvagedWeapons" ? true : undefined
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        defaultOverwrites
 | 
					        defaultOverwrites
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
 | 
				
			|||||||
@ -54,6 +54,7 @@ import { getInfNodes } from "@/src/helpers/nemesisHelpers";
 | 
				
			|||||||
import { Loadout } from "../models/inventoryModels/loadoutModel";
 | 
					import { Loadout } from "../models/inventoryModels/loadoutModel";
 | 
				
			||||||
import { ILoadoutConfigDatabase } from "../types/saveLoadoutTypes";
 | 
					import { ILoadoutConfigDatabase } from "../types/saveLoadoutTypes";
 | 
				
			||||||
import { getWorldState } from "./worldStateService";
 | 
					import { getWorldState } from "./worldStateService";
 | 
				
			||||||
 | 
					import { config } from "./configService";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const getRotations = (rewardInfo: IRewardInfo, tierOverride?: number): number[] => {
 | 
					const getRotations = (rewardInfo: IRewardInfo, tierOverride?: number): number[] => {
 | 
				
			||||||
    // For Spy missions, e.g. 3 vaults cracked = A, B, C
 | 
					    // For Spy missions, e.g. 3 vaults cracked = A, B, C
 | 
				
			||||||
@ -418,22 +419,24 @@ export const addMissionInventoryUpdates = async (
 | 
				
			|||||||
                break;
 | 
					                break;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            case "DeathMarks": {
 | 
					            case "DeathMarks": {
 | 
				
			||||||
                for (const bossName of value) {
 | 
					                if (!config.noDeathMarks) {
 | 
				
			||||||
                    if (inventory.DeathMarks.indexOf(bossName) == -1) {
 | 
					                    for (const bossName of value) {
 | 
				
			||||||
                        // It's a new death mark; we have to say the line.
 | 
					                        if (inventory.DeathMarks.indexOf(bossName) == -1) {
 | 
				
			||||||
                        await createMessage(inventory.accountOwnerId, [
 | 
					                            // It's a new death mark; we have to say the line.
 | 
				
			||||||
                            {
 | 
					                            await createMessage(inventory.accountOwnerId, [
 | 
				
			||||||
                                sub: bossName,
 | 
					                                {
 | 
				
			||||||
                                sndr: "/Lotus/Language/G1Quests/DeathMarkSender",
 | 
					                                    sub: bossName,
 | 
				
			||||||
                                msg: "/Lotus/Language/G1Quests/DeathMarkMessage",
 | 
					                                    sndr: "/Lotus/Language/G1Quests/DeathMarkSender",
 | 
				
			||||||
                                icon: "/Lotus/Interface/Icons/Npcs/Stalker_d.png",
 | 
					                                    msg: "/Lotus/Language/G1Quests/DeathMarkMessage",
 | 
				
			||||||
                                highPriority: true,
 | 
					                                    icon: "/Lotus/Interface/Icons/Npcs/Stalker_d.png",
 | 
				
			||||||
                                expiry: new Date(Date.now() + 86400_000) // TOVERIFY: This type of inbox message seems to automatically delete itself. We'll just delete it after 24 hours, but it's clear if this is correct.
 | 
					                                    highPriority: true,
 | 
				
			||||||
                            }
 | 
					                                    expiry: new Date(Date.now() + 86400_000) // TOVERIFY: This type of inbox message seems to automatically delete itself. We'll just delete it after 24 hours, but it's clear if this is correct.
 | 
				
			||||||
                        ]);
 | 
					                                }
 | 
				
			||||||
 | 
					                            ]);
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
 | 
					                    inventory.DeathMarks = value;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                inventory.DeathMarks = value;
 | 
					 | 
				
			||||||
                break;
 | 
					                break;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            case "CapturedAnimals": {
 | 
					            case "CapturedAnimals": {
 | 
				
			||||||
@ -581,6 +584,16 @@ export const addMissionRewards = async (
 | 
				
			|||||||
    const AffiliationMods: IAffiliationMods[] = [];
 | 
					    const AffiliationMods: IAffiliationMods[] = [];
 | 
				
			||||||
    let SyndicateXPItemReward;
 | 
					    let SyndicateXPItemReward;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (rewardInfo.sortieTag == "Final") {
 | 
				
			||||||
 | 
					        inventory.LastSortieReward = [
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                SortieId: new Types.ObjectId(rewardInfo.sortieId!.split("_")[1]),
 | 
				
			||||||
 | 
					                StoreItem: MissionRewards[0].StoreItem,
 | 
				
			||||||
 | 
					                Manifest: "/Lotus/Types/Game/MissionDecks/SortieRewards"
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        ];
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let missionCompletionCredits = 0;
 | 
					    let missionCompletionCredits = 0;
 | 
				
			||||||
    //inventory change is what the client has not rewarded itself, also the client needs to know the credit changes for display
 | 
					    //inventory change is what the client has not rewarded itself, also the client needs to know the credit changes for display
 | 
				
			||||||
    if (levelKeyName) {
 | 
					    if (levelKeyName) {
 | 
				
			||||||
@ -940,6 +953,10 @@ function getLevelCreditRewards(node: IRegion): number {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
function getRandomMissionDrops(RewardInfo: IRewardInfo, tierOverride: number | undefined): IMissionReward[] {
 | 
					function getRandomMissionDrops(RewardInfo: IRewardInfo, tierOverride: number | undefined): IMissionReward[] {
 | 
				
			||||||
    const drops: IMissionReward[] = [];
 | 
					    const drops: IMissionReward[] = [];
 | 
				
			||||||
 | 
					    if (RewardInfo.sortieTag == "Final") {
 | 
				
			||||||
 | 
					        const drop = getRandomRewardByChance(ExportRewards["/Lotus/Types/Game/MissionDecks/SortieRewards"][0])!;
 | 
				
			||||||
 | 
					        drops.push({ StoreItem: drop.type, ItemCount: drop.itemCount });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    if (RewardInfo.periodicMissionTag?.startsWith("HardDaily")) {
 | 
					    if (RewardInfo.periodicMissionTag?.startsWith("HardDaily")) {
 | 
				
			||||||
        drops.push({
 | 
					        drops.push({
 | 
				
			||||||
            StoreItem: "/Lotus/StoreItems/Types/Items/MiscItems/SteelEssence",
 | 
					            StoreItem: "/Lotus/StoreItems/Types/Items/MiscItems/SteelEssence",
 | 
				
			||||||
 | 
				
			|||||||
@ -1,14 +1,10 @@
 | 
				
			|||||||
import staticWorldState from "@/static/fixed_responses/worldState/worldState.json";
 | 
					import staticWorldState from "@/static/fixed_responses/worldState/worldState.json";
 | 
				
			||||||
import static1999FallDays from "@/static/fixed_responses/worldState/1999_fall_days.json";
 | 
					 | 
				
			||||||
import static1999SpringDays from "@/static/fixed_responses/worldState/1999_spring_days.json";
 | 
					 | 
				
			||||||
import static1999SummerDays from "@/static/fixed_responses/worldState/1999_summer_days.json";
 | 
					 | 
				
			||||||
import static1999WinterDays from "@/static/fixed_responses/worldState/1999_winter_days.json";
 | 
					 | 
				
			||||||
import { buildConfig } from "@/src/services/buildConfigService";
 | 
					import { buildConfig } from "@/src/services/buildConfigService";
 | 
				
			||||||
import { unixTimesInMs } from "@/src/constants/timeConstants";
 | 
					import { unixTimesInMs } from "@/src/constants/timeConstants";
 | 
				
			||||||
import { config } from "@/src/services/configService";
 | 
					import { config } from "@/src/services/configService";
 | 
				
			||||||
import { CRng } from "@/src/services/rngService";
 | 
					import { CRng } from "@/src/services/rngService";
 | 
				
			||||||
import { eMissionType, ExportNightwave, ExportRegions } from "warframe-public-export-plus";
 | 
					import { eMissionType, ExportNightwave, ExportRegions } from "warframe-public-export-plus";
 | 
				
			||||||
import { ISeasonChallenge, ISortie, IWorldState } from "../types/worldStateTypes";
 | 
					import { ICalendarDay, ICalendarSeason, ISeasonChallenge, ISortie, IWorldState } from "../types/worldStateTypes";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const sortieBosses = [
 | 
					const sortieBosses = [
 | 
				
			||||||
    "SORTIE_BOSS_HYENA",
 | 
					    "SORTIE_BOSS_HYENA",
 | 
				
			||||||
@ -352,6 +348,209 @@ const getSeasonWeeklyHardChallenge = (week: number, id: number): ISeasonChalleng
 | 
				
			|||||||
    };
 | 
					    };
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const birthdays: number[] = [
 | 
				
			||||||
 | 
					    1, // Kaya
 | 
				
			||||||
 | 
					    45, // Lettie
 | 
				
			||||||
 | 
					    74, // Minerva (MinervaVelemirDialogue_rom.dialogue)
 | 
				
			||||||
 | 
					    143, // Amir
 | 
				
			||||||
 | 
					    166, // Flare
 | 
				
			||||||
 | 
					    191, // Aoi
 | 
				
			||||||
 | 
					    306, // Eleanor
 | 
				
			||||||
 | 
					    307, // Arthur
 | 
				
			||||||
 | 
					    338, // Quincy
 | 
				
			||||||
 | 
					    355 // Velimir (MinervaVelemirDialogue_rom.dialogue)
 | 
				
			||||||
 | 
					];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const getCalendarSeason = (week: number): ICalendarSeason => {
 | 
				
			||||||
 | 
					    const seasonIndex = week % 4;
 | 
				
			||||||
 | 
					    const seasonDay1 = seasonIndex * 90 + 1;
 | 
				
			||||||
 | 
					    const seasonDay91 = seasonIndex * 90 + 91;
 | 
				
			||||||
 | 
					    const eventDays: ICalendarDay[] = [];
 | 
				
			||||||
 | 
					    for (const day of birthdays) {
 | 
				
			||||||
 | 
					        if (day < seasonDay1) {
 | 
				
			||||||
 | 
					            continue;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        if (day >= seasonDay91) {
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        //logger.debug(`birthday on day ${day}`);
 | 
				
			||||||
 | 
					        eventDays.push({ day, events: [] }); // This is how CET_PLOT looks in worldState as of around 38.5.0
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    const rng = new CRng(week);
 | 
				
			||||||
 | 
					    const challenges = [
 | 
				
			||||||
 | 
					        "/Lotus/Types/Challenges/Calendar1999/CalendarKillEnemiesEasy",
 | 
				
			||||||
 | 
					        "/Lotus/Types/Challenges/Calendar1999/CalendarKillEnemiesMedium",
 | 
				
			||||||
 | 
					        "/Lotus/Types/Challenges/Calendar1999/CalendarKillEnemiesHard",
 | 
				
			||||||
 | 
					        "/Lotus/Types/Challenges/Calendar1999/CalendarKillEnemiesWithMeleeEasy",
 | 
				
			||||||
 | 
					        "/Lotus/Types/Challenges/Calendar1999/CalendarKillEnemiesWithMeleeMedium",
 | 
				
			||||||
 | 
					        "/Lotus/Types/Challenges/Calendar1999/CalendarKillEnemiesWithMeleeHard",
 | 
				
			||||||
 | 
					        "/Lotus/Types/Challenges/Calendar1999/CalendarKillEnemiesWithAbilitiesEasy",
 | 
				
			||||||
 | 
					        "/Lotus/Types/Challenges/Calendar1999/CalendarKillEnemiesWithAbilitiesMedium",
 | 
				
			||||||
 | 
					        "/Lotus/Types/Challenges/Calendar1999/CalendarKillEnemiesWithAbilitiesHard",
 | 
				
			||||||
 | 
					        "/Lotus/Types/Challenges/Calendar1999/CalendarDestroyPropsEasy",
 | 
				
			||||||
 | 
					        "/Lotus/Types/Challenges/Calendar1999/CalendarDestroyPropsMedium",
 | 
				
			||||||
 | 
					        "/Lotus/Types/Challenges/Calendar1999/CalendarDestroyPropsHard",
 | 
				
			||||||
 | 
					        "/Lotus/Types/Challenges/Calendar1999/CalendarKillEximusEasy",
 | 
				
			||||||
 | 
					        "/Lotus/Types/Challenges/Calendar1999/CalendarKillEximusMedium",
 | 
				
			||||||
 | 
					        "/Lotus/Types/Challenges/Calendar1999/CalendarKillEximusHard",
 | 
				
			||||||
 | 
					        "/Lotus/Types/Challenges/Calendar1999/CalendarKillScaldraEnemiesEasy",
 | 
				
			||||||
 | 
					        "/Lotus/Types/Challenges/Calendar1999/CalendarKillScaldraEnemiesMedium",
 | 
				
			||||||
 | 
					        "/Lotus/Types/Challenges/Calendar1999/CalendarKillScaldraEnemiesHard",
 | 
				
			||||||
 | 
					        "/Lotus/Types/Challenges/Calendar1999/CalendarKillScaldraEnemiesWithAbilitiesEasy",
 | 
				
			||||||
 | 
					        "/Lotus/Types/Challenges/Calendar1999/CalendarKillScaldraEnemiesWithAbilitiesMedium",
 | 
				
			||||||
 | 
					        "/Lotus/Types/Challenges/Calendar1999/CalendarKillScaldraEnemiesWithAbilitiesHard",
 | 
				
			||||||
 | 
					        "/Lotus/Types/Challenges/Calendar1999/CalendarKillTankHard",
 | 
				
			||||||
 | 
					        "/Lotus/Types/Challenges/Calendar1999/CalendarKillScaldraEnemiesWithMeleeEasy",
 | 
				
			||||||
 | 
					        "/Lotus/Types/Challenges/Calendar1999/CalendarKillScaldraEnemiesWithMeleeMedium",
 | 
				
			||||||
 | 
					        "/Lotus/Types/Challenges/Calendar1999/CalendarKillScaldraEnemiesWithMeleeHard",
 | 
				
			||||||
 | 
					        "/Lotus/Types/Challenges/Calendar1999/CalendarKillTechrotEnemiesEasy",
 | 
				
			||||||
 | 
					        "/Lotus/Types/Challenges/Calendar1999/CalendarKillTechrotEnemiesMedium",
 | 
				
			||||||
 | 
					        "/Lotus/Types/Challenges/Calendar1999/CalendarKillTechrotEnemiesHard",
 | 
				
			||||||
 | 
					        "/Lotus/Types/Challenges/Calendar1999/CalendarKillTechrotEnemiesWithAbilitiesEasy",
 | 
				
			||||||
 | 
					        "/Lotus/Types/Challenges/Calendar1999/CalendarKillTechrotEnemiesWithAbilitiesMedium",
 | 
				
			||||||
 | 
					        "/Lotus/Types/Challenges/Calendar1999/CalendarKillTechrotEnemiesWithAbilitiesHard",
 | 
				
			||||||
 | 
					        "/Lotus/Types/Challenges/Calendar1999/CalendarKillTechrotEnemiesWithMeleeEasy",
 | 
				
			||||||
 | 
					        "/Lotus/Types/Challenges/Calendar1999/CalendarKillTechrotEnemiesWithMeleeMedium",
 | 
				
			||||||
 | 
					        "/Lotus/Types/Challenges/Calendar1999/CalendarKillTechrotEnemiesWithMeleeHard"
 | 
				
			||||||
 | 
					    ];
 | 
				
			||||||
 | 
					    const rewardRanges: number[] = [];
 | 
				
			||||||
 | 
					    const upgradeRanges: number[] = [];
 | 
				
			||||||
 | 
					    for (let i = 0; i != 6; ++i) {
 | 
				
			||||||
 | 
					        const chunkDay1 = seasonDay1 + i * 15;
 | 
				
			||||||
 | 
					        const chunkDay13 = chunkDay1 - 1 + 13;
 | 
				
			||||||
 | 
					        let challengeDay: number;
 | 
				
			||||||
 | 
					        do {
 | 
				
			||||||
 | 
					            challengeDay = rng.randomInt(chunkDay1, chunkDay13);
 | 
				
			||||||
 | 
					        } while (birthdays.indexOf(challengeDay) != -1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        const challengeIndex = rng.randomInt(0, challenges.length - 1);
 | 
				
			||||||
 | 
					        const challenge = challenges[challengeIndex];
 | 
				
			||||||
 | 
					        challenges.splice(challengeIndex, 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        //logger.debug(`challenge on day ${challengeDay}`);
 | 
				
			||||||
 | 
					        eventDays.push({
 | 
				
			||||||
 | 
					            day: challengeDay,
 | 
				
			||||||
 | 
					            events: [{ type: "CET_CHALLENGE", challenge }]
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        rewardRanges.push(challengeDay);
 | 
				
			||||||
 | 
					        if (i == 0 || i == 3 || i == 5) {
 | 
				
			||||||
 | 
					            upgradeRanges.push(challengeDay);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    rewardRanges.push(seasonDay91);
 | 
				
			||||||
 | 
					    upgradeRanges.push(seasonDay91);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const rewards = [
 | 
				
			||||||
 | 
					        "/Lotus/StoreItems/Types/Items/MiscItems/UtilityUnlocker",
 | 
				
			||||||
 | 
					        "/Lotus/StoreItems/Types/Recipes/Components/FormaAuraBlueprint",
 | 
				
			||||||
 | 
					        "/Lotus/StoreItems/Types/Recipes/Components/FormaBlueprint",
 | 
				
			||||||
 | 
					        "/Lotus/StoreItems/Types/Recipes/Components/WeaponUtilityUnlockerBlueprint",
 | 
				
			||||||
 | 
					        "/Lotus/StoreItems/Types/Items/MiscItems/WeaponMeleeArcaneUnlocker",
 | 
				
			||||||
 | 
					        "/Lotus/StoreItems/Types/Items/MiscItems/WeaponSecondaryArcaneUnlocker",
 | 
				
			||||||
 | 
					        "/Lotus/StoreItems/Types/Items/MiscItems/WeaponPrimaryArcaneUnlocker",
 | 
				
			||||||
 | 
					        "/Lotus/StoreItems/Upgrades/Mods/FusionBundles/CircuitSilverSteelPathFusionBundle",
 | 
				
			||||||
 | 
					        "/Lotus/StoreItems/Types/BoosterPacks/CalendarRivenPack",
 | 
				
			||||||
 | 
					        "/Lotus/Types/StoreItems/Packages/Calendar/CalendarKuvaBundleSmall",
 | 
				
			||||||
 | 
					        "/Lotus/Types/StoreItems/Packages/Calendar/CalendarKuvaBundleLarge",
 | 
				
			||||||
 | 
					        "/Lotus/StoreItems/Types/BoosterPacks/CalendarArtifactPack",
 | 
				
			||||||
 | 
					        "/Lotus/StoreItems/Types/BoosterPacks/CalendarMajorArtifactPack",
 | 
				
			||||||
 | 
					        "/Lotus/Types/StoreItems/Boosters/AffinityBooster3DayStoreItem",
 | 
				
			||||||
 | 
					        "/Lotus/Types/StoreItems/Boosters/ModDropChanceBooster3DayStoreItem",
 | 
				
			||||||
 | 
					        "/Lotus/Types/StoreItems/Boosters/ResourceDropChance3DayStoreItem",
 | 
				
			||||||
 | 
					        "/Lotus/StoreItems/Types/Items/MiscItems/Forma",
 | 
				
			||||||
 | 
					        "/Lotus/StoreItems/Types/Recipes/Components/OrokinCatalystBlueprint",
 | 
				
			||||||
 | 
					        "/Lotus/StoreItems/Types/Recipes/Components/OrokinReactorBlueprint",
 | 
				
			||||||
 | 
					        "/Lotus/StoreItems/Types/Items/MiscItems/WeaponUtilityUnlocker",
 | 
				
			||||||
 | 
					        "/Lotus/Types/StoreItems/Packages/Calendar/CalendarVosforPack",
 | 
				
			||||||
 | 
					        "/Lotus/StoreItems/Types/Gameplay/NarmerSorties/ArchonCrystalOrange",
 | 
				
			||||||
 | 
					        "/Lotus/StoreItems/Types/Gameplay/NarmerSorties/ArchonCrystalNira",
 | 
				
			||||||
 | 
					        "/Lotus/StoreItems/Types/Gameplay/NarmerSorties/ArchonCrystalGreen",
 | 
				
			||||||
 | 
					        "/Lotus/StoreItems/Types/Gameplay/NarmerSorties/ArchonCrystalBoreal",
 | 
				
			||||||
 | 
					        "/Lotus/StoreItems/Types/Gameplay/NarmerSorties/ArchonCrystalAmar",
 | 
				
			||||||
 | 
					        "/Lotus/StoreItems/Types/Gameplay/NarmerSorties/ArchonCrystalViolet"
 | 
				
			||||||
 | 
					    ];
 | 
				
			||||||
 | 
					    for (let i = 0; i != rewardRanges.length - 1; ++i) {
 | 
				
			||||||
 | 
					        const rewardIndex = rng.randomInt(0, rewards.length - 1);
 | 
				
			||||||
 | 
					        const reward = rewards[rewardIndex];
 | 
				
			||||||
 | 
					        rewards.splice(rewardIndex, 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        //logger.debug(`trying to fit a reward between day ${rewardRanges[i]} and ${rewardRanges[i + 1]}`);
 | 
				
			||||||
 | 
					        let day: number;
 | 
				
			||||||
 | 
					        do {
 | 
				
			||||||
 | 
					            day = rng.randomInt(rewardRanges[i] + 1, rewardRanges[i + 1] - 1);
 | 
				
			||||||
 | 
					        } while (eventDays.find(x => x.day == day));
 | 
				
			||||||
 | 
					        eventDays.push({ day, events: [{ type: "CET_REWARD", reward }] });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const upgrades = [
 | 
				
			||||||
 | 
					        "/Lotus/Upgrades/Calendar/MeleeCritChance",
 | 
				
			||||||
 | 
					        "/Lotus/Upgrades/Calendar/MeleeAttackSpeed",
 | 
				
			||||||
 | 
					        "/Lotus/Upgrades/Calendar/EnergyOrbToAbilityRange",
 | 
				
			||||||
 | 
					        "/Lotus/Upgrades/Calendar/AbilityStrength",
 | 
				
			||||||
 | 
					        "/Lotus/Upgrades/Calendar/Armor",
 | 
				
			||||||
 | 
					        "/Lotus/Upgrades/Calendar/RadiationProcOnTakeDamage",
 | 
				
			||||||
 | 
					        "/Lotus/Upgrades/Calendar/CompanionDamage",
 | 
				
			||||||
 | 
					        "/Lotus/Upgrades/Calendar/GasChanceToPrimaryAndSecondary",
 | 
				
			||||||
 | 
					        "/Lotus/Upgrades/Calendar/MagazineCapacity",
 | 
				
			||||||
 | 
					        "/Lotus/Upgrades/Calendar/PunchToPrimary",
 | 
				
			||||||
 | 
					        "/Lotus/Upgrades/Calendar/HealingEffects",
 | 
				
			||||||
 | 
					        "/Lotus/Upgrades/Calendar/EnergyRestoration",
 | 
				
			||||||
 | 
					        "/Lotus/Upgrades/Calendar/OvershieldCap",
 | 
				
			||||||
 | 
					        "/Lotus/Upgrades/Calendar/ElectricStatusDamageAndChance",
 | 
				
			||||||
 | 
					        "/Lotus/Upgrades/Calendar/FinisherChancePerComboMultiplier",
 | 
				
			||||||
 | 
					        "/Lotus/Upgrades/Calendar/MagnetStatusPull",
 | 
				
			||||||
 | 
					        "/Lotus/Upgrades/Calendar/CompanionsBuffNearbyPlayer",
 | 
				
			||||||
 | 
					        "/Lotus/Upgrades/Calendar/StatusChancePerAmmoSpent",
 | 
				
			||||||
 | 
					        "/Lotus/Upgrades/Calendar/OrbsDuplicateOnPickup",
 | 
				
			||||||
 | 
					        "/Lotus/Upgrades/Calendar/AttackAndMovementSpeedOnCritMelee",
 | 
				
			||||||
 | 
					        "/Lotus/Upgrades/Calendar/RadialJavelinOnHeavy",
 | 
				
			||||||
 | 
					        "/Lotus/Upgrades/Calendar/MagnitizeWithinRangeEveryXCasts",
 | 
				
			||||||
 | 
					        "/Lotus/Upgrades/Calendar/CompanionsRadiationChance",
 | 
				
			||||||
 | 
					        "/Lotus/Upgrades/Calendar/BlastEveryXShots",
 | 
				
			||||||
 | 
					        "/Lotus/Upgrades/Calendar/GenerateOmniOrbsOnWeakKill",
 | 
				
			||||||
 | 
					        "/Lotus/Upgrades/Calendar/ElectricDamagePerDistance",
 | 
				
			||||||
 | 
					        "/Lotus/Upgrades/Calendar/MeleeSlideFowardMomentumOnEnemyHit",
 | 
				
			||||||
 | 
					        "/Lotus/Upgrades/Calendar/SharedFreeAbilityEveryXCasts",
 | 
				
			||||||
 | 
					        "/Lotus/Upgrades/Calendar/ReviveEnemyAsSpectreOnKill",
 | 
				
			||||||
 | 
					        "/Lotus/Upgrades/Calendar/RefundBulletOnStatusProc",
 | 
				
			||||||
 | 
					        "/Lotus/Upgrades/Calendar/ExplodingHealthOrbs",
 | 
				
			||||||
 | 
					        "/Lotus/Upgrades/Calendar/SpeedBuffsWhenAirborne",
 | 
				
			||||||
 | 
					        "/Lotus/Upgrades/Calendar/EnergyWavesOnCombo",
 | 
				
			||||||
 | 
					        "/Lotus/Upgrades/Calendar/PowerStrengthAndEfficiencyPerEnergySpent",
 | 
				
			||||||
 | 
					        "/Lotus/Upgrades/Calendar/CloneActiveCompanionForEnergySpent",
 | 
				
			||||||
 | 
					        "/Lotus/Upgrades/Calendar/GuidingMissilesChance",
 | 
				
			||||||
 | 
					        "/Lotus/Upgrades/Calendar/EnergyOrbsGrantShield",
 | 
				
			||||||
 | 
					        "/Lotus/Upgrades/Calendar/ElectricalDamageOnBulletJump"
 | 
				
			||||||
 | 
					    ];
 | 
				
			||||||
 | 
					    for (let i = 0; i != upgradeRanges.length - 1; ++i) {
 | 
				
			||||||
 | 
					        const upgradeIndex = rng.randomInt(0, upgrades.length - 1);
 | 
				
			||||||
 | 
					        const upgrade = upgrades[upgradeIndex];
 | 
				
			||||||
 | 
					        upgrades.splice(upgradeIndex, 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        //logger.debug(`trying to fit an upgrade between day ${upgradeRanges[i]} and ${upgradeRanges[i + 1]}`);
 | 
				
			||||||
 | 
					        let day: number;
 | 
				
			||||||
 | 
					        do {
 | 
				
			||||||
 | 
					            day = rng.randomInt(upgradeRanges[i] + 1, upgradeRanges[i + 1] - 1);
 | 
				
			||||||
 | 
					        } while (eventDays.find(x => x.day == day));
 | 
				
			||||||
 | 
					        eventDays.push({ day, events: [{ type: "CET_UPGRADE", upgrade }] });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    eventDays.sort((a, b) => a.day - b.day);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const weekStart = EPOCH + week * 604800000;
 | 
				
			||||||
 | 
					    const weekEnd = weekStart + 604800000;
 | 
				
			||||||
 | 
					    return {
 | 
				
			||||||
 | 
					        Activation: { $date: { $numberLong: weekStart.toString() } },
 | 
				
			||||||
 | 
					        Expiry: { $date: { $numberLong: weekEnd.toString() } },
 | 
				
			||||||
 | 
					        Days: eventDays,
 | 
				
			||||||
 | 
					        Season: ["CST_WINTER", "CST_SPRING", "CST_SUMMER", "CST_FALL"][seasonIndex],
 | 
				
			||||||
 | 
					        YearIteration: Math.trunc(week / 4),
 | 
				
			||||||
 | 
					        Version: 19,
 | 
				
			||||||
 | 
					        UpgradeAvaliabilityRequirements: ["/Lotus/Upgrades/Calendar/1999UpgradeApplicationRequirement"]
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const getWorldState = (buildLabel?: string): IWorldState => {
 | 
					export const getWorldState = (buildLabel?: string): IWorldState => {
 | 
				
			||||||
    const day = Math.trunc((Date.now() - EPOCH) / 86400000);
 | 
					    const day = Math.trunc((Date.now() - EPOCH) / 86400000);
 | 
				
			||||||
    const week = Math.trunc(day / 7);
 | 
					    const week = Math.trunc(day / 7);
 | 
				
			||||||
@ -376,6 +575,7 @@ export const getWorldState = (buildLabel?: string): IWorldState => {
 | 
				
			|||||||
            Params: "",
 | 
					            Params: "",
 | 
				
			||||||
            ActiveChallenges: []
 | 
					            ActiveChallenges: []
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
 | 
					        KnownCalendarSeasons: [],
 | 
				
			||||||
        ...staticWorldState,
 | 
					        ...staticWorldState,
 | 
				
			||||||
        SyndicateMissions: [...staticWorldState.SyndicateMissions]
 | 
					        SyndicateMissions: [...staticWorldState.SyndicateMissions]
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
@ -834,17 +1034,10 @@ export const getWorldState = (buildLabel?: string): IWorldState => {
 | 
				
			|||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // 1999 Calendar Season cycling every week + YearIteration every 4 weeks
 | 
					    // 1999 Calendar Season cycling every week + YearIteration every 4 weeks
 | 
				
			||||||
    // TODO: Handle imminent rollover
 | 
					    worldState.KnownCalendarSeasons.push(getCalendarSeason(week));
 | 
				
			||||||
    worldState.KnownCalendarSeasons[0].Activation = { $date: { $numberLong: weekStart.toString() } };
 | 
					    if (isBeforeNextExpectedWorldStateRefresh(weekEnd)) {
 | 
				
			||||||
    worldState.KnownCalendarSeasons[0].Expiry = { $date: { $numberLong: weekEnd.toString() } };
 | 
					        worldState.KnownCalendarSeasons.push(getCalendarSeason(week + 1));
 | 
				
			||||||
    worldState.KnownCalendarSeasons[0].Season = ["CST_WINTER", "CST_SPRING", "CST_SUMMER", "CST_FALL"][week % 4];
 | 
					    }
 | 
				
			||||||
    worldState.KnownCalendarSeasons[0].Days = [
 | 
					 | 
				
			||||||
        static1999WinterDays,
 | 
					 | 
				
			||||||
        static1999SpringDays,
 | 
					 | 
				
			||||||
        static1999SummerDays,
 | 
					 | 
				
			||||||
        static1999FallDays
 | 
					 | 
				
			||||||
    ][week % 4];
 | 
					 | 
				
			||||||
    worldState.KnownCalendarSeasons[0].YearIteration = Math.trunc(week / 4);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Sentient Anomaly cycling every 30 minutes
 | 
					    // Sentient Anomaly cycling every 30 minutes
 | 
				
			||||||
    const halfHour = Math.trunc(Date.now() / (unixTimesInMs.hour / 2));
 | 
					    const halfHour = Math.trunc(Date.now() / (unixTimesInMs.hour / 2));
 | 
				
			||||||
 | 
				
			|||||||
@ -47,6 +47,8 @@ export interface IInventoryDatabase
 | 
				
			|||||||
            | "BrandedSuits"
 | 
					            | "BrandedSuits"
 | 
				
			||||||
            | "LockedWeaponGroup"
 | 
					            | "LockedWeaponGroup"
 | 
				
			||||||
            | "PersonalTechProjects"
 | 
					            | "PersonalTechProjects"
 | 
				
			||||||
 | 
					            | "LastSortieReward"
 | 
				
			||||||
 | 
					            | "LastLiteSortieReward"
 | 
				
			||||||
            | TEquipmentKey
 | 
					            | TEquipmentKey
 | 
				
			||||||
        >,
 | 
					        >,
 | 
				
			||||||
        InventoryDatabaseEquipment {
 | 
					        InventoryDatabaseEquipment {
 | 
				
			||||||
@ -79,6 +81,8 @@ export interface IInventoryDatabase
 | 
				
			|||||||
    BrandedSuits?: Types.ObjectId[];
 | 
					    BrandedSuits?: Types.ObjectId[];
 | 
				
			||||||
    LockedWeaponGroup?: ILockedWeaponGroupDatabase;
 | 
					    LockedWeaponGroup?: ILockedWeaponGroupDatabase;
 | 
				
			||||||
    PersonalTechProjects: IPersonalTechProjectDatabase[];
 | 
					    PersonalTechProjects: IPersonalTechProjectDatabase[];
 | 
				
			||||||
 | 
					    LastSortieReward?: ILastSortieRewardDatabase[];
 | 
				
			||||||
 | 
					    LastLiteSortieReward?: ILastSortieRewardDatabase[];
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export interface IQuestKeyDatabase {
 | 
					export interface IQuestKeyDatabase {
 | 
				
			||||||
@ -277,7 +281,8 @@ export interface IInventoryClient extends IDailyAffiliations, InventoryClientEqu
 | 
				
			|||||||
    Wishlist: string[];
 | 
					    Wishlist: string[];
 | 
				
			||||||
    Alignment?: IAlignment;
 | 
					    Alignment?: IAlignment;
 | 
				
			||||||
    CompletedSorties: string[];
 | 
					    CompletedSorties: string[];
 | 
				
			||||||
    LastSortieReward: ILastSortieReward[];
 | 
					    LastSortieReward?: ILastSortieRewardClient[];
 | 
				
			||||||
 | 
					    LastLiteSortieReward?: ILastSortieRewardClient[];
 | 
				
			||||||
    Drones: IDroneClient[];
 | 
					    Drones: IDroneClient[];
 | 
				
			||||||
    StepSequencers: IStepSequencer[];
 | 
					    StepSequencers: IStepSequencer[];
 | 
				
			||||||
    ActiveAvatarImageType: string;
 | 
					    ActiveAvatarImageType: string;
 | 
				
			||||||
@ -724,12 +729,16 @@ export enum Status {
 | 
				
			|||||||
    StatusStasis = "STATUS_STASIS"
 | 
					    StatusStasis = "STATUS_STASIS"
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export interface ILastSortieReward {
 | 
					export interface ILastSortieRewardClient {
 | 
				
			||||||
    SortieId: IOid;
 | 
					    SortieId: IOid;
 | 
				
			||||||
    StoreItem: string;
 | 
					    StoreItem: string;
 | 
				
			||||||
    Manifest: string;
 | 
					    Manifest: string;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export interface ILastSortieRewardDatabase extends Omit<ILastSortieRewardClient, "SortieId"> {
 | 
				
			||||||
 | 
					    SortieId: Types.ObjectId;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export interface ILibraryDailyTaskInfo {
 | 
					export interface ILibraryDailyTaskInfo {
 | 
				
			||||||
    EnemyTypes: string[];
 | 
					    EnemyTypes: string[];
 | 
				
			||||||
    EnemyLocTag: string;
 | 
					    EnemyLocTag: string;
 | 
				
			||||||
 | 
				
			|||||||
@ -129,6 +129,9 @@ export type IMissionInventoryUpdateRequest = {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
export interface IRewardInfo {
 | 
					export interface IRewardInfo {
 | 
				
			||||||
    node: string;
 | 
					    node: string;
 | 
				
			||||||
 | 
					    sortieId?: string;
 | 
				
			||||||
 | 
					    sortieTag?: string;
 | 
				
			||||||
 | 
					    sortiePrereqs?: string[];
 | 
				
			||||||
    VaultsCracked?: number; // for Spy missions
 | 
					    VaultsCracked?: number; // for Spy missions
 | 
				
			||||||
    rewardTier?: number;
 | 
					    rewardTier?: number;
 | 
				
			||||||
    nightmareMode?: boolean;
 | 
					    nightmareMode?: boolean;
 | 
				
			||||||
 | 
				
			|||||||
@ -127,8 +127,22 @@ export interface ICalendarSeason {
 | 
				
			|||||||
    Activation: IMongoDate;
 | 
					    Activation: IMongoDate;
 | 
				
			||||||
    Expiry: IMongoDate;
 | 
					    Expiry: IMongoDate;
 | 
				
			||||||
    Season: string; // "CST_UNDEFINED" | "CST_WINTER" | "CST_SPRING" | "CST_SUMMER" | "CST_FALL"
 | 
					    Season: string; // "CST_UNDEFINED" | "CST_WINTER" | "CST_SPRING" | "CST_SUMMER" | "CST_FALL"
 | 
				
			||||||
    Days: {
 | 
					    Days: ICalendarDay[];
 | 
				
			||||||
        day: number;
 | 
					 | 
				
			||||||
    }[];
 | 
					 | 
				
			||||||
    YearIteration: number;
 | 
					    YearIteration: number;
 | 
				
			||||||
 | 
					    Version: number;
 | 
				
			||||||
 | 
					    UpgradeAvaliabilityRequirements: string[];
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export interface ICalendarDay {
 | 
				
			||||||
 | 
					    day: number;
 | 
				
			||||||
 | 
					    events: ICalendarEvent[];
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export interface ICalendarEvent {
 | 
				
			||||||
 | 
					    type: string;
 | 
				
			||||||
 | 
					    challenge?: string;
 | 
				
			||||||
 | 
					    reward?: string;
 | 
				
			||||||
 | 
					    upgrade?: string;
 | 
				
			||||||
 | 
					    dialogueName?: string;
 | 
				
			||||||
 | 
					    dialogueConvo?: string;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -1,77 +0,0 @@
 | 
				
			|||||||
[
 | 
					 | 
				
			||||||
  { "day": 276, "events": [{ "type": "CET_CHALLENGE", "challenge": "/Lotus/Types/Challenges/Calendar1999/CalendarKillScaldraEnemiesEasy" }] },
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    "day": 283,
 | 
					 | 
				
			||||||
    "events": [
 | 
					 | 
				
			||||||
      { "type": "CET_UPGRADE", "upgrade": "/Lotus/Upgrades/Calendar/CompanionDamage" },
 | 
					 | 
				
			||||||
      { "type": "CET_UPGRADE", "upgrade": "/Lotus/Upgrades/Calendar/GasChanceToPrimaryAndSecondary" },
 | 
					 | 
				
			||||||
      { "type": "CET_UPGRADE", "upgrade": "/Lotus/Upgrades/Calendar/ElectricStatusDamageAndChance" }
 | 
					 | 
				
			||||||
    ]
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    "day": 289,
 | 
					 | 
				
			||||||
    "events": [
 | 
					 | 
				
			||||||
      { "type": "CET_REWARD", "reward": "/Lotus/StoreItems/Types/Items/MiscItems/WeaponUtilityUnlocker" },
 | 
					 | 
				
			||||||
      { "type": "CET_REWARD", "reward": "/Lotus/StoreItems/Types/BoosterPacks/CalendarMajorArtifactPack" }
 | 
					 | 
				
			||||||
    ]
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
  { "day": 295, "events": [{ "type": "CET_CHALLENGE", "challenge": "/Lotus/Types/Challenges/Calendar1999/CalendarKillEnemiesWithMeleeEasy" }] },
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    "day": 302,
 | 
					 | 
				
			||||||
    "events": [
 | 
					 | 
				
			||||||
      { "type": "CET_REWARD", "reward": "/Lotus/StoreItems/Types/BoosterPacks/CalendarArtifactPack" },
 | 
					 | 
				
			||||||
      { "type": "CET_REWARD", "reward": "/Lotus/StoreItems/Types/Items/MiscItems/WeaponSecondaryArcaneUnlocker" }
 | 
					 | 
				
			||||||
    ]
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
  { "day": 305, "events": [{ "type": "CET_CHALLENGE", "challenge": "/Lotus/Types/Challenges/Calendar1999/CalendarKillEximusMedium" }] },
 | 
					 | 
				
			||||||
  { "day": 306, "events": [{ "type": "CET_PLOT", "dialogueName": "/Lotus/Types/Gameplay/1999Wf/Dialogue/EleanorDialogue_rom.dialogue", "dialogueConvo": "EleanorBirthdayConvo" }] },
 | 
					 | 
				
			||||||
  { "day": 307, "events": [{ "type": "CET_PLOT", "dialogueName": "/Lotus/Types/Gameplay/1999Wf/Dialogue/ArthurDialogue_rom.dialogue", "dialogueConvo": "ArthurBirthdayConvo" }] },
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    "day": 309,
 | 
					 | 
				
			||||||
    "events": [
 | 
					 | 
				
			||||||
      { "type": "CET_REWARD", "reward": "/Lotus/StoreItems/Types/Items/MiscItems/Forma" },
 | 
					 | 
				
			||||||
      { "type": "CET_REWARD", "reward": "/Lotus/StoreItems/Types/Gameplay/NarmerSorties/ArchonCrystalBoreal" }
 | 
					 | 
				
			||||||
    ]
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    "day": 314,
 | 
					 | 
				
			||||||
    "events": [
 | 
					 | 
				
			||||||
      { "type": "CET_UPGRADE", "upgrade": "/Lotus/Upgrades/Calendar/PowerStrengthAndEfficiencyPerEnergySpent" },
 | 
					 | 
				
			||||||
      { "type": "CET_UPGRADE", "upgrade": "/Lotus/Upgrades/Calendar/ElectricalDamageOnBulletJump" },
 | 
					 | 
				
			||||||
      { "type": "CET_UPGRADE", "upgrade": "/Lotus/Upgrades/Calendar/MeleeSlideFowardMomentumOnEnemyHit" }
 | 
					 | 
				
			||||||
    ]
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
  { "day": 322, "events": [{ "type": "CET_CHALLENGE", "challenge": "/Lotus/Types/Challenges/Calendar1999/CalendarKillEnemiesMedium" }] },
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    "day": 328,
 | 
					 | 
				
			||||||
    "events": [
 | 
					 | 
				
			||||||
      { "type": "CET_REWARD", "reward": "/Lotus/StoreItems/Types/Items/MiscItems/WeaponSecondaryArcaneUnlocker" },
 | 
					 | 
				
			||||||
      { "type": "CET_REWARD", "reward": "/Lotus/Types/StoreItems/Packages/Calendar/CalendarKuvaBundleSmall" }
 | 
					 | 
				
			||||||
    ]
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
  { "day": 337, "events": [{ "type": "CET_CHALLENGE", "challenge": "/Lotus/Types/Challenges/Calendar1999/CalendarKillScaldraEnemiesWithAbilitiesHard" }] },
 | 
					 | 
				
			||||||
  { "day": 338, "events": [{ "type": "CET_PLOT", "dialogueName": "/Lotus/Types/Gameplay/1999Wf/Dialogue/QuincyDialogue_rom.dialogue", "dialogueConvo": "QuincyBirthdayConvo" }] },
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    "day": 340,
 | 
					 | 
				
			||||||
    "events": [
 | 
					 | 
				
			||||||
      { "type": "CET_UPGRADE", "upgrade": "/Lotus/Upgrades/Calendar/MeleeCritChance" },
 | 
					 | 
				
			||||||
      { "type": "CET_UPGRADE", "upgrade": "/Lotus/Upgrades/Calendar/RadiationProcOnTakeDamage" },
 | 
					 | 
				
			||||||
      { "type": "CET_UPGRADE", "upgrade": "/Lotus/Upgrades/Calendar/AbilityStrength" }
 | 
					 | 
				
			||||||
    ]
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    "day": 343,
 | 
					 | 
				
			||||||
    "events": [
 | 
					 | 
				
			||||||
      { "type": "CET_REWARD", "reward": "/Lotus/StoreItems/Types/Items/MiscItems/WeaponPrimaryArcaneUnlocker" },
 | 
					 | 
				
			||||||
      { "type": "CET_REWARD", "reward": "/Lotus/StoreItems/Types/Items/MiscItems/FormaAura" }
 | 
					 | 
				
			||||||
    ]
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
  { "day": 352, "events": [{ "type": "CET_CHALLENGE", "challenge": "/Lotus/Types/Challenges/Calendar1999/CalendarKillTankHard" }] },
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    "day": 364,
 | 
					 | 
				
			||||||
    "events": [
 | 
					 | 
				
			||||||
      { "type": "CET_REWARD", "reward": "/Lotus/StoreItems/Types/BoosterPacks/CalendarMajorArtifactPack" },
 | 
					 | 
				
			||||||
      { "type": "CET_REWARD", "reward": "/Lotus/Types/StoreItems/Boosters/ModDropChanceBooster3DayStoreItem" }
 | 
					 | 
				
			||||||
    ]
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
]
 | 
					 | 
				
			||||||
@ -1,75 +0,0 @@
 | 
				
			|||||||
[
 | 
					 | 
				
			||||||
  { "day": 100, "events": [{ "type": "CET_CHALLENGE", "challenge": "/Lotus/Types/Challenges/Calendar1999/CalendarKillScaldraEnemiesEasy" }] },
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    "day": 101,
 | 
					 | 
				
			||||||
    "events": [
 | 
					 | 
				
			||||||
      { "type": "CET_UPGRADE", "upgrade": "/Lotus/Upgrades/Calendar/EnergyOrbToAbilityRange" },
 | 
					 | 
				
			||||||
      { "type": "CET_UPGRADE", "upgrade": "/Lotus/Upgrades/Calendar/ElectricStatusDamageAndChance" },
 | 
					 | 
				
			||||||
      { "type": "CET_UPGRADE", "upgrade": "/Lotus/Upgrades/Calendar/EnergyRestoration" }
 | 
					 | 
				
			||||||
    ]
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    "day": 102,
 | 
					 | 
				
			||||||
    "events": [
 | 
					 | 
				
			||||||
      { "type": "CET_REWARD", "reward": "/Lotus/StoreItems/Types/Gameplay/NarmerSorties/ArchonCrystalBoreal" },
 | 
					 | 
				
			||||||
      { "type": "CET_REWARD", "reward": "/Lotus/StoreItems/Types/BoosterPacks/CalendarMajorArtifactPack" }
 | 
					 | 
				
			||||||
    ]
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
  { "day": 106, "events": [{ "type": "CET_CHALLENGE", "challenge": "/Lotus/Types/Challenges/Calendar1999/CalendarKillTechrotEnemiesEasy" }] },
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    "day": 107,
 | 
					 | 
				
			||||||
    "events": [
 | 
					 | 
				
			||||||
      { "type": "CET_REWARD", "reward": "/Lotus/StoreItems/Types/BoosterPacks/CalendarArtifactPack" },
 | 
					 | 
				
			||||||
      { "type": "CET_REWARD", "reward": "/Lotus/Types/StoreItems/Packages/Calendar/CalendarKuvaBundleSmall" }
 | 
					 | 
				
			||||||
    ]
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
  { "day": 122, "events": [{ "type": "CET_CHALLENGE", "challenge": "/Lotus/Types/Challenges/Calendar1999/CalendarKillTechrotEnemiesWithMeleeMedium" }] },
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    "day": 127,
 | 
					 | 
				
			||||||
    "events": [
 | 
					 | 
				
			||||||
      { "type": "CET_REWARD", "reward": "/Lotus/StoreItems/Types/Items/MiscItems/Forma" },
 | 
					 | 
				
			||||||
      { "type": "CET_REWARD", "reward": "/Lotus/Types/StoreItems/Packages/Calendar/CalendarVosforPack" }
 | 
					 | 
				
			||||||
    ]
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
  { "day": 129, "events": [{ "type": "CET_CHALLENGE", "challenge": "/Lotus/Types/Challenges/Calendar1999/CalendarKillEnemiesWithAbilitiesMedium" }] },
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    "day": 135,
 | 
					 | 
				
			||||||
    "events": [
 | 
					 | 
				
			||||||
      { "type": "CET_REWARD", "reward": "/Lotus/StoreItems/Types/BoosterPacks/CalendarArtifactPack" },
 | 
					 | 
				
			||||||
      { "type": "CET_REWARD", "reward": "/Lotus/StoreItems/Types/Items/MiscItems/WeaponMeleeArcaneUnlocker" }
 | 
					 | 
				
			||||||
    ]
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    "day": 142,
 | 
					 | 
				
			||||||
    "events": [
 | 
					 | 
				
			||||||
      { "type": "CET_UPGRADE", "upgrade": "/Lotus/Upgrades/Calendar/BlastEveryXShots" },
 | 
					 | 
				
			||||||
      { "type": "CET_UPGRADE", "upgrade": "/Lotus/Upgrades/Calendar/MagnitizeWithinRangeEveryXCasts" },
 | 
					 | 
				
			||||||
      { "type": "CET_UPGRADE", "upgrade": "/Lotus/Upgrades/Calendar/GenerateOmniOrbsOnWeakKill" }
 | 
					 | 
				
			||||||
    ]
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
  { "day": 143, "events": [{ "type": "CET_PLOT", "dialogueName": "/Lotus/Types/Gameplay/1999Wf/Dialogue/JabirDialogue_rom.dialogue", "dialogueConvo": "AmirBirthdayConvo" }] },
 | 
					 | 
				
			||||||
  { "day": 161, "events": [{ "type": "CET_CHALLENGE", "challenge": "/Lotus/Types/Challenges/Calendar1999/CalendarKillScaldraEnemiesWithAbilitiesHard" }] },
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    "day": 165,
 | 
					 | 
				
			||||||
    "events": [
 | 
					 | 
				
			||||||
      { "type": "CET_REWARD", "reward": "/Lotus/StoreItems/Types/Items/MiscItems/Forma" },
 | 
					 | 
				
			||||||
      { "type": "CET_REWARD", "reward": "/Lotus/Types/StoreItems/Boosters/ModDropChanceBooster3DayStoreItem" }
 | 
					 | 
				
			||||||
    ]
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
  { "day": 169, "events": [{ "type": "CET_CHALLENGE", "challenge": "/Lotus/Types/Challenges/Calendar1999/CalendarDestroyPropsHard" }] },
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    "day": 171,
 | 
					 | 
				
			||||||
    "events": [
 | 
					 | 
				
			||||||
      { "type": "CET_UPGRADE", "upgrade": "/Lotus/Upgrades/Calendar/GasChanceToPrimaryAndSecondary" },
 | 
					 | 
				
			||||||
      { "type": "CET_UPGRADE", "upgrade": "/Lotus/Upgrades/Calendar/AbilityStrength" },
 | 
					 | 
				
			||||||
      { "type": "CET_UPGRADE", "upgrade": "/Lotus/Upgrades/Calendar/MeleeCritChance" }
 | 
					 | 
				
			||||||
    ]
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    "day": 176,
 | 
					 | 
				
			||||||
    "events": [
 | 
					 | 
				
			||||||
      { "type": "CET_REWARD", "reward": "/Lotus/StoreItems/Types/BoosterPacks/CalendarArtifactPack" },
 | 
					 | 
				
			||||||
      { "type": "CET_REWARD", "reward": "/Lotus/StoreItems/Types/Recipes/Components/WeaponUtilityUnlockerBlueprint" }
 | 
					 | 
				
			||||||
    ]
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
]
 | 
					 | 
				
			||||||
@ -1,75 +0,0 @@
 | 
				
			|||||||
[
 | 
					 | 
				
			||||||
  { "day": 186, "events": [{ "type": "CET_CHALLENGE", "challenge": "/Lotus/Types/Challenges/Calendar1999/CalendarKillScaldraEnemiesEasy" }] },
 | 
					 | 
				
			||||||
  { "day": 191, "events": [{ "type": "CET_PLOT", "dialogueName": "/Lotus/Types/Gameplay/1999Wf/Dialogue/AoiDialogue_rom.dialogue", "dialogueConvo": "AoiBirthdayConvo" }] },
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    "day": 193,
 | 
					 | 
				
			||||||
    "events": [
 | 
					 | 
				
			||||||
      { "type": "CET_REWARD", "reward": "/Lotus/StoreItems/Types/Gameplay/NarmerSorties/ArchonCrystalAmar" },
 | 
					 | 
				
			||||||
      { "type": "CET_REWARD", "reward": "/Lotus/StoreItems/Types/BoosterPacks/CalendarMajorArtifactPack" }
 | 
					 | 
				
			||||||
    ]
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    "day": 197,
 | 
					 | 
				
			||||||
    "events": [
 | 
					 | 
				
			||||||
      { "type": "CET_UPGRADE", "upgrade": "/Lotus/Upgrades/Calendar/MeleeAttackSpeed" },
 | 
					 | 
				
			||||||
      { "type": "CET_UPGRADE", "upgrade": "/Lotus/Upgrades/Calendar/AbilityStrength" },
 | 
					 | 
				
			||||||
      { "type": "CET_UPGRADE", "upgrade": "/Lotus/Upgrades/Calendar/CompanionDamage" }
 | 
					 | 
				
			||||||
    ]
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
  { "day": 199, "events": [{ "type": "CET_CHALLENGE", "challenge": "/Lotus/Types/Challenges/Calendar1999/CalendarKillScaldraEnemiesWithMeleeMedium" }] },
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    "day": 210,
 | 
					 | 
				
			||||||
    "events": [
 | 
					 | 
				
			||||||
      { "type": "CET_REWARD", "reward": "/Lotus/StoreItems/Types/BoosterPacks/CalendarArtifactPack" },
 | 
					 | 
				
			||||||
      { "type": "CET_REWARD", "reward": "/Lotus/StoreItems/Upgrades/Mods/FusionBundles/CircuitSilverSteelPathFusionBundle" }
 | 
					 | 
				
			||||||
    ]
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
  { "day": 215, "events": [{ "type": "CET_CHALLENGE", "challenge": "/Lotus/Types/Challenges/Calendar1999/CalendarKillTechrotEnemiesWithMeleeEasy" }] },
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    "day": 228,
 | 
					 | 
				
			||||||
    "events": [
 | 
					 | 
				
			||||||
      { "type": "CET_REWARD", "reward": "/Lotus/StoreItems/Types/Recipes/Components/WeaponUtilityUnlockerBlueprint" },
 | 
					 | 
				
			||||||
      { "type": "CET_REWARD", "reward": "/Lotus/StoreItems/Types/BoosterPacks/CalendarRivenPack" }
 | 
					 | 
				
			||||||
    ]
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
  { "day": 236, "events": [{ "type": "CET_CHALLENGE", "challenge": "/Lotus/Types/Challenges/Calendar1999/CalendarDestroyPropsMedium" }] },
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    "day": 237,
 | 
					 | 
				
			||||||
    "events": [
 | 
					 | 
				
			||||||
      { "type": "CET_REWARD", "reward": "/Lotus/Types/StoreItems/Packages/Calendar/CalendarKuvaBundleLarge" },
 | 
					 | 
				
			||||||
      { "type": "CET_REWARD", "reward": "/Lotus/StoreItems/Types/BoosterPacks/CalendarMajorArtifactPack" }
 | 
					 | 
				
			||||||
    ]
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    "day": 240,
 | 
					 | 
				
			||||||
    "events": [
 | 
					 | 
				
			||||||
      { "type": "CET_UPGRADE", "upgrade": "/Lotus/Upgrades/Calendar/RadialJavelinOnHeavy" },
 | 
					 | 
				
			||||||
      { "type": "CET_UPGRADE", "upgrade": "/Lotus/Upgrades/Calendar/SharedFreeAbilityEveryXCasts" },
 | 
					 | 
				
			||||||
      { "type": "CET_UPGRADE", "upgrade": "/Lotus/Upgrades/Calendar/CompanionsRadiationChance" }
 | 
					 | 
				
			||||||
    ]
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
  { "day": 245, "events": [{ "type": "CET_CHALLENGE", "challenge": "/Lotus/Types/Challenges/Calendar1999/CalendarKillEnemiesWithAbilitiesHard" }] },
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    "day": 250,
 | 
					 | 
				
			||||||
    "events": [
 | 
					 | 
				
			||||||
      { "type": "CET_REWARD", "reward": "/Lotus/Types/StoreItems/Boosters/AffinityBooster3DayStoreItem" },
 | 
					 | 
				
			||||||
      { "type": "CET_REWARD", "reward": "/Lotus/StoreItems/Types/Recipes/Components/OrokinReactorBlueprint" }
 | 
					 | 
				
			||||||
    ]
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
  { "day": 254, "events": [{ "type": "CET_CHALLENGE", "challenge": "/Lotus/Types/Challenges/Calendar1999/CalendarKillTankHard" }] },
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    "day": 267,
 | 
					 | 
				
			||||||
    "events": [
 | 
					 | 
				
			||||||
      { "type": "CET_REWARD", "reward": "/Lotus/StoreItems/Types/BoosterPacks/CalendarArtifactPack" },
 | 
					 | 
				
			||||||
      { "type": "CET_REWARD", "reward": "/Lotus/StoreItems/Types/Items/MiscItems/WeaponSecondaryArcaneUnlocker" }
 | 
					 | 
				
			||||||
    ]
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    "day": 270,
 | 
					 | 
				
			||||||
    "events": [
 | 
					 | 
				
			||||||
      { "type": "CET_UPGRADE", "upgrade": "/Lotus/Upgrades/Calendar/EnergyOrbToAbilityRange" },
 | 
					 | 
				
			||||||
      { "type": "CET_UPGRADE", "upgrade": "/Lotus/Upgrades/Calendar/PunchToPrimary" },
 | 
					 | 
				
			||||||
      { "type": "CET_UPGRADE", "upgrade": "/Lotus/Upgrades/Calendar/OvershieldCap" }
 | 
					 | 
				
			||||||
    ]
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
]
 | 
					 | 
				
			||||||
@ -1,75 +0,0 @@
 | 
				
			|||||||
[
 | 
					 | 
				
			||||||
  { "day": 6, "events": [{ "type": "CET_CHALLENGE", "challenge": "/Lotus/Types/Challenges/Calendar1999/CalendarKillEximusEasy" }] },
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    "day": 15,
 | 
					 | 
				
			||||||
    "events": [
 | 
					 | 
				
			||||||
      { "type": "CET_UPGRADE", "upgrade": "/Lotus/Upgrades/Calendar/MagazineCapacity" },
 | 
					 | 
				
			||||||
      { "type": "CET_UPGRADE", "upgrade": "/Lotus/Upgrades/Calendar/Armor" },
 | 
					 | 
				
			||||||
      { "type": "CET_UPGRADE", "upgrade": "/Lotus/Upgrades/Calendar/EnergyRestoration" }
 | 
					 | 
				
			||||||
    ]
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
  { "day": 21, "events": [{ "type": "CET_CHALLENGE", "challenge": "/Lotus/Types/Challenges/Calendar1999/CalendarKillScaldraEnemiesEasy" }] },
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    "day": 25,
 | 
					 | 
				
			||||||
    "events": [
 | 
					 | 
				
			||||||
      { "type": "CET_REWARD", "reward": "/Lotus/StoreItems/Types/BoosterPacks/CalendarMajorArtifactPack" },
 | 
					 | 
				
			||||||
      { "type": "CET_REWARD", "reward": "/Lotus/StoreItems/Types/Gameplay/NarmerSorties/ArchonCrystalGreen" }
 | 
					 | 
				
			||||||
    ]
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    "day": 31,
 | 
					 | 
				
			||||||
    "events": [
 | 
					 | 
				
			||||||
      { "type": "CET_REWARD", "reward": "/Lotus/StoreItems/Types/Recipes/Components/WeaponUtilityUnlockerBlueprint" },
 | 
					 | 
				
			||||||
      { "type": "CET_REWARD", "reward": "/Lotus/Types/StoreItems/Packages/Calendar/CalendarKuvaBundleSmall" }
 | 
					 | 
				
			||||||
    ]
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
  { "day": 43, "events": [{ "type": "CET_CHALLENGE", "challenge": "/Lotus/Types/Challenges/Calendar1999/CalendarKillEnemiesWithAbilitiesMedium" }] },
 | 
					 | 
				
			||||||
  { "day": 45, "events": [{ "type": "CET_PLOT", "dialogueName": "/Lotus/Types/Gameplay/1999Wf/Dialogue/LettieDialogue_rom.dialogue", "dialogueConvo": "LettieBirthdayConvo" }] },
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    "day": 47,
 | 
					 | 
				
			||||||
    "events": [
 | 
					 | 
				
			||||||
      { "type": "CET_REWARD", "reward": "/Lotus/Types/StoreItems/Boosters/AffinityBooster3DayStoreItem" },
 | 
					 | 
				
			||||||
      { "type": "CET_REWARD", "reward": "/Lotus/StoreItems/Types/BoosterPacks/CalendarMajorArtifactPack" }
 | 
					 | 
				
			||||||
    ]
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
  { "day": 48, "events": [{ "type": "CET_CHALLENGE", "challenge": "/Lotus/Types/Challenges/Calendar1999/CalendarKillScaldraEnemiesWithMeleeMedium" }] },
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    "day": 54,
 | 
					 | 
				
			||||||
    "events": [
 | 
					 | 
				
			||||||
      { "type": "CET_UPGRADE", "upgrade": "/Lotus/Upgrades/Calendar/CompanionsBuffNearbyPlayer" },
 | 
					 | 
				
			||||||
      { "type": "CET_UPGRADE", "upgrade": "/Lotus/Upgrades/Calendar/OrbsDuplicateOnPickup" },
 | 
					 | 
				
			||||||
      { "type": "CET_UPGRADE", "upgrade": "/Lotus/Upgrades/Calendar/FinisherChancePerComboMultiplier" }
 | 
					 | 
				
			||||||
    ]
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    "day": 56,
 | 
					 | 
				
			||||||
    "events": [
 | 
					 | 
				
			||||||
      { "type": "CET_REWARD", "reward": "/Lotus/StoreItems/Types/BoosterPacks/CalendarArtifactPack" },
 | 
					 | 
				
			||||||
      { "type": "CET_REWARD", "reward": "/Lotus/Types/StoreItems/Packages/Calendar/CalendarKuvaBundleSmall" }
 | 
					 | 
				
			||||||
    ]
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
  { "day": 71, "events": [{ "type": "CET_CHALLENGE", "challenge": "/Lotus/Types/Challenges/Calendar1999/CalendarKillTechrotEnemiesHard" }] },
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    "day": 77,
 | 
					 | 
				
			||||||
    "events": [
 | 
					 | 
				
			||||||
      { "type": "CET_REWARD", "reward": "/Lotus/StoreItems/Types/Items/MiscItems/WeaponSecondaryArcaneUnlocker" },
 | 
					 | 
				
			||||||
      { "type": "CET_REWARD", "reward": "/Lotus/StoreItems/Upgrades/Mods/FusionBundles/CircuitSilverSteelPathFusionBundle" }
 | 
					 | 
				
			||||||
    ]
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
  { "day": 80, "events": [{ "type": "CET_CHALLENGE", "challenge": "/Lotus/Types/Challenges/Calendar1999/CalendarDestroyPropsMedium" }] },
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    "day": 83,
 | 
					 | 
				
			||||||
    "events": [
 | 
					 | 
				
			||||||
      { "type": "CET_REWARD", "reward": "/Lotus/StoreItems/Types/Recipes/Components/OrokinReactorBlueprint" },
 | 
					 | 
				
			||||||
      { "type": "CET_REWARD", "reward": "/Lotus/StoreItems/Types/Items/MiscItems/WeaponUtilityUnlocker" }
 | 
					 | 
				
			||||||
    ]
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    "day": 87,
 | 
					 | 
				
			||||||
    "events": [
 | 
					 | 
				
			||||||
      { "type": "CET_UPGRADE", "upgrade": "/Lotus/Upgrades/Calendar/EnergyOrbToAbilityRange" },
 | 
					 | 
				
			||||||
      { "type": "CET_UPGRADE", "upgrade": "/Lotus/Upgrades/Calendar/MeleeAttackSpeed" },
 | 
					 | 
				
			||||||
      { "type": "CET_UPGRADE", "upgrade": "/Lotus/Upgrades/Calendar/CompanionDamage" }
 | 
					 | 
				
			||||||
    ]
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
]
 | 
					 | 
				
			||||||
@ -2716,90 +2716,5 @@
 | 
				
			|||||||
  "ConstructionProjects": [],
 | 
					  "ConstructionProjects": [],
 | 
				
			||||||
  "TwitchPromos": [],
 | 
					  "TwitchPromos": [],
 | 
				
			||||||
  "ExperimentRecommended": [],
 | 
					  "ExperimentRecommended": [],
 | 
				
			||||||
  "ForceLogoutVersion": 0,
 | 
					  "ForceLogoutVersion": 0
 | 
				
			||||||
  "KnownCalendarSeasons": [
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
      "Activation": { "$date": { "$numberLong": "1733961600000" } },
 | 
					 | 
				
			||||||
      "Expiry": { "$date": { "$numberLong": "2000000000000" } },
 | 
					 | 
				
			||||||
      "Days": [
 | 
					 | 
				
			||||||
        { "day": 6, "events": [{ "type": "CET_CHALLENGE", "challenge": "/Lotus/Types/Challenges/Calendar1999/CalendarKillEximusEasy" }] },
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
          "day": 15,
 | 
					 | 
				
			||||||
          "events": [
 | 
					 | 
				
			||||||
            { "type": "CET_UPGRADE", "upgrade": "/Lotus/Upgrades/Calendar/MagazineCapacity" },
 | 
					 | 
				
			||||||
            { "type": "CET_UPGRADE", "upgrade": "/Lotus/Upgrades/Calendar/Armor" },
 | 
					 | 
				
			||||||
            { "type": "CET_UPGRADE", "upgrade": "/Lotus/Upgrades/Calendar/EnergyRestoration" }
 | 
					 | 
				
			||||||
          ]
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
        { "day": 21, "events": [{ "type": "CET_CHALLENGE", "challenge": "/Lotus/Types/Challenges/Calendar1999/CalendarKillScaldraEnemiesEasy" }] },
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
          "day": 25,
 | 
					 | 
				
			||||||
          "events": [
 | 
					 | 
				
			||||||
            { "type": "CET_REWARD", "reward": "/Lotus/StoreItems/Types/BoosterPacks/CalendarMajorArtifactPack" },
 | 
					 | 
				
			||||||
            { "type": "CET_REWARD", "reward": "/Lotus/StoreItems/Types/Gameplay/NarmerSorties/ArchonCrystalGreen" }
 | 
					 | 
				
			||||||
          ]
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
          "day": 31,
 | 
					 | 
				
			||||||
          "events": [
 | 
					 | 
				
			||||||
            { "type": "CET_REWARD", "reward": "/Lotus/StoreItems/Types/Recipes/Components/WeaponUtilityUnlockerBlueprint" },
 | 
					 | 
				
			||||||
            { "type": "CET_REWARD", "reward": "/Lotus/Types/StoreItems/Packages/Calendar/CalendarKuvaBundleSmall" }
 | 
					 | 
				
			||||||
          ]
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
        { "day": 43, "events": [{ "type": "CET_CHALLENGE", "challenge": "/Lotus/Types/Challenges/Calendar1999/CalendarKillEnemiesWithAbilitiesMedium" }] },
 | 
					 | 
				
			||||||
        { "day": 45, "events": [{ "type": "CET_PLOT", "dialogueName": "/Lotus/Types/Gameplay/1999Wf/Dialogue/LettieDialogue_rom.dialogue", "dialogueConvo": "LettieBirthdayConvo" }] },
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
          "day": 47,
 | 
					 | 
				
			||||||
          "events": [
 | 
					 | 
				
			||||||
            { "type": "CET_REWARD", "reward": "/Lotus/Types/StoreItems/Boosters/AffinityBooster3DayStoreItem" },
 | 
					 | 
				
			||||||
            { "type": "CET_REWARD", "reward": "/Lotus/StoreItems/Types/BoosterPacks/CalendarMajorArtifactPack" }
 | 
					 | 
				
			||||||
          ]
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
        { "day": 48, "events": [{ "type": "CET_CHALLENGE", "challenge": "/Lotus/Types/Challenges/Calendar1999/CalendarKillScaldraEnemiesWithMeleeMedium" }] },
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
          "day": 54,
 | 
					 | 
				
			||||||
          "events": [
 | 
					 | 
				
			||||||
            { "type": "CET_UPGRADE", "upgrade": "/Lotus/Upgrades/Calendar/CompanionsBuffNearbyPlayer" },
 | 
					 | 
				
			||||||
            { "type": "CET_UPGRADE", "upgrade": "/Lotus/Upgrades/Calendar/OrbsDuplicateOnPickup" },
 | 
					 | 
				
			||||||
            { "type": "CET_UPGRADE", "upgrade": "/Lotus/Upgrades/Calendar/FinisherChancePerComboMultiplier" }
 | 
					 | 
				
			||||||
          ]
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
          "day": 56,
 | 
					 | 
				
			||||||
          "events": [
 | 
					 | 
				
			||||||
            { "type": "CET_REWARD", "reward": "/Lotus/StoreItems/Types/BoosterPacks/CalendarArtifactPack" },
 | 
					 | 
				
			||||||
            { "type": "CET_REWARD", "reward": "/Lotus/Types/StoreItems/Packages/Calendar/CalendarKuvaBundleSmall" }
 | 
					 | 
				
			||||||
          ]
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
        { "day": 71, "events": [{ "type": "CET_CHALLENGE", "challenge": "/Lotus/Types/Challenges/Calendar1999/CalendarKillTechrotEnemiesHard" }] },
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
          "day": 77,
 | 
					 | 
				
			||||||
          "events": [
 | 
					 | 
				
			||||||
            { "type": "CET_REWARD", "reward": "/Lotus/StoreItems/Types/Items/MiscItems/WeaponSecondaryArcaneUnlocker" },
 | 
					 | 
				
			||||||
            { "type": "CET_REWARD", "reward": "/Lotus/StoreItems/Upgrades/Mods/FusionBundles/CircuitSilverSteelPathFusionBundle" }
 | 
					 | 
				
			||||||
          ]
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
        { "day": 80, "events": [{ "type": "CET_CHALLENGE", "challenge": "/Lotus/Types/Challenges/Calendar1999/CalendarDestroyPropsMedium" }] },
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
          "day": 83,
 | 
					 | 
				
			||||||
          "events": [
 | 
					 | 
				
			||||||
            { "type": "CET_REWARD", "reward": "/Lotus/StoreItems/Types/Recipes/Components/OrokinReactorBlueprint" },
 | 
					 | 
				
			||||||
            { "type": "CET_REWARD", "reward": "/Lotus/StoreItems/Types/Items/MiscItems/WeaponUtilityUnlocker" }
 | 
					 | 
				
			||||||
          ]
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
          "day": 87,
 | 
					 | 
				
			||||||
          "events": [
 | 
					 | 
				
			||||||
            { "type": "CET_UPGRADE", "upgrade": "/Lotus/Upgrades/Calendar/EnergyOrbToAbilityRange" },
 | 
					 | 
				
			||||||
            { "type": "CET_UPGRADE", "upgrade": "/Lotus/Upgrades/Calendar/MeleeAttackSpeed" },
 | 
					 | 
				
			||||||
            { "type": "CET_UPGRADE", "upgrade": "/Lotus/Upgrades/Calendar/CompanionDamage" }
 | 
					 | 
				
			||||||
          ]
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      ],
 | 
					 | 
				
			||||||
      "Season": "CST_WINTER",
 | 
					 | 
				
			||||||
      "YearIteration": 0,
 | 
					 | 
				
			||||||
      "Version": 17,
 | 
					 | 
				
			||||||
      "UpgradeAvaliabilityRequirements": ["/Lotus/Upgrades/Calendar/1999UpgradeApplicationRequirement"]
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  ]
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -611,6 +611,10 @@
 | 
				
			|||||||
                                        <input class="form-check-input" type="checkbox" id="noVendorPurchaseLimits" />
 | 
					                                        <input class="form-check-input" type="checkbox" id="noVendorPurchaseLimits" />
 | 
				
			||||||
                                        <label class="form-check-label" for="noVendorPurchaseLimits" data-loc="cheats_noVendorPurchaseLimits"></label>
 | 
					                                        <label class="form-check-label" for="noVendorPurchaseLimits" data-loc="cheats_noVendorPurchaseLimits"></label>
 | 
				
			||||||
                                    </div>
 | 
					                                    </div>
 | 
				
			||||||
 | 
					                                    <div class="form-check">
 | 
				
			||||||
 | 
					                                        <input class="form-check-input" type="checkbox" id="noDeathMarks" />
 | 
				
			||||||
 | 
					                                        <label class="form-check-label" for="noDeathMarks" data-loc="cheats_noDeathMarks"></label>
 | 
				
			||||||
 | 
					                                    </div>
 | 
				
			||||||
                                    <div class="form-check">
 | 
					                                    <div class="form-check">
 | 
				
			||||||
                                        <input class="form-check-input" type="checkbox" id="noKimCooldowns" />
 | 
					                                        <input class="form-check-input" type="checkbox" id="noKimCooldowns" />
 | 
				
			||||||
                                        <label class="form-check-label" for="noKimCooldowns" data-loc="cheats_noKimCooldowns"></label>
 | 
					                                        <label class="form-check-label" for="noKimCooldowns" data-loc="cheats_noKimCooldowns"></label>
 | 
				
			||||||
 | 
				
			|||||||
@ -138,6 +138,7 @@ dict = {
 | 
				
			|||||||
    cheats_noArgonCrystalDecay: `Argon-Kristalle verschwinden niemals`,
 | 
					    cheats_noArgonCrystalDecay: `Argon-Kristalle verschwinden niemals`,
 | 
				
			||||||
    cheats_noMasteryRankUpCooldown: `Keine Wartezeit beim Meisterschaftsrangaufstieg`,
 | 
					    cheats_noMasteryRankUpCooldown: `Keine Wartezeit beim Meisterschaftsrangaufstieg`,
 | 
				
			||||||
    cheats_noVendorPurchaseLimits: `Keine Kaufbeschränkungen bei Händlern`,
 | 
					    cheats_noVendorPurchaseLimits: `Keine Kaufbeschränkungen bei Händlern`,
 | 
				
			||||||
 | 
					    cheats_noDeathMarks: `[UNTRANSLATED] No Death Marks`,
 | 
				
			||||||
    cheats_noKimCooldowns: `Keine Wartezeit bei KIM`,
 | 
					    cheats_noKimCooldowns: `Keine Wartezeit bei KIM`,
 | 
				
			||||||
    cheats_instantResourceExtractorDrones: `Sofortige Ressourcen-Extraktor-Drohnen`,
 | 
					    cheats_instantResourceExtractorDrones: `Sofortige Ressourcen-Extraktor-Drohnen`,
 | 
				
			||||||
    cheats_noResourceExtractorDronesDamage: `Kein Schaden für Ressourcen-Extraktor-Drohnen`,
 | 
					    cheats_noResourceExtractorDronesDamage: `Kein Schaden für Ressourcen-Extraktor-Drohnen`,
 | 
				
			||||||
 | 
				
			|||||||
@ -137,6 +137,7 @@ dict = {
 | 
				
			|||||||
    cheats_noArgonCrystalDecay: `No Argon Crystal Decay`,
 | 
					    cheats_noArgonCrystalDecay: `No Argon Crystal Decay`,
 | 
				
			||||||
    cheats_noMasteryRankUpCooldown: `No Mastery Rank Up Cooldown`,
 | 
					    cheats_noMasteryRankUpCooldown: `No Mastery Rank Up Cooldown`,
 | 
				
			||||||
    cheats_noVendorPurchaseLimits: `No Vendor Purchase Limits`,
 | 
					    cheats_noVendorPurchaseLimits: `No Vendor Purchase Limits`,
 | 
				
			||||||
 | 
					    cheats_noDeathMarks: `No Death Marks`,
 | 
				
			||||||
    cheats_noKimCooldowns: `No KIM Cooldowns`,
 | 
					    cheats_noKimCooldowns: `No KIM Cooldowns`,
 | 
				
			||||||
    cheats_instantResourceExtractorDrones: `Instant Resource Extractor Drones`,
 | 
					    cheats_instantResourceExtractorDrones: `Instant Resource Extractor Drones`,
 | 
				
			||||||
    cheats_noResourceExtractorDronesDamage: `No Resource Extractor Drones Damage`,
 | 
					    cheats_noResourceExtractorDronesDamage: `No Resource Extractor Drones Damage`,
 | 
				
			||||||
 | 
				
			|||||||
@ -138,6 +138,7 @@ dict = {
 | 
				
			|||||||
    cheats_noArgonCrystalDecay: `Sin descomposición de cristal de Argón`,
 | 
					    cheats_noArgonCrystalDecay: `Sin descomposición de cristal de Argón`,
 | 
				
			||||||
    cheats_noMasteryRankUpCooldown: `Sin tiempo de espera para rango de maestría`,
 | 
					    cheats_noMasteryRankUpCooldown: `Sin tiempo de espera para rango de maestría`,
 | 
				
			||||||
    cheats_noVendorPurchaseLimits: `Sin límite de compras de vendedores`,
 | 
					    cheats_noVendorPurchaseLimits: `Sin límite de compras de vendedores`,
 | 
				
			||||||
 | 
					    cheats_noDeathMarks: `[UNTRANSLATED] No Death Marks`,
 | 
				
			||||||
    cheats_noKimCooldowns: `Sin tiempo de espera para conversaciones KIM`,
 | 
					    cheats_noKimCooldowns: `Sin tiempo de espera para conversaciones KIM`,
 | 
				
			||||||
    cheats_instantResourceExtractorDrones: `Drones de extracción de recursos instantáneos`,
 | 
					    cheats_instantResourceExtractorDrones: `Drones de extracción de recursos instantáneos`,
 | 
				
			||||||
    cheats_noResourceExtractorDronesDamage: `Sin daño a los drones extractores de recursos`,
 | 
					    cheats_noResourceExtractorDronesDamage: `Sin daño a los drones extractores de recursos`,
 | 
				
			||||||
 | 
				
			|||||||
@ -138,6 +138,7 @@ dict = {
 | 
				
			|||||||
    cheats_noArgonCrystalDecay: `[UNTRANSLATED] No Argon Crystal Decay`,
 | 
					    cheats_noArgonCrystalDecay: `[UNTRANSLATED] No Argon Crystal Decay`,
 | 
				
			||||||
    cheats_noMasteryRankUpCooldown: `[UNTRANSLATED] No Mastery Rank Up Cooldown`,
 | 
					    cheats_noMasteryRankUpCooldown: `[UNTRANSLATED] No Mastery Rank Up Cooldown`,
 | 
				
			||||||
    cheats_noVendorPurchaseLimits: `[UNTRANSLATED] No Vendor Purchase Limits`,
 | 
					    cheats_noVendorPurchaseLimits: `[UNTRANSLATED] No Vendor Purchase Limits`,
 | 
				
			||||||
 | 
					    cheats_noDeathMarks: `[UNTRANSLATED] No Death Marks`,
 | 
				
			||||||
    cheats_noKimCooldowns: `[UNTRANSLATED] No KIM Cooldowns`,
 | 
					    cheats_noKimCooldowns: `[UNTRANSLATED] No KIM Cooldowns`,
 | 
				
			||||||
    cheats_instantResourceExtractorDrones: `Ressources de drone d'extraction instantannées`,
 | 
					    cheats_instantResourceExtractorDrones: `Ressources de drone d'extraction instantannées`,
 | 
				
			||||||
    cheats_noResourceExtractorDronesDamage: `[UNTRANSLATED] No Resource Extractor Drones Damage`,
 | 
					    cheats_noResourceExtractorDronesDamage: `[UNTRANSLATED] No Resource Extractor Drones Damage`,
 | 
				
			||||||
 | 
				
			|||||||
@ -138,6 +138,7 @@ dict = {
 | 
				
			|||||||
    cheats_noArgonCrystalDecay: `Без распада аргоновых кристаллов`,
 | 
					    cheats_noArgonCrystalDecay: `Без распада аргоновых кристаллов`,
 | 
				
			||||||
    cheats_noMasteryRankUpCooldown: `Повышение ранга мастерства без кулдауна`,
 | 
					    cheats_noMasteryRankUpCooldown: `Повышение ранга мастерства без кулдауна`,
 | 
				
			||||||
    cheats_noVendorPurchaseLimits: `Отсутствие лимитов на покупки у вендоров`,
 | 
					    cheats_noVendorPurchaseLimits: `Отсутствие лимитов на покупки у вендоров`,
 | 
				
			||||||
 | 
					    cheats_noDeathMarks: `[UNTRANSLATED] No Death Marks`,
 | 
				
			||||||
    cheats_noKimCooldowns: `[UNTRANSLATED] No KIM Cooldowns`,
 | 
					    cheats_noKimCooldowns: `[UNTRANSLATED] No KIM Cooldowns`,
 | 
				
			||||||
    cheats_instantResourceExtractorDrones: `Мгновенные Экстракторы Ресурсов`,
 | 
					    cheats_instantResourceExtractorDrones: `Мгновенные Экстракторы Ресурсов`,
 | 
				
			||||||
    cheats_noResourceExtractorDronesDamage: `[UNTRANSLATED] No Resource Extractor Drones Damage`,
 | 
					    cheats_noResourceExtractorDronesDamage: `[UNTRANSLATED] No Resource Extractor Drones Damage`,
 | 
				
			||||||
 | 
				
			|||||||
@ -138,6 +138,7 @@ dict = {
 | 
				
			|||||||
    cheats_noArgonCrystalDecay: `[UNTRANSLATED] No Argon Crystal Decay`,
 | 
					    cheats_noArgonCrystalDecay: `[UNTRANSLATED] No Argon Crystal Decay`,
 | 
				
			||||||
    cheats_noMasteryRankUpCooldown: `[UNTRANSLATED] No Mastery Rank Up Cooldown`,
 | 
					    cheats_noMasteryRankUpCooldown: `[UNTRANSLATED] No Mastery Rank Up Cooldown`,
 | 
				
			||||||
    cheats_noVendorPurchaseLimits: `[UNTRANSLATED] No Vendor Purchase Limits`,
 | 
					    cheats_noVendorPurchaseLimits: `[UNTRANSLATED] No Vendor Purchase Limits`,
 | 
				
			||||||
 | 
					    cheats_noDeathMarks: `[UNTRANSLATED] No Death Marks`,
 | 
				
			||||||
    cheats_noKimCooldowns: `[UNTRANSLATED] No KIM Cooldowns`,
 | 
					    cheats_noKimCooldowns: `[UNTRANSLATED] No KIM Cooldowns`,
 | 
				
			||||||
    cheats_instantResourceExtractorDrones: `即时资源采集无人机`,
 | 
					    cheats_instantResourceExtractorDrones: `即时资源采集无人机`,
 | 
				
			||||||
    cheats_noResourceExtractorDronesDamage: `[UNTRANSLATED] No Resource Extractor Drones Damage`,
 | 
					    cheats_noResourceExtractorDronesDamage: `[UNTRANSLATED] No Resource Extractor Drones Damage`,
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user