diff --git a/include/rendering/camera_controller.hpp b/include/rendering/camera_controller.hpp index 1ccf7f63..79a7d622 100644 --- a/include/rendering/camera_controller.hpp +++ b/include/rendering/camera_controller.hpp @@ -82,6 +82,7 @@ public: bool isSwimming() const { return swimming; } bool isInsideWMO() const { return cachedInsideWMO; } void setGrounded(bool g) { grounded = g; } + void setSitting(bool s) { sitting = s; } bool isOnTaxi() const { return externalFollow_; } const glm::vec3* getFollowTarget() const { return followTarget; } glm::vec3* getFollowTargetMutable() { return followTarget; } diff --git a/src/core/application.cpp b/src/core/application.cpp index a3c12e98..0d7e1e8c 100644 --- a/src/core/application.cpp +++ b/src/core/application.cpp @@ -2795,8 +2795,15 @@ void Application::setupUICallbacks() { }); // Stand state animation callback — map server stand state to M2 animation on player + // and sync camera sit flag so movement is blocked while sitting gameHandler->setStandStateCallback([this](uint8_t standState) { if (!renderer) return; + + // Sync camera controller sitting flag: block movement while sitting/kneeling + if (auto* cc = renderer->getCameraController()) { + cc->setSitting(standState >= 1 && standState <= 8 && standState != 7); + } + auto* cr = renderer->getCharacterRenderer(); if (!cr) return; uint32_t charInstId = renderer->getCharacterInstanceId(); @@ -2813,7 +2820,7 @@ void Application::setupUICallbacks() { } else if (standState == 8) { animId = 72; // Kneel } - // Non-looping sit/kneel looks wrong frozen; loop them so the held-pose frame shows + // Loop sit/kneel (not death) so the held-pose frame stays visible const bool loop = (animId != 1); cr->playAnimation(charInstId, animId, loop); });