From 122d65840e9430f69654c4b69546c465f5dd1fb9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tr=C3=A8sAbhi?= <43380238+tresabhi@users.noreply.github.com> Date: Mon, 1 Dec 2025 13:09:55 -0600 Subject: [PATCH] feat: aggregateAttributes --- .../src/core/blitz/aggregateAttributes.ts | 51 +++++++++++++++++ .../src/pages/tanks/[slug]/_index.tsx | 57 ++++--------------- 2 files changed, 62 insertions(+), 46 deletions(-) create mode 100644 packages/website-ue/src/core/blitz/aggregateAttributes.ts diff --git a/packages/website-ue/src/core/blitz/aggregateAttributes.ts b/packages/website-ue/src/core/blitz/aggregateAttributes.ts new file mode 100644 index 000000000..c3c598114 --- /dev/null +++ b/packages/website-ue/src/core/blitz/aggregateAttributes.ts @@ -0,0 +1,51 @@ +import { + TankAttributeChange_AttributeName, + TankAttributeChange_Modifier, + type TankAttributeChange, +} from "@protos/blitz_static_tank_upgrade_single_stage"; +import { times } from "lodash-es"; + +function patch( + changes: TankAttributeChange[], + attributes: Partial> +) { + for (const { attribute_name, value, modifier } of changes) { + switch (modifier) { + case TankAttributeChange_Modifier.MODIFIER_OVERRIDE: + attributes[attribute_name] = value; + break; + + case TankAttributeChange_Modifier.MODIFIER_MULTIPLY: { + if (!(attribute_name in attributes)) { + throw new Error( + `Missing attribute ${TankAttributeChange_AttributeName[attribute_name]} to modify` + ); + } + } + + case TankAttributeChange_Modifier.MODIFIER_MULTIPLY: { + attributes[attribute_name]! *= value; + break; + } + + default: + throw new Error( + `Unhandled modified ${TankAttributeChange_Modifier[modifier]}` + ); + } + } +} + +export function aggregateAttributes( + base: TankAttributeChange[], + stages: TankAttributeChange[][], + stage: number +) { + const attributes: Partial> = + {}; + + patch(base, attributes); + times(stage, (index) => patch(stages[index], attributes)); + + return attributes; +} diff --git a/packages/website-ue/src/pages/tanks/[slug]/_index.tsx b/packages/website-ue/src/pages/tanks/[slug]/_index.tsx index dd57078cc..84bc47c30 100644 --- a/packages/website-ue/src/pages/tanks/[slug]/_index.tsx +++ b/packages/website-ue/src/pages/tanks/[slug]/_index.tsx @@ -1,8 +1,4 @@ -import { - TankAttributeChange, - TankAttributeChange_AttributeName, - TankAttributeChange_Modifier, -} from "@protos/blitz_static_tank_upgrade_single_stage"; +import { TankAttributeChange_AttributeName } from "@protos/blitz_static_tank_upgrade_single_stage"; import { times } from "lodash-es"; import { Suspense, useMemo } from "react"; import { @@ -10,6 +6,7 @@ import { characteristicsOrder, } from "../../../constants/characteristicsOrder"; import { api } from "../../../core/api/dynamic"; +import { aggregateAttributes } from "../../../core/blitz/aggregateAttributes"; import { useAwait } from "../../../hooks/useAwait"; import { Tankopedia } from "../../../stores/tankopedia"; @@ -26,47 +23,15 @@ function Content({ id }: { id: string }) { const stage = Tankopedia.use((state) => state.stage); - const attributes = useMemo(() => { - const attributes: Partial< - Record - > = {}; - - function patch(changes: TankAttributeChange[]) { - for (const { attribute_name, value, modifier } of changes) { - switch (modifier) { - case TankAttributeChange_Modifier.MODIFIER_OVERRIDE: - attributes[attribute_name] = value; - break; - - case TankAttributeChange_Modifier.MODIFIER_MULTIPLY: { - if (!(attribute_name in attributes)) { - throw new Error( - `Missing attribute ${TankAttributeChange_AttributeName[attribute_name]} to modify` - ); - } - } - - case TankAttributeChange_Modifier.MODIFIER_MULTIPLY: { - attributes[attribute_name]! *= value; - break; - } - - default: - throw new Error( - `Unhandled modified ${TankAttributeChange_Modifier[modifier]}` - ); - } - } - } - - patch(tank.base_stats!.attributes); - - times(stage, (index) => { - patch(tank.upgrade_stages[index].attributes); - }); - - return attributes; - }, [stage]); + const attributes = useMemo( + () => + aggregateAttributes( + tank.base_stats!.attributes, + tank.upgrade_stages.map((stage) => stage.attributes), + stage + ), + [stage] + ); return ( <>