[9035] Attempt make more fast and less hackish spell target checks

* Enable server side recheck clear negative to friend or positive to enemy casts that already checks at client side
* Use more fast way check in similar cases for non-players, and fall back to old way in unclear (for while at least)

Please report if some spell stop propertly casted at friends/enemies.
This commit is contained in:
VladimirMangos 2009-12-20 03:26:39 +03:00
parent 27e7190301
commit 9e18fc5745
4 changed files with 58 additions and 7 deletions

View file

@ -4079,21 +4079,35 @@ SpellCastResult Spell::CheckCast(bool strict)
} }
} }
// TODO: this check can be applied and for player to prevent cheating when IsPositiveSpell will return always correct result. if(non_caster_target)
// check target for pet/charmed casts (not self targeted), self targeted cast used for area effects and etc
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) // simple cases
if(IsPositiveSpell(m_spellInfo->Id)) if (IsExplicitPositiveTarget(m_spellInfo->EffectImplicitTargetA[0]))
{ {
if(m_caster->IsHostileTo(target)) if(m_caster->IsHostileTo(target))
return SPELL_FAILED_BAD_TARGETS; return SPELL_FAILED_BAD_TARGETS;
} }
else else if (IsExplicitNegativeTarget(m_spellInfo->EffectImplicitTargetA[0]))
{ {
if(m_caster->IsFriendlyTo(target)) if(m_caster->IsFriendlyTo(target))
return SPELL_FAILED_BAD_TARGETS; return SPELL_FAILED_BAD_TARGETS;
} }
// 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())
{
// check correctness positive/negative cast target (pet cast real check and cheating check)
if(IsPositiveSpell(m_spellInfo->Id))
{
if(m_caster->IsHostileTo(target))
return SPELL_FAILED_BAD_TARGETS;
}
else
{
if(m_caster->IsFriendlyTo(target))
return SPELL_FAILED_BAD_TARGETS;
}
}
} }
if(IsPositiveSpell(m_spellInfo->Id)) if(IsPositiveSpell(m_spellInfo->Id))

View file

@ -426,6 +426,40 @@ bool IsPositiveTarget(uint32 targetA, uint32 targetB)
return true; return true;
} }
bool IsExplicitPositiveTarget(uint32 targetA)
{
// positive targets
switch(targetA)
{
case TARGET_SELF:
case TARGET_SINGLE_FRIEND:
case TARGET_SINGLE_PARTY:
case TARGET_CHAIN_HEAL:
case TARGET_SINGLE_FRIEND_2:
case TARGET_AREAEFFECT_PARTY_AND_CLASS:
case TARGET_SELF2:
return true;
default:
break;
}
return false;
}
bool IsExplicitNegativeTarget(uint32 targetA)
{
// non-positive targets
switch(targetA)
{
case TARGET_CHAIN_DAMAGE:
case TARGET_CURRENT_ENEMY_COORDINATES:
case TARGET_SINGLE_ENEMY:
return true;
default:
break;
}
return false;
}
bool IsPositiveEffect(uint32 spellId, uint32 effIndex) bool IsPositiveEffect(uint32 spellId, uint32 effIndex)
{ {
SpellEntry const *spellproto = sSpellStore.LookupEntry(spellId); SpellEntry const *spellproto = sSpellStore.LookupEntry(spellId);

View file

@ -220,6 +220,9 @@ bool IsPositiveSpell(uint32 spellId);
bool IsPositiveEffect(uint32 spellId, uint32 effIndex); bool IsPositiveEffect(uint32 spellId, uint32 effIndex);
bool IsPositiveTarget(uint32 targetA, uint32 targetB); bool IsPositiveTarget(uint32 targetA, uint32 targetB);
bool IsExplicitPositiveTarget(uint32 targetA);
bool IsExplicitNegativeTarget(uint32 targetA);
bool IsSingleTargetSpell(SpellEntry const *spellInfo); bool IsSingleTargetSpell(SpellEntry const *spellInfo);
bool IsSingleTargetSpells(SpellEntry const *spellInfo1, SpellEntry const *spellInfo2); bool IsSingleTargetSpells(SpellEntry const *spellInfo1, SpellEntry const *spellInfo2);

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 "9034" #define REVISION_NR "9035"
#endif // __REVISION_NR_H__ #endif // __REVISION_NR_H__