From 1c276ce133de71a3440d00655bbd7d162170385b Mon Sep 17 00:00:00 2001 From: Sainan Date: Sun, 9 Mar 2025 07:42:55 -0700 Subject: [PATCH] feat: stripped rewards (#1123) Closes #683 Reviewed-on: https://onlyg.it/OpenWF/SpaceNinjaServer/pulls/1123 --- package-lock.json | 8 ++--- package.json | 2 +- src/controllers/api/dronesController.ts | 3 +- src/services/inventoryService.ts | 4 +-- src/services/itemDataService.ts | 8 +++++ src/services/missionInventoryUpdateService.ts | 30 +++++++++++++++++-- src/services/purchaseService.ts | 6 ++-- src/services/questService.ts | 8 ++--- src/types/requestTypes.ts | 4 +++ 9 files changed, 56 insertions(+), 17 deletions(-) diff --git a/package-lock.json b/package-lock.json index 99bdfa62..98c06df8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,7 +12,7 @@ "copyfiles": "^2.4.1", "express": "^5", "mongoose": "^8.11.0", - "warframe-public-export-plus": "^0.5.41", + "warframe-public-export-plus": "^0.5.42", "warframe-riven-info": "^0.1.2", "winston": "^3.17.0", "winston-daily-rotate-file": "^5.0.0" @@ -4083,9 +4083,9 @@ } }, "node_modules/warframe-public-export-plus": { - "version": "0.5.41", - "resolved": "https://registry.npmjs.org/warframe-public-export-plus/-/warframe-public-export-plus-0.5.41.tgz", - "integrity": "sha512-qVOUY4UjF1cyBrBbMwD25xHSdSf9q57/CJgjHsfSE7NUu/6pBDSZzwS0iAetAukws/1V2kDvsuy8AGtOec2L1w==" + "version": "0.5.42", + "resolved": "https://registry.npmjs.org/warframe-public-export-plus/-/warframe-public-export-plus-0.5.42.tgz", + "integrity": "sha512-up3P5bLKD42Xkr3o7TX9WUwvpJzK88aQTLZ2bB6QWUHdsJxl/Z3TBn+HSd3eouIDTMVUzbTDeDPosSw7TcLegA==" }, "node_modules/warframe-riven-info": { "version": "0.1.2", diff --git a/package.json b/package.json index a57639f6..1a931ddf 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,7 @@ "mongoose": "^8.11.0", "morgan": "^1.10.0", "typescript": ">=4.7.4 <5.6.0", - "warframe-public-export-plus": "^0.5.41", + "warframe-public-export-plus": "^0.5.42", "warframe-riven-info": "^0.1.2", "winston": "^3.17.0", "winston-daily-rotate-file": "^5.0.0" diff --git a/src/controllers/api/dronesController.ts b/src/controllers/api/dronesController.ts index 9337dc62..972f8f6b 100644 --- a/src/controllers/api/dronesController.ts +++ b/src/controllers/api/dronesController.ts @@ -1,6 +1,7 @@ import { toMongoDate, toOid } from "@/src/helpers/inventoryHelpers"; import { config } from "@/src/services/configService"; import { addMiscItems, getInventory } from "@/src/services/inventoryService"; +import { fromStoreItem } from "@/src/services/itemDataService"; import { getAccountIdForRequest } from "@/src/services/loginService"; import { getRandomInt, getRandomWeightedRewardUc } from "@/src/services/rngService"; import { IMongoDate, IOid } from "@/src/types/commonTypes"; @@ -58,7 +59,7 @@ export const dronesController: RequestHandler = async (req, res) => { : 0; const resource = getRandomWeightedRewardUc(system.resources, droneMeta.probabilities)!; //logger.debug(`drone rolled`, resource); - drone.ResourceType = "/Lotus/" + resource.StoreItem.substring(18); + drone.ResourceType = fromStoreItem(resource.StoreItem); const resourceMeta = ExportResources[drone.ResourceType]; if (resourceMeta.pickupQuantity) { const pickupsToCollect = droneMeta.binCapacity * droneMeta.capacityMultipliers[resource.Rarity]; diff --git a/src/services/inventoryService.ts b/src/services/inventoryService.ts index ccfaf0d0..0c5a4cc1 100644 --- a/src/services/inventoryService.ts +++ b/src/services/inventoryService.ts @@ -35,7 +35,7 @@ import { IUpdateChallengeProgressRequest } from "../types/requestTypes"; import { logger } from "@/src/utils/logger"; -import { convertInboxMessage, getExalted, getKeyChainItems } from "@/src/services/itemDataService"; +import { convertInboxMessage, fromStoreItem, getExalted, getKeyChainItems } from "@/src/services/itemDataService"; import { EquipmentFeatures, IEquipmentClient, @@ -1260,7 +1260,7 @@ export const addKeyChainItems = async ( `adding key chain items ${keyChainItems.join()} for ${keyChainData.KeyChain} at stage ${keyChainData.ChainStage}` ); - const nonStoreItems = keyChainItems.map(item => item.replace("StoreItems/", "")); + const nonStoreItems = keyChainItems.map(item => fromStoreItem(item)); //TODO: inventoryChanges is not typed correctly const inventoryChanges = {}; diff --git a/src/services/itemDataService.ts b/src/services/itemDataService.ts index 8fd3969d..724e0243 100644 --- a/src/services/itemDataService.ts +++ b/src/services/itemDataService.ts @@ -244,3 +244,11 @@ export const convertInboxMessage = (message: IInboxMessage): IMessage => { r: false } satisfies IMessage; }; + +export const toStoreItem = (type: string): string => { + return "/Lotus/StoreItems/" + type.substring("/Lotus/".length); +}; + +export const fromStoreItem = (type: string): string => { + return "/Lotus/" + type.substring("/Lotus/StoreItems/".length); +}; diff --git a/src/services/missionInventoryUpdateService.ts b/src/services/missionInventoryUpdateService.ts index c9986c38..c020e807 100644 --- a/src/services/missionInventoryUpdateService.ts +++ b/src/services/missionInventoryUpdateService.ts @@ -1,4 +1,5 @@ import { + ExportEnemies, ExportFusionBundles, ExportRegions, ExportRewards, @@ -18,6 +19,7 @@ import { addFocusXpIncreases, addFusionTreasures, addGearExpByCategory, + addItem, addMiscItems, addMissionComplete, addMods, @@ -28,7 +30,7 @@ import { import { updateQuestKey } from "@/src/services/questService"; import { HydratedDocument } from "mongoose"; import { IInventoryChanges } from "@/src/types/purchaseTypes"; -import { getLevelKeyRewards, getNode } from "@/src/services/itemDataService"; +import { getLevelKeyRewards, getNode, toStoreItem } from "@/src/services/itemDataService"; import { InventoryDocumentProps, TInventoryDatabaseDocument } from "@/src/models/inventoryModels/inventoryModel"; import { getEntriesUnsafe } from "@/src/utils/ts-utils"; import { IEquipmentClient } from "@/src/types/inventoryTypes/commonInventoryTypes"; @@ -319,7 +321,8 @@ export const addMissionRewards = async ( LevelKeyName: levelKeyName, Missions: missions, RegularCredits: creditDrops, - VoidTearParticipantsCurrWave: voidTearWave + VoidTearParticipantsCurrWave: voidTearWave, + StrippedItems: strippedItems }: IMissionInventoryUpdateRequest ) => { if (!rewardInfo) { @@ -406,6 +409,29 @@ export const addMissionRewards = async ( MissionRewards.push({ StoreItem: reward.type, ItemCount: reward.itemCount }); } + if (strippedItems) { + for (const si of strippedItems) { + const droptable = ExportEnemies.droptables[si.DropTable]; + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition + if (!droptable) { + logger.error(`unknown droptable ${si.DropTable}`); + } else { + for (let i = 0; i != si.DROP_MOD.length; ++i) { + for (const pool of droptable) { + const reward = getRandomReward(pool.items)!; + logger.debug(`stripped droptable rolled`, reward); + await addItem(inventory, reward.type); + MissionRewards.push({ + StoreItem: toStoreItem(reward.type), + ItemCount: 1, + FromEnemyCache: true // to show "identified" + }); + } + } + } + } + } + return { inventoryChanges, MissionRewards, credits }; }; diff --git a/src/services/purchaseService.ts b/src/services/purchaseService.ts index 3a84ec4a..b153c86c 100644 --- a/src/services/purchaseService.ts +++ b/src/services/purchaseService.ts @@ -27,6 +27,7 @@ import { } from "warframe-public-export-plus"; import { config } from "./configService"; import { TInventoryDatabaseDocument } from "../models/inventoryModels/inventoryModel"; +import { fromStoreItem, toStoreItem } from "./itemDataService"; export const getStoreItemCategory = (storeItem: string): string => { const storeItemString = getSubstringFromKeyword(storeItem, "StoreItems/"); @@ -240,7 +241,7 @@ export const handleStoreItemAcquisition = async ( await handleBundleAcqusition(storeItemName, inventory, quantity, purchaseResponse.InventoryChanges); } else { const storeCategory = getStoreItemCategory(storeItemName); - const internalName = storeItemName.replace("/StoreItems", ""); + const internalName = fromStoreItem(storeItemName); logger.debug(`store category ${storeCategory}`); if (!ignorePurchaseQuantity) { if (internalName in ExportGear) { @@ -328,8 +329,7 @@ const handleBoosterPackPurchase = async ( const result = getRandomWeightedRewardUc(pack.components, weights); if (result) { logger.debug(`booster pack rolled`, result); - purchaseResponse.BoosterPackItems += - result.Item.split("/Lotus/").join("/Lotus/StoreItems/") + ',{"lvl":0};'; + purchaseResponse.BoosterPackItems += toStoreItem(result.Item) + ',{"lvl":0};'; combineInventoryChanges( purchaseResponse.InventoryChanges, (await addItem(inventory, result.Item, 1)).InventoryChanges diff --git a/src/services/questService.ts b/src/services/questService.ts index 3e036a76..f52536be 100644 --- a/src/services/questService.ts +++ b/src/services/questService.ts @@ -3,7 +3,7 @@ import { isEmptyObject } from "@/src/helpers/general"; import { TInventoryDatabaseDocument } from "@/src/models/inventoryModels/inventoryModel"; import { createMessage } from "@/src/services/inboxService"; import { addItem, addKeyChainItems } from "@/src/services/inventoryService"; -import { getKeyChainMessage, getLevelKeyRewards } from "@/src/services/itemDataService"; +import { fromStoreItem, getKeyChainMessage, getLevelKeyRewards } from "@/src/services/itemDataService"; import { IInventoryDatabase, IQuestKeyClient, @@ -157,7 +157,7 @@ export const completeQuest = async (inventory: TInventoryDatabaseDocument, quest addFixedLevelRewards(fixedLevelRewards.levelKeyRewards, inventory, missionRewards); for (const reward of missionRewards) { - await addItem(inventory, reward.StoreItem.replace("StoreItems/", ""), reward.ItemCount); + await addItem(inventory, fromStoreItem(reward.StoreItem), reward.ItemCount); } } else if (fixedLevelRewards.levelKeyRewards2) { for (const reward of fixedLevelRewards.levelKeyRewards2) { @@ -166,9 +166,9 @@ export const completeQuest = async (inventory: TInventoryDatabaseDocument, quest continue; } if (reward.rewardType == "RT_RESOURCE") { - await addItem(inventory, reward.itemType.replace("StoreItems/", ""), reward.amount); + await addItem(inventory, fromStoreItem(reward.itemType), reward.amount); } else { - await addItem(inventory, reward.itemType.replace("StoreItems/", "")); + await addItem(inventory, fromStoreItem(reward.itemType)); } } } diff --git a/src/types/requestTypes.ts b/src/types/requestTypes.ts index 441e8d63..c3777112 100644 --- a/src/types/requestTypes.ts +++ b/src/types/requestTypes.ts @@ -103,6 +103,10 @@ export type IMissionInventoryUpdateRequest = { }[]; CollectibleScans?: ICollectibleEntry[]; Upgrades?: IUpgradeClient[]; // riven challenge progress + StrippedItems?: { + DropTable: string; + DROP_MOD: number[]; + }[]; } & { [K in TEquipmentKey]?: IEquipmentClient[]; };