Skip to content

Commit

Permalink
Merge pull request #32 from darthmaim/feature/sort-merchants-to-top
Browse files Browse the repository at this point in the history
Sort merchants to the top of crafting steps
  • Loading branch information
queicherius authored Nov 23, 2024
2 parents 2a95eb8 + 94abe01 commit 25d414a
Show file tree
Hide file tree
Showing 3 changed files with 183 additions and 9 deletions.
26 changes: 17 additions & 9 deletions src/craftingSteps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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')
)
}
66 changes: 66 additions & 0 deletions tests/__snapshots__/craftingSteps.spec.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -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",
},
]
`;
100 changes: 100 additions & 0 deletions tests/craftingSteps.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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()
})
})

0 comments on commit 25d414a

Please sign in to comment.