aboutsummaryrefslogtreecommitdiff
path: root/src/server/game/Entities
diff options
context:
space:
mode:
authorShauren <shauren.trinity@gmail.com>2022-01-29 16:01:57 +0100
committerShauren <shauren.trinity@gmail.com>2022-01-29 16:01:57 +0100
commit5a82a0381d704e4b4b9976daf04d541d1130e541 (patch)
tree3c24066dfab82cfcf572f4613c1b5de003da8522 /src/server/game/Entities
parent472384e75781ce362af9721fc16928da9eea82dd (diff)
Core/Objects: Properly choose between "Destroyed" or "OutOfRange" during visibility update
Diffstat (limited to 'src/server/game/Entities')
-rw-r--r--src/server/game/Entities/AreaTrigger/AreaTrigger.h2
-rw-r--r--src/server/game/Entities/Object/Object.cpp12
-rw-r--r--src/server/game/Entities/Object/Object.h6
-rw-r--r--src/server/game/Entities/Player/Player.cpp14
4 files changed, 29 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))
{