[11980] Improve support for wild summoned GOs

* Support GetGameObject for wild summoned GOs
* Proper delete WildSummoned GOs after they are used
This commit is contained in:
Schmoozerd 2011-03-22 22:14:20 +01:00 committed by Schmoozerd
parent c17fdc3093
commit d08edbd93c
5 changed files with 44 additions and 11 deletions

View file

@ -401,10 +401,11 @@ void GameObject::Update(uint32 update_diff, uint32 /*p_time*/)
//any return here in case battleground traps //any return here in case battleground traps
} }
if (GetOwnerGuid()) if (!HasStaticDBSpawnData()) // Remove wild summoned after use
{ {
if (Unit* owner = GetOwner()) if (GetOwnerGuid())
owner->RemoveGameObject(this, false); if (Unit* owner = GetOwner())
owner->RemoveGameObject(this, false);
SetRespawnTime(0); SetRespawnTime(0);
Delete(); Delete();

View file

@ -6249,6 +6249,9 @@ void Spell::EffectSummonObjectWild(SpellEffectIndex eff_idx)
// Wild object not have owner and check clickable by players // Wild object not have owner and check clickable by players
map->Add(pGameObj); map->Add(pGameObj);
// Store the GO to the caster
m_caster->AddWildGameObject(pGameObj);
if(pGameObj->GetGoType() == GAMEOBJECT_TYPE_FLAGDROP && m_caster->GetTypeId() == TYPEID_PLAYER) if(pGameObj->GetGoType() == GAMEOBJECT_TYPE_FLAGDROP && m_caster->GetTypeId() == TYPEID_PLAYER)
{ {
Player *pl = (Player*)m_caster; Player *pl = (Player*)m_caster;

View file

@ -5013,6 +5013,10 @@ GameObject* Unit::GetGameObject(uint32 spellId) const
if ((*i)->GetSpellId() == spellId) if ((*i)->GetSpellId() == spellId)
return *i; 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; return NULL;
} }
@ -5022,13 +5026,31 @@ void Unit::AddGameObject(GameObject* gameObj)
m_gameObj.push_back(gameObj); m_gameObj.push_back(gameObj);
gameObj->SetOwnerGuid(GetObjectGuid()); gameObj->SetOwnerGuid(GetObjectGuid());
if ( GetTypeId()==TYPEID_PLAYER && gameObj->GetSpellId() ) if (GetTypeId() == TYPEID_PLAYER && gameObj->GetSpellId())
{ {
SpellEntry const* createBySpell = sSpellStore.LookupEntry(gameObj->GetSpellId()); SpellEntry const* createBySpell = sSpellStore.LookupEntry(gameObj->GetSpellId());
// Need disable spell use for owner // Need disable spell use for owner
if (createBySpell && createBySpell->HasAttribute(SPELL_ATTR_DISABLED_WHILE_ACTIVE)) if (createBySpell && createBySpell->HasAttribute(SPELL_ATTR_DISABLED_WHILE_ACTIVE))
// note: item based cooldowns and cooldown spell mods with charges ignored (unknown existing cases) // 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); m_gameObj.remove(gameObj);
if(del) if (del)
{ {
gameObj->SetRespawnTime(0); gameObj->SetRespawnTime(0);
gameObj->Delete(); gameObj->Delete();
@ -5064,16 +5086,17 @@ void Unit::RemoveGameObject(GameObject* gameObj, bool del)
void Unit::RemoveGameObject(uint32 spellid, bool del) void Unit::RemoveGameObject(uint32 spellid, bool del)
{ {
if(m_gameObj.empty()) if (m_gameObj.empty())
return; return;
GameObjectList::iterator i, next; GameObjectList::iterator i, next;
for (i = m_gameObj.begin(); i != m_gameObj.end(); i = next) for (i = m_gameObj.begin(); i != m_gameObj.end(); i = next)
{ {
next = i; next = i;
if(spellid == 0 || (*i)->GetSpellId() == spellid) if (spellid == 0 || (*i)->GetSpellId() == spellid)
{ {
(*i)->SetOwnerGuid(ObjectGuid()); (*i)->SetOwnerGuid(ObjectGuid());
if(del) if (del)
{ {
(*i)->SetRespawnTime(0); (*i)->SetRespawnTime(0);
(*i)->Delete(); (*i)->Delete();
@ -5089,13 +5112,16 @@ void Unit::RemoveGameObject(uint32 spellid, bool del)
void Unit::RemoveAllGameObjects() void Unit::RemoveAllGameObjects()
{ {
// remove references to unit // 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)->SetOwnerGuid(ObjectGuid());
(*i)->SetRespawnTime(0); (*i)->SetRespawnTime(0);
(*i)->Delete(); (*i)->Delete();
i = m_gameObj.erase(i); i = m_gameObj.erase(i);
} }
// wild summoned GOs - only remove references, do not remove GOs
m_wildGameObjs.clear();
} }
void Unit::SendSpellNonMeleeDamageLog(SpellNonMeleeDamage *log) void Unit::SendSpellNonMeleeDamageLog(SpellNonMeleeDamage *log)

View file

@ -1751,6 +1751,7 @@ class MANGOS_DLL_SPEC Unit : public WorldObject
GameObject* GetGameObject(uint32 spellId) const; GameObject* GetGameObject(uint32 spellId) const;
void AddGameObject(GameObject* gameObj); void AddGameObject(GameObject* gameObj);
void AddWildGameObject(GameObject* gameObj);
void RemoveGameObject(GameObject* gameObj, bool del); void RemoveGameObject(GameObject* gameObj, bool del);
void RemoveGameObject(uint32 spellid, bool del); void RemoveGameObject(uint32 spellid, bool del);
void RemoveAllGameObjects(); void RemoveAllGameObjects();
@ -1936,6 +1937,8 @@ class MANGOS_DLL_SPEC Unit : public WorldObject
typedef std::list<GameObject*> GameObjectList; typedef std::list<GameObject*> GameObjectList;
GameObjectList m_gameObj; GameObjectList m_gameObj;
typedef std::map<uint32, ObjectGuid> WildGameObjectMap;
WildGameObjectMap m_wildGameObjs;
bool m_isSorted; bool m_isSorted;
uint32 m_transform; uint32 m_transform;

View file

@ -1,4 +1,4 @@
#ifndef __REVISION_NR_H__ #ifndef __REVISION_NR_H__
#define __REVISION_NR_H__ #define __REVISION_NR_H__
#define REVISION_NR "11979" #define REVISION_NR "11980"
#endif // __REVISION_NR_H__ #endif // __REVISION_NR_H__