aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rwxr-xr-xsrc/server/game/Entities/DynamicObject/DynamicObject.cpp128
-rwxr-xr-xsrc/server/game/Entities/DynamicObject/DynamicObject.h14
-rwxr-xr-xsrc/server/game/Entities/Unit/Unit.cpp63
-rwxr-xr-xsrc/server/game/Entities/Unit/Unit.h11
-rwxr-xr-xsrc/server/game/Grids/ObjectGridLoader.cpp4
-rwxr-xr-xsrc/server/game/Spells/SpellEffects.cpp14
6 files changed, 135 insertions, 99 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
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
index fde20ab09ec..ceff4094855 100755
--- a/src/server/game/Entities/Unit/Unit.cpp
+++ b/src/server/game/Entities/Unit/Unit.cpp
@@ -4468,57 +4468,50 @@ int32 Unit::GetMaxNegativeAuraModifierByAffectMask(AuraType auratype, SpellEntry
return modifier;
}
-void Unit::AddDynObject(DynamicObject* dynObj)
+void Unit::_RegisterDynObject(DynamicObject* dynObj)
{
- m_dynObjGUIDs.push_back(dynObj->GetGUID());
+ m_dynObj.push_back(dynObj);
}
-void Unit::RemoveDynObject(uint32 spellid)
+void Unit::_UnregisterDynObject(DynamicObject* dynObj)
{
- if (m_dynObjGUIDs.empty())
- return;
- for (DynObjectGUIDs::iterator i = m_dynObjGUIDs.begin(); i != m_dynObjGUIDs.end();)
- {
- DynamicObject* dynObj = GetMap()->GetDynamicObject(*i);
- if (!dynObj) // may happen if a dynobj is removed when grid unload
- i = m_dynObjGUIDs.erase(i);
- else if (spellid == 0 || dynObj->GetSpellId() == spellid)
- {
- dynObj->Delete();
- i = m_dynObjGUIDs.erase(i);
- }
- else
- ++i;
- }
+ m_dynObj.remove(dynObj);
}
-void Unit::RemoveAllDynObjects()
+DynamicObject * Unit::GetDynObject(uint32 spellId)
{
- while (!m_dynObjGUIDs.empty())
+ if (m_dynObj.empty())
+ return NULL;
+ for (DynObjectList::const_iterator i = m_dynObj.begin(); i != m_dynObj.end();++i)
{
- DynamicObject* dynObj = GetMap()->GetDynamicObject(*m_dynObjGUIDs.begin());
- if (dynObj)
- dynObj->Delete();
- m_dynObjGUIDs.erase(m_dynObjGUIDs.begin());
+ DynamicObject* dynObj = *i;
+ if (dynObj->GetSpellId() == spellId)
+ return dynObj;
}
+ return NULL;
}
-DynamicObject * Unit::GetDynObject(uint32 spellId)
+void Unit::RemoveDynObject(uint32 spellId)
{
- for (DynObjectGUIDs::iterator i = m_dynObjGUIDs.begin(); i != m_dynObjGUIDs.end();)
+ if (m_dynObj.empty())
+ return;
+ for (DynObjectList::iterator i = m_dynObj.begin(); i != m_dynObj.end();)
{
- DynamicObject* dynObj = GetMap()->GetDynamicObject(*i);
- if (!dynObj)
+ DynamicObject* dynObj = *i;
+ if (dynObj->GetSpellId() == spellId)
{
- i = m_dynObjGUIDs.erase(i);
- continue;
+ dynObj->Remove();
+ i = m_dynObj.begin();
}
-
- if (dynObj->GetSpellId() == spellId)
- return dynObj;
- ++i;
+ else
+ ++i;
}
- return NULL;
+}
+
+void Unit::RemoveAllDynObjects()
+{
+ while (!m_dynObj.empty())
+ m_dynObj.front()->Remove();
}
GameObject* Unit::GetGameObject(uint32 spellId) const
diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h
index 97599a4634c..debdc830a13 100755
--- a/src/server/game/Entities/Unit/Unit.h
+++ b/src/server/game/Entities/Unit/Unit.h
@@ -1863,10 +1863,11 @@ class Unit : public WorldObject
void setTransForm(uint32 spellid) { m_transform = spellid;}
uint32 getTransForm() const { return m_transform;}
+ // DynamicObject management
+ void _RegisterDynObject(DynamicObject* dynObj);
+ void _UnregisterDynObject(DynamicObject* dynObj);
DynamicObject* GetDynObject(uint32 spellId);
- void AddDynObject(DynamicObject* dynObj);
- void RemoveDynObject(uint32 spellid);
- void RemoveDynObjectWithGUID(uint64 guid) { m_dynObjGUIDs.remove(guid); }
+ void RemoveDynObject(uint32 spellId);
void RemoveAllDynObjects();
GameObject* GetGameObject(uint32 spellId) const;
@@ -2078,8 +2079,8 @@ class Unit : public WorldObject
int32 m_procDeep;
- typedef std::list<uint64> DynObjectGUIDs;
- DynObjectGUIDs m_dynObjGUIDs;
+ typedef std::list<DynamicObject*> DynObjectList;
+ DynObjectList m_dynObj;
typedef std::list<GameObject*> GameObjectList;
GameObjectList m_gameObj;
diff --git a/src/server/game/Grids/ObjectGridLoader.cpp b/src/server/game/Grids/ObjectGridLoader.cpp
index 09d623c84d0..89bf39b1fe5 100755
--- a/src/server/game/Grids/ObjectGridLoader.cpp
+++ b/src/server/game/Grids/ObjectGridLoader.cpp
@@ -280,13 +280,13 @@ ObjectGridStoper::Visit(CreatureMapType &m)
// stop any fights at grid de-activation and remove dynobjects created at cast by creatures
for (CreatureMapType::iterator iter=m.begin(); iter != m.end(); ++iter)
{
+ iter->getSource()->RemoveAllDynObjects();
if (iter->getSource()->isInCombat())
{
iter->getSource()->CombatStop();
iter->getSource()->DeleteThreatList();
- iter->getSource()->AI()->EnterEvadeMode(); // Calls RemoveAllAuras
+ iter->getSource()->AI()->EnterEvadeMode();
}
- iter->getSource()->RemoveAllDynObjects(); // Calls RemoveFromWorld, needs to be after RemoveAllAuras or we invalidate the Owner pointer of the aura
}
}
diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp
index 3e8aea4fe63..86268cfbb32 100755
--- a/src/server/game/Spells/SpellEffects.cpp
+++ b/src/server/game/Spells/SpellEffects.cpp
@@ -2556,17 +2556,15 @@ void Spell::EffectPersistentAA(SpellEffIndex effIndex)
delete dynObj;
return;
}
- caster->AddDynObject(dynObj);
dynObj->GetMap()->Add(dynObj);
if (Aura * aura = Aura::TryCreate(m_spellInfo, dynObj, caster, &m_spellValue->EffectBasePoints[0]))
+ {
m_spellAura = aura;
+ m_spellAura->_RegisterForTargets();
+ }
else
- {
- ASSERT(false);
return;
- }
- m_spellAura->_RegisterForTargets();
}
ASSERT(m_spellAura->GetDynobjOwner());
m_spellAura->_ApplyEffectForTargets(effIndex);
@@ -3387,14 +3385,10 @@ void Spell::EffectAddFarsight(SpellEffIndex effIndex)
}
dynObj->SetDuration(duration);
dynObj->SetUInt32Value(DYNAMICOBJECT_BYTES, 0x80000002);
- m_caster->AddDynObject(dynObj);
dynObj->setActive(true); //must before add to map to be put in world container
dynObj->GetMap()->Add(dynObj); //grid will also be loaded
-
- // Need to update visibility of object for client to accept farsight guid
- m_caster->ToPlayer()->SetViewpoint(dynObj, true);
- //m_caster->ToPlayer()->UpdateVisibilityOf(dynObj);
+ dynObj->SetCasterViewpoint();
}
void Spell::EffectUntrainTalents(SpellEffIndex /*effIndex*/)