Core/Movement: Fixed player movement being blocked if teleported within the same map while not being in control of their character

This commit is contained in:
luis
2026-06-30 19:05:52 -03:00
parent 86fe9fac0f
commit 8c8d816d08
4 changed files with 17 additions and 5 deletions
+5 -2
View File
@@ -1283,7 +1283,7 @@ bool Player::TeleportTo(TeleportLocation const& teleportLocation, TeleportToOpti
SetUnitMovementFlags(GetUnitMovementFlags() & MOVEMENTFLAG_MASK_HAS_PLAYER_STATUS_OPCODE); SetUnitMovementFlags(GetUnitMovementFlags() & MOVEMENTFLAG_MASK_HAS_PLAYER_STATUS_OPCODE);
m_movementInfo.ResetJump(); m_movementInfo.ResetJump();
DisableSpline(); DisableSpline();
GetMotionMaster()->Remove(EFFECT_MOTION_TYPE); GetMotionMaster()->InterruptOnTeleport();
if (TransportBase* transport = GetTransport()) if (TransportBase* transport = GetTransport())
if (!teleportLocation.TransportGuid || teleportLocation.TransportGuid != transport->GetTransportGUID()) if (!teleportLocation.TransportGuid || teleportLocation.TransportGuid != transport->GetTransportGUID())
@@ -1332,10 +1332,13 @@ bool Player::TeleportTo(TeleportLocation const& teleportLocation, TeleportToOpti
// code for finish transfer called in WorldSession::HandleMovementOpcodes() // code for finish transfer called in WorldSession::HandleMovementOpcodes()
// at client packet CMSG_MOVE_TELEPORT_ACK // at client packet CMSG_MOVE_TELEPORT_ACK
SetTeleportState(TeleportState::WaitingForTeleportAck); SetTeleportState(GetPlayerMovingMe() ? TeleportState::WaitingForTeleportAck : TeleportState::NotTeleporting);
// near teleport, triggering send CMSG_MOVE_TELEPORT_ACK from client at landing // near teleport, triggering send CMSG_MOVE_TELEPORT_ACK from client at landing
if (!GetSession()->PlayerLogout()) if (!GetSession()->PlayerLogout())
SendTeleportPacket(m_teleport_dest); SendTeleportPacket(m_teleport_dest);
if (!IsBeingTeleportedNear()) // update position immediately if we will not be waiting for client ACK
UpdatePosition(m_teleport_dest.Location, true);
} }
else else
{ {
+4 -3
View File
@@ -13602,11 +13602,12 @@ bool Unit::CanSwim() const
void Unit::NearTeleportTo(TeleportLocation const& target, bool casting) void Unit::NearTeleportTo(TeleportLocation const& target, bool casting)
{ {
DisableSpline(); if (Player* player = ToPlayer())
if (GetTypeId() == TYPEID_PLAYER) player->TeleportTo(target, TELE_TO_NOT_LEAVE_TRANSPORT | TELE_TO_NOT_LEAVE_COMBAT | (casting ? TELE_TO_SPELL : TELE_TO_NONE));
ToPlayer()->TeleportTo(target, TELE_TO_NOT_LEAVE_TRANSPORT | TELE_TO_NOT_LEAVE_COMBAT | (casting ? TELE_TO_SPELL : TELE_TO_NONE));
else else
{ {
DisableSpline();
GetMotionMaster()->InterruptOnTeleport();
SendTeleportPacket(target); SendTeleportPacket(target);
UpdatePosition(target.Location, true); UpdatePosition(target.Location, true);
UpdateObjectVisibility(); UpdateObjectVisibility();
@@ -533,6 +533,13 @@ bool MotionMaster::StopOnDeath()
return true; return true;
} }
void MotionMaster::InterruptOnTeleport()
{
if (MovementGenerator* top = GetCurrentMovementGenerator())
if (!top->HasFlag(MOVEMENTGENERATOR_FLAG_DEACTIVATED | MOVEMENTGENERATOR_FLAG_FINALIZED))
top->Deactivate(_owner); // only deactivate top, don't remove it. non-resumable generators will clean up themselves on next update
}
void MotionMaster::MoveIdle() void MotionMaster::MoveIdle()
{ {
Add(GetIdleMovementGenerator(), MOTION_SLOT_DEFAULT); Add(GetIdleMovementGenerator(), MOTION_SLOT_DEFAULT);
+1
View File
@@ -152,6 +152,7 @@ public:
void PropagateSpeedChange(); void PropagateSpeedChange();
bool GetDestination(float& x, float& y, float& z); bool GetDestination(float& x, float& y, float& z);
bool StopOnDeath(); bool StopOnDeath();
void InterruptOnTeleport();
void MoveIdle(); void MoveIdle();
void MoveTargetedHome(); void MoveTargetedHome();