From 5b16e22750f6ded86d6a534cc468c371c13dd07c Mon Sep 17 00:00:00 2001 From: tresabhi <43380238+tresabhi@users.noreply.github.com> Date: Thu, 20 Mar 2025 21:48:17 -0500 Subject: [PATCH] feat: some armor rendering --- .../Armor/components/StaticArmor.tsx | 483 +++------------- .../website/src/components/SmallTankIcon.tsx | 4 +- .../src/components/TankSearch/index.tsx | 5 +- .../Options/components/QuickInputs/index.tsx | 28 +- .../Options/components/Thicknesses.tsx | 6 +- .../HeroSection/components/Options/index.tsx | 97 ++-- .../TankSandbox/components/Control.tsx | 534 +++++++++--------- .../TankSandbox/components/Lighting.tsx | 7 +- .../components/SceneProps/index.tsx | 354 ++++++------ .../TankSandbox/components/TankModel.tsx | 2 + .../components/TankSandbox/index.tsx | 190 +++---- .../Tankopedia/HeroSection/index.tsx | 10 +- .../website/src/stores/tankopediaEphemeral.ts | 2 +- 13 files changed, 662 insertions(+), 1060 deletions(-) diff --git a/packages/website/src/components/Armor/components/StaticArmor.tsx b/packages/website/src/components/Armor/components/StaticArmor.tsx index c6f410263..f26575b3f 100644 --- a/packages/website/src/components/Armor/components/StaticArmor.tsx +++ b/packages/website/src/components/Armor/components/StaticArmor.tsx @@ -1,23 +1,10 @@ -import { normalizeAngleRad } from '@blitzkit/core'; -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 { asset } from '@blitzkit/core'; +import { useGLTF } from '@react-three/drei'; +import { memo } from 'react'; +import { Color, Material, MeshBasicMaterial } from 'three'; +import { jsxTree } from '../../../core/blitzkit/jsxTree'; 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'; interface ArmorSceneProps { thicknessRange: ThicknessRange; @@ -28,401 +15,87 @@ export interface ThicknessRange { } export const StaticArmor = memo(({ thicknessRange }) => { - const wrapper = useRef(null); - const turretContainer = useRef(null); - const gunContainer = useRef(null); - const protagonist = Duel.use((draft) => draft.protagonist); - const tank = Duel.use((state) => state.protagonist.tank); - const track = Duel.use((state) => state.protagonist.track); - const turret = Duel.use((state) => state.protagonist.turret); - const gun = Duel.use((state) => state.protagonist.gun); - const { gltf: armorGltf } = useArmor(tank.id); - const { gltf: modelGltf } = useModel(tank.id); - const armorNodes = Object.values(armorGltf.nodes); - const modelNodes = Object.values(modelGltf.nodes); - const tankModelDefinition = useTankModelDefinition(); - const trackModelDefinition = tankModelDefinition.tracks[track.id]; - const turretModelDefinition = tankModelDefinition.turrets[turret.id]; - const gunModelDefinition = - turretModelDefinition.guns[gun.gun_type!.value.base.id]; - const hullOrigin = correctZYTuple(trackModelDefinition.origin); - const turretOrigin = correctZYTuple(tankModelDefinition.turret_origin); - const gunOrigin = correctZYTuple(turretModelDefinition.gun_origin); - const mutateDuel = Duel.useMutation(); - const canvas = useThree((state) => state.gl.domElement); - const mutateTankopediaEphemeral = TankopediaEphemeral.useMutation(); - const duelStore = Duel.useStore(); - const maskOrigin = - gunModelDefinition.mask === undefined - ? undefined - : gunModelDefinition.mask + hullOrigin.y + turretOrigin.y + gunOrigin.y; - const showPrimaryArmor = TankopediaPersistent.use( - (state) => state.showPrimaryArmor, - ); - const showSpacedArmor = TankopediaPersistent.use( - (state) => state.showSpacedArmor, - ); - const showExternalModules = TankopediaPersistent.use( - (state) => state.showExternalModules, - ); - const isDynamicArmorActive = Duel.use((state) => - state.protagonist.consumables.includes(73), - ); + // const wrapper = useRef(null); + // const turretContainer = useRef(null); + // const gunContainer = useRef(null); + // const protagonist = Duel.use((draft) => draft.protagonist); + // const tank = Duel.use((state) => state.protagonist.tank); + // const track = Duel.use((state) => state.protagonist.track); + // const turret = Duel.use((state) => state.protagonist.turret); + // const gun = Duel.use((state) => state.protagonist.gun); + // const { gltf: armorGltf } = useArmor(tank.id); + // const { gltf: modelGltf } = useModel(tank.id); + // const armorNodes = Object.values(armorGltf.nodes); + // const modelNodes = Object.values(modelGltf.nodes); + // const tankModelDefinition = useTankModelDefinition(); + // const trackModelDefinition = tankModelDefinition.tracks[track.id]; + // const turretModelDefinition = tankModelDefinition.turrets[turret.id]; + // const gunModelDefinition = + // turretModelDefinition.guns[gun.gun_type!.value.base.id]; + // const hullOrigin = correctZYTuple(trackModelDefinition.origin); + // const turretOrigin = correctZYTuple(tankModelDefinition.turret_origin); + // const gunOrigin = correctZYTuple(turretModelDefinition.gun_origin); + // const mutateDuel = Duel.useMutation(); + // const canvas = useThree((state) => state.gl.domElement); + // const mutateTankopediaEphemeral = TankopediaEphemeral.useMutation(); + // const duelStore = Duel.useStore(); + // const maskOrigin = + // gunModelDefinition.mask === undefined + // ? undefined + // : gunModelDefinition.mask + hullOrigin.y + turretOrigin.y + gunOrigin.y; + // const showPrimaryArmor = TankopediaPersistent.use( + // (state) => state.showPrimaryArmor, + // ); + // const showSpacedArmor = TankopediaPersistent.use( + // (state) => state.showSpacedArmor, + // ); + // const showExternalModules = TankopediaPersistent.use( + // (state) => state.showExternalModules, + // ); + // const isDynamicArmorActive = Duel.use((state) => + // state.protagonist.consumables.includes(73), + // ); - useTankTransform(track, turret, turretContainer, gunContainer); + // useTankTransform(track, turret, turretContainer, gunContainer); + + const tank = Duel.use((state) => state.protagonist.tank); + const armor = TankopediaEphemeral.use((state) => state.armor); + const hullArmor = armor.groups.hull; + const hullGltf = useGLTF(asset(`tanks/${tank.id}/collision/hull.glb`)); return ( - - - {armorNodes.map((node) => { - const isHull = node.name.startsWith('hull_'); - const isVisible = isHull; - const armorId = nameToArmorId(node.name); - const { spaced, thickness } = resolveArmor( - tankModelDefinition.armor, - armorId, - ); + + {jsxTree(hullGltf.scene, { + mesh(mesh) { + if (!(mesh.material instanceof Material)) { + return { visible: false }; + } - if ( - !isVisible || - thickness === undefined || - (!showPrimaryArmor && !spaced) || - (!showSpacedArmor && spaced) || - (isDynamicArmorActive && node.name.includes('state_00')) || - (!isDynamicArmorActive && node.name.includes('state_01')) - ) - return null; + const armorName = mesh.material.name; + const material = new MeshBasicMaterial({}); + const armorPlate = hullArmor.armors[armorName]; - return ( - event.stopPropagation()} - /> - ); - })} - + switch (armorPlate.type) { + case 'Armor': + material.color = new Color('#ec6142'); + material.transparent = true; + material.opacity = 0.5; + break; - {modelNodes.map((node) => { - const isWheel = node.name.startsWith('chassis_wheel_'); - const isTrack = node.name.startsWith('chassis_track_'); - const isVisible = isWheel || isTrack; + case 'ArmorScreen': + material.color = new Color('#ff8dcc'); + material.transparent = true; + material.opacity = 0.5; + break; - if (!isVisible || !showExternalModules) return null; + default: + material.color = new Color('#70b8ff'); + break; + } - return ( - event.stopPropagation()} - /> - ); + return { material }; + }, })} - - - {armorNodes.map((node) => { - const isCurrentTurret = node.name.startsWith( - `turret_${turretModelDefinition.model_id.toString().padStart(2, '0')}`, - ); - const isVisible = isCurrentTurret; - const armorId = nameToArmorId(node.name); - const { spaced, thickness } = resolveArmor( - turretModelDefinition.armor, - armorId, - ); - - if ( - !isVisible || - thickness === undefined || - (!showPrimaryArmor && !spaced) || - (!showSpacedArmor && spaced) || - (isDynamicArmorActive && node.name.includes('state_00')) || - (!isDynamicArmorActive && node.name.includes('state_01')) - ) { - return null; - } - - const position = new Vector2(); - const delta = new Vector2(); - let pitch = 0; - let yaw = 0; - - function onPointerDown(event: ThreeEvent) { - event.stopPropagation(); - - position.set(event.clientX, event.clientY); - yaw = protagonist.yaw; - pitch = protagonist.pitch; - - mutateTankopediaEphemeral((draft) => { - draft.controlsEnabled = false; - }); - mutateTankopediaEphemeral((draft) => { - draft.shot = undefined; - draft.highlightArmor = undefined; - }); - window.addEventListener('pointermove', handlePointerMove); - window.addEventListener('pointerup', handlePointerUp); - } - async function handlePointerMove(event: PointerEvent) { - const duel = duelStore.getState(); - const hasImprovedVerticalStabilizer = await hasEquipment( - 122, - duel.protagonist.tank.equipment_preset, - duel.protagonist.equipmentMatrix, - ); - const hasDownImprovedVerticalStabilizer = await hasEquipment( - 124, - duel.protagonist.tank.equipment_preset, - duel.protagonist.equipmentMatrix, - ); - const boundingRect = canvas.getBoundingClientRect(); - - delta.set(event.clientX, event.clientY).sub(position); - position.set(event.clientX, event.clientY); - - [pitch, yaw] = applyPitchYawLimits( - pitch, - yaw + delta.x * (Math.PI / boundingRect.width), - gunModelDefinition.pitch, - turretModelDefinition.yaw, - hasImprovedVerticalStabilizer, - hasDownImprovedVerticalStabilizer, - ); - modelTransformEvent.emit({ pitch, yaw }); - } - function handlePointerUp() { - mutateDuel((draft) => { - draft.protagonist.pitch = normalizeAngleRad(pitch); - draft.protagonist.yaw = normalizeAngleRad(yaw); - }); - mutateTankopediaEphemeral((draft) => { - draft.controlsEnabled = true; - }); - window.removeEventListener('pointermove', handlePointerMove); - window.removeEventListener('pointerup', handlePointerUp); - } - - return ( - - - - - - ); - })} - - - {armorNodes.map((node) => { - const isCurrentGun = node.name.startsWith( - `gun_${gunModelDefinition.model_id.toString().padStart(2, '0')}`, - ); - const isVisible = isCurrentGun; - const armorId = nameToArmorId(node.name); - const { spaced, thickness } = resolveArmor( - gunModelDefinition.armor, - armorId, - ); - - if ( - !isVisible || - thickness === undefined || - (!showPrimaryArmor && !spaced) || - (!showSpacedArmor && spaced) || - (isDynamicArmorActive && node.name.includes('state_00')) || - (!isDynamicArmorActive && node.name.includes('state_01')) - ) - return null; - - const position = new Vector2(); - const delta = new Vector2(); - let pitch = 0; - let yaw = 0; - - function onPointerDown(event: ThreeEvent) { - event.stopPropagation(); - - mutateTankopediaEphemeral((draft) => { - draft.controlsEnabled = false; - }); - mutateTankopediaEphemeral((draft) => { - draft.shot = undefined; - draft.highlightArmor = undefined; - }); - - position.set(event.clientX, event.clientY); - pitch = protagonist.pitch; - yaw = protagonist.yaw; - - window.addEventListener('pointermove', handlePointerMove); - window.addEventListener('pointerup', handlePointerUp); - } - async function handlePointerMove(event: PointerEvent) { - const duel = duelStore.getState(); - const hasImprovedVerticalStabilizer = await hasEquipment( - 122, - duel.protagonist.tank.equipment_preset, - duel.protagonist.equipmentMatrix, - ); - const hasDownImprovedVerticalStabilizer = await hasEquipment( - 124, - duel.protagonist.tank.equipment_preset, - duel.protagonist.equipmentMatrix, - ); - const boundingRect = canvas.getBoundingClientRect(); - delta.set(event.clientX, event.clientY).sub(position); - position.set(event.clientX, event.clientY); - - [pitch, yaw] = applyPitchYawLimits( - pitch - delta.y * (Math.PI / boundingRect.height), - yaw + delta.x * (Math.PI / boundingRect.width), - gunModelDefinition.pitch, - turretModelDefinition.yaw, - hasImprovedVerticalStabilizer, - hasDownImprovedVerticalStabilizer, - ); - modelTransformEvent.emit({ pitch, yaw }); - } - function handlePointerUp() { - mutateTankopediaEphemeral((draft) => { - draft.controlsEnabled = true; - }); - mutateDuel((draft) => { - draft.protagonist.pitch = normalizeAngleRad(pitch); - draft.protagonist.yaw = normalizeAngleRad(yaw); - }); - window.removeEventListener('pointermove', handlePointerMove); - window.removeEventListener('pointerup', handlePointerUp); - } - - return ( - - - - - - ); - })} - - {modelNodes.map((node) => { - const gunString = `gun_${gunModelDefinition.model_id - .toString() - .padStart(2, '0')}`; - const isCurrentGun = gunModelDefinition.mask - ? node.name.startsWith(gunString) - : node.name === gunString; - const isVisible = isCurrentGun; - - if (!isVisible || !showExternalModules) return null; - - const position = new Vector2(); - const delta = new Vector2(); - let pitch = 0; - let yaw = 0; - - function onPointerDown(event: ThreeEvent) { - event.stopPropagation(); - - mutateTankopediaEphemeral((draft) => { - draft.controlsEnabled = false; - }); - mutateTankopediaEphemeral((draft) => { - draft.shot = undefined; - draft.highlightArmor = undefined; - }); - - position.set(event.clientX, event.clientY); - pitch = protagonist.pitch; - yaw = protagonist.yaw; - - window.addEventListener('pointermove', handlePointerMove); - window.addEventListener('pointerup', handlePointerUp); - } - async function handlePointerMove(event: PointerEvent) { - const duel = duelStore.getState(); - const hasImprovedVerticalStabilizer = await hasEquipment( - 122, - duel.protagonist.tank.equipment_preset, - duel.protagonist.equipmentMatrix, - ); - const hasDownImprovedVerticalStabilizer = await hasEquipment( - 124, - duel.protagonist.tank.equipment_preset, - duel.protagonist.equipmentMatrix, - ); - const boundingRect = canvas.getBoundingClientRect(); - delta.set(event.clientX, event.clientY).sub(position); - position.set(event.clientX, event.clientY); - - [pitch, yaw] = applyPitchYawLimits( - pitch - delta.y * (Math.PI / boundingRect.height), - yaw + delta.x * (Math.PI / boundingRect.width), - gunModelDefinition.pitch, - turretModelDefinition.yaw, - hasImprovedVerticalStabilizer, - hasDownImprovedVerticalStabilizer, - ); - modelTransformEvent.emit({ pitch, yaw }); - } - function handlePointerUp() { - mutateTankopediaEphemeral((draft) => { - draft.controlsEnabled = true; - }); - mutateDuel((draft) => { - draft.protagonist.pitch = normalizeAngleRad(pitch); - draft.protagonist.yaw = normalizeAngleRad(yaw); - }); - window.removeEventListener('pointermove', handlePointerMove); - window.removeEventListener('pointerup', handlePointerUp); - } - - return ( - - ); - })} - - - + ); }); diff --git a/packages/website/src/components/SmallTankIcon.tsx b/packages/website/src/components/SmallTankIcon.tsx index 9bf36d757..fc6f6b35b 100644 --- a/packages/website/src/components/SmallTankIcon.tsx +++ b/packages/website/src/components/SmallTankIcon.tsx @@ -1,7 +1,7 @@ import { asset } from '@blitzkit/core'; interface SmallTankIconProps { - id: number; + id: string; size?: number; } @@ -19,7 +19,7 @@ export function SmallTankIcon({ id, size = HEIGHT }: SmallTankIconProps) { > {`Tank & { compact?: boolean; - onSelect?: (tank: TankDefinition) => void; - onSelectAll?: (tanks: TankDefinition[]) => void; + onSelect?: (tank: Tank) => void; + onSelectAll?: (tanks: Tank[]) => void; }; const PREVIEW_COUNT = 20; diff --git a/packages/website/src/components/Tankopedia/HeroSection/components/Options/components/QuickInputs/index.tsx b/packages/website/src/components/Tankopedia/HeroSection/components/Options/components/QuickInputs/index.tsx index 83867a4b0..d6c68bb9e 100644 --- a/packages/website/src/components/Tankopedia/HeroSection/components/Options/components/QuickInputs/index.tsx +++ b/packages/website/src/components/Tankopedia/HeroSection/components/Options/components/QuickInputs/index.tsx @@ -18,28 +18,28 @@ export function QuickInputs() { const yawInput = useRef(null); const pitchInput = useRef(null); const tankModelDefinition = useTankModelDefinition(); - const turretModelDefinition = - tankModelDefinition.turrets[protagonist.turret.id]; - const gunModelDefinition = - turretModelDefinition.guns[protagonist.gun.gun_type!.value.base.id]; + // const turretModelDefinition = + // tankModelDefinition.turrets[protagonist.turret.id]; + // const gunModelDefinition = + // turretModelDefinition.guns[protagonist.gun.gun_type!.value.base.id]; const initialGunPitch = tankModelDefinition.initial_turret_rotation?.pitch ?? 0; const hasImprovedVerticalStabilizer = useEquipment(122); const hasDownImprovedVerticalStabilizer = useEquipment(124); - useEffect(() => { - if (!yawInput.current) return; + // useEffect(() => { + // if (!yawInput.current) return; - yawInput.current.value = radToDeg(protagonist.yaw).toFixed(1); - }, [protagonist.yaw]); + // yawInput.current.value = radToDeg(protagonist.yaw).toFixed(1); + // }, [protagonist.yaw]); - useEffect(() => { - if (!pitchInput.current) return; + // useEffect(() => { + // if (!pitchInput.current) return; - pitchInput.current.value = ( - -radToDeg(protagonist.pitch) + initialGunPitch - ).toFixed(1); - }, [protagonist.pitch]); + // pitchInput.current.value = ( + // -radToDeg(protagonist.pitch) + initialGunPitch + // ).toFixed(1); + // }, [protagonist.pitch]); useEffect(() => { function handleTransformEvent({ pitch, yaw }: ModelTransformEventData) { diff --git a/packages/website/src/components/Tankopedia/HeroSection/components/Options/components/Thicknesses.tsx b/packages/website/src/components/Tankopedia/HeroSection/components/Options/components/Thicknesses.tsx index 1c0333408..9d640754a 100644 --- a/packages/website/src/components/Tankopedia/HeroSection/components/Options/components/Thicknesses.tsx +++ b/packages/website/src/components/Tankopedia/HeroSection/components/Options/components/Thicknesses.tsx @@ -1,12 +1,10 @@ import { literals } from '@blitzkit/i18n/src/literals'; import { EyeClosedIcon, EyeOpenIcon, ReloadIcon } from '@radix-ui/react-icons'; import { Button, Checkbox, Flex, Text } from '@radix-ui/themes'; -import { Suspense } from 'react'; import { useLocale } from '../../../../../../hooks/useLocale'; import { TankopediaEphemeral } from '../../../../../../stores/tankopediaEphemeral'; import { TankopediaPersistent } from '../../../../../../stores/tankopediaPersistent'; import type { ThicknessRange } from '../../../../../Armor/components/StaticArmor'; -import { DynamicArmorSwitcher } from './DynamicArmorSwitcher'; interface ThicknessesProps { thicknessRange: ThicknessRange; @@ -190,9 +188,9 @@ export function Thicknesses({ thicknessRange }: ThicknessesProps) { - + {/* - + */} ); } diff --git a/packages/website/src/components/Tankopedia/HeroSection/components/Options/index.tsx b/packages/website/src/components/Tankopedia/HeroSection/components/Options/index.tsx index 213bde9d9..5f412c645 100644 --- a/packages/website/src/components/Tankopedia/HeroSection/components/Options/index.tsx +++ b/packages/website/src/components/Tankopedia/HeroSection/components/Options/index.tsx @@ -1,37 +1,6 @@ -import { - asset, - imgur, - resolvePenetrationCoefficient, - TIER_ROMAN_NUMERALS, - uniqueGuns, -} from '@blitzkit/core'; -import { literals } from '@blitzkit/i18n/src/literals'; -import { - CameraIcon, - CopyIcon, - DownloadIcon, - EnterFullScreenIcon, - ExitFullScreenIcon, - EyeOpenIcon, - GearIcon, -} from '@radix-ui/react-icons'; -import { - Box, - Button, - Checkbox, - Dialog, - DropdownMenu, - Flex, - IconButton, - Popover, - SegmentedControl, - Tabs, - Text, - Tooltip, -} from '@radix-ui/themes'; -import { Suspense, useState, type RefObject } from 'react'; -import { Pose, poseEvent } from '../../../../../core/blitzkit/pose'; -import { useEquipment } from '../../../../../hooks/useEquipment'; +import { imgur } from '@blitzkit/core'; +import { Box, Flex, SegmentedControl, Tooltip } from '@radix-ui/themes'; +import { useState, type RefObject } from 'react'; import { useFullScreen } from '../../../../../hooks/useFullScreen'; import { useFullscreenAvailability } from '../../../../../hooks/useFullscreenAvailability'; import { useLocale } from '../../../../../hooks/useLocale'; @@ -44,12 +13,6 @@ import { import { TankopediaPersistent } from '../../../../../stores/tankopediaPersistent'; import { TankopediaDisplay } from '../../../../../stores/tankopediaPersistent/constants'; import type { ThicknessRange } from '../../../../Armor/components/StaticArmor'; -import { ModuleButton } from '../../../../ModuleButtons/ModuleButton'; -import { SmallTankIcon } from '../../../../SmallTankIcon'; -import { TankSearch } from '../../../../TankSearch'; -import { CustomShellButton } from './components/CustomShellButton'; -import { DynamicArmorSwitcher } from './components/DynamicArmorSwitcher'; -import { QuickInputs } from './components/QuickInputs'; import { Thicknesses } from './components/Thicknesses'; interface OptionsProps { @@ -78,22 +41,22 @@ export function Options({ thicknessRange, canvas }: OptionsProps) { const fullScreenAvailable = useFullscreenAvailability(); const developerMode = App.use((state) => state.developerMode); const protagonistTank = Duel.use((state) => state.protagonist.tank); - const antagonistGun = Duel.use((state) => state.antagonist.gun); - const antagonistShell = Duel.use((state) => state.antagonist.shell); + // const antagonistGun = Duel.use((state) => state.antagonist.gun); + // const antagonistShell = Duel.use((state) => state.antagonist.shell); const [antagonistSelectorOpen, setAntagonistSelectorOpen] = useState(false); const antagonistTank = Duel.use((state) => state.antagonist.tank); - const hasCalibratedShells = useEquipment(103, true); + // const hasCalibratedShells = useEquipment(103, true); const [tab, setTab] = useState('search'); const mutateDuel = Duel.useMutation(); - const hasEnhancedArmor = useEquipment(110); - const antagonistUniqueGuns = uniqueGuns(antagonistTank.turrets); + // const hasEnhancedArmor = useEquipment(110); + // const antagonistUniqueGuns = uniqueGuns(antagonistTank.turrets); const mutateTankopediaPersistent = TankopediaPersistent.useMutation(); const mutateTankopediaEphemeral = TankopediaEphemeral.useMutation(); const { strings, unwrap } = useLocale(); return ( <> - + {/* */} {display === TankopediaDisplay.ShootingRange && ( )} - {display === TankopediaDisplay.DynamicArmor && ( + {/* {display === TankopediaDisplay.DynamicArmor && ( )} + {antagonistUniqueGuns.length > 1 && ( @@ -215,6 +179,8 @@ export function Options({ thicknessRange, canvas }: OptionsProps) { )} + + - )} + )} */} - {display === TankopediaDisplay.DynamicArmor && ( + {/* {display === TankopediaDisplay.DynamicArmor && ( <> { mutateDuel((draft) => { draft.antagonist.tank = tank; - draft.antagonist.engine = tank.engines.at(-1)!; - draft.antagonist.track = tank.tracks.at(-1)!; - draft.antagonist.turret = tank.turrets.at(-1)!; - draft.antagonist.gun = - draft.antagonist.turret.guns.at(-1)!; - draft.antagonist.shell = - draft.antagonist.gun.gun_type!.value.base.shells[0]; + // draft.antagonist.engine = tank.engines.at(-1)!; + // draft.antagonist.track = tank.tracks.at(-1)!; + // draft.antagonist.turret = tank.turrets.at(-1)!; + // draft.antagonist.gun = + // draft.antagonist.turret.guns.at(-1)!; + // draft.antagonist.shell = + // draft.antagonist.gun.gun_type!.value.base.shells[0]; }); setAntagonistSelectorOpen(false); }} @@ -396,7 +362,8 @@ export function Options({ thicknessRange, canvas }: OptionsProps) { - )} + )} */} + */} - + {/* @@ -461,9 +428,9 @@ export function Options({ thicknessRange, canvas }: OptionsProps) { {strings.website.tools.tanks.sandbox.poses.default} - + */} - + {/* @@ -549,9 +516,9 @@ export function Options({ thicknessRange, canvas }: OptionsProps) { {strings.website.tools.tanks.sandbox.settings.show_grid} - + */} - + {/* @@ -603,9 +570,9 @@ export function Options({ thicknessRange, canvas }: OptionsProps) { - + */} - {fullScreenAvailable && ( + {/* {fullScreenAvailable && ( {isFullScreen ? : } - )} + )} */} diff --git a/packages/website/src/components/Tankopedia/HeroSection/components/TankSandbox/components/Control.tsx b/packages/website/src/components/Tankopedia/HeroSection/components/TankSandbox/components/Control.tsx index 67808f69a..1b4bdc593 100644 --- a/packages/website/src/components/Tankopedia/HeroSection/components/TankSandbox/components/Control.tsx +++ b/packages/website/src/components/Tankopedia/HeroSection/components/TankSandbox/components/Control.tsx @@ -1,22 +1,14 @@ import { OrbitControls } from '@react-three/drei'; -import { invalidate, useThree } from '@react-three/fiber'; -import { clamp } from 'lodash-es'; -import { useEffect, useRef, useState } from 'react'; -import { PerspectiveCamera, Vector3 } from 'three'; +import { useThree } from '@react-three/fiber'; +import { useRef, useState } from 'react'; +import { PerspectiveCamera } from 'three'; import { OrbitControls as OrbitControlsClass } from 'three-stdlib'; import { degToRad } from 'three/src/math/MathUtils.js'; import { awaitableModelDefinitions } from '../../../../../../core/awaitables/modelDefinitions'; -import { applyPitchYawLimits } from '../../../../../../core/blitz/applyPitchYawLimits'; -import { hasEquipment } from '../../../../../../core/blitzkit/hasEquipment'; -import { Pose, poseEvent } from '../../../../../../core/blitzkit/pose'; +import { Pose } from '../../../../../../core/blitzkit/pose'; import { Duel } from '../../../../../../stores/duel'; -import { - SHOOTING_RANGE_ZOOM_COEFFICIENTS, - ShootingRangeZoom, - TankopediaEphemeral, -} from '../../../../../../stores/tankopediaEphemeral'; +import { TankopediaEphemeral } from '../../../../../../stores/tankopediaEphemeral'; import { TankopediaDisplay } from '../../../../../../stores/tankopediaPersistent/constants'; -import { aimTarget } from './SceneProps/constants'; const poseDistances: Record = { [Pose.HullDown]: 15, @@ -43,302 +35,302 @@ export function Controls({ naked }: ControlsProps) { const camera = useThree((state) => state.camera as PerspectiveCamera); const canvas = useThree((state) => state.gl.domElement); const orbitControls = useRef(null); - const protagonistTurret = Duel.use((state) => state.protagonist.turret); - const antagonistTurret = Duel.use((state) => state.antagonist.turret); - const protagonistTrack = Duel.use((state) => state.protagonist.track); + // const protagonistTurret = Duel.use((state) => state.protagonist.turret); + // const antagonistTurret = Duel.use((state) => state.antagonist.turret); + // const protagonistTrack = Duel.use((state) => state.protagonist.track); const protagonistTank = Duel.use((state) => state.protagonist.tank); - const antagonistTank = Duel.use((state) => state.antagonist.tank); - const protagonistGun = Duel.use((state) => state.protagonist.gun); - const protagonistModelDefinition = - modelDefinitions.models[protagonistTank.id]; - const protagonistTrackModelDefinition = - modelDefinitions.models[protagonistTank.id].tracks[protagonistTrack.id]; - const antagonistModelDefinition = modelDefinitions.models[antagonistTank.id]; - const protagonistTurretModelDefinition = - protagonistModelDefinition.turrets[protagonistTurret.id]; - const antagonistTurretModelDefinition = - antagonistModelDefinition.turrets[antagonistTurret.id]; - const protagonistGunModelDefinition = - protagonistTurretModelDefinition.guns[ - protagonistGun.gun_type!.value.base.id - ]; - const protagonistHullOrigin = new Vector3( - protagonistTrackModelDefinition.origin.x, - protagonistTrackModelDefinition.origin.y, - -protagonistTrackModelDefinition.origin.z, - ); - const protagonistTurretOrigin = new Vector3( - protagonistModelDefinition.turret_origin.x, - protagonistModelDefinition.turret_origin.y, - -protagonistModelDefinition.turret_origin.z, - ); - const protagonistGunOrigin = new Vector3( - protagonistTurretModelDefinition.gun_origin.x, - protagonistTurretModelDefinition.gun_origin.y, - -protagonistTurretModelDefinition.gun_origin.z, - ); - const antagonistGunHeight = - protagonistTrackModelDefinition.origin.y + - antagonistModelDefinition.turret_origin.y + - antagonistTurretModelDefinition.gun_origin.y; + // const antagonistTank = Duel.use((state) => state.antagonist.tank); + // const protagonistGun = Duel.use((state) => state.protagonist.gun); + // const protagonistModelDefinition = + // modelDefinitions.models[protagonistTank.id]; + // const protagonistTrackModelDefinition = + // modelDefinitions.models[protagonistTank.id].tracks[protagonistTrack.id]; + // const antagonistModelDefinition = modelDefinitions.models[antagonistTank.id]; + // const protagonistTurretModelDefinition = + // protagonistModelDefinition.turrets[protagonistTurret.id]; + // const antagonistTurretModelDefinition = + // antagonistModelDefinition.turrets[antagonistTurret.id]; + // const protagonistGunModelDefinition = + // protagonistTurretModelDefinition.guns[ + // protagonistGun.gun_type!.value.base.id + // ]; + // const protagonistHullOrigin = new Vector3( + // protagonistTrackModelDefinition.origin.x, + // protagonistTrackModelDefinition.origin.y, + // -protagonistTrackModelDefinition.origin.z, + // ); + // const protagonistTurretOrigin = new Vector3( + // protagonistModelDefinition.turret_origin.x, + // protagonistModelDefinition.turret_origin.y, + // -protagonistModelDefinition.turret_origin.z, + // ); + // const protagonistGunOrigin = new Vector3( + // protagonistTurretModelDefinition.gun_origin.x, + // protagonistTurretModelDefinition.gun_origin.y, + // -protagonistTurretModelDefinition.gun_origin.z, + // ); + // const antagonistGunHeight = + // protagonistTrackModelDefinition.origin.y + + // antagonistModelDefinition.turret_origin.y + + // antagonistTurretModelDefinition.gun_origin.y; const [autoRotate, setAutoRotate] = useState( display !== TankopediaDisplay.ShootingRange && !naked, ); - const gunHeight = - protagonistHullOrigin.y + - protagonistTurretOrigin.y + - protagonistGunOrigin.y; - const inspectModeInitialPosition = [ - -8, - gunHeight + (naked ? 10 : 4), - -13, - ] as const; - const protagonistGunOriginOnlyY = new Vector3( - 0, - protagonistTurretModelDefinition.gun_origin.y, - 0, - ); - const shellOrigin = protagonistHullOrigin - .clone() - .add(protagonistTurretOrigin) - .add(protagonistGunOriginOnlyY); + // const gunHeight = + // protagonistHullOrigin.y + + // protagonistTurretOrigin.y + + // protagonistGunOrigin.y; + // const inspectModeInitialPosition = [ + // -8, + // gunHeight + (naked ? 10 : 4), + // -13, + // ] as const; + // const protagonistGunOriginOnlyY = new Vector3( + // 0, + // protagonistTurretModelDefinition.gun_origin.y, + // 0, + // ); + // const shellOrigin = protagonistHullOrigin + // .clone() + // .add(protagonistTurretOrigin) + // .add(protagonistGunOriginOnlyY); - useEffect(() => { - const unsubscribeTankopediaEphemeral = tankopediaEphemeralStore.subscribe( - (state) => state.controlsEnabled, - (enabled) => { - if (orbitControls.current) orbitControls.current.enabled = enabled; - }, - ); + // useEffect(() => { + // const unsubscribeTankopediaEphemeral = tankopediaEphemeralStore.subscribe( + // (state) => state.controlsEnabled, + // (enabled) => { + // if (orbitControls.current) orbitControls.current.enabled = enabled; + // }, + // ); - async function handlePoseEvent(event: Pose) { - const duel = duelStore.getState(); - const hasImprovedVerticalStabilizer = await hasEquipment( - 122, - duel.protagonist.tank.equipment_preset, - duel.protagonist.equipmentMatrix, - ); - const hasDownImprovedVerticalStabilizer = await hasEquipment( - 124, - duel.protagonist.tank.equipment_preset, - duel.protagonist.equipmentMatrix, - ); + // async function handlePoseEvent(event: Pose) { + // const duel = duelStore.getState(); + // const hasImprovedVerticalStabilizer = await hasEquipment( + // 122, + // duel.protagonist.tank.equipment_preset, + // duel.protagonist.equipmentMatrix, + // ); + // const hasDownImprovedVerticalStabilizer = await hasEquipment( + // 124, + // duel.protagonist.tank.equipment_preset, + // duel.protagonist.equipmentMatrix, + // ); - switch (event) { - case Pose.HullDown: { - const [pitch] = applyPitchYawLimits( - -Infinity, - 0, - protagonistGunModelDefinition.pitch, - protagonistTurretModelDefinition.yaw, - hasImprovedVerticalStabilizer, - hasDownImprovedVerticalStabilizer, - ); + // switch (event) { + // case Pose.HullDown: { + // const [pitch] = applyPitchYawLimits( + // -Infinity, + // 0, + // protagonistGunModelDefinition.pitch, + // protagonistTurretModelDefinition.yaw, + // hasImprovedVerticalStabilizer, + // hasDownImprovedVerticalStabilizer, + // ); - camera.position - .set(0, 0, 0) - .add(protagonistHullOrigin) - .add(protagonistTurretOrigin) - .add(protagonistGunOrigin) - .add( - new Vector3( - 0, - poseDistances[event] * Math.sin(pitch), - poseDistances[event] * -Math.cos(pitch), - ), - ); - camera.lookAt( - protagonistHullOrigin - .clone() - .add(protagonistTurretOrigin) - .add(protagonistGunOrigin), - ); - orbitControls.current?.target.set(0, antagonistGunHeight, 0); + // camera.position + // .set(0, 0, 0) + // .add(protagonistHullOrigin) + // .add(protagonistTurretOrigin) + // .add(protagonistGunOrigin) + // .add( + // new Vector3( + // 0, + // poseDistances[event] * Math.sin(pitch), + // poseDistances[event] * -Math.cos(pitch), + // ), + // ); + // camera.lookAt( + // protagonistHullOrigin + // .clone() + // .add(protagonistTurretOrigin) + // .add(protagonistGunOrigin), + // ); + // orbitControls.current?.target.set(0, antagonistGunHeight, 0); - break; - } + // break; + // } - case Pose.FaceHug: { - const [pitch] = applyPitchYawLimits( - 0, - 0, - protagonistGunModelDefinition.pitch, - protagonistTurretModelDefinition.yaw, - hasImprovedVerticalStabilizer, - hasDownImprovedVerticalStabilizer, - ); + // case Pose.FaceHug: { + // const [pitch] = applyPitchYawLimits( + // 0, + // 0, + // protagonistGunModelDefinition.pitch, + // protagonistTurretModelDefinition.yaw, + // hasImprovedVerticalStabilizer, + // hasDownImprovedVerticalStabilizer, + // ); - camera.position - .set(0, 0, 0) - .add(protagonistHullOrigin) - .add(protagonistTurretOrigin) - .add(protagonistGunOrigin) - .add( - new Vector3( - 0, - poseDistances[event] * Math.sin(pitch), - poseDistances[event] * -Math.cos(pitch), - ), - ); - orbitControls.current?.target - .set(0, 0, 0) - .add(protagonistHullOrigin) - .add(protagonistTurretOrigin) - .add(protagonistGunOrigin) - .add( - new Vector3( - 0, - 0.5 * poseDistances[event] * Math.sin(pitch), - 0.5 * poseDistances[event] * -Math.cos(pitch), - ), - ); + // camera.position + // .set(0, 0, 0) + // .add(protagonistHullOrigin) + // .add(protagonistTurretOrigin) + // .add(protagonistGunOrigin) + // .add( + // new Vector3( + // 0, + // poseDistances[event] * Math.sin(pitch), + // poseDistances[event] * -Math.cos(pitch), + // ), + // ); + // orbitControls.current?.target + // .set(0, 0, 0) + // .add(protagonistHullOrigin) + // .add(protagonistTurretOrigin) + // .add(protagonistGunOrigin) + // .add( + // new Vector3( + // 0, + // 0.5 * poseDistances[event] * Math.sin(pitch), + // 0.5 * poseDistances[event] * -Math.cos(pitch), + // ), + // ); - break; - } + // break; + // } - case Pose.Default: { - camera.position.set(...inspectModeInitialPosition); - orbitControls.current?.target.set(0, 1.25, 0); - break; - } - } + // case Pose.Default: { + // camera.position.set(...inspectModeInitialPosition); + // orbitControls.current?.target.set(0, 1.25, 0); + // break; + // } + // } - invalidate(); - } + // invalidate(); + // } - poseEvent.on(handlePoseEvent); + // poseEvent.on(handlePoseEvent); - return () => { - unsubscribeTankopediaEphemeral(); - poseEvent.off(handlePoseEvent); - }; - }, [camera, protagonistTank.id, antagonistTank.id]); + // return () => { + // unsubscribeTankopediaEphemeral(); + // poseEvent.off(handlePoseEvent); + // }; + // }, [camera, protagonistTank.id, antagonistTank.id]); - useEffect(() => { - let isInitialIteration = true; + // useEffect(() => { + // let isInitialIteration = true; - function handleDisturbance() { - setAutoRotate(false); - } + // function handleDisturbance() { + // setAutoRotate(false); + // } - function handleKeyDown(event: KeyboardEvent) { - if (display !== TankopediaDisplay.ShootingRange || event.repeat) return; + // function handleKeyDown(event: KeyboardEvent) { + // if (display !== TankopediaDisplay.ShootingRange || event.repeat) return; - if (event.key === 'Shift') { - mutateTankopediaEphemeral((draft) => { - draft.shootingRangeZoom = - draft.shootingRangeZoom === ShootingRangeZoom.Arcade - ? ShootingRangeZoom.Zoom0 - : ShootingRangeZoom.Arcade; - }); - } - } + // if (event.key === 'Shift') { + // mutateTankopediaEphemeral((draft) => { + // draft.shootingRangeZoom = + // draft.shootingRangeZoom === ShootingRangeZoom.Arcade + // ? ShootingRangeZoom.Zoom0 + // : ShootingRangeZoom.Arcade; + // }); + // } + // } - function handleWheel(event: WheelEvent) { - if (display !== TankopediaDisplay.ShootingRange) return; + // function handleWheel(event: WheelEvent) { + // if (display !== TankopediaDisplay.ShootingRange) return; - event.preventDefault(); + // event.preventDefault(); - mutateTankopediaEphemeral((draft) => { - draft.shootingRangeZoom = clamp( - draft.shootingRangeZoom - Math.sign(event.deltaY), - ShootingRangeZoom.Arcade, - ShootingRangeZoom.Zoom2, - ); - }); - } + // mutateTankopediaEphemeral((draft) => { + // draft.shootingRangeZoom = clamp( + // draft.shootingRangeZoom - Math.sign(event.deltaY), + // ShootingRangeZoom.Arcade, + // ShootingRangeZoom.Zoom2, + // ); + // }); + // } - function handleScroll(event: Event) { - if (display !== TankopediaDisplay.ShootingRange) return; + // function handleScroll(event: Event) { + // if (display !== TankopediaDisplay.ShootingRange) return; - event.preventDefault(); - } + // event.preventDefault(); + // } - poseEvent.on(handleDisturbance); - canvas.addEventListener('pointerdown', handleDisturbance); - window.addEventListener('keydown', handleKeyDown); - canvas.addEventListener('wheel', handleWheel); - document.body.addEventListener('scroll', handleScroll); + // poseEvent.on(handleDisturbance); + // canvas.addEventListener('pointerdown', handleDisturbance); + // window.addEventListener('keydown', handleKeyDown); + // canvas.addEventListener('wheel', handleWheel); + // document.body.addEventListener('scroll', handleScroll); - function updateCamera() { - if (!orbitControls.current) return; + // function updateCamera() { + // if (!orbitControls.current) return; - orbitControls.current.rotateSpeed = 0.25; + // orbitControls.current.rotateSpeed = 0.25; - if (display === TankopediaDisplay.ShootingRange) { - const { shootingRangeZoom } = tankopediaEphemeralStore.getState(); + // if (display === TankopediaDisplay.ShootingRange) { + // const { shootingRangeZoom } = tankopediaEphemeralStore.getState(); - orbitControls.current.enablePan = false; - orbitControls.current.enableZoom = false; - orbitControls.current.rotateSpeed *= - SHOOTING_RANGE_ZOOM_COEFFICIENTS[shootingRangeZoom]; - camera.fov = - ARCADE_MODE_FOV * SHOOTING_RANGE_ZOOM_COEFFICIENTS[shootingRangeZoom]; + // orbitControls.current.enablePan = false; + // orbitControls.current.enableZoom = false; + // orbitControls.current.rotateSpeed *= + // SHOOTING_RANGE_ZOOM_COEFFICIENTS[shootingRangeZoom]; + // camera.fov = + // ARCADE_MODE_FOV * SHOOTING_RANGE_ZOOM_COEFFICIENTS[shootingRangeZoom]; - if (shootingRangeZoom === ShootingRangeZoom.Arcade) { - orbitControls.current.target.set(0, gunHeight + 3, 0); + // if (shootingRangeZoom === ShootingRangeZoom.Arcade) { + // orbitControls.current.target.set(0, gunHeight + 3, 0); - if (isInitialIteration) { - isInitialIteration = false; - camera.position.set( - 0, - gunHeight + ARCADE_MODE_DISTANCE * Math.sin(ARCADE_MODE_ANGLE), - ARCADE_MODE_DISTANCE * Math.cos(ARCADE_MODE_ANGLE), - ); - } else { - camera.position - .copy(aimTarget) - .sub(orbitControls.current.target) - .normalize() - .multiplyScalar(-ARCADE_MODE_DISTANCE) - .add(orbitControls.current.target); - } - } else { - orbitControls.current.target.copy(shellOrigin); + // if (isInitialIteration) { + // isInitialIteration = false; + // camera.position.set( + // 0, + // gunHeight + ARCADE_MODE_DISTANCE * Math.sin(ARCADE_MODE_ANGLE), + // ARCADE_MODE_DISTANCE * Math.cos(ARCADE_MODE_ANGLE), + // ); + // } else { + // camera.position + // .copy(aimTarget) + // .sub(orbitControls.current.target) + // .normalize() + // .multiplyScalar(-ARCADE_MODE_DISTANCE) + // .add(orbitControls.current.target); + // } + // } else { + // orbitControls.current.target.copy(shellOrigin); - camera.position - .copy(aimTarget) - .sub(shellOrigin) - .normalize() - .multiplyScalar(-Number.EPSILON) - .add(shellOrigin); - } - } else { - camera.position.set(...inspectModeInitialPosition); - orbitControls.current.target.set(0, gunHeight / (naked ? 4 : 2), 0); - orbitControls.current.enablePan = true; - orbitControls.current.enableZoom = true; - camera.fov = naked ? 20 : 25; - } + // camera.position + // .copy(aimTarget) + // .sub(shellOrigin) + // .normalize() + // .multiplyScalar(-Number.EPSILON) + // .add(shellOrigin); + // } + // } else { + // camera.position.set(...inspectModeInitialPosition); + // orbitControls.current.target.set(0, gunHeight / (naked ? 4 : 2), 0); + // orbitControls.current.enablePan = true; + // orbitControls.current.enableZoom = true; + // camera.fov = naked ? 20 : 25; + // } - camera.updateProjectionMatrix(); - } + // camera.updateProjectionMatrix(); + // } - updateCamera(); + // updateCamera(); - const unsubscribeDisplay = tankopediaEphemeralStore.subscribe( - (state) => state.display, - () => { - handleDisturbance(); - updateCamera(); - }, - ); + // const unsubscribeDisplay = tankopediaEphemeralStore.subscribe( + // (state) => state.display, + // () => { + // handleDisturbance(); + // updateCamera(); + // }, + // ); - const unsubscribeShootingRangeZoom = tankopediaEphemeralStore.subscribe( - (state) => state.shootingRangeZoom, - updateCamera, - ); + // const unsubscribeShootingRangeZoom = tankopediaEphemeralStore.subscribe( + // (state) => state.shootingRangeZoom, + // updateCamera, + // ); - return () => { - canvas.removeEventListener('pointerdown', handleDisturbance); - poseEvent.off(handleDisturbance); - unsubscribeDisplay(); - unsubscribeShootingRangeZoom(); - window.removeEventListener('keydown', handleKeyDown); - canvas.removeEventListener('wheel', handleWheel); - document.body.removeEventListener('scroll', handleScroll); - }; - }, [display === TankopediaDisplay.ShootingRange]); + // return () => { + // canvas.removeEventListener('pointerdown', handleDisturbance); + // poseEvent.off(handleDisturbance); + // unsubscribeDisplay(); + // unsubscribeShootingRangeZoom(); + // window.removeEventListener('keydown', handleKeyDown); + // canvas.removeEventListener('wheel', handleWheel); + // document.body.removeEventListener('scroll', handleScroll); + // }; + // }, [display === TankopediaDisplay.ShootingRange]); return ( state.protagonist); const display = TankopediaEphemeral.use((state) => state.display); - const { hasPbr } = useModel(protagonist.tank.id); - const isBrighterLighting = - !hasPbr && display !== TankopediaDisplay.StaticArmor; + const isBrighterLighting = display !== TankopediaDisplay.StaticArmor; return ( <> diff --git a/packages/website/src/components/Tankopedia/HeroSection/components/TankSandbox/components/SceneProps/index.tsx b/packages/website/src/components/Tankopedia/HeroSection/components/TankSandbox/components/SceneProps/index.tsx index afcff80e4..c742b8567 100644 --- a/packages/website/src/components/Tankopedia/HeroSection/components/TankSandbox/components/SceneProps/index.tsx +++ b/packages/website/src/components/Tankopedia/HeroSection/components/TankSandbox/components/SceneProps/index.tsx @@ -1,29 +1,13 @@ -import { asset, I_HAT, imgur, J_HAT } from '@blitzkit/core'; -import { Html } from '@react-three/drei'; +import { imgur } from '@blitzkit/core'; import { useFrame, useLoader } from '@react-three/fiber'; import { clamp } from 'lodash-es'; import { useRef } from 'react'; -import { - Group, - MeshStandardMaterial, - PerspectiveCamera, - TextureLoader, - Vector2, - Vector3, -} from 'three'; -import { GLTFLoader } from 'three/examples/jsm/Addons.js'; -import { degToRad, radToDeg } from 'three/src/math/MathUtils.js'; +import { MeshStandardMaterial, TextureLoader, Vector2 } from 'three'; import { awaitableEquipmentDefinitions } from '../../../../../../../core/awaitables/equipmentDefinitions'; import { awaitableModelDefinitions } from '../../../../../../../core/awaitables/modelDefinitions'; 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 { Duel } from '../../../../../../../stores/duel'; import { TankopediaEphemeral } from '../../../../../../../stores/tankopediaEphemeral'; import { TankopediaDisplay } from '../../../../../../../stores/tankopediaPersistent/constants'; -import { TargetCircle } from './components/TargetCircle'; -import { aimTarget } from './constants'; const [modelDefinitions, equipmentDefinitions, provisionDefinitions] = await Promise.all([ @@ -35,203 +19,203 @@ const [modelDefinitions, equipmentDefinitions, provisionDefinitions] = const emptyVector = new Vector2(); export function SceneProps() { - const targetCircleWrapper = useRef(null); - const clientTargetCircle = useRef(null); - const serverTargetCircle = useRef(null); + // const targetCircleWrapper = useRef(null); + // const clientTargetCircle = useRef(null); + // const serverTargetCircle = useRef(null); const material = useRef(null); - const playground = useRef(null); + // const playground = useRef(null); - let lastPitch = Duel.use((state) => state.protagonist.pitch); - let lastYaw = Duel.use((state) => state.protagonist.yaw); + // let lastPitch = Duel.use((state) => state.protagonist.pitch); + // let lastYaw = Duel.use((state) => state.protagonist.yaw); const display = TankopediaEphemeral.use((state) => state.display); - const turret = Duel.use((state) => state.protagonist.turret); - const track = Duel.use((state) => state.protagonist.track); - const tank = Duel.use((state) => state.protagonist.tank); - const gun = Duel.use((state) => state.protagonist.gun); - const shell = Duel.use((state) => state.protagonist.shell); - const engine = Duel.use((state) => state.protagonist.engine); - const tankModelDefinition = modelDefinitions.models[tank.id]; - const trackModelDefinition = - modelDefinitions.models[tank.id].tracks[track.id]; - const gunModelDefinition = - tankModelDefinition.turrets[turret.id].guns[gun.gun_type!.value.base.id]; - const turretModelDefinition = tankModelDefinition.turrets[turret.id]; - const hullOrigin = new Vector3( - trackModelDefinition.origin.x, - trackModelDefinition.origin.y, - -trackModelDefinition.origin.z, - ); - const turretOrigin = new Vector3( - tankModelDefinition.turret_origin.x, - tankModelDefinition.turret_origin.y, - -tankModelDefinition.turret_origin.z, - ); - const gunOriginOnlyY = new Vector3(0, turretModelDefinition.gun_origin.y, 0); - const shellOrigin = hullOrigin.clone().add(turretOrigin).add(gunOriginOnlyY); - const camouflage = Duel.use((state) => state.protagonist.camouflage); - const crewSkills = TankopediaEphemeral.use((state) => state.skills); - const consumables = Duel.use((state) => state.protagonist.consumables); - const provisions = Duel.use((state) => state.protagonist.provisions); - const equipmentMatrix = Duel.use( - (state) => state.protagonist.equipmentMatrix, - ); - const characteristics = tankCharacteristics( - { - tank, - turret, - gun, - shell, - consumables, - applyDynamicArmor: false, - applyReactiveArmor: false, - applySpallLiner: false, - camouflage, - crewSkills, - engine, - equipmentMatrix, - provisions, - stockEngine: tank.engines[0], - stockGun: tank.turrets[0].guns[0], - stockTurret: tank.turrets[0], - stockTrack: tank.tracks[0], - track, - }, - { equipmentDefinitions, provisionDefinitions, tankModelDefinition }, - ); - let { dispersion } = characteristics; - const gunRotationSpeed = degToRad(characteristics.gunTraverseSpeed); - const mockTank = useLoader(GLTFLoader, asset(`3d/tanks/models/6929.glb`)); + // const turret = Duel.use((state) => state.protagonist.turret); + // const track = Duel.use((state) => state.protagonist.track); + // const tank = Duel.use((state) => state.protagonist.tank); + // const gun = Duel.use((state) => state.protagonist.gun); + // const shell = Duel.use((state) => state.protagonist.shell); + // const engine = Duel.use((state) => state.protagonist.engine); + // const tankModelDefinition = modelDefinitions.models[tank.id]; + // const trackModelDefinition = + // modelDefinitions.models[tank.id].tracks[track.id]; + // const gunModelDefinition = + // tankModelDefinition.turrets[turret.id].guns[gun.gun_type!.value.base.id]; + // const turretModelDefinition = tankModelDefinition.turrets[turret.id]; + // const hullOrigin = new Vector3( + // trackModelDefinition.origin.x, + // trackModelDefinition.origin.y, + // -trackModelDefinition.origin.z, + // ); + // const turretOrigin = new Vector3( + // tankModelDefinition.turret_origin.x, + // tankModelDefinition.turret_origin.y, + // -tankModelDefinition.turret_origin.z, + // ); + // const gunOriginOnlyY = new Vector3(0, turretModelDefinition.gun_origin.y, 0); + // const shellOrigin = hullOrigin.clone().add(turretOrigin).add(gunOriginOnlyY); + // const camouflage = Duel.use((state) => state.protagonist.camouflage); + // const crewSkills = TankopediaEphemeral.use((state) => state.skills); + // const consumables = Duel.use((state) => state.protagonist.consumables); + // const provisions = Duel.use((state) => state.protagonist.provisions); + // const equipmentMatrix = Duel.use( + // (state) => state.protagonist.equipmentMatrix, + // ); + // const characteristics = tankCharacteristics( + // { + // tank, + // turret, + // gun, + // shell, + // consumables, + // applyDynamicArmor: false, + // applyReactiveArmor: false, + // applySpallLiner: false, + // camouflage, + // crewSkills, + // engine, + // equipmentMatrix, + // provisions, + // stockEngine: tank.engines[0], + // stockGun: tank.turrets[0].guns[0], + // stockTurret: tank.turrets[0], + // stockTrack: tank.tracks[0], + // track, + // }, + // { equipmentDefinitions, provisionDefinitions, tankModelDefinition }, + // ); + // let { dispersion } = characteristics; + // const gunRotationSpeed = degToRad(characteristics.gunTraverseSpeed); + // const mockTank = useLoader(GLTFLoader, asset(`3d/tanks/models/6929.glb`)); const texture = useLoader(TextureLoader, imgur('C28Z8nU')); - const path = new Vector3(); - const direction = new Vector3(); texture.anisotropy = 2; + // const path = new Vector3(); + // const direction = new Vector3(); useFrame(({ camera }) => { if (!material.current) return; material.current.opacity = clamp(0.5 * camera.position.y, 0, 1); }); - let lastTime = 0; - let DEBUG_disable = false; + // let lastTime = 0; + // let DEBUG_disable = false; - useFrame(({ raycaster, camera, clock, gl }) => { - if ( - display !== TankopediaDisplay.ShootingRange || - !playground.current || - !targetCircleWrapper.current || - DEBUG_disable || - !clientTargetCircle.current || - !serverTargetCircle.current - ) { - return; - } + // useFrame(({ raycaster, camera, clock, gl }) => { + // if ( + // display !== TankopediaDisplay.ShootingRange || + // !playground.current || + // !targetCircleWrapper.current || + // DEBUG_disable || + // !clientTargetCircle.current || + // !serverTargetCircle.current + // ) { + // return; + // } - raycaster.setFromCamera(emptyVector, camera); + // raycaster.setFromCamera(emptyVector, camera); - const cameraIntersections = raycaster.intersectObjects( - playground.current.children, - true, - ); + // const cameraIntersections = raycaster.intersectObjects( + // playground.current.children, + // true, + // ); - let length: number; + // let length: number; - if (cameraIntersections.length === 0) { - length = characteristics.shellRange; - direction.set(0, 0, -1).applyQuaternion(camera.quaternion); - aimTarget.copy(shellOrigin).addScaledVector(direction, length); - } else { - aimTarget.copy(cameraIntersections[0].point); - path.copy(aimTarget).sub(shellOrigin); - length = path.length(); - direction.copy(path).normalize(); - } + // if (cameraIntersections.length === 0) { + // length = characteristics.shellRange; + // direction.set(0, 0, -1).applyQuaternion(camera.quaternion); + // aimTarget.copy(shellOrigin).addScaledVector(direction, length); + // } else { + // aimTarget.copy(cameraIntersections[0].point); + // path.copy(aimTarget).sub(shellOrigin); + // length = path.length(); + // direction.copy(path).normalize(); + // } - const deltaT = clock.elapsedTime - lastTime; - lastTime = clock.elapsedTime; + // const deltaT = clock.elapsedTime - lastTime; + // lastTime = clock.elapsedTime; - const desiredPitch = Math.asin(direction.y); - const desiredYaw = Math.atan2(-direction.x, -direction.z); - const deltaPitch = desiredPitch - lastPitch; - const deltaYaw = desiredYaw - lastYaw; - const deltaAngle = Math.sqrt(deltaPitch ** 2 + deltaYaw ** 2); - const maxPossibleRotationInTime = gunRotationSpeed * deltaT; - const clampedDeltaAngle = Math.min(maxPossibleRotationInTime, deltaAngle); - const clampedDeltaPitch = - deltaAngle === 0 ? 0 : deltaPitch * (clampedDeltaAngle / deltaAngle); - const clampedDeltaYaw = - deltaAngle === 0 ? 0 : deltaYaw * (clampedDeltaAngle / deltaAngle); + // const desiredPitch = Math.asin(direction.y); + // const desiredYaw = Math.atan2(-direction.x, -direction.z); + // const deltaPitch = desiredPitch - lastPitch; + // const deltaYaw = desiredYaw - lastYaw; + // const deltaAngle = Math.sqrt(deltaPitch ** 2 + deltaYaw ** 2); + // const maxPossibleRotationInTime = gunRotationSpeed * deltaT; + // const clampedDeltaAngle = Math.min(maxPossibleRotationInTime, deltaAngle); + // const clampedDeltaPitch = + // deltaAngle === 0 ? 0 : deltaPitch * (clampedDeltaAngle / deltaAngle); + // const clampedDeltaYaw = + // deltaAngle === 0 ? 0 : deltaYaw * (clampedDeltaAngle / deltaAngle); - const [pitch, yaw] = applyPitchYawLimits( - lastPitch + clampedDeltaPitch, - lastYaw + clampedDeltaYaw, - gunModelDefinition.pitch, - turretModelDefinition.yaw, - ); + // const [pitch, yaw] = applyPitchYawLimits( + // lastPitch + clampedDeltaPitch, + // lastYaw + clampedDeltaYaw, + // gunModelDefinition.pitch, + // turretModelDefinition.yaw, + // ); - const actualDeltaPitch = pitch - lastPitch; - const actualDeltaYaw = yaw - lastYaw; - const deltaRotation = Math.abs(actualDeltaPitch) + Math.abs(actualDeltaYaw); - const rotationSpeed = deltaRotation / deltaT; - const turretTraversePenalty = - characteristics.dispersionTurretTraversing * radToDeg(rotationSpeed); + // const actualDeltaPitch = pitch - lastPitch; + // const actualDeltaYaw = yaw - lastYaw; + // const deltaRotation = Math.abs(actualDeltaPitch) + Math.abs(actualDeltaYaw); + // const rotationSpeed = deltaRotation / deltaT; + // const turretTraversePenalty = + // characteristics.dispersionTurretTraversing * radToDeg(rotationSpeed); - const penalty = Math.sqrt(1 + turretTraversePenalty ** 2); + // const penalty = Math.sqrt(1 + turretTraversePenalty ** 2); - if (penalty === 1) { - const dispersionMod = dispersion - characteristics.dispersion; - const dispersionModDischarged = - dispersionMod * Math.exp(-deltaT / characteristics.aimTime) - - dispersionMod; + // if (penalty === 1) { + // const dispersionMod = dispersion - characteristics.dispersion; + // const dispersionModDischarged = + // dispersionMod * Math.exp(-deltaT / characteristics.aimTime) - + // dispersionMod; - dispersion += dispersionModDischarged; - } else { - dispersion = Math.max(characteristics.dispersion * penalty, dispersion); - } + // dispersion += dispersionModDischarged; + // } else { + // dispersion = Math.max(characteristics.dispersion * penalty, dispersion); + // } - modelTransformEvent.emit({ pitch, yaw }); - lastPitch = pitch; - lastYaw = yaw; + // modelTransformEvent.emit({ pitch, yaw }); + // lastPitch = pitch; + // lastYaw = yaw; - const gunDirection = new Vector3(0, 0, -1) - .applyAxisAngle(I_HAT, pitch) - .applyAxisAngle(J_HAT, yaw); + // const gunDirection = new Vector3(0, 0, -1) + // .applyAxisAngle(I_HAT, pitch) + // .applyAxisAngle(J_HAT, yaw); - raycaster.set(shellOrigin, gunDirection); + // raycaster.set(shellOrigin, gunDirection); - const gunIntersections = raycaster.intersectObjects( - playground.current.children, - true, - ); + // const gunIntersections = raycaster.intersectObjects( + // playground.current.children, + // true, + // ); - let gunTarget: Vector3; + // let gunTarget: Vector3; - if (gunIntersections.length === 0) { - gunTarget = shellOrigin - .clone() - .add(gunDirection.multiplyScalar(characteristics.shellRange)); - } else { - gunTarget = gunIntersections[0].point; - } + // if (gunIntersections.length === 0) { + // gunTarget = shellOrigin + // .clone() + // .add(gunDirection.multiplyScalar(characteristics.shellRange)); + // } else { + // gunTarget = gunIntersections[0].point; + // } - targetCircleWrapper.current.position.copy(gunTarget); + // targetCircleWrapper.current.position.copy(gunTarget); - const distanceToTarget = gunTarget.distanceTo(shellOrigin); - const dispersionRadius = dispersion * (distanceToTarget / 100); - const dispersionSize = 2 * dispersionRadius; - const targetDistanceFromCamera = gunTarget.distanceTo(camera.position); - const angularSize = - 2 * Math.atan(dispersionSize / (2 * targetDistanceFromCamera)); - const verticalScreenSize = - 2 * Math.tan(degToRad((camera as PerspectiveCamera).fov) / 2); - const screenSpaceSize = - gl.domElement.clientHeight * (angularSize / verticalScreenSize); - const targetCircleDotsSize = `${screenSpaceSize}px`; + // const distanceToTarget = gunTarget.distanceTo(shellOrigin); + // const dispersionRadius = dispersion * (distanceToTarget / 100); + // const dispersionSize = 2 * dispersionRadius; + // const targetDistanceFromCamera = gunTarget.distanceTo(camera.position); + // const angularSize = + // 2 * Math.atan(dispersionSize / (2 * targetDistanceFromCamera)); + // const verticalScreenSize = + // 2 * Math.tan(degToRad((camera as PerspectiveCamera).fov) / 2); + // const screenSpaceSize = + // gl.domElement.clientHeight * (angularSize / verticalScreenSize); + // const targetCircleDotsSize = `${screenSpaceSize}px`; - clientTargetCircle.current.style.width = targetCircleDotsSize; - clientTargetCircle.current.style.height = targetCircleDotsSize; - serverTargetCircle.current.style.width = targetCircleDotsSize; - serverTargetCircle.current.style.height = targetCircleDotsSize; - }); + // clientTargetCircle.current.style.width = targetCircleDotsSize; + // clientTargetCircle.current.style.height = targetCircleDotsSize; + // serverTargetCircle.current.style.width = targetCircleDotsSize; + // serverTargetCircle.current.style.height = targetCircleDotsSize; + // }); return ( <> @@ -242,7 +226,7 @@ export function SceneProps() { )} - {display === TankopediaDisplay.ShootingRange && ( + {/* {display === TankopediaDisplay.ShootingRange && ( <> @@ -272,7 +256,7 @@ export function SceneProps() { - )} + )} */} ); } diff --git a/packages/website/src/components/Tankopedia/HeroSection/components/TankSandbox/components/TankModel.tsx b/packages/website/src/components/Tankopedia/HeroSection/components/TankSandbox/components/TankModel.tsx index b91ee66b6..fa22e2c90 100644 --- a/packages/website/src/components/Tankopedia/HeroSection/components/TankSandbox/components/TankModel.tsx +++ b/packages/website/src/components/Tankopedia/HeroSection/components/TankSandbox/components/TankModel.tsx @@ -18,6 +18,8 @@ import { TankopediaDisplay } from '../../../../../../stores/tankopediaPersistent import { ModelTankWrapper } from '../../../../../Armor/components/ModelTankWrapper'; export function TankModel() { + return null; + const mutateDuel = Duel.useMutation(); const duelStore = Duel.useStore(); const protagonist = Duel.use((draft) => draft.protagonist); diff --git a/packages/website/src/components/Tankopedia/HeroSection/components/TankSandbox/index.tsx b/packages/website/src/components/Tankopedia/HeroSection/components/TankSandbox/index.tsx index fb383bcd1..9bc71709d 100644 --- a/packages/website/src/components/Tankopedia/HeroSection/components/TankSandbox/index.tsx +++ b/packages/website/src/components/Tankopedia/HeroSection/components/TankSandbox/index.tsx @@ -1,19 +1,7 @@ import { BLITZKIT_TANK_ICON_SIZE } from '@blitzkit/core'; import { Canvas } from '@react-three/fiber'; -import { - forwardRef, - Suspense, - useEffect, - useImperativeHandle, - useRef, -} from 'react'; -import { applyPitchYawLimits } from '../../../../../core/blitz/applyPitchYawLimits'; -import { modelTransformEvent } from '../../../../../core/blitzkit/modelTransform'; -import { Pose, poseEvent } from '../../../../../core/blitzkit/pose'; -import { useEquipment } from '../../../../../hooks/useEquipment'; +import { forwardRef, Suspense, useImperativeHandle, useRef } from 'react'; import { useOnScreen } from '../../../../../hooks/useOnScreen'; -import { useTankModelDefinition } from '../../../../../hooks/useTankModelDefinition'; -import { Duel } from '../../../../../stores/duel'; import { TankopediaEphemeral } from '../../../../../stores/tankopediaEphemeral'; import { TankopediaPersistent } from '../../../../../stores/tankopediaPersistent'; import { TankopediaDisplay } from '../../../../../stores/tankopediaPersistent/constants'; @@ -40,16 +28,16 @@ export const TankSandbox = forwardRef( ({ thicknessRange, naked }, ref) => { const mutateTankopediaEphemeral = TankopediaEphemeral.useMutation(); const canvas = useRef(null); - const hasImprovedVerticalStabilizer = useEquipment(122); - const hasDownImprovedVerticalStabilizer = useEquipment(124); - const protagonistGun = Duel.use((state) => state.protagonist.gun); - const protagonistTurret = Duel.use((state) => state.protagonist.turret); - const mutateDuel = Duel.useMutation(); - const tankModelDefinition = useTankModelDefinition(); - const turretModelDefinition = - tankModelDefinition.turrets[protagonistTurret.id]; - const gunModelDefinition = - turretModelDefinition.guns[protagonistGun.gun_type!.value.base.id]; + // const hasImprovedVerticalStabilizer = useEquipment(122); + // const hasDownImprovedVerticalStabilizer = useEquipment(124); + // const protagonistGun = Duel.use((state) => state.protagonist.gun); + // const protagonistTurret = Duel.use((state) => state.protagonist.turret); + // const mutateDuel = Duel.useMutation(); + // const tankModelDefinition = useTankModelDefinition(); + // const turretModelDefinition = + // tankModelDefinition.turrets[protagonistTurret.id]; + // const gunModelDefinition = + // turretModelDefinition.guns[protagonistGun.gun_type!.value.base.id]; const display = TankopediaEphemeral.use((state) => state.display); const hideTankModelUnderArmor = TankopediaPersistent.use( (state) => state.hideTankModelUnderArmor, @@ -72,97 +60,97 @@ export const TankSandbox = forwardRef( window.removeEventListener('pointerup', handlePointerUp); } - useEffect(() => { - function handlePoseEvent(pose: Pose) { - switch (pose) { - case Pose.HullDown: { - mutateDuel((draft) => { - const [pitch, yaw] = applyPitchYawLimits( - -Infinity, - 0, - gunModelDefinition.pitch, - turretModelDefinition.yaw, - hasImprovedVerticalStabilizer, - hasDownImprovedVerticalStabilizer, - ); + // useEffect(() => { + // function handlePoseEvent(pose: Pose) { + // switch (pose) { + // case Pose.HullDown: { + // mutateDuel((draft) => { + // const [pitch, yaw] = applyPitchYawLimits( + // -Infinity, + // 0, + // gunModelDefinition.pitch, + // turretModelDefinition.yaw, + // hasImprovedVerticalStabilizer, + // hasDownImprovedVerticalStabilizer, + // ); - modelTransformEvent.emit({ pitch, yaw }); - draft.protagonist.pitch = pitch; - draft.protagonist.yaw = yaw; - }); + // modelTransformEvent.emit({ pitch, yaw }); + // draft.protagonist.pitch = pitch; + // draft.protagonist.yaw = yaw; + // }); - break; - } + // break; + // } - case Pose.FaceHug: { - mutateDuel((draft) => { - const [pitch, yaw] = applyPitchYawLimits( - Infinity, - 0, - gunModelDefinition.pitch, - turretModelDefinition.yaw, - hasImprovedVerticalStabilizer, - ); + // case Pose.FaceHug: { + // mutateDuel((draft) => { + // const [pitch, yaw] = applyPitchYawLimits( + // Infinity, + // 0, + // gunModelDefinition.pitch, + // turretModelDefinition.yaw, + // hasImprovedVerticalStabilizer, + // ); - modelTransformEvent.emit({ pitch, yaw }); - draft.protagonist.pitch = pitch; - draft.protagonist.yaw = yaw; - }); + // modelTransformEvent.emit({ pitch, yaw }); + // draft.protagonist.pitch = pitch; + // draft.protagonist.yaw = yaw; + // }); - break; - } + // break; + // } - case Pose.Default: - mutateDuel((draft) => { - const [pitch, yaw] = applyPitchYawLimits( - 0, - 0, - gunModelDefinition.pitch, - turretModelDefinition.yaw, - hasImprovedVerticalStabilizer, - ); + // case Pose.Default: + // mutateDuel((draft) => { + // const [pitch, yaw] = applyPitchYawLimits( + // 0, + // 0, + // gunModelDefinition.pitch, + // turretModelDefinition.yaw, + // hasImprovedVerticalStabilizer, + // ); - modelTransformEvent.emit({ pitch, yaw }); - draft.protagonist.pitch = pitch; - draft.protagonist.yaw = yaw; - }); + // modelTransformEvent.emit({ pitch, yaw }); + // draft.protagonist.pitch = pitch; + // draft.protagonist.yaw = yaw; + // }); - break; - } - } + // break; + // } + // } - poseEvent.on(handlePoseEvent); + // poseEvent.on(handlePoseEvent); - return () => { - poseEvent.off(handlePoseEvent); - }; - }); + // return () => { + // poseEvent.off(handlePoseEvent); + // }; + // }); - useEffect(() => { - mutateDuel((draft) => { - [draft.protagonist.pitch, draft.protagonist.yaw] = applyPitchYawLimits( - draft.protagonist.pitch, - draft.protagonist.yaw, - gunModelDefinition.pitch, - turretModelDefinition.yaw, - hasImprovedVerticalStabilizer, - ); - }); - }, [protagonistGun, protagonistTurret]); + // useEffect(() => { + // mutateDuel((draft) => { + // [draft.protagonist.pitch, draft.protagonist.yaw] = applyPitchYawLimits( + // draft.protagonist.pitch, + // draft.protagonist.yaw, + // gunModelDefinition.pitch, + // turretModelDefinition.yaw, + // hasImprovedVerticalStabilizer, + // ); + // }); + // }, [protagonistGun, protagonistTurret]); - useEffect(() => { - if (display !== TankopediaDisplay.DynamicArmor) { - mutateTankopediaEphemeral((draft) => { - draft.shot = undefined; - }); - } + // useEffect(() => { + // if (display !== TankopediaDisplay.DynamicArmor) { + // mutateTankopediaEphemeral((draft) => { + // draft.shot = undefined; + // }); + // } - if (display !== TankopediaDisplay.StaticArmor) { - mutateTankopediaEphemeral((draft) => { - draft.highlightArmor = undefined; - }); - } - }, [display]); + // if (display !== TankopediaDisplay.StaticArmor) { + // mutateTankopediaEphemeral((draft) => { + // draft.highlightArmor = undefined; + // }); + // } + // }, [display]); return ( {skeleton && } - {/* }> + }> - */} + - {/* */} + diff --git a/packages/website/src/stores/tankopediaEphemeral.ts b/packages/website/src/stores/tankopediaEphemeral.ts index 60202f331..6cdb690d2 100644 --- a/packages/website/src/stores/tankopediaEphemeral.ts +++ b/packages/website/src/stores/tankopediaEphemeral.ts @@ -134,7 +134,7 @@ export const TankopediaEphemeral = createContextualStore((armor: TankArmor) => { armor, controlsEnabled: true, xpMultiplier: 1, - display: TankopediaDisplay.Model, + display: TankopediaDisplay.StaticArmor, })), ); });