fix(Core/Transports): Exclude out of world players from receiving transport creations/removes. (#26680)
Co-authored-by: Claude <claude@users.noreply.github.com>
This commit is contained in:
@@ -35,6 +35,7 @@
|
|||||||
#include "ScriptMgr.h"
|
#include "ScriptMgr.h"
|
||||||
#include "SpellAuras.h"
|
#include "SpellAuras.h"
|
||||||
#include "Transport.h"
|
#include "Transport.h"
|
||||||
|
#include "UpdateData.h"
|
||||||
#include "Vehicle.h"
|
#include "Vehicle.h"
|
||||||
#include "WaypointMovementGenerator.h"
|
#include "WaypointMovementGenerator.h"
|
||||||
#include "WorldPacket.h"
|
#include "WorldPacket.h"
|
||||||
@@ -129,6 +130,14 @@ void WorldSession::HandleMoveWorldportAck()
|
|||||||
if (Transport* t = _player->GetTransport())
|
if (Transport* t = _player->GetTransport())
|
||||||
if (!t->IsInMap(_player))
|
if (!t->IsInMap(_player))
|
||||||
{
|
{
|
||||||
|
// Client was never told to destroy its own transport
|
||||||
|
// Destroy it now or it keeps a phantom copy of the transport on the new map
|
||||||
|
UpdateData transData;
|
||||||
|
t->BuildOutOfRangeUpdateBlock(&transData);
|
||||||
|
WorldPacket packet;
|
||||||
|
transData.BuildPacket(packet);
|
||||||
|
_player->SendDirectMessage(&packet);
|
||||||
|
|
||||||
t->RemovePassenger(_player);
|
t->RemovePassenger(_player);
|
||||||
_player->m_transport = nullptr;
|
_player->m_transport = nullptr;
|
||||||
_player->m_movementInfo.transport.Reset();
|
_player->m_movementInfo.transport.Reset();
|
||||||
|
|||||||
@@ -376,9 +376,12 @@ bool Map::AddToMap(Transport* obj, bool /*checkTransport*/)
|
|||||||
_transports.insert(obj);
|
_transports.insert(obj);
|
||||||
|
|
||||||
// Broadcast creation to players
|
// Broadcast creation to players
|
||||||
|
// Skip players that are not in world. Sending the create to their loading client
|
||||||
|
// could materialize a lingering transport on whatever map they are teleporting to.
|
||||||
|
// They get the correct transport list from SendInitTransports when added to their new map
|
||||||
for (Map::PlayerList::const_iterator itr = GetPlayers().begin(); itr != GetPlayers().end(); ++itr)
|
for (Map::PlayerList::const_iterator itr = GetPlayers().begin(); itr != GetPlayers().end(); ++itr)
|
||||||
{
|
{
|
||||||
if (itr->GetSource()->GetTransport() != obj)
|
if (itr->GetSource()->IsInWorld() && itr->GetSource()->GetTransport() != obj)
|
||||||
{
|
{
|
||||||
UpdateData data;
|
UpdateData data;
|
||||||
obj->BuildCreateUpdateBlockForPlayer(&data, itr->GetSource());
|
obj->BuildCreateUpdateBlockForPlayer(&data, itr->GetSource());
|
||||||
@@ -761,8 +764,10 @@ void Map::RemoveFromMap(Transport* obj, bool remove)
|
|||||||
obj->BuildOutOfRangeUpdateBlock(&data);
|
obj->BuildOutOfRangeUpdateBlock(&data);
|
||||||
WorldPacket packet;
|
WorldPacket packet;
|
||||||
data.BuildPacket(packet);
|
data.BuildPacket(packet);
|
||||||
|
// Skip players that are not in world
|
||||||
|
// Their client already received the destroy from SendRemoveTransports when leaving this map
|
||||||
for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
|
for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
|
||||||
if (itr->GetSource()->GetTransport() != obj)
|
if (itr->GetSource()->IsInWorld() && itr->GetSource()->GetTransport() != obj)
|
||||||
itr->GetSource()->SendDirectMessage(&packet);
|
itr->GetSource()->SendDirectMessage(&packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user