diff options
Diffstat (limited to 'src/server')
| -rw-r--r-- | src/server/game/Entities/AreaTrigger/AreaTrigger.h | 2 | ||||
| -rw-r--r-- | src/server/game/Entities/Object/Object.cpp | 12 | ||||
| -rw-r--r-- | src/server/game/Entities/Object/Object.h | 6 | ||||
| -rw-r--r-- | src/server/game/Entities/Player/Player.cpp | 14 | ||||
| -rw-r--r-- | src/server/game/Grids/ObjectGridLoader.cpp | 3 | ||||
| -rw-r--r-- | src/server/game/Maps/Map.cpp | 1 | ||||
| -rw-r--r-- | src/server/game/Server/WorldSession.cpp | 1 | 
7 files changed, 34 insertions, 5 deletions
| diff --git a/src/server/game/Entities/AreaTrigger/AreaTrigger.h b/src/server/game/Entities/AreaTrigger/AreaTrigger.h index 5db5409d476..3ba82809ec3 100644 --- a/src/server/game/Entities/AreaTrigger/AreaTrigger.h +++ b/src/server/game/Entities/AreaTrigger/AreaTrigger.h @@ -63,7 +63,7 @@ class TC_GAME_API AreaTrigger : public WorldObject, public GridObject<AreaTrigge          bool IsServerSide() const { return _areaTriggerTemplate->Id.IsServerSide; } -        bool IsNeverVisibleFor(WorldObject const* /*seer*/) const override { return IsServerSide(); } +        bool IsNeverVisibleFor(WorldObject const* seer) const override { return WorldObject::IsNeverVisibleFor(seer) || IsServerSide(); }      private:          bool Create(uint32 areaTriggerCreatePropertiesId, Unit* caster, Unit* target, SpellInfo const* spell, Position const& pos, int32 duration, SpellCastVisual spellVisual, ObjectGuid const& castId, AuraEffect const* aurEff); diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp index f07d8f71fb6..e926d7d5aab 100644 --- a/src/server/game/Entities/Object/Object.cpp +++ b/src/server/game/Entities/Object/Object.cpp @@ -75,6 +75,7 @@ Object::Object() : m_values(this)      m_inWorld           = false;      m_isNewObject       = false; +    m_isDestroyedObject = false;      m_objectUpdated     = false;  } @@ -243,6 +244,17 @@ void Object::DestroyForPlayer(Player* target) const      target->SendDirectMessage(&packet);  } +void Object::SendOutOfRangeForPlayer(Player* target) const +{ +    ASSERT(target); + +    UpdateData updateData(target->GetMapId()); +    BuildOutOfRangeUpdateBlock(&updateData); +    WorldPacket packet; +    updateData.BuildPacket(&packet); +    target->SendDirectMessage(&packet); +} +  void Object::BuildMovementUpdate(ByteBuffer* data, CreateObjectBits flags) const  {      std::vector<uint32> const* PauseTimes = nullptr; diff --git a/src/server/game/Entities/Object/Object.h b/src/server/game/Entities/Object/Object.h index 065994344d3..7068f7e73bf 100644 --- a/src/server/game/Entities/Object/Object.h +++ b/src/server/game/Entities/Object/Object.h @@ -180,6 +180,7 @@ class TC_GAME_API Object          ByteBuffer PrepareValuesUpdateBuffer() const;          virtual void DestroyForPlayer(Player* target) const; +        void SendOutOfRangeForPlayer(Player* target) const;          virtual void ClearUpdateMask(bool remove); @@ -188,6 +189,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; @@ -391,6 +394,7 @@ class TC_GAME_API Object          ObjectGuid m_guid;          bool m_inWorld;          bool m_isNewObject; +        bool m_isDestroyedObject;          Object(Object const& right) = delete;          Object& operator=(Object const& right) = delete; @@ -745,7 +749,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 IsNeverVisibleFor(WorldObject const* /*seer*/) const { return !IsInWorld(); } +        virtual bool IsNeverVisibleFor(WorldObject const* /*seer*/) 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 diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index ba43e020d2f..36892a3bd4b 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -24186,7 +24186,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 @@ -24273,7 +24277,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->BuildDestroyUpdateBlock(&data); +              m_clientGUIDs.erase(target->GetGUID());              #ifdef TRINITY_DEBUG @@ -24281,7 +24289,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))          { diff --git a/src/server/game/Grids/ObjectGridLoader.cpp b/src/server/game/Grids/ObjectGridLoader.cpp index 666dd0037f3..f110d9b84ea 100644 --- a/src/server/game/Grids/ObjectGridLoader.cpp +++ b/src/server/game/Grids/ObjectGridLoader.cpp @@ -282,7 +282,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 &); diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp index 1b00a50db5a..eb0c6b1a0b8 100644 --- a/src/server/game/Maps/Map.cpp +++ b/src/server/game/Maps/Map.cpp @@ -3667,6 +3667,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); diff --git a/src/server/game/Server/WorldSession.cpp b/src/server/game/Server/WorldSession.cpp index 7d06c95b42a..2f71f2c9a45 100644 --- a/src/server/game/Server/WorldSession.cpp +++ b/src/server/game/Server/WorldSession.cpp @@ -648,6 +648,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: %u (IP: %s) Logout Character:[%s] %s Level: %d, XP: %u/%u (%u left)",              GetAccountId(), GetRemoteAddress().c_str(), _player->GetName().c_str(), _player->GetGUID().ToString().c_str(), _player->GetLevel(), | 
