diff --git a/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/components/Info.tsx b/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/components/Info.tsx index 93772e116..27d959d7e 100644 --- a/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/components/Info.tsx +++ b/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/components/Info.tsx @@ -1,5 +1,5 @@ import { CaretDownIcon, CaretUpIcon } from '@radix-ui/react-icons'; -import { Flex, Separator, Text } from '@radix-ui/themes'; +import { Box, Flex, Text } from '@radix-ui/themes'; import type { ReactNode } from 'react'; export interface InfoProps { @@ -24,11 +24,7 @@ export function Info({ deltaType = 'higherIsBetter', }: InfoProps) { return ( - + {name} {unit != undefined && ( @@ -41,7 +37,7 @@ export function Info({ )} - {children !== undefined && } + {children !== undefined && ( diff --git a/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/components/InfoWithDelta.tsx b/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/components/InfoWithDelta.tsx index f6c5a5a9a..13ff2cf5d 100644 --- a/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/components/InfoWithDelta.tsx +++ b/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/components/InfoWithDelta.tsx @@ -1,20 +1,115 @@ -import type { TankCharacteristics } from '../../../../../../core/blitzkit/tankCharacteristics'; +import { + createDefaultSkills, + fetchEquipmentDefinitions, + fetchModelDefinitions, + fetchProvisionDefinitions, + fetchSkillDefinitions, + fetchTankDefinitions, +} from '@blitzkit/core'; +import { Flex, Progress, Text } from '@radix-ui/themes'; +import { useMemo } from 'react'; +import { + tankCharacteristics, + type TankCharacteristics, +} from '../../../../../../core/blitzkit/tankCharacteristics'; +import { tankToDuelMember } from '../../../../../../core/blitzkit/tankToDuelMember'; import { useDelta } from '../../../../../../hooks/useDelta'; -import { type InfoProps, Info } from './Info'; +import { Duel } from '../../../../../../stores/duel'; +import { Info, type InfoProps } from './Info'; interface InfoWithDeltaProps extends InfoProps { stats: TankCharacteristics; - value: keyof TankCharacteristics | (() => number | undefined); + value: + | keyof TankCharacteristics + | ((tank: TankCharacteristics) => number | undefined); + noRanking?: boolean; } -export function InfoWithDelta({ value, stats, ...props }: InfoWithDeltaProps) { +const tankDefinitions = await fetchTankDefinitions(); +const provisionDefinitions = await fetchProvisionDefinitions(); +const equipmentDefinitions = await fetchEquipmentDefinitions(); +const tankModelDefinitions = await fetchModelDefinitions(); +const skillDefinitions = await fetchSkillDefinitions(); + +export function InfoWithDelta({ + value, + stats, + indent, + noRanking, + deltaType, + ...props +}: InfoWithDeltaProps) { const uhWhatDoICallThisVariable = - typeof value === 'function' ? value()! : (stats[value] as number); + typeof value === 'function' ? value(stats)! : (stats[value] as number); const delta = useDelta(uhWhatDoICallThisVariable); + const protagonistTank = Duel.use((state) => state.protagonist.tank); + const others = useMemo(() => { + const defaultSkills = createDefaultSkills(skillDefinitions); + + return Object.values(tankDefinitions.tanks) + .filter((tank) => tank.tier === protagonistTank.tier) + .map((tank) => { + const member = tankToDuelMember(tank, provisionDefinitions); + + return tankCharacteristics( + { + applyDynamicArmor: false, + applyReactiveArmor: false, + applySpallLiner: false, + camouflage: member.camouflage, + consumables: member.consumables, + crewSkills: defaultSkills, + provisions: member.provisions, + engine: member.engine, + gun: member.gun, + equipmentMatrix: member.equipmentMatrix, + shell: member.shell, + stockEngine: tank.engines[0], + stockGun: tank.turrets[0].guns[0], + stockTrack: tank.tracks[0], + stockTurret: tank.turrets[0], + tank, + track: member.track, + turret: member.turret, + }, + { + equipmentDefinitions, + provisionDefinitions, + tankModelDefinition: tankModelDefinitions.models[tank.id], + }, + ); + }) + .filter((tank) => { + const othersValue = + typeof value === 'function' ? value(tank)! : (tank[value] as number); + + return othersValue !== undefined; + }); + }, []); + const betterTanks = others.filter((tank) => { + const othersValue = + typeof value === 'function' ? value(tank)! : (tank[value] as number); + + if (othersValue === undefined) return false; + return deltaType === 'lowerIsBetter' + ? othersValue < uhWhatDoICallThisVariable + : othersValue > uhWhatDoICallThisVariable; + }); return ( - - {uhWhatDoICallThisVariable} - + + + {uhWhatDoICallThisVariable} + + + {!noRanking && ( + + + + {betterTanks.length + 1} / {others.length} + + + )} + ); } 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 2c3513429..33ccd655b 100644 --- a/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/index.tsx +++ b/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/index.tsx @@ -138,7 +138,7 @@ export function Characteristics() { }} > - + Firepower @@ -215,6 +215,7 @@ export function Characteristics() { name={`Shell ${index + 1}`} decimals={2} deltaType="lowerIsBetter" + noRanking value={() => reload} /> ))} @@ -255,6 +256,7 @@ export function Characteristics() { indent decimals={0} name={`At ${penetrationDistance}m`} + noRanking value={() => lerp( shell.penetration.near, @@ -331,6 +333,7 @@ export function Characteristics() { stats={stats} name="Splash radius" unit="m" + noRanking decimals={0} value="explosionRadius" /> @@ -347,12 +350,14 @@ export function Characteristics() { name="Normalization" decimals={0} unit="°" + noRanking value="shellNormalization" /> {!isExplosive(shell.type) && ( )} - + + Crew training @@ -554,6 +560,7 @@ export function Characteristics() { }`} unit="%" decimals={0} + noRanking value={() => (member.type === CrewType.COMMANDER ? commanderMastery @@ -580,6 +587,7 @@ export function Characteristics() { } + noRanking value={() => commanderMastery * 1.05 * 100} /> )} @@ -590,7 +598,7 @@ export function Characteristics() { - + Maneuverability - + + Survivability stats.fireChance * 100} + value={(stats) => stats.fireChance * 100} /> stats.camouflageStill * 100} + value={(stats) => stats.camouflageStill * 100} stats={stats} indent name="Still" decimals={2} /> stats.camouflageMoving * 100} + value={(stats) => stats.camouflageMoving * 100} stats={stats} indent name="Moving" @@ -770,21 +779,21 @@ export function Characteristics() { indent name="Shooting still" decimals={2} - value={() => stats.camouflageShootingStill * 100} + value={(stats) => stats.camouflageShootingStill * 100} /> stats.camouflageShootingMoving * 100} + value={(stats) => stats.camouflageShootingMoving * 100} /> stats.camouflageCaughtOnFire * 100} + value={(stats) => stats.camouflageCaughtOnFire * 100} />