mirror of
https://github.com/blitzkit/blitzkit.git
synced 2026-10-21 02:37:05 +02:00
feat: remove shooting range
This commit is contained in:
1 parent
b3046d8655
commit
ea90ca21b1
10 files changed
+18
-262
No files matched your search
Binary file not shown.
|
Before Width: | Height: | Size: 5.2 KiB |
+1
-30
@@ -15,7 +15,6 @@ import {
|
||||
GearIcon,
|
||||
} from '@radix-ui/react-icons';
|
||||
import {
|
||||
Box,
|
||||
Button,
|
||||
Checkbox,
|
||||
Dialog,
|
||||
@@ -36,10 +35,7 @@ import { useFullscreenAvailability } from '../../../../../hooks/useFullscreenAva
|
||||
import { useLocale } from '../../../../../hooks/useLocale';
|
||||
import { App } from '../../../../../stores/app';
|
||||
import { Duel } from '../../../../../stores/duel';
|
||||
import {
|
||||
ShootingRangeZoom,
|
||||
TankopediaEphemeral,
|
||||
} from '../../../../../stores/tankopediaEphemeral';
|
||||
import { TankopediaEphemeral } from '../../../../../stores/tankopediaEphemeral';
|
||||
import { TankopediaPersistent } from '../../../../../stores/tankopediaPersistent';
|
||||
import { TankopediaDisplay } from '../../../../../stores/tankopediaPersistent/constants';
|
||||
import type { MaybeSkeletonComponentProps } from '../../../../../types/maybeSkeletonComponentProps';
|
||||
@@ -97,23 +93,6 @@ export function Options({ thicknessRange, canvas, skeleton }: OptionsProps) {
|
||||
<>
|
||||
{disturbed && <QuickInputs />}
|
||||
|
||||
{display === TankopediaDisplay.ShootingRange && (
|
||||
<Box
|
||||
width="1rem"
|
||||
height="1rem"
|
||||
position="absolute"
|
||||
top="50%"
|
||||
left="50%"
|
||||
style={{
|
||||
zIndex: 2,
|
||||
backgroundImage: 'url(/assets/images/icons/aim-caret.png)',
|
||||
backgroundSize: 'contain',
|
||||
transform: 'translateX(-50%)',
|
||||
borderRadius: '50%',
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
|
||||
<Thicknesses skeleton={skeleton} thicknessRange={thicknessRange} />
|
||||
|
||||
<Flex
|
||||
@@ -408,7 +387,6 @@ export function Options({ thicknessRange, canvas, skeleton }: OptionsProps) {
|
||||
mutateTankopediaEphemeral((draft) => {
|
||||
draft.disturbed = true;
|
||||
draft.display = Number(value);
|
||||
draft.shootingRangeZoom = ShootingRangeZoom.Arcade;
|
||||
});
|
||||
}}
|
||||
>
|
||||
@@ -448,13 +426,6 @@ export function Options({ thicknessRange, canvas, skeleton }: OptionsProps) {
|
||||
</Flex>
|
||||
</Tooltip>
|
||||
</SegmentedControl.Item>
|
||||
{/* <SegmentedControl.Item value={`${TankopediaDisplay.ShootingRange}`}>
|
||||
<Tooltip content="Shooting range">
|
||||
<Flex height="100%" align="center">
|
||||
<img src="/assets/images/icons/tankopedia-shooting-range.png" style={{ height: '1.25em' }} />
|
||||
</Flex>
|
||||
</Tooltip>
|
||||
</SegmentedControl.Item> */}
|
||||
</SegmentedControl.Root>
|
||||
|
||||
{disturbed && (
|
||||
|
||||
+7
-96
@@ -1,7 +1,6 @@
|
||||
import { I_HAT, J_HAT } from '@blitzkit/core';
|
||||
import { OrbitControls } from '@react-three/drei';
|
||||
import { invalidate, useThree } from '@react-three/fiber';
|
||||
import { clamp } from 'lodash-es';
|
||||
import { useEffect, useRef } from 'react';
|
||||
import { PerspectiveCamera, Vector3 } from 'three';
|
||||
import { OrbitControls as OrbitControlsClass } from 'three-stdlib';
|
||||
@@ -11,13 +10,7 @@ import { applyPitchYawLimits } from '../../../../../../core/blitz/applyPitchYawL
|
||||
import { hasEquipment } from '../../../../../../core/blitzkit/hasEquipment';
|
||||
import { Pose, poseEvent } from '../../../../../../core/blitzkit/pose';
|
||||
import { Duel } from '../../../../../../stores/duel';
|
||||
import {
|
||||
SHOOTING_RANGE_ZOOM_COEFFICIENTS,
|
||||
ShootingRangeZoom,
|
||||
TankopediaEphemeral,
|
||||
} from '../../../../../../stores/tankopediaEphemeral';
|
||||
import { TankopediaDisplay } from '../../../../../../stores/tankopediaPersistent/constants';
|
||||
import { aimTarget } from './SceneProps/constants';
|
||||
import { TankopediaEphemeral } from '../../../../../../stores/tankopediaEphemeral';
|
||||
|
||||
const poseDistances: Record<Pose, number> = {
|
||||
[Pose.HullDown]: 15,
|
||||
@@ -254,36 +247,11 @@ export function Controls({
|
||||
useEffect(() => {
|
||||
let isInitialIteration = true;
|
||||
|
||||
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;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function handleWheel(event: WheelEvent) {
|
||||
if (display !== TankopediaDisplay.ShootingRange) return;
|
||||
|
||||
event.preventDefault();
|
||||
|
||||
mutateTankopediaEphemeral((draft) => {
|
||||
draft.shootingRangeZoom = clamp(
|
||||
draft.shootingRangeZoom - Math.sign(event.deltaY),
|
||||
ShootingRangeZoom.Arcade,
|
||||
ShootingRangeZoom.Zoom2,
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
function handleScroll(event: Event) {
|
||||
if (display !== TankopediaDisplay.ShootingRange) return;
|
||||
|
||||
event.preventDefault();
|
||||
}
|
||||
|
||||
@@ -295,7 +263,6 @@ export function Controls({
|
||||
|
||||
poseEvent.on(disturb);
|
||||
canvas.addEventListener('pointerdown', disturb);
|
||||
window.addEventListener('keydown', handleKeyDown);
|
||||
canvas.addEventListener('wheel', handleWheel);
|
||||
document.body.addEventListener('scroll', handleScroll);
|
||||
|
||||
@@ -304,80 +271,24 @@ export function Controls({
|
||||
|
||||
orbitControls.current.rotateSpeed = 0.25;
|
||||
|
||||
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];
|
||||
|
||||
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);
|
||||
|
||||
camera.position
|
||||
.copy(aimTarget)
|
||||
.sub(shellOrigin)
|
||||
.normalize()
|
||||
.multiplyScalar(-Number.EPSILON)
|
||||
.add(shellOrigin);
|
||||
}
|
||||
} else {
|
||||
camera.position.copy(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(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();
|
||||
}
|
||||
|
||||
updateCamera();
|
||||
|
||||
const unsubscribeDisplay = tankopediaEphemeralStore.subscribe(
|
||||
(state) => state.display === TankopediaDisplay.ShootingRange,
|
||||
() => {
|
||||
disturb();
|
||||
updateCamera();
|
||||
},
|
||||
);
|
||||
|
||||
const unsubscribeShootingRangeZoom = tankopediaEphemeralStore.subscribe(
|
||||
(state) => state.shootingRangeZoom,
|
||||
updateCamera,
|
||||
);
|
||||
|
||||
return () => {
|
||||
canvas.removeEventListener('pointerdown', disturb);
|
||||
poseEvent.off(disturb);
|
||||
unsubscribeDisplay();
|
||||
unsubscribeShootingRangeZoom();
|
||||
window.removeEventListener('keydown', handleKeyDown);
|
||||
canvas.removeEventListener('wheel', handleWheel);
|
||||
document.body.removeEventListener('scroll', handleScroll);
|
||||
};
|
||||
}, [display === TankopediaDisplay.ShootingRange]);
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<OrbitControls
|
||||
|
||||
-19
@@ -1,5 +1,4 @@
|
||||
import { Environment } from '@react-three/drei';
|
||||
import { times } from 'lodash-es';
|
||||
import { Euler } from 'three';
|
||||
import { degToRad } from 'three/src/math/MathUtils.js';
|
||||
import { useModel } from '../../../../../../hooks/useModel';
|
||||
@@ -30,24 +29,6 @@ export function Lighting({ display }: LightingProps) {
|
||||
{display === TankopediaDisplay.StaticArmor && (
|
||||
<Environment preset="lobby" />
|
||||
)}
|
||||
{display === TankopediaDisplay.ShootingRange && (
|
||||
<>
|
||||
<directionalLight position={[0, -1, 0]} />
|
||||
|
||||
{times(LIGHTS_COUNT, (index) => (
|
||||
<directionalLight
|
||||
key={index}
|
||||
castShadow
|
||||
intensity={3 / LIGHTS_COUNT}
|
||||
position={[
|
||||
Math.sin(2 * Math.PI * (index / LIGHTS_COUNT)),
|
||||
1,
|
||||
Math.cos(2 * Math.PI * (index / LIGHTS_COUNT)),
|
||||
]}
|
||||
/>
|
||||
))}
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
+4
-44
@@ -1,5 +1,4 @@
|
||||
import { asset, I_HAT, J_HAT } from '@blitzkit/core';
|
||||
import { Html } from '@react-three/drei';
|
||||
import { useFrame, useLoader } from '@react-three/fiber';
|
||||
import { clamp } from 'lodash-es';
|
||||
import { useRef } from 'react';
|
||||
@@ -21,8 +20,6 @@ import { modelTransformEvent } from '../../../../../../../core/blitzkit/modelTra
|
||||
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] =
|
||||
@@ -121,7 +118,6 @@ export function SceneProps() {
|
||||
|
||||
useFrame(({ raycaster, camera, clock, gl }) => {
|
||||
if (
|
||||
display !== TankopediaDisplay.ShootingRange ||
|
||||
!playground.current ||
|
||||
!targetCircleWrapper.current ||
|
||||
DEBUG_disable ||
|
||||
@@ -241,45 +237,9 @@ export function SceneProps() {
|
||||
if (!disturbed) return null;
|
||||
|
||||
return (
|
||||
<>
|
||||
{display !== TankopediaDisplay.ShootingRange && (
|
||||
<mesh rotation={[-Math.PI / 2, 0, 0]}>
|
||||
<planeGeometry args={[10, 10]} />
|
||||
<meshStandardMaterial ref={material} map={texture} transparent />
|
||||
</mesh>
|
||||
)}
|
||||
|
||||
{display === TankopediaDisplay.ShootingRange && (
|
||||
<>
|
||||
<group ref={targetCircleWrapper}>
|
||||
<Html center occlude={false} zIndexRange={[0, 0]}>
|
||||
<TargetCircle variant="client" ref={clientTargetCircle} />
|
||||
<TargetCircle variant="server" ref={serverTargetCircle} />
|
||||
</Html>
|
||||
</group>
|
||||
|
||||
<group ref={playground}>
|
||||
<mesh rotation={[-Math.PI / 2, 0, 0]} receiveShadow>
|
||||
<planeGeometry args={[100, 100]} />
|
||||
<meshStandardMaterial color={0x404040} />
|
||||
</mesh>
|
||||
|
||||
<mesh
|
||||
receiveShadow
|
||||
castShadow
|
||||
position={[10, 1.5, -10]}
|
||||
rotation={[0, Math.PI / 4, 0]}
|
||||
>
|
||||
<boxGeometry args={[1, 3, 1]} />
|
||||
<meshStandardMaterial color={0xff8040} />
|
||||
</mesh>
|
||||
|
||||
<group position={[0, 0, -25]} rotation={[-Math.PI / 2, 0, Math.PI]}>
|
||||
<primitive object={mockTank.scene} />
|
||||
</group>
|
||||
</group>
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
<mesh rotation={[-Math.PI / 2, 0, 0]}>
|
||||
<planeGeometry args={[10, 10]} />
|
||||
<meshStandardMaterial ref={material} map={texture} transparent />
|
||||
</mesh>
|
||||
);
|
||||
}
|
||||
+3
-29
@@ -1,6 +1,6 @@
|
||||
import { normalizeAngleRad } from '@blitzkit/core';
|
||||
import { invalidate, useThree, type ThreeEvent } from '@react-three/fiber';
|
||||
import { useEffect, useRef } from 'react';
|
||||
import { useRef } from 'react';
|
||||
import { Group, Mesh, MeshStandardMaterial, Vector2 } from 'three';
|
||||
import { applyPitchYawLimits } from '../../../../../../core/blitz/applyPitchYawLimits';
|
||||
import { hasEquipment } from '../../../../../../core/blitzkit/hasEquipment';
|
||||
@@ -10,10 +10,7 @@ import { useModel } from '../../../../../../hooks/useModel';
|
||||
import { useTankModelDefinition } from '../../../../../../hooks/useTankModelDefinition';
|
||||
import { useTankTransform } from '../../../../../../hooks/useTankTransform';
|
||||
import { Duel } from '../../../../../../stores/duel';
|
||||
import {
|
||||
ShootingRangeZoom,
|
||||
TankopediaEphemeral,
|
||||
} from '../../../../../../stores/tankopediaEphemeral';
|
||||
import { TankopediaEphemeral } from '../../../../../../stores/tankopediaEphemeral';
|
||||
import { TankopediaDisplay } from '../../../../../../stores/tankopediaPersistent/constants';
|
||||
import { ModelTankWrapper } from '../../../../../Armor/components/ModelTankWrapper';
|
||||
|
||||
@@ -37,18 +34,6 @@ export function TankModel() {
|
||||
const { gltf } = useModel(protagonist.tank.id);
|
||||
const nodes = Object.values(gltf.nodes);
|
||||
|
||||
useEffect(() => {
|
||||
const unsubscribeShootingRangeZoom = tankopediaEphemeralStore.subscribe(
|
||||
(state) => state.shootingRangeZoom,
|
||||
(zoom) => {
|
||||
if (!hullContainer.current) return;
|
||||
hullContainer.current.visible = zoom === ShootingRangeZoom.Arcade;
|
||||
},
|
||||
);
|
||||
|
||||
return unsubscribeShootingRangeZoom;
|
||||
}, []);
|
||||
|
||||
useTankTransform(track, turret, turretContainer, gunContainer);
|
||||
|
||||
return (
|
||||
@@ -163,12 +148,7 @@ export function TankModel() {
|
||||
function onPointerDown(event: ThreeEvent<PointerEvent>) {
|
||||
event.stopPropagation();
|
||||
|
||||
if (
|
||||
!isTurret ||
|
||||
tankopediaEphemeralStore.getState().display ===
|
||||
TankopediaDisplay.ShootingRange
|
||||
)
|
||||
return;
|
||||
if (!isTurret) return;
|
||||
|
||||
position.set(event.clientX, event.clientY);
|
||||
yaw = protagonist.yaw;
|
||||
@@ -277,12 +257,6 @@ export function TankModel() {
|
||||
function onPointerDown(event: ThreeEvent<PointerEvent>) {
|
||||
event.stopPropagation();
|
||||
|
||||
if (
|
||||
tankopediaEphemeralStore.getState().display ===
|
||||
TankopediaDisplay.ShootingRange
|
||||
)
|
||||
return;
|
||||
|
||||
mutateTankopediaEphemeral((draft) => {
|
||||
draft.controlsEnabled = false;
|
||||
});
|
||||
|
||||
+2
-17
@@ -1,14 +1,11 @@
|
||||
import { useEffect, useRef } from 'react';
|
||||
import { useRef } from 'react';
|
||||
import { Group, ShaderMaterial, UniformsLib, UniformsUtils } from 'three';
|
||||
import { jsxTree } from '../../../../../../../core/blitzkit/jsxTree';
|
||||
import { useModel } from '../../../../../../../hooks/useModel';
|
||||
import { useTankModelDefinition } from '../../../../../../../hooks/useTankModelDefinition';
|
||||
import { useTankTransform } from '../../../../../../../hooks/useTankTransform';
|
||||
import { Duel } from '../../../../../../../stores/duel';
|
||||
import {
|
||||
ShootingRangeZoom,
|
||||
TankopediaEphemeral,
|
||||
} from '../../../../../../../stores/tankopediaEphemeral';
|
||||
import { TankopediaEphemeral } from '../../../../../../../stores/tankopediaEphemeral';
|
||||
import { ModelTankWrapper } from '../../../../../../Armor/components/ModelTankWrapper';
|
||||
import fragmentShader from './shaders/fragment.glsl?raw';
|
||||
import vertexShader from './shaders/vertex.glsl?raw';
|
||||
@@ -40,18 +37,6 @@ export function TransitionSkeleton() {
|
||||
const nodes = Object.values(gltf.nodes);
|
||||
const revealed = tankopediaEphemeralStore((state) => state.revealed);
|
||||
|
||||
useEffect(() => {
|
||||
const unsubscribeShootingRangeZoom = tankopediaEphemeralStore.subscribe(
|
||||
(state) => state.shootingRangeZoom,
|
||||
(zoom) => {
|
||||
if (!hullContainer.current) return;
|
||||
hullContainer.current.visible = zoom === ShootingRangeZoom.Arcade;
|
||||
},
|
||||
);
|
||||
|
||||
return unsubscribeShootingRangeZoom;
|
||||
}, []);
|
||||
|
||||
useTankTransform(track, turret, turretContainer, gunContainer);
|
||||
|
||||
return (
|
||||
|
||||
+1
-7
@@ -207,13 +207,7 @@ export const TankSandbox = forwardRef<HTMLCanvasElement, TankSandboxProps>(
|
||||
<Canvas
|
||||
ref={canvas}
|
||||
scene={{ fog: naked ? undefined : fog.current }}
|
||||
frameloop={
|
||||
onScreen
|
||||
? display === TankopediaDisplay.ShootingRange
|
||||
? 'always'
|
||||
: 'demand'
|
||||
: 'never'
|
||||
}
|
||||
frameloop={onScreen ? 'demand' : 'never'}
|
||||
gl={{
|
||||
clippingPlanes: [],
|
||||
localClippingEnabled: true,
|
||||
|
||||
@@ -78,28 +78,10 @@ export enum TankopediaRelativeAgainst {
|
||||
All,
|
||||
}
|
||||
|
||||
export enum ShootingRangeZoom {
|
||||
Arcade,
|
||||
Zoom0,
|
||||
Zoom1,
|
||||
Zoom2,
|
||||
}
|
||||
|
||||
export const SHOOTING_RANGE_ZOOM_COEFFICIENTS: Record<
|
||||
ShootingRangeZoom,
|
||||
number
|
||||
> = {
|
||||
[ShootingRangeZoom.Arcade]: 1,
|
||||
[ShootingRangeZoom.Zoom0]: 1 / 8,
|
||||
[ShootingRangeZoom.Zoom1]: 1 / 16,
|
||||
[ShootingRangeZoom.Zoom2]: 1 / 25,
|
||||
};
|
||||
|
||||
interface TankopediaEphemeral {
|
||||
disturbed: boolean;
|
||||
revealed: boolean;
|
||||
shot?: Shot;
|
||||
shootingRangeZoom: ShootingRangeZoom;
|
||||
skills: Record<string, number>;
|
||||
relativeAgainst: TankopediaRelativeAgainst;
|
||||
controlsEnabled: boolean;
|
||||
@@ -133,7 +115,6 @@ export const TankopediaEphemeral = createContextualStore(
|
||||
subscribeWithSelector<TankopediaEphemeral>(() => ({
|
||||
disturbed: false,
|
||||
revealed: false,
|
||||
shootingRangeZoom: ShootingRangeZoom.Arcade,
|
||||
relativeAgainst: TankopediaRelativeAgainst.Class,
|
||||
editStatic: false,
|
||||
skills: createDefaultSkills(skillDefinitions),
|
||||
|
||||
@@ -38,5 +38,4 @@ export enum TankopediaDisplay {
|
||||
Model,
|
||||
DynamicArmor,
|
||||
StaticArmor,
|
||||
ShootingRange,
|
||||
}
|
||||
Reference in new issue
Block a user