diff --git a/package-lock.json b/package-lock.json index ec52be41..a43d45a2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4093,9 +4093,9 @@ } }, "node_modules/warframe-public-export-plus": { - "version": "0.5.30", - "resolved": "https://registry.npmjs.org/warframe-public-export-plus/-/warframe-public-export-plus-0.5.30.tgz", - "integrity": "sha512-vzs+naEqp3iFZTbgIky4jiNbjNIovuR4oSimrFiuyIbrnfTlfXFzDfzT0hG2rgS8yEXBAbOcv2Zfm3fmWuZ0Kg==" + "version": "0.5.32", + "resolved": "https://registry.npmjs.org/warframe-public-export-plus/-/warframe-public-export-plus-0.5.32.tgz", + "integrity": "sha512-jO9i2Gzz9DWibiHlEO17D975ajs6KrTay8cS5I0GkUUe1XWVU8mML4b+IYCHzM4FWq1t6p2YPCGznQfknqvorg==" }, "node_modules/warframe-riven-info": { "version": "0.1.2", diff --git a/src/controllers/api/giveStartingGearController.ts b/src/controllers/api/giveStartingGearController.ts index 4969c83c..c1ead7dd 100644 --- a/src/controllers/api/giveStartingGearController.ts +++ b/src/controllers/api/giveStartingGearController.ts @@ -1 +1,127 @@ -export const giveStartingGearController = async () => {}; +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; + +export const giveStartingGearController: RequestHandler = async (req, res) => { + const accountId = await getAccountIdForRequest(req); + const startingGear = getJSONfromString(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, + 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); + } + // currentloadoutids + + // "LoadOutPresets": { + // "NORMAL": [ + // { + // "s": { + // "ItemId": { "$oid": "67b73fbfb56b4b84d70433c2" }, + // "mod": 0, + // "cus": 0 + // }, + // "p": { + // "ItemId": { "$oid": "67b73fbfb56b4b84d70433c5" }, + // "mod": 0, + // "cus": 0 + // }, + // "l": { + // "ItemId": { "$oid": "67b73fbfb56b4b84d70433c4" }, + // "mod": 0, + // "cus": 0 + // }, + // "m": { + // "ItemId": { "$oid": "67b73fbfb56b4b84d70433c6" }, + // "mod": 0, + // "cus": 0 + // }, + // "ItemId": { "$oid": "67b73fbfb56b4b84d70433c7" } + // } + // ] + // }, + + inventory.PlayedParkourTutorial = true; + inventory.ReceivedStartingGear = true; + + //originally ship is returned + //also weaponskins + return inventoryChanges; +}; diff --git a/src/services/inventoryService.ts b/src/services/inventoryService.ts index 32d0ca05..a553eb8c 100644 --- a/src/services/inventoryService.ts +++ b/src/services/inventoryService.ts @@ -23,7 +23,8 @@ import { IInventoryDatabase, IKubrowPetEggDatabase, IKubrowPetEggClient, - ILibraryAvailableDailyTaskInfo + ILibraryAvailableDailyTaskInfo, + ICalendarProgress } from "@/src/types/inventoryTypes/inventoryTypes"; import { IGenericUpdate } from "../types/genericUpdate"; import { @@ -33,7 +34,7 @@ import { } from "../types/requestTypes"; import { logger } from "@/src/utils/logger"; import { getExalted, getKeyChainItems } from "@/src/services/itemDataService"; -import { IEquipmentClient, IItemConfig } from "../types/inventoryTypes/commonInventoryTypes"; +import { IEquipmentClient, IEquipmentDatabase, IItemConfig } from "../types/inventoryTypes/commonInventoryTypes"; import { ExportArcanes, ExportCustoms, @@ -53,6 +54,8 @@ import { creditBundles, fusionBundles } from "@/src/services/missionInventoryUpd import { IKeyChainRequest } from "@/src/controllers/api/giveKeyChainTriggeredItemsController"; 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 ( accountOwnerId: Types.ObjectId, @@ -68,68 +71,17 @@ export const createInventory = async ( }); inventory.LibraryAvailableDailyTaskInfo = createLibraryAvailableDailyTaskInfo(); + inventory.CalendarProgress = createCalendar(); inventory.RewardSeed = generateRewardSeed(); - //await addItem(inventory, "/Lotus/Types/Friendly/PlayerControllable/Weapons/DuviriDualSwords"); TODO: can enable this once driter melees have been added to export + inventory.DuviriInfo = { + Seed: generateRewardSeed(), + NumCompletions: 0 + }; + await addItem(inventory, "/Lotus/Types/Friendly/PlayerControllable/Weapons/DuviriDualSwords"); if (config.skipTutorial) { - const defaultEquipment = [ - // Awakening rewards - { 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" - }); + await addStartingGear(inventory); + await completeQuest(inventory, "/Lotus/Types/Keys/VorsPrize/VorsPrizeQuestKeyChain"); const completedMissions = ["SolNode27", "SolNode89", "SolNode63", "SolNode85", "SolNode15", "SolNode79"]; @@ -139,9 +91,6 @@ export const createInventory = async ( Tag: tag })) ); - - inventory.RegularCredits = 25000; - inventory.FusionPoints = 180; } await inventory.save(); @@ -156,6 +105,7 @@ export const createInventory = async ( * @param InventoryChanges - will hold the combined changes * @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 => { for (const key in delta) { if (!(key in InventoryChanges)) { @@ -596,7 +546,8 @@ export const addSentinelWeapon = ( export const addPowerSuit = ( inventory: TInventoryDatabaseDocument, powersuitName: string, - inventoryChanges: IInventoryChanges = {} + inventoryChanges: IInventoryChanges = {}, + configs: IItemConfig[] = [] ): IInventoryChanges => { const specialItems = getExalted(powersuitName); if (specialItems) { @@ -604,7 +555,7 @@ export const addPowerSuit = ( addSpecialItem(inventory, specialItem, inventoryChanges); } } - const suitIndex = inventory.Suits.push({ ItemType: powersuitName, Configs: [], UpgradeVer: 101, XP: 0 }) - 1; + const suitIndex = inventory.Suits.push({ ItemType: powersuitName, Configs: configs, UpgradeVer: 101, XP: 0 }) - 1; inventoryChanges.Suits ??= []; inventoryChanges.Suits.push(inventory.Suits[suitIndex].toJSON()); return inventoryChanges; @@ -785,15 +736,19 @@ export const addEquipment = ( category: TEquipmentKey, type: string, modularParts: string[] | undefined = undefined, - inventoryChanges: IInventoryChanges = {} + inventoryChanges: IInventoryChanges = {}, + defaultOverwrites: Partial | undefined = undefined ): IInventoryChanges => { - const index = - inventory[category].push({ + const equipment = Object.assign( + { ItemType: type, Configs: [], XP: 0, ModularParts: modularParts - }) - 1; + }, + defaultOverwrites + ); + const index = inventory[category].push(equipment) - 1; inventoryChanges[category] ??= []; inventoryChanges[category].push(inventory[category][index].toJSON()); @@ -1190,3 +1145,17 @@ const createLibraryAvailableDailyTaskInfo = (): ILibraryAvailableDailyTaskInfo = RewardStanding: 7500 }; }; + +const createCalendar = (): ICalendarProgress => { + return { + Version: 19, + Iteration: 2, + YearProgress: { Upgrades: [] }, + SeasonProgress: { + SeasonType: "CST_SPRING", + LastCompletedDayIdx: -1, + LastCompletedChallengeDayIdx: -1, + ActivatedChallenges: [] + } + }; +};