mirror of
https://github.com/blitzkit/blitzkit.git
synced 2026-10-24 03:59:50 +02:00
fix: ricochet angle
This commit is contained in:
1 parent
e16f3653bb
commit
2b34863b53
2 files changed
+29
-10
No files matched your search
@@ -7,6 +7,7 @@ import { radToDeg } from 'three/src/math/MathUtils';
|
|||||||
import { J_HAT } from '../../../constants/axis';
|
import { J_HAT } from '../../../constants/axis';
|
||||||
import {
|
import {
|
||||||
ShotLayer,
|
ShotLayer,
|
||||||
|
ShotLayerNonExternal,
|
||||||
ShotStatus,
|
ShotStatus,
|
||||||
useTankopediaTemporary,
|
useTankopediaTemporary,
|
||||||
} from '../../../stores/tankopedia';
|
} from '../../../stores/tankopedia';
|
||||||
@@ -43,7 +44,7 @@ const shotStatusColors: Record<
|
|||||||
};
|
};
|
||||||
|
|
||||||
const LENGTH_INFINITY = 4;
|
const LENGTH_INFINITY = 4;
|
||||||
const TRACER_THICK = 1 / 64;
|
const TRACER_THICK = 1 / 32;
|
||||||
const TRACER_THIN = TRACER_THICK / 2;
|
const TRACER_THIN = TRACER_THICK / 2;
|
||||||
|
|
||||||
function LayerEntry({
|
function LayerEntry({
|
||||||
@@ -146,7 +147,7 @@ export function ShotDisplay() {
|
|||||||
if (!outTracer.current) return;
|
if (!outTracer.current) return;
|
||||||
|
|
||||||
outTracer.current.scale.set(1, 1 - 2 * Math.abs(t2 - 0.5), 1);
|
outTracer.current.scale.set(1, 1 - 2 * Math.abs(t2 - 0.5), 1);
|
||||||
outTracer.current.position.set(0, t2 * inLength, 0);
|
outTracer.current.position.set(0, t2 * outLength, 0);
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!shot) return null;
|
if (!shot) return null;
|
||||||
@@ -156,6 +157,12 @@ export function ShotDisplay() {
|
|||||||
if (layer.type === null) return accumulator + layer.distance;
|
if (layer.type === null) return accumulator + layer.distance;
|
||||||
return accumulator;
|
return accumulator;
|
||||||
}, 0) + LENGTH_INFINITY;
|
}, 0) + LENGTH_INFINITY;
|
||||||
|
const outLength =
|
||||||
|
shot.out && shot.out.layers.length > 0
|
||||||
|
? (shot.in.layers.at(-1) as ShotLayerNonExternal).point.distanceTo(
|
||||||
|
(shot.out.layers.at(-1) as ShotLayerNonExternal).point,
|
||||||
|
)
|
||||||
|
: LENGTH_INFINITY;
|
||||||
const inLast = shot.in.layers.findLast((layer) => layer.type !== null)!;
|
const inLast = shot.in.layers.findLast((layer) => layer.type !== null)!;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -282,7 +289,13 @@ export function ShotDisplay() {
|
|||||||
: shotStatusColors[layer.status];
|
: shotStatusColors[layer.status];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Html position={layer.point} center>
|
<Html
|
||||||
|
position={layer.point}
|
||||||
|
center
|
||||||
|
style={{
|
||||||
|
pointerEvents: 'none',
|
||||||
|
}}
|
||||||
|
>
|
||||||
<Kbd>
|
<Kbd>
|
||||||
<Text color={shotStatusColor}>{layerIndex}</Text>
|
<Text color={shotStatusColor}>{layerIndex}</Text>
|
||||||
</Kbd>
|
</Kbd>
|
||||||
@@ -315,21 +328,24 @@ export function ShotDisplay() {
|
|||||||
<group
|
<group
|
||||||
position={inLast.point}
|
position={inLast.point}
|
||||||
rotation={new Euler().setFromQuaternion(
|
rotation={new Euler().setFromQuaternion(
|
||||||
new Quaternion().setFromUnitVectors(J_HAT, shot.out.surfaceNormal),
|
new Quaternion().setFromUnitVectors(
|
||||||
|
J_HAT,
|
||||||
|
shot.out.surfaceNormal.clone(),
|
||||||
|
),
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<mesh position={[0, inLength / 2, 0]}>
|
<mesh position={[0, outLength / 2, 0]}>
|
||||||
<cylinderGeometry
|
<cylinderGeometry
|
||||||
args={[TRACER_THIN / 2, TRACER_THIN / 2, inLength]}
|
args={[TRACER_THIN / 2, TRACER_THIN / 2, outLength]}
|
||||||
/>
|
/>
|
||||||
<meshBasicMaterial depthTest={false} />
|
<meshBasicMaterial depthTest={false} />
|
||||||
</mesh>
|
</mesh>
|
||||||
|
|
||||||
<mesh ref={outTracer} position={[0, inLength / 2, 0]}>
|
<mesh ref={outTracer} position={[0, outLength / 2, 0]}>
|
||||||
<cylinderGeometry
|
<cylinderGeometry
|
||||||
args={[TRACER_THICK / 2, TRACER_THICK / 2, inLength]}
|
args={[TRACER_THICK / 2, TRACER_THICK / 2, outLength]}
|
||||||
/>
|
/>
|
||||||
<meshBasicMaterial color="red" />
|
<meshBasicMaterial color="yellow" />
|
||||||
</mesh>
|
</mesh>
|
||||||
</group>
|
</group>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -83,6 +83,7 @@ export function SpacedArmorSceneComponent({
|
|||||||
point: Vector3,
|
point: Vector3,
|
||||||
intersections: Intersection[],
|
intersections: Intersection[],
|
||||||
allowRicochet: boolean,
|
allowRicochet: boolean,
|
||||||
|
remainingPenetrationInput?: number,
|
||||||
) {
|
) {
|
||||||
const { antagonist, protagonist } = useDuel.getState();
|
const { antagonist, protagonist } = useDuel.getState();
|
||||||
const shell = antagonist!.shell;
|
const shell = antagonist!.shell;
|
||||||
@@ -138,7 +139,7 @@ export function SpacedArmorSceneComponent({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let remainingPenetration = penetration;
|
let remainingPenetration = remainingPenetrationInput ?? penetration;
|
||||||
let index = 0;
|
let index = 0;
|
||||||
for (const intersection of noDuplicateIntersections) {
|
for (const intersection of noDuplicateIntersections) {
|
||||||
const layer = intersection.object.userData;
|
const layer = intersection.object.userData;
|
||||||
@@ -314,6 +315,7 @@ export function SpacedArmorSceneComponent({
|
|||||||
lastLayer.point,
|
lastLayer.point,
|
||||||
ricochetIntersections,
|
ricochetIntersections,
|
||||||
false,
|
false,
|
||||||
|
remainingPenetration,
|
||||||
);
|
);
|
||||||
|
|
||||||
shot.in.status = 'ricochet';
|
shot.in.status = 'ricochet';
|
||||||
@@ -327,6 +329,7 @@ export function SpacedArmorSceneComponent({
|
|||||||
} else {
|
} else {
|
||||||
shot.damage = outShot.damage;
|
shot.damage = outShot.damage;
|
||||||
shot.out = outShot.in;
|
shot.out = outShot.in;
|
||||||
|
shot.out.surfaceNormal = ricochetNormal;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in new issue
Block a user