Avoid target requirement checks for spells with caster base target selection (self,pet,around).

This fix cast fail for some spells, mostly triggered or scripted with unexpected prowided explicit tatrget different from caster.
This commit is contained in:
VladimirMangos 2009-07-31 16:12:50 +04:00
parent 8e6386aac0
commit c7f8c9b52b
2 changed files with 56 additions and 4 deletions

View file

@ -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;
}

View file

@ -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 )