diff --git a/scripts/buildAssets/definitions.ts b/scripts/buildAssets/definitions.ts index 6f737f4f7..89af27e07 100644 --- a/scripts/buildAssets/definitions.ts +++ b/scripts/buildAssets/definitions.ts @@ -453,6 +453,36 @@ export async function definitions(production: boolean) { `${DATA}/${POI.vehicleDefinitions}/${nation}/components/chassis.xml.dvpl`, ); + function resolveUnlocks(unlocks?: Unlocks) { + if (!unlocks) return undefined; + + return Object.entries(unlocks) + .map(([type, list]) => + (Array.isArray(list) ? list : [list]).map((item) => { + const typeTyped = type as keyof Unlocks; + let rawId: number; + + if (typeTyped === 'chassis') { + rawId = chassisList.root.ids[item['#text']]; + } else if (typeTyped === 'engine') { + rawId = enginesList.root.ids[item['#text']]; + } else if (typeTyped === 'gun') { + rawId = gunList.root.ids[item['#text']]; + } else if (typeTyped === 'turret') { + rawId = turretList.root.ids[item['#text']]; + } else if (typeTyped === 'vehicle') { + rawId = tankList.root[item['#text']].id; + } + + return { + type: typeTyped, + id: toUniqueId(nation, rawId!), + }; + }), + ) + .flat(); + } + for (const tankKey in tankList.root) { if (botPattern.test(tankKey)) continue; @@ -626,6 +656,7 @@ export async function definitions(production: boolean) { soft: terrainResistances[2], }, tier: track.level as Tier, + unlocks: resolveUnlocks(track.unlocks), }); modelDefinitions[tankId].tracks[trackId] = { @@ -650,6 +681,7 @@ export async function definitions(production: boolean) { tier: engineListEntry.level as Tier, weight: engineListEntry.weight, power: engineListEntry.power, + unlocks: resolveUnlocks(engine.unlocks), }); }); @@ -711,6 +743,7 @@ export async function definitions(production: boolean) { health: turret.maxHealth, viewRange: turret.circularVisionRadius, weight: turret.weight, + unlocks: resolveUnlocks(turret.unlocks), }); modelDefinitions[tankId].turrets[turretId] = { @@ -829,6 +862,7 @@ export async function definitions(production: boolean) { shot: shotDispersionFactors.afterShot, traverse: shotDispersionFactors.turretRotation, }, + unlocks: resolveUnlocks(gun.unlocks), } as GunDefinition); modelDefinitions[tankId].turrets[turretId].guns[gunId] = { diff --git a/src/app/tools/tankopedia/[id]/components/Model/ModulesSection.tsx b/src/app/tools/tankopedia/[id]/components/Model/ModulesSection.tsx new file mode 100644 index 000000000..de04ef3c7 --- /dev/null +++ b/src/app/tools/tankopedia/[id]/components/Model/ModulesSection.tsx @@ -0,0 +1,73 @@ +import { Heading } from '@radix-ui/themes'; +import { use } from 'react'; +import PageWrapper from '../../../../../../components/PageWrapper'; +import { + EngineDefinition, + GunDefinition, + ModuleType, + tankDefinitions, + TrackDefinition, + TurretDefinition, + Unlock, +} from '../../../../../../core/blitzkit/tankDefinitions'; +import { useDuel } from '../../../../../../stores/duel'; + +export function ModulesSection() { + const awaitedTankDefinitions = use(tankDefinitions); + const tank = useDuel((state) => state.protagonist!.tank); + + function tree(type: ModuleType, unlocks: Unlock[]) { + return ( + + ); + } + + return ( + + turret0 + {tank.turrets[0].unlocks && tree('turret', tank.turrets[0].unlocks)} + + gun0 + {tank.turrets[0].guns[0].unlocks && + tree('gun', tank.turrets[0].guns[0].unlocks)} + + engine0 + {tank.engines[0].unlocks && tree('engine', tank.engines[0].unlocks)} + + track0 + {tank.tracks[0].unlocks && tree('chassis', tank.tracks[0].unlocks)} + + ); +} diff --git a/src/app/tools/tankopedia/[id]/page.tsx b/src/app/tools/tankopedia/[id]/page.tsx index 8b111e1ff..9b0965cd4 100644 --- a/src/app/tools/tankopedia/[id]/page.tsx +++ b/src/app/tools/tankopedia/[id]/page.tsx @@ -7,6 +7,7 @@ import { mutateDuel, useDuel } from '../../../../stores/duel'; import { mutateTankopediaTemporary } from '../../../../stores/tankopedia'; import { HeroSection } from './components/Model/HeroSection'; import { HistoricalSection } from './components/Model/HistoricalSection'; +import { ModulesSection } from './components/Model/ModulesSection'; import { TechTreeSection } from './components/Model/TechTreeSection'; import { Videos } from './components/Videos'; @@ -62,6 +63,7 @@ export default function Page({ params }: { params: { id: string } }) { {/* */} + {/* */} diff --git a/src/core/blitzkit/tankDefinitions/index.ts b/src/core/blitzkit/tankDefinitions/index.ts index 551570587..1df044345 100644 --- a/src/core/blitzkit/tankDefinitions/index.ts +++ b/src/core/blitzkit/tankDefinitions/index.ts @@ -14,6 +14,11 @@ export type CrewMember = | 'driver' | 'loader'; export type TankDefinitions = Record; +export type ModuleType = 'vehicle' | 'engine' | 'chassis' | 'turret' | 'gun'; +export interface Unlock { + type: ModuleType; + id: number; +} export interface Crew { type: CrewMember; count?: number; @@ -69,6 +74,7 @@ export interface TrackDefinition { medium: number; soft: number; }; + unlocks?: Unlock[]; } export interface EngineDefinition { id: number; @@ -78,6 +84,7 @@ export interface EngineDefinition { fireChance: number; power: number; weight: number; + unlocks?: Unlock[]; } export type TankDefinitionPrice = | { type: 'credits'; value: number } @@ -92,6 +99,7 @@ export interface TurretDefinition { tier: Tier; guns: GunDefinition[]; weight: number; + unlocks?: Unlock[]; } export type GunDefinition = | GunDefinitionRegular @@ -113,6 +121,7 @@ interface GunDefinitionBase { shot: number; damaged: number; }; + unlocks?: Unlock[]; } interface GunDefinitionRegular extends GunDefinitionBase { type: 'regular';