Core/PacketIO: Properly destroy objects clientside when removing from world

This commit is contained in:
Shauren
2020-02-09 17:47:25 +01:00
parent bdc34c46aa
commit 38cc011af0
5 changed files with 32 additions and 15 deletions

View File

@@ -259,6 +259,11 @@ void Object::BuildValuesUpdateBlockForPlayerWithFlag(UpdateData* data, UF::Updat
data->AddUpdateBlock(buf);
}
void Object::BuildDestroyUpdateBlock(UpdateData* data) const
{
data->AddDestroyObject(GetGUID());
}
void Object::BuildOutOfRangeUpdateBlock(UpdateData* data) const
{
data->AddOutOfRangeGUID(GetGUID());
@@ -269,7 +274,7 @@ void Object::DestroyForPlayer(Player* target) const
ASSERT(target);
UpdateData updateData(target->GetMapId());
BuildOutOfRangeUpdateBlock(&updateData);
BuildDestroyUpdateBlock(&updateData);
WorldPacket packet;
updateData.BuildPacket(&packet);
target->SendDirectMessage(&packet);

View File

@@ -153,6 +153,7 @@ class TC_GAME_API Object
void BuildValuesUpdateBlockForPlayer(UpdateData* data, Player const* target) const;
void BuildValuesUpdateBlockForPlayerWithFlag(UpdateData* data, UF::UpdateFieldFlag flags, Player const* target) const;
void BuildDestroyUpdateBlock(UpdateData* data) const;
void BuildOutOfRangeUpdateBlock(UpdateData* data) const;
virtual void DestroyForPlayer(Player* target) const;

View File

@@ -22,6 +22,11 @@
UpdateData::UpdateData(uint32 map) : m_map(map), m_blockCount(0) { }
void UpdateData::AddDestroyObject(ObjectGuid guid)
{
m_destroyGUIDs.insert(guid);
}
void UpdateData::AddOutOfRangeGUID(GuidSet& guids)
{
m_outOfRangeGUIDs.insert(guids.begin(), guids.end());
@@ -41,18 +46,21 @@ void UpdateData::AddUpdateBlock(const ByteBuffer &block)
bool UpdateData::BuildPacket(WorldPacket* packet)
{
ASSERT(packet->empty()); // shouldn't happen
packet->Initialize(SMSG_UPDATE_OBJECT, 2 + 4 + (m_outOfRangeGUIDs.empty() ? 0 : 1 + 4 + 9 * m_outOfRangeGUIDs.size()) + m_data.wpos());
packet->Initialize(SMSG_UPDATE_OBJECT, 4 + 2 + 1 + (2 + 4 + 17 * (m_destroyGUIDs.size() + m_outOfRangeGUIDs.size())) + m_data.wpos());
*packet << uint32(m_blockCount);
*packet << uint16(m_map);
if (packet->WriteBit(!m_outOfRangeGUIDs.empty()))
if (packet->WriteBit(!m_outOfRangeGUIDs.empty() || !m_destroyGUIDs.empty()))
{
*packet << uint16(0); // object limit to instantly destroy - objects before this index on m_outOfRangeGUIDs list get "smoothly phased out"
*packet << uint32(m_outOfRangeGUIDs.size());
*packet << uint16(m_destroyGUIDs.size());
*packet << uint32(m_destroyGUIDs.size() + m_outOfRangeGUIDs.size());
for (GuidSet::const_iterator i = m_outOfRangeGUIDs.begin(); i != m_outOfRangeGUIDs.end(); ++i)
*packet << *i;
for (ObjectGuid const& destroyGuid : m_destroyGUIDs)
*packet << destroyGuid;
for (ObjectGuid const& outOfRangeGuid : m_outOfRangeGUIDs)
*packet << outOfRangeGuid;
}
*packet << uint32(m_data.size());
@@ -63,6 +71,7 @@ bool UpdateData::BuildPacket(WorldPacket* packet)
void UpdateData::Clear()
{
m_data.clear();
m_destroyGUIDs.clear();
m_outOfRangeGUIDs.clear();
m_blockCount = 0;
m_map = 0;

View File

@@ -43,6 +43,7 @@ class UpdateData
{
}
void AddDestroyObject(ObjectGuid guid);
void AddOutOfRangeGUID(GuidSet& guids);
void AddOutOfRangeGUID(ObjectGuid guid);
void AddUpdateBlock(const ByteBuffer &block);
@@ -55,6 +56,7 @@ class UpdateData
protected:
uint32 m_map;
uint32 m_blockCount;
GuidSet m_destroyGUIDs;
GuidSet m_outOfRangeGUIDs;
ByteBuffer m_data;

View File

@@ -3689,16 +3689,16 @@ void Player::DestroyForPlayer(Player* target) const
{
Unit::DestroyForPlayer(target);
for (uint8 i = 0; i < EQUIPMENT_SLOT_END; ++i)
{
if (m_items[i] == nullptr)
continue;
m_items[i]->DestroyForPlayer(target);
}
if (target == this)
{
for (uint8 i = 0; i < EQUIPMENT_SLOT_END; ++i)
{
if (m_items[i] == nullptr)
continue;
m_items[i]->DestroyForPlayer(target);
}
for (uint8 i = INVENTORY_SLOT_BAG_START; i < BANK_SLOT_BAG_END; ++i)
{
if (m_items[i] == nullptr)