feat: some turret traverse penalties

This commit is contained in:
tresabhi committed 2024-12-08 21:51:39 -06:00
1 parent 631af6205e
commit 31a61c8a6b
4 files changed
+74 -35

No files matched your search

@@ -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;
@@ -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"
@@ -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,