diff options
Diffstat (limited to 'src')
| -rwxr-xr-x | src/server/game/Entities/DynamicObject/DynamicObject.cpp | 128 | ||||
| -rwxr-xr-x | src/server/game/Entities/DynamicObject/DynamicObject.h | 14 | ||||
| -rwxr-xr-x | src/server/game/Entities/Unit/Unit.cpp | 63 | ||||
| -rwxr-xr-x | src/server/game/Entities/Unit/Unit.h | 11 | ||||
| -rwxr-xr-x | src/server/game/Grids/ObjectGridLoader.cpp | 4 | ||||
| -rwxr-xr-x | src/server/game/Spells/SpellEffects.cpp | 14 |
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*/) |
