diff --git a/include/game/game_handler.hpp b/include/game/game_handler.hpp index a9bf2eb9..9e5ad6a7 100644 --- a/include/game/game_handler.hpp +++ b/include/game/game_handler.hpp @@ -1173,6 +1173,9 @@ public: static_cast(MovementFlags::FLYING); return (movementInfo.flags & flyMask) == flyMask; } + bool isHovering() const { + return (movementInfo.flags & static_cast(MovementFlags::HOVER)) != 0; + } void dismount(); // Taxi / Flight Paths diff --git a/include/rendering/camera_controller.hpp b/include/rendering/camera_controller.hpp index e68a8093..2471fb8d 100644 --- a/include/rendering/camera_controller.hpp +++ b/include/rendering/camera_controller.hpp @@ -102,6 +102,7 @@ public: void setFeatherFallActive(bool active) { featherFallActive_ = active; } void setWaterWalkActive(bool active) { waterWalkActive_ = active; } void setFlyingActive(bool active) { flyingActive_ = active; } + void setHoverActive(bool active) { hoverActive_ = active; } void setMounted(bool m) { mounted_ = m; } void setMountHeightOffset(float offset) { mountHeightOffset_ = offset; } void setExternalFollow(bool enabled) { externalFollow_ = enabled; } @@ -292,6 +293,8 @@ private: bool waterWalkActive_ = false; // Player-controlled flight (CAN_FLY + FLYING): 3D movement, no gravity. bool flyingActive_ = false; + // Server-driven hover (HOVER flag): float at fixed height above ground. + bool hoverActive_ = false; bool mounted_ = false; float mountHeightOffset_ = 0.0f; bool externalMoving_ = false; diff --git a/src/core/application.cpp b/src/core/application.cpp index afad190e..a5df593e 100644 --- a/src/core/application.cpp +++ b/src/core/application.cpp @@ -1018,6 +1018,7 @@ void Application::update(float deltaTime) { renderer->getCameraController()->setFeatherFallActive(gameHandler->isFeatherFalling()); renderer->getCameraController()->setWaterWalkActive(gameHandler->isWaterWalking()); renderer->getCameraController()->setFlyingActive(gameHandler->isPlayerFlying()); + renderer->getCameraController()->setHoverActive(gameHandler->isHovering()); } bool onTaxi = gameHandler && diff --git a/src/rendering/camera_controller.cpp b/src/rendering/camera_controller.cpp index f1da0403..c4e93e3c 100644 --- a/src/rendering/camera_controller.cpp +++ b/src/rendering/camera_controller.cpp @@ -1249,7 +1249,10 @@ void CameraController::update(float deltaTime) { dz >= -0.25f && dz <= stepUp * 1.5f); if (dz >= -fallCatch && (nearGround || airFalling || slopeGrace)) { - targetPos.z = *groundH; + // HOVER: float at fixed height above ground instead of standing on it + static constexpr float HOVER_HEIGHT = 4.0f; // ~4 yards above ground + const float snapH = hoverActive_ ? (*groundH + HOVER_HEIGHT) : *groundH; + targetPos.z = snapH; verticalVelocity = 0.0f; grounded = true; lastGroundZ = *groundH;