aboutsummaryrefslogtreecommitdiff
path: root/src/server/game/Entities/DynamicObject
diff options
context:
space:
mode:
authorQAston <qaston@gmail.com>2011-02-04 00:27:43 +0100
committerQAston <qaston@gmail.com>2011-02-04 00:27:43 +0100
commitd18193e52dd0799927ac925158300ef4e5c88ba8 (patch)
tree07f0d73d551d428d4b2a985e02d33d8e8a18465e /src/server/game/Entities/DynamicObject
parent1740df0fac298ccb61dd35f4e1c08e76932be212 (diff)
Core/DynamicObjects: Change the way how dynamic objects are bound to their owners, fixes some crashes in Aura::GetOwner.
Diffstat (limited to 'src/server/game/Entities/DynamicObject')
-rwxr-xr-xsrc/server/game/Entities/DynamicObject/DynamicObject.cpp128
-rwxr-xr-xsrc/server/game/Entities/DynamicObject/DynamicObject.h14
2 files changed, 95 insertions, 47 deletions
diff --git a/src/server/game/Entities/DynamicObject/DynamicObject.cpp b/src/server/game/Entities/DynamicObject/DynamicObject.cpp
index c7e64e9d3aa..3fa901a237a 100755
--- a/src/server/game/Entities/DynamicObject/DynamicObject.cpp
+++ b/src/server/game/Entities/DynamicObject/DynamicObject.cpp
@@ -36,37 +36,47 @@ DynamicObject::DynamicObject() : WorldObject()
m_valuesCount = DYNAMICOBJECT_END;
- m_aura = 0;
+ m_aura = NULL;
m_duration = 0;
+ m_caster = NULL;
+ m_isViewpoint = false;
+}
+
+DynamicObject::~DynamicObject()
+{
+ // make sure all references were properly removed
+ ASSERT(!m_aura);
+ ASSERT(!m_caster);
+ ASSERT(!m_isViewpoint);
}
void DynamicObject::AddToWorld()
{
- ///- Register the dynamicObject for guid lookup
+ ///- Register the dynamicObject for guid lookup and for caster
if (!IsInWorld())
{
sObjectAccessor->AddObject(this);
WorldObject::AddToWorld();
+ BindToCaster();
}
}
void DynamicObject::RemoveFromWorld()
{
- ///- Remove the dynamicObject from the accessor
+ ///- Remove the dynamicObject from the accessor and from all lists of objects in world
if (IsInWorld())
{
- if (m_isWorldObject)
- {
- if (Unit *caster = GetCaster())
- {
- if (caster->GetTypeId() == TYPEID_PLAYER)
- caster->ToPlayer()->SetViewpoint(this, false);
- }
- else
- {
- sLog->outCrash("DynamicObject::RemoveFromWorld cannot find viewpoint owner");
- }
- }
+ if (m_isViewpoint)
+ RemoveCasterViewpoint();
+
+ if (m_aura)
+ RemoveAura();
+
+ // dynobj could get removed in Aura::RemoveAura
+ if (!IsInWorld())
+ return;
+
+ UnbindFromCaster();
WorldObject::RemoveFromWorld();
sObjectAccessor->RemoveObject(this);
}
@@ -102,21 +112,11 @@ bool DynamicObject::Create(uint32 guidlow, Unit *caster, uint32 spellId, const P
return true;
}
-Unit* DynamicObject::GetCaster() const
-{
- // can be not found in some cases
- return ObjectAccessor::GetUnit(*this, GetCasterGUID());
-}
-
void DynamicObject::Update(uint32 p_time)
{
- // caster can be not in world at time dynamic object update, but dynamic object not yet deleted in Unit destructor
- Unit* caster = GetCaster();
- if (!caster)
- {
- Delete();
- return;
- }
+ // caster has to be always avalible and in the same map
+ ASSERT(m_caster);
+ ASSERT(m_caster->GetMap() == GetMap());
bool expired = false;
@@ -125,7 +125,7 @@ void DynamicObject::Update(uint32 p_time)
if (!m_aura->IsRemoved())
m_aura->UpdateOwner(p_time, this);
- // m_aura may be set to null in Unit::RemoveGameObject call
+ // m_aura may be set to null in Aura::UpdateOwner call
if (m_aura && (m_aura->IsRemoved() || m_aura->IsExpired()))
expired = true;
}
@@ -138,28 +138,19 @@ void DynamicObject::Update(uint32 p_time)
}
if (expired)
- {
- caster->RemoveDynObjectWithGUID(GetGUID());
- Delete();
- }
+ Remove();
else
sScriptMgr->OnDynamicObjectUpdate(this, p_time);
}
-void DynamicObject::Delete()
+void DynamicObject::Remove()
{
- if (m_aura)
+ if (IsInWorld())
{
- // dynObj may be removed in Aura::Remove - we cannot delete there
- // so recheck aura here
- if (!m_aura->IsRemoved())
- m_aura->_Remove(AURA_REMOVE_BY_DEFAULT);
- delete m_aura;
- m_aura = NULL;
+ SendObjectDeSpawnAnim(GetGUID());
+ RemoveFromWorld();
+ AddObjectToRemoveList();
}
- SendObjectDeSpawnAnim(GetGUID());
- RemoveFromWorld();
- AddObjectToRemoveList();
}
int32 DynamicObject::GetDuration() const
@@ -182,3 +173,52 @@ void DynamicObject::Delay(int32 delaytime)
{
SetDuration(GetDuration() - delaytime);
}
+
+void DynamicObject::SetAura(Aura * aura)
+{
+ ASSERT (!m_aura && aura);
+ m_aura = aura;
+}
+
+void DynamicObject::RemoveAura()
+{
+ ASSERT (m_aura);
+ if (!m_aura->IsRemoved())
+ m_aura->_Remove(AURA_REMOVE_BY_DEFAULT);
+ delete m_aura;
+ m_aura = NULL;
+}
+
+void DynamicObject::SetCasterViewpoint()
+{
+ if (Player * caster = m_caster->ToPlayer())
+ {
+ caster->SetViewpoint(this, true);
+ m_isViewpoint = true;
+ }
+}
+
+void DynamicObject::RemoveCasterViewpoint()
+{
+ if (Player * caster = m_caster->ToPlayer())
+ {
+ caster->SetViewpoint(this, false);
+ m_isViewpoint = false;
+ }
+}
+
+void DynamicObject::BindToCaster()
+{
+ ASSERT(!m_caster);
+ m_caster = ObjectAccessor::GetUnit(*this, GetCasterGUID());
+ ASSERT(m_caster);
+ ASSERT(m_caster->GetMap() == GetMap());
+ m_caster->_RegisterDynObject(this);
+}
+
+void DynamicObject::UnbindFromCaster()
+{
+ ASSERT(m_caster);
+ m_caster->_UnregisterDynObject(this);
+ m_caster = NULL;
+}
diff --git a/src/server/game/Entities/DynamicObject/DynamicObject.h b/src/server/game/Entities/DynamicObject/DynamicObject.h
index 6034db73cc9..7d42c1e4212 100755
--- a/src/server/game/Entities/DynamicObject/DynamicObject.h
+++ b/src/server/game/Entities/DynamicObject/DynamicObject.h
@@ -29,21 +29,27 @@ class DynamicObject : public WorldObject, public GridObject<DynamicObject>
{
public:
explicit DynamicObject();
+ ~DynamicObject();
void AddToWorld();
void RemoveFromWorld();
bool Create(uint32 guidlow, Unit *caster, uint32 spellId, const Position &pos, float radius, bool active);
void Update(uint32 p_time);
- void Delete();
+ void Remove();
void SetDuration(int32 newDuration);
int32 GetDuration() const;
- void SetAura(Aura * aura) {ASSERT (!m_aura && aura); m_aura = aura;}
void Delay(int32 delaytime);
+ void SetAura(Aura * aura);
+ void RemoveAura();
+ void SetCasterViewpoint();
+ void RemoveCasterViewpoint();
+ Unit * GetCaster() const { return m_caster; }
+ void BindToCaster();
+ void UnbindFromCaster();
uint32 GetSpellId() const { return GetUInt32Value(DYNAMICOBJECT_SPELLID); }
uint64 GetCasterGUID() const { return GetUInt64Value(DYNAMICOBJECT_CASTER); }
float GetRadius() const { return GetFloatValue(DYNAMICOBJECT_RADIUS); }
- Unit* GetCaster() const;
void Say(int32 textId, uint32 language, uint64 TargetGuid) { MonsterSay(textId,language,TargetGuid); }
void Yell(int32 textId, uint32 language, uint64 TargetGuid) { MonsterYell(textId,language,TargetGuid); }
@@ -54,5 +60,7 @@ class DynamicObject : public WorldObject, public GridObject<DynamicObject>
protected:
int32 m_duration; // for non-aura dynobjects
Aura * m_aura;
+ Unit * m_caster;
+ bool m_isViewpoint;
};
#endif