diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/game/SpellEffects.cpp | 32 | ||||
-rw-r--r-- | src/game/Unit.cpp | 20 | ||||
-rw-r--r-- | src/game/Unit.h | 4 |
3 files changed, 26 insertions, 30 deletions
diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp index 8e3af99e89c..cb8cda60536 100644 --- a/src/game/SpellEffects.cpp +++ b/src/game/SpellEffects.cpp @@ -3727,7 +3727,7 @@ void Spell::EffectLearnSpell(uint32 i) sLog.outDebug("Spell: Player %u has learned spell %u from NpcGUID=%u", player->GetGUIDLow(), spellToLearn, m_caster->GetGUIDLow()); } -typedef std::list< uint32 > DispelList; +typedef std::list< std::pair<uint32, uint64> > DispelList; void Spell::EffectDispel(uint32 i) { if(!unitTarget) @@ -3777,8 +3777,7 @@ void Spell::EffectDispel(uint32 i) if (GetDispelChance((*itr)->GetCaster(), (*itr)->GetId())) { - unitTarget->RemoveAurasDueToSpellByDispel(*itr, m_caster); - success_list.push_back((*itr)->GetId()); + success_list.push_back(std::make_pair((*itr)->GetId(), (*itr)->GetCasterGUID())); dispel_list.erase(itr); } else @@ -3811,8 +3810,9 @@ void Spell::EffectDispel(uint32 i) for (DispelList::iterator itr = success_list.begin(); itr != success_list.end(); ++itr) { // Send dispelled spell info - dataSuccess << uint32(*itr); // Spell Id + dataSuccess << uint32(itr->first); // Spell Id dataSuccess << uint8(0); // 0 - dispelled !=0 cleansed + unitTarget->RemoveAurasDueToSpellByDispel(itr->first, itr->second, m_caster); } m_caster->SendMessageToSet(&dataSuccess, true); @@ -7166,7 +7166,7 @@ void Spell::EffectStealBeneficialBuff(uint32 i) if(!unitTarget || unitTarget==m_caster) // can't steal from self return; - std::list <Aura *> steal_list; + Unit::AuraList steal_list; // Create dispel mask by dispel type uint32 dispelMask = GetDispellMask( DispelType(m_spellInfo->EffectMiscValue[i]) ); Unit::AuraMap const& auras = unitTarget->GetOwnedAuras(); @@ -7176,24 +7176,27 @@ void Spell::EffectStealBeneficialBuff(uint32 i) if ((1<<aura->GetSpellProto()->Dispel) & dispelMask) { // Need check for passive? this - if (aura->IsPositive(unitTarget) && !aura->IsPassive() && !(aura->GetSpellProto()->AttributesEx4 & SPELL_ATTR_EX4_NOT_STEALABLE)) + if (aura->IsPositive(unitTarget) || aura->IsPassive() || aura->GetSpellProto()->AttributesEx4 & SPELL_ATTR_EX4_NOT_STEALABLE) + continue; + + bool dispel_charges = aura->GetSpellProto()->AttributesEx7 & SPELL_ATTR_EX7_DISPEL_CHARGES; + + for (uint8 i = dispel_charges ? aura->GetCharges() : aura->GetStackAmount(); i; --i) steal_list.push_back(aura); } } // Ok if exist some buffs for dispel try dispel it if (uint32 list_size = steal_list.size()) { - std::list < Aura * > success_list; + DispelList success_list; // dispel N = damage buffs (or while exist buffs for dispel) for (int32 count=0; count < damage && list_size > 0; ++count, list_size = steal_list.size()) { // Random select buff for dispel - std::list < Aura * > ::iterator itr = steal_list.begin(); - for (uint32 i=urand(0, list_size-1); i>0; --i) - itr++; - success_list.push_back(*itr); - unitTarget->RemoveAurasDueToSpellBySteal(*itr, m_caster); + Unit::AuraList::iterator itr = steal_list.begin(); + std::advance(itr, urand(0, list_size-1)); + success_list.push_back(std::make_pair((*itr)->GetId(), (*itr)->GetCasterGUID())); steal_list.erase(itr); } if (success_list.size()) @@ -7204,10 +7207,11 @@ void Spell::EffectStealBeneficialBuff(uint32 i) data << uint32(m_spellInfo->Id); // dispel spell id data << uint8(0); // not used data << uint32(success_list.size()); // count - for (std::list < Aura * >::iterator itr = success_list.begin(); itr!=success_list.end(); ++itr) + for (DispelList::iterator itr = success_list.begin(); itr!=success_list.end(); ++itr) { - data << uint32((*itr)->GetId()); // Spell Id + data << uint32(itr->first); // Spell Id data << uint8(0); // 0 - steals !=0 transfers + unitTarget->RemoveAurasDueToSpellBySteal(itr->first, itr->second, m_caster); } m_caster->SendMessageToSet(&data, true); } diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index b31a406e185..195bc6230ee 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -3977,16 +3977,12 @@ inline void Unit::RemoveAuraFromStack(AuraMap::iterator &iter, AuraRemoveMode re RemoveOwnedAura(iter, removeMode); } -void Unit::RemoveAurasDueToSpellByDispel(Aura * aura, Unit *dispeller) +void Unit::RemoveAurasDueToSpellByDispel(uint32 spellId, uint64 casterGUID, Unit *dispeller) { - if (aura->IsRemoved()) - return; - - uint32 spellId = aura->GetId(); - for (AuraMap::iterator iter = m_ownedAuras.lower_bound(spellId); iter != m_ownedAuras.upper_bound(spellId);) { - if (aura == iter->second) + Aura * aura = iter->second; + if (aura->GetCasterGUID() == casterGUID) { if (aura->GetSpellProto()->AttributesEx7 & SPELL_ATTR_EX7_DISPEL_CHARGES) aura->DropCharge(); @@ -4039,16 +4035,12 @@ void Unit::RemoveAurasDueToSpellByDispel(Aura * aura, Unit *dispeller) } } -void Unit::RemoveAurasDueToSpellBySteal(Aura * aura, Unit *stealer) +void Unit::RemoveAurasDueToSpellBySteal(uint32 spellId, uint64 casterGUID, Unit *stealer) { - if (aura->IsRemoved()) - return; - - uint32 spellId = aura->GetId(); - for (AuraMap::iterator iter = m_ownedAuras.lower_bound(spellId); iter != m_ownedAuras.upper_bound(spellId);) { - if (aura == iter->second) + Aura * aura = iter->second; + if (aura->GetCasterGUID() == casterGUID) { int32 damage[MAX_SPELL_EFFECTS]; int32 baseDamage[MAX_SPELL_EFFECTS]; diff --git a/src/game/Unit.h b/src/game/Unit.h index 5507335d848..3cd964e583c 100644 --- a/src/game/Unit.h +++ b/src/game/Unit.h @@ -1562,8 +1562,8 @@ class TRINITY_DLL_SPEC Unit : public WorldObject void RemoveAurasDueToSpell(uint32 spellId, uint64 caster = NULL, uint8 reqEffMask = 0, AuraRemoveMode removeMode = AURA_REMOVE_BY_DEFAULT); void RemoveAuraFromStack(uint32 spellId, uint64 caster = NULL, AuraRemoveMode removeMode = AURA_REMOVE_BY_DEFAULT); inline void RemoveAuraFromStack(AuraMap::iterator &iter,AuraRemoveMode removeMode); - void RemoveAurasDueToSpellByDispel(Aura * aura, Unit *dispeller); - void RemoveAurasDueToSpellBySteal(Aura * aura, Unit *stealer); + void RemoveAurasDueToSpellByDispel(uint32 spellId, uint64 casterGUID, Unit *dispeller); + void RemoveAurasDueToSpellBySteal(uint32 spellId, uint64 casterGUID, Unit *stealer); void RemoveAurasDueToItemSpell(Item* castItem,uint32 spellId); void RemoveAurasByType(AuraType auraType, uint64 casterGUID = 0, Aura * except = NULL, bool negative = true, bool positive = true); void RemoveNotOwnSingleTargetAuras(uint32 newPhase = 0x0); |