From d89575b25deeef3b56c9eb8467fdf20bac6e8736 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tr=C3=A8sAbhi?= <43380238+tresabhi@users.noreply.github.com>
Date: Sat, 3 Feb 2024 12:16:33 -0600
Subject: [PATCH] feat: he based gaps
---
.../ArmorMesh/components/Armor/index.tsx | 50 +++++++++++++++----
src/components/ShotDisplay.tsx | 23 ++++++---
src/stores/tankopedia.ts | 19 ++++---
3 files changed, 68 insertions(+), 24 deletions(-)
diff --git a/src/components/ArmorMesh/components/Armor/index.tsx b/src/components/ArmorMesh/components/Armor/index.tsx
index 7263fb04a..11074b576 100644
--- a/src/components/ArmorMesh/components/Armor/index.tsx
+++ b/src/components/ArmorMesh/components/Armor/index.tsx
@@ -186,22 +186,18 @@ export function ArmorMesh({
if (mesh.current !== (coreArmorMesh as unknown as Mesh)) return;
- let accumulatedThickness = 0;
- const armorPiercingLayers = intersectionsTillFirstCoreArmor.map(
+ const armorPiercingLayersRaw = intersectionsTillFirstCoreArmor.map(
(event, index) => {
switch (event.object.userData.type) {
case 'externalModule': {
- accumulatedThickness +=
- event.object.userData.thickness * thicknessCoefficient;
-
return {
nominal:
event.object.userData.thickness * thicknessCoefficient,
angled:
event.object.userData.thickness * thicknessCoefficient,
ricochet: false,
- block: accumulatedThickness > resolvedPenetration,
type: 'external',
+ distance: event.distance,
} satisfies ArmorPiercingLayer;
}
@@ -235,28 +231,62 @@ export function ArmorMesh({
const angled =
(event.object.userData.thickness * thicknessCoefficient) /
Math.cos(angle - degToRad(normalization));
- accumulatedThickness += angled;
return {
nominal:
event.object.userData.thickness * thicknessCoefficient,
angled,
ricochet,
- block: accumulatedThickness > resolvedPenetration,
type:
event.object.userData.type === 'coreArmor'
? 'core'
: 'spaced',
+ distance: event.distance,
} satisfies ArmorPiercingLayer;
}
}
},
);
+ const gaps = armorPiercingLayersRaw.map((layerA, aIndex) => {
+ if (aIndex === armorPiercingLayersRaw.length - 1) return null;
+ const layerB = armorPiercingLayersRaw[aIndex + 1];
+
+ return {
+ type: 'gap',
+ gap: Math.abs(layerB.distance - layerA.distance),
+ } satisfies ArmorPiercingLayer;
+ });
+ const armorPiercingLayers: ArmorPiercingLayer[] = [];
+
+ armorPiercingLayersRaw.forEach((layer, index) => {
+ const gap = gaps[index];
+
+ armorPiercingLayers.push(layer);
+ if (gap) armorPiercingLayers.push(gap);
+ });
+
+ console.log(armorPiercingLayers);
+
+ let remainingPenetration = resolvedPenetration;
+ let accumulatedThickness = 0;
+ const explosiveCapable = isExplosive(shell.type);
+
+ armorPiercingLayers.forEach((layer) => {
+ if (layer.type !== 'gap') {
+ remainingPenetration -= layer.angled;
+ accumulatedThickness += layer.angled;
+ } else if (explosiveCapable) {
+ // there is a 50% penetration loss per meter for HE based shells
+ remainingPenetration -= 0.5 * remainingPenetration * layer.gap;
+ }
+
+ remainingPenetration = Math.max(0, remainingPenetration);
+ });
const hasRicochet = armorPiercingLayers.some(
- ({ ricochet }) => ricochet,
+ (layer) => layer.type !== 'gap' && layer.ricochet,
);
- const hasPenetrated = resolvedPenetration >= accumulatedThickness;
+ const hasPenetrated = remainingPenetration >= accumulatedThickness;
mutateTankopediaTemporary((draft) => {
draft.shot = {
diff --git a/src/components/ShotDisplay.tsx b/src/components/ShotDisplay.tsx
index 16e3f6378..6910b8ea7 100644
--- a/src/components/ShotDisplay.tsx
+++ b/src/components/ShotDisplay.tsx
@@ -106,23 +106,32 @@ export function ShotDisplay() {
paddingLeft: shot.thicknesses.length > 1 ? 8 : undefined,
}}
>
- {shot.thicknesses.map(({ nominal, angled, type }, index) => (
+ {shot.thicknesses.map((layer, index) => (
{shot.thicknesses.length > 1 && (
- {index + 1}. {type[0].toUpperCase()}
- {type.slice(1)}
+ {index + 1}. {layer.type[0].toUpperCase()}
+ {layer.type.slice(1)}
)}
-
- {nominal}mm
+ {layer.type !== 'gap' && (
+
+ )}
+
+ {Math.round(
+ layer.type === 'gap'
+ ? layer.gap * 1000
+ : layer.nominal,
+ )}
+ mm
+
- {type !== 'external' && (
+ {layer.type !== 'external' && layer.type !== 'gap' && (
- {Math.round(angled)}mm
+ {Math.round(layer.angled)}mm
)}
diff --git a/src/stores/tankopedia.ts b/src/stores/tankopedia.ts
index 4fba02d7b..eccabe1d5 100644
--- a/src/stores/tankopedia.ts
+++ b/src/stores/tankopedia.ts
@@ -76,13 +76,18 @@ export type Shot = {
angle: number;
};
-export interface ArmorPiercingLayer {
- nominal: number;
- angled: number;
- ricochet: boolean;
- block: boolean;
- type: 'core' | 'spaced' | 'external';
-}
+export type ArmorPiercingLayer =
+ | {
+ distance: number;
+ nominal: number;
+ angled: number;
+ ricochet: boolean;
+ type: 'core' | 'spaced' | 'external';
+ }
+ | {
+ type: 'gap';
+ gap: number;
+ };
export const useTankopediaPersistent = create()(
persist(