// Movement/State/BFL_MovementStateMachine.ts import { E_MovementState } from '#root/Movement/Core/E_MovementState.ts'; import type { S_MovementContext } from '#root/Movement/State/S_MovementContext.ts'; import { E_SurfaceType } from '#root/Movement/Surface/E_SurfaceType.ts'; /** * Movement State Machine * * Pure functional FSM for determining movement state * Takes movement context and returns appropriate state * No side effects - completely deterministic * * @category Movement State * @pure All methods are pure functions */ class BFL_MovementStateMachineClass { // ════════════════════════════════════════════════════════════════════════════════════════ // STATE DETERMINATION // ════════════════════════════════════════════════════════════════════════════════════════ /** * Determine movement state based on current Context * Main entry point for state machine logic * * @param Context - Current movement context * @returns Appropriate movement state * * @example * const state = MovementStateMachine.DetermineState({ * IsGrounded: true, * SurfaceType: E_SurfaceType.Walkable, * InputMagnitude: 0.8, * CurrentSpeed: 500, * VerticalVelocity: 0, * IsBlocked: false * }); * // Returns: E_MovementState.Walking * * @pure true * @category State Determination */ public DetermineState(Context: S_MovementContext): E_MovementState { // Priority 1: Check if grounded if (Context.IsGrounded) { // Priority 2: Check surface type if (Context.SurfaceType === E_SurfaceType.SteepSlope) { return E_MovementState.Sliding; } else if ( Context.SurfaceType === E_SurfaceType.Wall || Context.SurfaceType === E_SurfaceType.Ceiling || // Priority 3: Check if blocked by collision Context.IsBlocked ) { return E_MovementState.Blocked; } else { // Priority 4: Determine ground state based on input return this.DetermineGroundedState(Context); } } else { return this.DetermineAirborneState(Context); } } // ════════════════════════════════════════════════════════════════════════════════════════ // STATE HELPERS // ════════════════════════════════════════════════════════════════════════════════════════ /** * Determine state when character is airborne * Distinguishes between jumping, falling, etc. * * @param Context - Current movement context * @returns Airborne-specific state * * @pure true * @category State Helpers */ private DetermineAirborneState(Context: S_MovementContext): E_MovementState { // Could extend this to differentiate Jump vs Fall // For now, just return Airborne return E_MovementState.Airborne; } /** * Determine state when character is on ground * Distinguishes between idle, walking, running, etc. * * @param Context - Current movement context * @returns Grounded-specific state * * @pure true * @category State Helpers */ private DetermineGroundedState(Context: S_MovementContext): E_MovementState { // Check if player is providing input if (Context.InputMagnitude > 0.01 && Context.CurrentSpeed > 1.0) { return E_MovementState.Walking; } else { return E_MovementState.Idle; } } } export const BFL_MovementStateMachine = new BFL_MovementStateMachineClass();