diff --git a/src/controllers/api/guildTechController.ts b/src/controllers/api/guildTechController.ts index 34022699..b9d3b75d 100644 --- a/src/controllers/api/guildTechController.ts +++ b/src/controllers/api/guildTechController.ts @@ -54,10 +54,8 @@ export const guildTechController: RequestHandler = async (req, res) => { } } addMiscItems(inventory, miscItemChanges); - const inventoryChanges: IInventoryChanges = { - ...updateCurrency(inventory, contributions.RegularCredits, false), - MiscItems: miscItemChanges - }; + const inventoryChanges: IInventoryChanges = updateCurrency(inventory, contributions.RegularCredits, false); + inventoryChanges.MiscItems = miscItemChanges; if (techProject.ReqCredits == 0 && !techProject.ReqItems.find(x => x.ItemCount > 0)) { // This research is now fully funded. diff --git a/src/services/inventoryService.ts b/src/services/inventoryService.ts index cdf7bf5f..f4e48ca8 100644 --- a/src/services/inventoryService.ts +++ b/src/services/inventoryService.ts @@ -5,7 +5,7 @@ import { } from "@/src/models/inventoryModels/inventoryModel"; import { config } from "@/src/services/configService"; import { HydratedDocument, Types } from "mongoose"; -import { SlotNames, IInventoryChanges, IBinChanges, ICurrencyChanges } from "@/src/types/purchaseTypes"; +import { SlotNames, IInventoryChanges, IBinChanges, slotNames } from "@/src/types/purchaseTypes"; import { IChallengeProgress, IConsumable, @@ -26,8 +26,7 @@ import { ILibraryDailyTaskInfo, ICalendarProgress, IDroneClient, - IUpgradeClient, - ISlots + IUpgradeClient } from "@/src/types/inventoryTypes/inventoryTypes"; import { IGenericUpdate } from "../types/genericUpdate"; import { @@ -127,13 +126,17 @@ export const combineInventoryChanges = (InventoryChanges: IInventoryChanges, del for (const item of right) { left.push(item); } - } else if (typeof delta[key] == "object") { - console.assert(key.substring(-3) == "Bin"); - console.assert(key != "InfestedFoundry"); - const left = InventoryChanges[key] as IBinChanges; - const right = delta[key] as IBinChanges; - left.count += right.count; - left.platinum += right.platinum; + } else if (slotNames.indexOf(key as SlotNames) != -1) { + const left = InventoryChanges[key as SlotNames]!; + const right = delta[key as SlotNames]!; + if (right.count) { + left.count ??= 0; + left.count += right.count; + } + if (right.platinum) { + left.platinum ??= 0; + left.platinum += right.platinum; + } left.Slots += right.Slots; if (right.Extra) { left.Extra ??= 0; @@ -176,9 +179,9 @@ const occupySlot = ( slotChanges.Slots -= 1; } updateSlots(inventory, bin, slotChanges.Slots, slotChanges.Extra); - return { - [bin]: slotChanges satisfies ISlots - }; + const inventoryChanges: IInventoryChanges = {}; + inventoryChanges[bin] = slotChanges satisfies IBinChanges; + return inventoryChanges; }; export const addItem = async ( @@ -325,7 +328,7 @@ export const addItem = async ( const inventoryChanges = addEquipment(inventory, weapon.productCategory, typeName); if (weapon.additionalItems) { for (const item of weapon.additionalItems) { - combineInventoryChanges(inventoryChanges, await addItem(inventory, item, 1)); + combineInventoryChanges(inventoryChanges, (await addItem(inventory, item, 1)).InventoryChanges); } } return { @@ -684,8 +687,8 @@ export const updateCurrency = ( inventory: TInventoryDatabaseDocument, price: number, usePremium: boolean -): ICurrencyChanges => { - const currencyChanges: ICurrencyChanges = {}; +): IInventoryChanges => { + const currencyChanges: IInventoryChanges = {}; if (price != 0 && isCurrencyTracked(usePremium)) { if (usePremium) { if (inventory.PremiumCreditsFree > 0) { diff --git a/src/services/purchaseService.ts b/src/services/purchaseService.ts index cd6e7cad..2d1c66d3 100644 --- a/src/services/purchaseService.ts +++ b/src/services/purchaseService.ts @@ -164,7 +164,7 @@ export const handlePurchase = async ( addMiscItems(inventory, [invItem]); purchaseResponse.InventoryChanges.MiscItems ??= []; - (purchaseResponse.InventoryChanges.MiscItems as IMiscItem[]).push(invItem); + purchaseResponse.InventoryChanges.MiscItems.push(invItem); } else if (!config.infiniteRegalAya) { inventory.PrimeTokens -= offer.PrimePrice! * purchaseRequest.PurchaseParams.Quantity; } @@ -191,11 +191,11 @@ const handleItemPrices = ( addMiscItems(inventory, [invItem]); inventoryChanges.MiscItems ??= []; - const change = (inventoryChanges.MiscItems as IMiscItem[]).find(x => x.ItemType == item.ItemType); + const change = inventoryChanges.MiscItems.find(x => x.ItemType == item.ItemType); if (change) { change.ItemCount += invItem.ItemCount; } else { - (inventoryChanges.MiscItems as IMiscItem[]).push(invItem); + inventoryChanges.MiscItems.push(invItem); } } }; @@ -300,16 +300,14 @@ const handleSlotPurchase = ( logger.debug(`added ${slotsPurchased} slot ${slotName}`); - return { - InventoryChanges: { - [slotName]: { - count: 0, - platinum: 1, - Slots: slotsPurchased, - Extra: slotsPurchased - } - } + const inventoryChanges: IInventoryChanges = {}; + inventoryChanges[slotName] = { + count: 0, + platinum: 1, + Slots: slotsPurchased, + Extra: slotsPurchased }; + return { InventoryChanges: inventoryChanges }; }; const handleBoosterPackPurchase = async ( diff --git a/src/types/purchaseTypes.ts b/src/types/purchaseTypes.ts index f1e864be..e921d136 100644 --- a/src/types/purchaseTypes.ts +++ b/src/types/purchaseTypes.ts @@ -1,5 +1,5 @@ import { IEquipmentClient } from "./inventoryTypes/commonInventoryTypes"; -import { IDroneClient, IInfestedFoundryClient, TEquipmentKey } from "./inventoryTypes/inventoryTypes"; +import { IDroneClient, IInfestedFoundryClient, IMiscItem, TEquipmentKey } from "./inventoryTypes/inventoryTypes"; export interface IPurchaseRequest { PurchaseParams: IPurchaseParams; @@ -22,20 +22,31 @@ export interface IPurchaseParams { IsWeekly?: boolean; // for Source 7 } -export interface ICurrencyChanges { - RegularCredits?: number; - PremiumCredits?: number; - PremiumCreditsFree?: number; -} - export type IInventoryChanges = { [_ in SlotNames]?: IBinChanges; } & { [_ in TEquipmentKey]?: IEquipmentClient[]; -} & ICurrencyChanges & { - InfestedFoundry?: IInfestedFoundryClient; - Drones?: IDroneClient[]; - } & Record; +} & { + RegularCredits?: number; + PremiumCredits?: number; + PremiumCreditsFree?: number; + InfestedFoundry?: IInfestedFoundryClient; + Drones?: IDroneClient[]; + MiscItems?: IMiscItem[]; +} & Record< + Exclude< + string, + | SlotNames + | TEquipmentKey + | "RegularCredits" + | "PremiumCredits" + | "PremiumCreditsFree" + | "InfestedFoundry" + | "Drones" + | "MiscItems" + >, + number | object[] + >; export interface IAffiliationMods { Tag: string; @@ -51,8 +62,8 @@ export interface IPurchaseResponse { } export type IBinChanges = { - count: number; - platinum: number; + count?: number; + platinum?: number; Slots: number; Extra?: number; }; @@ -69,18 +80,21 @@ export type SlotPurchaseName = | "TwoCrewShipSalvageSlotItem" | "CrewMemberSlotItem"; -export type SlotNames = - | "SuitBin" - | "WeaponBin" - | "MechBin" - | "PveBonusLoadoutBin" - | "SentinelBin" - | "SpaceSuitBin" - | "SpaceWeaponBin" - | "OperatorAmpBin" - | "RandomModBin" - | "CrewShipSalvageBin" - | "CrewMemberBin"; +export const slotNames = [ + "SuitBin", + "WeaponBin", + "MechBin", + "PveBonusLoadoutBin", + "SentinelBin", + "SpaceSuitBin", + "SpaceWeaponBin", + "OperatorAmpBin", + "RandomModBin", + "CrewShipSalvageBin", + "CrewMemberBin" +] as const; + +export type SlotNames = (typeof slotNames)[number]; export type SlotPurchase = { [P in SlotPurchaseName]: { name: SlotNames; slotsPerPurchase: number };