feat: tutorial and natural new player experience (#983)
Reviewed-on: OpenWF/SpaceNinjaServer#983 Co-authored-by: Ordis <134585663+OrdisPrime@users.noreply.github.com> Co-committed-by: Ordis <134585663+OrdisPrime@users.noreply.github.com>
This commit is contained in:
		
							parent
							
								
									9203e0bf4d
								
							
						
					
					
						commit
						bf7fd42198
					
				
							
								
								
									
										6
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										6
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							@ -4093,9 +4093,9 @@
 | 
				
			|||||||
      }
 | 
					      }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    "node_modules/warframe-public-export-plus": {
 | 
					    "node_modules/warframe-public-export-plus": {
 | 
				
			||||||
      "version": "0.5.30",
 | 
					      "version": "0.5.32",
 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/warframe-public-export-plus/-/warframe-public-export-plus-0.5.30.tgz",
 | 
					      "resolved": "https://registry.npmjs.org/warframe-public-export-plus/-/warframe-public-export-plus-0.5.32.tgz",
 | 
				
			||||||
      "integrity": "sha512-vzs+naEqp3iFZTbgIky4jiNbjNIovuR4oSimrFiuyIbrnfTlfXFzDfzT0hG2rgS8yEXBAbOcv2Zfm3fmWuZ0Kg=="
 | 
					      "integrity": "sha512-jO9i2Gzz9DWibiHlEO17D975ajs6KrTay8cS5I0GkUUe1XWVU8mML4b+IYCHzM4FWq1t6p2YPCGznQfknqvorg=="
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    "node_modules/warframe-riven-info": {
 | 
					    "node_modules/warframe-riven-info": {
 | 
				
			||||||
      "version": "0.1.2",
 | 
					      "version": "0.1.2",
 | 
				
			||||||
 | 
				
			|||||||
@ -1,13 +1,11 @@
 | 
				
			|||||||
import { RequestHandler } from "express";
 | 
					import { RequestHandler } from "express";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const getNewRewardSeedController: RequestHandler = (_req, res) => {
 | 
					export const getNewRewardSeedController: RequestHandler = (_req, res) => {
 | 
				
			||||||
    res.json({ rewardSeed: generateRewardSeed() });
 | 
					    res.json({ rewardSeed: generateRewardSeed() });
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function generateRewardSeed(): number {
 | 
					export function generateRewardSeed(): number {
 | 
				
			||||||
    const min = -Number.MAX_SAFE_INTEGER;
 | 
					    const min = -Number.MAX_SAFE_INTEGER;
 | 
				
			||||||
    const max = Number.MAX_SAFE_INTEGER;
 | 
					    const max = Number.MAX_SAFE_INTEGER;
 | 
				
			||||||
    return Math.floor(Math.random() * (max - min + 1)) + min;
 | 
					    return Math.floor(Math.random() * (max - min + 1)) + min;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					 | 
				
			||||||
export { getNewRewardSeedController };
 | 
					 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										96
									
								
								src/controllers/api/giveStartingGearController.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										96
									
								
								src/controllers/api/giveStartingGearController.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,96 @@
 | 
				
			|||||||
 | 
					import { getJSONfromString } from "@/src/helpers/stringHelpers";
 | 
				
			||||||
 | 
					import { InventoryDocumentProps } from "@/src/models/inventoryModels/inventoryModel";
 | 
				
			||||||
 | 
					import {
 | 
				
			||||||
 | 
					    addEquipment,
 | 
				
			||||||
 | 
					    addItem,
 | 
				
			||||||
 | 
					    combineInventoryChanges,
 | 
				
			||||||
 | 
					    getInventory,
 | 
				
			||||||
 | 
					    updateSlots
 | 
				
			||||||
 | 
					} from "@/src/services/inventoryService";
 | 
				
			||||||
 | 
					import { getAccountIdForRequest } from "@/src/services/loginService";
 | 
				
			||||||
 | 
					import { IInventoryClient, IInventoryDatabase, InventorySlot } from "@/src/types/inventoryTypes/inventoryTypes";
 | 
				
			||||||
 | 
					import { IInventoryChanges } from "@/src/types/purchaseTypes";
 | 
				
			||||||
 | 
					import { RequestHandler } from "express";
 | 
				
			||||||
 | 
					import { HydratedDocument } from "mongoose";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type TPartialStartingGear = Pick<IInventoryClient, "LongGuns" | "Suits" | "Pistols" | "Melee">;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export const giveStartingGearController: RequestHandler = async (req, res) => {
 | 
				
			||||||
 | 
					    const accountId = await getAccountIdForRequest(req);
 | 
				
			||||||
 | 
					    const startingGear = getJSONfromString<TPartialStartingGear>(String(req.body));
 | 
				
			||||||
 | 
					    const inventory = await getInventory(accountId);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const inventoryChanges = await addStartingGear(inventory, startingGear);
 | 
				
			||||||
 | 
					    await inventory.save();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    res.send(inventoryChanges);
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//TODO: RawUpgrades might need to return a LastAdded
 | 
				
			||||||
 | 
					const awakeningRewards = [
 | 
				
			||||||
 | 
					    "/Lotus/Types/StoreItems/AvatarImages/AvatarImageItem1",
 | 
				
			||||||
 | 
					    "/Lotus/Types/StoreItems/AvatarImages/AvatarImageItem2",
 | 
				
			||||||
 | 
					    "/Lotus/Types/StoreItems/AvatarImages/AvatarImageItem3",
 | 
				
			||||||
 | 
					    "/Lotus/Types/StoreItems/AvatarImages/AvatarImageItem4",
 | 
				
			||||||
 | 
					    "/Lotus/Types/Restoratives/LisetAutoHack",
 | 
				
			||||||
 | 
					    "/Lotus/Upgrades/Mods/Warframe/AvatarShieldMaxMod"
 | 
				
			||||||
 | 
					];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export const addStartingGear = async (
 | 
				
			||||||
 | 
					    inventory: HydratedDocument<IInventoryDatabase, InventoryDocumentProps>,
 | 
				
			||||||
 | 
					    startingGear: TPartialStartingGear | undefined = undefined
 | 
				
			||||||
 | 
					) => {
 | 
				
			||||||
 | 
					    const { LongGuns, Pistols, Suits, Melee } = startingGear || {
 | 
				
			||||||
 | 
					        LongGuns: [{ ItemType: "/Lotus/Weapons/Tenno/Rifle/Rifle" }],
 | 
				
			||||||
 | 
					        Pistols: [{ ItemType: "/Lotus/Weapons/Tenno/Pistol/Pistol" }],
 | 
				
			||||||
 | 
					        Suits: [{ ItemType: "/Lotus/Powersuits/Excalibur/Excalibur" }],
 | 
				
			||||||
 | 
					        Melee: [{ ItemType: "/Lotus/Weapons/Tenno/Melee/LongSword/LongSword" }]
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    //TODO: properly merge weapon bin changes it is currently static here
 | 
				
			||||||
 | 
					    const inventoryChanges: IInventoryChanges = {};
 | 
				
			||||||
 | 
					    addEquipment(inventory, "LongGuns", LongGuns[0].ItemType, undefined, inventoryChanges);
 | 
				
			||||||
 | 
					    addEquipment(inventory, "Pistols", Pistols[0].ItemType, undefined, inventoryChanges);
 | 
				
			||||||
 | 
					    addEquipment(inventory, "Melee", Melee[0].ItemType, undefined, inventoryChanges);
 | 
				
			||||||
 | 
					    addEquipment(inventory, "Suits", Suits[0].ItemType, undefined, inventoryChanges, { Configs: Suits[0].Configs });
 | 
				
			||||||
 | 
					    addEquipment(
 | 
				
			||||||
 | 
					        inventory,
 | 
				
			||||||
 | 
					        "DataKnives",
 | 
				
			||||||
 | 
					        "/Lotus/Weapons/Tenno/HackingDevices/TnHackingDevice/TnHackingDeviceWeapon",
 | 
				
			||||||
 | 
					        undefined,
 | 
				
			||||||
 | 
					        inventoryChanges,
 | 
				
			||||||
 | 
					        { XP: 450_000 }
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					    addEquipment(
 | 
				
			||||||
 | 
					        inventory,
 | 
				
			||||||
 | 
					        "Scoops",
 | 
				
			||||||
 | 
					        "/Lotus/Weapons/Tenno/Speedball/SpeedballWeaponTest",
 | 
				
			||||||
 | 
					        undefined,
 | 
				
			||||||
 | 
					        inventoryChanges
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    updateSlots(inventory, InventorySlot.SUITS, 0, 1);
 | 
				
			||||||
 | 
					    updateSlots(inventory, InventorySlot.WEAPONS, 0, 3);
 | 
				
			||||||
 | 
					    inventoryChanges.SuitBin = { count: 1, platinum: 0, Slots: -1 };
 | 
				
			||||||
 | 
					    inventoryChanges.WeaponBin = { count: 3, platinum: 0, Slots: -3 };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    await addItem(inventory, "/Lotus/Types/Keys/VorsPrize/VorsPrizeQuestKeyChain");
 | 
				
			||||||
 | 
					    inventory.ActiveQuest = "/Lotus/Types/Keys/VorsPrize/VorsPrizeQuestKeyChain";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    inventory.PremiumCredits = 50;
 | 
				
			||||||
 | 
					    inventory.PremiumCreditsFree = 50;
 | 
				
			||||||
 | 
					    inventoryChanges.PremiumCredits = 50;
 | 
				
			||||||
 | 
					    inventoryChanges.PremiumCreditsFree = 50;
 | 
				
			||||||
 | 
					    inventory.RegularCredits = 3000;
 | 
				
			||||||
 | 
					    inventoryChanges.RegularCredits = 3000;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (const item of awakeningRewards) {
 | 
				
			||||||
 | 
					        const inventoryDelta = await addItem(inventory, item);
 | 
				
			||||||
 | 
					        combineInventoryChanges(inventoryChanges, inventoryDelta.InventoryChanges);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    inventory.PlayedParkourTutorial = true;
 | 
				
			||||||
 | 
					    inventory.ReceivedStartingGear = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return inventoryChanges;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
@ -63,8 +63,6 @@ export const manageQuestsController: RequestHandler = async (req, res) => {
 | 
				
			|||||||
                    inventory.ArchwingEnabled = true;
 | 
					                    inventory.ArchwingEnabled = true;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					 | 
				
			||||||
            inventory.ActiveQuest = "";
 | 
					 | 
				
			||||||
            break;
 | 
					            break;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        case "ResetAll": {
 | 
					        case "ResetAll": {
 | 
				
			||||||
@ -103,7 +101,6 @@ export const manageQuestsController: RequestHandler = async (req, res) => {
 | 
				
			|||||||
                    inventory.ArchwingEnabled = true;
 | 
					                    inventory.ArchwingEnabled = true;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            inventory.ActiveQuest = "";
 | 
					 | 
				
			||||||
            break;
 | 
					            break;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        case "giveAll": {
 | 
					        case "giveAll": {
 | 
				
			||||||
 | 
				
			|||||||
@ -64,7 +64,11 @@ import {
 | 
				
			|||||||
    IKubrowPetEggClient,
 | 
					    IKubrowPetEggClient,
 | 
				
			||||||
    ICustomMarkers,
 | 
					    ICustomMarkers,
 | 
				
			||||||
    IMarkerInfo,
 | 
					    IMarkerInfo,
 | 
				
			||||||
    IMarker
 | 
					    IMarker,
 | 
				
			||||||
 | 
					    ICalendarProgress,
 | 
				
			||||||
 | 
					    IPendingCouponDatabase,
 | 
				
			||||||
 | 
					    IPendingCouponClient,
 | 
				
			||||||
 | 
					    ILibraryAvailableDailyTaskInfo
 | 
				
			||||||
} from "../../types/inventoryTypes/inventoryTypes";
 | 
					} from "../../types/inventoryTypes/inventoryTypes";
 | 
				
			||||||
import { IOid } from "../../types/commonTypes";
 | 
					import { IOid } from "../../types/commonTypes";
 | 
				
			||||||
import {
 | 
					import {
 | 
				
			||||||
@ -323,7 +327,7 @@ MailboxSchema.set("toJSON", {
 | 
				
			|||||||
const DuviriInfoSchema = new Schema<IDuviriInfo>(
 | 
					const DuviriInfoSchema = new Schema<IDuviriInfo>(
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        Seed: Number,
 | 
					        Seed: Number,
 | 
				
			||||||
        NumCompletions: Number
 | 
					        NumCompletions: { type: Number, default: 0 }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        _id: false,
 | 
					        _id: false,
 | 
				
			||||||
@ -435,6 +439,7 @@ const seasonChallengeHistorySchema = new Schema<ISeasonChallenge>(
 | 
				
			|||||||
//TODO: check whether this is complete
 | 
					//TODO: check whether this is complete
 | 
				
			||||||
const playerSkillsSchema = new Schema<IPlayerSkills>(
 | 
					const playerSkillsSchema = new Schema<IPlayerSkills>(
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					        LPP_NONE: { type: Number, default: 0 },
 | 
				
			||||||
        LPP_SPACE: { type: Number, default: 0 },
 | 
					        LPP_SPACE: { type: Number, default: 0 },
 | 
				
			||||||
        LPS_PILOTING: { type: Number, default: 0 },
 | 
					        LPS_PILOTING: { type: Number, default: 0 },
 | 
				
			||||||
        LPS_GUNNERY: { type: Number, default: 0 },
 | 
					        LPS_GUNNERY: { type: Number, default: 0 },
 | 
				
			||||||
@ -891,19 +896,63 @@ const CustomMarkersSchema = new Schema<ICustomMarkers>(
 | 
				
			|||||||
    { _id: false }
 | 
					    { _id: false }
 | 
				
			||||||
);
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const calenderProgressSchema = new Schema<ICalendarProgress>(
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        Version: { type: Number, default: 19 },
 | 
				
			||||||
 | 
					        Iteration: { type: Number, default: 2 },
 | 
				
			||||||
 | 
					        YearProgress: {
 | 
				
			||||||
 | 
					            Upgrades: { type: [] }
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        SeasonProgress: {
 | 
				
			||||||
 | 
					            SeasonType: String,
 | 
				
			||||||
 | 
					            LastCompletedDayIdx: { type: Number, default: -1 },
 | 
				
			||||||
 | 
					            LastCompletedChallengeDayIdx: { type: Number, default: -1 },
 | 
				
			||||||
 | 
					            ActivatedChallenges: []
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    { _id: false }
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const pendingCouponSchema = new Schema<IPendingCouponDatabase>(
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        Expiry: { type: Date, default: new Date(0) },
 | 
				
			||||||
 | 
					        Discount: { type: Number, default: 0 }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    { _id: false }
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pendingCouponSchema.set("toJSON", {
 | 
				
			||||||
 | 
					    transform(_doc, ret, _options) {
 | 
				
			||||||
 | 
					        (ret as IPendingCouponClient).Expiry = toMongoDate((ret as IPendingCouponDatabase).Expiry);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const libraryAvailableDailyTaskInfoSchema = new Schema<ILibraryAvailableDailyTaskInfo>(
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        EnemyTypes: [String],
 | 
				
			||||||
 | 
					        EnemyLocTag: String,
 | 
				
			||||||
 | 
					        EnemyIcon: String,
 | 
				
			||||||
 | 
					        ScansRequired: Number,
 | 
				
			||||||
 | 
					        RewardStoreItem: String,
 | 
				
			||||||
 | 
					        RewardQuantity: Number,
 | 
				
			||||||
 | 
					        RewardStanding: Number
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    { _id: false }
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const inventorySchema = new Schema<IInventoryDatabase, InventoryDocumentProps>(
 | 
					const inventorySchema = new Schema<IInventoryDatabase, InventoryDocumentProps>(
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        accountOwnerId: Schema.Types.ObjectId,
 | 
					        accountOwnerId: Schema.Types.ObjectId,
 | 
				
			||||||
        SubscribedToEmails: Number,
 | 
					        SubscribedToEmails: { type: Number, default: 0 },
 | 
				
			||||||
        Created: Date,
 | 
					        SubscribedToEmailsPersonalized: { type: Number, default: 0 },
 | 
				
			||||||
        RewardSeed: Number,
 | 
					        RewardSeed: Number,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        //Credit
 | 
					        //Credit
 | 
				
			||||||
        RegularCredits: { type: Number, default: 0 },
 | 
					        RegularCredits: { type: Number, default: 0 },
 | 
				
			||||||
        //Platinum
 | 
					        //Platinum
 | 
				
			||||||
        PremiumCredits: { type: Number, default: 50 },
 | 
					        PremiumCredits: { type: Number, default: 0 },
 | 
				
			||||||
        //Gift Platinum(Non trade)
 | 
					        //Gift Platinum(Non trade)
 | 
				
			||||||
        PremiumCreditsFree: { type: Number, default: 50 },
 | 
					        PremiumCreditsFree: { type: Number, default: 0 },
 | 
				
			||||||
        //Endo
 | 
					        //Endo
 | 
				
			||||||
        FusionPoints: { type: Number, default: 0 },
 | 
					        FusionPoints: { type: Number, default: 0 },
 | 
				
			||||||
        //Regal Aya
 | 
					        //Regal Aya
 | 
				
			||||||
@ -911,7 +960,7 @@ const inventorySchema = new Schema<IInventoryDatabase, InventoryDocumentProps>(
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        //Slots
 | 
					        //Slots
 | 
				
			||||||
        SuitBin: { type: slotsBinSchema, default: { Slots: 3 } },
 | 
					        SuitBin: { type: slotsBinSchema, default: { Slots: 3 } },
 | 
				
			||||||
        WeaponBin: { type: slotsBinSchema, default: { Slots: 10 } },
 | 
					        WeaponBin: { type: slotsBinSchema, default: { Slots: 11 } },
 | 
				
			||||||
        SentinelBin: { type: slotsBinSchema, default: { Slots: 10 } },
 | 
					        SentinelBin: { type: slotsBinSchema, default: { Slots: 10 } },
 | 
				
			||||||
        SpaceSuitBin: { type: slotsBinSchema, default: { Slots: 4 } },
 | 
					        SpaceSuitBin: { type: slotsBinSchema, default: { Slots: 4 } },
 | 
				
			||||||
        SpaceWeaponBin: { type: slotsBinSchema, default: { Slots: 4 } },
 | 
					        SpaceWeaponBin: { type: slotsBinSchema, default: { Slots: 4 } },
 | 
				
			||||||
@ -1022,7 +1071,7 @@ const inventorySchema = new Schema<IInventoryDatabase, InventoryDocumentProps>(
 | 
				
			|||||||
        //Complete Mission\Quests
 | 
					        //Complete Mission\Quests
 | 
				
			||||||
        Missions: [missionSchema],
 | 
					        Missions: [missionSchema],
 | 
				
			||||||
        QuestKeys: [questKeysSchema],
 | 
					        QuestKeys: [questKeysSchema],
 | 
				
			||||||
        ActiveQuest: { type: String, default: "/Lotus/Types/Keys/VorsPrize/VorsPrizeQuestKeyChain" }, //TODO: check after mission starting gear
 | 
					        ActiveQuest: { type: String, default: "" },
 | 
				
			||||||
        //item like DojoKey or Boss missions key
 | 
					        //item like DojoKey or Boss missions key
 | 
				
			||||||
        LevelKeys: [Schema.Types.Mixed],
 | 
					        LevelKeys: [Schema.Types.Mixed],
 | 
				
			||||||
        //Active quests
 | 
					        //Active quests
 | 
				
			||||||
@ -1137,7 +1186,7 @@ const inventorySchema = new Schema<IInventoryDatabase, InventoryDocumentProps>(
 | 
				
			|||||||
        //Cephalon Simaris Entries Example:"TargetType"+"Scans"(1-10)+"Completed": true|false
 | 
					        //Cephalon Simaris Entries Example:"TargetType"+"Scans"(1-10)+"Completed": true|false
 | 
				
			||||||
        LibraryPersonalProgress: [Schema.Types.Mixed],
 | 
					        LibraryPersonalProgress: [Schema.Types.Mixed],
 | 
				
			||||||
        //Cephalon Simaris Daily Task
 | 
					        //Cephalon Simaris Daily Task
 | 
				
			||||||
        LibraryAvailableDailyTaskInfo: Schema.Types.Mixed,
 | 
					        LibraryAvailableDailyTaskInfo: libraryAvailableDailyTaskInfoSchema,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        //https://warframe.fandom.com/wiki/Invasion
 | 
					        //https://warframe.fandom.com/wiki/Invasion
 | 
				
			||||||
        InvasionChainProgress: [Schema.Types.Mixed],
 | 
					        InvasionChainProgress: [Schema.Types.Mixed],
 | 
				
			||||||
@ -1184,7 +1233,6 @@ const inventorySchema = new Schema<IInventoryDatabase, InventoryDocumentProps>(
 | 
				
			|||||||
        HandlerPoints: Number,
 | 
					        HandlerPoints: Number,
 | 
				
			||||||
        ChallengesFixVersion: Number,
 | 
					        ChallengesFixVersion: Number,
 | 
				
			||||||
        PlayedParkourTutorial: Boolean,
 | 
					        PlayedParkourTutorial: Boolean,
 | 
				
			||||||
        SubscribedToEmailsPersonalized: Number,
 | 
					 | 
				
			||||||
        ActiveLandscapeTraps: [Schema.Types.Mixed],
 | 
					        ActiveLandscapeTraps: [Schema.Types.Mixed],
 | 
				
			||||||
        RepVotes: [Schema.Types.Mixed],
 | 
					        RepVotes: [Schema.Types.Mixed],
 | 
				
			||||||
        LeagueTickets: [Schema.Types.Mixed],
 | 
					        LeagueTickets: [Schema.Types.Mixed],
 | 
				
			||||||
@ -1202,7 +1250,7 @@ const inventorySchema = new Schema<IInventoryDatabase, InventoryDocumentProps>(
 | 
				
			|||||||
        HasResetAccount: { type: Boolean, default: false },
 | 
					        HasResetAccount: { type: Boolean, default: false },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        //Discount Coupon
 | 
					        //Discount Coupon
 | 
				
			||||||
        PendingCoupon: Schema.Types.Mixed,
 | 
					        PendingCoupon: pendingCouponSchema,
 | 
				
			||||||
        //Like BossAladV,BossCaptainVor come for you on missions % chance
 | 
					        //Like BossAladV,BossCaptainVor come for you on missions % chance
 | 
				
			||||||
        DeathMarks: [String],
 | 
					        DeathMarks: [String],
 | 
				
			||||||
        //Zanuka
 | 
					        //Zanuka
 | 
				
			||||||
@ -1212,7 +1260,8 @@ const inventorySchema = new Schema<IInventoryDatabase, InventoryDocumentProps>(
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        EndlessXP: { type: [endlessXpProgressSchema], default: undefined },
 | 
					        EndlessXP: { type: [endlessXpProgressSchema], default: undefined },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        DialogueHistory: dialogueHistorySchema
 | 
					        DialogueHistory: dialogueHistorySchema,
 | 
				
			||||||
 | 
					        CalendarProgress: calenderProgressSchema
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    { timestamps: { createdAt: "Created", updatedAt: false } }
 | 
					    { timestamps: { createdAt: "Created", updatedAt: false } }
 | 
				
			||||||
);
 | 
					);
 | 
				
			||||||
 | 
				
			|||||||
@ -87,6 +87,7 @@ import { updateSessionGetController, updateSessionPostController } from "@/src/c
 | 
				
			|||||||
import { updateThemeController } from "../controllers/api/updateThemeController";
 | 
					import { updateThemeController } from "../controllers/api/updateThemeController";
 | 
				
			||||||
import { upgradesController } from "@/src/controllers/api/upgradesController";
 | 
					import { upgradesController } from "@/src/controllers/api/upgradesController";
 | 
				
			||||||
import { saveSettingsController } from "../controllers/api/saveSettingsController";
 | 
					import { saveSettingsController } from "../controllers/api/saveSettingsController";
 | 
				
			||||||
 | 
					import { giveStartingGearController } from "@/src/controllers/api/giveStartingGearController";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const apiRouter = express.Router();
 | 
					const apiRouter = express.Router();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -146,6 +147,7 @@ apiRouter.post("/gildWeapon.php", gildWeaponController);
 | 
				
			|||||||
apiRouter.post("/giveKeyChainTriggeredItems.php", giveKeyChainTriggeredItemsController);
 | 
					apiRouter.post("/giveKeyChainTriggeredItems.php", giveKeyChainTriggeredItemsController);
 | 
				
			||||||
apiRouter.post("/giveKeyChainTriggeredMessage.php", giveKeyChainTriggeredMessageController);
 | 
					apiRouter.post("/giveKeyChainTriggeredMessage.php", giveKeyChainTriggeredMessageController);
 | 
				
			||||||
apiRouter.post("/giveQuestKeyReward.php", giveQuestKeyRewardController);
 | 
					apiRouter.post("/giveQuestKeyReward.php", giveQuestKeyRewardController);
 | 
				
			||||||
 | 
					apiRouter.post("/giveStartingGear.php", giveStartingGearController);
 | 
				
			||||||
apiRouter.post("/guildTech.php", guildTechController);
 | 
					apiRouter.post("/guildTech.php", guildTechController);
 | 
				
			||||||
apiRouter.post("/hostSession.php", hostSessionController);
 | 
					apiRouter.post("/hostSession.php", hostSessionController);
 | 
				
			||||||
apiRouter.post("/infestedFoundry.php", infestedFoundryController);
 | 
					apiRouter.post("/infestedFoundry.php", infestedFoundryController);
 | 
				
			||||||
 | 
				
			|||||||
@ -2,7 +2,7 @@ import { IMessageDatabase, Inbox } from "@/src/models/inboxModel";
 | 
				
			|||||||
import { getAccountForRequest } from "@/src/services/loginService";
 | 
					import { getAccountForRequest } from "@/src/services/loginService";
 | 
				
			||||||
import { HydratedDocument } from "mongoose";
 | 
					import { HydratedDocument } from "mongoose";
 | 
				
			||||||
import { Request } from "express";
 | 
					import { Request } from "express";
 | 
				
			||||||
import messages from "@/static/fixed_responses/messages.json";
 | 
					import eventMessages from "@/static/fixed_responses/eventMessages.json";
 | 
				
			||||||
import { logger } from "@/src/utils/logger";
 | 
					import { logger } from "@/src/utils/logger";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const getAllMessagesSorted = async (accountId: string): Promise<HydratedDocument<IMessageDatabase>[]> => {
 | 
					export const getAllMessagesSorted = async (accountId: string): Promise<HydratedDocument<IMessageDatabase>[]> => {
 | 
				
			||||||
@ -32,7 +32,7 @@ export const createNewEventMessages = async (req: Request) => {
 | 
				
			|||||||
    const latestEventMessageDate = account.LatestEventMessageDate;
 | 
					    const latestEventMessageDate = account.LatestEventMessageDate;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    //TODO: is baroo there? create these kind of messages too (periodical messages)
 | 
					    //TODO: is baroo there? create these kind of messages too (periodical messages)
 | 
				
			||||||
    const newEventMessages = messages.Messages.filter(m => new Date(m.eventMessageDate) > latestEventMessageDate);
 | 
					    const newEventMessages = eventMessages.Messages.filter(m => new Date(m.eventMessageDate) > latestEventMessageDate);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (newEventMessages.length === 0) {
 | 
					    if (newEventMessages.length === 0) {
 | 
				
			||||||
        logger.debug(`No new event messages. Latest event message date: ${latestEventMessageDate.toISOString()}`);
 | 
					        logger.debug(`No new event messages. Latest event message date: ${latestEventMessageDate.toISOString()}`);
 | 
				
			||||||
 | 
				
			|||||||
@ -22,7 +22,9 @@ import {
 | 
				
			|||||||
    IDailyAffiliations,
 | 
					    IDailyAffiliations,
 | 
				
			||||||
    IInventoryDatabase,
 | 
					    IInventoryDatabase,
 | 
				
			||||||
    IKubrowPetEggDatabase,
 | 
					    IKubrowPetEggDatabase,
 | 
				
			||||||
    IKubrowPetEggClient
 | 
					    IKubrowPetEggClient,
 | 
				
			||||||
 | 
					    ILibraryAvailableDailyTaskInfo,
 | 
				
			||||||
 | 
					    ICalendarProgress
 | 
				
			||||||
} from "@/src/types/inventoryTypes/inventoryTypes";
 | 
					} from "@/src/types/inventoryTypes/inventoryTypes";
 | 
				
			||||||
import { IGenericUpdate } from "../types/genericUpdate";
 | 
					import { IGenericUpdate } from "../types/genericUpdate";
 | 
				
			||||||
import {
 | 
					import {
 | 
				
			||||||
@ -32,7 +34,7 @@ import {
 | 
				
			|||||||
} from "../types/requestTypes";
 | 
					} from "../types/requestTypes";
 | 
				
			||||||
import { logger } from "@/src/utils/logger";
 | 
					import { logger } from "@/src/utils/logger";
 | 
				
			||||||
import { getExalted, getKeyChainItems } from "@/src/services/itemDataService";
 | 
					import { getExalted, getKeyChainItems } from "@/src/services/itemDataService";
 | 
				
			||||||
import { IEquipmentClient, IItemConfig } from "../types/inventoryTypes/commonInventoryTypes";
 | 
					import { IEquipmentClient, IEquipmentDatabase, IItemConfig } from "../types/inventoryTypes/commonInventoryTypes";
 | 
				
			||||||
import {
 | 
					import {
 | 
				
			||||||
    ExportArcanes,
 | 
					    ExportArcanes,
 | 
				
			||||||
    ExportCustoms,
 | 
					    ExportCustoms,
 | 
				
			||||||
@ -51,6 +53,9 @@ import { createShip } from "./shipService";
 | 
				
			|||||||
import { creditBundles, fusionBundles } from "@/src/services/missionInventoryUpdateService";
 | 
					import { creditBundles, fusionBundles } from "@/src/services/missionInventoryUpdateService";
 | 
				
			||||||
import { IKeyChainRequest } from "@/src/controllers/api/giveKeyChainTriggeredItemsController";
 | 
					import { IKeyChainRequest } from "@/src/controllers/api/giveKeyChainTriggeredItemsController";
 | 
				
			||||||
import { toOid } from "../helpers/inventoryHelpers";
 | 
					import { toOid } from "../helpers/inventoryHelpers";
 | 
				
			||||||
 | 
					import { generateRewardSeed } from "@/src/controllers/api/getNewRewardSeedController";
 | 
				
			||||||
 | 
					import { addStartingGear } from "@/src/controllers/api/giveStartingGearController";
 | 
				
			||||||
 | 
					import { completeQuest } from "@/src/services/questService";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const createInventory = async (
 | 
					export const createInventory = async (
 | 
				
			||||||
    accountOwnerId: Types.ObjectId,
 | 
					    accountOwnerId: Types.ObjectId,
 | 
				
			||||||
@ -65,65 +70,18 @@ export const createInventory = async (
 | 
				
			|||||||
            ReceivedStartingGear: config.skipTutorial
 | 
					            ReceivedStartingGear: config.skipTutorial
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        inventory.LibraryAvailableDailyTaskInfo = createLibraryAvailableDailyTaskInfo();
 | 
				
			||||||
 | 
					        inventory.CalendarProgress = createCalendar();
 | 
				
			||||||
 | 
					        inventory.RewardSeed = generateRewardSeed();
 | 
				
			||||||
 | 
					        inventory.DuviriInfo = {
 | 
				
			||||||
 | 
					            Seed: generateRewardSeed(),
 | 
				
			||||||
 | 
					            NumCompletions: 0
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					        await addItem(inventory, "/Lotus/Types/Friendly/PlayerControllable/Weapons/DuviriDualSwords");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (config.skipTutorial) {
 | 
					        if (config.skipTutorial) {
 | 
				
			||||||
            const defaultEquipment = [
 | 
					            await addStartingGear(inventory);
 | 
				
			||||||
                // Awakening rewards
 | 
					            await completeQuest(inventory, "/Lotus/Types/Keys/VorsPrize/VorsPrizeQuestKeyChain");
 | 
				
			||||||
                { ItemCount: 1, ItemType: "/Lotus/Powersuits/Excalibur/Excalibur" },
 | 
					 | 
				
			||||||
                { ItemCount: 1, ItemType: "/Lotus/Weapons/Tenno/Melee/LongSword/LongSword" },
 | 
					 | 
				
			||||||
                { ItemCount: 1, ItemType: "/Lotus/Weapons/Tenno/Pistol/Pistol" },
 | 
					 | 
				
			||||||
                { ItemCount: 1, ItemType: "/Lotus/Weapons/Tenno/Rifle/Rifle" },
 | 
					 | 
				
			||||||
                { ItemCount: 1, ItemType: "/Lotus/Types/StoreItems/AvatarImages/AvatarImageItem1" },
 | 
					 | 
				
			||||||
                { ItemCount: 1, ItemType: "/Lotus/Types/StoreItems/AvatarImages/AvatarImageItem2" },
 | 
					 | 
				
			||||||
                { ItemCount: 1, ItemType: "/Lotus/Types/StoreItems/AvatarImages/AvatarImageItem3" },
 | 
					 | 
				
			||||||
                { ItemCount: 1, ItemType: "/Lotus/Types/StoreItems/AvatarImages/AvatarImageItem4" },
 | 
					 | 
				
			||||||
                { ItemCount: 1, ItemType: "/Lotus/Types/Restoratives/LisetAutoHack" }
 | 
					 | 
				
			||||||
            ];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            // const vorsPrizeRewards = [
 | 
					 | 
				
			||||||
            //     // Vor's Prize rewards
 | 
					 | 
				
			||||||
            //     { ItemCount: 1, ItemType: "/Lotus/Upgrades/Mods/Warframe/AvatarHealthMaxMod" },
 | 
					 | 
				
			||||||
            //     { ItemCount: 1, ItemType: "/Lotus/Upgrades/Mods/Warframe/AvatarShieldMaxMod" },
 | 
					 | 
				
			||||||
            //     { ItemCount: 1, ItemType: "/Lotus/Upgrades/Mods/Warframe/AvatarAbilityRangeMod" },
 | 
					 | 
				
			||||||
            //     { ItemCount: 1, ItemType: "/Lotus/Upgrades/Mods/Warframe/AvatarAbilityStrengthMod" },
 | 
					 | 
				
			||||||
            //     { ItemCount: 1, ItemType: "/Lotus/Upgrades/Mods/Warframe/AvatarAbilityDurationMod" },
 | 
					 | 
				
			||||||
            //     { ItemCount: 1, ItemType: "/Lotus/Upgrades/Mods/Warframe/AvatarPickupBonusMod" },
 | 
					 | 
				
			||||||
            //     { ItemCount: 1, ItemType: "/Lotus/Upgrades/Mods/Warframe/AvatarPowerMaxMod" },
 | 
					 | 
				
			||||||
            //     { ItemCount: 1, ItemType: "/Lotus/Upgrades/Mods/Warframe/AvatarEnemyRadarMod" },
 | 
					 | 
				
			||||||
            //     { ItemCount: 1, ItemType: "/Lotus/Upgrades/Mods/Melee/WeaponFireRateMod" },
 | 
					 | 
				
			||||||
            //     { ItemCount: 1, ItemType: "/Lotus/Upgrades/Mods/Melee/WeaponMeleeDamageMod" },
 | 
					 | 
				
			||||||
            //     { ItemCount: 1, ItemType: "/Lotus/Upgrades/Mods/Rifle/WeaponFactionDamageCorpus" },
 | 
					 | 
				
			||||||
            //     { ItemCount: 1, ItemType: "/Lotus/Upgrades/Mods/Rifle/WeaponFactionDamageGrineer" },
 | 
					 | 
				
			||||||
            //     { ItemCount: 1, ItemType: "/Lotus/Upgrades/Mods/Rifle/WeaponDamageAmountMod" },
 | 
					 | 
				
			||||||
            //     { ItemCount: 1, ItemType: "/Lotus/Upgrades/Mods/Pistol/WeaponFireDamageMod" },
 | 
					 | 
				
			||||||
            //     { ItemCount: 1, ItemType: "/Lotus/Upgrades/Mods/Pistol/WeaponElectricityDamageMod" },
 | 
					 | 
				
			||||||
            //     { ItemCount: 1, ItemType: "/Lotus/Upgrades/Mods/Pistol/WeaponDamageAmountMod" },
 | 
					 | 
				
			||||||
            //     { ItemCount: 1, ItemType: "/Lotus/Types/Recipes/Weapons/BurstonRifleBlueprint" },
 | 
					 | 
				
			||||||
            //     { ItemCount: 1, ItemType: "/Lotus/Types/Items/MiscItems/Morphic" },
 | 
					 | 
				
			||||||
            //     { ItemCount: 400, ItemType: "/Lotus/Types/Items/MiscItems/PolymerBundle" },
 | 
					 | 
				
			||||||
            //     { ItemCount: 150, ItemType: "/Lotus/Types/Items/MiscItems/AlloyPlate" }
 | 
					 | 
				
			||||||
            // ];
 | 
					 | 
				
			||||||
            for (const equipment of defaultEquipment) {
 | 
					 | 
				
			||||||
                await addItem(inventory, equipment.ItemType, equipment.ItemCount);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            // Missing in Public Export
 | 
					 | 
				
			||||||
            inventory.Horses.push({
 | 
					 | 
				
			||||||
                ItemType: "/Lotus/Types/NeutralCreatures/ErsatzHorse/ErsatzHorsePowerSuit"
 | 
					 | 
				
			||||||
            });
 | 
					 | 
				
			||||||
            inventory.DataKnives.push({
 | 
					 | 
				
			||||||
                ItemType: "/Lotus/Weapons/Tenno/HackingDevices/TnHackingDevice/TnHackingDeviceWeapon",
 | 
					 | 
				
			||||||
                XP: 450000
 | 
					 | 
				
			||||||
            });
 | 
					 | 
				
			||||||
            inventory.Scoops.push({
 | 
					 | 
				
			||||||
                ItemType: "/Lotus/Weapons/Tenno/Speedball/SpeedballWeaponTest"
 | 
					 | 
				
			||||||
            });
 | 
					 | 
				
			||||||
            inventory.DrifterMelee.push({
 | 
					 | 
				
			||||||
                ItemType: "/Lotus/Types/Friendly/PlayerControllable/Weapons/DuviriDualSwords"
 | 
					 | 
				
			||||||
            });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            inventory.QuestKeys.push({
 | 
					 | 
				
			||||||
                ItemType: "/Lotus/Types/Keys/VorsPrize/VorsPrizeQuestKeyChain"
 | 
					 | 
				
			||||||
            });
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
            const completedMissions = ["SolNode27", "SolNode89", "SolNode63", "SolNode85", "SolNode15", "SolNode79"];
 | 
					            const completedMissions = ["SolNode27", "SolNode89", "SolNode63", "SolNode85", "SolNode15", "SolNode79"];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -133,14 +91,11 @@ export const createInventory = async (
 | 
				
			|||||||
                    Tag: tag
 | 
					                    Tag: tag
 | 
				
			||||||
                }))
 | 
					                }))
 | 
				
			||||||
            );
 | 
					            );
 | 
				
			||||||
 | 
					 | 
				
			||||||
            inventory.RegularCredits = 25000;
 | 
					 | 
				
			||||||
            inventory.FusionPoints = 180;
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        await inventory.save();
 | 
					        await inventory.save();
 | 
				
			||||||
    } catch (error) {
 | 
					    } catch (error) {
 | 
				
			||||||
        throw new Error(`Error creating inventory: ${error instanceof Error ? error.message : "Unknown error"}`);
 | 
					        throw new Error(`Error creating inventory: ${error instanceof Error ? error.message : "Unknown error type"}`);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -150,6 +105,7 @@ export const createInventory = async (
 | 
				
			|||||||
 * @param InventoryChanges - will hold the combined changes
 | 
					 * @param InventoryChanges - will hold the combined changes
 | 
				
			||||||
 * @param delta - inventory changes to be added
 | 
					 * @param delta - inventory changes to be added
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					//TODO: this fails silently when providing an incorrect object to delta
 | 
				
			||||||
export const combineInventoryChanges = (InventoryChanges: IInventoryChanges, delta: IInventoryChanges): void => {
 | 
					export const combineInventoryChanges = (InventoryChanges: IInventoryChanges, delta: IInventoryChanges): void => {
 | 
				
			||||||
    for (const key in delta) {
 | 
					    for (const key in delta) {
 | 
				
			||||||
        if (!(key in InventoryChanges)) {
 | 
					        if (!(key in InventoryChanges)) {
 | 
				
			||||||
@ -779,15 +735,19 @@ export const addEquipment = (
 | 
				
			|||||||
    category: TEquipmentKey,
 | 
					    category: TEquipmentKey,
 | 
				
			||||||
    type: string,
 | 
					    type: string,
 | 
				
			||||||
    modularParts: string[] | undefined = undefined,
 | 
					    modularParts: string[] | undefined = undefined,
 | 
				
			||||||
    inventoryChanges: IInventoryChanges = {}
 | 
					    inventoryChanges: IInventoryChanges = {},
 | 
				
			||||||
 | 
					    defaultOverwrites: Partial<IEquipmentDatabase> | undefined = undefined
 | 
				
			||||||
): IInventoryChanges => {
 | 
					): IInventoryChanges => {
 | 
				
			||||||
    const index =
 | 
					    const equipment = Object.assign(
 | 
				
			||||||
        inventory[category].push({
 | 
					        {
 | 
				
			||||||
            ItemType: type,
 | 
					            ItemType: type,
 | 
				
			||||||
            Configs: [],
 | 
					            Configs: [],
 | 
				
			||||||
            XP: 0,
 | 
					            XP: 0,
 | 
				
			||||||
            ModularParts: modularParts
 | 
					            ModularParts: modularParts
 | 
				
			||||||
        }) - 1;
 | 
					        },
 | 
				
			||||||
 | 
					        defaultOverwrites
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					    const index = inventory[category].push(equipment) - 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    inventoryChanges[category] ??= [];
 | 
					    inventoryChanges[category] ??= [];
 | 
				
			||||||
    inventoryChanges[category].push(inventory[category][index].toJSON<IEquipmentClient>());
 | 
					    inventoryChanges[category].push(inventory[category][index].toJSON<IEquipmentClient>());
 | 
				
			||||||
@ -1173,3 +1133,28 @@ export const addKeyChainItems = async (
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    return inventoryChanges;
 | 
					    return inventoryChanges;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					const createLibraryAvailableDailyTaskInfo = (): ILibraryAvailableDailyTaskInfo => {
 | 
				
			||||||
 | 
					    return {
 | 
				
			||||||
 | 
					        EnemyTypes: ["/Lotus/Types/Enemies/Orokin/RifleLancerAvatar"],
 | 
				
			||||||
 | 
					        EnemyLocTag: "/Lotus/Language/Game/CorruptedLancer",
 | 
				
			||||||
 | 
					        EnemyIcon: "/Lotus/Interface/Icons/Npcs/OrokinRifleLancerAvatar.png",
 | 
				
			||||||
 | 
					        ScansRequired: 3,
 | 
				
			||||||
 | 
					        RewardStoreItem: "/Lotus/StoreItems/Upgrades/Mods/FusionBundles/UncommonFusionBundle",
 | 
				
			||||||
 | 
					        RewardQuantity: 7,
 | 
				
			||||||
 | 
					        RewardStanding: 7500
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const createCalendar = (): ICalendarProgress => {
 | 
				
			||||||
 | 
					    return {
 | 
				
			||||||
 | 
					        Version: 19,
 | 
				
			||||||
 | 
					        Iteration: 2,
 | 
				
			||||||
 | 
					        YearProgress: { Upgrades: [] },
 | 
				
			||||||
 | 
					        SeasonProgress: {
 | 
				
			||||||
 | 
					            SeasonType: "CST_SPRING",
 | 
				
			||||||
 | 
					            LastCompletedDayIdx: -1,
 | 
				
			||||||
 | 
					            LastCompletedChallengeDayIdx: -1,
 | 
				
			||||||
 | 
					            ActivatedChallenges: []
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
				
			|||||||
@ -126,7 +126,8 @@ export const completeQuest = async (inventory: TInventoryDatabaseDocument, quest
 | 
				
			|||||||
            });
 | 
					            });
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    //TODO: handle quest completions
 | 
					    inventory.ActiveQuest = "";
 | 
				
			||||||
 | 
					    //TODO: handle quest completion items
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const giveKeyChainItem = async (inventory: TInventoryDatabaseDocument, keyChainInfo: IKeyChainRequest) => {
 | 
					export const giveKeyChainItem = async (inventory: TInventoryDatabaseDocument, keyChainInfo: IKeyChainRequest) => {
 | 
				
			||||||
 | 
				
			|||||||
@ -38,6 +38,7 @@ export interface IInventoryDatabase
 | 
				
			|||||||
            | "InfestedFoundry"
 | 
					            | "InfestedFoundry"
 | 
				
			||||||
            | "DialogueHistory"
 | 
					            | "DialogueHistory"
 | 
				
			||||||
            | "KubrowPetEggs"
 | 
					            | "KubrowPetEggs"
 | 
				
			||||||
 | 
					            | "PendingCoupon"
 | 
				
			||||||
            | TEquipmentKey
 | 
					            | TEquipmentKey
 | 
				
			||||||
        >,
 | 
					        >,
 | 
				
			||||||
        InventoryDatabaseEquipment {
 | 
					        InventoryDatabaseEquipment {
 | 
				
			||||||
@ -61,6 +62,7 @@ export interface IInventoryDatabase
 | 
				
			|||||||
    InfestedFoundry?: IInfestedFoundryDatabase;
 | 
					    InfestedFoundry?: IInfestedFoundryDatabase;
 | 
				
			||||||
    DialogueHistory?: IDialogueHistoryDatabase;
 | 
					    DialogueHistory?: IDialogueHistoryDatabase;
 | 
				
			||||||
    KubrowPetEggs?: IKubrowPetEggDatabase[];
 | 
					    KubrowPetEggs?: IKubrowPetEggDatabase[];
 | 
				
			||||||
 | 
					    PendingCoupon: IPendingCouponDatabase;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export interface IQuestKeyDatabase {
 | 
					export interface IQuestKeyDatabase {
 | 
				
			||||||
@ -318,11 +320,12 @@ export interface IInventoryClient extends IDailyAffiliations, InventoryClientEqu
 | 
				
			|||||||
    CollectibleSeries: ICollectibleSery[];
 | 
					    CollectibleSeries: ICollectibleSery[];
 | 
				
			||||||
    LibraryAvailableDailyTaskInfo: ILibraryAvailableDailyTaskInfo;
 | 
					    LibraryAvailableDailyTaskInfo: ILibraryAvailableDailyTaskInfo;
 | 
				
			||||||
    HasResetAccount: boolean;
 | 
					    HasResetAccount: boolean;
 | 
				
			||||||
    PendingCoupon: IPendingCoupon;
 | 
					    PendingCoupon: IPendingCouponClient;
 | 
				
			||||||
    Harvestable: boolean;
 | 
					    Harvestable: boolean;
 | 
				
			||||||
    DeathSquadable: boolean;
 | 
					    DeathSquadable: boolean;
 | 
				
			||||||
    EndlessXP?: IEndlessXpProgress[];
 | 
					    EndlessXP?: IEndlessXpProgress[];
 | 
				
			||||||
    DialogueHistory?: IDialogueHistoryClient;
 | 
					    DialogueHistory?: IDialogueHistoryClient;
 | 
				
			||||||
 | 
					    CalendarProgress: ICalendarProgress;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export interface IAffiliation {
 | 
					export interface IAffiliation {
 | 
				
			||||||
@ -759,7 +762,12 @@ export enum Manifest {
 | 
				
			|||||||
    LotusTypesGameNemesisKuvaLichKuvaLichManifestVersionTwo = "/Lotus/Types/Game/Nemesis/KuvaLich/KuvaLichManifestVersionTwo"
 | 
					    LotusTypesGameNemesisKuvaLichKuvaLichManifestVersionTwo = "/Lotus/Types/Game/Nemesis/KuvaLich/KuvaLichManifestVersionTwo"
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export interface IPendingCoupon {
 | 
					export interface IPendingCouponDatabase {
 | 
				
			||||||
 | 
					    Expiry: Date;
 | 
				
			||||||
 | 
					    Discount: number;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export interface IPendingCouponClient {
 | 
				
			||||||
    Expiry: IMongoDate;
 | 
					    Expiry: IMongoDate;
 | 
				
			||||||
    Discount: number;
 | 
					    Discount: number;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -858,6 +866,7 @@ export interface IPersonalTechProject {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export interface IPlayerSkills {
 | 
					export interface IPlayerSkills {
 | 
				
			||||||
 | 
					    LPP_NONE: number;
 | 
				
			||||||
    LPP_SPACE: number;
 | 
					    LPP_SPACE: number;
 | 
				
			||||||
    LPS_PILOTING: number;
 | 
					    LPS_PILOTING: number;
 | 
				
			||||||
    LPS_GUNNERY: number;
 | 
					    LPS_GUNNERY: number;
 | 
				
			||||||
@ -1042,3 +1051,16 @@ export interface IMarker {
 | 
				
			|||||||
    z: number;
 | 
					    z: number;
 | 
				
			||||||
    showInHud: boolean;
 | 
					    showInHud: boolean;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					export interface ISeasonProgress {
 | 
				
			||||||
 | 
					    SeasonType: "CST_UNDEFINED" | "CST_WINTER" | "CST_SPRING" | "CST_SUMMER" | "CST_FALL";
 | 
				
			||||||
 | 
					    LastCompletedDayIdx: number;
 | 
				
			||||||
 | 
					    LastCompletedChallengeDayIdx: number;
 | 
				
			||||||
 | 
					    ActivatedChallenges: unknown[];
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export interface ICalendarProgress {
 | 
				
			||||||
 | 
					    Version: number;
 | 
				
			||||||
 | 
					    Iteration: number;
 | 
				
			||||||
 | 
					    YearProgress: { Upgrades: unknown[] };
 | 
				
			||||||
 | 
					    SeasonProgress: ISeasonProgress;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										12
									
								
								static/fixed_responses/eventMessages.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								static/fixed_responses/eventMessages.json
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,12 @@
 | 
				
			|||||||
 | 
					{
 | 
				
			||||||
 | 
					  "Messages": [
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      "sub": "Welcome to Space Ninja Server",
 | 
				
			||||||
 | 
					      "sndr": "/Lotus/Language/Bosses/Ordis",
 | 
				
			||||||
 | 
					      "msg": "Enjoy your Space Ninja Experience",
 | 
				
			||||||
 | 
					      "icon": "/Lotus/Interface/Icons/Npcs/Darvo.png",
 | 
				
			||||||
 | 
					      "eventMessageDate": "2025-01-30T13:00:00.000Z",
 | 
				
			||||||
 | 
					      "r": false
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  ]
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -1,49 +0,0 @@
 | 
				
			|||||||
{
 | 
					 | 
				
			||||||
  "Messages": [
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
      "sub": "Welcome to Space Ninja Server",
 | 
					 | 
				
			||||||
      "sndr": "/Lotus/Language/Bosses/Ordis",
 | 
					 | 
				
			||||||
      "msg": "Enjoy your Space Ninja Experience",
 | 
					 | 
				
			||||||
      "icon": "/Lotus/Interface/Icons/Npcs/Darvo.png",
 | 
					 | 
				
			||||||
      "eventMessageDate": "2025-01-30T13:00:00.000Z",
 | 
					 | 
				
			||||||
      "r": false
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
      "sub": "/Lotus/Language/Inbox/DarvoWeaponCraftingMessageBTitle",
 | 
					 | 
				
			||||||
      "sndr": "/Lotus/Language/Bosses/Darvo",
 | 
					 | 
				
			||||||
      "msg": "/Lotus/Language/Inbox/DarvoWeaponCraftingMessageBDesc",
 | 
					 | 
				
			||||||
      "icon": "/Lotus/Interface/Icons/Npcs/Darvo.png",
 | 
					 | 
				
			||||||
      "countedAtt": [
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
          "ItemCount": 1,
 | 
					 | 
				
			||||||
          "ItemType": "/Lotus/Types/Recipes/Weapons/BurstonRifleBlueprint"
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
          "ItemCount": 1,
 | 
					 | 
				
			||||||
          "ItemType": "/Lotus/Types/Items/MiscItems/Morphic"
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
          "ItemCount": 400,
 | 
					 | 
				
			||||||
          "ItemType": "/Lotus/Types/Items/MiscItems/PolymerBundle"
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
          "ItemCount": 150,
 | 
					 | 
				
			||||||
          "ItemType": "/Lotus/Types/Items/MiscItems/AlloyPlate"
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      ],
 | 
					 | 
				
			||||||
      "highPriority": true,
 | 
					 | 
				
			||||||
      "eventMessageDate": "2023-10-01T17:00:00.000Z",
 | 
					 | 
				
			||||||
      "r": false
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
      "sub": "/Lotus/Language/G1Quests/Beginner_Growth_Inbox_Title",
 | 
					 | 
				
			||||||
      "sndr": "/Lotus/Language/Menu/Mailbox_WarframeSender",
 | 
					 | 
				
			||||||
      "msg": "/Lotus/Language/G1Quests/Beginner_Growth_Inbox_Desc",
 | 
					 | 
				
			||||||
      "icon": "/Lotus/Interface/Icons/Npcs/Lotus_d.png",
 | 
					 | 
				
			||||||
      "transmission": "/Lotus/Sounds/Dialog/VorsPrize/DLisetPostAssassinate110Lotus",
 | 
					 | 
				
			||||||
      "highPriority": true,
 | 
					 | 
				
			||||||
      "eventMessageDate": "2023-09-01T17:00:00.000Z",
 | 
					 | 
				
			||||||
      "r": false
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  ]
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user