Skip to content

Commit 59e641d

Browse files
committed
Core/Movement: Fixed player movement being blocked if teleported within the same map while not being in control of their character
1 parent 8788094 commit 59e641d

4 files changed

Lines changed: 22 additions & 12 deletions

File tree

src/server/game/Entities/Player/Player.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1570,7 +1570,7 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati
15701570
// reset movement flags at teleport, because player will continue move with these flags after teleport
15711571
SetUnitMovementFlags(GetUnitMovementFlags() & MOVEMENTFLAG_MASK_HAS_PLAYER_STATUS_OPCODE);
15721572
DisableSpline();
1573-
GetMotionMaster()->Remove(EFFECT_MOTION_TYPE);
1573+
GetMotionMaster()->InterruptOnTeleport();
15741574

15751575
if (Transport* transport = GetTransport())
15761576
{
@@ -1622,10 +1622,13 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati
16221622

16231623
// code for finish transfer called in WorldSession::HandleMovementOpcodes()
16241624
// at client packet MSG_MOVE_TELEPORT_ACK
1625-
SetSemaphoreTeleportNear(true);
1625+
SetSemaphoreTeleportNear(IsMovedByClient());
16261626
// near teleport, triggering send MSG_MOVE_TELEPORT_ACK from client at landing
16271627
if (!GetSession()->PlayerLogout())
16281628
SendTeleportPacket(m_teleport_dest, (options & TELE_TO_TRANSPORT_TELEPORT) != 0);
1629+
1630+
if (!IsBeingTeleportedNear()) // update position immediately if we will not be waiting for client ACK
1631+
UpdatePosition(m_teleport_dest, true);
16291632
}
16301633
else
16311634
{

src/server/game/Entities/Unit/Unit.cpp

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12821,14 +12821,15 @@ bool Unit::CanSwim() const
1282112821

1282212822
void Unit::NearTeleportTo(Position const& pos, bool casting /*= false*/)
1282312823
{
12824-
DisableSpline();
12825-
if (GetTypeId() == TYPEID_PLAYER)
12824+
if (Player* player = ToPlayer())
1282612825
{
1282712826
WorldLocation target(GetMapId(), pos);
12828-
ToPlayer()->TeleportTo(target, TELE_TO_NOT_LEAVE_TRANSPORT | TELE_TO_NOT_LEAVE_COMBAT | (casting ? TELE_TO_SPELL : 0));
12827+
player->TeleportTo(target, TELE_TO_NOT_LEAVE_TRANSPORT | TELE_TO_NOT_LEAVE_COMBAT | (casting ? TELE_TO_SPELL : 0));
1282912828
}
1283012829
else
1283112830
{
12831+
DisableSpline();
12832+
GetMotionMaster()->InterruptOnTeleport();
1283212833
SendTeleportPacket(pos);
1283312834
UpdatePosition(pos, true);
1283412835
UpdateObjectVisibility();
@@ -12865,7 +12866,7 @@ void Unit::SendTeleportPacket(Position const& pos, bool teleportingTransport /*=
1286512866

1286612867
WorldPacket moveUpdateTeleport(MSG_MOVE_TELEPORT, 38);
1286712868
moveUpdateTeleport << GetPackGUID();
12868-
Unit* broadcastSource = this;
12869+
Unit::BuildMovementPacket(pos, transportPos, teleportMovementInfo, &moveUpdateTeleport);
1286912870

1287012871
if (IsMovedByClient())
1287112872
{
@@ -12876,13 +12877,11 @@ void Unit::SendTeleportPacket(Position const& pos, bool teleportingTransport /*=
1287612877
Unit::BuildMovementPacket(pos, transportPos, teleportMovementInfo, &moveTeleport);
1287712878
playerMover->SendDirectMessage(&moveTeleport);
1287812879

12879-
broadcastSource = playerMover;
12880+
// Broadcast the packet to everyone except self.
12881+
SendMessageToSet(&moveUpdateTeleport, playerMover);
1288012882
}
12881-
12882-
Unit::BuildMovementPacket(pos, transportPos, teleportMovementInfo, &moveUpdateTeleport);
12883-
12884-
// Broadcast the packet to everyone except self.
12885-
broadcastSource->SendMessageToSet(&moveUpdateTeleport, false);
12883+
else
12884+
SendMessageToSet(&moveUpdateTeleport, true);
1288612885
}
1288712886

1288812887
bool Unit::UpdatePosition(float x, float y, float z, float orientation, bool teleport)

src/server/game/Movement/MotionMaster.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -534,6 +534,13 @@ bool MotionMaster::StopOnDeath()
534534
return true;
535535
}
536536

537+
void MotionMaster::InterruptOnTeleport()
538+
{
539+
if (MovementGenerator* top = GetCurrentMovementGenerator())
540+
if (!top->HasFlag(MOVEMENTGENERATOR_FLAG_DEACTIVATED | MOVEMENTGENERATOR_FLAG_FINALIZED))
541+
top->Deactivate(_owner); // only deactivate top, don't remove it. non-resumable generators will clean up themselves on next update
542+
}
543+
537544
void MotionMaster::MoveIdle()
538545
{
539546
Add(GetIdleMovementGenerator(), MOTION_SLOT_DEFAULT);

src/server/game/Movement/MotionMaster.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,7 @@ class TC_GAME_API MotionMaster
148148
void PropagateSpeedChange();
149149
bool GetDestination(float &x, float &y, float &z);
150150
bool StopOnDeath();
151+
void InterruptOnTeleport();
151152

152153
void MoveIdle();
153154
void MoveTargetedHome();

0 commit comments

Comments
 (0)