SpaceNinjaServer/src/controllers/api/claimCompletedRecipeController.ts

123 lines
5.1 KiB
TypeScript
Raw Normal View History

2024-01-25 14:49:45 +01:00
//this is a controller for the claimCompletedRecipe route
//it will claim a recipe for the user
import { RequestHandler } from "express";
2024-01-25 14:49:45 +01:00
import { logger } from "@/src/utils/logger";
2024-06-19 10:32:16 +02:00
import { getRecipe } from "@/src/services/itemDataService";
2024-01-25 14:49:45 +01:00
import { IOid } from "@/src/types/commonTypes";
import { getJSONfromString } from "@/src/helpers/stringHelpers";
2024-05-28 13:45:06 +02:00
import { getAccountIdForRequest } from "@/src/services/loginService";
import { getInventory, updateCurrency, addItem, addMiscItems, addRecipes } from "@/src/services/inventoryService";
import { IInventoryChanges } from "@/src/types/purchaseTypes";
import { IEquipmentClient } from "@/src/types/inventoryTypes/commonInventoryTypes";
import { IMiscItem } from "@/src/types/inventoryTypes/inventoryTypes";
2024-01-25 14:49:45 +01:00
export interface IClaimCompletedRecipeRequest {
RecipeIds: IOid[];
}
export const claimCompletedRecipeController: RequestHandler = async (req, res) => {
const claimCompletedRecipeRequest = getJSONfromString<IClaimCompletedRecipeRequest>(String(req.body));
2024-05-28 13:45:06 +02:00
const accountId = await getAccountIdForRequest(req);
2024-01-25 14:49:45 +01:00
if (!accountId) throw new Error("no account id");
const inventory = await getInventory(accountId);
const pendingRecipe = inventory.PendingRecipes.id(claimCompletedRecipeRequest.RecipeIds[0].$oid);
2024-01-25 14:49:45 +01:00
if (!pendingRecipe) {
throw new Error(`no pending recipe found with id ${claimCompletedRecipeRequest.RecipeIds[0].$oid}`);
}
//check recipe is indeed ready to be completed
// if (pendingRecipe.CompletionDate > new Date()) {
// throw new Error(`recipe ${pendingRecipe._id} is not ready to be completed`);
// }
inventory.PendingRecipes.pull(pendingRecipe._id);
2024-01-25 14:49:45 +01:00
2024-06-19 10:32:16 +02:00
const recipe = getRecipe(pendingRecipe.ItemType);
if (!recipe) {
throw new Error(`no completed item found for recipe ${pendingRecipe._id.toString()}`);
2024-01-25 14:49:45 +01:00
}
if (req.query.cancel) {
const inventoryChanges: IInventoryChanges = {
...updateCurrency(inventory, recipe.buildPrice * -1, false)
};
2024-06-19 10:32:16 +02:00
const nonMiscItemIngredients = new Set();
for (const category of ["LongGuns", "Pistols", "Melee"] as const) {
if (pendingRecipe[category]) {
pendingRecipe[category].forEach(item => {
const index = inventory[category].push(item) - 1;
inventoryChanges[category] ??= [];
inventoryChanges[category].push(inventory[category][index].toJSON<IEquipmentClient>());
nonMiscItemIngredients.add(item.ItemType);
inventoryChanges.WeaponBin ??= { Slots: 0 };
inventoryChanges.WeaponBin.Slots -= 1;
});
}
}
const miscItemChanges: IMiscItem[] = [];
recipe.ingredients.forEach(ingredient => {
if (!nonMiscItemIngredients.has(ingredient.ItemType)) {
miscItemChanges.push(ingredient);
}
2024-06-19 10:32:16 +02:00
});
addMiscItems(inventory, miscItemChanges);
inventoryChanges.MiscItems = miscItemChanges;
await inventory.save();
res.json(inventoryChanges); // Not a bug: In the specific case of cancelling a recipe, InventoryChanges are expected to be the root.
} else {
2024-06-19 10:32:16 +02:00
logger.debug("Claiming Recipe", { recipe, pendingRecipe });
2025-01-06 01:21:37 +01:00
if (recipe.secretIngredientAction == "SIA_SPECTRE_LOADOUT_COPY") {
inventory.PendingSpectreLoadouts ??= [];
inventory.SpectreLoadouts ??= [];
const pendingLoadoutIndex = inventory.PendingSpectreLoadouts.findIndex(
x => x.ItemType == recipe.resultType
);
if (pendingLoadoutIndex != -1) {
const loadoutIndex = inventory.SpectreLoadouts.findIndex(x => x.ItemType == recipe.resultType);
if (loadoutIndex != -1) {
inventory.SpectreLoadouts.splice(loadoutIndex, 1);
}
logger.debug(
"moving spectre loadout from pending to active",
inventory.toJSON().PendingSpectreLoadouts![pendingLoadoutIndex]
);
inventory.SpectreLoadouts.push(inventory.PendingSpectreLoadouts[pendingLoadoutIndex]);
inventory.PendingSpectreLoadouts.splice(pendingLoadoutIndex, 1);
}
}
2024-06-19 10:32:16 +02:00
let InventoryChanges = {};
if (recipe.consumeOnUse) {
const recipeChanges = [
{
ItemType: pendingRecipe.ItemType,
ItemCount: -1
}
];
InventoryChanges = { ...InventoryChanges, Recipes: recipeChanges };
addRecipes(inventory, recipeChanges);
}
2024-06-19 10:32:16 +02:00
if (req.query.rush) {
InventoryChanges = {
...InventoryChanges,
...updateCurrency(inventory, recipe.skipBuildTimePrice, true)
2024-06-19 10:32:16 +02:00
};
}
InventoryChanges = {
...InventoryChanges,
...(await addItem(inventory, recipe.resultType, recipe.num, false)).InventoryChanges
};
await inventory.save();
res.json({ InventoryChanges });
}
2024-01-25 14:49:45 +01:00
};