From dbc3d0df3a8f8029491cbdd3a4cb12bc5eb97b1b Mon Sep 17 00:00:00 2001
From: tresabhi <43380238+tresabhi@users.noreply.github.com>
Date: Sun, 10 Nov 2024 20:59:01 -0600
Subject: [PATCH] feat: custom shell functionality
---
.../PrimaryArmorSceneComponent/index.tsx | 19 +++++++++++----
.../SpacedArmorSubExternal/index.tsx | 21 +++++++++++------
.../components/SpacedArmorSubSpaced/index.tsx | 23 ++++++++++++-------
.../SpacedArmorSceneComponent/index.tsx | 3 ++-
.../Options/components/CustomShellButton.tsx | 8 +++++++
.../Tankopedia/HeroSection/index.tsx | 5 ++++
6 files changed, 58 insertions(+), 21 deletions(-)
diff --git a/packages/website/src/components/Armor/components/PrimaryArmorSceneComponent/index.tsx b/packages/website/src/components/Armor/components/PrimaryArmorSceneComponent/index.tsx
index 5fb0e17f2..b78ecaf0e 100644
--- a/packages/website/src/components/Armor/components/PrimaryArmorSceneComponent/index.tsx
+++ b/packages/website/src/components/Armor/components/PrimaryArmorSceneComponent/index.tsx
@@ -1,5 +1,4 @@
import {
- type ShellDefinition,
canSplash,
isExplosive,
resolvePenetrationCoefficient,
@@ -11,6 +10,7 @@ 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 { TankopediaEphemeral } from '../../../../stores/tankopediaEphemeral';
import { TankopediaPersistent } from '../../../../stores/tankopediaPersistent';
import fragmentShader from './shaders/fragment.glsl?raw';
import vertexShader from './shaders/vertex.glsl?raw';
@@ -31,6 +31,7 @@ export function PrimaryArmorSceneComponent({
}: PrimaryArmorSceneComponentProps) {
const tankopediaPersistentStore = TankopediaPersistent.useStore();
const duelStore = Duel.useStore();
+ const tankopediaEphemeralStore = TankopediaEphemeral.useStore();
const material = new ShaderMaterial({
fragmentShader,
vertexShader,
@@ -58,7 +59,11 @@ export function PrimaryArmorSceneComponent({
});
useEffect(() => {
- async function handleShellChange(shell: ShellDefinition) {
+ async function handleShellChange() {
+ const duel = duelStore.getState();
+ const tankopediaEphemeral = tankopediaEphemeralStore.getState();
+ const shell = tankopediaEphemeral.customShell ?? duel.antagonist.shell;
+
material.uniforms.caliber.value = shell.caliber;
material.uniforms.ricochet.value = degToRad(
isExplosive(shell.type) ? 90 : shell.ricochet!,
@@ -71,7 +76,6 @@ export function PrimaryArmorSceneComponent({
material.uniforms.damage.value = shell.armor_damage;
material.uniforms.explosionRadius.value = shell.explosion_radius;
- const duel = duelStore.getState();
await handleProtagonistEquipmentChange(duel.protagonist.equipmentMatrix);
await handleAntagonistEquipmentChange(duel.antagonist.equipmentMatrix);
invalidate();
@@ -104,7 +108,8 @@ export function PrimaryArmorSceneComponent({
}
async function handleAntagonistEquipmentChange(equipment: EquipmentMatrix) {
const duel = duelStore.getState();
- const shell = duel.antagonist.shell;
+ const tankopediaEphemeral = tankopediaEphemeralStore.getState();
+ const shell = tankopediaEphemeral.customShell ?? duel.antagonist.shell;
const penetration = shell.penetration.near;
const hasCalibratedShells = await hasEquipment(
103,
@@ -119,7 +124,7 @@ export function PrimaryArmorSceneComponent({
invalidate();
}
- handleShellChange(duelStore.getState().antagonist.shell);
+ handleShellChange();
handleGreenPenetrationChange(
tankopediaPersistentStore.getState().greenPenetration,
);
@@ -134,6 +139,10 @@ export function PrimaryArmorSceneComponent({
const unsubscribes = [
duelStore.subscribe((state) => state.antagonist.shell, handleShellChange),
+ tankopediaEphemeralStore.subscribe(
+ (state) => state.customShell,
+ handleShellChange,
+ ),
tankopediaPersistentStore.subscribe(
(state) => state.greenPenetration,
handleGreenPenetrationChange,
diff --git a/packages/website/src/components/Armor/components/SpacedArmorSceneComponent/components/SpacedArmorSubExternal/index.tsx b/packages/website/src/components/Armor/components/SpacedArmorSceneComponent/components/SpacedArmorSubExternal/index.tsx
index aafd08e77..4d4a162eb 100644
--- a/packages/website/src/components/Armor/components/SpacedArmorSceneComponent/components/SpacedArmorSubExternal/index.tsx
+++ b/packages/website/src/components/Armor/components/SpacedArmorSceneComponent/components/SpacedArmorSubExternal/index.tsx
@@ -1,7 +1,4 @@
-import {
- resolvePenetrationCoefficient,
- type ShellDefinition,
-} from '@blitzkit/core';
+import { resolvePenetrationCoefficient } from '@blitzkit/core';
import { invalidate } from '@react-three/fiber';
import { useEffect } from 'react';
import {
@@ -15,6 +12,7 @@ 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 { TankopediaEphemeral } from '../../../../../../stores/tankopediaEphemeral';
import { ArmorType } from '../../../SpacedArmorScene';
import fragmentShader from './shaders/fragment.glsl?raw';
import vertexShader from './shaders/vertex.glsl?raw';
@@ -32,6 +30,7 @@ export function SpacedArmorSubExternal({
variant,
clip,
}: SpacedArmorSubExternalProps) {
+ const tankopediaEphemeralStore = TankopediaEphemeral.useStore();
const duelStore = Duel.useStore();
const material = new ShaderMaterial({
fragmentShader,
@@ -50,7 +49,10 @@ export function SpacedArmorSubExternal({
});
useEffect(() => {
- function handleShellChange(shell: ShellDefinition) {
+ function handleShellChange() {
+ const duel = duelStore.getState();
+ const tankopediaEphemeral = tankopediaEphemeralStore.getState();
+ const shell = tankopediaEphemeral.customShell ?? duel.antagonist.shell;
material.uniforms.penetration.value = shell.penetration.near;
invalidate();
}
@@ -71,7 +73,8 @@ export function SpacedArmorSubExternal({
}
async function handleAntagonistEquipmentChange(equipment: EquipmentMatrix) {
const duel = duelStore.getState();
- const shell = duel.antagonist.shell;
+ const tankopediaEphemeral = tankopediaEphemeralStore.getState();
+ const shell = tankopediaEphemeral.customShell ?? duel.antagonist.shell;
const penetration = shell.penetration.near;
const hasCalibratedShells = await hasEquipment(
103,
@@ -86,7 +89,7 @@ export function SpacedArmorSubExternal({
invalidate();
}
- handleShellChange(duelStore.getState().antagonist.shell);
+ handleShellChange();
handleProtagonistEquipmentChange(
duelStore.getState().protagonist.equipmentMatrix,
);
@@ -96,6 +99,10 @@ export function SpacedArmorSubExternal({
const unsubscribes = [
duelStore.subscribe((state) => state.antagonist.shell, handleShellChange),
+ tankopediaEphemeralStore.subscribe(
+ (state) => state.customShell,
+ handleShellChange,
+ ),
duelStore.subscribe(
(state) => state.protagonist.equipmentMatrix,
handleProtagonistEquipmentChange,
diff --git a/packages/website/src/components/Armor/components/SpacedArmorSceneComponent/components/SpacedArmorSubSpaced/index.tsx b/packages/website/src/components/Armor/components/SpacedArmorSceneComponent/components/SpacedArmorSubSpaced/index.tsx
index dcf4afb79..0dbba9c45 100644
--- a/packages/website/src/components/Armor/components/SpacedArmorSceneComponent/components/SpacedArmorSubSpaced/index.tsx
+++ b/packages/website/src/components/Armor/components/SpacedArmorSceneComponent/components/SpacedArmorSubSpaced/index.tsx
@@ -1,8 +1,4 @@
-import {
- isExplosive,
- resolvePenetrationCoefficient,
- type ShellDefinition,
-} from '@blitzkit/core';
+import { isExplosive, resolvePenetrationCoefficient } from '@blitzkit/core';
import { invalidate } from '@react-three/fiber';
import { useEffect } from 'react';
import {
@@ -16,6 +12,7 @@ import type { ArmorUserData } from '../..';
import { hasEquipment } from '../../../../../../core/blitzkit/hasEquipment';
import { jsxTree } from '../../../../../../core/blitzkit/jsxTree';
import { Duel, type EquipmentMatrix } from '../../../../../../stores/duel';
+import { TankopediaEphemeral } from '../../../../../../stores/tankopediaEphemeral';
import { ArmorType } from '../../../SpacedArmorScene';
import fragmentShader from './shaders/fragment.glsl?raw';
import vertexShader from './shaders/vertex.glsl?raw';
@@ -34,6 +31,7 @@ export function SpacedArmorSubSpaced({
node,
thickness,
}: SpacedArmorSubSpacedProps) {
+ const tankopediaEphemeralStore = TankopediaEphemeral.useStore();
const duelStore = Duel.useStore();
const material = new ShaderMaterial({
fragmentShader,
@@ -53,7 +51,11 @@ export function SpacedArmorSubSpaced({
});
useEffect(() => {
- function handleShellChange(shell: ShellDefinition) {
+ function handleShellChange() {
+ const duel = duelStore.getState();
+ const tankopediaEphemeral = tankopediaEphemeralStore.getState();
+ const shell = tankopediaEphemeral.customShell ?? duel.antagonist.shell;
+
material.uniforms.penetration.value = shell.penetration.near;
material.uniforms.caliber.value = shell.caliber;
material.uniforms.ricochet.value = degToRad(
@@ -82,7 +84,8 @@ export function SpacedArmorSubSpaced({
}
async function handleAntagonistEquipmentChange(equipment: EquipmentMatrix) {
const duel = duelStore.getState();
- const shell = duelStore.getState().antagonist.shell;
+ const tankopediaEphemeral = tankopediaEphemeralStore.getState();
+ const shell = tankopediaEphemeral.customShell ?? duel.antagonist.shell;
const penetration = shell.penetration.near;
const hasCalibratedShells = await hasEquipment(
103,
@@ -97,7 +100,7 @@ export function SpacedArmorSubSpaced({
invalidate();
}
- handleShellChange(duelStore.getState().antagonist.shell);
+ handleShellChange();
handleProtagonistEquipmentChange(
duelStore.getState().protagonist.equipmentMatrix,
);
@@ -107,6 +110,10 @@ export function SpacedArmorSubSpaced({
const unsubscribes = [
duelStore.subscribe((state) => state.antagonist.shell, handleShellChange),
+ tankopediaEphemeralStore.subscribe(
+ (state) => state.customShell,
+ handleShellChange,
+ ),
duelStore.subscribe(
(state) => state.protagonist.equipmentMatrix,
handleProtagonistEquipmentChange,
diff --git a/packages/website/src/components/Armor/components/SpacedArmorSceneComponent/index.tsx b/packages/website/src/components/Armor/components/SpacedArmorSceneComponent/index.tsx
index d1ee159ef..5f038985e 100644
--- a/packages/website/src/components/Armor/components/SpacedArmorSceneComponent/index.tsx
+++ b/packages/website/src/components/Armor/components/SpacedArmorSceneComponent/index.tsx
@@ -88,7 +88,8 @@ export function SpacedArmorSceneComponent({
remainingPenetrationInput?: number,
) => {
const { antagonist, protagonist } = duelStore.getState();
- const shell = antagonist.shell;
+ const { customShell } = tankopediaEphemeralStore.getState();
+ const shell = customShell ?? antagonist.shell;
const cameraNormal = camera.position.clone().sub(point).normalize();
const shot: Shot = {
splashRadius: shell.explosion_radius,
diff --git a/packages/website/src/components/Tankopedia/HeroSection/components/Options/components/CustomShellButton.tsx b/packages/website/src/components/Tankopedia/HeroSection/components/Options/components/CustomShellButton.tsx
index 495b6b802..815df2d02 100644
--- a/packages/website/src/components/Tankopedia/HeroSection/components/Options/components/CustomShellButton.tsx
+++ b/packages/website/src/components/Tankopedia/HeroSection/components/Options/components/CustomShellButton.tsx
@@ -200,6 +200,14 @@ export function CustomShellButton() {
Cancel
+