mirror of
https://github.com/blitzkit/blitzkit.git
synced 2026-10-21 18:57:03 +02:00
feat: he based gaps
This commit is contained in:
1 parent
8f9306a3db
commit
d89575b25d
3 files changed
+68
-24
No files matched your search
@@ -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 = {
|
||||
|
||||
@@ -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) => (
|
||||
<Flex gap="2">
|
||||
{shot.thicknesses.length > 1 && (
|
||||
<Text>
|
||||
{index + 1}. {type[0].toUpperCase()}
|
||||
{type.slice(1)}
|
||||
{index + 1}. {layer.type[0].toUpperCase()}
|
||||
{layer.type.slice(1)}
|
||||
</Text>
|
||||
)}
|
||||
|
||||
<Flex gap="1">
|
||||
<NominalPenetration width={24} height={24} />
|
||||
<Text>{nominal}mm</Text>
|
||||
{layer.type !== 'gap' && (
|
||||
<NominalPenetration width={24} height={24} />
|
||||
)}
|
||||
<Text>
|
||||
{Math.round(
|
||||
layer.type === 'gap'
|
||||
? layer.gap * 1000
|
||||
: layer.nominal,
|
||||
)}
|
||||
mm
|
||||
</Text>
|
||||
</Flex>
|
||||
{type !== 'external' && (
|
||||
{layer.type !== 'external' && layer.type !== 'gap' && (
|
||||
<Flex gap="1">
|
||||
<AngledPenetration width={24} height={24} />
|
||||
<Text>{Math.round(angled)}mm</Text>
|
||||
<Text>{Math.round(layer.angled)}mm</Text>
|
||||
</Flex>
|
||||
)}
|
||||
</Flex>
|
||||
|
||||
Reference in new issue
Block a user