Core/Objects: ported master branch handling for properly destroying objects via out of range and destroy object opcode

# Conflicts:
#	src/server/game/Entities/Creature/Creature.cpp
This commit is contained in:
Shauren authored and Ovahlord committed 2022-02-02 16:24:42 +01:00
1 parent 284b2a23eb
commit f2b4f2208e
10 files changed
+43 -16

No files matched your search

@@ -1992,7 +1992,7 @@ void Creature::Respawn(bool force)
if (m_respawnCompatibilityMode)
{
DestroyForNearbyPlayers();
UpdateObjectVisibilityOnDestroy();
RemoveCorpse(false);
if (getDeathState() == DEAD)
@@ -2055,7 +2055,7 @@ void Creature::ForcedDespawn(uint32 timeMSToDespawn, Seconds forceRespawnTimer)
uint32 respawnDelay = GetRespawnDelay();
// do it before killing creature
DestroyForNearbyPlayers();
UpdateObjectVisibilityOnDestroy();
bool overrideRespawnTime = false;
if (IsAlive())
@@ -164,10 +164,7 @@ void DynamicObject::Update(uint32 p_time)
void DynamicObject::Remove()
{
if (IsInWorld())
{
RemoveFromWorld();
AddObjectToRemoveList();
}
}
void DynamicObject::BuildValuesUpdate(uint8 updateType, ByteBuffer* data, Player* target) const
@@ -789,7 +789,7 @@ void GameObject::Update(uint32 diff)
m_respawnTime = 0;
if (m_spawnId)
DestroyForNearbyPlayers();
UpdateObjectVisibilityOnDestroy();
else
Delete();
@@ -806,7 +806,7 @@ void GameObject::Update(uint32 diff)
SaveRespawnTime();
if (m_respawnCompatibilityMode)
DestroyForNearbyPlayers();
UpdateObjectVisibilityOnDestroy();
else
AddObjectToRemoveList();
+12 -1
View File
@@ -276,6 +276,17 @@ void Object::DestroyForPlayer(Player* target, bool isDead /*= false*/) const
target->SendDirectMessage(packet.Write());
}
void Object::SendOutOfRangeForPlayer(Player* target) const
{
ASSERT(target);
UpdateData updateData(target->GetMapId());
BuildOutOfRangeUpdateBlock(&updateData);
WorldPacket packet;
updateData.BuildPacket(&packet);
target->SendDirectMessage(&packet);
}
int32 Object::GetInt32Value(uint16 index) const
{
ASSERT(index < m_valuesCount || PrintIndexError(index, false));
@@ -1265,7 +1276,7 @@ void WorldObject::RemoveFromWorld()
if (!IsInWorld())
return;
DestroyForNearbyPlayers();
UpdateObjectVisibilityOnDestroy();
Object::RemoveFromWorld();
}
+6 -1
View File
@@ -90,6 +90,7 @@ class TC_GAME_API Object
void BuildOutOfRangeUpdateBlock(UpdateData* data) const;
virtual void DestroyForPlayer(Player* target, bool isDead = false) const;
void SendOutOfRangeForPlayer(Player* target) const;
int32 GetInt32Value(uint16 index) const;
uint32 GetUInt32Value(uint16 index) const;
@@ -145,6 +146,8 @@ class TC_GAME_API Object
virtual bool hasQuest(uint32 /* quest_id */) const { return false; }
virtual bool hasInvolvedQuest(uint32 /* quest_id */) const { return false; }
void SetIsNewObject(bool enable) { m_isNewObject = enable; }
bool IsDestroyedObject() const { return m_isDestroyedObject; }
void SetDestroyedObject(bool destroyed) { m_isDestroyedObject = destroyed; }
virtual void BuildUpdate(UpdateDataMapType&) { }
void BuildFieldsUpdate(Player*, UpdateDataMapType &) const;
@@ -222,6 +225,7 @@ class TC_GAME_API Object
private:
bool m_inWorld;
bool m_isNewObject;
bool m_isDestroyedObject;
PackedGuid m_PackGUID;
@@ -426,6 +430,7 @@ class TC_GAME_API WorldObject : public Object, public WorldLocation
void DestroyForNearbyPlayers();
virtual void UpdateObjectVisibility(bool forced = true);
virtual void UpdateObjectVisibilityOnCreate() { UpdateObjectVisibility(true); }
virtual void UpdateObjectVisibilityOnDestroy() { DestroyForNearbyPlayers(); }
void UpdatePositionData();
void BuildUpdate(UpdateDataMapType&) override;
@@ -516,7 +521,7 @@ class TC_GAME_API WorldObject : public Object, public WorldLocation
void SetLocationMapId(uint32 _mapId) { m_mapId = _mapId; }
void SetLocationInstanceId(uint32 _instanceId) { m_InstanceId = _instanceId; }
virtual bool IsNeverVisible() const { return !IsInWorld(); }
virtual bool IsNeverVisible() const { return !IsInWorld() || IsDestroyedObject(); }
virtual bool IsAlwaysVisibleFor(WorldObject const* /*seer*/) const { return false; }
virtual bool IsInvisibleDueToDespawn() const { return false; }
//difference from IsAlwaysVisibleFor: 1. after distance check; 2. use owner or charmer as seer
+11 -3
View File
@@ -23121,7 +23121,11 @@ void Player::UpdateVisibilityOf(WorldObject* target)
if (target->GetTypeId() == TYPEID_UNIT)
BeforeVisibilityDestroy<Creature>(target->ToCreature(), this);
target->DestroyForPlayer(this);
if (!target->IsDestroyedObject())
target->SendOutOfRangeForPlayer(this);
else
target->DestroyForPlayer(this);
m_clientGUIDs.erase(target->GetGUID());
#ifdef TRINITY_DEBUG
@@ -23209,7 +23213,11 @@ void Player::UpdateVisibilityOf(T* target, UpdateData& data, std::set<Unit*>& vi
{
BeforeVisibilityDestroy<T>(target, this);
target->BuildOutOfRangeUpdateBlock(&data);
if (!target->IsDestroyedObject())
target->BuildOutOfRangeUpdateBlock(&data);
else
target->DestroyForPlayer(this);
m_clientGUIDs.erase(target->GetGUID());
#ifdef TRINITY_DEBUG
@@ -23217,7 +23225,7 @@ void Player::UpdateVisibilityOf(T* target, UpdateData& data, std::set<Unit*>& vi
#endif
}
}
else //if (visibleNow.size() < 30 || target->GetTypeId() == TYPEID_UNIT && target->ToCreature()->IsVehicle())
else
{
if (CanSeeOrDetect(target, false, true))
{
+2 -1
View File
@@ -1850,11 +1850,12 @@ class TC_GAME_API Unit : public WorldObject
void CancelPendingCastRequest();
bool CanRequestSpellCast(SpellInfo const* spell) const;
void DestroyForPlayer(Player* target, bool onDeath = false) const override;
protected:
explicit Unit (bool isWorldObject);
void BuildValuesUpdate(uint8 updatetype, ByteBuffer* data, Player* target) const override;
void DestroyForPlayer(Player* target, bool onDeath = false) const override;
void _UpdateSpells(uint32 time);
void _DeleteRemovedAuras();
@@ -255,7 +255,10 @@ template<class T>
void ObjectGridCleaner::Visit(GridRefManager<T> &m)
{
for (typename GridRefManager<T>::iterator iter = m.begin(); iter != m.end(); ++iter)
{
iter->GetSource()->SetDestroyedObject(true);
iter->GetSource()->CleanupsBeforeDelete();
}
}
template void ObjectGridUnloader::Visit(CreatureMapType &);
+4 -3
View File
@@ -1091,7 +1091,7 @@ void Map::RemovePlayerFromMap(Player* player, bool remove)
SendRemoveTransports(player);
if (!inWorld) // if was in world, RemoveFromWorld() called DestroyForNearbyPlayers()
player->DestroyForNearbyPlayers(); // previous player->UpdateObjectVisibility(true)
player->UpdateObjectVisibilityOnDestroy();
if (player->IsInGrid())
player->RemoveFromGrid();
@@ -1112,7 +1112,7 @@ void Map::RemoveFromMap(T *obj, bool remove)
RemoveFromActive(obj);
if (!inWorld) // if was in world, RemoveFromWorld() called DestroyForNearbyPlayers()
obj->DestroyForNearbyPlayers(); // previous obj->UpdateObjectVisibility(true)
obj->UpdateObjectVisibilityOnDestroy();
obj->RemoveFromGrid();
@@ -3489,6 +3489,7 @@ void Map::AddObjectToRemoveList(WorldObject* obj)
{
ASSERT(obj->GetMapId() == GetId() && obj->GetInstanceId() == GetInstanceId());
obj->SetDestroyedObject(true);
obj->CleanupsBeforeDelete(false); // remove or simplify at least cross referenced links
i_objectsToRemove.insert(obj);
@@ -4541,7 +4542,7 @@ void Map::RemoveCorpse(Corpse* corpse)
{
ASSERT(corpse);
corpse->DestroyForNearbyPlayers();
corpse->UpdateObjectVisibilityOnDestroy();
if (corpse->IsInGrid())
RemoveFromMap(corpse, false);
else
+1
View File
@@ -645,6 +645,7 @@ void WorldSession::LogoutPlayer(bool save)
// the player may not be in the world when logging out
// e.g if he got disconnected during a transfer to another map
// calls to GetMap in this case may cause crashes
_player->SetDestroyedObject(true);
_player->CleanupsBeforeDelete();
TC_LOG_INFO("entities.player.character", "Account: %d (IP: %s) Logout Character:[%s] (GUID: %u) Level: %d",
GetAccountId(), GetRemoteAddress().c_str(), _player->GetName().c_str(), _player->GetGUID().GetCounter(), _player->getLevel());