From ce4a9c85faa4d20de6b63bb2bf0774dcffef2d78 Mon Sep 17 00:00:00 2001 From: AMelonInsideLemon <166175391+AMelonInsideLemon@users.noreply.github.com> Date: Mon, 29 Jul 2024 18:49:45 +0200 Subject: [PATCH] feat: acquiring a sentinel mods and weapon Closes #323 --- src/services/inventoryService.ts | 68 +++++++++++++++++++++++++------- src/services/itemDataService.ts | 26 ++++++++++-- 2 files changed, 76 insertions(+), 18 deletions(-) diff --git a/src/services/inventoryService.ts b/src/services/inventoryService.ts index c32a8af1..83355e89 100644 --- a/src/services/inventoryService.ts +++ b/src/services/inventoryService.ts @@ -27,7 +27,7 @@ import { IUpdateChallengeProgressRequest } from "../types/requestTypes"; import { logger } from "@/src/utils/logger"; -import { getWeaponType, getExalted } from "@/src/services/itemDataService"; +import { getWeaponType, getExalted, getSentinelDefaultEquipment } from "@/src/services/itemDataService"; import { getRandomWeightedReward } from "@/src/services/rngService"; import { ISyndicateSacrifice, ISyndicateSacrificeResponse } from "../types/syndicateTypes"; import { IEquipmentClient } from "../types/inventoryTypes/commonInventoryTypes"; @@ -264,15 +264,8 @@ export const addItem = async ( case "Types": switch (typeName.substr(1).split("/")[2]) { case "Sentinels": - // TOOD: Sentinels should also grant their DefaultUpgrades & SentinelWeapon. - const sentinel = await addSentinel(typeName, accountId); - await updateSlots(accountId, InventorySlot.SENTINELS, 0, 1); - return { - InventoryChanges: { - SentinelBin: { count: 1, platinum: 0, Slots: -1 }, - Sentinels: [sentinel] - } - }; + const changes = await addSentinel(typeName, accountId); + return { InventoryChanges: changes }; case "Items": { switch (typeName.substr(1).split("/")[3]) { case "ShipDecos": { @@ -353,15 +346,61 @@ export const addItem = async ( //TODO: maybe genericMethod for all the add methods, they share a lot of logic export const addSentinel = async (sentinelName: string, accountId: string) => { + const defaultEquipment = getSentinelDefaultEquipment(sentinelName) || { + defaultWeapon: undefined, + defaultUpgrades: [] + }; + const sentinelWeapon = defaultEquipment.defaultWeapon + ? await addEquipment("SentinelWeapons", defaultEquipment.defaultWeapon, accountId) + : undefined; const inventory = await getInventory(accountId); - const sentinelIndex = inventory.Sentinels.push({ ItemType: sentinelName, Configs: [], XP: 0 }); + + const mods = (defaultEquipment.defaultUpgrades || []).map(upgrade => { + const itemIndex = inventory.RawUpgrades.findIndex(i => i.ItemType === upgrade.ItemType); + if (itemIndex !== -1) { + inventory.RawUpgrades[itemIndex].ItemCount += 1; + } else { + inventory.RawUpgrades.push({ ItemCount: 1, ItemType: upgrade.ItemType }); + } + return { ItemType: upgrade.ItemType, ItemCount: 1 }; + }); + + const configs = [{ Upgrades: new Array(10).fill("") }]; + const defaultSlots = [0, 4, 5, 9]; + const usedSlots = new Set(); + + (defaultEquipment.defaultUpgrades || []).forEach(upgrade => { + const slotIndex = upgrade.Slot !== -1 ? upgrade.Slot : defaultSlots.find(slot => !usedSlots.has(slot)); + if (slotIndex !== undefined && slotIndex < 10) { + configs[0].Upgrades[slotIndex] = upgrade.ItemType; + usedSlots.add(slotIndex); + } + }); + + inventory.Sentinels.push({ + ItemType: sentinelName, + Configs: configs, + XP: 0 + }); + const changedInventory = await inventory.save(); - return changedInventory.Sentinels[sentinelIndex - 1].toJSON(); + await updateSlots(accountId, InventorySlot.SENTINELS, 0, sentinelWeapon ? 2 : 1); + + return { + SentinelBin: { + count: sentinelWeapon ? 2 : 1, + platinum: 0, + Slots: sentinelWeapon ? -2 : -1 + }, + RawUpgrades: mods, + SentinelWeapons: sentinelWeapon ? [sentinelWeapon] : [], + Sentinels: [changedInventory.Sentinels[changedInventory.Sentinels.length - 1].toJSON()] + }; }; export const addPowerSuit = async (powersuitName: string, accountId: string): Promise => { const specialItems = getExalted(powersuitName); - if (specialItems != false) { + if (specialItems) { for await (const specialItem of specialItems) { await addSpecialItem(specialItem, accountId); } @@ -374,7 +413,7 @@ export const addPowerSuit = async (powersuitName: string, accountId: string): Pr export const addMechSuit = async (mechsuitName: string, accountId: string) => { const specialItems = getExalted(mechsuitName); - if (specialItems != false) { + if (specialItems) { for await (const specialItem of specialItems) { await addSpecialItem(specialItem, accountId); } @@ -647,6 +686,7 @@ export const addMods = (inventory: IInventoryDatabaseDocument, itemsArray: IRawU inventory.markModified(`RawUpgrades.${itemIndex}.ItemCount`); } else { RawUpgrades.push({ ItemCount, ItemType }); + inventory.markModified("RawUpgrades"); } }); }; diff --git a/src/services/itemDataService.ts b/src/services/itemDataService.ts index 3bf039dd..416728c7 100644 --- a/src/services/itemDataService.ts +++ b/src/services/itemDataService.ts @@ -3,10 +3,12 @@ import { logger } from "@/src/utils/logger"; import { dict_en, ExportRecipes, + ExportSentinels, ExportWarframes, ExportWeapons, IPowersuit, - IRecipe + IRecipe, + ISentinel } from "warframe-public-export-plus"; export type WeaponTypeInternal = @@ -47,10 +49,22 @@ export const getRecipe = (uniqueName: string): IRecipe | undefined => { export const getExalted = (uniqueName: string) => { const suit = getSuitByUniqueName(uniqueName); - if (suit?.exalted !== undefined) { - return suit.exalted; + if (suit) { + return suit.exalted || undefined; } else { - return false; + return undefined; + } +}; + +export const getSentinelDefaultEquipment = (uniqueName: string) => { + const sentinel = getSentinelByUniqueName(uniqueName); + if (sentinel) { + return { + defaultWeapon: sentinel.defaultWeapon || undefined, + defaultUpgrades: sentinel.defaultUpgrades || undefined + }; + } else { + return undefined; } }; @@ -75,6 +89,10 @@ export const getSuitByUniqueName = (uniqueName: string): IPowersuit | undefined return ExportWarframes[uniqueName]; }; +export const getSentinelByUniqueName = (uniqueName: string): ISentinel | undefined => { + return ExportSentinels[uniqueName]; +}; + export const getEnglishString = (key: string): string => { return dict_en[key] ?? key; };