tengri/Content/Movement/Components/AC_Movement.ts

189 lines
6.5 KiB
TypeScript

// Movement/Components/AC_Movement.ts
import { BFL_Vectors } from '#root/Math/Libraries/BFL_Vectors.ts';
import { E_SurfaceType } from '#root/Movement/Enums/E_SurfaceType.ts';
import { S_AngleThresholds } from '#root/Movement/Structs/S_AngleThresholds.ts';
import type { S_MovementConstants } from '#root/Movement/Structs/S_MovementConstants.ts';
import { ActorComponent } from '#root/UE/ActorComponent.ts';
import type { Float } from '#root/UE/Float.ts';
import { MathLibrary } from '#root/UE/MathLibrary.ts';
import type { Vector } from '#root/UE/Vector.ts';
/**
* Movement System Component
* Core deterministic movement system for 3D platformer
* Handles surface classification and movement physics calculations
*/
export class AC_Movement extends ActorComponent {
// ════════════════════════════════════════════════════════════════════════════════════════
// FUNCTIONS
// ════════════════════════════════════════════════════════════════════════════════════════
/**
* Classify surface type based on normal vector
* @param SurfaceNormal - Normalized surface normal vector
* @param AngleThresholds - Angle thresholds in radians
* @returns Surface type classification
* @example
* // Classify flat ground
* ClassifySurface(new Vector(0,0,1), thresholds) // returns E_SurfaceType.Walkable
* @pure true
* @category Surface Detection
*/
public ClassifySurface(
SurfaceNormal: Vector,
AngleThresholds: S_AngleThresholds
): E_SurfaceType {
const SurfaceAngle = BFL_Vectors.GetSurfaceAngle(SurfaceNormal);
/**
* Check if angle is within walkable range
*/
const IsWalkableAngle = (walkableAngle: Float): boolean =>
SurfaceAngle <= walkableAngle;
/**
* Check if angle is within steep slope range
*/
const IsSteepSlopeAngle = (steepSlopeAngle: Float): boolean =>
SurfaceAngle <= steepSlopeAngle;
/**
* Check if angle is within wall range
*/
const IsWallAngle = (wallAngle: Float): boolean =>
SurfaceAngle <= wallAngle;
if (IsWalkableAngle(AngleThresholds.Walkable)) {
return E_SurfaceType.Walkable;
} else if (IsSteepSlopeAngle(AngleThresholds.SteepSlope)) {
return E_SurfaceType.SteepSlope;
} else if (IsWallAngle(AngleThresholds.Wall)) {
return E_SurfaceType.Wall;
} else {
return E_SurfaceType.Ceiling;
}
}
/**
* Check if surface allows normal walking movement
* @param SurfaceType - Surface type to check
* @returns True if surface is walkable
* @pure true
* @category Surface Detection
*/
private IsSurfaceWalkable(SurfaceType: E_SurfaceType): boolean {
return SurfaceType === E_SurfaceType.Walkable;
}
/**
* Check if surface causes sliding behavior
* @param SurfaceType - Surface type to check
* @returns True if surface is steep slope
* @pure true
* @category Surface Detection
*/
private IsSurfaceSteep(SurfaceType: E_SurfaceType): boolean {
return SurfaceType === E_SurfaceType.SteepSlope;
}
/**
* Check if surface blocks movement (collision)
* @param SurfaceType - Surface type to check
* @returns True if surface is a wall
* @pure true
* @category Surface Detection
*/
private IsSurfaceWall(SurfaceType: E_SurfaceType): boolean {
return SurfaceType === E_SurfaceType.Wall;
}
/**
* Check if surface is overhead (ceiling)
* @param SurfaceType - Surface type to check
* @returns True if surface is ceiling
* @pure true
* @category Surface Detection
*/
private IsSurfaceCeiling(SurfaceType: E_SurfaceType): boolean {
return SurfaceType === E_SurfaceType.Ceiling;
}
/**
* Check if no surface detected (airborne state)
* @param SurfaceType - Surface type to check
* @returns True if no surface contact
* @pure true
* @category Surface Detection
*/
private IsSurfaceNone(SurfaceType: E_SurfaceType): boolean {
return SurfaceType === E_SurfaceType.None;
}
/**
* Initialize movement system with angle conversion
* Converts degree thresholds to radians for runtime performance
* @category System
*/
public InitializeMovementSystem(): void {
this.IsInitialized = true;
this.AngleThresholdsRads = {
Walkable: MathLibrary.DegreesToRadians(
this.AngleThresholdsDegrees.Walkable
),
SteepSlope: MathLibrary.DegreesToRadians(
this.AngleThresholdsDegrees.SteepSlope
),
Wall: MathLibrary.DegreesToRadians(this.AngleThresholdsDegrees.Wall),
};
}
// ════════════════════════════════════════════════════════════════════════════════════════
// VARIABLES
// ════════════════════════════════════════════════════════════════════════════════════════
/**
* Movement physics constants
* Controls speed, acceleration, friction, and gravity values
* @category Movement Config
* @instanceEditable true
*/
public readonly MovementConstants: S_MovementConstants = {
MaxSpeed: 600.0,
Acceleration: 2000.0,
Friction: 8.0,
Gravity: 980.0,
};
/**
* Surface classification angle thresholds in degrees
* Walkable ≤50°, SteepSlope ≤85°, Wall ≤95°, Ceiling >95°
* @category Movement Config
* @instanceEditable true
*/
public readonly AngleThresholdsDegrees: S_AngleThresholds = {
Walkable: 50.0,
SteepSlope: 85.0,
Wall: 95.0,
};
/**
* Runtime cached angle thresholds in radians
* Converted from degrees during initialization for performance
* @category Internal Cache
*/
private AngleThresholdsRads: S_AngleThresholds = {
Walkable: 0.0,
SteepSlope: 0.0,
Wall: 0.0,
};
/**
* Flag indicating if movement system has been initialized
* Ensures angle thresholds are converted before use
* @category Debug
*/
public IsInitialized = false;
}