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:
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();
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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))
|
||||
{
|
||||
|
||||
@@ -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 &);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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());
|
||||
|
||||
Reference in new issue
Block a user