diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp index 2e7cf82e6..eafee4451 100644 --- a/src/game/Spell.cpp +++ b/src/game/Spell.cpp @@ -505,6 +505,16 @@ void Spell::FillTargetMap() // but need it support in some know cases switch(m_spellInfo->EffectImplicitTargetA[i]) { + case 0: + switch(m_spellInfo->EffectImplicitTargetB[i]) + { + case 0: + break; + default: + SetTargetMap(i, m_spellInfo->EffectImplicitTargetB[i], tmpUnitMap); + break; + } + break; case TARGET_SELF: switch(m_spellInfo->EffectImplicitTargetB[i]) { @@ -3751,7 +3761,9 @@ SpellCastResult Spell::CheckCast(bool strict) return SPELL_FAILED_CASTER_AURASTATE; } - if(target != m_caster) + bool non_caster_target = target != m_caster && !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_spellInfo->TargetAuraState && !target->HasAuraStateForCaster(AuraState(m_spellInfo->TargetAuraState),m_caster->GetGUID())) @@ -3806,7 +3818,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)) { @@ -3819,7 +3831,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)) @@ -3859,7 +3871,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 7f06e1a90..76c3da926 100644 --- a/src/game/SpellMgr.h +++ b/src/game/SpellMgr.h @@ -196,6 +196,46 @@ bool IsPositiveTarget(uint32 targetA, uint32 targetB); bool IsSingleTargetSpell(SpellEntry const *spellInfo); bool IsSingleTargetSpells(SpellEntry const *spellInfo1, SpellEntry const *spellInfo2); +inline bool IsCasterSourceTarget(uint32 target) +{ + switch (target ) + { + case TARGET_SELF: + case TARGET_PET: + case TARGET_ALL_PARTY_AROUND_CASTER: + case TARGET_IN_FRONT_OF_CASTER: + case TARGET_MASTER: + case TARGET_MINION: + case TARGET_ALL_PARTY: + case TARGET_ALL_PARTY_AROUND_CASTER_2: + case TARGET_SELF_FISHING: + case TARGET_TOTEM_EARTH: + case TARGET_TOTEM_WATER: + case TARGET_TOTEM_AIR: + case TARGET_TOTEM_FIRE: + case TARGET_SUMMON: + case TARGET_AREAEFFECT_CUSTOM_2: + case TARGET_ALL_RAID_AROUND_CASTER: + case TARGET_SELF2: + case TARGET_DIRECTLY_FORWARD: + case TARGET_NONCOMBAT_PET: + case TARGET_IN_FRONT_OF_CASTER_30: + return true; + default: + break; + } + return false; +} + +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; +} + inline bool IsPointEffectTarget( Targets target ) { switch (target )