Index: src/game/BattleGround.cpp =================================================================== --- src/game/BattleGround.cpp (revision 5333) +++ src/game/BattleGround.cpp (working copy) @@ -720,7 +720,7 @@ SpellEntry const *spellInfo = sSpellStore.LookupEntry( SPELL_WAITING_FOR_RESURRECT ); if(spellInfo) { - Aura *Aur = new Aura(spellInfo, 0, NULL, plr); + Aura *Aur = CreateAura(spellInfo, 0, NULL, plr); plr->AddAura(Aur); } } Index: src/game/Creature.cpp =================================================================== --- src/game/Creature.cpp (revision 5333) +++ src/game/Creature.cpp (working copy) @@ -1706,7 +1706,7 @@ continue; } - Aura* AdditionalAura = new Aura(AdditionalSpellInfo, cAura->effect_idx, NULL, this, this, 0); + Aura* AdditionalAura = CreateAura(AdditionalSpellInfo, cAura->effect_idx, NULL, this, this, 0); AddAura(AdditionalAura); sLog.outDebug("Spell: %u with Aura %u added to creature (GUIDLow: %u Entry: %u )", cAura->spell_id, AdditionalSpellInfo->EffectApplyAuraName[0],GetGUIDLow(),GetEntry()); } Index: src/game/Level3.cpp =================================================================== --- src/game/Level3.cpp (revision 5333) +++ src/game/Level3.cpp (working copy) @@ -2892,7 +2892,7 @@ else if (eff == SPELL_EFFECT_APPLY_AURA || eff == SPELL_EFFECT_PERSISTENT_AREA_AURA) { - Aura *Aur = new Aura(spellInfo, i, NULL, target); + Aura *Aur = CreateAura(spellInfo, i, NULL, target); target->AddAura(Aur); } } Index: src/game/Pet.cpp =================================================================== --- src/game/Pet.cpp (revision 5333) +++ src/game/Pet.cpp (working copy) @@ -1253,7 +1253,7 @@ if(spellproto->Effect[effindex] == SPELL_EFFECT_APPLY_AREA_AURA) aura = new AreaAura(spellproto, effindex, NULL, this, NULL); else - aura = new Aura(spellproto, effindex, NULL, this, NULL); + aura = CreateAura(spellproto, effindex, NULL, this, NULL); if(!damage) damage = aura->GetModifier()->m_amount; aura->SetLoadedState(caster_guid,damage,maxduration,remaintime,remaincharges); Index: src/game/Player.cpp =================================================================== --- src/game/Player.cpp (revision 5333) +++ src/game/Player.cpp (working copy) @@ -13023,7 +13023,7 @@ if(spellproto->Effect[effindex] == SPELL_EFFECT_APPLY_AREA_AURA) aura = new AreaAura(spellproto, effindex, NULL, this, NULL); else - aura = new Aura(spellproto, effindex, NULL, this, NULL); + aura = CreateAura(spellproto, effindex, NULL, this, NULL); if(!damage) damage = aura->GetModifier()->m_amount; aura->SetLoadedState(caster_guid,damage,maxduration,remaintime,remaincharges); Index: src/game/SpellAuras.cpp =================================================================== --- src/game/SpellAuras.cpp (revision 5333) +++ src/game/SpellAuras.cpp (working copy) @@ -429,6 +429,40 @@ { } +SingleEnemyTargetAura::SingleEnemyTargetAura(SpellEntry const* spellproto, uint32 eff, int32 *currentBasePoints, Unit *target, +Unit *caster, Item* castItem) : Aura(spellproto, eff, currentBasePoints, target, caster, castItem) +{ + if (caster) + m_casters_target_guid = caster->GetUInt64Value(UNIT_FIELD_TARGET); +} + +SingleEnemyTargetAura::~SingleEnemyTargetAura() +{ +} + +Unit* SingleEnemyTargetAura::GetTriggerTarget() const +{ + return ObjectAccessor::GetUnit(*m_target, m_casters_target_guid); +} + +Aura* CreateAura(SpellEntry const* spellproto, uint32 eff, int32 *currentBasePoints, Unit *target, Unit *caster, Item* castItem) +{ + uint32 triggeredSpellId = spellproto->EffectTriggerSpell[eff]; + + bool hasTargetSingleEnemy = false; + SpellEntry const* triggredSpellInfo = sSpellStore.LookupEntry(triggeredSpellId); + if (triggredSpellInfo) + { + for (int i = 0; i < 3; ++i) + hasTargetSingleEnemy |= (triggredSpellInfo->EffectImplicitTargetA[i] == TARGET_SINGLE_ENEMY); + } + + if (hasTargetSingleEnemy) + return new SingleEnemyTargetAura(spellproto, eff, currentBasePoints, target, caster, castItem); + else + return new Aura(spellproto, eff, currentBasePoints, target, caster, castItem); +} + Unit* Aura::GetCaster() const { if(m_caster_guid==m_target->GetGUID()) @@ -1055,7 +1089,7 @@ // generic casting code with custom spells and target/caster customs uint32 trigger_spell_id = GetSpellProto()->EffectTriggerSpell[m_effIndex]; Unit* caster = GetCaster(); - Unit* target = m_target; + Unit* target = GetTriggerTarget(); uint64 originalCasterGUID = GetCasterGUID(); // specific code for cases with no trigger spell provided in field @@ -1077,14 +1111,6 @@ case 29528: trigger_spell_id = 28713; break; // Inoculation case 29917: trigger_spell_id = 29916; break; // Feed Captured Animal - case 1515: // Tame Beast - { - // TODO: currently this used as hack for Tame beast triggered spell, - // BUT this can be correct way to provide target for ALL this function calls - // in case m_target==caster (or GetSpellProto()->EffectImplicitTargetA[m_effIndex]==TARGET_SELF ) - target = ObjectAccessor::GetUnit(*m_target, m_target->GetUInt64Value(UNIT_FIELD_TARGET)); - break; - } case 1010: // Curse of Idiocy { // TODO: spell casted by result in correct way mostly Index: src/game/SpellAuras.h =================================================================== --- src/game/SpellAuras.h (revision 5333) +++ src/game/SpellAuras.h (working copy) @@ -261,6 +261,8 @@ int32 m_procCharges; + virtual Unit* GetTriggerTarget() const { return m_target; } + // add/remove SPELL_AURA_MOD_SHAPESHIFT (36) linked auras void HandleShapeshiftBoosts(bool apply); protected: @@ -319,4 +321,18 @@ ~PersistentAreaAura(); void Update(uint32 diff); }; + +class MANGOS_DLL_SPEC SingleEnemyTargetAura : public Aura +{ + public: + SingleEnemyTargetAura(SpellEntry const* spellproto, uint32 eff, int32 *currentBasePoints, Unit *target, Unit *caster = NULL, Item* castItem = NULL); + ~SingleEnemyTargetAura(); + Unit* GetTriggerTarget() const; + + protected: + uint64 m_casters_target_guid; +}; + +Aura* CreateAura(SpellEntry const* spellproto, uint32 eff, int32 *currentBasePoints, Unit *target, Unit *caster = NULL, Item* castItem = NULL); + #endif Index: src/game/SpellEffects.cpp =================================================================== --- src/game/SpellEffects.cpp (revision 5333) +++ src/game/SpellEffects.cpp (working copy) @@ -1520,7 +1520,7 @@ sLog.outDebug("Spell: Aura is: %u", m_spellInfo->EffectApplyAuraName[i]); - Aura* Aur = new Aura(m_spellInfo, i, &m_currentBasePoints[i], unitTarget,m_caster, m_CastItem); + Aura* Aur = CreateAura(m_spellInfo, i, &m_currentBasePoints[i], unitTarget,m_caster, m_CastItem); if (!Aur->IsPositive() && Aur->GetCasterGUID() != Aur->GetTarget()->GetGUID()) { @@ -1640,31 +1640,11 @@ SpellEntry const *AdditionalSpellInfo = sSpellStore.LookupEntry(spellId); if (AdditionalSpellInfo) { - Aura* AdditionalAura = new Aura(AdditionalSpellInfo, 0, &m_currentBasePoints[0], unitTarget,m_caster, 0); + Aura* AdditionalAura = CreateAura(AdditionalSpellInfo, 0, &m_currentBasePoints[0], unitTarget,m_caster, 0); unitTarget->AddAura(AdditionalAura); sLog.outDebug("Spell: Additional Aura is: %u", AdditionalSpellInfo->EffectApplyAuraName[0]); } } - - // arcane missiles, do not affect tame beast - if(Aur->IsTrigger() && m_spellInfo->Id != 1515) - { - SpellEntry const *spellInfo = sSpellStore.LookupEntry(m_spellInfo->EffectTriggerSpell[i]); - if (!spellInfo) return; - if (m_caster->GetTypeId() == TYPEID_PLAYER && spellInfo->EffectImplicitTargetA[0] == TARGET_SINGLE_ENEMY) - { - Unit *target = ObjectAccessor::GetUnit(*m_caster, ((Player*)m_caster)->GetSelection()); - if (target) - { - if (!m_caster->IsFriendlyTo(target)) - Aur->SetTarget(target); - else - cancel(); - } - else - cancel(); - } - } } void Spell::EffectUnlearnSpecialization( uint32 i ) @@ -4799,7 +4779,7 @@ int32 basePoints = aur->GetBasePoints(); // construct the new aura for the attacker - Aura * new_aur = new Aura(aur->GetSpellProto(), i, &basePoints, m_caster); + Aura * new_aur = CreateAura(aur->GetSpellProto(), i, &basePoints, m_caster); if(!new_aur) continue; Index: src/game/SpellMgr.cpp =================================================================== --- src/game/SpellMgr.cpp (revision 5333) +++ src/game/SpellMgr.cpp (working copy) @@ -1524,4 +1524,4 @@ return true; return false; -} +} \ No newline at end of file Index: src/game/SpellMgr.h =================================================================== --- src/game/SpellMgr.h (revision 5333) +++ src/game/SpellMgr.h (working copy) @@ -106,6 +106,8 @@ bool CanUsedWhileStealthed(uint32 spellId); bool IsMechanicInvulnerabilityImmunityToSpell(SpellEntry const* spellInfo); +bool IsTargetSingleEnemyAura(SpellEntry const* spellInfo, uint8 effectId); + // Spell affects related declarations (accessed using SpellMgr functions) struct SpellAffection {