diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp index d8f6259ca..67da066c3 100644 --- a/src/game/Spell.cpp +++ b/src/game/Spell.cpp @@ -1542,9 +1542,11 @@ void Spell::SetTargetMap(uint32 i,uint32 cur,UnitList& TagUnitMap) { if (EffectChainTarget <= 1) { - Unit* pUnitTarget = SelectMagnetTarget(); - if(pUnitTarget) + if(Unit* pUnitTarget = m_caster->SelectMagnetTarget(m_targets.getUnitTarget(), m_spellInfo)) + { + m_targets.setUnitTarget(pUnitTarget); TagUnitMap.push_back(pUnitTarget); + } } else { @@ -1871,9 +1873,11 @@ void Spell::SetTargetMap(uint32 i,uint32 cur,UnitList& TagUnitMap) } else { - Unit* pUnitTarget = SelectMagnetTarget(); - if(pUnitTarget) + if(Unit* pUnitTarget = m_caster->SelectMagnetTarget(m_targets.getUnitTarget(), m_spellInfo)) + { + m_targets.setUnitTarget(pUnitTarget); TagUnitMap.push_back(pUnitTarget); + } } } }break; @@ -1905,9 +1909,11 @@ void Spell::SetTargetMap(uint32 i,uint32 cur,UnitList& TagUnitMap) }break; case TARGET_SINGLE_ENEMY: { - Unit* pUnitTarget = SelectMagnetTarget(); - if(pUnitTarget) + if(Unit* pUnitTarget = m_caster->SelectMagnetTarget(m_targets.getUnitTarget(), m_spellInfo)) + { + m_targets.setUnitTarget(pUnitTarget); TagUnitMap.push_back(pUnitTarget); + } }break; case TARGET_AREAEFFECT_PARTY: { @@ -5419,30 +5425,6 @@ bool Spell::CheckTarget( Unit* target, uint32 eff ) return true; } -Unit* Spell::SelectMagnetTarget() -{ - Unit* target = m_targets.getUnitTarget(); - - if(target && target->HasAuraType(SPELL_AURA_SPELL_MAGNET) && !(m_spellInfo->Attributes & 0x10)) - { - Unit::AuraList const& magnetAuras = target->GetAurasByType(SPELL_AURA_SPELL_MAGNET); - for(Unit::AuraList::const_iterator itr = magnetAuras.begin(); itr != magnetAuras.end(); ++itr) - { - if(Unit* magnet = (*itr)->GetCaster()) - { - if(magnet->IsWithinLOSInMap(m_caster)) - { - target = magnet; - m_targets.setUnitTarget(target); - break; - } - } - } - } - - return target; -} - bool Spell::IsNeedSendToClient() const { return m_spellInfo->SpellVisual[0] || m_spellInfo->SpellVisual[1] || IsChanneledSpell(m_spellInfo) || diff --git a/src/game/Spell.h b/src/game/Spell.h index f621c2d41..5fd7e8490 100644 --- a/src/game/Spell.h +++ b/src/game/Spell.h @@ -381,7 +381,6 @@ class Spell void SetTargetMap(uint32 i,uint32 cur,UnitList& TagUnitMap); void FillAreaTargets( UnitList& TagUnitMap, float x, float y, float radius, SpellNotifyPushType pushType, SpellTargets spellTargets ); - Unit* SelectMagnetTarget(); bool CheckTarget( Unit* target, uint32 eff ); bool CanAutoCast(Unit* target); diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp index a02ea15a4..5da2d285c 100644 --- a/src/game/SpellAuras.cpp +++ b/src/game/SpellAuras.cpp @@ -145,7 +145,7 @@ pAuraHandler AuraHandler[TOTAL_AURAS]= &Aura::HandleModUnattackable, // 93 SPELL_AURA_MOD_UNATTACKABLE &Aura::HandleNoImmediateEffect, // 94 SPELL_AURA_INTERRUPT_REGEN implemented in Player::RegenerateAll &Aura::HandleAuraGhost, // 95 SPELL_AURA_GHOST - &Aura::HandleNoImmediateEffect, // 96 SPELL_AURA_SPELL_MAGNET implemented in Spell::SelectMagnetTarget + &Aura::HandleNoImmediateEffect, // 96 SPELL_AURA_SPELL_MAGNET implemented in Unit::SelectMagnetTarget &Aura::HandleManaShield, // 97 SPELL_AURA_MANA_SHIELD implemented in Unit::CalcAbsorbResist &Aura::HandleAuraModSkill, // 98 SPELL_AURA_MOD_SKILL_TALENT &Aura::HandleAuraModAttackPower, // 99 SPELL_AURA_MOD_ATTACK_POWER @@ -160,7 +160,7 @@ pAuraHandler AuraHandler[TOTAL_AURAS]= &Aura::HandleAddModifier, //108 SPELL_AURA_ADD_PCT_MODIFIER &Aura::HandleAddTargetTrigger, //109 SPELL_AURA_ADD_TARGET_TRIGGER &Aura::HandleModPowerRegenPCT, //110 SPELL_AURA_MOD_POWER_REGEN_PERCENT - &Aura::HandleNULL, //111 SPELL_AURA_ADD_CASTER_HIT_TRIGGER chance redirect attack to caster + &Aura::HandleNoImmediateEffect, //111 SPELL_AURA_ADD_CASTER_HIT_TRIGGER implemented in Unit::SelectMagnetTarget &Aura::HandleNoImmediateEffect, //112 SPELL_AURA_OVERRIDE_CLASS_SCRIPTS &Aura::HandleNoImmediateEffect, //113 SPELL_AURA_MOD_RANGED_DAMAGE_TAKEN implemented in Unit::MeleeDamageBonus &Aura::HandleNoImmediateEffect, //114 SPELL_AURA_MOD_RANGED_DAMAGE_TAKEN_PCT implemented in Unit::MeleeDamageBonus diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index d2779c97e..a9b3605e2 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -1961,6 +1961,9 @@ void Unit::AttackerStateUpdate (Unit *pVictim, WeaponAttackType attType, bool ex return; } + // attack can be redirected to another target + pVictim = SelectMagnetTarget(pVictim); + CalcDamageInfo damageInfo; CalculateMeleeDamage(pVictim, 0, &damageInfo, attType); // Send log damage message to client @@ -7420,6 +7423,34 @@ void Unit::UnsummonAllTotems() } } +Unit* Unit::SelectMagnetTarget(Unit *victim, SpellEntry const *spellInfo) +{ + if(!victim) + return NULL; + + // Magic case + if(spellInfo && (spellInfo->DmgClass == SPELL_DAMAGE_CLASS_NONE || spellInfo->DmgClass == SPELL_DAMAGE_CLASS_MAGIC)) + { + Unit::AuraList const& magnetAuras = victim->GetAurasByType(SPELL_AURA_SPELL_MAGNET); + for(Unit::AuraList::const_iterator itr = magnetAuras.begin(); itr != magnetAuras.end(); ++itr) + if(Unit* magnet = (*itr)->GetCaster()) + if(magnet->IsWithinLOSInMap(this) && magnet->isAlive()) + return magnet; + } + // Melee && ranged case + else + { + AuraList const& hitTriggerAuras = victim->GetAurasByType(SPELL_AURA_ADD_CASTER_HIT_TRIGGER); + for(AuraList::const_iterator i = hitTriggerAuras.begin(); i != hitTriggerAuras.end(); ++i) + if(Unit* magnet = (*i)->GetCaster()) + if(magnet->isAlive() && magnet->IsWithinLOSInMap(this)) + if(roll_chance_i((*i)->GetModifier()->m_amount)) + return magnet; + } + + return victim; +} + void Unit::SendHealSpellLog(Unit *pVictim, uint32 SpellID, uint32 Damage, bool critical) { // we guess size diff --git a/src/game/Unit.h b/src/game/Unit.h index e3ea874e7..69f01e527 100644 --- a/src/game/Unit.h +++ b/src/game/Unit.h @@ -1339,6 +1339,7 @@ class MANGOS_DLL_SPEC Unit : public WorldObject void ModifyAuraState(AuraState flag, bool apply); bool HasAuraState(AuraState flag) const { return HasFlag(UNIT_FIELD_AURASTATE, 1<<(flag-1)); } void UnsummonAllTotems(); + Unit* SelectMagnetTarget(Unit *victim, SpellEntry const *spellInfo = NULL); int32 SpellBaseDamageBonus(SpellSchoolMask schoolMask); int32 SpellBaseHealingBonus(SpellSchoolMask schoolMask); int32 SpellBaseDamageBonusForVictim(SpellSchoolMask schoolMask, Unit *pVictim); diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 606ac5ebf..2d2a4cb1c 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 "7685" + #define REVISION_NR "7686" #endif // __REVISION_NR_H__