feat: aiming caster

This commit is contained in:
tresabhi committed 2024-12-01 22:11:38 -06:00
1 parent 5a34a35638
commit 65c52c2e82
3 files changed
+45 -21

No files matched your search

@@ -1,7 +1,7 @@
import { OrbitControls } from '@react-three/drei';
import { invalidate, useThree } from '@react-three/fiber';
import { useEffect, useRef, useState } from 'react';
import { PerspectiveCamera, Vector3 } from 'three';
import { AxesHelper, PerspectiveCamera, Vector2, Vector3 } from 'three';
import { OrbitControls as OrbitControlsClass } from 'three-stdlib';
import { degToRad } from 'three/src/math/MathUtils.js';
import { awaitableModelDefinitions } from '../../../../../../core/awaitables/modelDefinitions';
@@ -22,11 +22,13 @@ const modelDefinitions = await awaitableModelDefinitions;
const ARCADE_MODE_DISTANCE = 16;
const ARCADE_MODE_ANGLE = Math.PI / 8;
export const ARCADE_MODE_FOV = 54;
export const INSPECT_MODE_FOV = 25;
const emptyVector = new Vector2();
export function Controls() {
const helper = useRef<AxesHelper>(null);
const display = TankopediaEphemeral.use((state) => state.display);
const duelStore = Duel.useStore();
const tankopediaEphemeralStore = TankopediaEphemeral.useStore();
@@ -79,6 +81,8 @@ export function Controls() {
protagonistTurretOrigin.y +
protagonistGunOrigin.y;
const initialPosition = [-8, gunHeight + 4, -13] as const;
const raycaster = useThree((state) => state.raycaster);
const scene = useThree((state) => state.scene);
useEffect(() => {
if (!orbitControls.current) return;
@@ -232,19 +236,39 @@ export function Controls() {
};
}, []);
useEffect(() => {}, [display]);
return (
<OrbitControls
maxDistance={20}
minDistance={5}
ref={orbitControls}
enabled={tankopediaEphemeralStore.getState().controlsEnabled}
rotateSpeed={0.25}
enableDamping={false}
maxPolarAngle={degToRad(100)}
autoRotate={autoRotate}
autoRotateSpeed={1 / 4}
/>
<>
<axesHelper ref={helper} />
<OrbitControls
maxDistance={20}
minDistance={5}
ref={orbitControls}
enabled={tankopediaEphemeralStore.getState().controlsEnabled}
rotateSpeed={0.25}
enableDamping={false}
maxPolarAngle={degToRad(100)}
autoRotate={autoRotate}
autoRotateSpeed={1 / 4}
onChange={() => {
if (display !== TankopediaDisplay.ShootingRange || !helper.current) {
return;
}
raycaster.setFromCamera(emptyVector, camera);
const intersections = raycaster.intersectObjects(
scene.children,
true,
);
const first = intersections.find(
(intersection) => intersection.object !== helper.current,
);
if (first === undefined) return;
helper.current.position.copy(first.point);
}}
/>
</>
);
}
@@ -34,6 +34,7 @@ export function Lighting() {
{times(LIGHTS_COUNT, (index) => (
<directionalLight
key={index}
castShadow
position={[
Math.sin(2 * Math.PI * (index / LIGHTS_COUNT)),
@@ -14,7 +14,6 @@ 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';
import { Armor } from '../../../../Armor';
import { ArmorPlateDisplay } from '../../../../Armor/components/ArmorPlateDisplay';
@@ -39,15 +38,15 @@ export const TankSandbox = forwardRef<HTMLCanvasElement, TankSandboxProps>(
const mutateTankopediaEphemeral = TankopediaEphemeral.useMutation();
const canvas = useRef<HTMLCanvasElement>(null);
const hasImprovedVerticalStabilizer = useEquipment(122);
const protagonist = Duel.use((state) => state.protagonist);
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[protagonist.turret.id];
tankModelDefinition.turrets[protagonistTurret.id];
const gunModelDefinition =
turretModelDefinition.guns[protagonist.gun.gun_type!.value.base.id];
turretModelDefinition.guns[protagonistGun.gun_type!.value.base.id];
const display = TankopediaEphemeral.use((state) => state.display);
const tankopediaPersistentStore = TankopediaPersistent.useStore();
const onScreen = useOnScreen(canvas);
useImperativeHandle(ref, () => canvas.current!, []);
@@ -141,7 +140,7 @@ export const TankSandbox = forwardRef<HTMLCanvasElement, TankSandboxProps>(
hasImprovedVerticalStabilizer,
);
});
}, [protagonist.gun, protagonist.turret]);
}, [protagonistGun, protagonistTurret]);
useEffect(() => {
if (display !== TankopediaDisplay.DynamicArmor) {