diff --git a/src/game/Pet.cpp b/src/game/Pet.cpp index 994d7ae83..c8fa9cb0b 100644 --- a/src/game/Pet.cpp +++ b/src/game/Pet.cpp @@ -354,38 +354,32 @@ void Pet::SavePetToDB(PetSaveMode mode) if (!pOwner) return; - // not save pet as current if another pet temporary unsummoned - if (mode == PET_SAVE_AS_CURRENT && pOwner->GetTemporaryUnsummonedPetNumber() && - pOwner->GetTemporaryUnsummonedPetNumber() != m_charmInfo->GetPetNumber()) - { - // pet will lost anyway at restore temporary unsummoned - if(getPetType()==HUNTER_PET) - return; - - // for warlock case - mode = PET_SAVE_NOT_IN_SLOT; - } - - uint32 curhealth = GetHealth(); - uint32 curmana = GetPower(POWER_MANA); - - // stable and not in slot saves - if(mode > PET_SAVE_AS_CURRENT) - { - RemoveAllAuras(); - - //only alive hunter pets get auras saved, the others don't - if(!(getPetType() == HUNTER_PET && isAlive())) - m_Auras.clear(); - } - - _SaveSpells(); - _SaveSpellCooldowns(); - _SaveAuras(); - // current/stable/not_in_slot - if(mode >= PET_SAVE_AS_CURRENT) + if (mode >= PET_SAVE_AS_CURRENT) { + // not save pet as current if another pet temporary unsummoned + if (mode == PET_SAVE_AS_CURRENT && pOwner->GetTemporaryUnsummonedPetNumber() && + pOwner->GetTemporaryUnsummonedPetNumber() != m_charmInfo->GetPetNumber()) + { + // pet will lost anyway at restore temporary unsummoned + if(getPetType()==HUNTER_PET) + return; + + // for warlock case + mode = PET_SAVE_NOT_IN_SLOT; + } + + uint32 curhealth = GetHealth(); + uint32 curmana = GetPower(POWER_MANA); + + // stable and not in slot saves + if (mode != PET_SAVE_AS_CURRENT) + RemoveAllAuras(); + + _SaveSpells(); + _SaveSpellCooldowns(); + _SaveAuras(); + uint32 owner = GUID_LOPART(GetOwnerGUID()); std::string name = m_name; CharacterDatabase.escape_string(name); @@ -440,7 +434,7 @@ void Pet::SavePetToDB(PetSaveMode mode) // delete else { - RemoveAllAuras(); + RemoveAllAuras(AURA_REMOVE_BY_DELETE); DeleteFromDB(m_charmInfo->GetPetNumber()); } } @@ -1144,9 +1138,7 @@ void Pet::_SaveSpells() void Pet::_LoadAuras(uint32 timediff) { - m_Auras.clear(); - for (int i = 0; i < TOTAL_AURAS; ++i) - m_modAuras[i].clear(); + RemoveAllAuras(); QueryResult *result = CharacterDatabase.PQuery("SELECT caster_guid,spell,effect_index,stackcount,amount,maxduration,remaintime,remaincharges FROM pet_aura WHERE guid = '%u'",m_charmInfo->GetPetNumber()); diff --git a/src/game/Player.cpp b/src/game/Player.cpp index c8e9ca2e5..09d61f4f2 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -14783,9 +14783,7 @@ void Player::_LoadActions(QueryResult *result) void Player::_LoadAuras(QueryResult *result, uint32 timediff) { - m_Auras.clear(); - for (int i = 0; i < TOTAL_AURAS; ++i) - m_modAuras[i].clear(); + RemoveAllAuras(); //QueryResult *result = CharacterDatabase.PQuery("SELECT caster_guid,spell,effect_index,stackcount,amount,maxduration,remaintime,remaincharges FROM character_aura WHERE guid = '%u'",GetGUIDLow()); diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp index 582946a67..3bf098f2d 100644 --- a/src/game/SpellAuras.cpp +++ b/src/game/SpellAuras.cpp @@ -1141,85 +1141,89 @@ bool Aura::_RemoveAura() SetAura(true); SetAuraFlags(AFLAG_NONE); SetAuraLevel(0); - SendAuraUpdate(true); - // update for out of range group members - m_target->UpdateAuraForGroup(slot); - - //***************************************************** - // Update target aura state flag (at last aura remove) - //***************************************************** - // Enrage aura state - if(m_spellProto->Dispel == DISPEL_ENRAGE) - m_target->ModifyAuraState(AURA_STATE_ENRAGE, false); - - uint32 removeState = 0; - uint64 removeFamilyFlag = m_spellProto->SpellFamilyFlags; - uint32 removeFamilyFlag2 = m_spellProto->SpellFamilyFlags2; - switch(m_spellProto->SpellFamilyName) + if (m_removeMode != AURA_REMOVE_BY_DELETE) { - case SPELLFAMILY_PALADIN: - if (IsSealSpell(m_spellProto)) - removeState = AURA_STATE_JUDGEMENT; // Update Seals information - break; - case SPELLFAMILY_WARLOCK: - // Conflagrate aura state on Immolate and Shadowflame, - if ((m_spellProto->SpellFamilyFlags & UI64LIT(0x0000000000000004)) || - (m_spellProto->SpellFamilyFlags2 & 0x00000002)) - { - removeFamilyFlag = UI64LIT(0x0000000000000004); - removeFamilyFlag2 = 0x00000002; - removeState = AURA_STATE_CONFLAGRATE; - } - break; - case SPELLFAMILY_DRUID: - if(m_spellProto->SpellFamilyFlags & UI64LIT(0x0000000000000400)) - removeState = AURA_STATE_FAERIE_FIRE; // Faerie Fire (druid versions) - else if(m_spellProto->SpellFamilyFlags & UI64LIT(0x50)) - { - removeFamilyFlag = 0x50; - removeState = AURA_STATE_SWIFTMEND; // Swiftmend aura state - } - break; - case SPELLFAMILY_WARRIOR: - if(m_spellProto->SpellFamilyFlags & UI64LIT(0x0004000000000000)) - removeState = AURA_STATE_WARRIOR_VICTORY_RUSH; // Victorious - break; - case SPELLFAMILY_ROGUE: - if(m_spellProto->SpellFamilyFlags & UI64LIT(0x10000)) - removeState = AURA_STATE_DEADLY_POISON; // Deadly poison aura state - break; - case SPELLFAMILY_HUNTER: - if(m_spellProto->SpellFamilyFlags & UI64LIT(0x1000000000000000)) - removeState = AURA_STATE_FAERIE_FIRE; // Sting (hunter versions) + SendAuraUpdate(true); - } - // Remove state (but need check other auras for it) - if (removeState) - { - bool found = false; - Unit::AuraMap& Auras = m_target->GetAuras(); - for(Unit::AuraMap::iterator i = Auras.begin(); i != Auras.end(); ++i) + // update for out of range group members + m_target->UpdateAuraForGroup(slot); + + //***************************************************** + // Update target aura state flag (at last aura remove) + //***************************************************** + // Enrage aura state + if(m_spellProto->Dispel == DISPEL_ENRAGE) + m_target->ModifyAuraState(AURA_STATE_ENRAGE, false); + + uint32 removeState = 0; + uint64 removeFamilyFlag = m_spellProto->SpellFamilyFlags; + uint32 removeFamilyFlag2 = m_spellProto->SpellFamilyFlags2; + switch(m_spellProto->SpellFamilyName) { - SpellEntry const *auraSpellInfo = (*i).second->GetSpellProto(); - if(auraSpellInfo->SpellFamilyName == m_spellProto->SpellFamilyName && - (auraSpellInfo->SpellFamilyFlags & removeFamilyFlag || auraSpellInfo->SpellFamilyFlags2 & removeFamilyFlag2)) - { - found = true; + case SPELLFAMILY_PALADIN: + if (IsSealSpell(m_spellProto)) + removeState = AURA_STATE_JUDGEMENT; // Update Seals information break; - } + case SPELLFAMILY_WARLOCK: + // Conflagrate aura state on Immolate and Shadowflame, + if ((m_spellProto->SpellFamilyFlags & UI64LIT(0x0000000000000004)) || + (m_spellProto->SpellFamilyFlags2 & 0x00000002)) + { + removeFamilyFlag = UI64LIT(0x0000000000000004); + removeFamilyFlag2 = 0x00000002; + removeState = AURA_STATE_CONFLAGRATE; + } + break; + case SPELLFAMILY_DRUID: + if(m_spellProto->SpellFamilyFlags & UI64LIT(0x0000000000000400)) + removeState = AURA_STATE_FAERIE_FIRE; // Faerie Fire (druid versions) + else if(m_spellProto->SpellFamilyFlags & UI64LIT(0x50)) + { + removeFamilyFlag = 0x50; + removeState = AURA_STATE_SWIFTMEND; // Swiftmend aura state + } + break; + case SPELLFAMILY_WARRIOR: + if(m_spellProto->SpellFamilyFlags & UI64LIT(0x0004000000000000)) + removeState = AURA_STATE_WARRIOR_VICTORY_RUSH; // Victorious + break; + case SPELLFAMILY_ROGUE: + if(m_spellProto->SpellFamilyFlags & UI64LIT(0x10000)) + removeState = AURA_STATE_DEADLY_POISON; // Deadly poison aura state + break; + case SPELLFAMILY_HUNTER: + if(m_spellProto->SpellFamilyFlags & UI64LIT(0x1000000000000000)) + removeState = AURA_STATE_FAERIE_FIRE; // Sting (hunter versions) } - // this has been last aura - if(!found) - m_target->ModifyAuraState(AuraState(removeState), false); - } - // reset cooldown state for spells - if(caster && caster->GetTypeId() == TYPEID_PLAYER) - { - if ( GetSpellProto()->Attributes & SPELL_ATTR_DISABLED_WHILE_ACTIVE ) - // note: item based cooldowns and cooldown spell mods with charges ignored (unknown existed cases) - ((Player*)caster)->SendCooldownEvent(GetSpellProto()); + // Remove state (but need check other auras for it) + if (removeState) + { + bool found = false; + Unit::AuraMap& Auras = m_target->GetAuras(); + for(Unit::AuraMap::iterator i = Auras.begin(); i != Auras.end(); ++i) + { + SpellEntry const *auraSpellInfo = (*i).second->GetSpellProto(); + if(auraSpellInfo->SpellFamilyName == m_spellProto->SpellFamilyName && + (auraSpellInfo->SpellFamilyFlags & removeFamilyFlag || auraSpellInfo->SpellFamilyFlags2 & removeFamilyFlag2)) + { + found = true; + break; + } + } + // this has been last aura + if(!found) + m_target->ModifyAuraState(AuraState(removeState), false); + } + + // reset cooldown state for spells + if(caster && caster->GetTypeId() == TYPEID_PLAYER) + { + if ( GetSpellProto()->Attributes & SPELL_ATTR_DISABLED_WHILE_ACTIVE ) + // note: item based cooldowns and cooldown spell mods with charges ignored (unknown existed cases) + ((Player*)caster)->SendCooldownEvent(GetSpellProto()); + } } return true; diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index a282c96d1..a7d6a56f9 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -4021,7 +4021,7 @@ void Unit::RemoveNotOwnSingleTargetAuras(uint32 newPhase) } -void Unit::RemoveAura(Aura* aura) +void Unit::RemoveAura(Aura* aura, AuraRemoveMode mode /*= AURA_REMOVE_BY_DEFAULT*/) { AuraMap::iterator i = m_Auras.lower_bound(spellEffectPair(aura->GetId(), aura->GetEffIndex())); AuraMap::iterator upperBound = m_Auras.upper_bound(spellEffectPair(aura->GetId(), aura->GetEffIndex())); @@ -4029,7 +4029,7 @@ void Unit::RemoveAura(Aura* aura) { if (i->second == aura) { - RemoveAura(i); + RemoveAura(i,mode); return; } } @@ -4079,12 +4079,13 @@ void Unit::RemoveAura(AuraMap::iterator &i, AuraRemoveMode mode) } sLog.outDebug("Aura %u now is remove mode %d",Aur->GetModifier()->m_auraname, mode); - Aur->ApplyModifier(false,true); + if (mode != AURA_REMOVE_BY_DELETE) // not unapply if target will deleted + Aur->ApplyModifier(false,true); - if(Aur->_RemoveAura()) + if (Aur->_RemoveAura()) { // last aura in stack removed - if(IsSpellLastAuraEffect(Aur->GetSpellProto(),Aur->GetEffIndex())) + if (mode != AURA_REMOVE_BY_DELETE && IsSpellLastAuraEffect(Aur->GetSpellProto(),Aur->GetEffIndex())) Aur->HandleSpellSpecificBoosts(false); } @@ -4108,12 +4109,12 @@ void Unit::RemoveAura(AuraMap::iterator &i, AuraRemoveMode mode) i = m_Auras.begin(); } -void Unit::RemoveAllAuras() +void Unit::RemoveAllAuras(AuraRemoveMode mode /*= AURA_REMOVE_BY_DEFAULT*/) { while (!m_Auras.empty()) { AuraMap::iterator iter = m_Auras.begin(); - RemoveAura(iter); + RemoveAura(iter,mode); } } @@ -11105,7 +11106,7 @@ void Unit::CleanupsBeforeDelete() ClearComboPointHolders(); DeleteThreatList(); getHostileRefManager().setOnlineOfflineState(false); - RemoveAllAuras(); + RemoveAllAuras(AURA_REMOVE_BY_DELETE); RemoveAllGameObjects(); RemoveAllDynObjects(); GetMotionMaster()->Clear(false); // remove different non-standard movement generators. diff --git a/src/game/Unit.h b/src/game/Unit.h index 95a062647..9dcb55c7a 100644 --- a/src/game/Unit.h +++ b/src/game/Unit.h @@ -323,7 +323,8 @@ enum AuraRemoveMode AURA_REMOVE_BY_STACK, // at replace by similar aura AURA_REMOVE_BY_CANCEL, AURA_REMOVE_BY_DISPEL, - AURA_REMOVE_BY_DEATH + AURA_REMOVE_BY_DEATH, + AURA_REMOVE_BY_DELETE, // use for speedup and prevent unexpected effects at player logout/pet unsummon (must be used _only_ after save), delete. }; enum UnitMods @@ -1206,7 +1207,7 @@ class MANGOS_DLL_SPEC Unit : public WorldObject bool AddAura(Aura *aur); - void RemoveAura(Aura* aura); + void RemoveAura(Aura* aura, AuraRemoveMode mode = AURA_REMOVE_BY_DEFAULT); void RemoveAura(AuraMap::iterator &i, AuraRemoveMode mode = AURA_REMOVE_BY_DEFAULT); void RemoveAura(uint32 spellId, uint32 effindex, Aura* except = NULL); void RemoveSingleSpellAurasFromStack(uint32 spellId); @@ -1228,7 +1229,7 @@ class MANGOS_DLL_SPEC Unit : public WorldObject void RemoveAurasWithInterruptFlags(uint32 flags); void RemoveAurasWithDispelType( DispelType type ); - void RemoveAllAuras(); + void RemoveAllAuras(AuraRemoveMode mode = AURA_REMOVE_BY_DEFAULT); void RemoveArenaAuras(bool onleave = false); void RemoveAllAurasOnDeath(); void DelayAura(uint32 spellId, uint32 effindex, int32 delaytime); diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 9023c7760..3530d62c3 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 "8741" + #define REVISION_NR "8742" #endif // __REVISION_NR_H__