[8023] Move guardian list at Unit level and unsummon guardians at owner-creature death/unload.

This expected to fix well known crash at intances unload with creature with summoned guardians.
Note: this "fix" special case but not original source of problem in general.
This commit is contained in:
VladimirMangos 2009-06-15 23:43:15 +04:00
parent 02a71edb86
commit 309ac7ead0
6 changed files with 56 additions and 46 deletions

View file

@ -7383,13 +7383,10 @@ void Unit::CombatStopWithPets(bool includingCast)
pet->CombatStop(includingCast);
if(Unit* charm = GetCharm())
charm->CombatStop(includingCast);
if(GetTypeId()==TYPEID_PLAYER)
{
GuardianPetList const& guardians = ((Player*)this)->GetGuardians();
for(GuardianPetList::const_iterator itr = guardians.begin(); itr != guardians.end(); ++itr)
if(Unit* guardian = Unit::GetUnit(*this,*itr))
guardian->CombatStop(includingCast);
}
for(GuardianPetList::const_iterator itr = m_guardianPets.begin(); itr != m_guardianPets.end(); ++itr)
if(Unit* guardian = Unit::GetUnit(*this,*itr))
guardian->CombatStop(includingCast);
}
bool Unit::isAttackingPlayer() const
@ -7563,6 +7560,44 @@ void Unit::SetCharm(Unit* pet)
((Player*)this)->m_mover = pet ? pet : this;
}
void Unit::AddGuardian( Pet* pet )
{
m_guardianPets.insert(pet->GetGUID());
}
void Unit::RemoveGuardian( Pet* pet )
{
m_guardianPets.erase(pet->GetGUID());
}
void Unit::RemoveGuardians()
{
while(!m_guardianPets.empty())
{
uint64 guid = *m_guardianPets.begin();
if(Pet* pet = ObjectAccessor::GetPet(guid))
pet->Remove(PET_SAVE_AS_DELETED);
m_guardianPets.erase(guid);
}
}
bool Unit::HasGuardianWithEntry(uint32 entry)
{
// pet guid middle part is entry (and creature also)
// and in guardian list must be guardians with same entry _always_
for(GuardianPetList::const_iterator itr = m_guardianPets.begin(); itr != m_guardianPets.end(); ++itr)
{
if(Pet* pet = ObjectAccessor::GetPet(*itr))
if (pet->GetEntry() == entry)
return true;
}
return false;
}
void Unit::UnsummonAllTotems()
{
for (int8 i = 0; i < MAX_TOTEM; ++i)
@ -9461,6 +9496,7 @@ void Unit::setDeathState(DeathState s)
if (s == JUST_DIED)
{
RemoveAllAurasOnDeath();
RemoveGuardians();
UnsummonAllTotems();
ModifyAuraState(AURA_STATE_HEALTHLESS_20_PERCENT, false);
@ -10322,6 +10358,7 @@ void Unit::RemoveFromWorld()
if(IsInWorld())
{
RemoveNotOwnSingleTargetAuras();
RemoveGuardians();
}
Object::RemoveFromWorld();