From 018aa33a7f63804e0c19830155b2f93728044604 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tr=C3=A8sAbhi?= <43380238+tresabhi@users.noreply.github.com> Date: Tue, 28 Apr 2026 21:22:50 -0500 Subject: [PATCH] feat: some aggregation Co-authored-by: Copilot --- ...geParameters.ts => aggregateParameters.ts} | 32 +- .../core/tankopedia/computeCharacteristics.ts | 2 +- .../pages/[...locale]/tanks/[slug]/_index.tsx | 456 ++++++++++-------- 3 files changed, 262 insertions(+), 228 deletions(-) rename packages/website-ue/src/core/tankopedia/{aggregateStageParameters.ts => aggregateParameters.ts} (87%) diff --git a/packages/website-ue/src/core/tankopedia/aggregateStageParameters.ts b/packages/website-ue/src/core/tankopedia/aggregateParameters.ts similarity index 87% rename from packages/website-ue/src/core/tankopedia/aggregateStageParameters.ts rename to packages/website-ue/src/core/tankopedia/aggregateParameters.ts index 6366027be..e4f812684 100644 --- a/packages/website-ue/src/core/tankopedia/aggregateStageParameters.ts +++ b/packages/website-ue/src/core/tankopedia/aggregateParameters.ts @@ -1,4 +1,4 @@ -import { TankAttributeChange } from "@protos/game/proto/legacy/auto_items"; +import type { TankCatalogComponent } from "@blitzkit/closed/protos/game/proto/legacy/blitz_static_tank_component"; import { StandardSinglePrice } from "@protos/game/proto/legacy/blitz_static_standard_single_price"; import { PenetrationGroup } from "@protos/game/proto/legacy/blitz_static_tank_penetration_group"; import { @@ -7,13 +7,14 @@ import { ShellUpgrade, ShellUpgradeSingleChange, StageParameters, + TankAttributeChange, TankAttributeChange_AttributeName, TankAttributeChange_Modifier, VisualChanges, } from "@protos/game/proto/legacy/blitz_static_tank_upgrade_single_stage"; function patch(stage0: StageParameters, stage1: StageParameters) { - if (stage1.stage_number !== ++stage0.stage_number) { + if (stage1.number !== ++stage0.number) { throw new Error("Change stage number must be 1 greater than base"); } @@ -181,26 +182,21 @@ function patch(stage0: StageParameters, stage1: StageParameters) { } } -export function aggregateStageParameters( - base: StageParameters, - stages: StageParameters[], +export function aggregateParameters( + tank: TankCatalogComponent, + upgrades: Record, ) { - const stage0 = StageParameters.create({ ...base, stage_number: 0 }); + const stage0 = StageParameters.create({}); - /** - * Bug in Reforged: base stats are stage 1, so is the first upgrade. Manually - * setting it to stage 0 below and if the bug's been fixed, throw an error - * in dev mode to allow clean up in the future. Also, update the initial - * stage number to -1. - */ + for (const line of tank.upgrade_lines) { + const stage = upgrades[line.name]; - if (base.stage_number === 0 && import.meta.env.DEV) { - throw new Error( - "Base stats are now stage 0. In-game bug fixed, please remove hack.", - ); + stage0.number = 0; + + for (let i = 0; i < stage; i++) { + patch(stage0, line.stages[i]); + } } - stages.forEach((stage) => patch(stage0, stage)); - return stage0; } diff --git a/packages/website-ue/src/core/tankopedia/computeCharacteristics.ts b/packages/website-ue/src/core/tankopedia/computeCharacteristics.ts index aab219bb0..6c3a77f22 100644 --- a/packages/website-ue/src/core/tankopedia/computeCharacteristics.ts +++ b/packages/website-ue/src/core/tankopedia/computeCharacteristics.ts @@ -3,7 +3,7 @@ import { ShellUpgradeSingleChange_AttributeName, TankAttributeChange_AttributeName, } from "@protos/game/proto/legacy/blitz_static_tank_upgrade_single_stage"; -import { aggregateStageParameters } from "./aggregateStageParameters"; +import { aggregateStageParameters } from "./aggregateParameters"; import { characteristics, type CharacteristicName, diff --git a/packages/website-ue/src/pages/[...locale]/tanks/[slug]/_index.tsx b/packages/website-ue/src/pages/[...locale]/tanks/[slug]/_index.tsx index 3a7aa68f7..9791251f2 100644 --- a/packages/website-ue/src/pages/[...locale]/tanks/[slug]/_index.tsx +++ b/packages/website-ue/src/pages/[...locale]/tanks/[slug]/_index.tsx @@ -1,15 +1,15 @@ -import { times } from "lodash-es"; -import { Suspense, useMemo } from "react"; -import { TankopediaCharacteristic } from "../../../../components/TankopediaCharacteristic"; -import { TankopediaToy } from "../../../../components/TankopediaToy"; +import { Grade } from "@blitzkit/closed/protos/game/proto/legacy/blitz_static_standard_grades_enum"; +import { + StageParameters_StageType, + TankAttributeChange_AttributeName, +} from "@blitzkit/closed/protos/game/proto/legacy/blitz_static_tank_upgrade_single_stage"; +import { Suspense } from "react"; import { api } from "../../../../core/api/dynamic"; -import { characteristicsOrder } from "../../../../core/tankopedia/characteristicsOrder"; -import { computeCharacteristics } from "../../../../core/tankopedia/computeCharacteristics"; -import { TerrainHardness } from "../../../../core/tankopedia/tankState"; +import { aggregateParameters } from "../../../../core/tankopedia/aggregateParameters"; import { useAwait } from "../../../../hooks/useAwait"; import { useGameStrings } from "../../../../hooks/useGameStrings"; import { LocaleProvider } from "../../../../hooks/useLocale"; -import { Tankopedia, TankopediaCompare } from "../../../../stores/tankopedia"; +import { Tankopedia } from "../../../../stores/tankopedia"; interface PageProps { id: string; @@ -43,21 +43,44 @@ function Content() { `tank-${protagonist.id}`, ); + const parameters = aggregateParameters( + protagonistTank.tank!, + protagonist.upgrades, + ); + return ( <>

{protagonist.id}


+

upgrades

+ {protagonistTank.tank!.upgrade_lines.map((line) => { return ( <> -

+

{line.name} ({protagonist.upgrades[line.name]}) -

+ -
+
{line.stages.map((stage, index) => { + if (stage.custom_picture) { + throw new Error("Custom picture not supported"); + } + + if (stage.required_upgrades.length > 0) { + console.log(stage.required_upgrades); + throw new Error("Required upgrades not supported"); + } + return ( ); @@ -76,230 +101,243 @@ function Content() { ); })} + +

parameters

+ +

attributes

+ + {parameters.attributes.map((attribute) => { + return ( + + {TankAttributeChange_AttributeName[attribute.attribute_name]}:{" "} + {attribute.value} + + ); + })} ); - const compare = Tankopedia.use((state) => state.compare); - const characteristics = useMemo( - () => computeCharacteristics(id, tank, protagonist), - [protagonist], - ); - // const otherCharacteristics = useMemo( - // () => - // tankList.list - // .filter((tank) => tank.id !== id) - // .map(({ id }) => { - // const state = { ...protagonist }; - // const tank = otherTanks.tanks[id]; - - // return computeCharacteristics( - // id, - // tank.tank!, - // tank.compensation!, - // state - // ); - // }), - // [protagonist] + // const compare = Tankopedia.use((state) => state.compare); + // const characteristics = useMemo( + // () => computeCharacteristics(id, tank, protagonist), + // [protagonist], // ); + // // const otherCharacteristics = useMemo( + // // () => + // // tankList.list + // // .filter((tank) => tank.id !== id) + // // .map(({ id }) => { + // // const state = { ...protagonist }; + // // const tank = otherTanks.tanks[id]; - return ( - <> -

{id}

+ // // return computeCharacteristics( + // // id, + // // tank.tank!, + // // tank.compensation!, + // // state + // // ); + // // }), + // // [protagonist] + // // ); -
- {tank.tank?.feature_screens?.tags.map((tag) => ( - {tag.value} - ))} -
+ // return ( + // <> + //

{id}

-
+ //
+ // {tank.tank?.feature_screens?.tags.map((tag) => ( + // {tag.value} + // ))} + //
-
- {times(tank.tank!.upgrade_stages.length + 1, (index) => ( - - ))} -
+ //
-
+ //
+ // {times(tank.tank!.upgrade_stages.length + 1, (index) => ( + // + // ))} + //
-
- {characteristics.parameters.shells_upgrades.map((shell) => ( - - ))} -
+ //
-
+ //
+ // {characteristics.parameters.shells_upgrades.map((shell) => ( + // + // ))} + //
-
- speed (0 - {characteristics.characteristics.speed_forward}) - { - Tankopedia.mutate((draft) => { - draft.protagonist.speed = event.target.valueAsNumber; - }); - }} - /> -
+ //
-
+ //
+ // speed (0 - {characteristics.characteristics.speed_forward}) + // { + // Tankopedia.mutate((draft) => { + // draft.protagonist.speed = event.target.valueAsNumber; + // }); + // }} + // /> + //
-
- isHullTraversing - { - Tankopedia.mutate((draft) => { - draft.protagonist.isHullTraversing = event.target.checked; - }); - }} - /> -
+ //
-
+ //
+ // isHullTraversing + // { + // Tankopedia.mutate((draft) => { + // draft.protagonist.isHullTraversing = event.target.checked; + // }); + // }} + // /> + //
-
- isTurretTraversing - { - Tankopedia.mutate((draft) => { - draft.protagonist.isTurretTraversing = event.target.checked; - }); - }} - /> -
+ //
-
+ //
+ // isTurretTraversing + // { + // Tankopedia.mutate((draft) => { + // draft.protagonist.isTurretTraversing = event.target.checked; + // }); + // }} + // /> + //
-
- isShooting - { - Tankopedia.mutate((draft) => { - draft.protagonist.isShooting = event.target.checked; - }); - }} - /> -
+ //
-
+ //
+ // isShooting + // { + // Tankopedia.mutate((draft) => { + // draft.protagonist.isShooting = event.target.checked; + // }); + // }} + // /> + //
-
- isGunDamaged - { - Tankopedia.mutate((draft) => { - draft.protagonist.isGunDamaged = event.target.checked; - }); - }} - /> -
+ //
-
+ //
+ // isGunDamaged + // { + // Tankopedia.mutate((draft) => { + // draft.protagonist.isGunDamaged = event.target.checked; + // }); + // }} + // /> + //
-
- {Object.values(TerrainHardness).map( - (hardness) => - typeof hardness === "number" && ( - - ), - )} -
+ //
-
+ //
+ // {Object.values(TerrainHardness).map( + // (hardness) => + // typeof hardness === "number" && ( + // + // ), + // )} + //
-
- isCaughtOnFire - { - Tankopedia.mutate((draft) => { - draft.protagonist.isCaughtOnFire = event.target.checked; - }); - }} - /> -
+ //
-
+ //
+ // isCaughtOnFire + // { + // Tankopedia.mutate((draft) => { + // draft.protagonist.isCaughtOnFire = event.target.checked; + // }); + // }} + // /> + //
-
- {Object.values(TankopediaCompare).map( - (c) => - typeof c === "number" && ( - - ), - )} -
+ //
-
+ //
+ // {Object.values(TankopediaCompare).map( + // (c) => + // typeof c === "number" && ( + // + // ), + // )} + //
- {characteristicsOrder.map(({ group, order }) => ( - <> -

{group}

+ //
- {order.map((config) => - "toy" in config ? ( - - ) : ( - - ), - )} - - ))} - - ); + // {characteristicsOrder.map(({ group, order }) => ( + // <> + //

{group}

+ + // {order.map((config) => + // "toy" in config ? ( + // + // ) : ( + // + // ), + // )} + // + // ))} + // + // ); }