diff options
author | megamage <none@none> | 2009-09-04 10:01:52 -0500 |
---|---|---|
committer | megamage <none@none> | 2009-09-04 10:01:52 -0500 |
commit | 7a877b39aad8e6a2fb062cd47143e0a099099e2c (patch) | |
tree | 0094d701d457aad5ae6782210ffa402d3da2b2df /src | |
parent | 596d1714d45a41befe7e5ebef17cac490b23e407 (diff) |
*Fix a crash caused by dispel effect. Thanks to nanouniko
--HG--
branch : trunk
Diffstat (limited to 'src')
-rw-r--r-- | src/game/SpellEffects.cpp | 122 |
1 files changed, 60 insertions, 62 deletions
diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp index ff810a3efb7..208ae3759f8 100644 --- a/src/game/SpellEffects.cpp +++ b/src/game/SpellEffects.cpp @@ -3559,12 +3559,13 @@ 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< std::pair<uint32, uint64> > DispelList; void Spell::EffectDispel(uint32 i) { if(!unitTarget) return; - std::list < Aura * > dispel_list; + Unit::AuraList dispel_list; // Create dispel mask by dispel type uint32 dispel_type = m_spellInfo->EffectMiscValue[i]; @@ -3572,89 +3573,86 @@ void Spell::EffectDispel(uint32 i) Unit::AuraMap const& auras = unitTarget->GetAuras(); for(Unit::AuraMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr) { - Aura *aur = (*itr).second; - if (aur && ((1<<aur->GetSpellProto()->Dispel) & dispelMask)) + Aura *aur = itr->second; + if ((1<<aur->GetSpellProto()->Dispel) & dispelMask) { if(aur->GetSpellProto()->Dispel == DISPEL_MAGIC) { - bool positive = true; - if (!aur->IsPositive()) - positive = false; - else - positive = (aur->GetSpellProto()->AttributesEx & SPELL_ATTR_EX_NEGATIVE)==0; + bool positive = aur->IsPositive() ? (!(aur->GetSpellProto()->AttributesEx & SPELL_ATTR_EX_NEGATIVE)) : false; // do not remove positive auras if friendly target // negative auras if non-friendly target if(positive == unitTarget->IsFriendlyTo(m_caster)) continue; } - for (uint8 i = aur->GetStackAmount();i!=0;--i) + + for (uint8 i = aur->GetStackAmount(); i; --i) dispel_list.push_back(aur); } } + + if (dispel_list.empty()) + return; + // Ok if exist some buffs for dispel try dispel it - if (uint32 list_size = dispel_list.size()) + uint32 failCount = 0; + DispelList success_list; + WorldPacket dataFail(SMSG_DISPEL_FAILED, 8+8+4+4+damage*4); + // dispel N = damage buffs (or while exist buffs for dispel) + for (int32 count = 0; count < damage && !dispel_list.empty(); ++count) { - uint32 failCount = 0; - std::list < Aura * > success_list; - WorldPacket dataFail(SMSG_DISPEL_FAILED, 8+8+4+4+damage*4); - // dispel N = damage buffs (or while exist buffs for dispel) - for (int32 count=0; count < damage && list_size > 0; ++count, list_size = dispel_list.size()) - { - // Random select buff for dispel - std::list < Aura * > ::iterator itr = dispel_list.begin(); - for (uint32 i=urand(0, list_size-1);i>0;--i) - itr++; + // Random select buff for dispel + Unit::AuraList::iterator itr = dispel_list.begin(); + std::advance(itr, urand(0, dispel_list.size() - 1)); - if (GetDispelChance((*itr)->GetCaster(), (*itr)->GetId())) - { - success_list.push_back(*itr); - dispel_list.erase(itr); - } - else - { - if (!failCount) - { - // Failed to dispell - dataFail << uint64(m_caster->GetGUID()); // Caster GUID - dataFail << uint64(unitTarget->GetGUID()); // Victim GUID - dataFail << uint32(m_spellInfo->Id); // dispel spell id - } - failCount++; - dataFail << uint32((*itr)->GetId()); // Spell Id - } - } - if (failCount) + if (GetDispelChance((*itr)->GetCaster(), (*itr)->GetId())) { - m_caster->SendMessageToSet(&dataFail, true); + success_list.push_back(std::make_pair((*itr)->GetId(), (*itr)->GetCasterGUID())); + dispel_list.erase(itr); } - if (success_list.size()) + else { - WorldPacket dataSuccess(SMSG_SPELLDISPELLOG, 8+8+4+1+4+damage*5); - // Send packet header - dataSuccess.append(unitTarget->GetPackGUID()); // Victim GUID - dataSuccess.append(m_caster->GetPackGUID()); // Caster GUID - dataSuccess << uint32(m_spellInfo->Id); // dispel spell id - dataSuccess << uint8(0); // not used - dataSuccess << uint32(success_list.size()); // count - for (std::list < Aura * > ::iterator itr = success_list.begin();itr!=success_list.end();++itr) + if (!failCount) { - // Send dispelled spell info - dataSuccess << uint32((*itr)->GetId()); // Spell Id - dataSuccess << uint8(0); // 0 - dispelled !=0 cleansed - unitTarget->RemoveAurasDueToSpellByDispel((*itr)->GetId(), (*itr)->GetCasterGUID(), m_caster); - } - m_caster->SendMessageToSet(&dataSuccess, true); - - // On success dispel - // Devour Magic - if (m_spellInfo->SpellFamilyName == SPELLFAMILY_WARLOCK && m_spellInfo->Category == SPELLCATEGORY_DEVOUR_MAGIC) - { - int32 heal_amount = m_spellInfo->CalculateSimpleValue(1); - m_caster->CastCustomSpell(m_caster, 19658, &heal_amount, NULL, NULL, true); + // Failed to dispell + dataFail << uint64(m_caster->GetGUID()); // Caster GUID + dataFail << uint64(unitTarget->GetGUID()); // Victim GUID + dataFail << uint32(m_spellInfo->Id); // dispel spell id } + ++failCount; + dataFail << uint32((*itr)->GetId()); // Spell Id } } + + if (failCount) + m_caster->SendMessageToSet(&dataFail, true); + + if (success_list.empty()) + return; + + WorldPacket dataSuccess(SMSG_SPELLDISPELLOG, 8+8+4+1+4+damage*5); + // Send packet header + dataSuccess.append(unitTarget->GetPackGUID()); // Victim GUID + dataSuccess.append(m_caster->GetPackGUID()); // Caster GUID + dataSuccess << uint32(m_spellInfo->Id); // dispel spell id + dataSuccess << uint8(0); // not used + dataSuccess << uint32(success_list.size()); // count + for (DispelList::iterator itr = success_list.begin(); itr != success_list.end(); ++itr) + { + // Send dispelled spell info + 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); + + // On success dispel + // Devour Magic + if (m_spellInfo->SpellFamilyName == SPELLFAMILY_WARLOCK && m_spellInfo->Category == SPELLCATEGORY_DEVOUR_MAGIC) + { + int32 heal_amount = m_spellInfo->CalculateSimpleValue(1); + m_caster->CastCustomSpell(m_caster, 19658, &heal_amount, NULL, NULL, true); + } } void Spell::EffectDualWield(uint32 /*i*/) |