mirror of
https://github.com/blitzkit/blitzkit.git
synced 2026-10-21 18:57:03 +02:00
feat: some turret traverse penalties
This commit is contained in:
1 parent
631af6205e
commit
31a61c8a6b
4 files changed
+74
-35
No files matched your search
+1
-1
@@ -20,7 +20,7 @@ const poseDistances: Record<Pose, number> = {
|
||||
|
||||
const modelDefinitions = await awaitableModelDefinitions;
|
||||
|
||||
const ARCADE_MODE_DISTANCE = 12;
|
||||
const ARCADE_MODE_DISTANCE = 19;
|
||||
const ARCADE_MODE_ANGLE = Math.PI / 8;
|
||||
export const ARCADE_MODE_FOV = 54;
|
||||
export const INSPECT_MODE_FOV = 25;
|
||||
|
||||
+38
-24
@@ -1,40 +1,54 @@
|
||||
import { imgur } from '@blitzkit/core';
|
||||
import { Box, type BoxProps } from '@radix-ui/themes';
|
||||
import { times } from 'lodash-es';
|
||||
import { forwardRef } from 'react';
|
||||
import { Var } from '../../../../../../../../core/radix/var';
|
||||
|
||||
const DOTS = 32;
|
||||
|
||||
export const TargetCircle = forwardRef<HTMLDivElement, BoxProps>(
|
||||
({ ...props }, ref) => {
|
||||
type TargetCircleProps = BoxProps & {
|
||||
variant: 'client' | 'server';
|
||||
};
|
||||
|
||||
export const TargetCircle = forwardRef<HTMLDivElement, TargetCircleProps>(
|
||||
({ style, variant, ...props }, ref) => {
|
||||
return (
|
||||
<Box
|
||||
ref={ref}
|
||||
position="relative"
|
||||
position="absolute"
|
||||
top="50%"
|
||||
left="50%"
|
||||
minWidth={variant === 'client' ? '23px' : undefined}
|
||||
minHeight={variant === 'client' ? '23px' : undefined}
|
||||
style={{
|
||||
transform: 'translate(-50%, -50%)',
|
||||
borderRadius: '50%',
|
||||
outline: `${variant === 'client' ? 2 : 1}px solid ${variant === 'client' ? Var('grass-11') : Var('gray-11')}`,
|
||||
outlineOffset: `-${variant === 'client' ? 1 : 0.5}px`,
|
||||
...style,
|
||||
}}
|
||||
{...props}
|
||||
minWidth="23px"
|
||||
minHeight="23px"
|
||||
>
|
||||
{times(DOTS, (index) => {
|
||||
const angle = 2 * Math.PI * (index / DOTS);
|
||||
{/* {variant === 'client' &&
|
||||
times(DOTS, (index) => {
|
||||
const angle = 2 * Math.PI * (index / DOTS);
|
||||
|
||||
return (
|
||||
<Box
|
||||
key={index}
|
||||
style={{
|
||||
borderRadius: '50%',
|
||||
background: Var('grass-11'),
|
||||
transform: `translate(-50%, -50%)`,
|
||||
position: 'absolute',
|
||||
}}
|
||||
top={`${(0.5 * Math.sin(angle) + 0.5) * 100}%`}
|
||||
left={`${(0.5 * Math.cos(angle) + 0.5) * 100}%`}
|
||||
width={'calc(1rem / 6)'}
|
||||
height={'calc(1rem / 6)'}
|
||||
/>
|
||||
);
|
||||
})} */}
|
||||
|
||||
return (
|
||||
<Box
|
||||
key={index}
|
||||
style={{
|
||||
borderRadius: '50%',
|
||||
background: Var('grass-11'),
|
||||
transform: `translate(-50%, -50%)`,
|
||||
position: 'absolute',
|
||||
}}
|
||||
top={`${(0.5 * Math.sin(angle) + 0.5) * 100}%`}
|
||||
left={`${(0.5 * Math.cos(angle) + 0.5) * 100}%`}
|
||||
width={`${1 / 6}rem`}
|
||||
height={`${1 / 6}rem`}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
<Box
|
||||
width="1rem"
|
||||
height="1rem"
|
||||
|
||||
+32
-10
@@ -12,7 +12,7 @@ import {
|
||||
Vector3,
|
||||
} from 'three';
|
||||
import { GLTFLoader } from 'three/examples/jsm/Addons.js';
|
||||
import { degToRad } from 'three/src/math/MathUtils.js';
|
||||
import { degToRad, radToDeg } from 'three/src/math/MathUtils.js';
|
||||
import { awaitableEquipmentDefinitions } from '../../../../../../../core/awaitables/equipmentDefinitions';
|
||||
import { awaitableModelDefinitions } from '../../../../../../../core/awaitables/modelDefinitions';
|
||||
import { awaitableProvisionDefinitions } from '../../../../../../../core/awaitables/provisionDefinitions';
|
||||
@@ -40,7 +40,8 @@ export function SceneProps() {
|
||||
(state) => state.showGrid && !state.showEnvironment,
|
||||
);
|
||||
const targetCircleWrapper = useRef<Group>(null);
|
||||
const targetCircle = useRef<HTMLDivElement>(null);
|
||||
const clientTargetCircle = useRef<HTMLDivElement>(null);
|
||||
const serverTargetCircle = useRef<HTMLDivElement>(null);
|
||||
const material = useRef<MeshStandardMaterial>(null);
|
||||
const playground = useRef<Group>(null);
|
||||
|
||||
@@ -70,8 +71,6 @@ export function SceneProps() {
|
||||
-tankModelDefinition.turret_origin.z,
|
||||
);
|
||||
const gunOriginOnlyY = new Vector3(0, turretModelDefinition.gun_origin.y, 0);
|
||||
const turretRotationSpeed = degToRad(turret.traverse_speed);
|
||||
const gunRotationSpeed = degToRad(gun.gun_type!.value.base.rotation_speed);
|
||||
const shellOrigin = new Vector3()
|
||||
.add(hullOrigin)
|
||||
.add(turretOrigin)
|
||||
@@ -106,6 +105,9 @@ export function SceneProps() {
|
||||
},
|
||||
{ equipmentDefinitions, provisionDefinitions, tankModelDefinition },
|
||||
);
|
||||
let { dispersion } = characteristics;
|
||||
const turretRotationSpeed = degToRad(characteristics.turretTraverseSpeed);
|
||||
const gunRotationSpeed = degToRad(characteristics.gunTraverseSpeed);
|
||||
|
||||
const mockTank = useLoader(GLTFLoader, asset(`3d/tanks/models/12305.glb`));
|
||||
const texture = useLoader(TextureLoader, imgur('C28Z8nU'));
|
||||
@@ -125,7 +127,8 @@ export function SceneProps() {
|
||||
!playground.current ||
|
||||
!targetCircleWrapper.current ||
|
||||
DEBUG_disable ||
|
||||
!targetCircle.current
|
||||
!clientTargetCircle.current ||
|
||||
!serverTargetCircle.current
|
||||
) {
|
||||
return;
|
||||
}
|
||||
@@ -152,6 +155,7 @@ export function SceneProps() {
|
||||
|
||||
const deltaT = clock.elapsedTime - lastTime;
|
||||
lastTime = clock.elapsedTime;
|
||||
|
||||
const desiredPitch = Math.asin(direction.y);
|
||||
const desiredYaw = Math.atan2(-direction.x, -direction.z);
|
||||
const deltaPitch = desiredPitch - lastPitch;
|
||||
@@ -170,6 +174,22 @@ export function SceneProps() {
|
||||
turretModelDefinition.yaw,
|
||||
);
|
||||
|
||||
const deltaRotation = Math.abs(maxDeltaPitch) + Math.abs(maxDeltaYaw);
|
||||
const rotationSpeed = deltaRotation;
|
||||
const turretTraversePenalty =
|
||||
characteristics.dispersionTurretTraversing * radToDeg(rotationSpeed);
|
||||
|
||||
const penalty = turretTraversePenalty;
|
||||
|
||||
const dispersionMod = dispersion - characteristics.dispersion;
|
||||
const dispersionModDischarged =
|
||||
dispersionMod * Math.exp(-deltaT / characteristics.aimTime) -
|
||||
dispersionMod;
|
||||
|
||||
dispersion += penalty + dispersionModDischarged;
|
||||
|
||||
document.title = `${dispersion.toFixed(3)} (${penalty.toFixed(3)})`;
|
||||
|
||||
modelTransformEvent.emit({ pitch, yaw });
|
||||
lastPitch = pitch;
|
||||
lastYaw = yaw;
|
||||
@@ -198,8 +218,7 @@ export function SceneProps() {
|
||||
targetCircleWrapper.current.position.copy(gunTarget);
|
||||
|
||||
const distanceToTarget = gunTarget.distanceTo(shellOrigin);
|
||||
const dispersionRadius =
|
||||
characteristics.dispersion * (distanceToTarget / 100);
|
||||
const dispersionRadius = dispersion * (distanceToTarget / 100);
|
||||
const dispersionSize = 2 * dispersionRadius;
|
||||
const targetDistanceFromCamera = gunTarget.distanceTo(camera.position);
|
||||
const angularSize =
|
||||
@@ -210,8 +229,10 @@ export function SceneProps() {
|
||||
gl.domElement.clientHeight * (angularSize / verticalScreenSize);
|
||||
const targetCircleDotsSize = `${screenSpaceSize}px`;
|
||||
|
||||
targetCircle.current.style.width = targetCircleDotsSize;
|
||||
targetCircle.current.style.height = targetCircleDotsSize;
|
||||
clientTargetCircle.current.style.width = targetCircleDotsSize;
|
||||
clientTargetCircle.current.style.height = targetCircleDotsSize;
|
||||
serverTargetCircle.current.style.width = targetCircleDotsSize;
|
||||
serverTargetCircle.current.style.height = targetCircleDotsSize;
|
||||
});
|
||||
|
||||
return (
|
||||
@@ -227,7 +248,8 @@ export function SceneProps() {
|
||||
<>
|
||||
<group ref={targetCircleWrapper}>
|
||||
<Html center occlude={false} zIndexRange={[0, 0]}>
|
||||
<TargetCircle ref={targetCircle} />
|
||||
<TargetCircle variant="client" ref={clientTargetCircle} />
|
||||
<TargetCircle variant="server" ref={serverTargetCircle} />
|
||||
</Html>
|
||||
</group>
|
||||
|
||||
|
||||
@@ -461,6 +461,8 @@ export function tankCharacteristics(
|
||||
resolvedEnginePower / weightTons / softTerrainCoefficientRaw;
|
||||
const weight = weightTons;
|
||||
const turretTraverseSpeed = turret.traverse_speed * turretTraverseCoefficient;
|
||||
const gunTraverseSpeed =
|
||||
gun.gun_type!.value.base.rotation_speed * turretTraverseCoefficient;
|
||||
const hullTraverseHardTerrain =
|
||||
(resolvedEnginePower / stockEngine.power) *
|
||||
track.traverse_speed *
|
||||
@@ -555,6 +557,7 @@ export function tankCharacteristics(
|
||||
powerToWeightRatioSoftTerrain,
|
||||
weight,
|
||||
turretTraverseSpeed,
|
||||
gunTraverseSpeed, // TODO: display this
|
||||
hullTraverseHardTerrain,
|
||||
hullTraverseMediumTerrain,
|
||||
hullTraverseSoftTerrain,
|
||||
|
||||
Reference in new issue
Block a user