From acd0b90256166c597b8fd25b28cd2befef1c205b Mon Sep 17 00:00:00 2001 From: Sainan Date: Wed, 19 Jun 2024 05:17:50 +0200 Subject: [PATCH] feat: handle costs of recipes - Resources and credits are deducted when starting a recipe - Resources and credits are refunded when cancelling the recipe - The recipe is consumed if it is not reusable --- .../api/claimCompletedRecipeController.ts | 39 ++++++++++++---- src/services/recipeService.ts | 46 ++++--------------- 2 files changed, 39 insertions(+), 46 deletions(-) diff --git a/src/controllers/api/claimCompletedRecipeController.ts b/src/controllers/api/claimCompletedRecipeController.ts index b3877376..cd8aa3c4 100644 --- a/src/controllers/api/claimCompletedRecipeController.ts +++ b/src/controllers/api/claimCompletedRecipeController.ts @@ -7,7 +7,7 @@ import { getRecipe } from "@/src/services/itemDataService"; import { IOid } from "@/src/types/commonTypes"; import { getJSONfromString } from "@/src/helpers/stringHelpers"; import { getAccountIdForRequest } from "@/src/services/loginService"; -import { getInventory, updateCurrency, addItem } from "@/src/services/inventoryService"; +import { getInventory, updateCurrency, addItem, addMiscItems, addRecipes } from "@/src/services/inventoryService"; export interface IClaimCompletedRecipeRequest { RecipeIds: IOid[]; @@ -44,20 +44,43 @@ export const claimCompletedRecipeController: RequestHandler = async (req, res) = } if (req.query.cancel) { - // TODO: Refund items - res.json({}); + const currencyChanges = await updateCurrency(recipe.buildPrice * -1, false, accountId); + + const inventory = await getInventory(accountId); + addMiscItems(inventory, recipe.ingredients); + await inventory.save(); + + // Not a bug: In the specific case of cancelling a recipe, InventoryChanges are expected to be the root. + res.json({ + ...currencyChanges, + MiscItems: recipe.ingredients + }); } else { logger.debug("Claiming Recipe", { recipe, pendingRecipe }); + let InventoryChanges = {}; if (recipe.consumeOnUse) { - // TODO: Remove one instance of this recipe, and include that in InventoryChanges. + const recipeChanges = [ + { + ItemType: pendingRecipe.ItemType, + ItemCount: -1 + } + ]; + + InventoryChanges = { ...InventoryChanges, Recipes: recipeChanges }; + + const inventory = await getInventory(accountId); + addRecipes(inventory, recipeChanges); + await inventory.save(); } - let currencyChanges = {}; - if (req.query.rush && recipe.skipBuildTimePrice) { - currencyChanges = await updateCurrency(recipe.skipBuildTimePrice, true, accountId); + if (req.query.rush) { + InventoryChanges = { + ...InventoryChanges, + ...(await updateCurrency(recipe.skipBuildTimePrice, true, accountId)) + }; } res.json({ InventoryChanges: { - ...currencyChanges, + ...InventoryChanges, ...(await addItem(accountId, recipe.resultType, recipe.num)).InventoryChanges } }); diff --git a/src/services/recipeService.ts b/src/services/recipeService.ts index d1e8cdcb..8594def4 100644 --- a/src/services/recipeService.ts +++ b/src/services/recipeService.ts @@ -1,31 +1,9 @@ import { unixTimesInMs } from "@/src/constants/timeConstants"; -import { getInventory } from "@/src/services/inventoryService"; +import { addMiscItems, getInventory, updateCurrency } from "@/src/services/inventoryService"; import { getRecipe } from "@/src/services/itemDataService"; import { logger } from "@/src/utils/logger"; import { Types } from "mongoose"; -export interface IResource { - uniqueName: string; - count: number; -} - -// export const updateResources = async (accountId: string, components: IResource[]) => { -// const inventory = await getInventory(accountId); - -// for (const component of components) { -// const category = getItemCategoryByUniqueName(component.uniqueName) as keyof typeof inventory; -// //validate category - -// console.log(component.uniqueName); -// console.log("cate", category); - -// const invItem = inventory[category]; -// console.log("invItem", invItem); - -// inventory["MiscItems"]; -// } -// }; - export const startRecipe = async (recipeName: string, accountId: string) => { const recipe = getRecipe(recipeName); @@ -34,27 +12,19 @@ export const startRecipe = async (recipeName: string, accountId: string) => { throw new Error(`unknown recipe ${recipeName}`); } - const componentsNeeded = recipe.ingredients.map(component => ({ - uniqueName: component.ItemType, - count: component.ItemCount + await updateCurrency(recipe.buildPrice, false, accountId); + + const ingredientsInverse = recipe.ingredients.map(component => ({ + ItemType: component.ItemType, + ItemCount: component.ItemCount * -1 })); - if (!componentsNeeded) { - logger.error(`recipe ${recipeName} has no components`); - throw new Error(`recipe ${recipeName} has no components`); - } + const inventory = await getInventory(accountId); + addMiscItems(inventory, ingredientsInverse); - //TODO: consume components used - //await updateResources(accountId, componentsNeeded); - - if (!recipe.buildTime) { - logger.error(`recipe ${recipeName} has no build time`); - throw new Error(`recipe ${recipeName} has no build time`); - } //buildtime is in seconds const completionDate = new Date(Date.now() + recipe.buildTime * unixTimesInMs.second); - const inventory = await getInventory(accountId); inventory.PendingRecipes.push({ ItemType: recipeName, CompletionDate: completionDate,