From be5a2716093270ac6659ae9277071d9d27b1f334 Mon Sep 17 00:00:00 2001 From: Sainan Date: Wed, 19 Jun 2024 10:32:16 +0200 Subject: [PATCH] feat: handle costs of recipes (#329) --- .../api/claimCompletedRecipeController.ts | 51 ++++++++++++++----- src/services/itemDataService.ts | 3 +- src/services/recipeService.ts | 50 ++++-------------- 3 files changed, 48 insertions(+), 56 deletions(-) diff --git a/src/controllers/api/claimCompletedRecipeController.ts b/src/controllers/api/claimCompletedRecipeController.ts index 43abc899..cd8aa3c4 100644 --- a/src/controllers/api/claimCompletedRecipeController.ts +++ b/src/controllers/api/claimCompletedRecipeController.ts @@ -3,11 +3,11 @@ import { RequestHandler } from "express"; import { logger } from "@/src/utils/logger"; -import { getItemByBlueprint } from "@/src/services/itemDataService"; +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[]; @@ -37,28 +37,51 @@ export const claimCompletedRecipeController: RequestHandler = async (req, res) = inventory.PendingRecipes.pull(pendingRecipe._id); await inventory.save(); - const buildable = getItemByBlueprint(pendingRecipe.ItemType); - if (!buildable) { + const recipe = getRecipe(pendingRecipe.ItemType); + if (!recipe) { logger.error(`no completed item found for recipe ${pendingRecipe._id}`); throw new Error(`no completed item found for recipe ${pendingRecipe._id}`); } 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", { buildable, pendingRecipe }); - if (buildable.consumeOnUse) { - // TODO: Remove one instance of this recipe, and include that in InventoryChanges. + logger.debug("Claiming Recipe", { recipe, pendingRecipe }); + let InventoryChanges = {}; + if (recipe.consumeOnUse) { + 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 && buildable.skipBuildTimePrice) { - currencyChanges = await updateCurrency(buildable.skipBuildTimePrice, true, accountId); + if (req.query.rush) { + InventoryChanges = { + ...InventoryChanges, + ...(await updateCurrency(recipe.skipBuildTimePrice, true, accountId)) + }; } res.json({ InventoryChanges: { - ...currencyChanges, - ...(await addItem(accountId, buildable.resultType, buildable.num)).InventoryChanges + ...InventoryChanges, + ...(await addItem(accountId, recipe.resultType, recipe.num)).InventoryChanges } }); } diff --git a/src/services/itemDataService.ts b/src/services/itemDataService.ts index 694a766f..890cde2a 100644 --- a/src/services/itemDataService.ts +++ b/src/services/itemDataService.ts @@ -97,8 +97,7 @@ export const blueprintNames = Object.fromEntries( .map(name => [name, craftNames[name]]) ); -// Gets a recipe by its uniqueName -export const getItemByBlueprint = (uniqueName: string): IRecipe | undefined => { +export const getRecipe = (uniqueName: string): IRecipe | undefined => { return ExportRecipes[uniqueName]; }; diff --git a/src/services/recipeService.ts b/src/services/recipeService.ts index c9d315bd..8594def4 100644 --- a/src/services/recipeService.ts +++ b/src/services/recipeService.ts @@ -1,60 +1,30 @@ import { unixTimesInMs } from "@/src/constants/timeConstants"; -import { getInventory } from "@/src/services/inventoryService"; -import { getItemByBlueprint } from "@/src/services/itemDataService"; +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 = getItemByBlueprint(recipeName); + const recipe = getRecipe(recipeName); if (!recipe) { logger.error(`unknown recipe ${recipeName}`); 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,