From d3d966a50304af1a3034cac109a244499ca0f799 Mon Sep 17 00:00:00 2001 From: Sainan <63328889+Sainan@users.noreply.github.com> Date: Mon, 31 Mar 2025 04:14:20 -0700 Subject: [PATCH] feat: grustrag bolt (#1392) Reviewed-on: https://onlyg.it/OpenWF/SpaceNinjaServer/pulls/1392 Co-authored-by: Sainan <63328889+Sainan@users.noreply.github.com> Co-committed-by: Sainan <63328889+Sainan@users.noreply.github.com> --- .../api/claimCompletedRecipeController.ts | 15 +++++++--- src/controllers/api/startRecipeController.ts | 2 ++ src/models/inventoryModels/inventoryModel.ts | 11 ++++++-- src/services/missionInventoryUpdateService.ts | 28 ++++++++++++++++++- src/types/inventoryTypes/inventoryTypes.ts | 6 +++- 5 files changed, 54 insertions(+), 8 deletions(-) diff --git a/src/controllers/api/claimCompletedRecipeController.ts b/src/controllers/api/claimCompletedRecipeController.ts index e8c1b4fb..2d3c480f 100644 --- a/src/controllers/api/claimCompletedRecipeController.ts +++ b/src/controllers/api/claimCompletedRecipeController.ts @@ -99,6 +99,11 @@ export const claimCompletedRecipeController: RequestHandler = async (req, res) = inventory.SpectreLoadouts.push(inventory.PendingSpectreLoadouts[pendingLoadoutIndex]); inventory.PendingSpectreLoadouts.splice(pendingLoadoutIndex, 1); } + } else if (recipe.secretIngredientAction == "SIA_UNBRAND") { + inventory.BrandedSuits!.splice( + inventory.BrandedSuits!.findIndex(x => x.equals(pendingRecipe.SuitToUnbrand)), + 1 + ); } let InventoryChanges = {}; @@ -116,10 +121,12 @@ export const claimCompletedRecipeController: RequestHandler = async (req, res) = ...updateCurrency(inventory, recipe.skipBuildTimePrice, true) }; } - InventoryChanges = { - ...InventoryChanges, - ...(await addItem(inventory, recipe.resultType, recipe.num, false)) - }; + if (recipe.secretIngredientAction != "SIA_UNBRAND") { + InventoryChanges = { + ...InventoryChanges, + ...(await addItem(inventory, recipe.resultType, recipe.num, false)) + }; + } await inventory.save(); res.json({ InventoryChanges }); } diff --git a/src/controllers/api/startRecipeController.ts b/src/controllers/api/startRecipeController.ts index efdcb292..b313771a 100644 --- a/src/controllers/api/startRecipeController.ts +++ b/src/controllers/api/startRecipeController.ts @@ -111,6 +111,8 @@ export const startRecipeController: RequestHandler = async (req, res) => { inventory.PendingSpectreLoadouts.push(spectreLoadout); logger.debug("pending spectre loadout", spectreLoadout); } + } else if (recipe.secretIngredientAction == "SIA_UNBRAND") { + pr.SuitToUnbrand = new Types.ObjectId(startRecipeRequest.Ids[recipe.ingredients.length + 0]); } await inventory.save(); diff --git a/src/models/inventoryModels/inventoryModel.ts b/src/models/inventoryModels/inventoryModel.ts index 8e7d42c1..ecd007be 100644 --- a/src/models/inventoryModels/inventoryModel.ts +++ b/src/models/inventoryModels/inventoryModel.ts @@ -903,7 +903,8 @@ const pendingRecipeSchema = new Schema( CompletionDate: Date, LongGuns: { type: [EquipmentSchema], default: undefined }, Pistols: { type: [EquipmentSchema], default: undefined }, - Melee: { type: [EquipmentSchema], default: undefined } + Melee: { type: [EquipmentSchema], default: undefined }, + SuitToUnbrand: { type: Schema.Types.ObjectId, default: undefined } }, { id: false } ); @@ -920,6 +921,7 @@ pendingRecipeSchema.set("toJSON", { delete returnedObject.LongGuns; delete returnedObject.Pistols; delete returnedObject.Melees; + delete returnedObject.SuitToUnbrand; (returnedObject as IPendingRecipeClient).CompletionDate = { $date: { $numberLong: (returnedObject as IPendingRecipeDatabase).CompletionDate.getTime().toString() } }; @@ -1484,7 +1486,9 @@ const inventorySchema = new Schema( EchoesHexConquestHardModeStatus: { type: Number, default: undefined }, EchoesHexConquestCacheScoreMission: { type: Number, default: undefined }, EchoesHexConquestActiveFrameVariants: { type: [String], default: undefined }, - EchoesHexConquestActiveStickers: { type: [String], default: undefined } + EchoesHexConquestActiveStickers: { type: [String], default: undefined }, + + BrandedSuits: { type: [Schema.Types.ObjectId], default: undefined } }, { timestamps: { createdAt: "Created", updatedAt: false } } ); @@ -1516,6 +1520,9 @@ inventorySchema.set("toJSON", { if (inventoryDatabase.EntratiVaultCountResetDate) { inventoryResponse.EntratiVaultCountResetDate = toMongoDate(inventoryDatabase.EntratiVaultCountResetDate); } + if (inventoryDatabase.BrandedSuits) { + inventoryResponse.BrandedSuits = inventoryDatabase.BrandedSuits.map(toOid); + } } }); diff --git a/src/services/missionInventoryUpdateService.ts b/src/services/missionInventoryUpdateService.ts index ef66afbf..46134b43 100644 --- a/src/services/missionInventoryUpdateService.ts +++ b/src/services/missionInventoryUpdateService.ts @@ -30,7 +30,7 @@ import { updateSyndicate } from "@/src/services/inventoryService"; import { updateQuestKey } from "@/src/services/questService"; -import { HydratedDocument } from "mongoose"; +import { HydratedDocument, Types } from "mongoose"; import { IInventoryChanges } from "@/src/types/purchaseTypes"; import { getLevelKeyRewards, getNode, toStoreItem } from "@/src/services/itemDataService"; import { InventoryDocumentProps, TInventoryDatabaseDocument } from "@/src/models/inventoryModels/inventoryModel"; @@ -45,6 +45,7 @@ import kuriaMessage75 from "@/static/fixed_responses/kuriaMessages/seventyFivePe import kuriaMessage100 from "@/static/fixed_responses/kuriaMessages/oneHundredPercent.json"; import conservationAnimals from "@/static/fixed_responses/conservationAnimals.json"; import { getInfNodes } from "@/src/helpers/nemesisHelpers"; +import { Loadout } from "../models/inventoryModels/loadoutModel"; const getRotations = (rotationCount: number): number[] => { if (rotationCount === 0) return [0]; @@ -89,6 +90,31 @@ export const addMissionInventoryUpdates = async ( if (inventoryUpdates.RewardInfo && inventoryUpdates.RewardInfo.NemesisAbandonedRewards) { inventory.NemesisAbandonedRewards = inventoryUpdates.RewardInfo.NemesisAbandonedRewards; } + if ( + inventoryUpdates.MissionFailed && + inventoryUpdates.MissionStatus == "GS_FAILURE" && + inventoryUpdates.EndOfMatchUpload && + inventoryUpdates.ObjectiveReached + ) { + const loadout = (await Loadout.findById(inventory.LoadOutPresets, "NORMAL"))!; + const config = loadout.NORMAL.id(inventory.CurrentLoadOutIds[0].$oid)!; + const SuitId = new Types.ObjectId(config.s!.ItemId.$oid); + + inventory.BrandedSuits ??= []; + if (!inventory.BrandedSuits.find(x => x.equals(SuitId))) { + inventory.BrandedSuits.push(SuitId); + + await createMessage(inventory.accountOwnerId.toString(), [ + { + sndr: "/Lotus/Language/Menu/Mailbox_WarframeSender", + msg: "/Lotus/Language/G1Quests/BrandedMessage", + sub: "/Lotus/Language/G1Quests/BrandedTitle", + att: ["/Lotus/Types/Recipes/Components/BrandRemovalBlueprint"], + highPriority: true // I cannot find any content of this within the last 10 years so I can only assume that highPriority is set (it certainly would make sense), but I just don't know for sure that it is so on live. + } + ]); + } + } for (const [key, value] of getEntriesUnsafe(inventoryUpdates)) { if (value === undefined) { logger.error(`Inventory update key ${key} has no value `); diff --git a/src/types/inventoryTypes/inventoryTypes.ts b/src/types/inventoryTypes/inventoryTypes.ts index 6f258e13..b4d60f20 100644 --- a/src/types/inventoryTypes/inventoryTypes.ts +++ b/src/types/inventoryTypes/inventoryTypes.ts @@ -44,6 +44,7 @@ export interface IInventoryDatabase | "NextRefill" | "Nemesis" | "EntratiVaultCountResetDate" + | "BrandedSuits" | TEquipmentKey >, InventoryDatabaseEquipment { @@ -73,6 +74,7 @@ export interface IInventoryDatabase NextRefill?: Date; Nemesis?: INemesisDatabase; EntratiVaultCountResetDate?: Date; + BrandedSuits?: Types.ObjectId[]; } export interface IQuestKeyDatabase { @@ -346,6 +348,7 @@ export interface IInventoryClient extends IDailyAffiliations, InventoryClientEqu EchoesHexConquestCacheScoreMission?: number; EchoesHexConquestActiveFrameVariants?: string[]; EchoesHexConquestActiveStickers?: string[]; + BrandedSuits?: IOid[]; } export interface IAffiliation { @@ -857,10 +860,11 @@ export interface IPendingRecipeDatabase { LongGuns?: IEquipmentDatabase[]; Pistols?: IEquipmentDatabase[]; Melee?: IEquipmentDatabase[]; + SuitToUnbrand?: Types.ObjectId; } export interface IPendingRecipeClient - extends Omit { + extends Omit { CompletionDate: IMongoDate; }