From 7313d35ed90d23fc59bbbb1b465fe28abff9b505 Mon Sep 17 00:00:00 2001 From: Sainan Date: Wed, 19 Jun 2024 04:50:57 +0200 Subject: [PATCH 1/2] refactor getItemByBlueprint stuff to make more sense --- .../api/claimCompletedRecipeController.ts | 16 ++++++++-------- src/services/itemDataService.ts | 3 +-- src/services/recipeService.ts | 4 ++-- 3 files changed, 11 insertions(+), 12 deletions(-) diff --git a/src/controllers/api/claimCompletedRecipeController.ts b/src/controllers/api/claimCompletedRecipeController.ts index 43abc899..b3877376 100644 --- a/src/controllers/api/claimCompletedRecipeController.ts +++ b/src/controllers/api/claimCompletedRecipeController.ts @@ -3,7 +3,7 @@ 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"; @@ -37,8 +37,8 @@ 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}`); } @@ -47,18 +47,18 @@ export const claimCompletedRecipeController: RequestHandler = async (req, res) = // TODO: Refund items res.json({}); } else { - logger.debug("Claiming Recipe", { buildable, pendingRecipe }); - if (buildable.consumeOnUse) { + logger.debug("Claiming Recipe", { recipe, pendingRecipe }); + if (recipe.consumeOnUse) { // TODO: Remove one instance of this recipe, and include that in InventoryChanges. } let currencyChanges = {}; - if (req.query.rush && buildable.skipBuildTimePrice) { - currencyChanges = await updateCurrency(buildable.skipBuildTimePrice, true, accountId); + if (req.query.rush && recipe.skipBuildTimePrice) { + currencyChanges = await updateCurrency(recipe.skipBuildTimePrice, true, accountId); } res.json({ InventoryChanges: { ...currencyChanges, - ...(await addItem(accountId, buildable.resultType, buildable.num)).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..d1e8cdcb 100644 --- a/src/services/recipeService.ts +++ b/src/services/recipeService.ts @@ -1,6 +1,6 @@ import { unixTimesInMs } from "@/src/constants/timeConstants"; import { getInventory } from "@/src/services/inventoryService"; -import { getItemByBlueprint } from "@/src/services/itemDataService"; +import { getRecipe } from "@/src/services/itemDataService"; import { logger } from "@/src/utils/logger"; import { Types } from "mongoose"; @@ -27,7 +27,7 @@ export interface IResource { // }; export const startRecipe = async (recipeName: string, accountId: string) => { - const recipe = getItemByBlueprint(recipeName); + const recipe = getRecipe(recipeName); if (!recipe) { logger.error(`unknown recipe ${recipeName}`); -- 2.47.2 From acd0b90256166c597b8fd25b28cd2befef1c205b Mon Sep 17 00:00:00 2001 From: Sainan Date: Wed, 19 Jun 2024 05:17:50 +0200 Subject: [PATCH 2/2] 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, -- 2.47.2