From a9ddfe70c2c4d68a306b759668d0ff92aa20db1e Mon Sep 17 00:00:00 2001 From: Kelsi Date: Tue, 10 Mar 2026 14:18:25 -0700 Subject: [PATCH] physics: sync server turn rate and fix SPLINE speed handlers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add getServerTurnRate() accessor and turnRateOverride_ field so the keyboard turn speed respects SMSG_FORCE_TURN_RATE_CHANGE from server - Convert rad/s → deg/s before applying to camera yaw logic - Fix SMSG_SPLINE_SET_RUN_BACK/SWIM/FLIGHT/FLIGHT_BACK/SWIM_BACK/WALK/ TURN_RATE handlers: all previously discarded the value; now update the corresponding serverXxxSpeed_ / serverTurnRate_ field when GUID matches playerGuid (camera controller syncs these every frame) --- include/game/game_handler.hpp | 1 + include/rendering/camera_controller.hpp | 3 +++ src/core/application.cpp | 1 + src/game/game_handler.cpp | 31 ++++++++++++++++++------- src/rendering/camera_controller.cpp | 11 ++++++--- 5 files changed, 36 insertions(+), 11 deletions(-) diff --git a/include/game/game_handler.hpp b/include/game/game_handler.hpp index af623646..d715b17a 100644 --- a/include/game/game_handler.hpp +++ b/include/game/game_handler.hpp @@ -1158,6 +1158,7 @@ public: float getServerFlightSpeed() const { return serverFlightSpeed_; } float getServerFlightBackSpeed() const { return serverFlightBackSpeed_; } float getServerRunBackSpeed() const { return serverRunBackSpeed_; } + float getServerTurnRate() const { return serverTurnRate_; } bool isPlayerRooted() const { return (movementInfo.flags & static_cast(MovementFlags::ROOT)) != 0; } diff --git a/include/rendering/camera_controller.hpp b/include/rendering/camera_controller.hpp index c13df29b..eabbe81c 100644 --- a/include/rendering/camera_controller.hpp +++ b/include/rendering/camera_controller.hpp @@ -98,6 +98,8 @@ public: void setFlightSpeedOverride(float speed) { flightSpeedOverride_ = speed; } void setFlightBackSpeedOverride(float speed) { flightBackSpeedOverride_ = speed; } void setRunBackSpeedOverride(float speed) { runBackSpeedOverride_ = speed; } + // Server turn rate in rad/s (SMSG_FORCE_TURN_RATE_CHANGE); 0 = use WOW_TURN_SPEED default + void setTurnRateOverride(float rateRadS) { turnRateOverride_ = rateRadS; } void setMovementRooted(bool rooted) { movementRooted_ = rooted; } bool isMovementRooted() const { return movementRooted_; } void setGravityDisabled(bool disabled) { gravityDisabled_ = disabled; } @@ -287,6 +289,7 @@ private: float flightSpeedOverride_ = 0.0f; float flightBackSpeedOverride_ = 0.0f; float runBackSpeedOverride_ = 0.0f; + float turnRateOverride_ = 0.0f; // rad/s; 0 = WOW_TURN_SPEED default (π rad/s) // Server-driven root state: when true, block all horizontal movement input. bool movementRooted_ = false; // Server-driven gravity disable (levitate/hover): skip gravity accumulation. diff --git a/src/core/application.cpp b/src/core/application.cpp index b6bfc975..78ec827d 100644 --- a/src/core/application.cpp +++ b/src/core/application.cpp @@ -1015,6 +1015,7 @@ void Application::update(float deltaTime) { renderer->getCameraController()->setFlightSpeedOverride(gameHandler->getServerFlightSpeed()); renderer->getCameraController()->setFlightBackSpeedOverride(gameHandler->getServerFlightBackSpeed()); renderer->getCameraController()->setRunBackSpeedOverride(gameHandler->getServerRunBackSpeed()); + renderer->getCameraController()->setTurnRateOverride(gameHandler->getServerTurnRate()); renderer->getCameraController()->setMovementRooted(gameHandler->isPlayerRooted()); renderer->getCameraController()->setGravityDisabled(gameHandler->isGravityDisabled()); renderer->getCameraController()->setFeatherFallActive(gameHandler->isFeatherFalling()); diff --git a/src/game/game_handler.cpp b/src/game/game_handler.cpp index df05652b..74656907 100644 --- a/src/game/game_handler.cpp +++ b/src/game/game_handler.cpp @@ -2401,9 +2401,13 @@ void GameHandler::handlePacket(network::Packet& packet) { uint64_t guid = UpdateObjectParser::readPackedGuid(packet); if (packet.getSize() - packet.getReadPos() < 4) break; float speed = packet.readFloat(); - if (guid == playerGuid && std::isfinite(speed) && speed > 0.1f && speed < 100.0f && - *logicalOp == Opcode::SMSG_SPLINE_SET_RUN_SPEED) { - serverRunSpeed_ = speed; + if (guid == playerGuid && std::isfinite(speed) && speed > 0.01f && speed < 200.0f) { + if (*logicalOp == Opcode::SMSG_SPLINE_SET_RUN_SPEED) + serverRunSpeed_ = speed; + else if (*logicalOp == Opcode::SMSG_SPLINE_SET_RUN_BACK_SPEED) + serverRunBackSpeed_ = speed; + else if (*logicalOp == Opcode::SMSG_SPLINE_SET_SWIM_SPEED) + serverSwimSpeed_ = speed; } break; } @@ -5190,11 +5194,22 @@ void GameHandler::handlePacket(network::Packet& packet) { case Opcode::SMSG_SPLINE_SET_WALK_SPEED: case Opcode::SMSG_SPLINE_SET_TURN_RATE: case Opcode::SMSG_SPLINE_SET_PITCH_RATE: { - // Minimal parse: PackedGuid + float speed (no per-entity speed store yet) - if (packet.getSize() - packet.getReadPos() >= 5) { - (void)UpdateObjectParser::readPackedGuid(packet); - if (packet.getSize() - packet.getReadPos() >= 4) - (void)packet.readFloat(); + // Minimal parse: PackedGuid + float speed + if (packet.getSize() - packet.getReadPos() < 5) break; + uint64_t sGuid = UpdateObjectParser::readPackedGuid(packet); + if (packet.getSize() - packet.getReadPos() < 4) break; + float sSpeed = packet.readFloat(); + if (sGuid == playerGuid && std::isfinite(sSpeed) && sSpeed > 0.01f && sSpeed < 200.0f) { + if (*logicalOp == Opcode::SMSG_SPLINE_SET_FLIGHT_SPEED) + serverFlightSpeed_ = sSpeed; + else if (*logicalOp == Opcode::SMSG_SPLINE_SET_FLIGHT_BACK_SPEED) + serverFlightBackSpeed_ = sSpeed; + else if (*logicalOp == Opcode::SMSG_SPLINE_SET_SWIM_BACK_SPEED) + serverSwimBackSpeed_ = sSpeed; + else if (*logicalOp == Opcode::SMSG_SPLINE_SET_WALK_SPEED) + serverWalkSpeed_ = sSpeed; + else if (*logicalOp == Opcode::SMSG_SPLINE_SET_TURN_RATE) + serverTurnRate_ = sSpeed; // rad/s } break; } diff --git a/src/rendering/camera_controller.cpp b/src/rendering/camera_controller.cpp index 21bb1392..ff6205aa 100644 --- a/src/rendering/camera_controller.cpp +++ b/src/rendering/camera_controller.cpp @@ -298,11 +298,16 @@ void CameraController::update(float deltaTime) { nowStrafeRight = !movBlocked && (keyD || keyE); } - // Keyboard turning updates camera yaw (character follows yaw in renderer) + // Keyboard turning updates camera yaw (character follows yaw in renderer). + // Use server turn rate (rad/s) when set; otherwise fall back to WOW_TURN_SPEED (deg/s). + const float activeTurnSpeedDeg = (turnRateOverride_ > 0.0f && turnRateOverride_ < 20.0f + && !std::isnan(turnRateOverride_)) + ? glm::degrees(turnRateOverride_) + : WOW_TURN_SPEED; if (nowTurnLeft && !nowTurnRight) { - yaw += WOW_TURN_SPEED * deltaTime; + yaw += activeTurnSpeedDeg * deltaTime; } else if (nowTurnRight && !nowTurnLeft) { - yaw -= WOW_TURN_SPEED * deltaTime; + yaw -= activeTurnSpeedDeg * deltaTime; } if (nowTurnLeft || nowTurnRight) { camera->setRotation(yaw, pitch);