From d7a726a42399935b89c68c1f1825530df941890e Mon Sep 17 00:00:00 2001 From: peterbell10 Date: Wed, 4 Mar 2020 14:47:51 +0000 Subject: Update LastSentPosition when entity has no speed (#4487) * Update LastSentPosition when entity has no speed * Restructure BroadcastMovementUpdate and always process relmove --- src/Entities/Entity.cpp | 103 +++++++++++++++++++++++------------------------- 1 file changed, 50 insertions(+), 53 deletions(-) diff --git a/src/Entities/Entity.cpp b/src/Entities/Entity.cpp index 9779c90de..57a4680bd 100644 --- a/src/Entities/Entity.cpp +++ b/src/Entities/Entity.cpp @@ -1878,72 +1878,69 @@ void cEntity::TeleportToCoords(double a_PosX, double a_PosY, double a_PosZ) void cEntity::BroadcastMovementUpdate(const cClientHandle * a_Exclude) { // Process packet sending every two ticks - if (GetWorld()->GetWorldAge() % 2 == 0) + if (GetWorld()->GetWorldAge() % 2 != 0) { - double SpeedSqr = GetSpeed().SqrLength(); - if (SpeedSqr == 0.0) - { - // Speed is zero, send this to clients once only as well as an absolute position - if (!m_bHasSentNoSpeed) - { - m_World->BroadcastEntityVelocity(*this, a_Exclude); - m_World->BroadcastTeleportEntity(*this, a_Exclude); - m_bHasSentNoSpeed = true; - } - } - else + return; + } + + if (GetSpeed().HasNonZeroLength()) + { + // Movin' + m_World->BroadcastEntityVelocity(*this, a_Exclude); + m_bHasSentNoSpeed = false; + } + else + { + // Speed is zero, send this to clients once only as well as an absolute position + if (!m_bHasSentNoSpeed) { - // Movin' m_World->BroadcastEntityVelocity(*this, a_Exclude); - m_bHasSentNoSpeed = false; + m_World->BroadcastTeleportEntity(*this, a_Exclude); + m_LastSentPosition = GetPosition(); + m_bHasSentNoSpeed = true; } + } - // Only send movement if speed is not 0 and 'no speed' was sent to client - if (!m_bHasSentNoSpeed || IsPlayer()) + // TODO: Pickups move disgracefully if relative move packets are sent as opposed to just velocity. Have a system to send relmove only when SetPosXXX() is called with a large difference in position + Vector3i Diff = (GetPosition() * 32.0).Floor() - (m_LastSentPosition * 32.0).Floor(); + if (Diff.HasNonZeroLength()) // Have we moved? + { + if ((abs(Diff.x) <= 127) && (abs(Diff.y) <= 127) && (abs(Diff.z) <= 127)) // Limitations of a Byte { - // TODO: Pickups move disgracefully if relative move packets are sent as opposed to just velocity. Have a system to send relmove only when SetPosXXX() is called with a large difference in position - Vector3i Diff = (GetPosition() * 32.0).Floor() - (m_LastSentPosition * 32.0).Floor(); - - if (Diff.HasNonZeroLength()) // Have we moved? + // Difference within Byte limitations, use a relative move packet + if (m_bDirtyOrientation) { - if ((abs(Diff.x) <= 127) && (abs(Diff.y) <= 127) && (abs(Diff.z) <= 127)) // Limitations of a Byte - { - // Difference within Byte limitations, use a relative move packet - if (m_bDirtyOrientation) - { - m_World->BroadcastEntityRelMoveLook(*this, Vector3(Diff), a_Exclude); - m_bDirtyOrientation = false; - } - else - { - m_World->BroadcastEntityRelMove(*this, Vector3(Diff), a_Exclude); - } - // Clients seem to store two positions, one for the velocity packet and one for the teleport / relmove packet - // The latter is only changed with a relmove / teleport, and m_LastSentPosition stores this position - m_LastSentPosition = GetPosition(); - } - else - { - // Too big a movement, do a teleport - m_World->BroadcastTeleportEntity(*this, a_Exclude); - m_LastSentPosition = GetPosition(); // See above - m_bDirtyOrientation = false; - } + m_World->BroadcastEntityRelMoveLook(*this, Vector3(Diff), a_Exclude); + m_bDirtyOrientation = false; } + else + { + m_World->BroadcastEntityRelMove(*this, Vector3(Diff), a_Exclude); + } + // Clients seem to store two positions, one for the velocity packet and one for the teleport / relmove packet + // The latter is only changed with a relmove / teleport, and m_LastSentPosition stores this position + m_LastSentPosition = GetPosition(); } - - if (m_bDirtyHead) - { - m_World->BroadcastEntityHeadLook(*this, a_Exclude); - m_bDirtyHead = false; - } - if (m_bDirtyOrientation) + else { - // Send individual update in case above (sending with rel-move packet) wasn't done - GetWorld()->BroadcastEntityLook(*this, a_Exclude); + // Too big a movement, do a teleport + m_World->BroadcastTeleportEntity(*this, a_Exclude); + m_LastSentPosition = GetPosition(); // See above m_bDirtyOrientation = false; } } + + if (m_bDirtyHead) + { + m_World->BroadcastEntityHeadLook(*this, a_Exclude); + m_bDirtyHead = false; + } + if (m_bDirtyOrientation) + { + // Send individual update in case above (sending with rel-move packet) wasn't done + GetWorld()->BroadcastEntityLook(*this, a_Exclude); + m_bDirtyOrientation = false; + } } -- cgit v1.2.3