mirror of
https://github.com/blitzkit/blitzkit.git
synced 2026-10-21 02:37:05 +02:00
feat: equalizer for visual armor sandbox
This commit is contained in:
1 parent
145de2bbbc
commit
1a008a4852
5 files changed
+96
-55
No files matched your search
+31
-25
@@ -19,7 +19,7 @@ import {
|
||||
import { degToRad } from "three/src/math/MathUtils.js";
|
||||
import { hasEquipment } from "../../../../core/blitzkit/hasEquipment";
|
||||
import { jsxTree } from "../../../../core/blitzkit/jsxTree";
|
||||
import { Duel, type EquipmentMatrix } from "../../../../stores/duel";
|
||||
import { Duel } from "../../../../stores/duel";
|
||||
import { Tankopedia } from "../../../../stores/tankopedia";
|
||||
import { TankopediaPersistent } from "../../../../stores/tankopediaPersistent";
|
||||
import { transitionEvent } from "../../../Tankopedia/HeroSection/components/TankSandbox/components/Lighting";
|
||||
@@ -98,14 +98,8 @@ export function PrimaryArmorSceneComponent({
|
||||
material.uniforms.damage.value = shell.armor_damage;
|
||||
material.uniforms.explosionRadius.value = shell.explosion_radius;
|
||||
|
||||
handleProtagonistEquipmentChange(
|
||||
Duel.state.protagonist.equipmentMatrix,
|
||||
true,
|
||||
);
|
||||
handleAntagonistEquipmentChange(
|
||||
Duel.state.antagonist.equipmentMatrix,
|
||||
true,
|
||||
);
|
||||
handleProtagonistEquipmentChange(true);
|
||||
handleAntagonistEquipmentChange(true);
|
||||
|
||||
invalidate();
|
||||
}
|
||||
@@ -122,25 +116,25 @@ export function PrimaryArmorSceneComponent({
|
||||
function handleWireframeChange(wireframe: boolean) {
|
||||
material.wireframe = wireframe;
|
||||
}
|
||||
function handleProtagonistEquipmentChange(
|
||||
equipment: EquipmentMatrix,
|
||||
noInvalidate = false,
|
||||
) {
|
||||
function handleProtagonistEquipmentChange(noInvalidate = false) {
|
||||
const equipment = Duel.state.protagonist.equipmentMatrix;
|
||||
const hasEnhancedArmor = hasEquipment(
|
||||
110,
|
||||
Duel.state.protagonist.tank.equipment_preset,
|
||||
equipment,
|
||||
);
|
||||
material.uniforms.thickness.value = hasEnhancedArmor
|
||||
? thickness * 1.03
|
||||
: thickness;
|
||||
const equalizer =
|
||||
(Duel.state.equalize
|
||||
? Duel.state.protagonist.tank.equalizer?.armor
|
||||
: undefined) ?? 1;
|
||||
|
||||
material.uniforms.thickness.value =
|
||||
thickness * (hasEnhancedArmor ? 1.03 : 1) * equalizer;
|
||||
|
||||
if (!noInvalidate) invalidate();
|
||||
}
|
||||
function handleAntagonistEquipmentChange(
|
||||
equipment: EquipmentMatrix,
|
||||
noInvalidate = false,
|
||||
) {
|
||||
function handleAntagonistEquipmentChange(noInvalidate = false) {
|
||||
const equipment = Duel.state.antagonist.equipmentMatrix;
|
||||
const tankopediaEphemeral = Tankopedia.state;
|
||||
const shell =
|
||||
tankopediaEphemeral.customShell ?? Duel.state.antagonist.shell;
|
||||
@@ -150,10 +144,15 @@ export function PrimaryArmorSceneComponent({
|
||||
Duel.state.antagonist.tank.equipment_preset,
|
||||
equipment,
|
||||
);
|
||||
const equalize =
|
||||
(Duel.state.equalize
|
||||
? Duel.state.antagonist.tank.equalizer?.penetration
|
||||
: undefined) ?? 1;
|
||||
|
||||
material.uniforms.penetration.value =
|
||||
penetration *
|
||||
resolvePenetrationCoefficient(hasCalibratedShells, shell.type);
|
||||
resolvePenetrationCoefficient(hasCalibratedShells, shell.type) *
|
||||
equalize;
|
||||
|
||||
if (!noInvalidate) invalidate();
|
||||
}
|
||||
@@ -169,8 +168,8 @@ export function PrimaryArmorSceneComponent({
|
||||
);
|
||||
handleOpaqueChange(TankopediaPersistent.state.opaque);
|
||||
handleWireframeChange(TankopediaPersistent.state.wireframe);
|
||||
handleProtagonistEquipmentChange(Duel.state.protagonist.equipmentMatrix);
|
||||
handleAntagonistEquipmentChange(Duel.state.antagonist.equipmentMatrix);
|
||||
handleProtagonistEquipmentChange();
|
||||
handleAntagonistEquipmentChange();
|
||||
|
||||
transitionEvent.on(handleTransitionEvent);
|
||||
|
||||
@@ -188,11 +187,18 @@ export function PrimaryArmorSceneComponent({
|
||||
TankopediaPersistent.on((state) => state.opaque, handleOpaqueChange),
|
||||
Duel.on(
|
||||
(state) => state.protagonist.equipmentMatrix,
|
||||
(equipment) => handleProtagonistEquipmentChange(equipment),
|
||||
() => handleProtagonistEquipmentChange(),
|
||||
),
|
||||
Duel.on(
|
||||
(state) => state.antagonist.equipmentMatrix,
|
||||
(equipment) => handleAntagonistEquipmentChange(equipment),
|
||||
() => handleAntagonistEquipmentChange(),
|
||||
),
|
||||
Duel.on(
|
||||
(state) => state.equalize,
|
||||
() => {
|
||||
handleProtagonistEquipmentChange();
|
||||
handleAntagonistEquipmentChange();
|
||||
},
|
||||
),
|
||||
() => transitionEvent.off(handleTransitionEvent),
|
||||
];
|
||||
|
||||
@@ -52,7 +52,7 @@ export function ShotDisplay() {
|
||||
useEffect(() => {
|
||||
if (shot?.splashRadius !== undefined) {
|
||||
const outlineGeometry = new BufferGeometry().setFromPoints(
|
||||
new Path().absarc(0, 0, 1, 0, Math.PI * 2).getSpacedPoints(50)
|
||||
new Path().absarc(0, 0, 1, 0, Math.PI * 2).getSpacedPoints(50),
|
||||
);
|
||||
const outlineMaterial = new LineDashedMaterial({
|
||||
color: "orange",
|
||||
@@ -61,7 +61,7 @@ export function ShotDisplay() {
|
||||
});
|
||||
const outline = new Line(
|
||||
outlineGeometry,
|
||||
outlineMaterial
|
||||
outlineMaterial,
|
||||
).computeLineDistances();
|
||||
|
||||
splashRadiusWrapper.current?.add(outline);
|
||||
@@ -134,11 +134,11 @@ export function ShotDisplay() {
|
||||
const outLength =
|
||||
shot.out && shot.out.layers.length > 0
|
||||
? (shot.in.layers.at(-1) as ShotLayerNonExternal).point.distanceTo(
|
||||
(shot.out.layers.at(-1) as ShotLayerNonExternal).point
|
||||
(shot.out.layers.at(-1) as ShotLayerNonExternal).point,
|
||||
)
|
||||
: SHOT_DISPLAY_LENGTH_INFINITY;
|
||||
const inLast = shot.in.layers.findLast(
|
||||
(layer) => layer.type !== null
|
||||
(layer) => layer.type !== null,
|
||||
) as ShotLayerNonExternal;
|
||||
const outTitleColor = shot.out
|
||||
? shotStatusColors[shot.out.status]
|
||||
@@ -154,7 +154,7 @@ export function ShotDisplay() {
|
||||
position={inLast.point}
|
||||
ref={splashRadiusWrapper}
|
||||
rotation={new Euler().setFromQuaternion(
|
||||
new Quaternion().setFromUnitVectors(K_HAT, shot.in.surfaceNormal)
|
||||
new Quaternion().setFromUnitVectors(K_HAT, shot.in.surfaceNormal),
|
||||
)}
|
||||
>
|
||||
<mesh>
|
||||
@@ -225,7 +225,7 @@ export function ShotDisplay() {
|
||||
<group
|
||||
position={inLast.point}
|
||||
rotation={new Euler().setFromQuaternion(
|
||||
new Quaternion().setFromUnitVectors(J_HAT, shot.in.surfaceNormal)
|
||||
new Quaternion().setFromUnitVectors(J_HAT, shot.in.surfaceNormal),
|
||||
)}
|
||||
>
|
||||
<mesh position={[0, inLength / 2, 0]} renderOrder={2}>
|
||||
@@ -253,8 +253,8 @@ export function ShotDisplay() {
|
||||
rotation={new Euler().setFromQuaternion(
|
||||
new Quaternion().setFromUnitVectors(
|
||||
J_HAT,
|
||||
shot.out.surfaceNormal.clone()
|
||||
)
|
||||
shot.out.surfaceNormal.clone(),
|
||||
),
|
||||
)}
|
||||
>
|
||||
<mesh position={[0, outLength / 2, 0]} renderOrder={2}>
|
||||
|
||||
+27
-9
@@ -10,7 +10,7 @@ import {
|
||||
import type { ArmorUserData, ExternalModuleVariant } from "../..";
|
||||
import { hasEquipment } from "../../../../../../core/blitzkit/hasEquipment";
|
||||
import { jsxTree } from "../../../../../../core/blitzkit/jsxTree";
|
||||
import { Duel, type EquipmentMatrix } from "../../../../../../stores/duel";
|
||||
import { Duel } from "../../../../../../stores/duel";
|
||||
import { Tankopedia } from "../../../../../../stores/tankopedia";
|
||||
import { ArmorType } from "../../../SpacedArmorScene";
|
||||
import fragmentShader from "./shaders/fragment.glsl?raw";
|
||||
@@ -52,17 +52,23 @@ export function SpacedArmorSubExternal({
|
||||
tankopediaEphemeral.customShell ?? Duel.state.antagonist.shell;
|
||||
material.uniforms.penetration.value = shell.penetration!.near;
|
||||
}
|
||||
function handleProtagonistEquipmentChange(equipment: EquipmentMatrix) {
|
||||
function handleProtagonistEquipmentChange() {
|
||||
const equipment = Duel.state.protagonist.equipmentMatrix;
|
||||
const hasEnhancedArmor = hasEquipment(
|
||||
110,
|
||||
Duel.state.protagonist.tank.equipment_preset,
|
||||
equipment,
|
||||
);
|
||||
material.uniforms.thickness.value = hasEnhancedArmor
|
||||
? thickness * 1.03
|
||||
: thickness;
|
||||
const equalizer =
|
||||
(Duel.state.equalize
|
||||
? Duel.state.protagonist.tank.equalizer?.armor
|
||||
: undefined) ?? 1;
|
||||
|
||||
material.uniforms.thickness.value =
|
||||
thickness * (hasEnhancedArmor ? 1.03 : 1) * equalizer;
|
||||
}
|
||||
function handleAntagonistEquipmentChange(equipment: EquipmentMatrix) {
|
||||
function handleAntagonistEquipmentChange() {
|
||||
const equipment = Duel.state.antagonist.equipmentMatrix;
|
||||
const tankopediaEphemeral = Tankopedia.state;
|
||||
const shell =
|
||||
tankopediaEphemeral.customShell ?? Duel.state.antagonist.shell;
|
||||
@@ -72,15 +78,20 @@ export function SpacedArmorSubExternal({
|
||||
Duel.state.antagonist.tank.equipment_preset,
|
||||
equipment,
|
||||
);
|
||||
const equalize =
|
||||
(Duel.state.equalize
|
||||
? Duel.state.antagonist.tank.equalizer?.penetration
|
||||
: undefined) ?? 1;
|
||||
|
||||
material.uniforms.penetration.value =
|
||||
penetration *
|
||||
resolvePenetrationCoefficient(hasCalibratedShells, shell.type);
|
||||
resolvePenetrationCoefficient(hasCalibratedShells, shell.type) *
|
||||
equalize;
|
||||
}
|
||||
|
||||
handleShellChange();
|
||||
handleProtagonistEquipmentChange(Duel.state.protagonist.equipmentMatrix);
|
||||
handleAntagonistEquipmentChange(Duel.state.antagonist.equipmentMatrix);
|
||||
handleProtagonistEquipmentChange();
|
||||
handleAntagonistEquipmentChange();
|
||||
|
||||
const unsubscribes = [
|
||||
Duel.on((state) => state.antagonist.shell, handleShellChange),
|
||||
@@ -93,6 +104,13 @@ export function SpacedArmorSubExternal({
|
||||
(state) => state.antagonist.equipmentMatrix,
|
||||
handleAntagonistEquipmentChange,
|
||||
),
|
||||
Duel.on(
|
||||
(state) => state.equalize,
|
||||
() => {
|
||||
handleProtagonistEquipmentChange();
|
||||
handleAntagonistEquipmentChange();
|
||||
},
|
||||
),
|
||||
];
|
||||
|
||||
return () => {
|
||||
|
||||
+27
-9
@@ -10,7 +10,7 @@ import { degToRad } from "three/src/math/MathUtils.js";
|
||||
import type { ArmorUserData } from "../..";
|
||||
import { hasEquipment } from "../../../../../../core/blitzkit/hasEquipment";
|
||||
import { jsxTree } from "../../../../../../core/blitzkit/jsxTree";
|
||||
import { Duel, type EquipmentMatrix } from "../../../../../../stores/duel";
|
||||
import { Duel } from "../../../../../../stores/duel";
|
||||
import { Tankopedia } from "../../../../../../stores/tankopedia";
|
||||
import { ArmorType } from "../../../SpacedArmorScene";
|
||||
import fragmentShader from "./shaders/fragment.glsl?raw";
|
||||
@@ -62,17 +62,23 @@ export function SpacedArmorSubSpaced({
|
||||
shell.normalization ?? 0,
|
||||
);
|
||||
}
|
||||
function handleProtagonistEquipmentChange(equipment: EquipmentMatrix) {
|
||||
function handleProtagonistEquipmentChange() {
|
||||
const equipment = Duel.state.protagonist.equipmentMatrix;
|
||||
const hasEnhancedArmor = hasEquipment(
|
||||
110,
|
||||
Duel.state.protagonist.tank.equipment_preset,
|
||||
equipment,
|
||||
);
|
||||
material.uniforms.thickness.value = hasEnhancedArmor
|
||||
? thickness * 1.03
|
||||
: thickness;
|
||||
const equalizer =
|
||||
(Duel.state.equalize
|
||||
? Duel.state.protagonist.tank.equalizer?.armor
|
||||
: undefined) ?? 1;
|
||||
|
||||
material.uniforms.thickness.value =
|
||||
thickness * (hasEnhancedArmor ? 1.03 : 1) * equalizer;
|
||||
}
|
||||
function handleAntagonistEquipmentChange(equipment: EquipmentMatrix) {
|
||||
function handleAntagonistEquipmentChange() {
|
||||
const equipment = Duel.state.antagonist.equipmentMatrix;
|
||||
const tankopediaEphemeral = Tankopedia.state;
|
||||
const shell =
|
||||
tankopediaEphemeral.customShell ?? Duel.state.antagonist.shell;
|
||||
@@ -82,15 +88,20 @@ export function SpacedArmorSubSpaced({
|
||||
Duel.state.antagonist.tank.equipment_preset,
|
||||
equipment,
|
||||
);
|
||||
const equalize =
|
||||
(Duel.state.equalize
|
||||
? Duel.state.antagonist.tank.equalizer?.penetration
|
||||
: undefined) ?? 1;
|
||||
|
||||
material.uniforms.penetration.value =
|
||||
penetration *
|
||||
resolvePenetrationCoefficient(hasCalibratedShells, shell.type);
|
||||
resolvePenetrationCoefficient(hasCalibratedShells, shell.type) *
|
||||
equalize;
|
||||
}
|
||||
|
||||
handleShellChange();
|
||||
handleProtagonistEquipmentChange(Duel.state.protagonist.equipmentMatrix);
|
||||
handleAntagonistEquipmentChange(Duel.state.antagonist.equipmentMatrix);
|
||||
handleProtagonistEquipmentChange();
|
||||
handleAntagonistEquipmentChange();
|
||||
|
||||
const unsubscribes = [
|
||||
Duel.on((state) => state.antagonist.shell, handleShellChange),
|
||||
@@ -103,6 +114,13 @@ export function SpacedArmorSubSpaced({
|
||||
(state) => state.antagonist.equipmentMatrix,
|
||||
handleAntagonistEquipmentChange,
|
||||
),
|
||||
Duel.on(
|
||||
(state) => state.equalize,
|
||||
() => {
|
||||
handleProtagonistEquipmentChange();
|
||||
handleAntagonistEquipmentChange();
|
||||
},
|
||||
),
|
||||
];
|
||||
|
||||
return () => {
|
||||
|
||||
+3
-4
@@ -18,7 +18,6 @@ import {
|
||||
import { degToRad } from "three/src/math/MathUtils.js";
|
||||
import { hasEquipment } from "../../../../core/blitzkit/hasEquipment";
|
||||
import { jsxTree } from "../../../../core/blitzkit/jsxTree";
|
||||
import { defaultEqualizer } from "../../../../core/blitzkit/tankToDuelMember";
|
||||
import { discardClippingPlane } from "../../../../core/three/discardClippingPlane";
|
||||
import { Duel } from "../../../../stores/duel";
|
||||
import {
|
||||
@@ -90,8 +89,8 @@ export function SpacedArmorSceneComponent({
|
||||
const shell = customShell ?? Duel.state.antagonist.shell;
|
||||
const { equalize } = Duel.state;
|
||||
const equalizer =
|
||||
(equalize ? Duel.state.antagonist.tank.equalizer : undefined) ??
|
||||
defaultEqualizer;
|
||||
(equalize ? Duel.state.antagonist.tank.equalizer?.damage : undefined) ??
|
||||
1;
|
||||
const cameraNormal = camera.position.clone().sub(point).normalize();
|
||||
const shot: Shot = {
|
||||
splashRadius:
|
||||
@@ -372,7 +371,7 @@ export function SpacedArmorSceneComponent({
|
||||
}
|
||||
}
|
||||
|
||||
shot.damage *= equalizer.damage;
|
||||
shot.damage *= equalizer;
|
||||
|
||||
return shot;
|
||||
},
|
||||
|
||||
Reference in new issue
Block a user