feat: enhanced armor

This commit is contained in:
TrèsAbhi committed 2024-02-27 18:08:50 -06:00
1 parent d377067441
commit cc4177bf14
4 files changed
+71 -19

No files matched your search

@@ -11,9 +11,10 @@ import { degToRad } from 'three/src/math/MathUtils';
import { canSplash } from '../../../../core/blitz/canSplash'; import { canSplash } from '../../../../core/blitz/canSplash';
import { isExplosive } from '../../../../core/blitz/isExplosive'; import { isExplosive } from '../../../../core/blitz/isExplosive';
import { resolveNearPenetration } from '../../../../core/blitz/resolveNearPenetration'; import { resolveNearPenetration } from '../../../../core/blitz/resolveNearPenetration';
import { hasEquipment } from '../../../../core/blitzkrieg/hasEquipment';
import { jsxTree } from '../../../../core/blitzkrieg/jsxTree'; import { jsxTree } from '../../../../core/blitzkrieg/jsxTree';
import { ShellDefinition } from '../../../../core/blitzkrieg/tankDefinitions'; import { ShellDefinition } from '../../../../core/blitzkrieg/tankDefinitions';
import { useDuel } from '../../../../stores/duel'; import { EquipmentMatrix, useDuel } from '../../../../stores/duel';
import { import {
TankopediaPersistent, TankopediaPersistent,
useTankopediaPersistent, useTankopediaPersistent,
@@ -40,7 +41,7 @@ export function CoreArmor({ node, thickness }: CoreArmorProps) {
transparent: true, transparent: true,
uniforms: { uniforms: {
thickness: { value: thickness }, thickness: { value: null },
penetration: { value: null }, penetration: { value: null },
caliber: { value: null }, caliber: { value: null },
ricochet: { value: null }, ricochet: { value: null },
@@ -82,9 +83,16 @@ export function CoreArmor({ node, thickness }: CoreArmorProps) {
material.uniforms.opaque.value = visual.opaque || visual.wireframe; material.uniforms.opaque.value = visual.opaque || visual.wireframe;
material.wireframe = visual.wireframe; material.wireframe = visual.wireframe;
} }
async function handleEquipmentChange(equipment: EquipmentMatrix) {
const hasEnhancedArmor = await hasEquipment(110, false, equipment);
material.uniforms.thickness.value = hasEnhancedArmor
? thickness * 1.04
: thickness;
}
handleShellChange(useDuel.getState().antagonist!.shell); handleShellChange(useDuel.getState().antagonist!.shell);
handleVisualChange(useTankopediaPersistent.getState().model.visual); handleVisualChange(useTankopediaPersistent.getState().model.visual);
handleEquipmentChange(useDuel.getState().protagonist!.equipment);
const unsubscribes = [ const unsubscribes = [
useDuel.subscribe((state) => state.antagonist!.shell, handleShellChange), useDuel.subscribe((state) => state.antagonist!.shell, handleShellChange),
@@ -92,6 +100,10 @@ export function CoreArmor({ node, thickness }: CoreArmorProps) {
(state) => state.model.visual, (state) => state.model.visual,
handleVisualChange, handleVisualChange,
), ),
useDuel.subscribe(
(state) => state.protagonist!.equipment,
handleEquipmentChange,
),
]; ];
return () => { return () => {
@@ -6,9 +6,10 @@ import {
ShaderMaterial, ShaderMaterial,
} from 'three'; } from 'three';
import { resolveNearPenetration } from '../../../../../../core/blitz/resolveNearPenetration'; import { resolveNearPenetration } from '../../../../../../core/blitz/resolveNearPenetration';
import { hasEquipment } from '../../../../../../core/blitzkrieg/hasEquipment';
import { jsxTree } from '../../../../../../core/blitzkrieg/jsxTree'; import { jsxTree } from '../../../../../../core/blitzkrieg/jsxTree';
import { ShellDefinition } from '../../../../../../core/blitzkrieg/tankDefinitions'; import { ShellDefinition } from '../../../../../../core/blitzkrieg/tankDefinitions';
import { useDuel } from '../../../../../../stores/duel'; import { EquipmentMatrix, useDuel } from '../../../../../../stores/duel';
import fragmentShader from './shaders/fragment.glsl'; import fragmentShader from './shaders/fragment.glsl';
import vertexShader from './shaders/vertex.glsl'; import vertexShader from './shaders/vertex.glsl';
@@ -30,20 +31,38 @@ export function SpacedArmorSubExternal({
blending: AdditiveBlending, blending: AdditiveBlending,
uniforms: { uniforms: {
thickness: { value: thickness }, thickness: { value: null },
penetration: { value: null }, penetration: { value: null },
}, },
}); });
useEffect(() => { useEffect(() => {
function handleChange(shell: ShellDefinition) { function handleShellChange(shell: ShellDefinition) {
material.uniforms.penetration.value = resolveNearPenetration( material.uniforms.penetration.value = resolveNearPenetration(
shell.penetration, shell.penetration,
); );
} }
async function handleEquipmentChange(equipment: EquipmentMatrix) {
const hasEnhancedArmor = await hasEquipment(110, false, equipment);
material.uniforms.thickness.value = hasEnhancedArmor
? thickness * 1.04
: thickness;
}
handleChange(useDuel.getState().antagonist!.shell); handleShellChange(useDuel.getState().antagonist!.shell);
return useDuel.subscribe((state) => state.antagonist!.shell, handleChange); handleEquipmentChange(useDuel.getState().protagonist!.equipment);
const unsubscribes = [
useDuel.subscribe((state) => state.antagonist!.shell, handleShellChange),
useDuel.subscribe(
(state) => state.protagonist!.equipment,
handleEquipmentChange,
),
];
return () => {
unsubscribes.forEach((unsubscribe) => unsubscribe());
};
}, []); }, []);
return ( return (
@@ -7,9 +7,10 @@ import {
} from 'three'; } from 'three';
import { degToRad } from 'three/src/math/MathUtils'; import { degToRad } from 'three/src/math/MathUtils';
import { resolveNearPenetration } from '../../../../../../core/blitz/resolveNearPenetration'; import { resolveNearPenetration } from '../../../../../../core/blitz/resolveNearPenetration';
import { hasEquipment } from '../../../../../../core/blitzkrieg/hasEquipment';
import { jsxTree } from '../../../../../../core/blitzkrieg/jsxTree'; import { jsxTree } from '../../../../../../core/blitzkrieg/jsxTree';
import { ShellDefinition } from '../../../../../../core/blitzkrieg/tankDefinitions'; import { ShellDefinition } from '../../../../../../core/blitzkrieg/tankDefinitions';
import { useDuel } from '../../../../../../stores/duel'; import { EquipmentMatrix, useDuel } from '../../../../../../stores/duel';
import fragmentShader from './shaders/fragment.glsl'; import fragmentShader from './shaders/fragment.glsl';
import vertexShader from './shaders/vertex.glsl'; import vertexShader from './shaders/vertex.glsl';
@@ -36,7 +37,7 @@ export function SpacedArmorSubSpaced({
blending: AdditiveBlending, blending: AdditiveBlending,
uniforms: { uniforms: {
thickness: { value: thickness }, thickness: { value: null },
penetration: { value: null }, penetration: { value: null },
caliber: { value: null }, caliber: { value: null },
ricochet: { value: null }, ricochet: { value: null },
@@ -45,7 +46,7 @@ export function SpacedArmorSubSpaced({
}); });
useEffect(() => { useEffect(() => {
function handleChange(shell: ShellDefinition) { function handleShellChange(shell: ShellDefinition) {
material.uniforms.penetration.value = resolveNearPenetration( material.uniforms.penetration.value = resolveNearPenetration(
shell.penetration, shell.penetration,
); );
@@ -55,9 +56,27 @@ export function SpacedArmorSubSpaced({
shell.normalization ?? 0, shell.normalization ?? 0,
); );
} }
async function handleEquipmentChange(equipment: EquipmentMatrix) {
const hasEnhancedArmor = await hasEquipment(110, false, equipment);
material.uniforms.thickness.value = hasEnhancedArmor
? thickness * 1.04
: thickness;
}
handleChange(useDuel.getState().antagonist!.shell); handleShellChange(useDuel.getState().antagonist!.shell);
return useDuel.subscribe((state) => state.antagonist!.shell, handleChange); handleEquipmentChange(useDuel.getState().protagonist!.equipment);
const unsubscribes = [
useDuel.subscribe((state) => state.antagonist!.shell, handleShellChange),
useDuel.subscribe(
(state) => state.protagonist!.equipment,
handleEquipmentChange,
),
];
return () => {
unsubscribes.forEach((unsubscribe) => unsubscribe());
};
}, []); }, []);
return ( return (
+9 -7
View File
@@ -1,15 +1,17 @@
import { useDuel } from '../../stores/duel'; import { useDuel } from '../../stores/duel';
import { equipmentDefinitions } from './equipmentDefinitions'; import { equipmentDefinitions } from './equipmentDefinitions';
export async function hasEquipment(id: number, antagonist = false) { export async function hasEquipment(
id: number,
antagonist = false,
equipmentMatrix = useDuel.getState()[
antagonist ? 'antagonist' : 'protagonist'
]!.equipment,
) {
const awaitedEquipmentDefinitions = await equipmentDefinitions; const awaitedEquipmentDefinitions = await equipmentDefinitions;
const member = useDuel.getState()[antagonist ? 'antagonist' : 'protagonist']!; const member = useDuel.getState()[antagonist ? 'antagonist' : 'protagonist']!;
const equipmentRows = const presetRows = awaitedEquipmentDefinitions.presets[member.tank.equipment];
awaitedEquipmentDefinitions.presets[member.tank.equipment]; return presetRows.some((equipmentRow, rowIndex) => {
const equipmentMatrix =
useDuel.getState()[antagonist ? 'antagonist' : 'protagonist']!.equipment;
return equipmentRows.some((equipmentRow, rowIndex) => {
return equipmentRow.some((equipment, columnIndex) => { return equipmentRow.some((equipment, columnIndex) => {
const choice = equipmentMatrix[rowIndex][columnIndex]; const choice = equipmentMatrix[rowIndex][columnIndex];
if (choice === 0) return false; if (choice === 0) return false;