aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKandera <KanderaDev@gmail.com>2012-03-13 13:03:41 -0400
committerKandera <KanderaDev@gmail.com>2012-03-15 10:56:56 -0400
commit01bc6c483bc0756850ee8853f98bd8de4a2316bc (patch)
tree738b39dbad51ac87dec69b6caee1947f9f760437
parent84891377b5f11c93ba75a925703a654c3778b162 (diff)
Core/Spells: add correct checking for dispeling errors. Fixes spammable cleanse.
-rwxr-xr-xsrc/server/game/Entities/Unit/Unit.cpp39
-rwxr-xr-xsrc/server/game/Entities/Unit/Unit.h3
-rwxr-xr-xsrc/server/game/Spells/Spell.cpp18
-rwxr-xr-xsrc/server/game/Spells/SpellEffects.cpp41
4 files changed, 62 insertions, 39 deletions
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
index e89d289ba4e..01f4a610f6c 100755
--- a/src/server/game/Entities/Unit/Unit.cpp
+++ b/src/server/game/Entities/Unit/Unit.cpp
@@ -4113,6 +4113,45 @@ Aura* Unit::GetAuraOfRankedSpell(uint32 spellId, uint64 casterGUID, uint64 itemC
return aurApp ? aurApp->GetBase() : NULL;
}
+void Unit::GetDispellableAuraList(Unit* caster, uint32 dispelMask, DispelChargesList& dispelList)
+{
+ // we should not be able to dispel diseases if the target is affected by unholy blight
+ if (dispelMask & (1 << DISPEL_DISEASE) && HasAura(50536))
+ dispelMask &= ~(1 << DISPEL_DISEASE);
+
+ AuraMap const& auras = GetOwnedAuras();
+ for (AuraMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
+ {
+ Aura* aura = itr->second;
+ AuraApplication * aurApp = aura->GetApplicationOfTarget(GetGUID());
+ if (!aurApp)
+ continue;
+
+ // don't try to remove passive auras
+ if (aura->IsPassive())
+ continue;
+
+ if (aura->GetSpellInfo()->GetDispelMask() & dispelMask)
+ {
+ if (aura->GetSpellInfo()->Dispel == DISPEL_MAGIC)
+ {
+ // do not remove positive auras if friendly target
+ // negative auras if non-friendly target
+ if (aurApp->IsPositive() == IsFriendlyTo(caster))
+ continue;
+ }
+
+ // The charges / stack amounts don't count towards the total number of auras that can be dispelled.
+ // Ie: A dispel on a target with 5 stacks of Winters Chill and a Polymorph has 1 / (1 + 1) -> 50% chance to dispell
+ // Polymorph instead of 1 / (5 + 1) -> 16%.
+ bool dispel_charges = aura->GetSpellInfo()->AttributesEx7 & SPELL_ATTR7_DISPEL_CHARGES;
+ uint8 charges = dispel_charges ? aura->GetCharges() : aura->GetStackAmount();
+ if (charges > 0)
+ dispelList.push_back(std::make_pair(aura, charges));
+ }
+ }
+}
+
bool Unit::HasAuraEffect(uint32 spellId, uint8 effIndex, uint64 caster) const
{
for (AuraApplicationMap::const_iterator itr = m_appliedAuras.lower_bound(spellId); itr != m_appliedAuras.upper_bound(spellId); ++itr)
diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h
index 88eb0068f45..5192b8c5e8f 100755
--- a/src/server/game/Entities/Unit/Unit.h
+++ b/src/server/game/Entities/Unit/Unit.h
@@ -341,6 +341,7 @@ class Transport;
class Vehicle;
typedef std::list<Unit*> UnitList;
+typedef std::list< std::pair<Aura*, uint8> > DispelChargesList;
struct SpellImmune
{
@@ -1814,6 +1815,8 @@ class Unit : public WorldObject
AuraApplication * GetAuraApplicationOfRankedSpell(uint32 spellId, uint64 casterGUID = 0, uint64 itemCasterGUID = 0, uint8 reqEffMask = 0, AuraApplication * except = NULL) const;
Aura* GetAuraOfRankedSpell(uint32 spellId, uint64 casterGUID = 0, uint64 itemCasterGUID = 0, uint8 reqEffMask = 0) const;
+ void GetDispellableAuraList(Unit* caster, uint32 dispelMask, DispelChargesList& dispelList);
+
bool HasAuraEffect(uint32 spellId, uint8 effIndex, uint64 caster = 0) const;
uint32 GetAuraCount(uint32 spellId) const;
bool HasAura(uint32 spellId, uint64 casterGUID = 0, uint64 itemCasterGUID = 0, uint8 reqEffMask = 0) const;
diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp
index 38e66a218f8..6587ce71b61 100755
--- a/src/server/game/Spells/Spell.cpp
+++ b/src/server/game/Spells/Spell.cpp
@@ -4938,6 +4938,24 @@ SpellCastResult Spell::CheckCast(bool strict)
if (castResult != SPELL_CAST_OK)
return castResult;
+ bool hasDispellableAura = false;
+ for (int i = 0; i < MAX_SPELL_EFFECTS; i++)
+ if (m_spellInfo->Effects[i].Effect == SPELL_EFFECT_DISPEL)
+ if (Unit* target = m_targets.GetUnitTarget())
+ {
+ DispelChargesList dispelList;
+ uint32 dispelMask = SpellInfo::GetDispelMask(DispelType(m_spellInfo->Effects[i].MiscValue));
+ target->GetDispellableAuraList(m_caster, dispelMask, dispelList);
+ if (!dispelList.empty())
+ {
+ hasDispellableAura = true;
+ break;
+ }
+ }
+
+ if (!hasDispellableAura)
+ return SPELL_FAILED_NOTHING_TO_DISPEL;
+
for (int i = 0; i < MAX_SPELL_EFFECTS; i++)
{
// for effects of spells that have only one target
diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp
index 59b6d8971cf..01782ba4312 100755
--- a/src/server/game/Spells/SpellEffects.cpp
+++ b/src/server/game/Spells/SpellEffects.cpp
@@ -2536,7 +2536,6 @@ void Spell::EffectLearnSpell(SpellEffIndex effIndex)
}
typedef std::list< std::pair<uint32, uint64> > DispelList;
-typedef std::list< std::pair<Aura*, uint8> > DispelChargesList;
void Spell::EffectDispel(SpellEffIndex effIndex)
{
if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET)
@@ -2545,48 +2544,12 @@ void Spell::EffectDispel(SpellEffIndex effIndex)
if (!unitTarget)
return;
- DispelChargesList dispel_list;
-
// Create dispel mask by dispel type
uint32 dispel_type = m_spellInfo->Effects[effIndex].MiscValue;
uint32 dispelMask = SpellInfo::GetDispelMask(DispelType(dispel_type));
- // we should not be able to dispel diseases if the target is affected by unholy blight
- if (dispelMask & (1 << DISPEL_DISEASE) && unitTarget->HasAura(50536))
- dispelMask &= ~(1 << DISPEL_DISEASE);
-
- Unit::AuraMap const& auras = unitTarget->GetOwnedAuras();
- for (Unit::AuraMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
- {
- Aura* aura = itr->second;
- AuraApplication * aurApp = aura->GetApplicationOfTarget(unitTarget->GetGUID());
- if (!aurApp)
- continue;
-
- // don't try to remove passive auras
- if (aura->IsPassive())
- continue;
-
- if (aura->GetSpellInfo()->GetDispelMask() & dispelMask)
- {
- if (aura->GetSpellInfo()->Dispel == DISPEL_MAGIC)
- {
- // do not remove positive auras if friendly target
- // negative auras if non-friendly target
- if (aurApp->IsPositive() == unitTarget->IsFriendlyTo(m_caster))
- continue;
- }
-
- // The charges / stack amounts don't count towards the total number of auras that can be dispelled.
- // Ie: A dispel on a target with 5 stacks of Winters Chill and a Polymorph has 1 / (1 + 1) -> 50% chance to dispell
- // Polymorph instead of 1 / (5 + 1) -> 16%.
- bool dispel_charges = aura->GetSpellInfo()->AttributesEx7 & SPELL_ATTR7_DISPEL_CHARGES;
- uint8 charges = dispel_charges ? aura->GetCharges() : aura->GetStackAmount();
- if (charges > 0)
- dispel_list.push_back(std::make_pair(aura, charges));
- }
- }
-
+ DispelChargesList dispel_list;
+ unitTarget->GetDispellableAuraList(m_caster, dispelMask, dispel_list);
if (dispel_list.empty())
return;