From 9d916a588d9c601e126f3bb9c918e6aa6658d403 Mon Sep 17 00:00:00 2001 From: tresabhi <43380238+tresabhi@users.noreply.github.com> Date: Mon, 14 Apr 2025 19:26:41 -0500 Subject: [PATCH] feat: cooler header --- .../components/InfoWithDelta.tsx | 8 ++- .../TankSandbox/components/Control.tsx | 30 +++++----- .../Tankopedia/HeroSection/index.tsx | 58 ++++++++++++++----- .../Tankopedia/MetaSection/index.tsx | 3 + .../src/core/blitzkit/tankToCompareMember.ts | 9 ++- .../src/core/blitzkit/tankToDuelMember.ts | 17 +++++- .../tools/tankopedia/[id]/_index.tsx | 2 +- .../api/tankopedia/tank-icon/[id]/_index.tsx | 2 +- packages/website/src/stores/duel/index.ts | 6 +- .../website/src/stores/tankopediaEphemeral.ts | 2 + 10 files changed, 99 insertions(+), 38 deletions(-) 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 e035d72c6..459ab64ea 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 @@ -64,6 +64,7 @@ export function InfoWithDelta({ : (stats[props.value] as number); const delta = useDelta(uhWhatDoICallThisVariable); const protagonistTank = Duel.use((state) => state.protagonist.tank); + const model = modelDefinitions.models[protagonistTank.id]; const others = useMemo(() => { const defaultSkills = createDefaultSkills(skillDefinitions); @@ -78,7 +79,12 @@ export function InfoWithDelta({ relativeAgainst === TankopediaRelativeAgainst.All, ) .map((tank) => { - const member = tankToDuelMember(tank, provisionDefinitions); + const thisTankModel = modelDefinitions.models[tank.id]; + const member = tankToDuelMember( + tank, + thisTankModel, + provisionDefinitions, + ); return tankCharacteristics( { 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 4a90eb642..35fa2ff39 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,7 +1,7 @@ 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 { useEffect, useRef } from 'react'; import { PerspectiveCamera, Vector3 } from 'three'; import { OrbitControls as OrbitControlsClass } from 'three-stdlib'; import { degToRad } from 'three/src/math/MathUtils.js'; @@ -81,16 +81,14 @@ export function Controls({ naked }: ControlsProps) { protagonistTrackModelDefinition.origin.y + antagonistModelDefinition.turret_origin.y + antagonistTurretModelDefinition.gun_origin.y; - const [autoRotate, setAutoRotate] = useState( - display !== TankopediaDisplay.ShootingRange && !naked, - ); + const disturbed = TankopediaEphemeral.use((state) => state.disturbed); const gunHeight = protagonistHullOrigin.y + protagonistTurretOrigin.y + protagonistGunOrigin.y; const inspectModeInitialPosition = [ -8, - gunHeight + (naked ? 10 : 4), + gunHeight + (naked ? 10 : 2), -13, ] as const; const protagonistGunOriginOnlyY = new Vector3( @@ -217,10 +215,6 @@ export function Controls({ naked }: ControlsProps) { useEffect(() => { let isInitialIteration = true; - function handleDisturbance() { - setAutoRotate(false); - } - function handleKeyDown(event: KeyboardEvent) { if (display !== TankopediaDisplay.ShootingRange || event.repeat) return; @@ -254,8 +248,14 @@ export function Controls({ naked }: ControlsProps) { event.preventDefault(); } - poseEvent.on(handleDisturbance); - canvas.addEventListener('pointerdown', handleDisturbance); + function disturb() { + mutateTankopediaEphemeral((draft) => { + draft.disturbed = true; + }); + } + + poseEvent.on(disturb); + canvas.addEventListener('pointerdown', disturb); window.addEventListener('keydown', handleKeyDown); canvas.addEventListener('wheel', handleWheel); document.body.addEventListener('scroll', handleScroll); @@ -319,7 +319,7 @@ export function Controls({ naked }: ControlsProps) { const unsubscribeDisplay = tankopediaEphemeralStore.subscribe( (state) => state.display === TankopediaDisplay.ShootingRange, () => { - handleDisturbance(); + disturb(); updateCamera(); }, ); @@ -330,8 +330,8 @@ export function Controls({ naked }: ControlsProps) { ); return () => { - canvas.removeEventListener('pointerdown', handleDisturbance); - poseEvent.off(handleDisturbance); + canvas.removeEventListener('pointerdown', disturb); + poseEvent.off(disturb); unsubscribeDisplay(); unsubscribeShootingRangeZoom(); window.removeEventListener('keydown', handleKeyDown); @@ -347,7 +347,7 @@ export function Controls({ naked }: ControlsProps) { ref={orbitControls} enabled={tankopediaEphemeralStore.getState().controlsEnabled} enableDamping={false} - autoRotate={autoRotate} + autoRotate={!disturbed} autoRotateSpeed={1 / 4} /> ); diff --git a/packages/website/src/components/Tankopedia/HeroSection/index.tsx b/packages/website/src/components/Tankopedia/HeroSection/index.tsx index 06482662a..8e0981bc4 100644 --- a/packages/website/src/components/Tankopedia/HeroSection/index.tsx +++ b/packages/website/src/components/Tankopedia/HeroSection/index.tsx @@ -18,6 +18,7 @@ import { TankSandboxLoader } from './components/TankSandboxLoader'; const tankDefinitions = await awaitableTankDefinitions; export function HeroSection({ skeleton }: MaybeSkeletonComponentProps) { + const disturbed = TankopediaEphemeral.use((state) => state.disturbed); const { unwrap } = useLocale(); const canvas = useRef(null); const isFullScreen = useFullScreen(); @@ -73,10 +74,13 @@ export function HeroSection({ skeleton }: MaybeSkeletonComponentProps) { }, []); return ( - + @@ -117,14 +132,21 @@ export function HeroSection({ skeleton }: MaybeSkeletonComponentProps) { - - BlitzKit Tankopedia - + + + BlitzKit Tankopedia + + - - + + {skeleton && } }> diff --git a/packages/website/src/components/Tankopedia/MetaSection/index.tsx b/packages/website/src/components/Tankopedia/MetaSection/index.tsx index 312b98289..0a0f6e0b8 100644 --- a/packages/website/src/components/Tankopedia/MetaSection/index.tsx +++ b/packages/website/src/components/Tankopedia/MetaSection/index.tsx @@ -95,6 +95,8 @@ export function MetaSection() { { + const model = modelDefinitions.models[tank.id]; + setShowSwapDialog(false); mutateTankopediaEphemeral((draft) => { draft.model = modelDefinitions.models[tank.id]; @@ -102,6 +104,7 @@ export function MetaSection() { mutateDuel((draft) => { draft.protagonist = tankToDuelMember( tank, + model, provisionDefinitions, ); }); diff --git a/packages/website/src/core/blitzkit/tankToCompareMember.ts b/packages/website/src/core/blitzkit/tankToCompareMember.ts index 2930293d3..1e997b261 100644 --- a/packages/website/src/core/blitzkit/tankToCompareMember.ts +++ b/packages/website/src/core/blitzkit/tankToCompareMember.ts @@ -1,14 +1,19 @@ -import type { ProvisionDefinitions, TankDefinition } from '@blitzkit/core'; +import type { + ModelDefinition, + ProvisionDefinitions, + TankDefinition, +} from '@blitzkit/core'; import { uniqueId } from 'lodash-es'; import type { CompareMember } from '../../stores/compareEphemeral'; import { tankToDuelMember } from './tankToDuelMember'; export function tankToCompareMember( tank: TankDefinition, + model: ModelDefinition, provisionDefinitions: ProvisionDefinitions, ) { return { - ...tankToDuelMember(tank, provisionDefinitions), + ...tankToDuelMember(tank, model, provisionDefinitions), key: uniqueId(), } satisfies CompareMember; } diff --git a/packages/website/src/core/blitzkit/tankToDuelMember.ts b/packages/website/src/core/blitzkit/tankToDuelMember.ts index 945657d29..ab0d96a92 100644 --- a/packages/website/src/core/blitzkit/tankToDuelMember.ts +++ b/packages/website/src/core/blitzkit/tankToDuelMember.ts @@ -1,17 +1,30 @@ import { createDefaultProvisions, + ModelDefinition, type ProvisionDefinitions, type TankDefinition, } from '@blitzkit/core'; +import { degToRad } from 'three/src/math/MathUtils.js'; import type { DuelMember } from '../../stores/duel'; import { genericDefaultEquipmentMatrix } from '../../stores/duel/constants'; +import { applyPitchYawLimits } from '../blitz/applyPitchYawLimits'; export function tankToDuelMember( tank: TankDefinition, + model: ModelDefinition, provisionDefinitions: ProvisionDefinitions, ) { const turret = tank.turrets.at(-1)!; + const turretModel = model.turrets[turret.id]; const gun = turret.guns.at(-1)!; + const gunModel = turretModel.guns[gun.gun_type!.value.base.id]; + + const [pitch, yaw] = applyPitchYawLimits( + degToRad(8), + degToRad(25), + gunModel.pitch, + turretModel.yaw, + ); return { camouflage: true, @@ -24,8 +37,8 @@ export function tankToDuelMember( shell: tank.turrets.at(-1)!.guns.at(-1)!.gun_type!.value.base.shells[0], tank, track: tank.tracks.at(-1)!, - yaw: 0, - pitch: 0, + yaw, + pitch, turret, } satisfies DuelMember; } diff --git a/packages/website/src/pages/[...locale]/tools/tankopedia/[id]/_index.tsx b/packages/website/src/pages/[...locale]/tools/tankopedia/[id]/_index.tsx index 617382f94..b7c1441d4 100644 --- a/packages/website/src/pages/[...locale]/tools/tankopedia/[id]/_index.tsx +++ b/packages/website/src/pages/[...locale]/tools/tankopedia/[id]/_index.tsx @@ -42,7 +42,7 @@ export function Page({ id, skeleton, locale }: PageProps) { diff --git a/packages/website/src/pages/api/tankopedia/tank-icon/[id]/_index.tsx b/packages/website/src/pages/api/tankopedia/tank-icon/[id]/_index.tsx index 96a50aecc..7f00d7ad9 100644 --- a/packages/website/src/pages/api/tankopedia/tank-icon/[id]/_index.tsx +++ b/packages/website/src/pages/api/tankopedia/tank-icon/[id]/_index.tsx @@ -27,7 +27,7 @@ export function Page({ id }: PageProps) { - + diff --git a/packages/website/src/stores/duel/index.ts b/packages/website/src/stores/duel/index.ts index 77b6c0126..132c5d789 100644 --- a/packages/website/src/stores/duel/index.ts +++ b/packages/website/src/stores/duel/index.ts @@ -1,4 +1,5 @@ import { + ModelDefinition, type EngineDefinition, type GunDefinition, type ProvisionDefinitions, @@ -48,16 +49,19 @@ export interface DuelStore { export const Duel = createContextualStore( ({ tank, + model, provisionDefinitions, }: { tank: TankDefinition; + model: ModelDefinition; provisionDefinitions: ProvisionDefinitions; }) => { - const protagonist = tankToDuelMember(tank, provisionDefinitions); + const protagonist = tankToDuelMember(tank, model, provisionDefinitions); return create()( subscribeWithSelector(() => ({ protagonist, + model, antagonist: protagonist, })), ); diff --git a/packages/website/src/stores/tankopediaEphemeral.ts b/packages/website/src/stores/tankopediaEphemeral.ts index 1c69b89f3..0e9c14460 100644 --- a/packages/website/src/stores/tankopediaEphemeral.ts +++ b/packages/website/src/stores/tankopediaEphemeral.ts @@ -96,6 +96,7 @@ export const SHOOTING_RANGE_ZOOM_COEFFICIENTS: Record< }; interface TankopediaEphemeral { + disturbed: boolean; shot?: Shot; shootingRangeZoom: ShootingRangeZoom; skills: Record; @@ -128,6 +129,7 @@ export const TankopediaEphemeral = createContextualStore( (model: ModelDefinition) => { return create()( subscribeWithSelector(() => ({ + disturbed: false, shootingRangeZoom: ShootingRangeZoom.Arcade, relativeAgainst: TankopediaRelativeAgainst.Class, editStatic: false,