diff --git a/src/cheapestTree.ts b/src/cheapestTree.ts index f50f713..48a0d05 100755 --- a/src/cheapestTree.ts +++ b/src/cheapestTree.ts @@ -16,7 +16,6 @@ export function cheapestTree( forceBuyItems: Array = [], valueOwnItems = false ): RecipeTreeWithCraftFlags { - // calculateTreeQuantity already checks for craft flags, so we can set them here when valuing owned items if (valueOwnItems) { const treeWithQuantityWithoutAvailableItems = calculateTreeQuantity( amount, @@ -27,18 +26,22 @@ export function cheapestTree( treeWithQuantityWithoutAvailableItems, itemPrices ) + const cheaperToBuyItemIds = getCheaperToBuyItemIds(treeWithPriceWithoutAvailableItems) - disableCraftForItemIds(tree, cheaperToBuyItemIds) + + // calculateTreeQuantity already checks for craft flags, so we can set them here + tree = disableCraftForItemIds(tree, cheaperToBuyItemIds) as NestedRecipe } + // Adjust the tree total and used quantities const treeWithQuantity = calculateTreeQuantity(amount, tree as RecipeTree, availableItems) // Set the initial craft flags based on the subtree prices const treeWithPrices = calculateTreePrices(treeWithQuantity, itemPrices) - const treeWithCraftFlags = calculateTreeCraftFlags(treeWithPrices, forceBuyItems) + let treeWithCraftFlags = calculateTreeCraftFlags(treeWithPrices, forceBuyItems) // Force the root to be crafted - treeWithCraftFlags.craft = true + treeWithCraftFlags = { ...treeWithCraftFlags, craft: true } // After the "craft" flags are set, update the used materials // to only be used for things that actually get crafted @@ -87,12 +90,14 @@ function disableCraftForItemIds( ids: Array ) { if (ids.includes(tree.id)) { - tree.craft = false + tree = { ...tree, craft: false } } if ('components' in tree && Array.isArray(tree.components)) { - tree.components.forEach((component) => { + tree.components = tree.components.map((component) => disableCraftForItemIds(component as NestedRecipeAndBasicComponentWithCraftFlag, ids) - }) + ) } + + return tree } diff --git a/tests/cheapestTree.spec.ts b/tests/cheapestTree.spec.ts index 7ffbb54..98c3994 100755 --- a/tests/cheapestTree.spec.ts +++ b/tests/cheapestTree.spec.ts @@ -1,8 +1,6 @@ import { NestedRecipe } from '@gw2efficiency/recipe-nesting' import { cheapestTree } from '../src' import { RecipeTreeWithCraftFlags } from '../src/types' -import { clone } from '@devoxa/flocky' -import { JSONValue } from '@devoxa/flocky/dist/typeHelpers' type SimplifiedTree = { id: number @@ -18,10 +16,6 @@ function simplifyTree(tree: RecipeTreeWithCraftFlags): SimplifiedTree { } } -function cloneRecipe(recipe: NestedRecipe): NestedRecipe { - return clone(recipe as unknown as JSONValue) as unknown as NestedRecipe -} - describe('cheapestTree', () => { it('can calculate the cheapest tree correctly', () => { const recipeTree: NestedRecipe = { @@ -180,20 +174,17 @@ describe('cheapestTree', () => { const prices = { 1: 10, 3: 100, 4: 500 } const availableItems = { 3: 4, 4: 100 } - const recipeTreeA = cloneRecipe(recipeTree) - const calculatedTreeNoOwn = cheapestTree(1, recipeTreeA, prices) + const calculatedTreeNoOwn = cheapestTree(1, recipeTree, prices) const simpleTreeNoOwn = simplifyTree(calculatedTreeNoOwn) // Should make the same decisions as if we had no own materials - const recipeTreeB = cloneRecipe(recipeTree) - const calculatedTree = cheapestTree(1, recipeTreeB, prices, availableItems, [], true) + const calculatedTree = cheapestTree(1, recipeTree, prices, availableItems, [], true) const simpleTree = simplifyTree(calculatedTree) expect(calculatedTree).toMatchSnapshot() expect(simpleTree).toEqual(simpleTreeNoOwn) // Should value own materials as "free" and make other decisions - const recipeTreeC = cloneRecipe(recipeTree) - const calculatedTreeNoValue = cheapestTree(1, recipeTreeC, prices, availableItems, [], false) + const calculatedTreeNoValue = cheapestTree(1, recipeTree, prices, availableItems, [], false) const simpleTreeNoValue = simplifyTree(calculatedTreeNoValue) expect(simpleTree).not.toEqual(simpleTreeNoValue) })