From 96482d4268fd808317f6bf658864f60357567ed0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tr=C3=A8sAbhi?= <43380238+tresabhi@users.noreply.github.com> Date: Mon, 1 Sep 2025 22:56:39 -0500 Subject: [PATCH] feat: renaming --- .../Armor/components/ArmorPlateDisplay.tsx | 66 ++++--- .../PrimaryArmorSceneComponent/index.tsx | 60 +++---- .../Armor/components/ShotDisplay.tsx | 74 ++++---- .../Armor/components/ShotDisplayCard.tsx | 44 ++--- .../SpacedArmorSubExternal/index.tsx | 40 ++--- .../components/SpacedArmorSubSpaced/index.tsx | 46 ++--- .../SpacedArmorSceneComponent/index.tsx | 102 +++++------ .../Armor/components/StaticArmor.tsx | 136 +++++++-------- .../components/StaticArmorSceneComponent.tsx | 62 +++---- .../src/components/GuessBackground/index.tsx | 6 +- .../website/src/components/GuessRenderer.tsx | 2 +- packages/website/src/components/Guesser.tsx | 2 +- .../components/CompareOptions.tsx | 26 ++- .../Characteristics/components/Info.tsx | 38 ++-- .../components/InfoWithDelta.tsx | 78 ++++----- .../Characteristics/components/StatSearch.tsx | 38 ++-- .../components/Characteristics/index.tsx | 60 +++---- .../components/Skills.tsx | 20 +-- .../Options/components/CustomShellButton.tsx | 68 ++++---- .../components/DynamicArmorSwitcher.tsx | 24 +-- .../Options/components/Thicknesses.tsx | 82 ++++----- .../HeroSection/components/Options/index.tsx | 162 +++++++++--------- .../components/ScrollHint/index.tsx | 20 +-- .../components/TankSandbox/Title/index.tsx | 36 ++-- .../TankSandbox/components/Control.tsx | 78 ++++----- .../components/InitialFogReveal.tsx | 12 +- .../TankSandbox/components/TankModel.tsx | 99 ++++++----- .../components/TransitionSkeleton/index.tsx | 36 ++-- .../components/TankSandbox/index.tsx | 90 +++++----- .../Tankopedia/HeroSection/index.tsx | 76 ++++---- .../TechTreeSection/components/Node.tsx | 70 ++++---- .../Tankopedia/TechTreeSection/index.tsx | 70 ++++---- .../src/hooks/useTankModelDefinition.ts | 4 +- .../src/pages/[...locale]/guess/_index.tsx | 6 +- .../pages/[...locale]/tanks/[slug]/_index.tsx | 4 +- .../api/tankopedia/tank-icon/[id]/_index.tsx | 4 +- .../stores/{guessEphemeral.ts => guess.ts} | 0 .../{tankopediaEphemeral.ts => tankopedia.ts} | 33 ++-- 38 files changed, 931 insertions(+), 943 deletions(-) rename packages/website/src/stores/{guessEphemeral.ts => guess.ts} (100%) rename packages/website/src/stores/{tankopediaEphemeral.ts => tankopedia.ts} (71%) diff --git a/packages/website/src/components/Armor/components/ArmorPlateDisplay.tsx b/packages/website/src/components/Armor/components/ArmorPlateDisplay.tsx index 030a99f58..3dc063948 100644 --- a/packages/website/src/components/Armor/components/ArmorPlateDisplay.tsx +++ b/packages/website/src/components/Armor/components/ArmorPlateDisplay.tsx @@ -1,4 +1,4 @@ -import { ReloadIcon } from '@radix-ui/react-icons'; +import { ReloadIcon } from "@radix-ui/react-icons"; import { Card, Code, @@ -6,21 +6,19 @@ import { IconButton, Text, TextField, -} from '@radix-ui/themes'; -import { Html } from '@react-three/drei'; -import { useRef } from 'react'; -import { radToDeg } from 'three/src/math/MathUtils.js'; -import { resolveArmorIndex } from '../../../core/blitzkit/resolveArmorIndex'; -import { App } from '../../../stores/app'; -import { Duel } from '../../../stores/duel'; -import { TankopediaEphemeral } from '../../../stores/tankopediaEphemeral'; -import { layerTypeNames } from './ShotDisplayCard'; -import { ArmorType } from './SpacedArmorScene'; +} from "@radix-ui/themes"; +import { Html } from "@react-three/drei"; +import { useRef } from "react"; +import { radToDeg } from "three/src/math/MathUtils.js"; +import { resolveArmorIndex } from "../../../core/blitzkit/resolveArmorIndex"; +import { App } from "../../../stores/app"; +import { Duel } from "../../../stores/duel"; +import { Tankopedia } from "../../../stores/tankopedia"; +import { layerTypeNames } from "./ShotDisplayCard"; +import { ArmorType } from "./SpacedArmorScene"; export function ArmorPlateDisplay() { - const highlightArmor = TankopediaEphemeral.use( - (state) => state.highlightArmor, - ); + const highlightArmor = Tankopedia.use((state) => state.highlightArmor); const developerMode = App.useDeferred((state) => state.developerMode, false); const duelStore = Duel.useStore(); const input = useRef(null); @@ -31,20 +29,20 @@ export function ArmorPlateDisplay() { - {layerTypeNames[highlightArmor.type]}{' '} + {layerTypeNames[highlightArmor.type]}{" "} {highlightArmor.thickness.toFixed(0)} mm @@ -90,10 +88,10 @@ export function ArmorPlateDisplay() { if (isNaN(thickness) || thickness < 0) return; - if (event.key === 'Enter') { + if (event.key === "Enter") { input.current?.blur(); - TankopediaEphemeral.mutate((draft) => { + Tankopedia.mutate((draft) => { draft.highlightArmor = undefined; const { protagonist } = duelStore.getState(); const tank = draft.model; @@ -101,23 +99,23 @@ export function ArmorPlateDisplay() { const gun = turret.guns[protagonist.gun.id]; const track = tank.tracks[protagonist.track.id]; - if (highlightArmor.name.startsWith('hull_')) { + if (highlightArmor.name.startsWith("hull_")) { tank.armor.thickness[index] = thickness; - } else if (highlightArmor.name.startsWith('turret_')) { + } else if (highlightArmor.name.startsWith("turret_")) { turret.armor.thickness[index] = thickness; - } else if (highlightArmor.name.startsWith('gun_')) { - if (highlightArmor.name.includes('_armor_')) { + } else if (highlightArmor.name.startsWith("gun_")) { + if (highlightArmor.name.includes("_armor_")) { gun.armor.thickness[index] = thickness; } else { gun.thickness = thickness; } - } else if (highlightArmor.name.startsWith('chassis_')) { + } else if (highlightArmor.name.startsWith("chassis_")) { track.thickness = thickness; } }); - } else if (event.key === 'Escape') { + } else if (event.key === "Escape") { input.current?.blur(); - TankopediaEphemeral.mutate((draft) => { + Tankopedia.mutate((draft) => { draft.highlightArmor = undefined; }); } @@ -135,7 +133,7 @@ export function ArmorPlateDisplay() { mt="2" color="red" onClick={() => { - TankopediaEphemeral.mutate((draft) => { + Tankopedia.mutate((draft) => { if (!highlightArmor.editingPlate) return; const index = resolveArmorIndex(highlightArmor.name); @@ -143,7 +141,7 @@ export function ArmorPlateDisplay() { if (index === undefined) return; draft.highlightArmor = undefined; - const initialState = TankopediaEphemeral.initial; + const initialState = Tankopedia.initial; const { protagonist } = duelStore.getState(); const tank = draft.model; const initialTank = initialState.model; @@ -156,20 +154,20 @@ export function ArmorPlateDisplay() { const initialTrack = initialTank.tracks[protagonist.track.id]; - if (highlightArmor.name.startsWith('hull_')) { + if (highlightArmor.name.startsWith("hull_")) { tank.armor.thickness[index] = initialTank.armor.thickness[index]; - } else if (highlightArmor.name.startsWith('turret_')) { + } else if (highlightArmor.name.startsWith("turret_")) { turret.armor.thickness[index] = initialTurret.armor.thickness[index]; - } else if (highlightArmor.name.startsWith('gun_')) { - if (highlightArmor.name.includes('_armor_')) { + } else if (highlightArmor.name.startsWith("gun_")) { + if (highlightArmor.name.includes("_armor_")) { gun.armor.thickness[index] = initialGun.armor.thickness[index]; } else { gun.thickness = initialGun.thickness; } - } else if (highlightArmor.name.startsWith('chassis_')) { + } else if (highlightArmor.name.startsWith("chassis_")) { track.thickness = initialTrack.thickness; } }); diff --git a/packages/website/src/components/Armor/components/PrimaryArmorSceneComponent/index.tsx b/packages/website/src/components/Armor/components/PrimaryArmorSceneComponent/index.tsx index 60e5e3932..6b59e27e9 100644 --- a/packages/website/src/components/Armor/components/PrimaryArmorSceneComponent/index.tsx +++ b/packages/website/src/components/Armor/components/PrimaryArmorSceneComponent/index.tsx @@ -2,9 +2,9 @@ import { canSplash, isExplosive, resolvePenetrationCoefficient, -} from '@blitzkit/core'; -import { invalidate, useFrame } from '@react-three/fiber'; -import { useEffect } from 'react'; +} from "@blitzkit/core"; +import { invalidate, useFrame } from "@react-three/fiber"; +import { useEffect } from "react"; import { MeshBasicMaterial, NormalBlending, @@ -14,16 +14,16 @@ import { UniformsLib, UniformsUtils, Vector2, -} from 'three'; -import { degToRad } from 'three/src/math/MathUtils.js'; -import { hasEquipment } from '../../../../core/blitzkit/hasEquipment'; -import { jsxTree } from '../../../../core/blitzkit/jsxTree'; -import { Duel, type EquipmentMatrix } from '../../../../stores/duel'; -import { TankopediaEphemeral } from '../../../../stores/tankopediaEphemeral'; -import { TankopediaPersistent } from '../../../../stores/tankopediaPersistent'; -import fragmentShader from './shaders/fragment.glsl?raw'; -import vertexShader from './shaders/vertex.glsl?raw'; -import { spacedArmorRenderTarget } from './target'; +} from "three"; +import { degToRad } from "three/src/math/MathUtils.js"; +import { hasEquipment } from "../../../../core/blitzkit/hasEquipment"; +import { jsxTree } from "../../../../core/blitzkit/jsxTree"; +import { Duel, type EquipmentMatrix } from "../../../../stores/duel"; +import { Tankopedia } from "../../../../stores/tankopedia"; +import { TankopediaPersistent } from "../../../../stores/tankopediaPersistent"; +import fragmentShader from "./shaders/fragment.glsl?raw"; +import vertexShader from "./shaders/vertex.glsl?raw"; +import { spacedArmorRenderTarget } from "./target"; interface PrimaryArmorSceneComponentProps { thickness: number; @@ -81,15 +81,15 @@ export function PrimaryArmorSceneComponent({ useEffect(() => { function handleShellChange() { const duel = duelStore.getState(); - const tankopediaEphemeral = TankopediaEphemeral.state; + const tankopediaEphemeral = Tankopedia.state; const shell = tankopediaEphemeral.customShell ?? duel.antagonist.shell; material.uniforms.caliber.value = shell.caliber; material.uniforms.ricochet.value = degToRad( - isExplosive(shell.type) ? 90 : shell.ricochet!, + isExplosive(shell.type) ? 90 : shell.ricochet! ); material.uniforms.normalization.value = degToRad( - shell.normalization ?? 0, + shell.normalization ?? 0 ); material.uniforms.isExplosive.value = isExplosive(shell.type); material.uniforms.canSplash.value = canSplash(shell.type); @@ -116,13 +116,13 @@ export function PrimaryArmorSceneComponent({ } function handleProtagonistEquipmentChange( equipment: EquipmentMatrix, - noInvalidate = false, + noInvalidate = false ) { const duel = duelStore.getState(); const hasEnhancedArmor = hasEquipment( 110, duel.protagonist.tank.equipment_preset, - equipment, + equipment ); material.uniforms.thickness.value = hasEnhancedArmor ? thickness * 1.03 @@ -132,16 +132,16 @@ export function PrimaryArmorSceneComponent({ } function handleAntagonistEquipmentChange( equipment: EquipmentMatrix, - noInvalidate = false, + noInvalidate = false ) { const duel = duelStore.getState(); - const tankopediaEphemeral = TankopediaEphemeral.state; + const tankopediaEphemeral = Tankopedia.state; const shell = tankopediaEphemeral.customShell ?? duel.antagonist.shell; const penetration = shell.penetration.near; const hasCalibratedShells = hasEquipment( 103, duel.antagonist.tank.equipment_preset, - equipment, + equipment ); material.uniforms.penetration.value = @@ -159,34 +159,34 @@ export function PrimaryArmorSceneComponent({ handleOpaqueChange(initialState.opaque); handleWireframeChange(initialState.wireframe); handleProtagonistEquipmentChange( - duelStore.getState().protagonist.equipmentMatrix, + duelStore.getState().protagonist.equipmentMatrix ); handleAntagonistEquipmentChange( - duelStore.getState().antagonist.equipmentMatrix, + duelStore.getState().antagonist.equipmentMatrix ); const unsubscribes = [ duelStore.subscribe((state) => state.antagonist.shell, handleShellChange), - TankopediaEphemeral.on((state) => state.customShell, handleShellChange), + Tankopedia.on((state) => state.customShell, handleShellChange), tankopediaPersistentStore.subscribe( (state) => state.greenPenetration, - handleGreenPenetrationChange, + handleGreenPenetrationChange ), tankopediaPersistentStore.subscribe( (state) => state.advancedHighlighting, - handleAdvancedHighlightingChange, + handleAdvancedHighlightingChange ), tankopediaPersistentStore.subscribe( (state) => state.opaque, - handleOpaqueChange, + handleOpaqueChange ), duelStore.subscribe( (state) => state.protagonist.equipmentMatrix, - (equipment) => handleProtagonistEquipmentChange(equipment), + (equipment) => handleProtagonistEquipmentChange(equipment) ), duelStore.subscribe( (state) => state.antagonist.equipmentMatrix, - (equipment) => handleAntagonistEquipmentChange(equipment), + (equipment) => handleAntagonistEquipmentChange(equipment) ), ]; @@ -197,7 +197,7 @@ export function PrimaryArmorSceneComponent({ useFrame(({ gl, camera }) => { gl.getSize(material.uniforms.resolution.value).multiplyScalar( - gl.getPixelRatio(), + gl.getPixelRatio() ); material.uniforms.spacedArmorBuffer.value = spacedArmorRenderTarget.texture; material.uniforms.spacedArmorDepth.value = diff --git a/packages/website/src/components/Armor/components/ShotDisplay.tsx b/packages/website/src/components/Armor/components/ShotDisplay.tsx index 055f6e4fc..2832d2b6d 100644 --- a/packages/website/src/components/Armor/components/ShotDisplay.tsx +++ b/packages/website/src/components/Armor/components/ShotDisplay.tsx @@ -1,9 +1,9 @@ -import { J_HAT, K_HAT } from '@blitzkit/core'; -import { Box, Flex, Text } from '@radix-ui/themes'; -import { Html } from '@react-three/drei'; -import { invalidate, useFrame } from '@react-three/fiber'; -import { clamp } from 'lodash-es'; -import { useEffect, useRef, type ComponentProps } from 'react'; +import { J_HAT, K_HAT } from "@blitzkit/core"; +import { Box, Flex, Text } from "@radix-ui/themes"; +import { Html } from "@react-three/drei"; +import { invalidate, useFrame } from "@react-three/fiber"; +import { clamp } from "lodash-es"; +import { useEffect, useRef, type ComponentProps } from "react"; import { BufferGeometry, DoubleSide, @@ -15,24 +15,24 @@ import { MeshBasicMaterial, Path, Quaternion, -} from 'three'; -import { isHalloween } from '../../../core/blitzkit/isHalloween'; -import { LocaleProvider, useLocale } from '../../../hooks/useLocale'; +} from "three"; +import { isHalloween } from "../../../core/blitzkit/isHalloween"; +import { LocaleProvider, useLocale } from "../../../hooks/useLocale"; import { - TankopediaEphemeral, + Tankopedia, type ShotLayerNonExternal, type ShotStatus, -} from '../../../stores/tankopediaEphemeral'; -import { ShotDisplayCard } from './ShotDisplayCard'; +} from "../../../stores/tankopedia"; +import { ShotDisplayCard } from "./ShotDisplayCard"; export const shotStatusColors: Record< ShotStatus, - ComponentProps['color'] + ComponentProps["color"] > = { - blocked: 'red', - penetration: 'green', - ricochet: 'yellow', - splash: 'orange', + blocked: "red", + penetration: "green", + ricochet: "yellow", + splash: "orange", }; const SURFACE_POINT_SIZE = 12; @@ -41,7 +41,7 @@ const TRACER_THICK = 1 / 32; const TRACER_THIN = TRACER_THICK / 2; export function ShotDisplay() { - const shot = TankopediaEphemeral.use((state) => state.shot); + const shot = Tankopedia.use((state) => state.shot); const inTracer = useRef(null); const outTracer = useRef(null); const splashRadiusWrapper = useRef(null); @@ -52,16 +52,16 @@ export function ShotDisplay() { useEffect(() => { if (shot?.splashRadius !== undefined) { const outlineGeometry = new BufferGeometry().setFromPoints( - new Path().absarc(0, 0, 1, 0, Math.PI * 2).getSpacedPoints(50), + new Path().absarc(0, 0, 1, 0, Math.PI * 2).getSpacedPoints(50) ); const outlineMaterial = new LineDashedMaterial({ - color: 'orange', + color: "orange", dashSize: 0.05, gapSize: 0.025, }); const outline = new Line( outlineGeometry, - outlineMaterial, + outlineMaterial ).computeLineDistances(); splashRadiusWrapper.current?.add(outline); @@ -76,9 +76,9 @@ export function ShotDisplay() { if ( isHalloween() && shot?.splashRadius !== undefined && - shot.in.status === 'penetration' + shot.in.status === "penetration" ) { - const audio = new Audio('/assets/audio/lotta-damage.mp3'); + const audio = new Audio("/assets/audio/lotta-damage.mp3"); audio.currentTime = 0.7; audio.volume = 0.25; @@ -134,11 +134,11 @@ export function ShotDisplay() { const outLength = shot.out && shot.out.layers.length > 0 ? (shot.in.layers.at(-1) as ShotLayerNonExternal).point.distanceTo( - (shot.out.layers.at(-1) as ShotLayerNonExternal).point, + (shot.out.layers.at(-1) as ShotLayerNonExternal).point ) : SHOT_DISPLAY_LENGTH_INFINITY; const inLast = shot.in.layers.findLast( - (layer) => layer.type !== null, + (layer) => layer.type !== null ) as ShotLayerNonExternal; const outTitleColor = shot.out ? shotStatusColors[shot.out.status] @@ -154,7 +154,7 @@ export function ShotDisplay() { position={inLast.point} ref={splashRadiusWrapper} rotation={new Euler().setFromQuaternion( - new Quaternion().setFromUnitVectors(K_HAT, shot.in.surfaceNormal), + new Quaternion().setFromUnitVectors(K_HAT, shot.in.surfaceNormal) )} > @@ -172,13 +172,13 @@ export function ShotDisplay() { @@ -190,7 +190,7 @@ export function ShotDisplay() { if (layer.type === null) return null; const shotStatusColor = - shot.in.status === 'splash' + shot.in.status === "splash" ? shotStatusColors.splash : shotStatusColors[layer.status]; @@ -199,8 +199,8 @@ export function ShotDisplay() { position={layer.point} key={index} style={{ - pointerEvents: 'none', - transform: 'translateY(-50%)', + pointerEvents: "none", + transform: "translateY(-50%)", }} > @@ -253,8 +253,8 @@ export function ShotDisplay() { rotation={new Euler().setFromQuaternion( new Quaternion().setFromUnitVectors( J_HAT, - shot.out.surfaceNormal.clone(), - ), + shot.out.surfaceNormal.clone() + ) )} > diff --git a/packages/website/src/components/Armor/components/ShotDisplayCard.tsx b/packages/website/src/components/Armor/components/ShotDisplayCard.tsx index 48eb0952e..c90e36a0c 100644 --- a/packages/website/src/components/Armor/components/ShotDisplayCard.tsx +++ b/packages/website/src/components/Armor/components/ShotDisplayCard.tsx @@ -1,4 +1,4 @@ -import { literals } from '@blitzkit/i18n/src/literals'; +import { literals } from "@blitzkit/i18n/src/literals"; import { Card, Flex, @@ -6,19 +6,19 @@ import { Separator, Text, type CardProps, -} from '@radix-ui/themes'; -import type { ComponentProps } from 'react'; -import { radToDeg } from 'three/src/math/MathUtils.js'; -import { useLocale } from '../../../hooks/useLocale'; -import type { Shot, ShotLayer } from '../../../stores/tankopediaEphemeral'; -import { shotStatusColors } from './ShotDisplay'; -import { ArmorType } from './SpacedArmorScene'; +} from "@radix-ui/themes"; +import type { ComponentProps } from "react"; +import { radToDeg } from "three/src/math/MathUtils.js"; +import { useLocale } from "../../../hooks/useLocale"; +import type { Shot, ShotLayer } from "../../../stores/tankopedia"; +import { shotStatusColors } from "./ShotDisplay"; +import { ArmorType } from "./SpacedArmorScene"; export const layerTypeNames = { - [ArmorType.Primary]: 'primary', - [ArmorType.Spaced]: 'spaced', - [ArmorType.External]: 'external', - null: 'gap', + [ArmorType.Primary]: "primary", + [ArmorType.Spaced]: "spaced", + [ArmorType.External]: "external", + null: "gap", } as const; function LayerEntry({ @@ -29,7 +29,7 @@ function LayerEntry({ angle, }: { layerIndex?: string; - shotStatusColor: ComponentProps['color']; + shotStatusColor: ComponentProps["color"]; layerName: string; layer: ShotLayer; angle?: number; @@ -77,7 +77,7 @@ function LayerEntry({ [ Math.round(layer.thicknessAngled).toLocaleString(locale), radToDeg(angle ?? 0).toFixed(0), - ], + ] )} )} @@ -89,7 +89,7 @@ function LayerEntry({ {literals( strings.website.tools.tankopedia.sandbox.dynamic.shot_card.stats .ricochet_loss, - [Math.max(-100, -50 * layer.distance).toFixed(0)], + [Math.max(-100, -50 * layer.distance).toFixed(0)] )} )} @@ -100,7 +100,7 @@ function LayerEntry({ {literals( strings.website.tools.tankopedia.sandbox.dynamic.shot_card.stats .nominal, - [Math.round(layer.thickness).toLocaleString(locale)], + [Math.round(layer.thickness).toLocaleString(locale)] )} )} @@ -132,14 +132,14 @@ export function ShotDisplayCard({ shot, ...props }: ShotDisplayCardProps) { strings.website.tools.tankopedia.sandbox.dynamic.shot_card.status[ shot.in.status ], - [Math.round(shot.damage).toLocaleString(locale)], + [Math.round(shot.damage).toLocaleString(locale)] )} {shot.in.layers.map((layer, index) => { @@ -155,7 +155,7 @@ export function ShotDisplayCard({ shot, ...props }: ShotDisplayCardProps) { ? undefined : `${(shot.containsGaps ? index / 2 : index) + 1}.`; const shotStatusColor = - shot.in.status === 'splash' + shot.in.status === "splash" ? shotStatusColors.splash : shotStatusColors[layer.status]; @@ -202,7 +202,7 @@ export function ShotDisplayCard({ shot, ...props }: ShotDisplayCardProps) { {literals( strings.website.tools.tankopedia.sandbox.dynamic.shot_card .status[shot.out.status], - [Math.round(shot.damage).toLocaleString(locale)], + [Math.round(shot.damage).toLocaleString(locale)] )} @@ -224,7 +224,7 @@ export function ShotDisplayCard({ shot, ...props }: ShotDisplayCardProps) { 1 }.`; const shotStatusColor = - shot.out!.status === 'splash' + shot.out!.status === "splash" ? shotStatusColors.splash : shotStatusColors[layer.status]; diff --git a/packages/website/src/components/Armor/components/SpacedArmorSceneComponent/components/SpacedArmorSubExternal/index.tsx b/packages/website/src/components/Armor/components/SpacedArmorSceneComponent/components/SpacedArmorSubExternal/index.tsx index 25ca146ca..8d26029a6 100644 --- a/packages/website/src/components/Armor/components/SpacedArmorSceneComponent/components/SpacedArmorSubExternal/index.tsx +++ b/packages/website/src/components/Armor/components/SpacedArmorSceneComponent/components/SpacedArmorSubExternal/index.tsx @@ -1,20 +1,20 @@ -import { resolvePenetrationCoefficient } from '@blitzkit/core'; -import { useEffect } from 'react'; +import { resolvePenetrationCoefficient } from "@blitzkit/core"; +import { useEffect } from "react"; import { AdditiveBlending, MeshBasicMaterial, Object3D, Plane, ShaderMaterial, -} from 'three'; -import type { ArmorUserData, ExternalModuleVariant } from '../..'; -import { hasEquipment } from '../../../../../../core/blitzkit/hasEquipment'; -import { jsxTree } from '../../../../../../core/blitzkit/jsxTree'; -import { Duel, type EquipmentMatrix } from '../../../../../../stores/duel'; -import { TankopediaEphemeral } from '../../../../../../stores/tankopediaEphemeral'; -import { ArmorType } from '../../../SpacedArmorScene'; -import fragmentShader from './shaders/fragment.glsl?raw'; -import vertexShader from './shaders/vertex.glsl?raw'; +} from "three"; +import type { ArmorUserData, ExternalModuleVariant } from "../.."; +import { hasEquipment } from "../../../../../../core/blitzkit/hasEquipment"; +import { jsxTree } from "../../../../../../core/blitzkit/jsxTree"; +import { Duel, type EquipmentMatrix } from "../../../../../../stores/duel"; +import { Tankopedia } from "../../../../../../stores/tankopedia"; +import { ArmorType } from "../../../SpacedArmorScene"; +import fragmentShader from "./shaders/fragment.glsl?raw"; +import vertexShader from "./shaders/vertex.glsl?raw"; interface SpacedArmorSubExternalProps { node: Object3D; @@ -49,7 +49,7 @@ export function SpacedArmorSubExternal({ useEffect(() => { function handleShellChange() { const duel = duelStore.getState(); - const tankopediaEphemeral = TankopediaEphemeral.state; + const tankopediaEphemeral = Tankopedia.state; const shell = tankopediaEphemeral.customShell ?? duel.antagonist.shell; material.uniforms.penetration.value = shell.penetration.near; } @@ -58,7 +58,7 @@ export function SpacedArmorSubExternal({ const hasEnhancedArmor = hasEquipment( 110, duel.protagonist.tank.equipment_preset, - equipment, + equipment ); material.uniforms.thickness.value = hasEnhancedArmor ? thickness * 1.03 @@ -66,13 +66,13 @@ export function SpacedArmorSubExternal({ } function handleAntagonistEquipmentChange(equipment: EquipmentMatrix) { const duel = duelStore.getState(); - const tankopediaEphemeral = TankopediaEphemeral.state; + const tankopediaEphemeral = Tankopedia.state; const shell = tankopediaEphemeral.customShell ?? duel.antagonist.shell; const penetration = shell.penetration.near; const hasCalibratedShells = hasEquipment( 103, duel.antagonist.tank.equipment_preset, - equipment, + equipment ); material.uniforms.penetration.value = @@ -82,22 +82,22 @@ export function SpacedArmorSubExternal({ handleShellChange(); handleProtagonistEquipmentChange( - duelStore.getState().protagonist.equipmentMatrix, + duelStore.getState().protagonist.equipmentMatrix ); handleAntagonistEquipmentChange( - duelStore.getState().antagonist.equipmentMatrix, + duelStore.getState().antagonist.equipmentMatrix ); const unsubscribes = [ duelStore.subscribe((state) => state.antagonist.shell, handleShellChange), - TankopediaEphemeral.on((state) => state.customShell, handleShellChange), + Tankopedia.on((state) => state.customShell, handleShellChange), duelStore.subscribe( (state) => state.protagonist.equipmentMatrix, - handleProtagonistEquipmentChange, + handleProtagonistEquipmentChange ), duelStore.subscribe( (state) => state.antagonist.equipmentMatrix, - handleAntagonistEquipmentChange, + handleAntagonistEquipmentChange ), ]; diff --git a/packages/website/src/components/Armor/components/SpacedArmorSceneComponent/components/SpacedArmorSubSpaced/index.tsx b/packages/website/src/components/Armor/components/SpacedArmorSceneComponent/components/SpacedArmorSubSpaced/index.tsx index 3a94ac18e..b01b59aab 100644 --- a/packages/website/src/components/Armor/components/SpacedArmorSceneComponent/components/SpacedArmorSubSpaced/index.tsx +++ b/packages/website/src/components/Armor/components/SpacedArmorSceneComponent/components/SpacedArmorSubSpaced/index.tsx @@ -1,20 +1,20 @@ -import { isExplosive, resolvePenetrationCoefficient } from '@blitzkit/core'; -import { useEffect } from 'react'; +import { isExplosive, resolvePenetrationCoefficient } from "@blitzkit/core"; +import { useEffect } from "react"; import { AdditiveBlending, MeshBasicMaterial, ShaderMaterial, type Object3D, -} from 'three'; -import { degToRad } from 'three/src/math/MathUtils.js'; -import type { ArmorUserData } from '../..'; -import { hasEquipment } from '../../../../../../core/blitzkit/hasEquipment'; -import { jsxTree } from '../../../../../../core/blitzkit/jsxTree'; -import { Duel, type EquipmentMatrix } from '../../../../../../stores/duel'; -import { TankopediaEphemeral } from '../../../../../../stores/tankopediaEphemeral'; -import { ArmorType } from '../../../SpacedArmorScene'; -import fragmentShader from './shaders/fragment.glsl?raw'; -import vertexShader from './shaders/vertex.glsl?raw'; +} from "three"; +import { degToRad } from "three/src/math/MathUtils.js"; +import type { ArmorUserData } from "../.."; +import { hasEquipment } from "../../../../../../core/blitzkit/hasEquipment"; +import { jsxTree } from "../../../../../../core/blitzkit/jsxTree"; +import { Duel, type EquipmentMatrix } from "../../../../../../stores/duel"; +import { Tankopedia } from "../../../../../../stores/tankopedia"; +import { ArmorType } from "../../../SpacedArmorScene"; +import fragmentShader from "./shaders/fragment.glsl?raw"; +import vertexShader from "./shaders/vertex.glsl?raw"; interface SpacedArmorSubSpacedProps { node: Object3D; @@ -51,16 +51,16 @@ export function SpacedArmorSubSpaced({ useEffect(() => { function handleShellChange() { const duel = duelStore.getState(); - const tankopediaEphemeral = TankopediaEphemeral.state; + const tankopediaEphemeral = Tankopedia.state; const shell = tankopediaEphemeral.customShell ?? duel.antagonist.shell; material.uniforms.penetration.value = shell.penetration.near; material.uniforms.caliber.value = shell.caliber; material.uniforms.ricochet.value = degToRad( - isExplosive(shell.type) ? 90 : shell.ricochet!, + isExplosive(shell.type) ? 90 : shell.ricochet! ); material.uniforms.normalization.value = degToRad( - shell.normalization ?? 0, + shell.normalization ?? 0 ); } function handleProtagonistEquipmentChange(equipment: EquipmentMatrix) { @@ -68,7 +68,7 @@ export function SpacedArmorSubSpaced({ const hasEnhancedArmor = hasEquipment( 110, duel.protagonist.tank.equipment_preset, - equipment, + equipment ); material.uniforms.thickness.value = hasEnhancedArmor ? thickness * 1.03 @@ -76,13 +76,13 @@ export function SpacedArmorSubSpaced({ } function handleAntagonistEquipmentChange(equipment: EquipmentMatrix) { const duel = duelStore.getState(); - const tankopediaEphemeral = TankopediaEphemeral.state; + const tankopediaEphemeral = Tankopedia.state; const shell = tankopediaEphemeral.customShell ?? duel.antagonist.shell; const penetration = shell.penetration.near; const hasCalibratedShells = hasEquipment( 103, duel.antagonist.tank.equipment_preset, - equipment, + equipment ); material.uniforms.penetration.value = @@ -92,22 +92,22 @@ export function SpacedArmorSubSpaced({ handleShellChange(); handleProtagonistEquipmentChange( - duelStore.getState().protagonist.equipmentMatrix, + duelStore.getState().protagonist.equipmentMatrix ); handleAntagonistEquipmentChange( - duelStore.getState().antagonist.equipmentMatrix, + duelStore.getState().antagonist.equipmentMatrix ); const unsubscribes = [ duelStore.subscribe((state) => state.antagonist.shell, handleShellChange), - TankopediaEphemeral.on((state) => state.customShell, handleShellChange), + Tankopedia.on((state) => state.customShell, handleShellChange), duelStore.subscribe( (state) => state.protagonist.equipmentMatrix, - handleProtagonistEquipmentChange, + handleProtagonistEquipmentChange ), duelStore.subscribe( (state) => state.antagonist.equipmentMatrix, - handleAntagonistEquipmentChange, + handleAntagonistEquipmentChange ), ]; diff --git a/packages/website/src/components/Armor/components/SpacedArmorSceneComponent/index.tsx b/packages/website/src/components/Armor/components/SpacedArmorSceneComponent/index.tsx index 94f6a5e5f..e5000774d 100644 --- a/packages/website/src/components/Armor/components/SpacedArmorSceneComponent/index.tsx +++ b/packages/website/src/components/Armor/components/SpacedArmorSceneComponent/index.tsx @@ -2,9 +2,9 @@ import { ShellType, isExplosive, resolvePenetrationCoefficient, -} from '@blitzkit/core'; -import { useThree } from '@react-three/fiber'; -import { useCallback } from 'react'; +} from "@blitzkit/core"; +import { useThree } from "@react-three/fiber"; +import { useCallback } from "react"; import { type Intersection, MeshBasicMaterial, @@ -14,21 +14,21 @@ import { Raycaster, Scene, Vector3, -} from 'three'; -import { degToRad } from 'three/src/math/MathUtils.js'; -import { hasEquipment } from '../../../../core/blitzkit/hasEquipment'; -import { jsxTree } from '../../../../core/blitzkit/jsxTree'; -import { discardClippingPlane } from '../../../../core/three/discardClippingPlane'; -import { Duel } from '../../../../stores/duel'; +} from "three"; +import { degToRad } from "three/src/math/MathUtils.js"; +import { hasEquipment } from "../../../../core/blitzkit/hasEquipment"; +import { jsxTree } from "../../../../core/blitzkit/jsxTree"; +import { discardClippingPlane } from "../../../../core/three/discardClippingPlane"; +import { Duel } from "../../../../stores/duel"; import { type Shot, type ShotLayerBase, type ShotLayerNonExternal, - TankopediaEphemeral, -} from '../../../../stores/tankopediaEphemeral'; -import { ArmorType } from '../SpacedArmorScene'; -import { SpacedArmorSubExternal } from './components/SpacedArmorSubExternal'; -import { SpacedArmorSubSpaced } from './components/SpacedArmorSubSpaced'; + Tankopedia, +} from "../../../../stores/tankopedia"; +import { ArmorType } from "../SpacedArmorScene"; +import { SpacedArmorSubExternal } from "./components/SpacedArmorSubExternal"; +import { SpacedArmorSubSpaced } from "./components/SpacedArmorSubSpaced"; type SpacedArmorSceneComponentProps = { node: Object3D; @@ -45,7 +45,7 @@ type SpacedArmorSceneComponentProps = { } ); -export type ExternalModuleVariant = 'gun' | 'track'; +export type ExternalModuleVariant = "gun" | "track"; export type ArmorUserData = { thickness: number; } & ( @@ -84,10 +84,10 @@ export function SpacedArmorSceneComponent({ point: Vector3, intersections: Intersection[], allowRicochet: boolean, - remainingPenetrationInput?: number, + remainingPenetrationInput?: number ) => { const { antagonist, protagonist } = duelStore.getState(); - const { customShell } = TankopediaEphemeral.state; + const { customShell } = Tankopedia.state; const shell = customShell ?? antagonist.shell; const cameraNormal = camera.position.clone().sub(point).normalize(); const shot: Shot = { @@ -98,19 +98,19 @@ export function SpacedArmorSceneComponent({ in: { surfaceNormal: cameraNormal, layers: [], - status: 'blocked', + status: "blocked", }, }; const hasCalibratedShells = hasEquipment( 103, antagonist.tank.equipment_preset, - antagonist.equipmentMatrix, + antagonist.equipmentMatrix ); const hasEnhancedArmor = hasEquipment( 110, protagonist.tank.equipment_preset, - protagonist.equipmentMatrix, + protagonist.equipmentMatrix ); const penetration = shell.penetration.near * @@ -118,8 +118,8 @@ export function SpacedArmorSceneComponent({ const thicknessCoefficient = hasEnhancedArmor ? 1.03 : 1; const filteredIntersections = intersections.filter( (intersection) => - 'type' in intersection.object.userData && - !discardClippingPlane(intersection.object, intersection.point), + "type" in intersection.object.userData && + !discardClippingPlane(intersection.object, intersection.point) ) as unknown as Intersection[]; const encounteredExternalModuleVariants: ExternalModuleVariant[] = []; const noDuplicateIntersections: typeof filteredIntersections = []; @@ -128,12 +128,12 @@ export function SpacedArmorSceneComponent({ if (intersection.object.userData.type === ArmorType.External) { if ( !encounteredExternalModuleVariants.includes( - intersection.object.userData.variant, + intersection.object.userData.variant ) ) { noDuplicateIntersections.push(intersection); encounteredExternalModuleVariants.push( - intersection.object.userData.variant, + intersection.object.userData.variant ); } } else { @@ -161,7 +161,7 @@ export function SpacedArmorSceneComponent({ const surfaceNormal = intersection .normal!.clone() .applyQuaternion( - intersection.object.getWorldQuaternion(new Quaternion()), + intersection.object.getWorldQuaternion(new Quaternion()) ); if (shell.type === ShellType.HEAT && index > 0) { @@ -173,7 +173,7 @@ export function SpacedArmorSceneComponent({ shot.in.layers.push({ type: null, distance, - status: blocked ? 'blocked' : 'penetration', + status: blocked ? "blocked" : "penetration", }); if (blocked) break; @@ -193,16 +193,16 @@ export function SpacedArmorSceneComponent({ surfaceNormal, status: shell.type === ShellType.HE - ? 'blocked' + ? "blocked" : blocked - ? 'blocked' - : 'penetration', + ? "blocked" + : "penetration", variant: layer.variant, }); } else { const thickness = layer.thickness * thicknessCoefficient; const ricochet = degToRad( - isExplosive(shell.type) ? 90 : shell.ricochet!, + isExplosive(shell.type) ? 90 : shell.ricochet! ); const angle = surfaceNormal.angleTo(cameraNormal); @@ -226,7 +226,7 @@ export function SpacedArmorSceneComponent({ thicknessAngled: finalThickness, point: intersection.point, surfaceNormal, - status: 'ricochet', + status: "ricochet", angle, }); @@ -244,10 +244,10 @@ export function SpacedArmorSceneComponent({ surfaceNormal: intersection.face!.normal, status: shell.type === ShellType.HE && layer.type !== ArmorType.Primary - ? 'blocked' + ? "blocked" : blocked - ? 'blocked' - : 'penetration', + ? "blocked" + : "penetration", angle, }); } @@ -281,10 +281,10 @@ export function SpacedArmorSceneComponent({ return acc + layer.thicknessAngled; }, - 0, + 0 ); const distanceFromSpacedArmor = firstLayer.point.distanceTo( - lastLayer.point, + lastLayer.point ); const finalDamage = Math.max( 0, @@ -293,7 +293,7 @@ export function SpacedArmorSceneComponent({ (1 - distanceFromSpacedArmor / shell.explosion_radius!) - 1.1 * (lastLayer.thicknessAngled + - Math.min(penetration, totalSpacedArmorThickness)), + Math.min(penetration, totalSpacedArmorThickness)) ); /** @@ -307,19 +307,19 @@ export function SpacedArmorSceneComponent({ * for parity's sake, I am capping the value here. */ - if (shot.in.layers.length > 1 || lastLayer.status === 'blocked') { - shot.in.status = finalDamage > 0 ? 'splash' : 'blocked'; + if (shot.in.layers.length > 1 || lastLayer.status === "blocked") { + shot.in.status = finalDamage > 0 ? "splash" : "blocked"; shot.damage = finalDamage; } else { - shot.in.status = 'penetration'; + shot.in.status = "penetration"; shot.damage = shell.armor_damage; } } else { - if (lastLayer.status === 'blocked') { - shot.in.status = 'blocked'; + if (lastLayer.status === "blocked") { + shot.in.status = "blocked"; shot.damage = 0; - } else if (lastLayer.status === 'penetration') { - shot.in.status = 'penetration'; + } else if (lastLayer.status === "penetration") { + shot.in.status = "penetration"; shot.damage = shell.armor_damage; } else { const caster = new Raycaster(); @@ -330,29 +330,29 @@ export function SpacedArmorSceneComponent({ .sub( lastLayer.surfaceNormal .clone() - .multiplyScalar(2 * shellNormal.dot(lastLayer.surfaceNormal)), + .multiplyScalar(2 * shellNormal.dot(lastLayer.surfaceNormal)) ); caster.set(lastLayer.point, ricochetNormal); const ricochetIntersections = caster.intersectObjects( props.scene.children, - true, + true ); const outShot = shoot( lastLayer.point, ricochetIntersections, false, - remainingPenetration, + remainingPenetration ); - shot.in.status = 'ricochet'; + shot.in.status = "ricochet"; if (outShot === null) { shot.damage = 0; shot.out = { surfaceNormal: ricochetNormal, layers: [], - status: 'ricochet', + status: "ricochet", }; } else { shot.damage = outShot.damage; @@ -365,7 +365,7 @@ export function SpacedArmorSceneComponent({ return shot; }, - [camera], + [camera] ); return ( @@ -390,7 +390,7 @@ export function SpacedArmorSceneComponent({ const shot = shoot(event.point, event.intersections, true)!; - TankopediaEphemeral.mutate((draft) => { + Tankopedia.mutate((draft) => { draft.shot = shot; }); }} diff --git a/packages/website/src/components/Armor/components/StaticArmor.tsx b/packages/website/src/components/Armor/components/StaticArmor.tsx index 3f66093bf..cbe3ec134 100644 --- a/packages/website/src/components/Armor/components/StaticArmor.tsx +++ b/packages/website/src/components/Armor/components/StaticArmor.tsx @@ -1,22 +1,22 @@ -import { useThree, type ThreeEvent } from '@react-three/fiber'; -import { memo, useRef } from 'react'; -import { Group, Plane, Vector2, Vector3 } from 'three'; -import { applyPitchYawLimits } from '../../../core/blitz/applyPitchYawLimits'; -import { correctZYTuple } from '../../../core/blitz/correctZYTuple'; -import { hasEquipment } from '../../../core/blitzkit/hasEquipment'; -import { modelTransformEvent } from '../../../core/blitzkit/modelTransform'; -import { nameToArmorId } from '../../../core/blitzkit/nameToArmorId'; -import { resolveArmor } from '../../../core/blitzkit/resolveThickness'; -import { useArmor } from '../../../hooks/useArmor'; -import { useModel } from '../../../hooks/useModel'; -import { useTankModelDefinition } from '../../../hooks/useTankModelDefinition'; -import { useTankTransform } from '../../../hooks/useTankTransform'; -import { Duel } from '../../../stores/duel'; -import { TankopediaEphemeral } from '../../../stores/tankopediaEphemeral'; -import { TankopediaPersistent } from '../../../stores/tankopediaPersistent'; -import { ModelTankWrapper } from './ModelTankWrapper'; -import { ArmorType } from './SpacedArmorScene'; -import { StaticArmorSceneComponent } from './StaticArmorSceneComponent'; +import { useThree, type ThreeEvent } from "@react-three/fiber"; +import { memo, useRef } from "react"; +import { Group, Plane, Vector2, Vector3 } from "three"; +import { applyPitchYawLimits } from "../../../core/blitz/applyPitchYawLimits"; +import { correctZYTuple } from "../../../core/blitz/correctZYTuple"; +import { hasEquipment } from "../../../core/blitzkit/hasEquipment"; +import { modelTransformEvent } from "../../../core/blitzkit/modelTransform"; +import { nameToArmorId } from "../../../core/blitzkit/nameToArmorId"; +import { resolveArmor } from "../../../core/blitzkit/resolveThickness"; +import { useArmor } from "../../../hooks/useArmor"; +import { useModel } from "../../../hooks/useModel"; +import { useTankModelDefinition } from "../../../hooks/useTankModelDefinition"; +import { useTankTransform } from "../../../hooks/useTankTransform"; +import { Duel } from "../../../stores/duel"; +import { Tankopedia } from "../../../stores/tankopedia"; +import { TankopediaPersistent } from "../../../stores/tankopediaPersistent"; +import { ModelTankWrapper } from "./ModelTankWrapper"; +import { ArmorType } from "./SpacedArmorScene"; +import { StaticArmorSceneComponent } from "./StaticArmorSceneComponent"; interface ArmorSceneProps { thicknessRange: ThicknessRange; @@ -52,16 +52,16 @@ export const StaticArmor = memo(({ thicknessRange }) => { ? undefined : gunModelDefinition.mask + hullOrigin.y + turretOrigin.y + gunOrigin.y; const showPrimaryArmor = TankopediaPersistent.use( - (state) => state.showPrimaryArmor, + (state) => state.showPrimaryArmor ); const showSpacedArmor = TankopediaPersistent.use( - (state) => state.showSpacedArmor, + (state) => state.showSpacedArmor ); const showExternalModules = TankopediaPersistent.use( - (state) => state.showExternalModules, + (state) => state.showExternalModules ); const isDynamicArmorActive = Duel.use((state) => - state.protagonist.consumables.includes(73), + state.protagonist.consumables.includes(73) ); useTankTransform(track, turret, turretContainer, gunContainer); @@ -70,12 +70,12 @@ export const StaticArmor = memo(({ thicknessRange }) => { {armorNodes.map((node) => { - const isHull = node.name.startsWith('hull_'); + const isHull = node.name.startsWith("hull_"); const isVisible = isHull; const armorId = nameToArmorId(node.name); const { spaced, thickness } = resolveArmor( tankModelDefinition.armor, - armorId, + armorId ); if ( @@ -83,8 +83,8 @@ export const StaticArmor = memo(({ thicknessRange }) => { thickness === undefined || (!showPrimaryArmor && !spaced) || (!showSpacedArmor && spaced) || - (isDynamicArmorActive && node.name.includes('state_00')) || - (!isDynamicArmorActive && node.name.includes('state_01')) + (isDynamicArmorActive && node.name.includes("state_00")) || + (!isDynamicArmorActive && node.name.includes("state_01")) ) return null; @@ -103,8 +103,8 @@ export const StaticArmor = memo(({ thicknessRange }) => { {modelNodes.map((node) => { - const isWheel = node.name.startsWith('chassis_wheel_'); - const isTrack = node.name.startsWith('chassis_track_'); + const isWheel = node.name.startsWith("chassis_wheel_"); + const isTrack = node.name.startsWith("chassis_track_"); const isVisible = isWheel || isTrack; if (!isVisible || !showExternalModules) return null; @@ -126,13 +126,13 @@ export const StaticArmor = memo(({ thicknessRange }) => { {armorNodes.map((node) => { const isCurrentTurret = node.name.startsWith( - `turret_${turretModelDefinition.model_id.toString().padStart(2, '0')}`, + `turret_${turretModelDefinition.model_id.toString().padStart(2, "0")}` ); const isVisible = isCurrentTurret; const armorId = nameToArmorId(node.name); const { spaced, thickness } = resolveArmor( turretModelDefinition.armor, - armorId, + armorId ); if ( @@ -140,8 +140,8 @@ export const StaticArmor = memo(({ thicknessRange }) => { thickness === undefined || (!showPrimaryArmor && !spaced) || (!showSpacedArmor && spaced) || - (isDynamicArmorActive && node.name.includes('state_00')) || - (!isDynamicArmorActive && node.name.includes('state_01')) + (isDynamicArmorActive && node.name.includes("state_00")) || + (!isDynamicArmorActive && node.name.includes("state_01")) ) { return null; } @@ -154,27 +154,27 @@ export const StaticArmor = memo(({ thicknessRange }) => { position.set(event.clientX, event.clientY); - TankopediaEphemeral.mutate((draft) => { + Tankopedia.mutate((draft) => { draft.controlsEnabled = false; }); - TankopediaEphemeral.mutate((draft) => { + Tankopedia.mutate((draft) => { draft.shot = undefined; draft.highlightArmor = undefined; }); - window.addEventListener('pointermove', handlePointerMove); - window.addEventListener('pointerup', handlePointerUp); + window.addEventListener("pointermove", handlePointerMove); + window.addEventListener("pointerup", handlePointerUp); } function handlePointerMove(event: PointerEvent) { const duel = duelStore.getState(); const hasImprovedVerticalStabilizer = hasEquipment( 122, duel.protagonist.tank.equipment_preset, - duel.protagonist.equipmentMatrix, + duel.protagonist.equipmentMatrix ); const hasDownImprovedVerticalStabilizer = hasEquipment( 124, duel.protagonist.tank.equipment_preset, - duel.protagonist.equipmentMatrix, + duel.protagonist.equipmentMatrix ); const boundingRect = canvas.getBoundingClientRect(); @@ -188,16 +188,16 @@ export const StaticArmor = memo(({ thicknessRange }) => { gunModelDefinition.pitch, turretModelDefinition.yaw, hasImprovedVerticalStabilizer, - hasDownImprovedVerticalStabilizer, + hasDownImprovedVerticalStabilizer ); modelTransformEvent.dispatch({ pitch, yaw }); } function handlePointerUp() { - TankopediaEphemeral.mutate((draft) => { + Tankopedia.mutate((draft) => { draft.controlsEnabled = true; }); - window.removeEventListener('pointermove', handlePointerMove); - window.removeEventListener('pointerup', handlePointerUp); + window.removeEventListener("pointermove", handlePointerMove); + window.removeEventListener("pointerup", handlePointerUp); } return ( @@ -219,13 +219,13 @@ export const StaticArmor = memo(({ thicknessRange }) => { {armorNodes.map((node) => { const isCurrentGun = node.name.startsWith( - `gun_${gunModelDefinition.model_id.toString().padStart(2, '0')}`, + `gun_${gunModelDefinition.model_id.toString().padStart(2, "0")}` ); const isVisible = isCurrentGun; const armorId = nameToArmorId(node.name); const { spaced, thickness } = resolveArmor( gunModelDefinition.armor, - armorId, + armorId ); if ( @@ -233,8 +233,8 @@ export const StaticArmor = memo(({ thicknessRange }) => { thickness === undefined || (!showPrimaryArmor && !spaced) || (!showSpacedArmor && spaced) || - (isDynamicArmorActive && node.name.includes('state_00')) || - (!isDynamicArmorActive && node.name.includes('state_01')) + (isDynamicArmorActive && node.name.includes("state_00")) || + (!isDynamicArmorActive && node.name.includes("state_01")) ) return null; @@ -244,30 +244,30 @@ export const StaticArmor = memo(({ thicknessRange }) => { function onPointerDown(event: ThreeEvent) { event.stopPropagation(); - TankopediaEphemeral.mutate((draft) => { + Tankopedia.mutate((draft) => { draft.controlsEnabled = false; }); - TankopediaEphemeral.mutate((draft) => { + Tankopedia.mutate((draft) => { draft.shot = undefined; draft.highlightArmor = undefined; }); position.set(event.clientX, event.clientY); - window.addEventListener('pointermove', handlePointerMove); - window.addEventListener('pointerup', handlePointerUp); + window.addEventListener("pointermove", handlePointerMove); + window.addEventListener("pointerup", handlePointerUp); } function handlePointerMove(event: PointerEvent) { const duel = duelStore.getState(); const hasImprovedVerticalStabilizer = hasEquipment( 122, duel.protagonist.tank.equipment_preset, - duel.protagonist.equipmentMatrix, + duel.protagonist.equipmentMatrix ); const hasDownImprovedVerticalStabilizer = hasEquipment( 124, duel.protagonist.tank.equipment_preset, - duel.protagonist.equipmentMatrix, + duel.protagonist.equipmentMatrix ); const boundingRect = canvas.getBoundingClientRect(); delta.set(event.clientX, event.clientY).sub(position); @@ -281,16 +281,16 @@ export const StaticArmor = memo(({ thicknessRange }) => { gunModelDefinition.pitch, turretModelDefinition.yaw, hasImprovedVerticalStabilizer, - hasDownImprovedVerticalStabilizer, + hasDownImprovedVerticalStabilizer ); modelTransformEvent.dispatch({ pitch, yaw }); } function handlePointerUp() { - TankopediaEphemeral.mutate((draft) => { + Tankopedia.mutate((draft) => { draft.controlsEnabled = true; }); - window.removeEventListener('pointermove', handlePointerMove); - window.removeEventListener('pointerup', handlePointerUp); + window.removeEventListener("pointermove", handlePointerMove); + window.removeEventListener("pointerup", handlePointerUp); } return ( @@ -312,7 +312,7 @@ export const StaticArmor = memo(({ thicknessRange }) => { {modelNodes.map((node) => { const gunString = `gun_${gunModelDefinition.model_id .toString() - .padStart(2, '0')}`; + .padStart(2, "0")}`; const isCurrentGun = gunModelDefinition.mask ? node.name.startsWith(gunString) : node.name === gunString; @@ -326,29 +326,29 @@ export const StaticArmor = memo(({ thicknessRange }) => { function onPointerDown(event: ThreeEvent) { event.stopPropagation(); - TankopediaEphemeral.mutate((draft) => { + Tankopedia.mutate((draft) => { draft.controlsEnabled = false; }); - TankopediaEphemeral.mutate((draft) => { + Tankopedia.mutate((draft) => { draft.shot = undefined; draft.highlightArmor = undefined; }); position.set(event.clientX, event.clientY); - window.addEventListener('pointermove', handlePointerMove); - window.addEventListener('pointerup', handlePointerUp); + window.addEventListener("pointermove", handlePointerMove); + window.addEventListener("pointerup", handlePointerUp); } function handlePointerMove(event: PointerEvent) { const duel = duelStore.getState(); const hasImprovedVerticalStabilizer = hasEquipment( 122, duel.protagonist.tank.equipment_preset, - duel.protagonist.equipmentMatrix, + duel.protagonist.equipmentMatrix ); const hasDownImprovedVerticalStabilizer = hasEquipment( 124, duel.protagonist.tank.equipment_preset, - duel.protagonist.equipmentMatrix, + duel.protagonist.equipmentMatrix ); const boundingRect = canvas.getBoundingClientRect(); delta.set(event.clientX, event.clientY).sub(position); @@ -362,17 +362,17 @@ export const StaticArmor = memo(({ thicknessRange }) => { gunModelDefinition.pitch, turretModelDefinition.yaw, hasImprovedVerticalStabilizer, - hasDownImprovedVerticalStabilizer, + hasDownImprovedVerticalStabilizer ); modelTransformEvent.dispatch({ pitch, yaw }); } function handlePointerUp() { - TankopediaEphemeral.mutate((draft) => { + Tankopedia.mutate((draft) => { draft.controlsEnabled = true; }); - window.removeEventListener('pointermove', handlePointerMove); - window.removeEventListener('pointerup', handlePointerUp); + window.removeEventListener("pointermove", handlePointerMove); + window.removeEventListener("pointerup", handlePointerUp); } return ( diff --git a/packages/website/src/components/Armor/components/StaticArmorSceneComponent.tsx b/packages/website/src/components/Armor/components/StaticArmorSceneComponent.tsx index 58f5b3b8e..9db804df9 100644 --- a/packages/website/src/components/Armor/components/StaticArmorSceneComponent.tsx +++ b/packages/website/src/components/Armor/components/StaticArmorSceneComponent.tsx @@ -1,8 +1,8 @@ -import { I_HAT, J_HAT } from '@blitzkit/core'; -import { type MeshProps, useThree } from '@react-three/fiber'; -import { clamp } from 'lodash-es'; -import type { QuicklimeEvent } from 'quicklime'; -import { useEffect, useMemo } from 'react'; +import { I_HAT, J_HAT } from "@blitzkit/core"; +import { type MeshProps, useThree } from "@react-three/fiber"; +import { clamp } from "lodash-es"; +import type { QuicklimeEvent } from "quicklime"; +import { useEffect, useMemo } from "react"; import { Box3, Color, @@ -15,28 +15,28 @@ import { Plane, Quaternion, Vector3, -} from 'three'; -import { unrotateDavaVector } from '../../../core/blitz/unrotateDavaVector'; -import { jsxTree } from '../../../core/blitzkit/jsxTree'; +} from "three"; +import { unrotateDavaVector } from "../../../core/blitz/unrotateDavaVector"; +import { jsxTree } from "../../../core/blitzkit/jsxTree"; import { type ModelTransformEventData, modelTransformEvent, -} from '../../../core/blitzkit/modelTransform'; -import { discardClippingPlane } from '../../../core/three/discardClippingPlane'; -import { TankopediaEphemeral } from '../../../stores/tankopediaEphemeral'; -import { ArmorType } from './SpacedArmorScene'; +} from "../../../core/blitzkit/modelTransform"; +import { discardClippingPlane } from "../../../core/three/discardClippingPlane"; +import { Tankopedia } from "../../../stores/tankopedia"; +import { ArmorType } from "./SpacedArmorScene"; import type { ArmorUserData, ExternalModuleVariant, -} from './SpacedArmorSceneComponent'; -import type { ThicknessRange } from './StaticArmor'; +} from "./SpacedArmorSceneComponent"; +import type { ThicknessRange } from "./StaticArmor"; type StaticArmorSceneComponentProps = { name: string; thickness: number; thicknessRange: ThicknessRange; node: Object3D; - onPointerDown?: MeshProps['onPointerDown']; + onPointerDown?: MeshProps["onPointerDown"]; } & ( | { type: Exclude; @@ -90,7 +90,7 @@ export function StaticArmorSceneComponent({ color = new Color( clamp(1 - (7 / 8) * xClamped, 0, 1), 0, - clamp(1 - (1 / 8) * xClamped, 0, 1), + clamp(1 - (1 / 8) * xClamped, 0, 1) ); opacity = clamp(x + 1 / 2, 0, 1); break; @@ -113,7 +113,7 @@ export function StaticArmorSceneComponent({ depthWrite, ...(props.clip ? { clippingPlanes: [props.clip] } : {}), }), - [thickness], + [thickness] ); const outlineMaterial = useMemo( () => @@ -122,7 +122,7 @@ export function StaticArmorSceneComponent({ .clone() .multiplyScalar(props.type === ArmorType.Spaced ? 2 ** 2 : 2 ** -1), }), - [thickness], + [thickness] ); useEffect(() => { @@ -137,11 +137,11 @@ export function StaticArmorSceneComponent({ outlineMaterial.visible = true; } else if ( selectedName === name || - (name.startsWith('chassis_') && selectedName.startsWith('chassis_')) || - (name.startsWith('gun_') && - selectedName.startsWith('gun_') && - !name.includes('_armor_') && - !selectedName.includes('_armor_')) + (name.startsWith("chassis_") && selectedName.startsWith("chassis_")) || + (name.startsWith("gun_") && + selectedName.startsWith("gun_") && + !name.includes("_armor_") && + !selectedName.includes("_armor_")) ) { // this selected, stand out! surfaceMaterial.opacity = 1; @@ -164,9 +164,9 @@ export function StaticArmorSceneComponent({ } const unsubscribes = [ - TankopediaEphemeral.on( + Tankopedia.on( (state) => state.highlightArmor?.name, - handleHighlightArmor, + handleHighlightArmor ), ]; @@ -179,14 +179,14 @@ export function StaticArmorSceneComponent({ const { clip } = props; const gunOrigin = unrotateDavaVector(props.gunOrigin.clone()); const neckOrigin = unrotateDavaVector(props.hullOrigin.clone()).add( - unrotateDavaVector(props.turretOrigin.clone()), + unrotateDavaVector(props.turretOrigin.clone()) ); const barrelOrigin = neckOrigin.clone().add(gunOrigin); const distanceToBarrel = clip.distanceToPoint(barrelOrigin); const point = new Vector3(); function handleModelTransform( - event: QuicklimeEvent, + event: QuicklimeEvent ) { clip.normal .set(0, 0, -1) @@ -227,7 +227,7 @@ export function StaticArmorSceneComponent({ { type: props.type, variant: - props.type === ArmorType.External ? props.variant : 'gun', + props.type === ArmorType.External ? props.variant : "gun", thickness, } satisfies ArmorUserData } @@ -236,7 +236,7 @@ export function StaticArmorSceneComponent({ event.stopPropagation(); - const { editStatic } = TankopediaEphemeral.state; + const { editStatic } = Tankopedia.state; const bounds = new Box3().setFromObject(event.object); const point = bounds.min @@ -251,13 +251,13 @@ export function StaticArmorSceneComponent({ const surfaceNormal = event .normal!.clone() .applyQuaternion( - event.object.getWorldQuaternion(new Quaternion()), + event.object.getWorldQuaternion(new Quaternion()) ); const angle = surfaceNormal.angleTo(cameraNormal); const thicknessAngled = thickness / Math.sin(Math.PI / 2 - angle); - TankopediaEphemeral.mutate((draft) => { + Tankopedia.mutate((draft) => { draft.highlightArmor = { type: props.type, name, diff --git a/packages/website/src/components/GuessBackground/index.tsx b/packages/website/src/components/GuessBackground/index.tsx index 6a42a2a93..447098f65 100644 --- a/packages/website/src/components/GuessBackground/index.tsx +++ b/packages/website/src/components/GuessBackground/index.tsx @@ -5,8 +5,8 @@ import { awaitableProvisionDefinitions } from "../../core/awaitables/provisionDe import { tankToDuelMember } from "../../core/blitzkit/tankToDuelMember"; import { Var } from "../../core/radix/var"; import { Duel } from "../../stores/duel"; -import { Guess, GuessState } from "../../stores/guessEphemeral"; -import { TankopediaEphemeral } from "../../stores/tankopediaEphemeral"; +import { Guess, GuessState } from "../../stores/guess"; +import { Tankopedia } from "../../stores/tankopedia"; import "./index.css"; const [modelDefinitions, provisionDefinitions] = await Promise.all([ @@ -23,7 +23,7 @@ export function GuessBackground() { mutateDuel((state) => { state.protagonist = tankToDuelMember(tank, provisionDefinitions); }); - TankopediaEphemeral.mutate((state) => { + Tankopedia.mutate((state) => { state.model = modelDefinitions.models[tank.id]; }); }, [tank]); diff --git a/packages/website/src/components/GuessRenderer.tsx b/packages/website/src/components/GuessRenderer.tsx index 0fbd8fd80..65aa71e04 100644 --- a/packages/website/src/components/GuessRenderer.tsx +++ b/packages/website/src/components/GuessRenderer.tsx @@ -1,4 +1,4 @@ -import { Guess, GuessState } from "../stores/guessEphemeral"; +import { Guess, GuessState } from "../stores/guess"; import { SmartCanvas } from "./SmartCanvas"; import { Controls } from "./Tankopedia/HeroSection/components/TankSandbox/components/Control"; import { Lighting } from "./Tankopedia/HeroSection/components/TankSandbox/components/Lighting"; diff --git a/packages/website/src/components/Guesser.tsx b/packages/website/src/components/Guesser.tsx index df87a41fd..7520a49a2 100644 --- a/packages/website/src/components/Guesser.tsx +++ b/packages/website/src/components/Guesser.tsx @@ -24,7 +24,7 @@ import { useCallback, useEffect, useRef, useState } from "react"; import { awaitableTankDefinitions } from "../core/awaitables/tankDefinitions"; import { awaitableTankNames } from "../core/awaitables/tankNames"; import { useLocale } from "../hooks/useLocale"; -import { Guess, GuessState } from "../stores/guessEphemeral"; +import { Guess, GuessState } from "../stores/guess"; import { classIcons } from "./ClassIcon"; import { SearchResults } from "./SearchResults"; diff --git a/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/components/CompareOptions.tsx b/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/components/CompareOptions.tsx index a2324d8dc..635fcc3c7 100644 --- a/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/components/CompareOptions.tsx +++ b/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/components/CompareOptions.tsx @@ -1,17 +1,15 @@ -import { TIER_ROMAN_NUMERALS } from '@blitzkit/core'; -import { literals } from '@blitzkit/i18n/src/literals'; -import { Flex, SegmentedControl, Text, type FlexProps } from '@radix-ui/themes'; -import { useLocale } from '../../../../../../hooks/useLocale'; -import { Duel } from '../../../../../../stores/duel'; +import { TIER_ROMAN_NUMERALS } from "@blitzkit/core"; +import { literals } from "@blitzkit/i18n/src/literals"; +import { Flex, SegmentedControl, Text, type FlexProps } from "@radix-ui/themes"; +import { useLocale } from "../../../../../../hooks/useLocale"; +import { Duel } from "../../../../../../stores/duel"; import { - TankopediaEphemeral, + Tankopedia, TankopediaRelativeAgainst, -} from '../../../../../../stores/tankopediaEphemeral'; +} from "../../../../../../stores/tankopedia"; export function CompareOptions(props: FlexProps) { - const relativeAgainst = TankopediaEphemeral.use( - (state) => state.relativeAgainst, - ); + const relativeAgainst = Tankopedia.use((state) => state.relativeAgainst); const tank = Duel.use((state) => state.protagonist.tank); const { strings } = useLocale(); @@ -20,7 +18,7 @@ export function CompareOptions(props: FlexProps) { align="center" gap="2" justify="center" - direction={{ initial: 'column', sm: 'row' }} + direction={{ initial: "column", sm: "row" }} {...props} > @@ -32,7 +30,7 @@ export function CompareOptions(props: FlexProps) { size="1" value={`${relativeAgainst}`} onValueChange={(value) => { - TankopediaEphemeral.mutate((draft) => { + Tankopedia.mutate((draft) => { draft.relativeAgainst = Number(value) as TankopediaRelativeAgainst; }); }} @@ -43,13 +41,13 @@ export function CompareOptions(props: FlexProps) { [ TIER_ROMAN_NUMERALS[tank.tier], strings.common.tank_class_short_plural_lowercase[tank.class], - ], + ] )} {literals( strings.website.tools.tankopedia.characteristics.compare.tier, - [TIER_ROMAN_NUMERALS[tank.tier]], + [TIER_ROMAN_NUMERALS[tank.tier]] )} 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 5335a0676..f5d9dff06 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,10 +1,10 @@ -import { CaretDownIcon, CaretUpIcon } from '@radix-ui/react-icons'; -import { Box, Flex, Text } from '@radix-ui/themes'; -import fuzzysort from 'fuzzysort'; -import { Quicklime } from 'quicklime'; -import { useEffect, useRef, type ReactNode } from 'react'; -import { TankopediaEphemeral } from '../../../../../../stores/tankopediaEphemeral'; -import { Mark } from '../../../../../Mark'; +import { CaretDownIcon, CaretUpIcon } from "@radix-ui/react-icons"; +import { Box, Flex, Text } from "@radix-ui/themes"; +import fuzzysort from "fuzzysort"; +import { Quicklime } from "quicklime"; +import { useEffect, useRef, type ReactNode } from "react"; +import { Tankopedia } from "../../../../../../stores/tankopedia"; +import { Mark } from "../../../../../Mark"; export const highlightedRows = new Set(); export const highlightedRowsUpdate = new Quicklime(); @@ -16,7 +16,7 @@ export interface InfoProps { delta?: number; decimals?: number; prefix?: string; - deltaType?: 'higherIsBetter' | 'lowerIsBetter'; + deltaType?: "higherIsBetter" | "lowerIsBetter"; } export function Info({ @@ -26,15 +26,15 @@ export function Info({ delta, decimals, prefix, - deltaType = 'higherIsBetter', + deltaType = "higherIsBetter", }: InfoProps) { - const statSearch = TankopediaEphemeral.use((state) => state.statSearch); + const statSearch = Tankopedia.use((state) => state.statSearch); const container = useRef(null); let label = name; let highlighted = false; - if (statSearch !== undefined && typeof name === 'string') { + if (statSearch !== undefined && typeof name === "string") { const result = fuzzysort.single(statSearch, name); if (result) { @@ -62,7 +62,7 @@ export function Info({ return ( 0 - ? 'green' - : 'tomato' + delta * (deltaType === "lowerIsBetter" ? -1 : 1) > 0 + ? "green" + : "tomato" } > {decimals !== undefined @@ -88,9 +88,9 @@ export function Info({ 0 - ? 'green' - : 'tomato' + delta * (deltaType === "lowerIsBetter" ? -1 : 1) > 0 + ? "green" + : "tomato" } > {delta > 0 ? : } @@ -105,7 +105,7 @@ export function Info({ )} - {decimals !== undefined && typeof children === 'number' + {decimals !== undefined && typeof children === "number" ? children.toFixed(decimals) : children} 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 4302a9f95..1c5abb66f 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,27 +1,27 @@ -import { createDefaultSkills } from '@blitzkit/core'; -import { Flex, Progress, Text } from '@radix-ui/themes'; -import { clamp } from 'lodash-es'; -import { memo, useMemo, type ComponentProps, type ReactNode } from 'react'; -import { awaitableEquipmentDefinitions } from '../../../../../../core/awaitables/equipmentDefinitions'; -import { awaitableModelDefinitions } from '../../../../../../core/awaitables/modelDefinitions'; -import { awaitableProvisionDefinitions } from '../../../../../../core/awaitables/provisionDefinitions'; -import { awaitableSkillDefinitions } from '../../../../../../core/awaitables/skillDefinitions'; -import { awaitableTankDefinitions } from '../../../../../../core/awaitables/tankDefinitions'; +import { createDefaultSkills } from "@blitzkit/core"; +import { Flex, Progress, Text } from "@radix-ui/themes"; +import { clamp } from "lodash-es"; +import { memo, useMemo, type ComponentProps, type ReactNode } from "react"; +import { awaitableEquipmentDefinitions } from "../../../../../../core/awaitables/equipmentDefinitions"; +import { awaitableModelDefinitions } from "../../../../../../core/awaitables/modelDefinitions"; +import { awaitableProvisionDefinitions } from "../../../../../../core/awaitables/provisionDefinitions"; +import { awaitableSkillDefinitions } from "../../../../../../core/awaitables/skillDefinitions"; +import { awaitableTankDefinitions } from "../../../../../../core/awaitables/tankDefinitions"; import { tankCharacteristics, type TankCharacteristics, -} from '../../../../../../core/blitzkit/tankCharacteristics'; -import { tankToDuelMember } from '../../../../../../core/blitzkit/tankToDuelMember'; -import { useDelta } from '../../../../../../hooks/useDelta'; -import { useLocale } from '../../../../../../hooks/useLocale'; -import { Duel } from '../../../../../../stores/duel'; +} from "../../../../../../core/blitzkit/tankCharacteristics"; +import { tankToDuelMember } from "../../../../../../core/blitzkit/tankToDuelMember"; +import { useDelta } from "../../../../../../hooks/useDelta"; +import { useLocale } from "../../../../../../hooks/useLocale"; +import { Duel } from "../../../../../../stores/duel"; import { - TankopediaEphemeral, + Tankopedia, TankopediaRelativeAgainst, -} from '../../../../../../stores/tankopediaEphemeral'; -import { Info, type InfoProps } from './Info'; +} from "../../../../../../stores/tankopedia"; +import { Info, type InfoProps } from "./Info"; -type InfoWithDeltaProps = Omit & { +type InfoWithDeltaProps = Omit & { stats: TankCharacteristics; noRanking?: boolean; } & ( @@ -51,20 +51,18 @@ const [ export const InfoWithDelta = memo( ({ stats, indent, noRanking, deltaType, ...props }) => { const { strings } = useLocale(); - const relativeAgainst = TankopediaEphemeral.use( - (state) => state.relativeAgainst, - ); + const relativeAgainst = Tankopedia.use((state) => state.relativeAgainst); const uhWhatDoICallThisVariable = - typeof props.value === 'function' + typeof props.value === "function" ? props.value(stats)! : (stats[props.value] as number); const delta = useDelta(uhWhatDoICallThisVariable); const protagonistTank = Duel.use((state) => state.protagonist.tank); const shellIndex = Duel.use((state) => - state.protagonist.gun.shells.indexOf(state.protagonist.shell), + state.protagonist.gun.shells.indexOf(state.protagonist.shell) ); const equipmentMatrix = Duel.use( - (state) => state.protagonist.equipmentMatrix, + (state) => state.protagonist.equipmentMatrix ); const others = useMemo(() => { const defaultSkills = createDefaultSkills(skillDefinitions); @@ -77,7 +75,7 @@ export const InfoWithDelta = memo( tank.class === protagonistTank.class) || (relativeAgainst === TankopediaRelativeAgainst.Tier && tank.tier === protagonistTank.tier) || - relativeAgainst === TankopediaRelativeAgainst.All, + relativeAgainst === TankopediaRelativeAgainst.All ) .map((tank) => { const member = tankToDuelMember(tank, provisionDefinitions); @@ -112,14 +110,14 @@ export const InfoWithDelta = memo( equipmentDefinitions, provisionDefinitions, tankModelDefinition: modelDefinitions.models[tank.id], - }, + } ); }) .filter((tank) => { if (tank === undefined) return false; const othersValue = - typeof props.value === 'function' + typeof props.value === "function" ? props.value(tank)! : (tank[props.value] as number); @@ -128,22 +126,22 @@ export const InfoWithDelta = memo( }, [relativeAgainst, shellIndex, equipmentMatrix]); const betterTanks = others.filter((tank) => { const othersValue = - typeof props.value === 'function' + typeof props.value === "function" ? props.value(tank)! : (tank[props.value] as number); if (othersValue === undefined) return false; - return deltaType === 'lowerIsBetter' + return deltaType === "lowerIsBetter" ? othersValue < uhWhatDoICallThisVariable : othersValue > uhWhatDoICallThisVariable; }); const goodness = (others.length - betterTanks.length) / others.length; - let color: ComponentProps['color']; + let color: ComponentProps["color"]; - if (goodness <= 0.25) color = 'red'; - else if (goodness <= 0.5) color = 'orange'; - else if (goodness <= 0.75) color = 'yellow'; - else color = 'green'; + if (goodness <= 0.25) color = "red"; + else if (goodness <= 0.5) color = "orange"; + else if (goodness <= 0.75) color = "yellow"; + else color = "green"; return ( @@ -151,7 +149,7 @@ export const InfoWithDelta = memo( deltaType={deltaType} indent={indent} name={ - 'name' in props + "name" in props ? props.name : strings.website.tools.tankopedia.characteristics.values[ props.value @@ -164,17 +162,17 @@ export const InfoWithDelta = memo( {!noRanking && ( - + - {clamp(betterTanks.length + 1, 1, others.length)} /{' '} + {clamp(betterTanks.length + 1, 1, others.length)} /{" "} {others.length} @@ -184,6 +182,6 @@ export const InfoWithDelta = memo( }, (a, b) => - (typeof a.value === 'function' ? a.value(a.stats) : a.stats[a.value]) === - (typeof b.value === 'function' ? b.value(b.stats) : b.stats[b.value]), + (typeof a.value === "function" ? a.value(a.stats) : a.stats[a.value]) === + (typeof b.value === "function" ? b.value(b.stats) : b.stats[b.value]) ); diff --git a/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/components/StatSearch.tsx b/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/components/StatSearch.tsx index 08edfb622..77cde4dda 100644 --- a/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/components/StatSearch.tsx +++ b/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/components/StatSearch.tsx @@ -1,10 +1,10 @@ -import { MagnifyingGlassIcon } from '@radix-ui/react-icons'; -import { Flex, Spinner, TextField, type FlexProps } from '@radix-ui/themes'; -import { debounce } from 'lodash-es'; -import { useCallback, useEffect, useRef, useState } from 'react'; -import { useLocale } from '../../../../../../hooks/useLocale'; -import { TankopediaEphemeral } from '../../../../../../stores/tankopediaEphemeral'; -import { highlightedRows, highlightedRowsUpdate } from './Info'; +import { MagnifyingGlassIcon } from "@radix-ui/react-icons"; +import { Flex, Spinner, TextField, type FlexProps } from "@radix-ui/themes"; +import { debounce } from "lodash-es"; +import { useCallback, useEffect, useRef, useState } from "react"; +import { useLocale } from "../../../../../../hooks/useLocale"; +import { Tankopedia } from "../../../../../../stores/tankopedia"; +import { highlightedRows, highlightedRowsUpdate } from "./Info"; export function StatSearch(props: FlexProps) { const { strings } = useLocale(); @@ -19,7 +19,7 @@ export function StatSearch(props: FlexProps) { setSearching(true); } else { setSearching(false); - count.current.textContent = ''; + count.current.textContent = ""; } requestUpdate(); @@ -30,21 +30,21 @@ export function StatSearch(props: FlexProps) { if (!input.current || !count.current) return; if (input.current.value.length === 0) { - count.current.textContent = ''; + count.current.textContent = ""; setSearching(false); - TankopediaEphemeral.mutate((draft) => { + Tankopedia.mutate((draft) => { draft.statSearch = undefined; }); return; } setSearching(false); - TankopediaEphemeral.mutate((draft) => { + Tankopedia.mutate((draft) => { draft.statSearch = input.current!.value; }); }, 500), - [], + [] ); useEffect(() => { @@ -52,7 +52,7 @@ export function StatSearch(props: FlexProps) { if (!count.current || !input.current) return; count.current.textContent = - input.current.value.length === 0 ? '' : `0 / ${highlightedRows.size}`; + input.current.value.length === 0 ? "" : `0 / ${highlightedRows.size}`; }; highlightedRowsUpdate.on(handleHighlightedRowsUpdate); @@ -68,23 +68,23 @@ export function StatSearch(props: FlexProps) { ref={input} placeholder={strings.website.tools.tankopedia.search} variant="classic" - style={{ width: '100%' }} + style={{ width: "100%" }} onChange={search} onKeyDown={(event) => { if (!count.current) return; - if (event.key === 'Enter') { + if (event.key === "Enter") { const newIndex = (index + 1) % highlightedRows.size; count.current.textContent = `${newIndex + 1} / ${highlightedRows.size}`; const array = [...highlightedRows]; - array.forEach((element) => element.classList.remove('focused')); + array.forEach((element) => element.classList.remove("focused")); if (array[newIndex]) { - array[newIndex].classList.add('focused'); + array[newIndex].classList.add("focused"); array[newIndex].scrollIntoView({ - block: 'center', - inline: 'center', + block: "center", + inline: "center", }); } 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 13a05d7d0..e79b92713 100644 --- a/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/index.tsx +++ b/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/index.tsx @@ -1,19 +1,19 @@ -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 { modelTransformEvent } from '../../../../../core/blitzkit/modelTransform'; -import { tankCharacteristics } from '../../../../../core/blitzkit/tankCharacteristics'; -import { useEquipment } from '../../../../../hooks/useEquipment'; -import { useTankModelDefinition } from '../../../../../hooks/useTankModelDefinition'; -import { Duel } from '../../../../../stores/duel'; -import { TankopediaEphemeral } from '../../../../../stores/tankopediaEphemeral'; -import type { MaybeSkeletonComponentProps } from '../../../../../types/maybeSkeletonComponentProps'; -import { Crew } from './components/Crew'; -import { Firepower } from './components/Firepower'; -import { Maneuverability } from './components/Maneuverability'; -import { Survivability } from './components/Survivability'; +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 { modelTransformEvent } from "../../../../../core/blitzkit/modelTransform"; +import { tankCharacteristics } from "../../../../../core/blitzkit/tankCharacteristics"; +import { useEquipment } from "../../../../../hooks/useEquipment"; +import { useTankModelDefinition } from "../../../../../hooks/useTankModelDefinition"; +import { Duel } from "../../../../../stores/duel"; +import { Tankopedia } from "../../../../../stores/tankopedia"; +import type { MaybeSkeletonComponentProps } from "../../../../../types/maybeSkeletonComponentProps"; +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, @@ -21,18 +21,18 @@ const [equipmentDefinitions, provisionDefinitions] = await Promise.all([ ]); export function Characteristics({ skeleton }: MaybeSkeletonComponentProps) { - const crewSkills = TankopediaEphemeral.use((state) => state.skills); + const crewSkills = Tankopedia.use((state) => state.skills); const provisions = Duel.use((state) => state.protagonist.provisions); const consumables = Duel.use((state) => state.protagonist.consumables); const camouflage = Duel.use((state) => state.protagonist.camouflage); const assaultDistance = Duel.use( - (state) => state.protagonist.assaultDistance, + (state) => state.protagonist.assaultDistance ); const equipmentMatrix = Duel.use( - (state) => state.protagonist.equipmentMatrix, + (state) => state.protagonist.equipmentMatrix ); const { tank, turret, gun, engine, track, shell } = Duel.use( - (state) => state.protagonist, + (state) => state.protagonist ); const stockEngine = tank.engines[0]; const stockTrack = tank.tracks[0]; @@ -67,7 +67,7 @@ export function Characteristics({ skeleton }: MaybeSkeletonComponentProps) { tankModelDefinition, equipmentDefinitions: equipmentDefinitions, provisionDefinitions: provisionDefinitions, - }, + } ); const hasImprovedVerticalStabilizer = useEquipment(122); @@ -80,7 +80,7 @@ export function Characteristics({ skeleton }: MaybeSkeletonComponentProps) { gunModelDefinition.pitch, turretModelDefinition.yaw, hasImprovedVerticalStabilizer, - hasDownImprovedVerticalStabilizer, + hasDownImprovedVerticalStabilizer ); modelTransformEvent.dispatch({ pitch, yaw }); @@ -89,25 +89,25 @@ export function Characteristics({ skeleton }: MaybeSkeletonComponentProps) { return ( diff --git a/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Skills.tsx b/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Skills.tsx index 3a92e682b..0e16fd790 100644 --- a/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Skills.tsx +++ b/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Skills.tsx @@ -1,4 +1,4 @@ -import { InfoCircledIcon } from '@radix-ui/react-icons'; +import { InfoCircledIcon } from "@radix-ui/react-icons"; import { Button, Flex, @@ -6,14 +6,14 @@ import { IconButton, Popover, Text, -} from '@radix-ui/themes'; -import { useLocale } from '../../../../hooks/useLocale'; -import { TankopediaEphemeral } from '../../../../stores/tankopediaEphemeral'; -import { CrewSkillManager } from '../../../CrewSkillManager'; -import { ConfigurationChildWrapper } from './ConfigurationChildWrapper'; +} from "@radix-ui/themes"; +import { useLocale } from "../../../../hooks/useLocale"; +import { Tankopedia } from "../../../../stores/tankopedia"; +import { CrewSkillManager } from "../../../CrewSkillManager"; +import { ConfigurationChildWrapper } from "./ConfigurationChildWrapper"; export function Skills() { - const skillLevels = TankopediaEphemeral.use((state) => state.skills); + const skillLevels = Tankopedia.use((state) => state.skills); const { strings } = useLocale(); return ( @@ -45,7 +45,7 @@ export function Skills() { variant="ghost" color="red" onClick={() => { - TankopediaEphemeral.mutate((draft) => { + Tankopedia.mutate((draft) => { Object.keys(draft.skills).forEach((skill) => { draft.skills[skill] = 0; }); @@ -57,7 +57,7 @@ export function Skills() {