fix: consume a slot when item is crafted instead of bought via plat #1029
@ -91,7 +91,7 @@ export const claimCompletedRecipeController: RequestHandler = async (req, res) =
|
|||||||
}
|
}
|
||||||
InventoryChanges = {
|
InventoryChanges = {
|
||||||
...InventoryChanges,
|
...InventoryChanges,
|
||||||
...(await addItem(inventory, recipe.resultType, recipe.num)).InventoryChanges
|
...(await addItem(inventory, recipe.resultType, recipe.num, false)).InventoryChanges
|
||||||
};
|
};
|
||||||
await inventory.save();
|
await inventory.save();
|
||||||
res.json({ InventoryChanges });
|
res.json({ InventoryChanges });
|
||||||
|
@ -54,10 +54,8 @@ export const guildTechController: RequestHandler = async (req, res) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
addMiscItems(inventory, miscItemChanges);
|
addMiscItems(inventory, miscItemChanges);
|
||||||
const inventoryChanges: IInventoryChanges = {
|
const inventoryChanges: IInventoryChanges = updateCurrency(inventory, contributions.RegularCredits, false);
|
||||||
...updateCurrency(inventory, contributions.RegularCredits, false),
|
inventoryChanges.MiscItems = miscItemChanges;
|
||||||
MiscItems: miscItemChanges
|
|
||||||
};
|
|
||||||
|
|
||||||
if (techProject.ReqCredits == 0 && !techProject.ReqItems.find(x => x.ItemCount > 0)) {
|
if (techProject.ReqCredits == 0 && !techProject.ReqItems.find(x => x.ItemCount > 0)) {
|
||||||
// This research is now fully funded.
|
// This research is now fully funded.
|
||||||
|
@ -7,7 +7,7 @@ export const addItemsController: RequestHandler = async (req, res) => {
|
|||||||
const requests = req.body as IAddItemRequest[];
|
const requests = req.body as IAddItemRequest[];
|
||||||
const inventory = await getInventory(accountId);
|
const inventory = await getInventory(accountId);
|
||||||
for (const request of requests) {
|
for (const request of requests) {
|
||||||
await addItem(inventory, request.ItemType, request.ItemCount);
|
await addItem(inventory, request.ItemType, request.ItemCount, true);
|
||||||
}
|
}
|
||||||
await inventory.save();
|
await inventory.save();
|
||||||
res.end();
|
res.end();
|
||||||
|
@ -5,7 +5,7 @@ import {
|
|||||||
} from "@/src/models/inventoryModels/inventoryModel";
|
} from "@/src/models/inventoryModels/inventoryModel";
|
||||||
import { config } from "@/src/services/configService";
|
import { config } from "@/src/services/configService";
|
||||||
import { HydratedDocument, Types } from "mongoose";
|
import { HydratedDocument, Types } from "mongoose";
|
||||||
import { SlotNames, IInventoryChanges, IBinChanges, ICurrencyChanges } from "@/src/types/purchaseTypes";
|
import { SlotNames, IInventoryChanges, IBinChanges, slotNames } from "@/src/types/purchaseTypes";
|
||||||
import {
|
import {
|
||||||
IChallengeProgress,
|
IChallengeProgress,
|
||||||
IConsumable,
|
IConsumable,
|
||||||
@ -126,13 +126,17 @@ export const combineInventoryChanges = (InventoryChanges: IInventoryChanges, del
|
|||||||
for (const item of right) {
|
for (const item of right) {
|
||||||
left.push(item);
|
left.push(item);
|
||||||
}
|
}
|
||||||
} else if (typeof delta[key] == "object") {
|
} else if (slotNames.indexOf(key as SlotNames) != -1) {
|
||||||
console.assert(key.substring(-3) == "Bin");
|
const left = InventoryChanges[key as SlotNames]!;
|
||||||
console.assert(key != "InfestedFoundry");
|
const right = delta[key as SlotNames]!;
|
||||||
const left = InventoryChanges[key] as IBinChanges;
|
if (right.count) {
|
||||||
const right = delta[key] as IBinChanges;
|
left.count ??= 0;
|
||||||
left.count += right.count;
|
left.count += right.count;
|
||||||
left.platinum += right.platinum;
|
}
|
||||||
|
if (right.platinum) {
|
||||||
|
left.platinum ??= 0;
|
||||||
|
left.platinum += right.platinum;
|
||||||
|
}
|
||||||
left.Slots += right.Slots;
|
left.Slots += right.Slots;
|
||||||
if (right.Extra) {
|
if (right.Extra) {
|
||||||
left.Extra ??= 0;
|
left.Extra ??= 0;
|
||||||
@ -159,10 +163,32 @@ export const getInventory = async (
|
|||||||
return inventory;
|
return inventory;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const occupySlot = (
|
||||||
|
inventory: TInventoryDatabaseDocument,
|
||||||
|
bin: InventorySlot,
|
||||||
|
premiumPurchase: boolean
|
||||||
|
): IInventoryChanges => {
|
||||||
|
const slotChanges = {
|
||||||
|
Slots: 0,
|
||||||
|
Extra: 0
|
||||||
|
};
|
||||||
|
if (premiumPurchase) {
|
||||||
|
slotChanges.Extra += 1;
|
||||||
|
} else {
|
||||||
|
// { count: 1, platinum: 0, Slots: -1 }
|
||||||
|
slotChanges.Slots -= 1;
|
||||||
|
}
|
||||||
|
updateSlots(inventory, bin, slotChanges.Slots, slotChanges.Extra);
|
||||||
|
const inventoryChanges: IInventoryChanges = {};
|
||||||
|
inventoryChanges[bin] = slotChanges satisfies IBinChanges;
|
||||||
|
return inventoryChanges;
|
||||||
|
};
|
||||||
|
|
||||||
export const addItem = async (
|
export const addItem = async (
|
||||||
inventory: TInventoryDatabaseDocument,
|
inventory: TInventoryDatabaseDocument,
|
||||||
typeName: string,
|
typeName: string,
|
||||||
quantity: number = 1
|
quantity: number = 1,
|
||||||
|
premiumPurchase: boolean = false
|
||||||
): Promise<{ InventoryChanges: IInventoryChanges }> => {
|
): Promise<{ InventoryChanges: IInventoryChanges }> => {
|
||||||
// Bundles are technically StoreItems but a) they don't have a normal counterpart, and b) they are used in non-StoreItem contexts, e.g. email attachments.
|
// Bundles are technically StoreItems but a) they don't have a normal counterpart, and b) they are used in non-StoreItem contexts, e.g. email attachments.
|
||||||
if (typeName in ExportBundles) {
|
if (typeName in ExportBundles) {
|
||||||
@ -302,14 +328,13 @@ export const addItem = async (
|
|||||||
const inventoryChanges = addEquipment(inventory, weapon.productCategory, typeName);
|
const inventoryChanges = addEquipment(inventory, weapon.productCategory, typeName);
|
||||||
if (weapon.additionalItems) {
|
if (weapon.additionalItems) {
|
||||||
for (const item of weapon.additionalItems) {
|
for (const item of weapon.additionalItems) {
|
||||||
combineInventoryChanges(inventoryChanges, await addItem(inventory, item, 1));
|
combineInventoryChanges(inventoryChanges, (await addItem(inventory, item, 1)).InventoryChanges);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
updateSlots(inventory, InventorySlot.WEAPONS, 0, 1);
|
|
||||||
return {
|
return {
|
||||||
InventoryChanges: {
|
InventoryChanges: {
|
||||||
...inventoryChanges,
|
...inventoryChanges,
|
||||||
WeaponBin: { count: 1, platinum: 0, Slots: -1 }
|
...occupySlot(inventory, InventorySlot.WEAPONS, premiumPurchase)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
@ -378,44 +403,26 @@ export const addItem = async (
|
|||||||
case "Powersuits":
|
case "Powersuits":
|
||||||
switch (typeName.substr(1).split("/")[2]) {
|
switch (typeName.substr(1).split("/")[2]) {
|
||||||
default: {
|
default: {
|
||||||
const inventoryChanges = addPowerSuit(inventory, typeName);
|
|
||||||
updateSlots(inventory, InventorySlot.SUITS, 0, 1);
|
|
||||||
return {
|
return {
|
||||||
InventoryChanges: {
|
InventoryChanges: {
|
||||||
...inventoryChanges,
|
...addPowerSuit(inventory, typeName),
|
||||||
SuitBin: {
|
...occupySlot(inventory, InventorySlot.SUITS, premiumPurchase)
|
||||||
count: 1,
|
|
||||||
platinum: 0,
|
|
||||||
Slots: -1
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
case "Archwing": {
|
case "Archwing": {
|
||||||
const inventoryChanges = addSpaceSuit(inventory, typeName);
|
|
||||||
updateSlots(inventory, InventorySlot.SPACESUITS, 0, 1);
|
|
||||||
return {
|
return {
|
||||||
InventoryChanges: {
|
InventoryChanges: {
|
||||||
...inventoryChanges,
|
...addSpaceSuit(inventory, typeName),
|
||||||
SpaceSuitBin: {
|
...occupySlot(inventory, InventorySlot.SPACESUITS, premiumPurchase)
|
||||||
count: 1,
|
|
||||||
platinum: 0,
|
|
||||||
Slots: -1
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
case "EntratiMech": {
|
case "EntratiMech": {
|
||||||
const inventoryChanges = addMechSuit(inventory, typeName);
|
|
||||||
updateSlots(inventory, InventorySlot.MECHSUITS, 0, 1);
|
|
||||||
return {
|
return {
|
||||||
InventoryChanges: {
|
InventoryChanges: {
|
||||||
...inventoryChanges,
|
...addMechSuit(inventory, typeName),
|
||||||
MechBin: {
|
...occupySlot(inventory, InventorySlot.MECHSUITS, premiumPurchase)
|
||||||
count: 1,
|
|
||||||
platinum: 0,
|
|
||||||
Slots: -1
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -446,12 +453,10 @@ export const addItem = async (
|
|||||||
case "Types":
|
case "Types":
|
||||||
switch (typeName.substr(1).split("/")[2]) {
|
switch (typeName.substr(1).split("/")[2]) {
|
||||||
case "Sentinels": {
|
case "Sentinels": {
|
||||||
const inventoryChanges = addSentinel(inventory, typeName);
|
|
||||||
updateSlots(inventory, InventorySlot.SENTINELS, 0, 1);
|
|
||||||
return {
|
return {
|
||||||
InventoryChanges: {
|
InventoryChanges: {
|
||||||
...inventoryChanges,
|
...addSentinel(inventory, typeName),
|
||||||
SentinelBin: { count: 1, platinum: 0, Slots: -1 }
|
...occupySlot(inventory, InventorySlot.SENTINELS, premiumPurchase)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -531,9 +536,9 @@ export const addItems = async (
|
|||||||
let inventoryDelta;
|
let inventoryDelta;
|
||||||
for (const item of items) {
|
for (const item of items) {
|
||||||
if (typeof item === "string") {
|
if (typeof item === "string") {
|
||||||
inventoryDelta = await addItem(inventory, item);
|
inventoryDelta = await addItem(inventory, item, 1, true);
|
||||||
} else {
|
} else {
|
||||||
inventoryDelta = await addItem(inventory, item.ItemType, item.ItemCount);
|
inventoryDelta = await addItem(inventory, item.ItemType, item.ItemCount, true);
|
||||||
}
|
}
|
||||||
combineInventoryChanges(inventoryChanges, inventoryDelta.InventoryChanges);
|
combineInventoryChanges(inventoryChanges, inventoryDelta.InventoryChanges);
|
||||||
}
|
}
|
||||||
@ -682,8 +687,8 @@ export const updateCurrency = (
|
|||||||
inventory: TInventoryDatabaseDocument,
|
inventory: TInventoryDatabaseDocument,
|
||||||
price: number,
|
price: number,
|
||||||
usePremium: boolean
|
usePremium: boolean
|
||||||
): ICurrencyChanges => {
|
): IInventoryChanges => {
|
||||||
const currencyChanges: ICurrencyChanges = {};
|
const currencyChanges: IInventoryChanges = {};
|
||||||
if (price != 0 && isCurrencyTracked(usePremium)) {
|
if (price != 0 && isCurrencyTracked(usePremium)) {
|
||||||
if (usePremium) {
|
if (usePremium) {
|
||||||
if (inventory.PremiumCreditsFree > 0) {
|
if (inventory.PremiumCreditsFree > 0) {
|
||||||
|
@ -164,7 +164,7 @@ export const handlePurchase = async (
|
|||||||
addMiscItems(inventory, [invItem]);
|
addMiscItems(inventory, [invItem]);
|
||||||
|
|
||||||
purchaseResponse.InventoryChanges.MiscItems ??= [];
|
purchaseResponse.InventoryChanges.MiscItems ??= [];
|
||||||
(purchaseResponse.InventoryChanges.MiscItems as IMiscItem[]).push(invItem);
|
purchaseResponse.InventoryChanges.MiscItems.push(invItem);
|
||||||
} else if (!config.infiniteRegalAya) {
|
} else if (!config.infiniteRegalAya) {
|
||||||
inventory.PrimeTokens -= offer.PrimePrice! * purchaseRequest.PurchaseParams.Quantity;
|
inventory.PrimeTokens -= offer.PrimePrice! * purchaseRequest.PurchaseParams.Quantity;
|
||||||
}
|
}
|
||||||
@ -191,11 +191,11 @@ const handleItemPrices = (
|
|||||||
addMiscItems(inventory, [invItem]);
|
addMiscItems(inventory, [invItem]);
|
||||||
|
|
||||||
inventoryChanges.MiscItems ??= [];
|
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) {
|
if (change) {
|
||||||
change.ItemCount += invItem.ItemCount;
|
change.ItemCount += invItem.ItemCount;
|
||||||
} else {
|
} else {
|
||||||
(inventoryChanges.MiscItems as IMiscItem[]).push(invItem);
|
inventoryChanges.MiscItems.push(invItem);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -251,7 +251,7 @@ export const handleStoreItemAcquisition = async (
|
|||||||
}
|
}
|
||||||
switch (storeCategory) {
|
switch (storeCategory) {
|
||||||
default: {
|
default: {
|
||||||
purchaseResponse = await addItem(inventory, internalName, quantity);
|
purchaseResponse = await addItem(inventory, internalName, quantity, true);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "Types":
|
case "Types":
|
||||||
@ -300,16 +300,14 @@ const handleSlotPurchase = (
|
|||||||
|
|
||||||
logger.debug(`added ${slotsPurchased} slot ${slotName}`);
|
logger.debug(`added ${slotsPurchased} slot ${slotName}`);
|
||||||
|
|
||||||
return {
|
const inventoryChanges: IInventoryChanges = {};
|
||||||
InventoryChanges: {
|
inventoryChanges[slotName] = {
|
||||||
[slotName]: {
|
count: 0,
|
||||||
count: 0,
|
platinum: 1,
|
||||||
platinum: 1,
|
Slots: slotsPurchased,
|
||||||
Slots: slotsPurchased,
|
Extra: slotsPurchased
|
||||||
Extra: slotsPurchased
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
return { InventoryChanges: inventoryChanges };
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleBoosterPackPurchase = async (
|
const handleBoosterPackPurchase = async (
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { IEquipmentClient } from "./inventoryTypes/commonInventoryTypes";
|
import { IEquipmentClient } from "./inventoryTypes/commonInventoryTypes";
|
||||||
import { IDroneClient, IInfestedFoundryClient, TEquipmentKey } from "./inventoryTypes/inventoryTypes";
|
import { IDroneClient, IInfestedFoundryClient, IMiscItem, TEquipmentKey } from "./inventoryTypes/inventoryTypes";
|
||||||
|
|
||||||
export interface IPurchaseRequest {
|
export interface IPurchaseRequest {
|
||||||
PurchaseParams: IPurchaseParams;
|
PurchaseParams: IPurchaseParams;
|
||||||
@ -22,20 +22,31 @@ export interface IPurchaseParams {
|
|||||||
IsWeekly?: boolean; // for Source 7
|
IsWeekly?: boolean; // for Source 7
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ICurrencyChanges {
|
|
||||||
RegularCredits?: number;
|
|
||||||
PremiumCredits?: number;
|
|
||||||
PremiumCreditsFree?: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
export type IInventoryChanges = {
|
export type IInventoryChanges = {
|
||||||
[_ in SlotNames]?: IBinChanges;
|
[_ in SlotNames]?: IBinChanges;
|
||||||
} & {
|
} & {
|
||||||
[_ in TEquipmentKey]?: IEquipmentClient[];
|
[_ in TEquipmentKey]?: IEquipmentClient[];
|
||||||
} & ICurrencyChanges & {
|
} & {
|
||||||
InfestedFoundry?: IInfestedFoundryClient;
|
RegularCredits?: number;
|
||||||
Drones?: IDroneClient[];
|
PremiumCredits?: number;
|
||||||
} & Record<string, IBinChanges | number | object[] | IInfestedFoundryClient>;
|
PremiumCreditsFree?: number;
|
||||||
|
InfestedFoundry?: IInfestedFoundryClient;
|
||||||
|
Drones?: IDroneClient[];
|
||||||
|
MiscItems?: IMiscItem[];
|
||||||
|
} & Record<
|
||||||
|
Exclude<
|
||||||
|
string,
|
||||||
|
| SlotNames
|
||||||
|
| TEquipmentKey
|
||||||
|
| "RegularCredits"
|
||||||
|
| "PremiumCredits"
|
||||||
|
| "PremiumCreditsFree"
|
||||||
|
| "InfestedFoundry"
|
||||||
|
| "Drones"
|
||||||
|
| "MiscItems"
|
||||||
|
>,
|
||||||
|
number | object[]
|
||||||
|
>;
|
||||||
|
|
||||||
export interface IAffiliationMods {
|
export interface IAffiliationMods {
|
||||||
Tag: string;
|
Tag: string;
|
||||||
@ -51,8 +62,8 @@ export interface IPurchaseResponse {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export type IBinChanges = {
|
export type IBinChanges = {
|
||||||
count: number;
|
count?: number;
|
||||||
platinum: number;
|
platinum?: number;
|
||||||
Slots: number;
|
Slots: number;
|
||||||
Extra?: number;
|
Extra?: number;
|
||||||
};
|
};
|
||||||
@ -69,18 +80,21 @@ export type SlotPurchaseName =
|
|||||||
| "TwoCrewShipSalvageSlotItem"
|
| "TwoCrewShipSalvageSlotItem"
|
||||||
| "CrewMemberSlotItem";
|
| "CrewMemberSlotItem";
|
||||||
|
|
||||||
export type SlotNames =
|
export const slotNames = [
|
||||||
| "SuitBin"
|
"SuitBin",
|
||||||
| "WeaponBin"
|
"WeaponBin",
|
||||||
| "MechBin"
|
"MechBin",
|
||||||
| "PveBonusLoadoutBin"
|
"PveBonusLoadoutBin",
|
||||||
| "SentinelBin"
|
"SentinelBin",
|
||||||
| "SpaceSuitBin"
|
"SpaceSuitBin",
|
||||||
| "SpaceWeaponBin"
|
"SpaceWeaponBin",
|
||||||
| "OperatorAmpBin"
|
"OperatorAmpBin",
|
||||||
| "RandomModBin"
|
"RandomModBin",
|
||||||
| "CrewShipSalvageBin"
|
"CrewShipSalvageBin",
|
||||||
| "CrewMemberBin";
|
"CrewMemberBin"
|
||||||
|
] as const;
|
||||||
|
|
||||||
|
export type SlotNames = (typeof slotNames)[number];
|
||||||
|
|
||||||
export type SlotPurchase = {
|
export type SlotPurchase = {
|
||||||
[P in SlotPurchaseName]: { name: SlotNames; slotsPerPurchase: number };
|
[P in SlotPurchaseName]: { name: SlotNames; slotsPerPurchase: number };
|
||||||
|
Loading…
x
Reference in New Issue
Block a user