diff --git a/include/game/game_handler.hpp b/include/game/game_handler.hpp index c333676a..8b39d3d9 100644 --- a/include/game/game_handler.hpp +++ b/include/game/game_handler.hpp @@ -1152,6 +1152,9 @@ public: bool isMounted() const { return currentMountDisplayId_ != 0; } bool isHostileAttacker(uint64_t guid) const { return hostileAttackers_.count(guid) > 0; } float getServerRunSpeed() const { return serverRunSpeed_; } + bool isPlayerRooted() const { + return (movementInfo.flags & static_cast(MovementFlags::ROOT)) != 0; + } void dismount(); // Taxi / Flight Paths diff --git a/include/rendering/camera_controller.hpp b/include/rendering/camera_controller.hpp index 679b2fa4..2c8baf3a 100644 --- a/include/rendering/camera_controller.hpp +++ b/include/rendering/camera_controller.hpp @@ -92,6 +92,8 @@ public: void setMovementCallback(MovementCallback cb) { movementCallback = std::move(cb); } void setUseWoWSpeed(bool use) { useWoWSpeed = use; } void setRunSpeedOverride(float speed) { runSpeedOverride_ = speed; } + void setMovementRooted(bool rooted) { movementRooted_ = rooted; } + bool isMovementRooted() const { return movementRooted_; } void setMounted(bool m) { mounted_ = m; } void setMountHeightOffset(float offset) { mountHeightOffset_ = offset; } void setExternalFollow(bool enabled) { externalFollow_ = enabled; } @@ -268,6 +270,8 @@ private: // Server-driven run speed override (0 = use default WOW_RUN_SPEED) float runSpeedOverride_ = 0.0f; + // Server-driven root state: when true, block all horizontal movement input. + bool movementRooted_ = false; bool mounted_ = false; float mountHeightOffset_ = 0.0f; bool externalMoving_ = false; diff --git a/src/core/application.cpp b/src/core/application.cpp index 065912dc..7de5e2d9 100644 --- a/src/core/application.cpp +++ b/src/core/application.cpp @@ -1009,6 +1009,7 @@ void Application::update(float deltaTime) { runInGameStage("post-update sync", [&] { if (renderer && gameHandler && renderer->getCameraController()) { renderer->getCameraController()->setRunSpeedOverride(gameHandler->getServerRunSpeed()); + renderer->getCameraController()->setMovementRooted(gameHandler->isPlayerRooted()); } bool onTaxi = gameHandler && diff --git a/src/rendering/camera_controller.cpp b/src/rendering/camera_controller.cpp index 0e6f9f43..63935117 100644 --- a/src/rendering/camera_controller.cpp +++ b/src/rendering/camera_controller.cpp @@ -275,8 +275,10 @@ void CameraController::update(float deltaTime) { if (mouseAutorun) { autoRunning = false; } - bool nowForward = keyW || mouseAutorun || autoRunning; - bool nowBackward = keyS; + // When the server has rooted the player, suppress all horizontal movement input. + const bool movBlocked = movementRooted_; + bool nowForward = !movBlocked && (keyW || mouseAutorun || autoRunning); + bool nowBackward = !movBlocked && keyS; bool nowStrafeLeft = false; bool nowStrafeRight = false; bool nowTurnLeft = false;