feat: ricochet incapable shells

This commit is contained in:
TrèsAbhi committed 2024-01-11 12:04:01 -06:00
1 parent 28a9f9a849
commit 9ed2b79a4b
5 files changed
+71 -22

No files matched your search

@@ -5,12 +5,14 @@ import { GLTFLoader } from 'three-stdlib';
import { ArmorMesh } from '../../../../../../../components/ArmorMesh'; import { ArmorMesh } from '../../../../../../../components/ArmorMesh';
import { HeadsUpDisplay } from '../../../../../../../components/HeadsUpDisplay'; import { HeadsUpDisplay } from '../../../../../../../components/HeadsUpDisplay';
import { X_AXIS } from '../../../../../../../constants/axis'; import { X_AXIS } from '../../../../../../../constants/axis';
import { canRicochet } from '../../../../../../../core/blitz/canRicochet';
import { numericPenetration } from '../../../../../../../core/blitz/numericPenetration'; import { numericPenetration } from '../../../../../../../core/blitz/numericPenetration';
import { asset } from '../../../../../../../core/blitzkrieg/asset'; import { asset } from '../../../../../../../core/blitzkrieg/asset';
import { import {
ModelDefinitions, ModelDefinitions,
modelDefinitions, modelDefinitions,
} from '../../../../../../../core/blitzkrieg/modelDefinitions'; } from '../../../../../../../core/blitzkrieg/modelDefinitions';
import { RicochetCapableShell } from '../../../../../../../core/blitzkrieg/tankDefinitions';
import { useTankopedia } from '../../../../../../../stores/tankopedia'; import { useTankopedia } from '../../../../../../../stores/tankopedia';
import { Lighting } from '../../Lighting'; import { Lighting } from '../../Lighting';
@@ -66,6 +68,7 @@ export function TankArmor({ ...props }: TankArmorProps) {
.sub(turretOrigin) .sub(turretOrigin)
.applyAxisAngle(new Vector3(0, 0, 1), model.turretYaw); .applyAxisAngle(new Vector3(0, 0, 1), model.turretYaw);
const turretRotation = new Euler(0, 0, model.turretYaw); const turretRotation = new Euler(0, 0, model.turretYaw);
const ricochetCapable = canRicochet(antagonist.shell.type);
if (tankModelDefinition.turretRotation) { if (tankModelDefinition.turretRotation) {
const pitch = -tankModelDefinition.turretRotation.pitch * (Math.PI / 180); const pitch = -tankModelDefinition.turretRotation.pitch * (Math.PI / 180);
@@ -105,6 +108,7 @@ export function TankArmor({ ...props }: TankArmorProps) {
(isSpaced && !showSpacedArmor) (isSpaced && !showSpacedArmor)
) )
return null; return null;
return ( return (
<ArmorMesh <ArmorMesh
spaced={isSpaced} spaced={isSpaced}
@@ -112,9 +116,18 @@ export function TankArmor({ ...props }: TankArmorProps) {
geometry={(node as Mesh).geometry} geometry={(node as Mesh).geometry}
thickness={thickness} thickness={thickness}
penetration={numericPenetration(antagonist.shell.penetration)} penetration={numericPenetration(antagonist.shell.penetration)}
ricochet={antagonist.shell.ricochet} canRicochet={ricochetCapable}
ricochet={
ricochetCapable
? (antagonist.shell as RicochetCapableShell).ricochet
: undefined
}
normalization={
ricochetCapable
? (antagonist.shell as RicochetCapableShell).normalization
: undefined
}
caliber={antagonist.shell.caliber} caliber={antagonist.shell.caliber}
normalization={antagonist.shell.normalization}
/> />
); );
})} })}
@@ -138,6 +151,7 @@ export function TankArmor({ ...props }: TankArmorProps) {
(isSpaced && !showSpacedArmor) (isSpaced && !showSpacedArmor)
) )
return null; return null;
return ( return (
<ArmorMesh <ArmorMesh
spaced={isSpaced} spaced={isSpaced}
@@ -146,9 +160,18 @@ export function TankArmor({ ...props }: TankArmorProps) {
geometry={(node as Mesh).geometry} geometry={(node as Mesh).geometry}
thickness={thickness} thickness={thickness}
penetration={numericPenetration(antagonist.shell.penetration)} penetration={numericPenetration(antagonist.shell.penetration)}
ricochet={antagonist.shell.ricochet}
caliber={antagonist.shell.caliber} caliber={antagonist.shell.caliber}
normalization={antagonist.shell.normalization} canRicochet={ricochetCapable}
ricochet={
ricochetCapable
? (antagonist.shell as RicochetCapableShell).ricochet
: undefined
}
normalization={
ricochetCapable
? (antagonist.shell as RicochetCapableShell).normalization
: undefined
}
/> />
); );
})} })}
@@ -186,9 +209,18 @@ export function TankArmor({ ...props }: TankArmorProps) {
geometry={(node as Mesh).geometry} geometry={(node as Mesh).geometry}
thickness={thickness} thickness={thickness}
penetration={numericPenetration(antagonist.shell.penetration)} penetration={numericPenetration(antagonist.shell.penetration)}
ricochet={antagonist.shell.ricochet}
caliber={antagonist.shell.caliber} caliber={antagonist.shell.caliber}
normalization={antagonist.shell.normalization} canRicochet={ricochetCapable}
ricochet={
ricochetCapable
? (antagonist.shell as RicochetCapableShell).ricochet
: undefined
}
normalization={
ricochetCapable
? (antagonist.shell as RicochetCapableShell).normalization
: undefined
}
/> />
); );
})} })}
+15 -5
View File
@@ -9,10 +9,11 @@ import vertex from './shaders/vertex.glsl';
interface ArmorMeshProps extends MeshProps { interface ArmorMeshProps extends MeshProps {
thickness: number; thickness: number;
penetration: number; penetration: number;
ricochet: number;
caliber: number; caliber: number;
normalization: number;
spaced?: boolean; spaced?: boolean;
canRicochet: boolean;
ricochet?: number;
normalization?: number;
} }
// shader split: https://github.com/FarazzShaikh/THREE-CustomShaderMaterial/issues/48 // shader split: https://github.com/FarazzShaikh/THREE-CustomShaderMaterial/issues/48
@@ -21,6 +22,7 @@ export function ArmorMesh({
thickness, thickness,
penetration, penetration,
caliber, caliber,
canRicochet,
ricochet, ricochet,
normalization, normalization,
spaced = false, spaced = false,
@@ -45,10 +47,18 @@ export function ArmorMesh({
uniforms={{ uniforms={{
thickness: { value: thickness }, thickness: { value: thickness },
penetration: { value: penetration }, penetration: { value: penetration },
ricochet: { value: ricochet * (Math.PI / 180) }, ricochet: {
value: ricochet === undefined ? 0 : ricochet * (Math.PI / 180),
},
normalization: {
value:
normalization === undefined
? 0
: normalization * (Math.PI / 180),
},
caliber: { value: caliber }, caliber: { value: caliber },
normalization: { value: normalization * (Math.PI / 180) }, spaced: { value: spaced ?? false },
spaced: { value: spaced }, canRicochet: { value: canRicochet },
}} }}
vertexShader={vertex} vertexShader={vertex}
fragmentShader={opaqueArmor && !spaced ? fragmentOpaque : fragment} fragmentShader={opaqueArmor && !spaced ? fragmentOpaque : fragment}
@@ -7,6 +7,7 @@ uniform float ricochet;
uniform float caliber; uniform float caliber;
uniform float normalization; uniform float normalization;
uniform bool spaced; uniform bool spaced;
uniform bool canRichochet;
void main() { void main() {
vec3 normalizedNormal = normalize(vNormal); vec3 normalizedNormal = normalize(vNormal);
@@ -17,7 +18,7 @@ void main() {
float penetrationChance = -1.0; float penetrationChance = -1.0;
bool threeCaliberRule = caliber > 3.0 * thickness; bool threeCaliberRule = caliber > 3.0 * thickness;
if (!threeCaliberRule && angle >= ricochet) { if (canRichochet && !threeCaliberRule && angle >= ricochet) {
// auto ricochet angle and three caliber rule not met // auto ricochet angle and three caliber rule not met
penetrationChance = 0.0; penetrationChance = 0.0;
} else { } else {
+7
View File
@@ -0,0 +1,7 @@
import { ShellDefinition } from '../blitzkrieg/tankDefinitions';
export function canRicochet(
type: ShellDefinition['type'],
): type is 'ap' | 'ap_cr' {
return type === 'ap' || type === 'ap_cr';
}
+9 -10
View File
@@ -58,6 +58,14 @@ interface GunDefinitionAutoReloader {
interClip: number; interClip: number;
count: number; count: number;
} }
export interface RicochetCapableShell {
type: 'ap' | 'ap_cr';
normalization: number;
ricochet: number;
}
export interface RicochetIncapableShell {
type: 'hc' | 'he';
}
export type ShellDefinition = { export type ShellDefinition = {
id: number; id: number;
name: string; name: string;
@@ -66,16 +74,7 @@ export type ShellDefinition = {
caliber: number; caliber: number;
icon: string; icon: string;
penetration: number | Vector2Tuple; penetration: number | Vector2Tuple;
} & ( } & (RicochetCapableShell | RicochetIncapableShell);
| {
type: Omit<ShellType, 'hc' | 'he'>;
normalization: number;
ricochet: number;
}
| {
type: Omit<ShellType, 'ap' | 'ap_cr'>;
}
);
export const tankDefinitions = fetch(asset('definitions/tanks.json'), { export const tankDefinitions = fetch(asset('definitions/tanks.json'), {
cache: 'no-cache', cache: 'no-cache',