[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,9 +4079,22 @@ SpellCastResult Spell::CheckCast(bool strict)
} }
} }
if(non_caster_target)
{
// simple cases
if (IsExplicitPositiveTarget(m_spellInfo->EffectImplicitTargetA[0]))
{
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;
}
// 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
if(non_caster_target && m_caster->GetTypeId() == TYPEID_UNIT && m_caster->GetCharmerOrOwnerGUID()) else if (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))
@ -4095,6 +4108,7 @@ SpellCastResult Spell::CheckCast(bool strict)
return SPELL_FAILED_BAD_TARGETS; return SPELL_FAILED_BAD_TARGETS;
} }
} }
}
if(IsPositiveSpell(m_spellInfo->Id)) if(IsPositiveSpell(m_spellInfo->Id))
if(target->IsImmunedToSpell(m_spellInfo)) if(target->IsImmunedToSpell(m_spellInfo))

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__