diff --git a/scripts/buildAssets/definitions.ts b/scripts/buildAssets/definitions.ts index 43a3c23a8..3ed930fa9 100644 --- a/scripts/buildAssets/definitions.ts +++ b/scripts/buildAssets/definitions.ts @@ -68,6 +68,7 @@ interface VehicleDefinitions { armor: VehicleDefinitionArmor; turretPositions: { turret: string }; turretInitialRotation?: { yaw: 0; pitch: 6.5; roll: 0 }; + maxHealth: number; }; chassis: { [key: string]: { @@ -92,6 +93,7 @@ interface VehicleDefinitions { }; turrets0: { [key: string]: { + maxHealth: number; armor: VehicleDefinitionArmor; userString: number; level: number; @@ -345,6 +347,7 @@ export async function definitions(production: boolean) { }); tankDefinitions[tankId] = { + health: tankDefinition.root.hull.maxHealth, id: tankId, equipment, consumables: tankDefinition.root.consumableSlots, @@ -452,6 +455,7 @@ export async function definitions(production: boolean) { .replace(/^(Turret ([0-9] )?)+/, ''), tier: turret.level as Tier, guns: [], + health: turret.maxHealth, }); modelDefinitions[tankId].turrets[turretId] = { @@ -591,7 +595,7 @@ export async function definitions(production: boolean) { speed: gunShellEntry.speed, damage: { armor: shell.damage.armor, - devices: shell.damage.devices, + module: shell.damage.devices, }, caliber: shell.caliber, normalization: shell.normalizationAngle, diff --git a/src/app/tools/tankopedia/[id]/components/Characteristics/components/Info.tsx b/src/app/tools/tankopedia/[id]/components/Characteristics/components/Info.tsx index 40b2a93b0..d75d6e3eb 100644 --- a/src/app/tools/tankopedia/[id]/components/Characteristics/components/Info.tsx +++ b/src/app/tools/tankopedia/[id]/components/Characteristics/components/Info.tsx @@ -1,21 +1,29 @@ import { Flex, Text } from '@radix-ui/themes'; +import { ReactNode } from 'react'; import { theme } from '../../../../../../../stitches.config'; interface InfoProps { name: string; - value: string; + children: ReactNode; unit: string; indent?: boolean; + highlight?: boolean; } -export function Info({ name, value, unit, indent = false }: InfoProps) { +export function Info({ + name, + children, + unit, + indent = false, + highlight, +}: InfoProps) { return ( - + {name}{' '} {unit} @@ -26,11 +34,13 @@ export function Info({ name, value, unit, indent = false }: InfoProps) { style={{ flex: 1, height: 1, - backgroundColor: theme.colors.componentCallToActionInteractive_alpha, + backgroundColor: highlight + ? theme.colors.componentCallToActionInteractive_amberAlpha + : theme.colors.componentCallToActionInteractive_alpha, }} /> - {value} + {children} ); } diff --git a/src/app/tools/tankopedia/[id]/components/Characteristics/index.tsx b/src/app/tools/tankopedia/[id]/components/Characteristics/index.tsx index a71191a34..e4aae3225 100644 --- a/src/app/tools/tankopedia/[id]/components/Characteristics/index.tsx +++ b/src/app/tools/tankopedia/[id]/components/Characteristics/index.tsx @@ -1,4 +1,9 @@ import { Flex, Heading, Tabs } from '@radix-ui/themes'; +import { use } from 'react'; +import { resolveNearPenetration } from '../../../../../../core/blitz/resolveNearPenetration'; +import { modelDefinitions } from '../../../../../../core/blitzkrieg/modelDefinitions'; +import { SHELL_NAMES } from '../../../../../../core/blitzkrieg/tankDefinitions'; +import { useDuel } from '../../../../../../stores/duel'; import { Camouflage } from './components/Camouflage'; import { Consumables } from './components/Consumables'; import { Crew } from './components/Crew'; @@ -8,6 +13,29 @@ import { Modules } from './components/Modules'; import { Provisions } from './components/Provisions'; export function Characteristics() { + const awaitedModelDefinitions = use(modelDefinitions); + const { tank, turret, gun, shell } = useDuel((state) => state.protagonist!); + const tankModelDefinition = awaitedModelDefinitions[tank.id]; + const turretModelDefinition = tankModelDefinition.turrets[turret.id]; + const gunModelDefinition = turretModelDefinition.guns[gun.id]; + + let dpm: number; + + if (gun.type === 'regular') { + dpm = (shell.damage.armor / gun.reload) * 60; + } else if (gun.type === 'auto_loader') { + dpm = + ((shell.damage.armor * gun.count) / + (gun.reload + (gun.count - 1) * gun.interClip)) * + 60; + } else { + dpm = + ((shell.damage.armor * gun.count) / + (gun.reload.reduce((a, b) => a + b, 0) + + (gun.count - 1) * gun.interClip)) * + 60; + } + return ( @@ -20,75 +48,190 @@ export function Characteristics() { Survivability - - - - - - - - + + {tank.health + turret.health} + + + TODO + + + TODO + + + TODO + + + TODO + + + TODO + + + TODO + + + TODO + + + TODO + Fire - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + {dpm.toFixed(0)} + + {gun.type === 'auto_reloader' && ( + <> + + TODO + + + TODO + + + )} + {gun.type === 'auto_reloader' ? ( + gun.reload.map((reload, index) => ( + 0} + name={ + index > 0 ? `Shell ${index + 1}` : 'Reload on shell 1' + } + unit="s" + > + {reload.toFixed(2)} + + )) + ) : ( + + {gun.reload.toFixed(2)} + + )} + + {shell.caliber} + + {gun.shells.map((shell, index) => ( + 0} + name={`${SHELL_NAMES[shell.type]}${index === 0 ? ' penetration' : ''}`} + unit="mm" + > + {resolveNearPenetration(shell.penetration)} + + ))} + {gun.shells.map((shell, index) => ( + 0} + name={`${SHELL_NAMES[shell.type]}${index === 0 ? ' damage' : ''}`} + unit="hp" + > + {shell.damage.armor} + + ))} + {gun.shells.map((shell, index) => ( + 0} + name={`${SHELL_NAMES[shell.type]}${index === 0 ? ' module damage' : ''}`} + unit="hp" + > + {shell.damage.module} + + ))} + {gun.shells.map((shell, index) => ( + 0} + name={`${SHELL_NAMES[shell.type]}${index === 0 ? ' velocity' : ''}`} + unit="m/s" + > + {shell.speed} + + ))} + + TODO + + + TODO + + + TODO + + + TODO + + + TODO + + + TODO + + + {gunModelDefinition.pitch.max} + + + {-gunModelDefinition.pitch.min} + + {gunModelDefinition.pitch.front && ( + <> + + {gunModelDefinition.pitch.front.max} + + + {-gunModelDefinition.pitch.front.min} + + + )} + {gunModelDefinition.pitch.back && ( + <> + + {gunModelDefinition.pitch.back.max} + + + {-gunModelDefinition.pitch.back.min} + + + )} + {turretModelDefinition.yaw && ( + + {-turretModelDefinition.yaw.min},{' '} + {turretModelDefinition.yaw.max} + + )} Maneuverability - - - {/* TODO: average speed? */} - - - - - - - + + TODO + + + TODO + + + TODO + + + TODO + + + TODO + + + TODO + + + TODO + + + TODO + + + TODO + + + TODO + diff --git a/src/core/blitzkrieg/tankDefinitions.ts b/src/core/blitzkrieg/tankDefinitions.ts index 9c400de1f..5772e5917 100644 --- a/src/core/blitzkrieg/tankDefinitions.ts +++ b/src/core/blitzkrieg/tankDefinitions.ts @@ -15,6 +15,7 @@ export const SHELL_NAMES: Record = { export type TankDefinitions = Record; export interface TankDefinition { id: number; + health: number; nation: string; name: string; name_full?: string; @@ -33,6 +34,7 @@ export type TankDefinitionPrice = | { type: 'credits'; value: number } | { type: 'gold'; value: number }; export interface TurretDefinition { + health: number; id: number; name: string; tier: Tier; @@ -66,7 +68,7 @@ export type ShellDefinition = { id: number; name: string; speed: number; - damage: { armor: number; devices: number }; + damage: { armor: number; module: number }; caliber: number; icon: string; penetration: number | Vector2Tuple; diff --git a/src/stitches.config.ts b/src/stitches.config.ts index 0456441c8..413f706be 100644 --- a/src/stitches.config.ts +++ b/src/stitches.config.ts @@ -1,5 +1,6 @@ import { amberDark, + amberDarkA, blueDark, orangeDark, purpleDark, @@ -20,6 +21,7 @@ export const theme = { ...createColors(slate, 'light'), ...createColors(amberDark, 'amber'), + ...createColors(amberDarkA, 'amberAlpha'), ...createColors(orangeDark, 'orange'), ...createColors(purpleDark, 'purple'), ...createColors(blueDark, 'blue'),