From d08edbd93ce3958ca45a03f0fd68c25ccccab07e Mon Sep 17 00:00:00 2001 From: Schmoozerd Date: Tue, 22 Mar 2011 22:14:20 +0100 Subject: [PATCH] [11980] Improve support for wild summoned GOs * Support GetGameObject for wild summoned GOs * Proper delete WildSummoned GOs after they are used --- src/game/GameObject.cpp | 7 ++++--- src/game/SpellEffects.cpp | 3 +++ src/game/Unit.cpp | 40 ++++++++++++++++++++++++++++++++------- src/game/Unit.h | 3 +++ src/shared/revision_nr.h | 2 +- 5 files changed, 44 insertions(+), 11 deletions(-) diff --git a/src/game/GameObject.cpp b/src/game/GameObject.cpp index 9401a60e2..fc29bf47f 100644 --- a/src/game/GameObject.cpp +++ b/src/game/GameObject.cpp @@ -401,10 +401,11 @@ void GameObject::Update(uint32 update_diff, uint32 /*p_time*/) //any return here in case battleground traps } - if (GetOwnerGuid()) + if (!HasStaticDBSpawnData()) // Remove wild summoned after use { - if (Unit* owner = GetOwner()) - owner->RemoveGameObject(this, false); + if (GetOwnerGuid()) + if (Unit* owner = GetOwner()) + owner->RemoveGameObject(this, false); SetRespawnTime(0); Delete(); diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp index 547852c71..062380b9c 100644 --- a/src/game/SpellEffects.cpp +++ b/src/game/SpellEffects.cpp @@ -6249,6 +6249,9 @@ void Spell::EffectSummonObjectWild(SpellEffectIndex eff_idx) // Wild object not have owner and check clickable by players map->Add(pGameObj); + // Store the GO to the caster + m_caster->AddWildGameObject(pGameObj); + if(pGameObj->GetGoType() == GAMEOBJECT_TYPE_FLAGDROP && m_caster->GetTypeId() == TYPEID_PLAYER) { Player *pl = (Player*)m_caster; diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index 89e70849f..2e0a73c12 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -5013,6 +5013,10 @@ GameObject* Unit::GetGameObject(uint32 spellId) const if ((*i)->GetSpellId() == spellId) return *i; + WildGameObjectMap::const_iterator find = m_wildGameObjs.find(spellId); + if (find != m_wildGameObjs.end()) + return GetMap()->GetGameObject(find->second); // Can be NULL + return NULL; } @@ -5022,13 +5026,31 @@ void Unit::AddGameObject(GameObject* gameObj) m_gameObj.push_back(gameObj); gameObj->SetOwnerGuid(GetObjectGuid()); - if ( GetTypeId()==TYPEID_PLAYER && gameObj->GetSpellId() ) + if (GetTypeId() == TYPEID_PLAYER && gameObj->GetSpellId()) { SpellEntry const* createBySpell = sSpellStore.LookupEntry(gameObj->GetSpellId()); // Need disable spell use for owner if (createBySpell && createBySpell->HasAttribute(SPELL_ATTR_DISABLED_WHILE_ACTIVE)) // note: item based cooldowns and cooldown spell mods with charges ignored (unknown existing cases) - ((Player*)this)->AddSpellAndCategoryCooldowns(createBySpell,0,NULL,true); + ((Player*)this)->AddSpellAndCategoryCooldowns(createBySpell, 0, NULL, true); + } +} + +void Unit::AddWildGameObject(GameObject* gameObj) +{ + MANGOS_ASSERT(gameObj && gameObj->GetOwnerGuid().IsEmpty()); + m_wildGameObjs[gameObj->GetSpellId()] = gameObj->GetObjectGuid(); + + // As of 335 there are no wild-summon spells with SPELL_ATTR_DISABLED_WHILE_ACTIVE + + // Remove outdated wild summoned GOs + for (WildGameObjectMap::iterator itr = m_wildGameObjs.begin(); itr != m_wildGameObjs.end();) + { + GameObject* pGo = GetMap()->GetGameObject(itr->second); + if (pGo) + ++itr; + else + m_wildGameObjs.erase(itr++); } } @@ -5055,7 +5077,7 @@ void Unit::RemoveGameObject(GameObject* gameObj, bool del) m_gameObj.remove(gameObj); - if(del) + if (del) { gameObj->SetRespawnTime(0); gameObj->Delete(); @@ -5064,16 +5086,17 @@ void Unit::RemoveGameObject(GameObject* gameObj, bool del) void Unit::RemoveGameObject(uint32 spellid, bool del) { - if(m_gameObj.empty()) + if (m_gameObj.empty()) return; + GameObjectList::iterator i, next; for (i = m_gameObj.begin(); i != m_gameObj.end(); i = next) { next = i; - if(spellid == 0 || (*i)->GetSpellId() == spellid) + if (spellid == 0 || (*i)->GetSpellId() == spellid) { (*i)->SetOwnerGuid(ObjectGuid()); - if(del) + if (del) { (*i)->SetRespawnTime(0); (*i)->Delete(); @@ -5089,13 +5112,16 @@ void Unit::RemoveGameObject(uint32 spellid, bool del) void Unit::RemoveAllGameObjects() { // remove references to unit - for(GameObjectList::iterator i = m_gameObj.begin(); i != m_gameObj.end();) + for (GameObjectList::iterator i = m_gameObj.begin(); i != m_gameObj.end();) { (*i)->SetOwnerGuid(ObjectGuid()); (*i)->SetRespawnTime(0); (*i)->Delete(); i = m_gameObj.erase(i); } + + // wild summoned GOs - only remove references, do not remove GOs + m_wildGameObjs.clear(); } void Unit::SendSpellNonMeleeDamageLog(SpellNonMeleeDamage *log) diff --git a/src/game/Unit.h b/src/game/Unit.h index 113590dc3..1a7c42a75 100644 --- a/src/game/Unit.h +++ b/src/game/Unit.h @@ -1751,6 +1751,7 @@ class MANGOS_DLL_SPEC Unit : public WorldObject GameObject* GetGameObject(uint32 spellId) const; void AddGameObject(GameObject* gameObj); + void AddWildGameObject(GameObject* gameObj); void RemoveGameObject(GameObject* gameObj, bool del); void RemoveGameObject(uint32 spellid, bool del); void RemoveAllGameObjects(); @@ -1936,6 +1937,8 @@ class MANGOS_DLL_SPEC Unit : public WorldObject typedef std::list GameObjectList; GameObjectList m_gameObj; + typedef std::map WildGameObjectMap; + WildGameObjectMap m_wildGameObjs; bool m_isSorted; uint32 m_transform; diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 45950aed2..c3a676523 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "11979" + #define REVISION_NR "11980" #endif // __REVISION_NR_H__