From d3581f703a55b7efd705fa84d5642f0d30efb85e Mon Sep 17 00:00:00 2001 From: NetSky Date: Thu, 31 Dec 2009 15:14:06 +0300 Subject: [PATCH] [9089] Check explicit target correctness by all effect target modes. All effect target modes start from client provided target data so all its must be used for checking explicit target modes. For example exist spells that have as first effect SELF non-explicit target mode. but in same time negative to explicit target. Signed-off-by: VladimirMangos Also add caching IsHostileTo/IsFriendlyTo for avoid recall this not fast functions. --- src/game/Spell.cpp | 58 +++++++++++++++++++++++++++++++++++++++--------- src/shared/revision_nr.h | 2 +- 2 files changed, 48 insertions(+), 12 deletions(-) diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp index 8cac57a5c..9cf13c615 100644 --- a/src/game/Spell.cpp +++ b/src/game/Spell.cpp @@ -4110,29 +4110,65 @@ SpellCastResult Spell::CheckCast(bool strict) if(non_caster_target) { // simple cases - if (IsExplicitPositiveTarget(m_spellInfo->EffectImplicitTargetA[0])) + bool explicit_target_mode = false; + bool target_hostile = false; + bool target_hostile_checked = false; + bool target_friendly = false; + bool target_friendly_checked = false; + for(int k = 0; k < 3; ++k) { - if(m_caster->IsHostileTo(target)) - return SPELL_FAILED_BAD_TARGETS; - } - else if (IsExplicitNegativeTarget(m_spellInfo->EffectImplicitTargetA[0])) - { - if(m_caster->IsFriendlyTo(target)) - return SPELL_FAILED_BAD_TARGETS; + if (IsExplicitPositiveTarget(m_spellInfo->EffectImplicitTargetA[k])) + { + if (!target_hostile_checked) + { + target_hostile_checked = true; + target_hostile = m_caster->IsHostileTo(target); + } + + if(target_hostile) + return SPELL_FAILED_BAD_TARGETS; + + explicit_target_mode = true; + } + else if (IsExplicitNegativeTarget(m_spellInfo->EffectImplicitTargetA[k])) + { + if (!target_friendly_checked) + { + target_friendly_checked = true; + target_friendly = m_caster->IsFriendlyTo(target); + } + + if(target_friendly) + return SPELL_FAILED_BAD_TARGETS; + + explicit_target_mode = true; + } } // 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 - else if (m_caster->GetTypeId() == TYPEID_UNIT && m_caster->GetCharmerOrOwnerGUID()) + if (!explicit_target_mode && 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)) { - if(m_caster->IsHostileTo(target)) + if (!target_hostile_checked) + { + target_hostile_checked = true; + target_hostile = m_caster->IsHostileTo(target); + } + + if(target_hostile) return SPELL_FAILED_BAD_TARGETS; } else { - if(m_caster->IsFriendlyTo(target)) + if (!target_friendly_checked) + { + target_friendly_checked = true; + target_friendly = m_caster->IsFriendlyTo(target); + } + + if(target_friendly) return SPELL_FAILED_BAD_TARGETS; } } diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 851d74163..25e2883ae 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "9088" + #define REVISION_NR "9089" #endif // __REVISION_NR_H__ -- 2.11.4.GIT