/** * Gets all late game items from the item tree (items beyond first level) * Returns a flat array of unique items with their counts */ export function getLateGameItems(build: Build): Array<{ data: number; count: number }> { const lateGameItems: Array<{ data: number; count: number }> = [] const itemCounts = new Map() // Collect late items function collectLateItems(tree: ItemTree, depth: number = 0): void { if (depth >= 3 && tree.data !== undefined && tree.count > 0) { const existing = itemCounts.get(tree.data) || 0 itemCounts.set(tree.data, existing + tree.count) } for (const child of tree.children) { collectLateItems(child, depth + 1) } } collectLateItems(build.items) // Convert map to array for (const [data, count] of itemCounts.entries()) { lateGameItems.push({ data, count }) } lateGameItems.sort((a, b) => b.count - a.count) console.log(lateGameItems) // Sort by count descending return lateGameItems.filter(item => !treeToArray(getCoreItems(build)).includes(item.data)) } function treeToArray(tree: ItemTree): Array { const arr: Array = [] if (tree.data != null) arr.push(tree.data) for (const child of tree.children) arr.push(...treeToArray(child)) return arr } /** * Creates a deep copy of an ItemTree trimmed to a maximum depth * @param tree - The item tree to copy and trim * @param maxDepth - The maximum depth to keep (inclusive) * @param currentDepth - The current depth during recursion * @returns A new ItemTree with children trimmed beyond maxDepth */ function trimTreeDepth(tree: ItemTree, maxDepth: number, currentDepth: number = 0): ItemTree { const trimmedTree: ItemTree = { count: tree.count, data: tree.data, children: [] } // If we haven't reached maxDepth, include children if (currentDepth < maxDepth) { for (const child of tree.children || []) { trimmedTree.children.push(trimTreeDepth(child, maxDepth, currentDepth + 1)) } } return trimmedTree } function trimTreeChildrensAtDepth(tree: ItemTree, maxChildren: number, depth: number) { if (depth == 0) { if (tree.children.length > maxChildren) { tree.children.splice(maxChildren, tree.children.length - maxChildren) } return } for (const c of tree.children) { trimTreeChildrensAtDepth(c, maxChildren, depth - 1) } } export function getCoreItems(build: Build): ItemTree { const tree = trimTreeDepth(build.items, 3) trimTreeChildrensAtDepth(tree, 1, 0) trimTreeChildrensAtDepth(tree, 1, 1) trimTreeChildrensAtDepth(tree, 3, 2) return tree }