mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-03-23 07:40:14 +00:00
physics: implement knockback simulation from SMSG_MOVE_KNOCK_BACK
Previously the handler ACKed with current position and ignored the velocity fields entirely (vcos/vsin/hspeed/vspeed were [[maybe_unused]]). The server expects the client to fly through the air on knockback — without simulation the player stays in place while the server models them as airborne, causing position desync and rubberbanding. Changes: - CameraController: add applyKnockBack(vcos, vsin, hspeed, vspeed) that sets knockbackHorizVel_ and launches verticalVelocity = -vspeed (server sends vspeed as negative for upward launches, matching TrinityCore) - Physics loop: each tick adds knockbackHorizVel_ to targetPos then applies exponential drag (KNOCKBACK_HORIZ_DRAG=4.5/s) until velocity < 0.05 u/s - GameHandler: parse all four fields, add KnockBackCallback, call it for the local player so the camera controller receives the impulse - Application: register the callback — routes server knockback to physics The existing ACK path is unchanged; the server gets position confirmation as before while the client now actually simulates the trajectory.
This commit is contained in:
parent
dd3f9e5b9e
commit
c622fde7be
5 changed files with 67 additions and 5 deletions
|
|
@ -685,6 +685,20 @@ void CameraController::update(float deltaTime) {
|
|||
targetPos += movement * speed * physicsDeltaTime;
|
||||
}
|
||||
|
||||
// Apply server-driven knockback horizontal velocity (decays over time).
|
||||
if (knockbackActive_) {
|
||||
targetPos.x += knockbackHorizVel_.x * physicsDeltaTime;
|
||||
targetPos.y += knockbackHorizVel_.y * physicsDeltaTime;
|
||||
// Exponential drag: reduce each frame so the player decelerates naturally.
|
||||
float drag = std::exp(-KNOCKBACK_HORIZ_DRAG * physicsDeltaTime);
|
||||
knockbackHorizVel_ *= drag;
|
||||
// Once negligible, clear the flag so collision/grounding work normally.
|
||||
if (glm::length(knockbackHorizVel_) < 0.05f) {
|
||||
knockbackActive_ = false;
|
||||
knockbackHorizVel_ = glm::vec2(0.0f);
|
||||
}
|
||||
}
|
||||
|
||||
// Jump with input buffering and coyote time
|
||||
if (nowJump) jumpBufferTimer = JUMP_BUFFER_TIME;
|
||||
if (grounded) coyoteTimer = COYOTE_TIME;
|
||||
|
|
@ -2096,5 +2110,21 @@ void CameraController::triggerMountJump() {
|
|||
}
|
||||
}
|
||||
|
||||
void CameraController::applyKnockBack(float vcos, float vsin, float hspeed, float vspeed) {
|
||||
// The server sends (vcos, vsin) as the 2D direction vector in server/wire
|
||||
// coordinate space. After the server→canonical→render swaps, the direction
|
||||
// in render space is simply (vcos, vsin) — the two swaps cancel each other.
|
||||
knockbackHorizVel_ = glm::vec2(vcos, vsin) * hspeed;
|
||||
knockbackActive_ = true;
|
||||
|
||||
// vspeed in the wire packet is negative when the server wants to launch the
|
||||
// player upward (matches TrinityCore: data << float(-speedZ)). Negate it
|
||||
// here to obtain the correct upward initial velocity.
|
||||
verticalVelocity = -vspeed;
|
||||
grounded = false;
|
||||
coyoteTimer = 0.0f;
|
||||
jumpBufferTimer = 0.0f;
|
||||
}
|
||||
|
||||
} // namespace rendering
|
||||
} // namespace wowee
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue