diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp index fe1f9b0f5..81a21485d 100644 --- a/src/game/SpellEffects.cpp +++ b/src/game/SpellEffects.cpp @@ -3599,8 +3599,9 @@ void Spell::EffectDispel(uint32 i) if (positive == unitTarget->IsFriendlyTo(m_caster)) continue; } - // Add aura to dispel list - dispel_list.push_back(aur); + // Add aura to dispel list (all stack cases) + for(int k = 0; k < aur->GetStackAmount(); ++k) + dispel_list.push_back(aur); } } // Ok if exist some buffs for dispel try dispel it @@ -3618,7 +3619,10 @@ void Spell::EffectDispel(uint32 i) for (int32 count=0; count < damage && list_size > 0; ++count) { // Random select buff for dispel - Aura *aur = dispel_list[urand(0, list_size-1)]; + std::vector::iterator dispel_itr = dispel_list.begin(); + std::advance(dispel_itr,urand(0, list_size-1)); + + Aura *aur = *dispel_itr; SpellEntry const* spellInfo = aur->GetSpellProto(); // Base dispel chance @@ -3632,21 +3636,12 @@ void Spell::EffectDispel(uint32 i) } // Try dispel if (roll_chance_i(miss_chance)) - fail_list.push_back(aur->GetId()); + fail_list.push_back(spellInfo->Id); else success_list.push_back(std::pair(aur->GetId(),aur->GetCasterGUID())); - // Remove buff from list for prevent doubles - for (std::vector::iterator j = dispel_list.begin(); j != dispel_list.end(); ) - { - Aura *dispeled = *j; - if (dispeled->GetId() == aur->GetId() && dispeled->GetCasterGUID() == aur->GetCasterGUID()) - { - j = dispel_list.erase(j); - --list_size; - } - else - ++j; - } + + // remove entry from dispel_list + dispel_list.erase(dispel_itr); } // Send success log and really remove auras if (!success_list.empty()) @@ -3655,7 +3650,7 @@ void Spell::EffectDispel(uint32 i) WorldPacket data(SMSG_SPELLDISPELLOG, 8+8+4+1+4+count*5); data.append(unitTarget->GetPackGUID()); // Victim GUID data.append(m_caster->GetPackGUID()); // Caster GUID - data << uint32(m_spellInfo->Id); // Dispell spell id + data << uint32(m_spellInfo->Id); // Dispel spell id data << uint8(0); // not used data << uint32(count); // count for (std::list >::iterator j = success_list.begin(); j != success_list.end(); ++j) @@ -3663,7 +3658,7 @@ void Spell::EffectDispel(uint32 i) SpellEntry const* spellInfo = sSpellStore.LookupEntry(j->first); data << uint32(spellInfo->Id); // Spell Id data << uint8(0); // 0 - dispeled !=0 cleansed - unitTarget->RemoveAurasDueToSpellByDispel(spellInfo->Id, j->second, m_caster); + unitTarget->RemoveSingleAuraDueToSpellByDispel(spellInfo->Id, j->second, m_caster); } m_caster->SendMessageToSet(&data, true); diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index 8e46ce525..32213b74f 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -3863,34 +3863,27 @@ void Unit::RemoveAurasByCasterSpell(uint32 spellId, uint32 effindex, uint64 cast } } -void Unit::RemoveAurasDueToSpellByDispel(uint32 spellId, uint64 casterGUID, Unit *dispeler) +void Unit::RemoveSingleAuraDueToSpellByDispel(uint32 spellId, uint64 casterGUID, Unit *dispeler) { - for (AuraMap::iterator iter = m_Auras.begin(); iter != m_Auras.end(); ) + SpellEntry const* spellEntry = sSpellStore.LookupEntry(spellId); + + // Custom dispel case + // Unstable Affliction + if(spellEntry->SpellFamilyName == SPELLFAMILY_WARLOCK && (spellEntry->SpellFamilyFlags & UI64LIT(0x010000000000))) { - Aura *aur = iter->second; - if (aur->GetId() == spellId && aur->GetCasterGUID() == casterGUID) + if (Aura* dotAura = GetAura(SPELL_AURA_PERIODIC_DAMAGE,SPELLFAMILY_WARLOCK,UI64LIT(0x010000000000),0x00000000,casterGUID)) { - // Custom dispel case - // Unstable Affliction - if (aur->GetSpellProto()->SpellFamilyName == SPELLFAMILY_WARLOCK && (aur->GetSpellProto()->SpellFamilyFlags & UI64LIT(0x010000000000))) - { - int32 damage = aur->GetModifier()->m_amount*9; - uint64 caster_guid = aur->GetCasterGUID(); + int32 damage = dotAura->GetModifier()->m_amount*9; - // Remove aura - RemoveAura(iter, AURA_REMOVE_BY_DISPEL); + // Remove spell auras from stack + RemoveSingleSpellAurasByCasterSpell(spellId, casterGUID, AURA_REMOVE_BY_DISPEL); - // backfire damage and silence - dispeler->CastCustomSpell(dispeler, 31117, &damage, NULL, NULL, true, NULL, NULL,caster_guid); - - iter = m_Auras.begin(); // iterator can be invalidate at cast if self-dispel - } - else - RemoveAura(iter, AURA_REMOVE_BY_DISPEL); + // backfire damage and silence + dispeler->CastCustomSpell(dispeler, 31117, &damage, NULL, NULL, true, NULL, NULL,casterGUID); } - else - ++iter; } + else + RemoveSingleSpellAurasByCasterSpell(spellId, casterGUID, AURA_REMOVE_BY_DISPEL); } void Unit::RemoveAurasDueToSpellBySteal(uint32 spellId, uint64 casterGUID, Unit *stealer) @@ -3960,21 +3953,46 @@ void Unit::RemoveAurasWithDispelType( DispelType type ) } } -void Unit::RemoveSingleAuraFromStack(uint32 spellId, uint32 effindex) +void Unit::RemoveSingleAuraFromStack(AuraMap::iterator &i, AuraRemoveMode mode) +{ + if (i->second->modStackAmount(-1)) + RemoveAura(i,mode); +} + + +void Unit::RemoveSingleAuraFromStack(uint32 spellId, uint32 effindex, AuraRemoveMode mode) { AuraMap::iterator iter = m_Auras.find(spellEffectPair(spellId, effindex)); if(iter != m_Auras.end()) + RemoveSingleAuraFromStack(iter,mode); +} + +void Unit::RemoveSingleSpellAurasFromStack(uint32 spellId, AuraRemoveMode mode) +{ + for (int i=0; i<3; ++i) + RemoveSingleAuraFromStack(spellId, i, mode); +} + +void Unit::RemoveSingleSpellAurasByCasterSpell(uint32 spellId, uint64 casterGUID, AuraRemoveMode mode) +{ + for (int i=0; i<3; ++i) + RemoveSingleAuraByCasterSpell(spellId, i, casterGUID, mode); +} + +void Unit::RemoveSingleAuraByCasterSpell(uint32 spellId, uint32 effindex, uint64 casterGUID, AuraRemoveMode mode) +{ + spellEffectPair spair = spellEffectPair(spellId, effindex); + for(AuraMap::iterator iter = m_Auras.lower_bound(spair); iter != m_Auras.upper_bound(spair); ++iter) { - if (iter->second->modStackAmount(-1)) - RemoveAura(iter); + Aura *aur = iter->second; + if (aur->GetId() == spellId && aur->GetCasterGUID() == casterGUID) + { + RemoveSingleAuraFromStack(iter,mode); + break; + } } } -void Unit::RemoveSingleSpellAurasFromStack(uint32 spellId) -{ - for (int i=0; i<3; ++i) - RemoveSingleAuraFromStack(spellId, i); -} void Unit::RemoveAurasDueToSpell(uint32 spellId, Aura* except) { diff --git a/src/game/Unit.h b/src/game/Unit.h index b4dade09f..cec3d61a8 100644 --- a/src/game/Unit.h +++ b/src/game/Unit.h @@ -1235,31 +1235,42 @@ class MANGOS_DLL_SPEC Unit : public WorldObject bool AddAura(Aura *aur); + // removing specific aura stack 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); - void RemoveSingleAuraFromStack(uint32 spellId, uint32 effindex); + + // removing specific aura stacks by diff reasons and selections void RemoveAurasDueToSpell(uint32 spellId, Aura* except = NULL); void RemoveAurasDueToItemSpell(Item* castItem,uint32 spellId); void RemoveAurasByCasterSpell(uint32 spellId, uint64 casterGUID); void RemoveAurasByCasterSpell(uint32 spellId, uint32 effindex, uint64 casterGUID); - void RemoveAurasDueToSpellByDispel(uint32 spellId, uint64 casterGUID, Unit *dispeler); void RemoveAurasDueToSpellBySteal(uint32 spellId, uint64 casterGUID, Unit *stealer); void RemoveAurasDueToSpellByCancel(uint32 spellId); void RemoveAurasAtChanneledTarget(SpellEntry const* spellInfo); + + // removing unknown aura stacks by diff reasons and selections void RemoveNotOwnSingleTargetAuras(uint32 newPhase = 0x0); void RemoveAurasAtMechanicImmunity(uint32 mechMask, uint32 exceptSpellId, bool non_positive = false); - void RemoveSpellsCausingAura(AuraType auraType); void RemoveRankAurasDueToSpell(uint32 spellId); bool RemoveNoStackAurasDueToAura(Aura *Aur); void RemoveAurasWithInterruptFlags(uint32 flags); void RemoveAurasWithDispelType( DispelType type ); - void RemoveAllAuras(AuraRemoveMode mode = AURA_REMOVE_BY_DEFAULT); void RemoveArenaAuras(bool onleave = false); void RemoveAllAurasOnDeath(); + + // removing specific aura FROM stack + void RemoveSingleAuraFromStack(uint32 spellId, uint32 effindex, AuraRemoveMode mode = AURA_REMOVE_BY_DEFAULT); + void RemoveSingleAuraFromStack(AuraMap::iterator &i, AuraRemoveMode mode = AURA_REMOVE_BY_DEFAULT); + + // removing specific aura FROM stack by diff reasons and selections + void RemoveSingleSpellAurasFromStack(uint32 spellId, AuraRemoveMode mode = AURA_REMOVE_BY_DEFAULT); + void RemoveSingleSpellAurasByCasterSpell(uint32 spellId, uint64 casterGUID, AuraRemoveMode mode = AURA_REMOVE_BY_DEFAULT); + void RemoveSingleAuraByCasterSpell(uint32 spellId, uint32 effindex, uint64 casterGUID, AuraRemoveMode mode = AURA_REMOVE_BY_DEFAULT); + void RemoveSingleAuraDueToSpellByDispel(uint32 spellId, uint64 casterGUID, Unit *dispeler); + void DelayAura(uint32 spellId, uint32 effindex, int32 delaytime); float GetResistanceBuffMods(SpellSchools school, bool positive) const { return GetFloatValue(positive ? UNIT_FIELD_RESISTANCEBUFFMODSPOSITIVE+school : UNIT_FIELD_RESISTANCEBUFFMODSNEGATIVE+school ); } diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index dc9ce164f..236edc0ba 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 "8904" + #define REVISION_NR "8905" #endif // __REVISION_NR_H__