From f3d30e010c5de9e1998e1e1b45dcad483c4c8af1 Mon Sep 17 00:00:00 2001 From: darthmaim Date: Fri, 22 Nov 2024 10:27:49 +0100 Subject: [PATCH 1/2] Sort merchants to the top of crafting steps --- src/craftingSteps.ts | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/src/craftingSteps.ts b/src/craftingSteps.ts index 3c31665..62e0876 100755 --- a/src/craftingSteps.ts +++ b/src/craftingSteps.ts @@ -10,22 +10,22 @@ export function craftingSteps(tree: RecipeTreeWithCraftFlags) { // Make sure that "Mystic Clovers" (and it's components) get crafted as the first steps, // since they generate items that are always useful for crafting the other steps + // Obsidian Shards and Philosopher Stones (required for Mystic Clovers) will be sorted + // above the Mystic Clovers in the next step when sorting merchants const mysticCloversId = 19675 const mysticClovers = steps.find((step) => step.id === mysticCloversId) if (mysticClovers) { steps = steps.filter((step) => step.id !== mysticCloversId) steps.unshift(mysticClovers) + } - const philosopherStonesId = 20796 - const philosopherStones = steps.find((step) => step.id === philosopherStonesId) - steps = steps.filter((step) => step.id !== philosopherStonesId) - philosopherStones && steps.unshift(philosopherStones) + // Sort merchants that only require currencies to the top + steps = steps.sort((a, b) => { + const aIsMerchant = isMerchantWithOnlyCurrencies(a) + const bIsMerchant = isMerchantWithOnlyCurrencies(b) - const obsidianShardsId = 19925 - const obsidianShards = steps.find((step) => step.id === obsidianShardsId) - steps = steps.filter((step) => step.id !== obsidianShardsId) - obsidianShards && steps.unshift(obsidianShards) - } + return aIsMerchant === bIsMerchant ? 0 : aIsMerchant ? -1 : 1 + }) return steps.map((step) => ({ ...step, @@ -99,3 +99,11 @@ function craftingStepsInner( treeComponents.map((component) => craftingStepsInner(component, steps, index + 1)) return steps } + +function isMerchantWithOnlyCurrencies(step: CraftingStep): boolean { + return ( + step.disciplines.length === 1 && + step.disciplines[0] === 'Merchant' && + step.components.every(({ type }) => type === 'Currency') + ) +} From 94abe01a2c6444391a925dda646e5cf50b3cc590 Mon Sep 17 00:00:00 2001 From: darthmaim Date: Sat, 23 Nov 2024 15:22:44 +0100 Subject: [PATCH 2/2] Add test --- .../__snapshots__/craftingSteps.spec.ts.snap | 66 ++++++++++++ tests/craftingSteps.spec.ts | 100 ++++++++++++++++++ 2 files changed, 166 insertions(+) diff --git a/tests/__snapshots__/craftingSteps.spec.ts.snap b/tests/__snapshots__/craftingSteps.spec.ts.snap index 7b254b3..760b0ed 100644 --- a/tests/__snapshots__/craftingSteps.spec.ts.snap +++ b/tests/__snapshots__/craftingSteps.spec.ts.snap @@ -418,3 +418,69 @@ Array [ }, ] `; + +exports[`craftingSteps only sorts merchants to top if they only use currencies 1`] = ` +Array [ + Object { + "components": Array [ + Object { + "id": 89140, + "quantity": 250, + "type": "Item", + }, + ], + "crafts": 25, + "disciplines": Array [ + "Leatherworker", + "Armorsmith", + "Tailor", + "Artificer", + "Weaponsmith", + "Scribe", + "Huntsman", + ], + "id": 89271, + "merchant": undefined, + "minRating": 0, + "output": undefined, + "prerequisites": Array [ + Object { + "id": 12915, + "type": "Recipe", + }, + ], + "quantity": 25, + "type": "Recipe", + }, + Object { + "components": Array [ + Object { + "id": 89271, + "quantity": 25, + "type": "Recipe", + }, + Object { + "id": 2, + "quantity": 35000, + "type": "Currency", + }, + ], + "crafts": 1, + "disciplines": Array [ + "Merchant", + ], + "id": 91571, + "merchant": Object { + "locations": Array [ + "Crafting Station", + ], + "name": "Master Artificers", + }, + "minRating": null, + "output": undefined, + "prerequisites": Array [], + "quantity": 1, + "type": "Recipe", + }, +] +`; diff --git a/tests/craftingSteps.spec.ts b/tests/craftingSteps.spec.ts index 3eb3d67..5b04d24 100755 --- a/tests/craftingSteps.spec.ts +++ b/tests/craftingSteps.spec.ts @@ -881,7 +881,107 @@ describe('craftingSteps', () => { } const usedItemObject = craftingSteps(tree) + expect(usedItemObject).toMatchSnapshot() + }) + it('only sorts merchants to top if they only use currencies', () => { + const tree: RecipeTreeWithCraftFlags = { + id: 91571, + type: 'Recipe', + quantity: 1, + output: 1, + components: [ + { + id: 89271, + type: 'Recipe', + quantity: 25, + output: 1, + components: [ + { + id: 89140, + type: 'Item', + quantity: 10, + output: 1, + totalQuantity: 250, + usedQuantity: 250, + buyPriceEach: 77, + buyPrice: 19250, + decisionPrice: 19250, + craftResultPrice: 19250, + craftDecisionPrice: 19250, + craft: false, + min_rating: null, + disciplines: [], + prerequisites: [], + multipleRecipeCount: 1, + }, + ], + prerequisites: [ + { + type: 'Recipe', + id: 12915, + }, + ], + min_rating: 0, + disciplines: [ + 'Leatherworker', + 'Armorsmith', + 'Tailor', + 'Artificer', + 'Weaponsmith', + 'Scribe', + 'Huntsman', + ], + totalQuantity: 25, + usedQuantity: 25, + buyPriceEach: 770, + buyPrice: 19250, + craftPrice: 19250, + decisionPrice: 19250, + craftResultPrice: 19250, + craftDecisionPrice: 19250, + craft: true, + multipleRecipeCount: 1, + }, + { + id: 2, + type: 'Currency', + quantity: 35000, + output: 1, + totalQuantity: 35000, + usedQuantity: 35000, + buyPriceEach: false, + buyPrice: false, + decisionPrice: 35000, + craftResultPrice: false, + craftDecisionPrice: 35000, + craft: false, + min_rating: null, + disciplines: [], + prerequisites: [], + multipleRecipeCount: 1, + }, + ], + prerequisites: [], + min_rating: null, + disciplines: ['Merchant'], + merchant: { + name: 'Master Artificers', + locations: ['Crafting Station'], + }, + multipleRecipeCount: 3, + totalQuantity: 1, + usedQuantity: 1, + buyPriceEach: false, + buyPrice: false, + craftPrice: 19250, + decisionPrice: 54250, + craftResultPrice: 19250, + craftDecisionPrice: 54250, + craft: true, + } + + const usedItemObject = craftingSteps(tree) expect(usedItemObject).toMatchSnapshot() }) })