feat: isolated duel

This commit is contained in:
TrèsAbhi committed 2024-01-22 18:04:13 -06:00
1 parent fce5f19100
commit 0b5c2e42fb
15 files changed
+218 -249

No files matched your search

@@ -1,12 +1,12 @@
import { MeshProps, useFrame, useThree } from '@react-three/fiber';
import { useRef } from 'react';
import { useEffect, useRef } from 'react';
import { MeshStandardMaterial, ShaderMaterial, Vector2 } from 'three';
import ThreeCustomShaderMaterial from 'three-custom-shader-material';
import { degToRad } from 'three/src/math/MathUtils';
import { Duel } from '../../../../app/tools/tankopedia/[id]/page';
import { canSplash } from '../../../../core/blitz/canSplash';
import { isExplosive } from '../../../../core/blitz/isExplosive';
import { resolveNearPenetration } from '../../../../core/blitz/resolveNearPenetration';
import { useDuel } from '../../../../stores/duel';
import { useTankopediaPersistent } from '../../../../stores/tankopedia';
import { externalModuleMaskRenderTarget } from '../ExternalModuleMask';
import { spacedArmorDepthRenderTarget } from '../SpacedArmorDepth';
@@ -14,7 +14,6 @@ import fragmentShader from './shaders/fragment.glsl';
import vertexShader from './shaders/vertex.glsl';
interface ArmorMeshProps extends MeshProps {
duel: Duel;
thickness: number;
maxThickness: number;
}
@@ -22,23 +21,43 @@ interface ArmorMeshProps extends MeshProps {
export function ArmorMesh({
thickness,
maxThickness,
duel,
...props
}: ArmorMeshProps) {
const equipment = useTankopediaPersistent((draft) => draft.model.equipment);
const initialEquipment = useTankopediaPersistent.getState().model.equipment;
const camera = useThree((state) => state.camera);
const { shell } = duel.antagonist;
const shell = useDuel((state) => state.antagonist!.shell);
const greenPenetration = useTankopediaPersistent(
(state) => state.model.visual.greenPenetration,
);
const material = useRef<ShaderMaterial>(null);
const resolution = new Vector2();
const explosionCapable = isExplosive(shell.type);
let mutatedThickness = thickness;
let penetration = resolveNearPenetration(shell.penetration);
if (equipment.calibratedShells) penetration *= explosionCapable ? 1.1 : 1.05;
if (equipment.enhancedArmor) mutatedThickness *= 1.04;
useEffect(() => {
function updateQuickEquipments() {
const equipment = useTankopediaPersistent.getState().model.equipment;
const nearPenetration = resolveNearPenetration(shell.penetration);
if (material.current) {
material.current.uniforms.thickness.value =
thickness * (equipment.enhancedArmor ? 1.04 : 1);
material.current.uniforms.penetration.value =
nearPenetration *
(equipment.calibratedShells ? (explosionCapable ? 1.1 : 1.05) : 1);
}
}
const unsubscribes = [
useTankopediaPersistent.subscribe(
(state) => state.model.equipment,
updateQuickEquipments,
),
];
return () => {
unsubscribes.forEach((unsubscribe) => unsubscribe());
};
});
useFrame(({ gl, camera }) => {
if (material.current) {
@@ -84,9 +103,17 @@ export function ArmorMesh({
maxThickness: { value: maxThickness },
isExplosive: { value: explosionCapable },
canSplash: { value: canSplash(shell.type) },
thickness: { value: mutatedThickness },
thickness: {
value: thickness * (initialEquipment.enhancedArmor ? 1.04 : 1),
},
penetration: {
value: penetration,
value:
resolveNearPenetration(shell.penetration) *
(initialEquipment.calibratedShells
? explosionCapable
? 1.1
: 1.05
: 1),
},
caliber: { value: shell.caliber },
ricochetAngle: { value: degToRad(shell.ricochet ?? 90) },