#ifndef TACTICAL_SHOOTER_MOVEMENT_COMPONENT_H #define TACTICAL_SHOOTER_MOVEMENT_COMPONENT_H #include "entity.h" namespace tactical_shooter { /** * Physics-less movement simulation for networked FPS characters. * * Operates on Entity state directly — no Godot PhysicsServer3D involvement. * Uses semi-implicit Euler integration with configurable movement parameters. * * All values assume "Godot units" (1 unit ≈ 1 meter) with gravity in * units/s² and speeds in units/s. */ class MovementComponent { public: struct Parameters { float walk_speed = 4.0f; // units/s float sprint_speed = 6.5f; // units/s float crouch_speed = 2.0f; // units/s float acceleration = 20.0f; // units/s² float air_acceleration = 4.0f; // reduced control in air float friction = 8.0f; // ground deceleration float air_friction = 1.0f; // air resistance float jump_velocity = 5.0f; // initial upward velocity float gravity = -20.0f; // units/s² (negative = downward) float max_velocity = 10.0f; // speed cap (all directions) float crouch_height = 0.75f; // multiplier on entity base height float stand_height = 1.0f; }; MovementComponent(); explicit MovementComponent(const Parameters ¶ms); /** * Main update. Called once per simulation tick (e.g. every 1/128s). * * @param entity Entity to update * @param delta Timestep in seconds (e.g. 0.0078125 for 128Hz) */ void update(Entity &entity, float delta); /// Modify movement parameters at runtime void set_parameters(const Parameters ¶ms); const Parameters ¶meters() const { return params_; } private: /** * Apply ground movement with acceleration/friction. * Follows Quake/CS-style movement model (non-Strafe). */ void apply_ground_movement(Entity &entity, float delta); /** * Apply air movement with reduced acceleration. */ void apply_air_movement(Entity &entity, float delta); /** * Integrate velocity into position (semi-implicit Euler). */ void integrate_position(Entity &entity, float delta); Parameters params_; }; } // namespace tactical_shooter #endif // TACTICAL_SHOOTER_MOVEMENT_COMPONENT_H