Merge pull request #273 from Hitjack007/consumable-armor-view

This commit is contained in:
TrèsAbhi authored and GitHub committed 2026-10-02 14:34:28 -07:00
commit 802f04bbe6
1 file changed
+54 -50
@@ -5,7 +5,7 @@ import {
} from "@blitzkit/core"; } from "@blitzkit/core";
import { invalidate, useFrame } from "@react-three/fiber"; import { invalidate, useFrame } from "@react-three/fiber";
import type { QuicklimeEvent } from "quicklime"; import type { QuicklimeEvent } from "quicklime";
import { useEffect } from "react"; import { useEffect, useRef } from "react";
import { import {
MeshBasicMaterial, MeshBasicMaterial,
NormalBlending, NormalBlending,
@@ -43,42 +43,44 @@ export function PrimaryArmorSceneComponent({
node, node,
thickness, thickness,
}: PrimaryArmorSceneComponentProps) { }: PrimaryArmorSceneComponentProps) {
const material = new ShaderMaterial({ const material = useRef(
fragmentShader, new ShaderMaterial({
vertexShader, fragmentShader,
vertexShader,
fog: true, fog: true,
transparent: true, transparent: true,
blending: isHalloween ? SubtractiveBlending : NormalBlending, blending: isHalloween ? SubtractiveBlending : NormalBlending,
uniforms: UniformsUtils.merge([ uniforms: UniformsUtils.merge([
UniformsLib.common, UniformsLib.common,
UniformsLib.fog, UniformsLib.fog,
{ {
thickness: { value: null }, thickness: { value: null },
penetration: { value: null }, penetration: { value: null },
caliber: { value: null }, caliber: { value: null },
ricochet: { value: null }, ricochet: { value: null },
normalization: { value: null }, normalization: { value: null },
isExplosive: { value: null }, isExplosive: { value: null },
canSplash: { value: null }, canSplash: { value: null },
damage: { value: null }, damage: { value: null },
explosionRadius: { value: null }, explosionRadius: { value: null },
greenPenetration: { value: null }, greenPenetration: { value: null },
advancedHighlighting: { value: null }, advancedHighlighting: { value: null },
opaque: { value: null }, opaque: { value: null },
inverseProjectionMatrix: { value: null }, inverseProjectionMatrix: { value: null },
resolution: { value: new Vector2() }, resolution: { value: new Vector2() },
spacedArmorBuffer: { value: null }, spacedArmorBuffer: { value: null },
spacedArmorDepth: { value: null }, spacedArmorDepth: { value: null },
opacity: { value: 0 }, opacity: { value: 0 },
}, },
]), ]),
}); }),
);
useEffect(() => { useEffect(() => {
function handleShellChange() { function handleShellChange() {
@@ -86,17 +88,17 @@ export function PrimaryArmorSceneComponent({
const shell = const shell =
tankopediaEphemeral.customShell ?? Duel.state.antagonist.shell; tankopediaEphemeral.customShell ?? Duel.state.antagonist.shell;
material.uniforms.caliber.value = shell.caliber; material.current.uniforms.caliber.value = shell.caliber;
material.uniforms.ricochet.value = degToRad( material.current.uniforms.ricochet.value = degToRad(
isExplosive(shell.type) ? 90 : shell.ricochet!, isExplosive(shell.type) ? 90 : shell.ricochet!,
); );
material.uniforms.normalization.value = degToRad( material.current.uniforms.normalization.value = degToRad(
shell.normalization ?? 0, shell.normalization ?? 0,
); );
material.uniforms.isExplosive.value = isExplosive(shell.type); material.current.uniforms.isExplosive.value = isExplosive(shell.type);
material.uniforms.canSplash.value = canSplash(shell.type); material.current.uniforms.canSplash.value = canSplash(shell.type);
material.uniforms.damage.value = shell.armor_damage; material.current.uniforms.damage.value = shell.armor_damage;
material.uniforms.explosionRadius.value = shell.explosion_radius; material.current.uniforms.explosionRadius.value = shell.explosion_radius;
handleProtagonistEquipmentChange(true); handleProtagonistEquipmentChange(true);
handleAntagonistEquipmentChange(true); handleAntagonistEquipmentChange(true);
@@ -104,17 +106,18 @@ export function PrimaryArmorSceneComponent({
invalidate(); invalidate();
} }
function handleGreenPenetrationChange(greenPenetration: boolean) { function handleGreenPenetrationChange(greenPenetration: boolean) {
material.uniforms.greenPenetration.value = greenPenetration; material.current.uniforms.greenPenetration.value = greenPenetration;
} }
function handleAdvancedHighlightingChange(advancedHighlighting: boolean) { function handleAdvancedHighlightingChange(advancedHighlighting: boolean) {
material.uniforms.advancedHighlighting.value = advancedHighlighting; material.current.uniforms.advancedHighlighting.value =
advancedHighlighting;
invalidate(); invalidate();
} }
function handleOpaqueChange(opaque: boolean) { function handleOpaqueChange(opaque: boolean) {
material.uniforms.opaque.value = opaque; material.current.uniforms.opaque.value = opaque;
} }
function handleWireframeChange(wireframe: boolean) { function handleWireframeChange(wireframe: boolean) {
material.wireframe = wireframe; material.current.wireframe = wireframe;
} }
function handleProtagonistEquipmentChange(noInvalidate = false) { function handleProtagonistEquipmentChange(noInvalidate = false) {
const equipment = Duel.state.protagonist.equipmentMatrix; const equipment = Duel.state.protagonist.equipmentMatrix;
@@ -128,7 +131,7 @@ export function PrimaryArmorSceneComponent({
? Duel.state.protagonist.tank.equalizer?.armor ? Duel.state.protagonist.tank.equalizer?.armor
: undefined) ?? 1; : undefined) ?? 1;
material.uniforms.thickness.value = material.current.uniforms.thickness.value =
thickness * (hasEnhancedArmor ? 1.04 : 1) * equalizer; thickness * (hasEnhancedArmor ? 1.04 : 1) * equalizer;
if (!noInvalidate) invalidate(); if (!noInvalidate) invalidate();
@@ -145,7 +148,7 @@ export function PrimaryArmorSceneComponent({
equipment, equipment,
); );
material.uniforms.penetration.value = material.current.uniforms.penetration.value =
penetration * penetration *
resolvePenetrationCoefficient( resolvePenetrationCoefficient(
hasCalibratedShells, hasCalibratedShells,
@@ -158,7 +161,7 @@ export function PrimaryArmorSceneComponent({
} }
function handleTransitionEvent(event: QuicklimeEvent<number>) { function handleTransitionEvent(event: QuicklimeEvent<number>) {
material.uniforms.opacity.value = event.data; material.current.uniforms.opacity.value = event.data;
} }
handleShellChange(); handleShellChange();
@@ -209,13 +212,14 @@ export function PrimaryArmorSceneComponent({
}, []); }, []);
useFrame(({ gl, camera }) => { useFrame(({ gl, camera }) => {
gl.getSize(material.uniforms.resolution.value).multiplyScalar( gl.getSize(material.current.uniforms.resolution.value).multiplyScalar(
gl.getPixelRatio(), gl.getPixelRatio(),
); );
material.uniforms.spacedArmorBuffer.value = spacedArmorRenderTarget.texture; material.current.uniforms.spacedArmorBuffer.value =
material.uniforms.spacedArmorDepth.value = spacedArmorRenderTarget.texture;
material.current.uniforms.spacedArmorDepth.value =
spacedArmorRenderTarget.depthTexture; spacedArmorRenderTarget.depthTexture;
material.uniforms.inverseProjectionMatrix.value = material.current.uniforms.inverseProjectionMatrix.value =
camera.projectionMatrixInverse; camera.projectionMatrixInverse;
}); });
@@ -240,7 +244,7 @@ export function PrimaryArmorSceneComponent({
{...props} {...props}
key={`${key}-include`} key={`${key}-include`}
renderOrder={1} renderOrder={1}
material={material} material={material.current}
/> />
); );
}, },