mirror of
https://github.com/mangosfour/server.git
synced 2025-12-13 22:37:03 +00:00
[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:
parent
02a71edb86
commit
309ac7ead0
6 changed files with 56 additions and 46 deletions
|
|
@ -1372,7 +1372,6 @@ void Player::setDeathState(DeathState s)
|
||||||
|
|
||||||
// remove uncontrolled pets
|
// remove uncontrolled pets
|
||||||
RemoveMiniPet();
|
RemoveMiniPet();
|
||||||
RemoveGuardians();
|
|
||||||
|
|
||||||
// save value before aura remove in Unit::setDeathState
|
// save value before aura remove in Unit::setDeathState
|
||||||
ressSpellId = GetUInt32Value(PLAYER_SELF_RES_SPELL);
|
ressSpellId = GetUInt32Value(PLAYER_SELF_RES_SPELL);
|
||||||
|
|
@ -1764,7 +1763,6 @@ void Player::RemoveFromWorld()
|
||||||
Uncharm();
|
Uncharm();
|
||||||
UnsummonAllTotems();
|
UnsummonAllTotems();
|
||||||
RemoveMiniPet();
|
RemoveMiniPet();
|
||||||
RemoveGuardians();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for(int i = PLAYER_SLOT_START; i < PLAYER_SLOT_END; ++i)
|
for(int i = PLAYER_SLOT_START; i < PLAYER_SLOT_END; ++i)
|
||||||
|
|
@ -16213,7 +16211,7 @@ void Player::RemovePet(Pet* pet, PetSaveMode mode, bool returnreagent)
|
||||||
m_miniPet = 0;
|
m_miniPet = 0;
|
||||||
break;
|
break;
|
||||||
case GUARDIAN_PET:
|
case GUARDIAN_PET:
|
||||||
m_guardianPets.erase(pet->GetGUID());
|
RemoveGuardian(pet);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if(GetPetGUID() == pet->GetGUID())
|
if(GetPetGUID() == pet->GetGUID())
|
||||||
|
|
@ -16270,32 +16268,6 @@ Pet* Player::GetMiniPet()
|
||||||
return ObjectAccessor::GetPet(m_miniPet);
|
return ObjectAccessor::GetPet(m_miniPet);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Player::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 Player::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 Player::Uncharm()
|
void Player::Uncharm()
|
||||||
{
|
{
|
||||||
Unit* charm = GetCharm();
|
Unit* charm = GetCharm();
|
||||||
|
|
|
||||||
|
|
@ -273,8 +273,6 @@ struct Runes
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::set<uint64> GuardianPetList;
|
|
||||||
|
|
||||||
struct EnchantDuration
|
struct EnchantDuration
|
||||||
{
|
{
|
||||||
EnchantDuration() : item(NULL), slot(MAX_ENCHANTMENT_SLOT), leftduration(0) {};
|
EnchantDuration() : item(NULL), slot(MAX_ENCHANTMENT_SLOT), leftduration(0) {};
|
||||||
|
|
@ -991,10 +989,6 @@ class MANGOS_DLL_SPEC Player : public Unit
|
||||||
void RemoveMiniPet();
|
void RemoveMiniPet();
|
||||||
Pet* GetMiniPet();
|
Pet* GetMiniPet();
|
||||||
void SetMiniPet(Pet* pet) { m_miniPet = pet->GetGUID(); }
|
void SetMiniPet(Pet* pet) { m_miniPet = pet->GetGUID(); }
|
||||||
void RemoveGuardians();
|
|
||||||
bool HasGuardianWithEntry(uint32 entry);
|
|
||||||
void AddGuardian(Pet* pet) { m_guardianPets.insert(pet->GetGUID()); }
|
|
||||||
GuardianPetList const& GetGuardians() const { return m_guardianPets; }
|
|
||||||
void Uncharm();
|
void Uncharm();
|
||||||
uint32 GetPhaseMaskForSpawn() const; // used for proper set phase for DB at GM-mode creature/GO spawn
|
uint32 GetPhaseMaskForSpawn() const; // used for proper set phase for DB at GM-mode creature/GO spawn
|
||||||
|
|
||||||
|
|
@ -2311,7 +2305,6 @@ class MANGOS_DLL_SPEC Player : public Unit
|
||||||
uint64 m_auraUpdateMask;
|
uint64 m_auraUpdateMask;
|
||||||
|
|
||||||
uint64 m_miniPet;
|
uint64 m_miniPet;
|
||||||
GuardianPetList m_guardianPets;
|
|
||||||
|
|
||||||
// Player summoning
|
// Player summoning
|
||||||
time_t m_summon_expire;
|
time_t m_summon_expire;
|
||||||
|
|
|
||||||
|
|
@ -3711,8 +3711,7 @@ void Spell::EffectSummonGuardian(uint32 i)
|
||||||
|
|
||||||
spawnCreature->AIM_Initialize();
|
spawnCreature->AIM_Initialize();
|
||||||
|
|
||||||
if(m_caster->GetTypeId()==TYPEID_PLAYER)
|
m_caster->AddGuardian(spawnCreature);
|
||||||
((Player*)m_caster)->AddGuardian(spawnCreature);
|
|
||||||
|
|
||||||
map->Add((Creature*)spawnCreature);
|
map->Add((Creature*)spawnCreature);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7383,14 +7383,11 @@ void Unit::CombatStopWithPets(bool includingCast)
|
||||||
pet->CombatStop(includingCast);
|
pet->CombatStop(includingCast);
|
||||||
if(Unit* charm = GetCharm())
|
if(Unit* charm = GetCharm())
|
||||||
charm->CombatStop(includingCast);
|
charm->CombatStop(includingCast);
|
||||||
if(GetTypeId()==TYPEID_PLAYER)
|
|
||||||
{
|
for(GuardianPetList::const_iterator itr = m_guardianPets.begin(); itr != m_guardianPets.end(); ++itr)
|
||||||
GuardianPetList const& guardians = ((Player*)this)->GetGuardians();
|
|
||||||
for(GuardianPetList::const_iterator itr = guardians.begin(); itr != guardians.end(); ++itr)
|
|
||||||
if(Unit* guardian = Unit::GetUnit(*this,*itr))
|
if(Unit* guardian = Unit::GetUnit(*this,*itr))
|
||||||
guardian->CombatStop(includingCast);
|
guardian->CombatStop(includingCast);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
bool Unit::isAttackingPlayer() const
|
bool Unit::isAttackingPlayer() const
|
||||||
{
|
{
|
||||||
|
|
@ -7563,6 +7560,44 @@ void Unit::SetCharm(Unit* pet)
|
||||||
((Player*)this)->m_mover = pet ? pet : this;
|
((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()
|
void Unit::UnsummonAllTotems()
|
||||||
{
|
{
|
||||||
for (int8 i = 0; i < MAX_TOTEM; ++i)
|
for (int8 i = 0; i < MAX_TOTEM; ++i)
|
||||||
|
|
@ -9461,6 +9496,7 @@ void Unit::setDeathState(DeathState s)
|
||||||
if (s == JUST_DIED)
|
if (s == JUST_DIED)
|
||||||
{
|
{
|
||||||
RemoveAllAurasOnDeath();
|
RemoveAllAurasOnDeath();
|
||||||
|
RemoveGuardians();
|
||||||
UnsummonAllTotems();
|
UnsummonAllTotems();
|
||||||
|
|
||||||
ModifyAuraState(AURA_STATE_HEALTHLESS_20_PERCENT, false);
|
ModifyAuraState(AURA_STATE_HEALTHLESS_20_PERCENT, false);
|
||||||
|
|
@ -10322,6 +10358,7 @@ void Unit::RemoveFromWorld()
|
||||||
if(IsInWorld())
|
if(IsInWorld())
|
||||||
{
|
{
|
||||||
RemoveNotOwnSingleTargetAuras();
|
RemoveNotOwnSingleTargetAuras();
|
||||||
|
RemoveGuardians();
|
||||||
}
|
}
|
||||||
|
|
||||||
Object::RemoveFromWorld();
|
Object::RemoveFromWorld();
|
||||||
|
|
|
||||||
|
|
@ -859,6 +859,8 @@ enum ReactiveType
|
||||||
#define MAX_REACTIVE 3
|
#define MAX_REACTIVE 3
|
||||||
#define MAX_TOTEM 4
|
#define MAX_TOTEM 4
|
||||||
|
|
||||||
|
typedef std::set<uint64> GuardianPetList;
|
||||||
|
|
||||||
// delay time next attack to prevent client attack animation problems
|
// delay time next attack to prevent client attack animation problems
|
||||||
#define ATTACK_DISPLAY_DELAY 200
|
#define ATTACK_DISPLAY_DELAY 200
|
||||||
|
|
||||||
|
|
@ -1191,6 +1193,11 @@ class MANGOS_DLL_SPEC Unit : public WorldObject
|
||||||
void SetPet(Pet* pet);
|
void SetPet(Pet* pet);
|
||||||
void SetCharm(Unit* pet);
|
void SetCharm(Unit* pet);
|
||||||
|
|
||||||
|
void AddGuardian(Pet* pet);
|
||||||
|
void RemoveGuardian(Pet* pet);
|
||||||
|
void RemoveGuardians();
|
||||||
|
bool HasGuardianWithEntry(uint32 entry);
|
||||||
|
|
||||||
bool isCharmed() const { return GetCharmerGUID() != 0; }
|
bool isCharmed() const { return GetCharmerGUID() != 0; }
|
||||||
|
|
||||||
CharmInfo* GetCharmInfo() { return m_charmInfo; }
|
CharmInfo* GetCharmInfo() { return m_charmInfo; }
|
||||||
|
|
@ -1581,5 +1588,7 @@ class MANGOS_DLL_SPEC Unit : public WorldObject
|
||||||
FollowerRefManager m_FollowingRefManager;
|
FollowerRefManager m_FollowingRefManager;
|
||||||
|
|
||||||
ComboPointHolderSet m_ComboPointHolders;
|
ComboPointHolderSet m_ComboPointHolders;
|
||||||
|
|
||||||
|
GuardianPetList m_guardianPets;
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
#ifndef __REVISION_NR_H__
|
#ifndef __REVISION_NR_H__
|
||||||
#define __REVISION_NR_H__
|
#define __REVISION_NR_H__
|
||||||
#define REVISION_NR "8022"
|
#define REVISION_NR "8023"
|
||||||
#endif // __REVISION_NR_H__
|
#endif // __REVISION_NR_H__
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue