diff options
author | megamage <none@none> | 2009-08-02 10:03:38 +0800 |
---|---|---|
committer | megamage <none@none> | 2009-08-02 10:03:38 +0800 |
commit | a1d5f174be17c7fc230b9d362ffab27cd28a4ec7 (patch) | |
tree | e7ea98fb940f569323254676d76a230ed8c50a08 | |
parent | c1d94ad607e87325ba64d07857de08a93329d2ba (diff) |
Avoid target requirement checks for spells with caster base target selection (self,pet,around). Author: VladimirMangos
This fix cast fail for some spells, mostly triggered or scripted with unexpected prowided explicit tatrget different from caster.
--HG--
branch : trunk
-rw-r--r-- | src/game/Spell.cpp | 10 | ||||
-rw-r--r-- | src/game/SpellMgr.h | 23 |
2 files changed, 29 insertions, 4 deletions
diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp index af5cda5bec3..837b8606398 100644 --- a/src/game/Spell.cpp +++ b/src/game/Spell.cpp @@ -4354,7 +4354,9 @@ SpellCastResult Spell::CheckCast(bool strict) if(!m_IsTriggeredSpell && target == m_caster && m_spellInfo->AttributesEx & SPELL_ATTR_EX_CANT_TARGET_SELF) return SPELL_FAILED_BAD_TARGETS; - if(target != m_caster) + bool non_caster_target = target != m_caster && !spellmgr.IsSpellWithCasterSourceTargetsOnly(m_spellInfo); + + if(non_caster_target) { // target state requirements (apply to non-self only), to allow cast affects to self like Dirty Deeds if(!m_IsTriggeredSpell && m_spellInfo->TargetAuraState && !target->HasAuraState(AuraState(m_spellInfo->TargetAuraState), m_spellInfo, m_caster)) @@ -4402,7 +4404,7 @@ SpellCastResult Spell::CheckCast(bool strict) //check creature type //ignore self casts (including area casts when caster selected as target) - if(target != m_caster) + if(non_caster_target) { if(!CheckTargetCreatureType(target)) { @@ -4415,7 +4417,7 @@ SpellCastResult Spell::CheckCast(bool strict) // TODO: this check can be applied and for player to prevent cheating when IsPositiveSpell will return always correct result. // check target for pet/charmed casts (not self targeted), self targeted cast used for area effects and etc - if(m_caster != target && m_caster->GetTypeId() == TYPEID_UNIT && m_caster->GetCharmerOrOwnerGUID()) + if(non_caster_target && m_caster->GetTypeId() == TYPEID_UNIT && m_caster->GetCharmerOrOwnerGUID()) { // check correctness positive/negative cast target (pet cast real check and cheating check) if(IsPositiveSpell(m_spellInfo->Id)) @@ -4454,7 +4456,7 @@ SpellCastResult Spell::CheckCast(bool strict) } // check if target is in combat - if (target != m_caster && (m_spellInfo->AttributesEx & SPELL_ATTR_EX_NOT_IN_COMBAT_TARGET) && target->isInCombat()) + if (non_caster_target && (m_spellInfo->AttributesEx & SPELL_ATTR_EX_NOT_IN_COMBAT_TARGET) && target->isInCombat()) return SPELL_FAILED_TARGET_AFFECTING_COMBAT; } diff --git a/src/game/SpellMgr.h b/src/game/SpellMgr.h index cb0c9d9bdbd..b2ba185f82a 100644 --- a/src/game/SpellMgr.h +++ b/src/game/SpellMgr.h @@ -270,6 +270,7 @@ bool IsDispelableBySpell(SpellEntry const * dispelSpell, uint32 spellId, bool de bool IsSingleTargetSpell(SpellEntry const *spellInfo); bool IsSingleTargetSpells(SpellEntry const *spellInfo1, SpellEntry const *spellInfo2); + extern bool IsAreaEffectTarget[TOTAL_SPELL_TARGETS]; inline bool IsAreaOfEffectSpell(SpellEntry const *spellInfo) @@ -1051,6 +1052,28 @@ class SpellMgr bool IsSrcTargetSpell(SpellEntry const *spellInfo) const; + inline bool IsCasterSourceTarget(uint32 target) + { + switch (SpellTargetType[target]) + { + case TARGET_TYPE_UNIT_TARGET: + case TARGET_TYPE_DEST_TARGET: + return false; + default: + break; + } + return true; + } + + inline bool IsSpellWithCasterSourceTargetsOnly(SpellEntry const* spellInfo) + { + for(int i = 0; i < 3; ++i) + if(uint32 target = spellInfo->EffectImplicitTargetA[i]) + if(!IsCasterSourceTarget(target)) + return false; + return true; + } + // Modifiers public: static SpellMgr& Instance(); |