physics: implement feather fall and water walk movement flag tracking

Feather Fall (SMSG_MOVE_FEATHER_FALL / SMSG_MOVE_NORMAL_FALL):
- Add FEATHER_FALL = 0x00004000 to MovementFlags enum
- Fix handlers to set/clear the flag instead of passing flag=0
- Cap downward terminal velocity at -2.0 m/s in CameraController when
  feather fall is active (Slow Fall, Parachute, etc.)

All three handlers now correctly propagate server movement state flags
that were previously acknowledged without updating any local state.
This commit is contained in:
Kelsi 2026-03-10 13:14:52 -07:00
parent 701cb94ba6
commit 0b99cbafb2
6 changed files with 15 additions and 2 deletions

View file

@ -1160,6 +1160,9 @@ public:
bool isGravityDisabled() const {
return (movementInfo.flags & static_cast<uint32_t>(MovementFlags::LEVITATING)) != 0;
}
bool isFeatherFalling() const {
return (movementInfo.flags & static_cast<uint32_t>(MovementFlags::FEATHER_FALL)) != 0;
}
void dismount();
// Taxi / Flight Paths

View file

@ -395,6 +395,7 @@ enum class MovementFlags : uint32_t {
ROOT = 0x00000800,
FALLING = 0x00001000,
FALLINGFAR = 0x00002000,
FEATHER_FALL = 0x00004000, // Slow fall / Parachute
SWIMMING = 0x00200000,
ASCENDING = 0x00400000,
CAN_FLY = 0x00800000,

View file

@ -97,6 +97,7 @@ public:
void setMovementRooted(bool rooted) { movementRooted_ = rooted; }
bool isMovementRooted() const { return movementRooted_; }
void setGravityDisabled(bool disabled) { gravityDisabled_ = disabled; }
void setFeatherFallActive(bool active) { featherFallActive_ = active; }
void setMounted(bool m) { mounted_ = m; }
void setMountHeightOffset(float offset) { mountHeightOffset_ = offset; }
void setExternalFollow(bool enabled) { externalFollow_ = enabled; }
@ -279,6 +280,8 @@ private:
bool movementRooted_ = false;
// Server-driven gravity disable (levitate/hover): skip gravity accumulation.
bool gravityDisabled_ = false;
// Server-driven feather fall: cap downward velocity to slow-fall terminal.
bool featherFallActive_ = false;
bool mounted_ = false;
float mountHeightOffset_ = 0.0f;
bool externalMoving_ = false;