mirror of
https://github.com/blitzkit/blitzkit.git
synced 2026-10-24 03:59:50 +02:00
feat: ricochet incapable shells
This commit is contained in:
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
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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';
|
||||||
|
}
|
||||||
@@ -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',
|
||||||
|
|||||||
Reference in new issue
Block a user