mirror of
https://github.com/blitzkit/blitzkit.git
synced 2026-10-21 10:47:04 +02:00
feat: some more stuff
This commit is contained in:
1 parent
d7e556e136
commit
7a3bdd8f35
7 files changed
+58
-25
No files matched your search
@@ -55,10 +55,7 @@ export function Options({ thicknessRange, canvas }: OptionsProps) {
|
||||
const hasCustomShell = TankopediaEphemeral.use(
|
||||
(state) => state.customShell !== undefined,
|
||||
);
|
||||
const display = TankopediaPersistent.useDeferred(
|
||||
(state) => state.display,
|
||||
TankopediaDisplay.Model,
|
||||
);
|
||||
const display = TankopediaEphemeral.use((state) => state.display);
|
||||
const isFullScreen = useFullScreen();
|
||||
const showGrid = TankopediaPersistent.use((state) => state.showGrid);
|
||||
const showEnvironment = TankopediaPersistent.use(
|
||||
@@ -356,7 +353,7 @@ export function Options({ thicknessRange, canvas }: OptionsProps) {
|
||||
<SegmentedControl.Root
|
||||
value={`${display}`}
|
||||
onValueChange={(value) => {
|
||||
mutateTankopediaPersistent((draft) => {
|
||||
mutateTankopediaEphemeral((draft) => {
|
||||
draft.display = Number(value);
|
||||
});
|
||||
}}
|
||||
|
||||
+41
-6
@@ -1,7 +1,7 @@
|
||||
import { OrbitControls } from '@react-three/drei';
|
||||
import { invalidate, useThree } from '@react-three/fiber';
|
||||
import { useEffect, useRef, useState } from 'react';
|
||||
import { Vector3 } from 'three';
|
||||
import { PerspectiveCamera, Vector3 } from 'three';
|
||||
import { OrbitControls as OrbitControlsClass } from 'three-stdlib';
|
||||
import { awaitableModelDefinitions } from '../../../../../../core/awaitables/modelDefinitions';
|
||||
import { applyPitchYawLimits } from '../../../../../../core/blitz/applyPitchYawLimits';
|
||||
@@ -9,6 +9,7 @@ import { hasEquipment } from '../../../../../../core/blitzkit/hasEquipment';
|
||||
import { Pose, poseEvent } from '../../../../../../core/blitzkit/pose';
|
||||
import { Duel } from '../../../../../../stores/duel';
|
||||
import { TankopediaEphemeral } from '../../../../../../stores/tankopediaEphemeral';
|
||||
import { TankopediaDisplay } from '../../../../../../stores/tankopediaPersistent/constants';
|
||||
|
||||
const poseDistances: Record<Pose, number> = {
|
||||
[Pose.HullDown]: 15,
|
||||
@@ -18,7 +19,14 @@ const poseDistances: Record<Pose, number> = {
|
||||
|
||||
const modelDefinitions = await awaitableModelDefinitions;
|
||||
|
||||
const ARCADE_MODE_DISTANCE = 19;
|
||||
const ARCADE_MODE_ANGLE = Math.PI / 4;
|
||||
|
||||
export const ARCADE_MODE_FOV = 54;
|
||||
export const INSPECT_MODE_FOV = 25;
|
||||
|
||||
export function Controls() {
|
||||
const display = TankopediaEphemeral.use((state) => state.display);
|
||||
const duelStore = Duel.useStore();
|
||||
const tankopediaEphemeralStore = TankopediaEphemeral.useStore();
|
||||
const camera = useThree((state) => state.camera);
|
||||
@@ -62,8 +70,10 @@ export function Controls() {
|
||||
protagonistTrackModelDefinition.origin.y +
|
||||
antagonistModelDefinition.turret_origin.y +
|
||||
antagonistTurretModelDefinition.gun_origin.y;
|
||||
const [autoRotate, setAutoRotate] = useState(true);
|
||||
const initialPosition = [
|
||||
const [autoRotate, setAutoRotate] = useState(
|
||||
display !== TankopediaDisplay.ShootingRange,
|
||||
);
|
||||
let initialPosition = [
|
||||
-8,
|
||||
protagonistHullOrigin.y +
|
||||
protagonistTurretOrigin.y +
|
||||
@@ -72,9 +82,27 @@ export function Controls() {
|
||||
] as const;
|
||||
|
||||
useEffect(() => {
|
||||
camera.position.set(...initialPosition);
|
||||
orbitControls.current?.target.set(0, initialPosition[1] / 2, 0);
|
||||
}, [camera, protagonistTrack, protagonistTank]);
|
||||
if (display === TankopediaDisplay.ShootingRange) {
|
||||
(camera as PerspectiveCamera).fov = ARCADE_MODE_FOV;
|
||||
camera.position.set(
|
||||
0,
|
||||
initialPosition[1] + ARCADE_MODE_DISTANCE * Math.sin(ARCADE_MODE_ANGLE),
|
||||
ARCADE_MODE_DISTANCE * Math.cos(ARCADE_MODE_ANGLE),
|
||||
);
|
||||
orbitControls.current?.target.set(0, initialPosition[1], 0);
|
||||
} else {
|
||||
(camera as PerspectiveCamera).fov = INSPECT_MODE_FOV;
|
||||
camera.position.set(...initialPosition);
|
||||
orbitControls.current?.target.set(0, initialPosition[1] / 2, 0);
|
||||
}
|
||||
|
||||
camera.updateProjectionMatrix();
|
||||
}, [
|
||||
camera,
|
||||
protagonistTrack,
|
||||
protagonistTank,
|
||||
display === TankopediaDisplay.ShootingRange,
|
||||
]);
|
||||
|
||||
useEffect(() => {
|
||||
const unsubscribeTankopediaEphemeral = tankopediaEphemeralStore.subscribe(
|
||||
@@ -187,13 +215,20 @@ export function Controls() {
|
||||
|
||||
poseEvent.on(handleDisturbance);
|
||||
canvas.addEventListener('pointerdown', handleDisturbance);
|
||||
const unsubscribeTankopediaPersistent = tankopediaEphemeralStore.subscribe(
|
||||
(state) => state.display,
|
||||
handleDisturbance,
|
||||
);
|
||||
|
||||
return () => {
|
||||
canvas.removeEventListener('pointerdown', handleDisturbance);
|
||||
poseEvent.off(handleDisturbance);
|
||||
unsubscribeTankopediaPersistent();
|
||||
};
|
||||
}, []);
|
||||
|
||||
useEffect(() => {}, [display]);
|
||||
|
||||
return (
|
||||
<OrbitControls
|
||||
maxDistance={20}
|
||||
|
||||
+2
-1
@@ -1,12 +1,13 @@
|
||||
import { Environment } from '@react-three/drei';
|
||||
import { useModel } from '../../../../../../hooks/useModel';
|
||||
import { Duel } from '../../../../../../stores/duel';
|
||||
import { TankopediaEphemeral } from '../../../../../../stores/tankopediaEphemeral';
|
||||
import { TankopediaPersistent } from '../../../../../../stores/tankopediaPersistent';
|
||||
import { TankopediaDisplay } from '../../../../../../stores/tankopediaPersistent/constants';
|
||||
|
||||
export function Lighting() {
|
||||
const protagonist = Duel.use((state) => state.protagonist);
|
||||
const display = TankopediaPersistent.use((state) => state.display);
|
||||
const display = TankopediaEphemeral.use((state) => state.display);
|
||||
const { hasPbr } = useModel(protagonist.tank.id);
|
||||
const isBrighterLighting =
|
||||
!hasPbr && display !== TankopediaDisplay.StaticArmor;
|
||||
|
||||
+2
-3
@@ -11,7 +11,6 @@ import { useTankModelDefinition } from '../../../../../../hooks/useTankModelDefi
|
||||
import { useTankTransform } from '../../../../../../hooks/useTankTransform';
|
||||
import { Duel } from '../../../../../../stores/duel';
|
||||
import { TankopediaEphemeral } from '../../../../../../stores/tankopediaEphemeral';
|
||||
import { TankopediaPersistent } from '../../../../../../stores/tankopediaPersistent';
|
||||
import { TankopediaDisplay } from '../../../../../../stores/tankopediaPersistent/constants';
|
||||
import { ModelTankWrapper } from '../../../../../Armor/components/ModelTankWrapper';
|
||||
|
||||
@@ -19,7 +18,7 @@ export const TankModel = memo(() => {
|
||||
const mutateDuel = Duel.useMutation();
|
||||
const duelStore = Duel.useStore();
|
||||
const protagonist = Duel.use((draft) => draft.protagonist);
|
||||
const tankopediaPersistentStore = TankopediaPersistent.useStore();
|
||||
const tankopediaEphemeralStore = TankopediaEphemeral.useStore();
|
||||
const track = Duel.use((state) => state.protagonist.track);
|
||||
const turret = Duel.use((state) => state.protagonist.turret);
|
||||
const canvas = useThree((state) => state.gl.domElement);
|
||||
@@ -67,7 +66,7 @@ export const TankModel = memo(() => {
|
||||
function onPointerDown(event: ThreeEvent<PointerEvent>) {
|
||||
if (
|
||||
isTrack &&
|
||||
tankopediaPersistentStore.getState().display ===
|
||||
tankopediaEphemeralStore.getState().display ===
|
||||
TankopediaDisplay.Model
|
||||
) {
|
||||
position.set(event.clientX, event.clientY);
|
||||
|
||||
+7
-6
@@ -24,7 +24,7 @@ import {
|
||||
type ThicknessRange,
|
||||
} from '../../../../Armor/components/StaticArmor';
|
||||
import { AutoClear } from './components/AutoClear';
|
||||
import { Controls } from './components/Control';
|
||||
import { Controls, INSPECT_MODE_FOV } from './components/Control';
|
||||
import { Lighting } from './components/Lighting';
|
||||
import { ModelLoader } from './components/ModelLoader';
|
||||
import { SceneProps } from './components/SceneProps';
|
||||
@@ -46,10 +46,8 @@ export const TankSandbox = forwardRef<HTMLCanvasElement, TankSandboxProps>(
|
||||
tankModelDefinition.turrets[protagonist.turret.id];
|
||||
const gunModelDefinition =
|
||||
turretModelDefinition.guns[protagonist.gun.gun_type!.value.base.id];
|
||||
const display = TankopediaPersistent.useDeferred(
|
||||
(state) => state.display,
|
||||
TankopediaDisplay.Model,
|
||||
);
|
||||
const display = TankopediaEphemeral.use((state) => state.display);
|
||||
const tankopediaPersistentStore = TankopediaPersistent.useStore();
|
||||
const onScreen = useOnScreen(canvas);
|
||||
|
||||
useImperativeHandle(ref, () => canvas.current!, []);
|
||||
@@ -177,7 +175,10 @@ export const TankSandbox = forwardRef<HTMLCanvasElement, TankSandboxProps>(
|
||||
});
|
||||
}}
|
||||
style={{ userSelect: 'none' }}
|
||||
camera={{ fov: 25, far: 32 }}
|
||||
camera={{
|
||||
fov: INSPECT_MODE_FOV,
|
||||
far: 32,
|
||||
}}
|
||||
>
|
||||
<Controls />
|
||||
<SceneProps />
|
||||
|
||||
@@ -11,6 +11,7 @@ import type { ExternalModuleVariant } from '../components/Armor/components/Space
|
||||
import type { XP_MULTIPLIERS } from '../components/Tankopedia/TechTreeSection';
|
||||
import { awaitableSkillDefinitions } from '../core/awaitables/skillDefinitions';
|
||||
import { createContextualStore } from '../core/zustand/createContextualStore';
|
||||
import { TankopediaDisplay } from './tankopediaPersistent/constants';
|
||||
|
||||
export interface ShotLayerBase {
|
||||
index: number;
|
||||
@@ -100,6 +101,7 @@ interface TankopediaEphemeral {
|
||||
);
|
||||
xpMultiplier: (typeof XP_MULTIPLIERS)[number];
|
||||
customShell?: ShellDefinition;
|
||||
display: TankopediaDisplay;
|
||||
}
|
||||
|
||||
const skillDefinitions = await awaitableSkillDefinitions;
|
||||
@@ -114,6 +116,7 @@ export const TankopediaEphemeral = createContextualStore(
|
||||
model,
|
||||
controlsEnabled: true,
|
||||
xpMultiplier: 1,
|
||||
display: TankopediaDisplay.Model,
|
||||
})),
|
||||
);
|
||||
},
|
||||
|
||||
@@ -3,7 +3,7 @@ import { create } from 'zustand';
|
||||
import { persist, subscribeWithSelector } from 'zustand/middleware';
|
||||
import { ENVIRONMENTS } from '../../constants/lightingEnvironments';
|
||||
import { createContextualStore } from '../../core/zustand/createContextualStore';
|
||||
import { SORT_NAMES, TankopediaDisplay } from './constants';
|
||||
import { SORT_NAMES } from './constants';
|
||||
|
||||
export type TankopediaSortBy = keyof typeof SORT_NAMES;
|
||||
export type TankopediaSortDirection = 'ascending' | 'descending';
|
||||
@@ -25,8 +25,6 @@ export interface TankopediaPersistentStore {
|
||||
by: TankopediaSortBy;
|
||||
direction: TankopediaSortDirection;
|
||||
};
|
||||
|
||||
display: TankopediaDisplay;
|
||||
}
|
||||
|
||||
export const TankopediaPersistent = createContextualStore(() =>
|
||||
@@ -47,7 +45,6 @@ export const TankopediaPersistent = createContextualStore(() =>
|
||||
by: 'meta.none',
|
||||
direction: 'ascending',
|
||||
},
|
||||
display: TankopediaDisplay.Model,
|
||||
})),
|
||||
{ name: 'tankopedia', merge: (a, b) => lodash.merge(b, a) },
|
||||
),
|
||||
|
||||
Reference in new issue
Block a user