aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/game/Spell.cpp45
-rw-r--r--src/game/Spell.h1
-rw-r--r--src/game/SpellAuras.cpp4
-rw-r--r--src/game/Unit.cpp37
-rw-r--r--src/game/Unit.h1
5 files changed, 48 insertions, 40 deletions
diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp
index 69ac197f6be..2656e1af3c5 100644
--- a/src/game/Spell.cpp
+++ b/src/game/Spell.cpp
@@ -1569,6 +1569,11 @@ void Spell::SetTargetMap(uint32 i,uint32 cur,std::list<Unit*> &TagUnitMap)
break;
}
+ if(!IsPositiveSpell(m_spellInfo->Id))
+ if(Unit *magnet = m_caster->SelectMagnetTarget(target))
+ if(magnet != target)
+ m_targets.setUnitTarget(magnet);
+
switch(cur)
{
case TARGET_UNIT_MINIPET:
@@ -1577,7 +1582,7 @@ void Spell::SetTargetMap(uint32 i,uint32 cur,std::list<Unit*> &TagUnitMap)
break;
case TARGET_UNIT_TARGET_ALLY:
case TARGET_UNIT_TARGET_RAID:
- case TARGET_UNIT_TARGET_ANY: // SelectMagnetTarget()?
+ case TARGET_UNIT_TARGET_ANY:
case TARGET_UNIT_TARGET_PARTY:
TagUnitMap.push_back(target);
break;
@@ -1586,8 +1591,8 @@ void Spell::SetTargetMap(uint32 i,uint32 cur,std::list<Unit*> &TagUnitMap)
break;
case TARGET_UNIT_TARGET_ENEMY:
if(EffectChainTarget <= 1)
- TagUnitMap.push_back(SelectMagnetTarget());
- else if(SelectMagnetTarget()) //TODO: chain target should also use magnet target
+ TagUnitMap.push_back(target);
+ else
SearchChainTarget(TagUnitMap, radius_h, EffectChainTarget, SPELL_TARGETS_ENEMY);
break;
case TARGET_UNIT_CHAINHEAL:
@@ -5384,40 +5389,6 @@ bool Spell::CheckTarget( Unit* target, uint32 eff )
return true;
}
-Unit* Spell::SelectMagnetTarget()
-{
- Unit* target = m_targets.getUnitTarget();
-
- if(target && m_spellInfo->DmgClass == SPELL_DAMAGE_CLASS_MAGIC && target->HasAuraType(SPELL_AURA_SPELL_MAGNET)) //Attributes & 0x10 what is this?
- {
- Unit::AuraEffectList const& magnetAuras = target->GetAurasByType(SPELL_AURA_SPELL_MAGNET);
- for(Unit::AuraEffectList::const_iterator itr = magnetAuras.begin(); itr != magnetAuras.end(); ++itr)
- {
- if(Unit* magnet = (*itr)->GetCaster())
- {
- if((*itr)->GetParentAura()->DropAuraCharge())
- {
- target = magnet;
- m_targets.setUnitTarget(target);
- AddUnitTarget(target, 0);
- uint64 targetGUID = target->GetGUID();
- for(std::list<TargetInfo>::iterator ihit= m_UniqueTargetInfo.begin();ihit != m_UniqueTargetInfo.end();++ihit)
- {
- if (targetGUID == ihit->targetGUID) // Found in list
- {
- (*ihit).damage = target->GetHealth();
- break;
- }
- }
- 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 f5ee99fe171..660ab8f53a7 100644
--- a/src/game/Spell.h
+++ b/src/game/Spell.h
@@ -405,7 +405,6 @@ class Spell
void SetTargetMap(uint32 i,uint32 cur,std::list<Unit*> &TagUnitMap);
- 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 e3a920866f7..e394f9a18ca 100644
--- a/src/game/SpellAuras.cpp
+++ b/src/game/SpellAuras.cpp
@@ -147,7 +147,7 @@ pAuraHandler AuraHandler[TOTAL_AURAS]=
&AuraEffect::HandleModUnattackable, // 93 SPELL_AURA_MOD_UNATTACKABLE
&AuraEffect::HandleNoImmediateEffect, // 94 SPELL_AURA_INTERRUPT_REGEN implemented in Player::RegenerateAll
&AuraEffect::HandleAuraGhost, // 95 SPELL_AURA_GHOST
- &AuraEffect::HandleNoImmediateEffect, // 96 SPELL_AURA_SPELL_MAGNET implemented in Spell::SelectMagnetTarget
+ &AuraEffect::HandleNoImmediateEffect, // 96 SPELL_AURA_SPELL_MAGNET implemented in Unit::SelectMagnetTarget
&AuraEffect::HandleManaShield, // 97 SPELL_AURA_MANA_SHIELD implemented in Unit::CalcAbsorbResist
&AuraEffect::HandleAuraModSkill, // 98 SPELL_AURA_MOD_SKILL_TALENT
&AuraEffect::HandleAuraModAttackPower, // 99 SPELL_AURA_MOD_ATTACK_POWER
@@ -162,7 +162,7 @@ pAuraHandler AuraHandler[TOTAL_AURAS]=
&AuraEffect::HandleAddModifier, //108 SPELL_AURA_ADD_PCT_MODIFIER
&AuraEffect::HandleAddTargetTrigger, //109 SPELL_AURA_ADD_TARGET_TRIGGER
&AuraEffect::HandleModPowerRegenPCT, //110 SPELL_AURA_MOD_POWER_REGEN_PERCENT
- &AuraEffect::HandleNULL, //111 SPELL_AURA_ADD_CASTER_HIT_TRIGGER chance redirect attack to caster
+ &AuraEffect::HandleNoImmediateEffect, //111 SPELL_AURA_ADD_CASTER_HIT_TRIGGER implemented in Unit::SelectMagnetTarget
&AuraEffect::HandleNoImmediateEffect, //112 SPELL_AURA_OVERRIDE_CLASS_SCRIPTS
&AuraEffect::HandleNoImmediateEffect, //113 SPELL_AURA_MOD_RANGED_DAMAGE_TAKEN implemented in Unit::MeleeDamageBonus
&AuraEffect::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 2dca6c45491..f9c5d5c4d6f 100644
--- a/src/game/Unit.cpp
+++ b/src/game/Unit.cpp
@@ -2266,6 +2266,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
@@ -8175,6 +8178,40 @@ void Unit::SetCharm(Unit* charm, bool apply)
}
}
+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))
+ {
+ //I am not sure if this should be redirected.
+ if(spellInfo->DmgClass == SPELL_DAMAGE_CLASS_NONE)
+ return victim;
+
+ //if((*itr)->GetParentAura()->DropAuraCharge())
+
+ 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->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;
+}
+
Unit* Unit::GetFirstControlled() const
{
//Sequence: charmed, pet, other guardians
diff --git a/src/game/Unit.h b/src/game/Unit.h
index e49f07c0fcb..c52090b97d1 100644
--- a/src/game/Unit.h
+++ b/src/game/Unit.h
@@ -1499,6 +1499,7 @@ class TRINITY_DLL_SPEC Unit : public WorldObject
void ModifyAuraState(AuraState flag, bool apply);
bool HasAuraState(AuraState flag, SpellEntry const *spellProto = NULL, Unit * Caster = NULL) const ;
void UnsummonAllTotems();
+ Unit* SelectMagnetTarget(Unit *victim, SpellEntry const *spellInfo = NULL);
int32 SpellBaseDamageBonus(SpellSchoolMask schoolMask);
int32 SpellBaseHealingBonus(SpellSchoolMask schoolMask);
int32 SpellBaseDamageBonusForVictim(SpellSchoolMask schoolMask, Unit *pVictim);