From df1bc56a4c713ac1a5f07e060d2da7b4c422df64 Mon Sep 17 00:00:00 2001
From: tresabhi <43380238+tresabhi@users.noreply.github.com>
Date: Tue, 22 Apr 2025 21:22:26 -0500
Subject: [PATCH] feat: isolate stat sections
---
.../Characteristics/components/Crew.tsx | 112 +++
.../Characteristics/components/Firepower.tsx | 414 +++++++++
.../HullTraverseVisualizer/index.tsx | 4 +-
.../components/Maneuverability.tsx | 150 ++++
.../components/RicochetVisualizer.tsx | 4 +-
.../components/Survivability.tsx | 115 +++
.../components/ViewRangeVisualizer.tsx | 4 +-
.../components/Characteristics/index.tsx | 795 +-----------------
8 files changed, 807 insertions(+), 791 deletions(-)
create mode 100644 packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/components/Crew.tsx
create mode 100644 packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/components/Firepower.tsx
create mode 100644 packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/components/Maneuverability.tsx
create mode 100644 packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/components/Survivability.tsx
diff --git a/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/components/Crew.tsx b/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/components/Crew.tsx
new file mode 100644
index 000000000..56545abfb
--- /dev/null
+++ b/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/components/Crew.tsx
@@ -0,0 +1,112 @@
+import { CREW_MEMBER_NAMES, CrewType } from '@blitzkit/core';
+import { literals } from '@blitzkit/i18n';
+import { AccessibilityIcon, InfoCircledIcon } from '@radix-ui/react-icons';
+import { Flex, Heading, IconButton, Popover, Text } from '@radix-ui/themes';
+import { Fragment } from 'react/jsx-runtime';
+import { awaitableProvisionDefinitions } from '../../../../../../core/awaitables/provisionDefinitions';
+import { useEquipment } from '../../../../../../hooks/useEquipment';
+import { useLocale } from '../../../../../../hooks/useLocale';
+import { Duel } from '../../../../../../stores/duel';
+import type { StatsAcceptorProps } from './HullTraverseVisualizer';
+import { InfoWithDelta } from './InfoWithDelta';
+
+const provisionDefinitions = await awaitableProvisionDefinitions;
+
+export function Crew({ stats }: StatsAcceptorProps) {
+ const tank = Duel.use((state) => state.protagonist.tank);
+ const { strings } = useLocale();
+ const provisions = Duel.use((state) => state.protagonist.provisions);
+ const hasImprovedVentilation = useEquipment(102);
+ const provisionCrewBonus =
+ provisions.reduce(
+ (total, provision) =>
+ provisionDefinitions.provisions[provision].crew
+ ? total + provisionDefinitions.provisions[provision].crew! / 100
+ : total,
+ 0,
+ ) + (hasImprovedVentilation ? 0.08 : 0);
+ const commanderMastery = 1 + provisionCrewBonus;
+
+ return (
+
+
+
+ {strings.website.tools.tankopedia.crew.title}
+
+
+
+
+
+
+
+
+
+
+
+
+ {strings.website.tools.tankopedia.crew.info}
+
+
+
+
+
+
+
+ {tank.crew.map((member) => {
+ return (
+
+ 1
+ ? ` ${literals(strings.common.units.x, [`${member.count}`])}`
+ : ''
+ }`}
+ unit="%"
+ decimals={0}
+ noRanking
+ value={() =>
+ (member.type === CrewType.COMMANDER
+ ? commanderMastery
+ : commanderMastery * 1.1) * 100
+ }
+ />
+
+ {member.substitute.length > 0 && (
+
+
+
+ {member.substitute
+ .map((sub, index) =>
+ index === 0
+ ? strings.website.tools.tankopedia.crew[
+ CREW_MEMBER_NAMES[sub]
+ ]
+ : sub,
+ )
+ .join(', ')}
+
+ >
+ }
+ noRanking
+ value={() => commanderMastery * 1.05 * 100}
+ />
+ )}
+
+ );
+ })}
+
+ );
+}
diff --git a/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/components/Firepower.tsx b/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/components/Firepower.tsx
new file mode 100644
index 000000000..37a971ba4
--- /dev/null
+++ b/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/components/Firepower.tsx
@@ -0,0 +1,414 @@
+import {
+ asset,
+ coefficient,
+ isExplosive,
+ resolvePenetrationCoefficient,
+} from '@blitzkit/core';
+import { literals } from '@blitzkit/i18n';
+import {
+ Flex,
+ Heading,
+ IconButton,
+ Slider,
+ Text,
+ TextField,
+ Tooltip,
+} from '@radix-ui/themes';
+import { debounce } from 'lodash-es';
+import { useEffect, useRef, useState } from 'react';
+import { lerp } from 'three/src/math/MathUtils.js';
+import { useEquipment } from '../../../../../../hooks/useEquipment';
+import { useLocale } from '../../../../../../hooks/useLocale';
+import { useTankModelDefinition } from '../../../../../../hooks/useTankModelDefinition';
+import { Duel } from '../../../../../../stores/duel';
+import type { StatsAcceptorProps } from './HullTraverseVisualizer';
+import { Info } from './Info';
+import { InfoWithDelta } from './InfoWithDelta';
+import { RicochetVisualizer } from './RicochetVisualizer';
+
+export function Firepower({ stats }: StatsAcceptorProps) {
+ const mutateDuel = Duel.useMutation();
+ const { strings, unwrap } = useLocale();
+ const [penetrationDistance, setPenetrationDistance] = useState(250);
+ const setPenetrationDistanceDebounced = debounce((value: number) => {
+ setPenetrationDistance(value);
+ }, 500);
+ const { gun, shell, turret } = Duel.use((state) => state.protagonist);
+ const penetrationDistanceInput = useRef(null);
+ const hasSupercharger = useEquipment(107);
+ const hasCalibratedShells = useEquipment(103);
+ const penetrationCoefficient = coefficient([
+ hasCalibratedShells,
+ resolvePenetrationCoefficient(true, shell.type) - 1,
+ ]);
+ const penetrationLossOverDistanceCoefficient = coefficient([
+ hasSupercharger,
+ -0.6,
+ ]);
+ const tankModelDefinition = useTankModelDefinition();
+ const turretModelDefinition = tankModelDefinition.turrets[turret.id];
+ const gunModelDefinition =
+ turretModelDefinition.guns[gun.gun_type!.value.base.id];
+
+ useEffect(() => {
+ if (penetrationDistanceInput.current) {
+ penetrationDistanceInput.current.value = `${penetrationDistance}`;
+ }
+ }, [penetrationDistance]);
+
+ return (
+
+
+
+ {strings.website.tools.tankopedia.firepower.title}
+
+
+
+ {gun.gun_type!.value.base.shells.map((thisShell, shellIndex) => (
+
+ {
+ mutateDuel((draft) => {
+ draft.protagonist.shell = thisShell;
+ });
+ }}
+ >
+
+
+
+ ))}
+
+
+
+
+ {strings.common.gun_types[gun.gun_type!.$case]}
+
+
+ {gun.gun_type!.$case === 'auto_reloader' && (
+
+ )}
+ {gun.gun_type!.$case !== 'regular' && (
+
+ )}
+ {gun.gun_type!.$case === 'auto_reloader' ? (
+ <>
+
+ {stats.mostOptimalShellIndex! + 1}
+
+
+ {stats.shellReloads!.map((reload, index) => (
+ reload}
+ />
+ ))}
+ >
+ ) : (
+
+ )}
+ {(gun.gun_type!.$case === 'auto_loader' ||
+ gun.gun_type!.$case === 'auto_reloader') && (
+
+ )}
+
+ {typeof shell.penetration !== 'number' && (
+ <>
+
+ lerp(
+ shell.penetration.near,
+ shell.penetration.far,
+ (penetrationDistance * penetrationLossOverDistanceCoefficient) /
+ 500,
+ ) * penetrationCoefficient
+ }
+ />
+
+
+ {
+ strings.website.tools.tankopedia.characteristics.values
+ .at_distance_slider_label
+ }
+
+ {
+ setPenetrationDistanceDebounced(value);
+
+ if (!penetrationDistanceInput.current) return;
+
+ penetrationDistanceInput.current.value = value.toString();
+ }}
+ />
+ {
+ setPenetrationDistance(
+ Math.min(
+ parseInt(penetrationDistanceInput.current!.value),
+ 500,
+ ),
+ );
+ }}
+ onKeyDown={(event) => {
+ if (event.key === 'Enter') {
+ event.currentTarget.blur();
+ }
+ }}
+ >
+ m
+
+
+ >
+ )}
+
+ {gun.gun_type!.$case !== 'regular' && (
+
+ )}
+
+ {isExplosive(shell.type) && (
+
+ )}
+
+
+ {!isExplosive(shell.type) && (
+ <>
+
+
+
+ >
+ )}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {gunModelDefinition.pitch.front && (
+ <>
+
+
+ >
+ )}
+ {gunModelDefinition.pitch.back && (
+ <>
+
+
+ >
+ )}
+ {turretModelDefinition.yaw && (
+ <>
+
+
+ >
+ )}
+
+ );
+}
diff --git a/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/components/HullTraverseVisualizer/index.tsx b/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/components/HullTraverseVisualizer/index.tsx
index 08774a8eb..c9788a814 100644
--- a/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/components/HullTraverseVisualizer/index.tsx
+++ b/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/components/HullTraverseVisualizer/index.tsx
@@ -4,13 +4,13 @@ import type { TankCharacteristics } from '../../../../../../../core/blitzkit/tan
import { useLocale } from '../../../../../../../hooks/useLocale';
import './index.css';
-export interface VisualizerProps {
+export interface StatsAcceptorProps {
stats: TankCharacteristics;
}
type Terrain = 'Hard' | 'Medium' | 'Soft';
-export function HullTraverseVisualizer({ stats }: VisualizerProps) {
+export function HullTraverseVisualizer({ stats }: StatsAcceptorProps) {
const hull = useRef(null);
const turret = useRef(null);
const [terrain, setTerrain] = useState('Hard');
diff --git a/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/components/Maneuverability.tsx b/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/components/Maneuverability.tsx
new file mode 100644
index 000000000..f61ac9b04
--- /dev/null
+++ b/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/components/Maneuverability.tsx
@@ -0,0 +1,150 @@
+import { Flex, Heading } from '@radix-ui/themes';
+import { useLocale } from '../../../../../../hooks/useLocale';
+import {
+ HullTraverseVisualizer,
+ type StatsAcceptorProps,
+} from './HullTraverseVisualizer';
+import { Info } from './Info';
+import { InfoWithDelta } from './InfoWithDelta';
+
+export function Maneuverability({ stats }: StatsAcceptorProps) {
+ const { strings } = useLocale();
+
+ return (
+
+
+ {strings.website.tools.tankopedia.maneuverability.title}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
diff --git a/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/components/RicochetVisualizer.tsx b/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/components/RicochetVisualizer.tsx
index 8f9c67f77..328203712 100644
--- a/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/components/RicochetVisualizer.tsx
+++ b/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/components/RicochetVisualizer.tsx
@@ -6,9 +6,9 @@ import { clamp, degToRad, radToDeg } from 'three/src/math/MathUtils.js';
import { Var } from '../../../../../../core/radix/var';
import { useLocale } from '../../../../../../hooks/useLocale';
import { Duel } from '../../../../../../stores/duel';
-import type { VisualizerProps } from './HullTraverseVisualizer';
+import type { StatsAcceptorProps } from './HullTraverseVisualizer';
-export function RicochetVisualizer({ stats }: VisualizerProps) {
+export function RicochetVisualizer({ stats }: StatsAcceptorProps) {
const shell = Duel.use((state) => state.protagonist.shell);
const container = useRef(null);
const normalization = degToRad(stats.shellNormalization);
diff --git a/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/components/Survivability.tsx b/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/components/Survivability.tsx
new file mode 100644
index 000000000..6ca40635a
--- /dev/null
+++ b/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/components/Survivability.tsx
@@ -0,0 +1,115 @@
+import { Flex, Heading } from '@radix-ui/themes';
+import { useLocale } from '../../../../../../hooks/useLocale';
+import type { StatsAcceptorProps } from './HullTraverseVisualizer';
+import { Info } from './Info';
+import { InfoWithDelta } from './InfoWithDelta';
+import { ViewRangeVisualizer } from './ViewRangeVisualizer';
+
+export function Survivability({ stats }: StatsAcceptorProps) {
+ const { strings } = useLocale();
+
+ return (
+
+
+ {strings.website.tools.tankopedia.survivability.title}
+
+
+ stats.fireChance * 100}
+ />
+
+
+
+ stats.camouflageStill * 100}
+ stats={stats}
+ indent
+ name={
+ strings.website.tools.tankopedia.characteristics.values
+ .camouflageStill
+ }
+ decimals={2}
+ />
+ stats.camouflageMoving * 100}
+ stats={stats}
+ indent
+ name={
+ strings.website.tools.tankopedia.characteristics.values
+ .camouflageMoving
+ }
+ decimals={2}
+ />
+ stats.camouflageShootingStill * 100}
+ />
+ stats.camouflageShootingMoving * 100}
+ />
+ stats.camouflageCaughtOnFire * 100}
+ />
+
+
+
+
+
+ );
+}
diff --git a/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/components/ViewRangeVisualizer.tsx b/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/components/ViewRangeVisualizer.tsx
index d0288f2ea..2864ba246 100644
--- a/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/components/ViewRangeVisualizer.tsx
+++ b/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/components/ViewRangeVisualizer.tsx
@@ -4,7 +4,7 @@ import { Box, Card, Code, Flex, Slider, Tabs, Text } from '@radix-ui/themes';
import { useRef, useState } from 'react';
import { Var } from '../../../../../../core/radix/var';
import { useLocale } from '../../../../../../hooks/useLocale';
-import type { VisualizerProps } from './HullTraverseVisualizer';
+import type { StatsAcceptorProps } from './HullTraverseVisualizer';
const maps = [
{
@@ -19,7 +19,7 @@ const maps = [
},
] as const;
-export function ViewRangeVisualizer({ stats }: VisualizerProps) {
+export function ViewRangeVisualizer({ stats }: StatsAcceptorProps) {
const [mapIndex, setMapIndex] = useState(0);
const [camouflage, setCamouflage] = useState(0);
const map = maps[mapIndex];
diff --git a/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/index.tsx b/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/index.tsx
index 72010177e..acd15b239 100644
--- a/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/index.tsx
+++ b/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/index.tsx
@@ -1,41 +1,17 @@
-import {
- asset,
- coefficient,
- CREW_MEMBER_NAMES,
- CrewType,
- isExplosive,
- resolvePenetrationCoefficient,
-} from '@blitzkit/core';
-import { literals } from '@blitzkit/i18n/src/literals';
-import { AccessibilityIcon, InfoCircledIcon } from '@radix-ui/react-icons';
-import {
- Flex,
- Heading,
- IconButton,
- Popover,
- Slider,
- Text,
- TextField,
- Tooltip,
-} from '@radix-ui/themes';
-import { debounce } from 'lodash-es';
-import { useEffect, useRef, useState } from 'react';
-import { Fragment } from 'react/jsx-runtime';
-import { lerp } from 'three/src/math/MathUtils.js';
+import { Flex } from '@radix-ui/themes';
+import { useEffect } from 'react';
import { awaitableEquipmentDefinitions } from '../../../../../core/awaitables/equipmentDefinitions';
import { awaitableProvisionDefinitions } from '../../../../../core/awaitables/provisionDefinitions';
import { applyPitchYawLimits } from '../../../../../core/blitz/applyPitchYawLimits';
import { tankCharacteristics } from '../../../../../core/blitzkit/tankCharacteristics';
import { useEquipment } from '../../../../../hooks/useEquipment';
-import { useLocale } from '../../../../../hooks/useLocale';
import { useTankModelDefinition } from '../../../../../hooks/useTankModelDefinition';
import { Duel } from '../../../../../stores/duel';
import { TankopediaEphemeral } from '../../../../../stores/tankopediaEphemeral';
-import { HullTraverseVisualizer } from './components/HullTraverseVisualizer';
-import { Info } from './components/Info';
-import { InfoWithDelta } from './components/InfoWithDelta';
-import { RicochetVisualizer } from './components/RicochetVisualizer';
-import { ViewRangeVisualizer } from './components/ViewRangeVisualizer';
+import { Crew } from './components/Crew';
+import { Firepower } from './components/Firepower';
+import { Maneuverability } from './components/Maneuverability';
+import { Survivability } from './components/Survivability';
const [equipmentDefinitions, provisionDefinitions] = await Promise.all([
awaitableEquipmentDefinitions,
@@ -43,26 +19,9 @@ const [equipmentDefinitions, provisionDefinitions] = await Promise.all([
]);
export function Characteristics() {
- const { unwrap, strings } = useLocale();
const mutateDuel = Duel.useMutation();
const crewSkills = TankopediaEphemeral.use((state) => state.skills);
- const penetrationDistanceInput = useRef(null);
- const hasImprovedVentilation = useEquipment(102);
- const [penetrationDistance, setPenetrationDistance] = useState(250);
- const setPenetrationDistanceDebounced = debounce((value: number) => {
- setPenetrationDistance(value);
- }, 500);
-
const provisions = Duel.use((state) => state.protagonist.provisions);
- const provisionCrewBonus =
- provisions.reduce(
- (total, provision) =>
- provisionDefinitions.provisions[provision].crew
- ? total + provisionDefinitions.provisions[provision].crew! / 100
- : total,
- 0,
- ) + (hasImprovedVentilation ? 0.08 : 0);
- const commanderMastery = 1 + provisionCrewBonus;
const consumables = Duel.use((state) => state.protagonist.consumables);
const camouflage = Duel.use((state) => state.protagonist.camouflage);
const equipmentMatrix = Duel.use(
@@ -107,24 +66,9 @@ export function Characteristics() {
},
);
- const hasSupercharger = useEquipment(107);
- const hasCalibratedShells = useEquipment(103);
const hasImprovedVerticalStabilizer = useEquipment(122);
const hasDownImprovedVerticalStabilizer = useEquipment(124);
- const penetrationCoefficient = coefficient([
- hasCalibratedShells,
- resolvePenetrationCoefficient(true, shell.type) - 1,
- ]);
- const penetrationLossOverDistanceCoefficient = coefficient([
- hasSupercharger,
- -0.6,
- ]);
- useEffect(() => {
- if (penetrationDistanceInput.current) {
- penetrationDistanceInput.current.value = `${penetrationDistance}`;
- }
- }, [penetrationDistance]);
useEffect(() => {
mutateDuel((draft) => {
[draft.protagonist.pitch, draft.protagonist.yaw] = applyPitchYawLimits(
@@ -147,732 +91,13 @@ export function Characteristics() {
}}
>
-
-
-
- {strings.website.tools.tankopedia.firepower.title}
-
-
-
- {gun.gun_type!.value.base.shells.map((thisShell, shellIndex) => (
-
- {
- mutateDuel((draft) => {
- draft.protagonist.shell = thisShell;
- });
- }}
- >
-
-
-
- ))}
-
-
-
- {strings.common.gun_types[gun.gun_type!.$case]}
-
-
- {gun.gun_type!.$case === 'auto_reloader' && (
-
- )}
- {gun.gun_type!.$case !== 'regular' && (
-
- )}
- {gun.gun_type!.$case === 'auto_reloader' ? (
- <>
-
- {stats.mostOptimalShellIndex! + 1}
-
-
- {stats.shellReloads!.map((reload, index) => (
- reload}
- />
- ))}
- >
- ) : (
-
- )}
- {(gun.gun_type!.$case === 'auto_loader' ||
- gun.gun_type!.$case === 'auto_reloader') && (
-
- )}
-
- {typeof shell.penetration !== 'number' && (
- <>
-
- lerp(
- shell.penetration.near,
- shell.penetration.far,
- (penetrationDistance *
- penetrationLossOverDistanceCoefficient) /
- 500,
- ) * penetrationCoefficient
- }
- />
-
-
- {
- strings.website.tools.tankopedia.characteristics.values
- .at_distance_slider_label
- }
-
- {
- setPenetrationDistanceDebounced(value);
-
- if (!penetrationDistanceInput.current) return;
-
- penetrationDistanceInput.current.value = value.toString();
- }}
- />
- {
- setPenetrationDistance(
- Math.min(
- parseInt(penetrationDistanceInput.current!.value),
- 500,
- ),
- );
- }}
- onKeyDown={(event) => {
- if (event.key === 'Enter') {
- event.currentTarget.blur();
- }
- }}
- >
- m
-
-
- >
- )}
-
- {gun.gun_type!.$case !== 'regular' && (
-
- )}
-
- {isExplosive(shell.type) && (
-
- )}
-
-
- {!isExplosive(shell.type) && (
- <>
-
-
-
- >
- )}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {gunModelDefinition.pitch.front && (
- <>
-
-
- >
- )}
- {gunModelDefinition.pitch.back && (
- <>
-
-
- >
- )}
- {turretModelDefinition.yaw && (
- <>
-
-
- >
- )}
-
-
-
-
-
- {strings.website.tools.tankopedia.crew.title}
-
-
-
-
-
-
-
-
-
-
-
-
- {strings.website.tools.tankopedia.crew.info}
-
-
-
-
-
-
-
- {tank.crew.map((member) => {
- return (
-
- 1
- ? ` ${literals(strings.common.units.x, [
- `${member.count}`,
- ])}`
- : ''
- }`}
- unit="%"
- decimals={0}
- noRanking
- value={() =>
- (member.type === CrewType.COMMANDER
- ? commanderMastery
- : commanderMastery * 1.1) * 100
- }
- />
-
- {member.substitute.length > 0 && (
-
-
-
- {member.substitute
- .map((sub, index) =>
- index === 0
- ? strings.website.tools.tankopedia.crew[
- CREW_MEMBER_NAMES[sub]
- ]
- : sub,
- )
- .join(', ')}
-
- >
- }
- noRanking
- value={() => commanderMastery * 1.05 * 100}
- />
- )}
-
- );
- })}
-
+
+
-
-
- {strings.website.tools.tankopedia.maneuverability.title}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {strings.website.tools.tankopedia.survivability.title}
-
-
- stats.fireChance * 100}
- />
-
-
-
- stats.camouflageStill * 100}
- stats={stats}
- indent
- name={
- strings.website.tools.tankopedia.characteristics.values
- .camouflageStill
- }
- decimals={2}
- />
- stats.camouflageMoving * 100}
- stats={stats}
- indent
- name={
- strings.website.tools.tankopedia.characteristics.values
- .camouflageMoving
- }
- decimals={2}
- />
- stats.camouflageShootingStill * 100}
- />
- stats.camouflageShootingMoving * 100}
- />
- stats.camouflageCaughtOnFire * 100}
- />
-
-
-
-
-
+
+
);