93 lines
2.7 KiB
TypeScript
93 lines
2.7 KiB
TypeScript
import type { Build, ItemTree } from 'match_collector'
|
|
|
|
/**
|
|
* 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<number, number>()
|
|
|
|
// 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)
|
|
|
|
// Sort by count descending
|
|
return lateGameItems.filter(item => !treeToArray(getCoreItems(build)).includes(item.data))
|
|
}
|
|
|
|
function treeToArray(tree: ItemTree): Array<number> {
|
|
const arr: Array<number> = []
|
|
|
|
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: [],
|
|
tags: tree.tags,
|
|
boughtWhen: tree.boughtWhen,
|
|
platformCount: tree.platformCount
|
|
}
|
|
|
|
// 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
|
|
}
|