[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 <vladimir@getmangos.com>

Also add caching IsHostileTo/IsFriendlyTo for avoid recall this not fast functions.
This commit is contained in:
NetSky 2009-12-31 15:14:06 +03:00 committed by VladimirMangos
parent 375aedd611
commit 9a6c248dec
2 changed files with 48 additions and 12 deletions

View file

@ -4110,29 +4110,65 @@ SpellCastResult Spell::CheckCast(bool strict)
if(non_caster_target) if(non_caster_target)
{ {
// simple cases // 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)) if (IsExplicitPositiveTarget(m_spellInfo->EffectImplicitTargetA[k]))
return SPELL_FAILED_BAD_TARGETS; {
} if (!target_hostile_checked)
else if (IsExplicitNegativeTarget(m_spellInfo->EffectImplicitTargetA[0])) {
{ target_hostile_checked = true;
if(m_caster->IsFriendlyTo(target)) target_hostile = m_caster->IsHostileTo(target);
return SPELL_FAILED_BAD_TARGETS; }
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. // 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 // 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) // check correctness positive/negative cast target (pet cast real check and cheating check)
if(IsPositiveSpell(m_spellInfo->Id)) 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; return SPELL_FAILED_BAD_TARGETS;
} }
else 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; return SPELL_FAILED_BAD_TARGETS;
} }
} }

View file

@ -1,4 +1,4 @@
#ifndef __REVISION_NR_H__ #ifndef __REVISION_NR_H__
#define __REVISION_NR_H__ #define __REVISION_NR_H__
#define REVISION_NR "9088" #define REVISION_NR "9089"
#endif // __REVISION_NR_H__ #endif // __REVISION_NR_H__