mirror of
https://github.com/blitzkit/blitzkit.git
synced 2026-10-24 12:09:51 +02:00
feat: more advanced armor highlighting
This commit is contained in:
1 parent
909474d4cb
commit
d469f990f6
10 files changed
+118
-198
No files matched your search
@@ -20,7 +20,7 @@ export async function buildTankArmors() {
|
|||||||
|
|
||||||
await Promise.all(
|
await Promise.all(
|
||||||
nations.map(async (nation) => {
|
nations.map(async (nation) => {
|
||||||
if (nation !== 'china') return;
|
if (nation !== 'france') return;
|
||||||
|
|
||||||
const tanks = await readXMLDVPL<{ root: VehicleDefinitionList }>(
|
const tanks = await readXMLDVPL<{ root: VehicleDefinitionList }>(
|
||||||
`${DATA}/${DOI.vehicleDefinitions}/${nation}/list.xml.dvpl`,
|
`${DATA}/${DOI.vehicleDefinitions}/${nation}/list.xml.dvpl`,
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ export async function buildTankModels() {
|
|||||||
|
|
||||||
await Promise.all(
|
await Promise.all(
|
||||||
nations.map(async (nation) => {
|
nations.map(async (nation) => {
|
||||||
if (nation !== 'china') return;
|
if (nation !== 'france') return;
|
||||||
|
|
||||||
const tanks = await readXMLDVPL<{ root: VehicleDefinitionList }>(
|
const tanks = await readXMLDVPL<{ root: VehicleDefinitionList }>(
|
||||||
`${DATA}/${DOI.vehicleDefinitions}/${nation}/list.xml.dvpl`,
|
`${DATA}/${DOI.vehicleDefinitions}/${nation}/list.xml.dvpl`,
|
||||||
|
|||||||
@@ -5,16 +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 { canSplash } from '../../../../../../../core/blitz/canSplash';
|
import { canSplash } from '../../../../../../../core/blitz/canSplash';
|
||||||
import { isAffectedBySpaced } from '../../../../../../../core/blitz/isAffectedBySpaced';
|
import { isExplosive } from '../../../../../../../core/blitz/isExplosive';
|
||||||
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';
|
||||||
|
|
||||||
@@ -77,9 +75,11 @@ 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);
|
|
||||||
const splashCapable = canSplash(antagonist.shell.type);
|
const splashCapable = canSplash(antagonist.shell.type);
|
||||||
const affectedBySpacedCapable = isAffectedBySpaced(antagonist.shell.type);
|
const explosiveCapable = isExplosive(antagonist.shell.type);
|
||||||
|
const penetration = numericPenetration(antagonist.shell.penetration);
|
||||||
|
const ricochet = antagonist.shell.ricochet ?? Math.PI / 2;
|
||||||
|
const normalization = antagonist.shell.normalization ?? 0;
|
||||||
|
|
||||||
if (tankModelDefinition.turretRotation) {
|
if (tankModelDefinition.turretRotation) {
|
||||||
const pitch = -tankModelDefinition.turretRotation.pitch * (Math.PI / 180);
|
const pitch = -tankModelDefinition.turretRotation.pitch * (Math.PI / 180);
|
||||||
@@ -122,25 +122,17 @@ export function TankArmor({ ...props }: TankArmorProps) {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<ArmorMesh
|
<ArmorMesh
|
||||||
isAffectedBySpaced={affectedBySpacedCapable}
|
|
||||||
canSplash={splashCapable}
|
|
||||||
spaced={isSpaced}
|
|
||||||
key={node.uuid}
|
key={node.uuid}
|
||||||
geometry={(node as Mesh).geometry}
|
geometry={(node as Mesh).geometry}
|
||||||
thickness={thickness}
|
|
||||||
penetration={numericPenetration(antagonist.shell.penetration)}
|
|
||||||
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}
|
||||||
|
canSplash={splashCapable}
|
||||||
|
isExplosive={explosiveCapable}
|
||||||
|
isSpaced={isSpaced ?? false}
|
||||||
|
normalization={normalization}
|
||||||
|
penetration={penetration}
|
||||||
|
thickness={thickness}
|
||||||
|
ricochet={ricochet}
|
||||||
|
isArmor
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
@@ -155,25 +147,17 @@ export function TankArmor({ ...props }: TankArmorProps) {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<ArmorMesh
|
<ArmorMesh
|
||||||
isAffectedBySpaced={affectedBySpacedCapable}
|
|
||||||
canSplash={splashCapable}
|
|
||||||
spaced
|
|
||||||
key={node.uuid}
|
key={node.uuid}
|
||||||
geometry={(node as Mesh).geometry}
|
geometry={(node as Mesh).geometry}
|
||||||
thickness={thickness}
|
|
||||||
penetration={numericPenetration(antagonist.shell.penetration)}
|
|
||||||
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}
|
||||||
|
canSplash={splashCapable}
|
||||||
|
isExplosive={explosiveCapable}
|
||||||
|
isSpaced
|
||||||
|
normalization={normalization}
|
||||||
|
penetration={penetration}
|
||||||
|
thickness={thickness}
|
||||||
|
ricochet={ricochet}
|
||||||
|
isArmor={false}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
@@ -200,26 +184,18 @@ export function TankArmor({ ...props }: TankArmorProps) {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<ArmorMesh
|
<ArmorMesh
|
||||||
isAffectedBySpaced={affectedBySpacedCapable}
|
|
||||||
canSplash={splashCapable}
|
|
||||||
spaced={isSpaced}
|
|
||||||
key={node.uuid}
|
key={node.uuid}
|
||||||
position={turretOrigin}
|
|
||||||
geometry={(node as Mesh).geometry}
|
geometry={(node as Mesh).geometry}
|
||||||
thickness={thickness}
|
position={turretOrigin}
|
||||||
penetration={numericPenetration(antagonist.shell.penetration)}
|
|
||||||
caliber={antagonist.shell.caliber}
|
caliber={antagonist.shell.caliber}
|
||||||
canRicochet={ricochetCapable}
|
canSplash={splashCapable}
|
||||||
ricochet={
|
isExplosive={explosiveCapable}
|
||||||
ricochetCapable
|
isSpaced={isSpaced ?? false}
|
||||||
? (antagonist.shell as RicochetCapableShell).ricochet
|
normalization={normalization}
|
||||||
: undefined
|
penetration={penetration}
|
||||||
}
|
thickness={thickness}
|
||||||
normalization={
|
ricochet={ricochet}
|
||||||
ricochetCapable
|
isArmor
|
||||||
? (antagonist.shell as RicochetCapableShell).normalization
|
|
||||||
: undefined
|
|
||||||
}
|
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
@@ -252,26 +228,18 @@ export function TankArmor({ ...props }: TankArmorProps) {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<ArmorMesh
|
<ArmorMesh
|
||||||
isAffectedBySpaced={affectedBySpacedCapable}
|
|
||||||
canSplash={splashCapable}
|
|
||||||
spaced={isSpaced}
|
|
||||||
key={node.uuid}
|
key={node.uuid}
|
||||||
position={turretOrigin.clone().add(gunOrigin)}
|
|
||||||
geometry={(node as Mesh).geometry}
|
geometry={(node as Mesh).geometry}
|
||||||
thickness={thickness}
|
position={turretOrigin.clone().add(gunOrigin)}
|
||||||
penetration={numericPenetration(antagonist.shell.penetration)}
|
|
||||||
caliber={antagonist.shell.caliber}
|
caliber={antagonist.shell.caliber}
|
||||||
canRicochet={ricochetCapable}
|
canSplash={splashCapable}
|
||||||
ricochet={
|
isExplosive={explosiveCapable}
|
||||||
ricochetCapable
|
isSpaced={isSpaced ?? false}
|
||||||
? (antagonist.shell as RicochetCapableShell).ricochet
|
normalization={normalization}
|
||||||
: undefined
|
penetration={penetration}
|
||||||
}
|
thickness={thickness}
|
||||||
normalization={
|
ricochet={ricochet}
|
||||||
ricochetCapable
|
isArmor
|
||||||
? (antagonist.shell as RicochetCapableShell).normalization
|
|
||||||
: undefined
|
|
||||||
}
|
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
@@ -287,25 +255,17 @@ export function TankArmor({ ...props }: TankArmorProps) {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<ArmorMesh
|
<ArmorMesh
|
||||||
isAffectedBySpaced={affectedBySpacedCapable}
|
|
||||||
canSplash={splashCapable}
|
|
||||||
spaced
|
|
||||||
key={node.uuid}
|
key={node.uuid}
|
||||||
geometry={(node as Mesh).geometry}
|
geometry={(node as Mesh).geometry}
|
||||||
thickness={thickness}
|
|
||||||
penetration={numericPenetration(antagonist.shell.penetration)}
|
|
||||||
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}
|
||||||
|
canSplash={splashCapable}
|
||||||
|
isExplosive={explosiveCapable}
|
||||||
|
isSpaced
|
||||||
|
normalization={normalization}
|
||||||
|
penetration={penetration}
|
||||||
|
thickness={thickness}
|
||||||
|
ricochet={ricochet}
|
||||||
|
isArmor={false}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ export default function Page({ params }: { params: { id: string } }) {
|
|||||||
draft.model.hullYaw = 0;
|
draft.model.hullYaw = 0;
|
||||||
draft.model.turretYaw = 0;
|
draft.model.turretYaw = 0;
|
||||||
draft.model.gunPitch = 0;
|
draft.model.gunPitch = 0;
|
||||||
draft.mode = 'model';
|
draft.mode = 'armor';
|
||||||
draft.areTanksAssigned = true;
|
draft.areTanksAssigned = true;
|
||||||
|
|
||||||
if (!draft.areTanksAssigned) return;
|
if (!draft.areTanksAssigned) return;
|
||||||
|
|||||||
@@ -1,69 +1,58 @@
|
|||||||
import { MeshProps } from '@react-three/fiber';
|
import { MeshProps } from '@react-three/fiber';
|
||||||
import { MeshStandardMaterial } from 'three';
|
import { MeshStandardMaterial } from 'three';
|
||||||
import CustomShaderMaterial from 'three-custom-shader-material';
|
import CustomShaderMaterial from 'three-custom-shader-material';
|
||||||
import fragment from './shaders/fragment.glsl';
|
import fragmentShader from './shaders/fragment.glsl';
|
||||||
import vertex from './shaders/vertex.glsl';
|
|
||||||
|
|
||||||
interface ArmorMeshProps extends MeshProps {
|
interface ArmorMeshProps extends MeshProps {
|
||||||
|
isExplosive: boolean;
|
||||||
|
canSplash: boolean;
|
||||||
|
isSpaced: boolean;
|
||||||
|
isArmor: boolean;
|
||||||
thickness: number;
|
thickness: number;
|
||||||
penetration: number;
|
penetration: number;
|
||||||
caliber: number;
|
caliber: number;
|
||||||
spaced?: boolean;
|
ricochet: number;
|
||||||
canRicochet: boolean;
|
normalization: number;
|
||||||
canSplash: boolean;
|
|
||||||
ricochet?: number;
|
|
||||||
normalization?: number;
|
|
||||||
isAffectedBySpaced: boolean;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// shader split: https://github.com/FarazzShaikh/THREE-CustomShaderMaterial/issues/48
|
|
||||||
|
|
||||||
export function ArmorMesh({
|
export function ArmorMesh({
|
||||||
|
isExplosive,
|
||||||
|
canSplash,
|
||||||
|
isSpaced,
|
||||||
|
isArmor,
|
||||||
thickness,
|
thickness,
|
||||||
penetration,
|
penetration,
|
||||||
caliber,
|
caliber,
|
||||||
canRicochet,
|
|
||||||
ricochet,
|
ricochet,
|
||||||
canSplash,
|
|
||||||
isAffectedBySpaced,
|
|
||||||
normalization,
|
normalization,
|
||||||
spaced = false,
|
|
||||||
...props
|
...props
|
||||||
}: ArmorMeshProps) {
|
}: ArmorMeshProps) {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{!spaced && (
|
{!isSpaced && (
|
||||||
<mesh {...props}>
|
<mesh {...props}>
|
||||||
<meshBasicMaterial colorWrite={false} />
|
<meshBasicMaterial colorWrite={false} />
|
||||||
</mesh>
|
</mesh>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<mesh {...props} renderOrder={spaced ? 3 : 1}>
|
<mesh {...props} renderOrder={1}>
|
||||||
<CustomShaderMaterial
|
<CustomShaderMaterial
|
||||||
|
silent
|
||||||
baseMaterial={MeshStandardMaterial}
|
baseMaterial={MeshStandardMaterial}
|
||||||
transparent
|
transparent
|
||||||
silent
|
|
||||||
depthWrite={false}
|
depthWrite={false}
|
||||||
|
fragmentShader={fragmentShader}
|
||||||
uniforms={{
|
uniforms={{
|
||||||
|
isExplosive: { value: isExplosive },
|
||||||
|
canSplash: { value: canSplash },
|
||||||
|
isSpaced: { value: isSpaced },
|
||||||
|
isArmor: { value: isArmor },
|
||||||
thickness: { value: thickness },
|
thickness: { value: thickness },
|
||||||
penetration: { value: penetration },
|
penetration: { value: penetration },
|
||||||
ricochet: {
|
|
||||||
value: ricochet === undefined ? 0 : ricochet * (Math.PI / 180),
|
|
||||||
},
|
|
||||||
normalization: {
|
|
||||||
value:
|
|
||||||
normalization === undefined
|
|
||||||
? 0
|
|
||||||
: normalization * (Math.PI / 180),
|
|
||||||
},
|
|
||||||
caliber: { value: caliber },
|
caliber: { value: caliber },
|
||||||
spaced: { value: spaced ?? false },
|
ricochet: { value: ricochet * (Math.PI / 180) },
|
||||||
canRicochet: { value: canRicochet },
|
normalization: { value: normalization * (Math.PI / 180) },
|
||||||
canSplash: { value: canSplash },
|
|
||||||
isAffectedBySpaced: { value: isAffectedBySpaced },
|
|
||||||
}}
|
}}
|
||||||
vertexShader={vertex}
|
|
||||||
fragmentShader={fragment}
|
|
||||||
/>
|
/>
|
||||||
</mesh>
|
</mesh>
|
||||||
</>
|
</>
|
||||||
|
|||||||
@@ -1,75 +1,64 @@
|
|||||||
// split shaders due to https://github.com/FarazzShaikh/THREE-CustomShaderMaterial/issues/48
|
uniform bool isExplosive;
|
||||||
|
uniform bool canSplash;
|
||||||
varying vec3 vCSMViewPosition;
|
uniform bool isSpaced;
|
||||||
|
uniform bool isArmor;
|
||||||
uniform float thickness;
|
uniform float thickness;
|
||||||
uniform float penetration;
|
uniform float penetration;
|
||||||
uniform float ricochet;
|
|
||||||
uniform float caliber;
|
uniform float caliber;
|
||||||
|
uniform float ricochet;
|
||||||
uniform float normalization;
|
uniform float normalization;
|
||||||
uniform bool spaced;
|
|
||||||
uniform bool canRichochet;
|
vec3 zPositive = vec3(0.0, 0.0, 1.0);
|
||||||
uniform bool canSplash;
|
|
||||||
uniform bool isAffectedBySpaced;
|
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
vec3 normalizedNormal = normalize(vNormal);
|
float cosAngle = dot(zPositive, vNormal);
|
||||||
vec3 normalizedViewPosition = normalize(vCSMViewPosition);
|
float angle = acos(cosAngle);
|
||||||
float dotProduct = dot(normalizedNormal, -normalizedViewPosition);
|
|
||||||
float angle = acos(dotProduct);
|
|
||||||
|
|
||||||
float penetrationChance = -1.0;
|
float penetrationChance = -1.0;
|
||||||
bool threeCaliberRule = caliber > 3.0 * thickness;
|
float splashChance = -1.0;
|
||||||
|
bool threeCalibersRule = caliber > 3.0 * thickness;
|
||||||
|
|
||||||
if (canRichochet && !threeCaliberRule && angle >= ricochet) {
|
if (isArmor && !isExplosive && !threeCalibersRule && angle >= ricochet) {
|
||||||
// auto ricochet angle and three caliber rule not met
|
|
||||||
penetrationChance = 0.0;
|
penetrationChance = 0.0;
|
||||||
|
splashChance = 0.0;
|
||||||
} else {
|
} else {
|
||||||
bool twoCaliberRule = caliber > 2.0 * thickness;
|
bool twoCalibersRule = caliber > 2.0 * thickness;
|
||||||
float finalNormalization = twoCaliberRule ? (normalization * 1.4 * caliber) / (2.0 * thickness) : normalization;
|
float finalNormalization = twoCalibersRule ? (normalization * 1.4 * caliber) / (2.0 * thickness) : normalization;
|
||||||
float effectiveArmor = thickness / cos(angle - finalNormalization);
|
float finalThickness = thickness / cos(angle - finalNormalization);
|
||||||
float penetrationRandomRadius = penetration * 0.05;
|
|
||||||
float penetrationDifference = effectiveArmor - penetration;
|
|
||||||
|
|
||||||
if (penetrationDifference > penetrationRandomRadius) {
|
if (canSplash) {
|
||||||
// even with a +5% buff, can't penetrate
|
if (finalThickness * (5.0 / 11.0) > penetration) {
|
||||||
penetrationChance = 0.0;
|
penetrationChance = 0.0;
|
||||||
} else if (penetrationDifference < -penetrationRandomRadius) {
|
splashChance = 0.0;
|
||||||
// event with a -5% nerf, can penetrate
|
} else if (finalThickness > penetration) {
|
||||||
penetrationChance = 1.0;
|
penetrationChance = 0.0;
|
||||||
|
splashChance = 1.0;
|
||||||
|
} else {
|
||||||
|
penetrationChance = 1.0;
|
||||||
|
splashChance = 1.0;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// penetration gradiant
|
if (finalThickness > penetration) {
|
||||||
penetrationChance = 1.0 - (penetrationDifference + penetrationRandomRadius) / (2.0 * penetrationRandomRadius);
|
penetrationChance = 0.0;
|
||||||
|
splashChance = 0.0;
|
||||||
|
} else {
|
||||||
|
penetrationChance = 1.0;
|
||||||
|
splashChance = 0.0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
float alpha = (1.0 - penetrationChance) * 0.5;
|
if (isSpaced) {
|
||||||
|
if (isArmor) {
|
||||||
if (canSplash) {
|
if (isExplosive) {
|
||||||
// he
|
|
||||||
if (spaced) {
|
|
||||||
csm_FragColor = vec4(1.0, 0.0, 1.0, 0.5);
|
|
||||||
} else {
|
|
||||||
float angledThickness = thickness / cos(angle);
|
|
||||||
|
|
||||||
if (angledThickness * (5.0 / 11.0) > penetration) {
|
|
||||||
csm_FragColor = vec4(1.0, 0.0, 0.0, alpha);
|
|
||||||
} else {
|
|
||||||
csm_FragColor = vec4(1.0, 0.392, 0.0, alpha);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (spaced) {
|
|
||||||
if (isAffectedBySpaced) {
|
|
||||||
// hc
|
|
||||||
csm_FragColor = vec4(1.0, 0.0, 1.0, 0.5);
|
csm_FragColor = vec4(1.0, 0.0, 1.0, 0.5);
|
||||||
} else {
|
} else {
|
||||||
// ap, ap_cr
|
csm_FragColor = vec4(1.0, 0.0, 1.0, (1.0 - penetrationChance) * 0.5);
|
||||||
csm_FragColor = vec4(1.0, 0.0, 1.0, alpha);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// ap, ap_cr, hc
|
csm_FragColor = vec4(0.5, 0.0, 1.0, 0.5);
|
||||||
csm_FragColor = vec4(1.0, 0.0, 0.0, alpha);
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
csm_FragColor = vec4(1.0, splashChance * 0.392, 0.0, (1.0 - penetrationChance) * 0.5);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
varying vec3 vCSMViewPosition;
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
vec4 vViewPosition4 = modelViewMatrix * vec4(position, 1.0);
|
|
||||||
vCSMViewPosition = vViewPosition4.xyz;
|
|
||||||
}
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
import { ShellDefinition } from '../blitzkrieg/tankDefinitions';
|
|
||||||
|
|
||||||
export function canRicochet(
|
|
||||||
type: ShellDefinition['type'],
|
|
||||||
): type is 'ap' | 'ap_cr' {
|
|
||||||
return type === 'ap' || type === 'ap_cr';
|
|
||||||
}
|
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
import { ShellDefinition } from '../blitzkrieg/tankDefinitions';
|
import { ShellDefinition } from '../blitzkrieg/tankDefinitions';
|
||||||
|
|
||||||
export function isAffectedBySpaced(
|
export function isExplosive(
|
||||||
type: ShellDefinition['type'],
|
type: ShellDefinition['type'],
|
||||||
): type is 'he' | 'hc' {
|
): type is 'he' | 'hc' {
|
||||||
return type === 'he' || type === 'hc';
|
return type === 'he' || type === 'hc';
|
||||||
@@ -58,15 +58,7 @@ interface GunDefinitionAutoReloader {
|
|||||||
interClip: number;
|
interClip: number;
|
||||||
count: number;
|
count: number;
|
||||||
}
|
}
|
||||||
export interface RicochetCapableShell {
|
export interface ShellDefinition {
|
||||||
type: 'ap' | 'ap_cr';
|
|
||||||
normalization: number;
|
|
||||||
ricochet: number;
|
|
||||||
}
|
|
||||||
export interface RicochetIncapableShell {
|
|
||||||
type: 'hc' | 'he';
|
|
||||||
}
|
|
||||||
export type ShellDefinition = {
|
|
||||||
id: number;
|
id: number;
|
||||||
name: string;
|
name: string;
|
||||||
speed: number;
|
speed: number;
|
||||||
@@ -74,7 +66,10 @@ export type ShellDefinition = {
|
|||||||
caliber: number;
|
caliber: number;
|
||||||
icon: string;
|
icon: string;
|
||||||
penetration: number | Vector2Tuple;
|
penetration: number | Vector2Tuple;
|
||||||
} & (RicochetCapableShell | RicochetIncapableShell);
|
type: ShellType;
|
||||||
|
normalization?: number;
|
||||||
|
ricochet?: number;
|
||||||
|
}
|
||||||
|
|
||||||
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