forked from OpenWF/SpaceNinjaServer
		
	feat: handle costs of recipes (#329)
This commit is contained in:
		
							parent
							
								
									03ac8ab010
								
							
						
					
					
						commit
						be5a271609
					
				@ -3,11 +3,11 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import { RequestHandler } from "express";
 | 
					import { RequestHandler } from "express";
 | 
				
			||||||
import { logger } from "@/src/utils/logger";
 | 
					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 { IOid } from "@/src/types/commonTypes";
 | 
				
			||||||
import { getJSONfromString } from "@/src/helpers/stringHelpers";
 | 
					import { getJSONfromString } from "@/src/helpers/stringHelpers";
 | 
				
			||||||
import { getAccountIdForRequest } from "@/src/services/loginService";
 | 
					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 {
 | 
					export interface IClaimCompletedRecipeRequest {
 | 
				
			||||||
    RecipeIds: IOid[];
 | 
					    RecipeIds: IOid[];
 | 
				
			||||||
@ -37,28 +37,51 @@ export const claimCompletedRecipeController: RequestHandler = async (req, res) =
 | 
				
			|||||||
    inventory.PendingRecipes.pull(pendingRecipe._id);
 | 
					    inventory.PendingRecipes.pull(pendingRecipe._id);
 | 
				
			||||||
    await inventory.save();
 | 
					    await inventory.save();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const buildable = getItemByBlueprint(pendingRecipe.ItemType);
 | 
					    const recipe = getRecipe(pendingRecipe.ItemType);
 | 
				
			||||||
    if (!buildable) {
 | 
					    if (!recipe) {
 | 
				
			||||||
        logger.error(`no completed item found for recipe ${pendingRecipe._id}`);
 | 
					        logger.error(`no completed item found for recipe ${pendingRecipe._id}`);
 | 
				
			||||||
        throw new Error(`no completed item found for recipe ${pendingRecipe._id}`);
 | 
					        throw new Error(`no completed item found for recipe ${pendingRecipe._id}`);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (req.query.cancel) {
 | 
					    if (req.query.cancel) {
 | 
				
			||||||
        // TODO: Refund items
 | 
					        const currencyChanges = await updateCurrency(recipe.buildPrice * -1, false, accountId);
 | 
				
			||||||
        res.json({});
 | 
					
 | 
				
			||||||
 | 
					        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 {
 | 
					    } else {
 | 
				
			||||||
        logger.debug("Claiming Recipe", { buildable, pendingRecipe });
 | 
					        logger.debug("Claiming Recipe", { recipe, pendingRecipe });
 | 
				
			||||||
        if (buildable.consumeOnUse) {
 | 
					        let InventoryChanges = {};
 | 
				
			||||||
            // TODO: Remove one instance of this recipe, and include that in 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) {
 | 
				
			||||||
        if (req.query.rush && buildable.skipBuildTimePrice) {
 | 
					            InventoryChanges = {
 | 
				
			||||||
            currencyChanges = await updateCurrency(buildable.skipBuildTimePrice, true, accountId);
 | 
					                ...InventoryChanges,
 | 
				
			||||||
 | 
					                ...(await updateCurrency(recipe.skipBuildTimePrice, true, accountId))
 | 
				
			||||||
 | 
					            };
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        res.json({
 | 
					        res.json({
 | 
				
			||||||
            InventoryChanges: {
 | 
					            InventoryChanges: {
 | 
				
			||||||
                ...currencyChanges,
 | 
					                ...InventoryChanges,
 | 
				
			||||||
                ...(await addItem(accountId, buildable.resultType, buildable.num)).InventoryChanges
 | 
					                ...(await addItem(accountId, recipe.resultType, recipe.num)).InventoryChanges
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
				
			|||||||
@ -97,8 +97,7 @@ export const blueprintNames = Object.fromEntries(
 | 
				
			|||||||
        .map(name => [name, craftNames[name]])
 | 
					        .map(name => [name, craftNames[name]])
 | 
				
			||||||
);
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Gets a recipe by its uniqueName
 | 
					export const getRecipe = (uniqueName: string): IRecipe | undefined => {
 | 
				
			||||||
export const getItemByBlueprint = (uniqueName: string): IRecipe | undefined => {
 | 
					 | 
				
			||||||
    return ExportRecipes[uniqueName];
 | 
					    return ExportRecipes[uniqueName];
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -1,60 +1,30 @@
 | 
				
			|||||||
import { unixTimesInMs } from "@/src/constants/timeConstants";
 | 
					import { unixTimesInMs } from "@/src/constants/timeConstants";
 | 
				
			||||||
import { getInventory } from "@/src/services/inventoryService";
 | 
					import { addMiscItems, getInventory, updateCurrency } from "@/src/services/inventoryService";
 | 
				
			||||||
import { getItemByBlueprint } from "@/src/services/itemDataService";
 | 
					import { getRecipe } from "@/src/services/itemDataService";
 | 
				
			||||||
import { logger } from "@/src/utils/logger";
 | 
					import { logger } from "@/src/utils/logger";
 | 
				
			||||||
import { Types } from "mongoose";
 | 
					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) => {
 | 
					export const startRecipe = async (recipeName: string, accountId: string) => {
 | 
				
			||||||
    const recipe = getItemByBlueprint(recipeName);
 | 
					    const recipe = getRecipe(recipeName);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (!recipe) {
 | 
					    if (!recipe) {
 | 
				
			||||||
        logger.error(`unknown recipe ${recipeName}`);
 | 
					        logger.error(`unknown recipe ${recipeName}`);
 | 
				
			||||||
        throw new Error(`unknown recipe ${recipeName}`);
 | 
					        throw new Error(`unknown recipe ${recipeName}`);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const componentsNeeded = recipe.ingredients.map(component => ({
 | 
					    await updateCurrency(recipe.buildPrice, false, accountId);
 | 
				
			||||||
        uniqueName: component.ItemType,
 | 
					
 | 
				
			||||||
        count: component.ItemCount
 | 
					    const ingredientsInverse = recipe.ingredients.map(component => ({
 | 
				
			||||||
 | 
					        ItemType: component.ItemType,
 | 
				
			||||||
 | 
					        ItemCount: component.ItemCount * -1
 | 
				
			||||||
    }));
 | 
					    }));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (!componentsNeeded) {
 | 
					    const inventory = await getInventory(accountId);
 | 
				
			||||||
        logger.error(`recipe ${recipeName} has no components`);
 | 
					    addMiscItems(inventory, ingredientsInverse);
 | 
				
			||||||
        throw new Error(`recipe ${recipeName} has no components`);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    //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
 | 
					    //buildtime is in seconds
 | 
				
			||||||
    const completionDate = new Date(Date.now() + recipe.buildTime * unixTimesInMs.second);
 | 
					    const completionDate = new Date(Date.now() + recipe.buildTime * unixTimesInMs.second);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const inventory = await getInventory(accountId);
 | 
					 | 
				
			||||||
    inventory.PendingRecipes.push({
 | 
					    inventory.PendingRecipes.push({
 | 
				
			||||||
        ItemType: recipeName,
 | 
					        ItemType: recipeName,
 | 
				
			||||||
        CompletionDate: completionDate,
 | 
					        CompletionDate: completionDate,
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user