aboutsummaryrefslogtreecommitdiff
path: root/src/game/Unit.cpp
diff options
context:
space:
mode:
authormegamage <none@none>2008-11-17 19:39:24 -0600
committermegamage <none@none>2008-11-17 19:39:24 -0600
commit18dff69c555ab2bd4bbccb002a0995ba6353550e (patch)
treec7d7446543a6b5e8f9047270de8af7320f480e27 /src/game/Unit.cpp
parent474dc08c465b3360a9f578a0df65bb8d2feb9fcd (diff)
*Merge from Mangos
*[6833] More correct aura cancel for channeled spells. By VladimirMangos. *[6820] Cleanup spell proc event code. Avoid send same information by 2 ways to function. By VladimirMangos. --HG-- branch : trunk
Diffstat (limited to 'src/game/Unit.cpp')
-rw-r--r--src/game/Unit.cpp373
1 files changed, 205 insertions, 168 deletions
diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp
index 22249af36d6..e0345950ffc 100644
--- a/src/game/Unit.cpp
+++ b/src/game/Unit.cpp
@@ -4094,12 +4094,17 @@ void Unit::RemoveNotOwnSingleTargetAuras()
void Unit::RemoveAura(AuraMap::iterator &i, AuraRemoveMode mode)
{
- if (IsSingleTargetSpell((*i).second->GetSpellProto()))
+ Aura* Aur = i->second;
+ SpellEntry const* AurSpellInfo = Aur->GetSpellProto();
+
+ Unit* caster = NULL;
+ if (IsSingleTargetSpell(AurSpellInfo))
{
- if(Unit* caster = (*i).second->GetCaster())
+ caster = Aur->GetCaster();
+ if(caster)
{
AuraList& scAuras = caster->GetSingleCastAuras();
- scAuras.remove((*i).second);
+ scAuras.remove(Aur);
}
else
{
@@ -4108,20 +4113,19 @@ void Unit::RemoveAura(AuraMap::iterator &i, AuraRemoveMode mode)
}
}
- if ((*i).second->GetModifier()->m_auraname < TOTAL_AURAS)
+ // remove from list before mods removing (prevent cyclic calls, mods added before including to aura list - use reverse order)
+ if (Aur->GetModifier()->m_auraname < TOTAL_AURAS)
{
- m_modAuras[(*i).second->GetModifier()->m_auraname].remove((*i).second);
- if((*i).second->GetSpellProto()->AuraInterruptFlags)
+ m_modAuras[Aur->GetModifier()->m_auraname].remove(Aur);
+ if(Aur->GetSpellProto()->AuraInterruptFlags)
{
- m_interruptableAuras.remove((*i).second);
+ m_interruptableAuras.remove(Aur);
UpdateInterruptMask();
}
- if((*i).second->GetSpellProto()->Attributes & SPELL_ATTR_BREAKABLE_BY_DAMAGE)
- m_ccAuras.remove((*i).second);
+ if(Aur->GetSpellProto()->Attributes & SPELL_ATTR_BREAKABLE_BY_DAMAGE)
+ m_ccAuras.remove(Aur);
}
- // remove from list before mods removing (prevent cyclic calls, mods added before including to aura list - use reverse order)
- Aura* Aur = i->second;
// Set remove mode
Aur->SetRemoveMode(mode);
// some ShapeshiftBoosts at remove trigger removing other auras including parent Shapeshift aura
@@ -4129,12 +4133,22 @@ void Unit::RemoveAura(AuraMap::iterator &i, AuraRemoveMode mode)
m_Auras.erase(i);
++m_removedAuras; // internal count used by unit update
- // Status unsummoned at aura remove
+ // Statue unsummoned at aura remove
Totem* statue = NULL;
- if(IsChanneledSpell(Aur->GetSpellProto()))
- if(Unit* caster = Aur->GetCaster())
+ bool caster_channeled = false;
+ if(IsChanneledSpell(AurSpellInfo))
+ {
+ if(!caster) // can be already located for IsSingleTargetSpell case
+ caster = Aur->GetCaster();
+
+ if(caster)
+ {
if(caster->GetTypeId()==TYPEID_UNIT && ((Creature*)caster)->isTotem() && ((Totem*)caster)->GetTotemType()==TOTEM_STATUE)
statue = ((Totem*)caster);
+ else
+ caster_channeled = caster==this;
+ }
+ }
if(const std::vector<int32> *spell_triggered = spellmgr.GetSpellLinked(-(int32)Aur->GetSpellProto()->Id))
@@ -4153,6 +4167,9 @@ void Unit::RemoveAura(AuraMap::iterator &i, AuraRemoveMode mode)
Aur->_RemoveAura();
delete Aur;
+ if(caster_channeled)
+ RemoveAurasAtChanneledTarget (AurSpellInfo);
+
if(statue)
statue->UnSummon();
@@ -4578,8 +4595,10 @@ void Unit::CastMeleeProcDamageAndSpell(Unit* pVictim, uint32 damage, SpellSchool
ProcDamageAndSpell(pVictim, procAttacker, procVictim, damage, damageSchoolMask, spellCasted, isTriggeredSpell, attType);
}
-bool Unit::HandleHasteAuraProc(Unit *pVictim, SpellEntry const *hasteSpell, uint32 /*effIndex*/, uint32 damage, Aura* triggeredByAura, SpellEntry const * procSpell, uint32 /*procFlag*/, uint32 cooldown)
+bool Unit::HandleHasteAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAura, SpellEntry const * /*procSpell*/, uint32 /*procFlag*/, uint32 cooldown)
{
+ SpellEntry const *hasteSpell = triggeredByAura->GetSpellProto();
+
Item* castItem = triggeredByAura->GetCastItemGUID() && GetTypeId()==TYPEID_PLAYER
? ((Player*)this)->GetItemByGuid(triggeredByAura->GetCastItemGUID()) : NULL;
@@ -4639,8 +4658,11 @@ bool Unit::HandleHasteAuraProc(Unit *pVictim, SpellEntry const *hasteSpell, uint
return true;
}
-bool Unit::HandleDummyAuraProc(Unit *pVictim, SpellEntry const *dummySpell, uint32 effIndex, uint32 damage, Aura* triggeredByAura, SpellEntry const * procSpell, uint32 procFlag, uint32 cooldown)
+bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAura, SpellEntry const * procSpell, uint32 procFlag, uint32 cooldown)
{
+ SpellEntry const *dummySpell = triggeredByAura->GetSpellProto ();
+ uint32 effIndex = triggeredByAura->GetEffIndex ();
+
Item* castItem = triggeredByAura->GetCastItemGUID() && GetTypeId()==TYPEID_PLAYER
? ((Player*)this)->GetItemByGuid(triggeredByAura->GetCastItemGUID()) : NULL;
@@ -6458,8 +6480,10 @@ bool Unit::HandleProcTriggerSpell(Unit *pVictim, uint32 damage, Aura* triggeredB
return true;
}
-bool Unit::HandleOverrideClassScriptAuraProc(Unit *pVictim, int32 scriptId, uint32 damage, Aura *triggeredByAura, SpellEntry const *procSpell, uint32 cooldown)
+bool Unit::HandleOverrideClassScriptAuraProc(Unit *pVictim, Aura *triggeredByAura, SpellEntry const *procSpell, uint32 cooldown)
{
+ int32 scriptId = triggeredByAura->GetModifier()->m_miscvalue;
+
if(!pVictim || !pVictim->isAlive())
return false;
@@ -9923,17 +9947,15 @@ bool Unit::isFrozen() const
struct ProcTriggeredData
{
- ProcTriggeredData(SpellEntry const * _spellInfo, uint32 _spellParam, Aura* _triggeredByAura, uint32 _cooldown)
- : spellInfo(_spellInfo), spellParam(_spellParam), triggeredByAura(_triggeredByAura),
+ ProcTriggeredData(Aura* _triggeredByAura, uint32 _cooldown)
+ : triggeredByAura(_triggeredByAura),
triggeredByAura_SpellPair(Unit::spellEffectPair(triggeredByAura->GetId(),triggeredByAura->GetEffIndex())),
cooldown(_cooldown)
- {}
+ {}
- SpellEntry const * spellInfo;
- uint32 spellParam;
- Aura* triggeredByAura;
- Unit::spellEffectPair triggeredByAura_SpellPair;
- uint32 cooldown;
+ Aura* triggeredByAura; // triggred aura, can be invalidate at triggered aura proccessing
+ Unit::spellEffectPair triggeredByAura_SpellPair; // spell pair, used for re-find aura (by pointer comparison in range)
+ uint32 cooldown; // possible hidden cooldown
};
typedef std::list< ProcTriggeredData > ProcTriggeredList;
@@ -9950,87 +9972,13 @@ void Unit::ProcDamageAndSpellFor( bool isVictim, Unit * pTarget, uint32 procFlag
{
next = i; ++next;
- SpellEntry const *spellProto = (*i)->GetSpellProto();
- if(!spellProto)
- continue;
+ Aura* i_aura = *i;
- SpellProcEventEntry const *spellProcEvent = spellmgr.GetSpellProcEvent(spellProto->Id);
- if(!spellProcEvent)
- {
- // used to prevent spam in log about same non-handled spells
- static std::set<uint32> nonHandledSpellProcSet;
-
- if(spellProto->procFlags != 0 && nonHandledSpellProcSet.find(spellProto->Id)==nonHandledSpellProcSet.end())
- {
- sLog.outError("ProcDamageAndSpell: spell %u (%s aura source) not have record in `spell_proc_event`)",spellProto->Id,(isVictim?"a victim's":"an attacker's"));
- nonHandledSpellProcSet.insert(spellProto->Id);
- }
-
- // spell.dbc use totally different flags, that only can create problems if used.
+ uint32 cooldown; // returned at next line
+ if(!IsTriggeredAtSpellProcEvent(i_aura->GetSpellProto(), procSpell, procFlag,attType,isVictim,cooldown))
continue;
- }
- // Check spellProcEvent data requirements
- if(!SpellMgr::IsSpellProcEventCanTriggeredBy(spellProcEvent, procSpell,procFlag))
- continue;
-
- // Check if current equipment allows aura to proc
- if(!isVictim && GetTypeId() == TYPEID_PLAYER )
- {
- if(spellProto->EquippedItemClass == ITEM_CLASS_WEAPON)
- {
- Item *item = ((Player*)this)->GetWeaponForAttack(attType,true);
-
- if(!item || !((1<<item->GetProto()->SubClass) & spellProto->EquippedItemSubClassMask))
- continue;
- }
- else if(spellProto->EquippedItemClass == ITEM_CLASS_ARMOR)
- {
- // Check if player is wearing shield
- Item *item = ((Player*)this)->GetShield(true);
- if(!item || !((1<<item->GetProto()->SubClass) & spellProto->EquippedItemSubClassMask))
- continue;
- }
- }
-
- float chance = (float)spellProto->procChance;
-
- if(Player* modOwner = GetSpellModOwner())
- modOwner->ApplySpellMod(spellProto->Id,SPELLMOD_CHANCE_OF_SUCCESS,chance);
-
- if(!isVictim && spellProcEvent->ppmRate != 0)
- {
- uint32 WeaponSpeed = GetAttackTime(attType);
- chance = GetPPMProcChance(WeaponSpeed, spellProcEvent->ppmRate);
- }
-
- if(roll_chance_f(chance))
- {
- uint32 cooldown = spellProcEvent->cooldown;
-
- uint32 i_spell_eff = (*i)->GetEffIndex();
-
- int32 i_spell_param;
- switch(*aur)
- {
- case SPELL_AURA_PROC_TRIGGER_SPELL:
- i_spell_param = procFlag;
- break;
- case SPELL_AURA_DUMMY:
- case SPELL_AURA_PRAYER_OF_MENDING:
- case SPELL_AURA_MOD_HASTE:
- i_spell_param = i_spell_eff;
- break;
- case SPELL_AURA_OVERRIDE_CLASS_SCRIPTS:
- i_spell_param = (*i)->GetModifier()->m_miscvalue;
- break;
- default:
- i_spell_param = (*i)->GetModifier()->m_amount;
- break;
- }
-
- procTriggered.push_back( ProcTriggeredData(spellProto,i_spell_param,*i, cooldown) );
- }
+ procTriggered.push_back( ProcTriggeredData(i_aura, cooldown) );
}
// Handle effects proceed this time
@@ -10063,106 +10011,66 @@ void Unit::ProcDamageAndSpellFor( bool isVictim, Unit * pTarget, uint32 procFlag
}
}
+ // this is aura triggering code call
+ Aura* triggeredByAura = i->triggeredByAura;
+
// save charges existence before processing to prevent crash at access to deleted triggered aura after
- bool triggeredByAuraWithCharges = i->triggeredByAura->m_procCharges > 0;
+ bool triggeredByAuraWithCharges = triggeredByAura->m_procCharges > 0;
bool casted = false;
switch(*aur)
{
case SPELL_AURA_PROC_TRIGGER_SPELL:
{
- sLog.outDebug("ProcDamageAndSpell: casting spell %u (triggered by %s aura of spell %u)", i->spellInfo->Id,(isVictim?"a victim's":"an attacker's"),i->triggeredByAura->GetId());
- casted = HandleProcTriggerSpell(pTarget, damage, i->triggeredByAura, procSpell,i->spellParam,attType,i->cooldown);
+ sLog.outDebug("ProcDamageAndSpell: casting spell (triggered by %s proc aura of spell %u)",
+ (isVictim?"a victim's":"an attacker's"),i->triggeredByAura->GetId());
+ casted = HandleProcTriggerSpell(pTarget, damage, triggeredByAura, procSpell, procFlag, attType, i->cooldown);
break;
}
case SPELL_AURA_PROC_TRIGGER_DAMAGE:
{
- sLog.outDebug("ProcDamageAndSpell: doing %u damage from spell id %u (triggered by %s aura of spell %u)", i->spellParam, i->spellInfo->Id,(isVictim?"a victim's":"an attacker's"),i->triggeredByAura->GetId());
- uint32 damage = i->spellParam;
- SpellNonMeleeDamageLog(pTarget, i->spellInfo->Id, damage, true, true);
+ uint32 triggered_damage = triggeredByAura->GetModifier()->m_amount;
+ sLog.outDebug("ProcDamageAndSpell: doing %u damage (triggered by %s aura of spell %u)",
+ triggered_damage, (isVictim?"a victim's":"an attacker's"),triggeredByAura->GetId());
+ SpellNonMeleeDamageLog(pTarget, triggeredByAura->GetId(), triggered_damage, true, true);
casted = true;
break;
}
case SPELL_AURA_DUMMY:
{
- sLog.outDebug("ProcDamageAndSpell: casting spell id %u (triggered by %s dummy aura of spell %u)", i->spellInfo->Id,(isVictim?"a victim's":"an attacker's"),i->triggeredByAura->GetId());
- casted = HandleDummyAuraProc(pTarget, i->spellInfo, i->spellParam, damage, i->triggeredByAura, procSpell, procFlag,i->cooldown);
+ uint32 effect = triggeredByAura->GetEffIndex();
+ sLog.outDebug("ProcDamageAndSpell: casting spell (triggered by %s dummy aura of spell %u)",
+ (isVictim?"a victim's":"an attacker's"),triggeredByAura->GetId());
+ casted = HandleDummyAuraProc(pTarget, damage, triggeredByAura, procSpell, procFlag,i->cooldown);
break;
}
case SPELL_AURA_PRAYER_OF_MENDING:
{
- sLog.outDebug("ProcDamageAndSpell(mending): casting spell id %u (triggered by %s dummy aura of spell %u)", i->spellInfo->Id,(isVictim?"a victim's":"an attacker's"),i->triggeredByAura->GetId());
-
- // aura can be deleted at casts
- int32 heal = i->triggeredByAura->GetModifier()->m_amount;
- uint64 caster_guid = i->triggeredByAura->GetCasterGUID();
-
- // jumps
- int32 jumps = i->triggeredByAura->m_procCharges-1;
-
- // current aura expire
- i->triggeredByAura->m_procCharges = 1; // will removed at next charges decrease
-
- // next target selection
- if(jumps > 0 && GetTypeId()==TYPEID_PLAYER && IS_PLAYER_GUID(caster_guid))
- {
- Aura* aura = i->triggeredByAura;
-
- SpellEntry const* spellProto = aura->GetSpellProto();
- uint32 effIdx = aura->GetEffIndex();
-
- float radius;
- if (spellProto->EffectRadiusIndex[effIdx])
- radius = GetSpellRadius(sSpellRadiusStore.LookupEntry(spellProto->EffectRadiusIndex[effIdx]));
- else
- radius = GetSpellMaxRange(sSpellRangeStore.LookupEntry(spellProto->rangeIndex));
+ sLog.outDebug("ProcDamageAndSpell: casting mending (triggered by %s dummy aura of spell %u)",
+ (isVictim?"a victim's":"an attacker's"),triggeredByAura->GetId());
- if(Player* caster = ((Player*)aura->GetCaster()))
- {
- caster->ApplySpellMod(spellProto->Id, SPELLMOD_RADIUS, radius,NULL);
-
- if(Player* target = ((Player*)this)->GetNextRandomRaidMember(radius))
- {
- // aura will applied from caster, but spell casted from current aura holder
- SpellModifier *mod = new SpellModifier;
- mod->op = SPELLMOD_CHARGES;
- mod->value = jumps-5; // negative
- mod->type = SPELLMOD_FLAT;
- mod->spellId = spellProto->Id;
- mod->effectId = effIdx;
- mod->lastAffected = NULL;
- mod->mask = spellProto->SpellFamilyFlags;
- mod->charges = 0;
-
- caster->AddSpellMod(mod, true);
- CastCustomSpell(target,spellProto->Id,&heal,NULL,NULL,true,NULL,aura,caster->GetGUID());
- caster->AddSpellMod(mod, false);
- }
- }
- }
-
- // heal
- CastCustomSpell(this,33110,&heal,NULL,NULL,true,NULL,NULL,caster_guid);
- casted = true;
+ casted = HandleMeandingAuraProc(triggeredByAura);
break;
}
case SPELL_AURA_MOD_HASTE:
{
- sLog.outDebug("ProcDamageAndSpell: casting spell id %u (triggered by %s haste aura of spell %u)", i->spellInfo->Id,(isVictim?"a victim's":"an attacker's"),i->triggeredByAura->GetId());
- casted = HandleHasteAuraProc(pTarget, i->spellInfo, i->spellParam, damage, i->triggeredByAura, procSpell, procFlag,i->cooldown);
+ sLog.outDebug("ProcDamageAndSpell: casting spell (triggered by %s haste aura of spell %u)",
+ (isVictim?"a victim's":"an attacker's"),triggeredByAura->GetId());
+ casted = HandleHasteAuraProc(pTarget, damage, i->triggeredByAura, procSpell, procFlag,i->cooldown);
break;
}
case SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN:
{
// nothing do, just charges counter
// but count only in case appropriate school damage
- casted = i->triggeredByAura->GetModifier()->m_miscvalue & damageSchoolMask;
+ casted = triggeredByAura->GetModifier()->m_miscvalue & damageSchoolMask;
break;
}
case SPELL_AURA_OVERRIDE_CLASS_SCRIPTS:
{
- sLog.outDebug("ProcDamageAndSpell: casting spell id %u (triggered by %s aura of spell %u)", i->spellInfo->Id,(isVictim?"a victim's":"an attacker's"),i->triggeredByAura->GetId());
- casted = HandleOverrideClassScriptAuraProc(pTarget, i->spellParam, damage, i->triggeredByAura, procSpell,i->cooldown);
+ sLog.outDebug("ProcDamageAndSpell: casting spell id %u (triggered by %s class script aura of spell %u)",
+ (isVictim?"a victim's":"an attacker's"),triggeredByAura->GetId());
+ casted = HandleOverrideClassScriptAuraProc(pTarget, i->triggeredByAura, procSpell,i->cooldown);
break;
}
default:
@@ -10810,3 +10718,132 @@ Pet* Unit::CreateTamedPetFrom(Creature* creatureTarget,uint32 spell_id)
return pet;
}
+
+bool Unit::IsTriggeredAtSpellProcEvent(SpellEntry const* spellProto, SpellEntry const* procSpell, uint32 procFlag, WeaponAttackType attType, bool isVictim, uint32& cooldown )
+{
+ SpellProcEventEntry const * spellProcEvent = spellmgr.GetSpellProcEvent(spellProto->Id);
+
+ if(!spellProcEvent)
+ {
+ // used to prevent spam in log about same non-handled spells
+ static std::set<uint32> nonHandledSpellProcSet;
+
+ if(spellProto->procFlags != 0 && nonHandledSpellProcSet.find(spellProto->Id)==nonHandledSpellProcSet.end())
+ {
+ sLog.outError("ProcDamageAndSpell: spell %u (%s aura source) not have record in `spell_proc_event`)",spellProto->Id,(isVictim?"a victim's":"an attacker's"));
+ nonHandledSpellProcSet.insert(spellProto->Id);
+ }
+
+ // spell.dbc use totally different flags, that only can create problems if used.
+ return false;
+ }
+
+ // Check spellProcEvent data requirements
+ if(!SpellMgr::IsSpellProcEventCanTriggeredBy(spellProcEvent, procSpell,procFlag))
+ return false;
+
+ // Check if current equipment allows aura to proc
+ if(!isVictim && GetTypeId() == TYPEID_PLAYER )
+ {
+ if(spellProto->EquippedItemClass == ITEM_CLASS_WEAPON)
+ {
+ Item *item = ((Player*)this)->GetWeaponForAttack(attType,true);
+
+ if(!item || !((1<<item->GetProto()->SubClass) & spellProto->EquippedItemSubClassMask))
+ return false;
+ }
+ else if(spellProto->EquippedItemClass == ITEM_CLASS_ARMOR)
+ {
+ // Check if player is wearing shield
+ Item *item = ((Player*)this)->GetShield(true);
+ if(!item || !((1<<item->GetProto()->SubClass) & spellProto->EquippedItemSubClassMask))
+ return false;
+ }
+ }
+
+ float chance = (float)spellProto->procChance;
+
+ if(Player* modOwner = GetSpellModOwner())
+ modOwner->ApplySpellMod(spellProto->Id,SPELLMOD_CHANCE_OF_SUCCESS,chance);
+
+ if(!isVictim && spellProcEvent && spellProcEvent->ppmRate != 0)
+ {
+ uint32 WeaponSpeed = GetAttackTime(attType);
+ chance = GetPPMProcChance(WeaponSpeed, spellProcEvent->ppmRate);
+ }
+
+ cooldown = spellProcEvent ? spellProcEvent->cooldown : 0;
+ return roll_chance_f(chance);
+}
+
+bool Unit::HandleMeandingAuraProc( Aura* triggeredByAura )
+{
+ // aura can be deleted at casts
+ SpellEntry const* spellProto = triggeredByAura->GetSpellProto();
+ uint32 effIdx = triggeredByAura->GetEffIndex();
+ int32 heal = triggeredByAura->GetModifier()->m_amount;
+ uint64 caster_guid = triggeredByAura->GetCasterGUID();
+
+ // jumps
+ int32 jumps = triggeredByAura->m_procCharges-1;
+
+ // current aura expire
+ triggeredByAura->m_procCharges = 1; // will removed at next charges decrease
+
+ // next target selection
+ if(jumps > 0 && GetTypeId()==TYPEID_PLAYER && IS_PLAYER_GUID(caster_guid))
+ {
+ float radius;
+ if (spellProto->EffectRadiusIndex[effIdx])
+ radius = GetSpellRadius(sSpellRadiusStore.LookupEntry(spellProto->EffectRadiusIndex[effIdx]));
+ else
+ radius = GetSpellMaxRange(sSpellRangeStore.LookupEntry(spellProto->rangeIndex));
+
+ if(Player* caster = ((Player*)triggeredByAura->GetCaster()))
+ {
+ caster->ApplySpellMod(spellProto->Id, SPELLMOD_RADIUS, radius,NULL);
+
+ if(Player* target = ((Player*)this)->GetNextRandomRaidMember(radius))
+ {
+ // aura will applied from caster, but spell casted from current aura holder
+ SpellModifier *mod = new SpellModifier;
+ mod->op = SPELLMOD_CHARGES;
+ mod->value = jumps-5; // negative
+ mod->type = SPELLMOD_FLAT;
+ mod->spellId = spellProto->Id;
+ mod->effectId = effIdx;
+ mod->lastAffected = NULL;
+ mod->mask = spellProto->SpellFamilyFlags;
+ mod->charges = 0;
+
+ caster->AddSpellMod(mod, true);
+ CastCustomSpell(target,spellProto->Id,&heal,NULL,NULL,true,NULL,triggeredByAura,caster->GetGUID());
+ caster->AddSpellMod(mod, false);
+ }
+ }
+ }
+
+ // heal
+ CastCustomSpell(this,33110,&heal,NULL,NULL,true,NULL,NULL,caster_guid);
+ return true;
+}
+
+void Unit::RemoveAurasAtChanneledTarget(SpellEntry const* spellInfo)
+{
+ uint64 target_guid = GetUInt64Value(UNIT_FIELD_CHANNEL_OBJECT);
+
+ if(!IS_UNIT_GUID(target_guid))
+ return;
+
+ Unit* target = ObjectAccessor::GetUnit(*this, target_guid);
+ if(!target)
+ return;
+
+ for (AuraMap::iterator iter = target->GetAuras().begin(); iter != target->GetAuras().end(); )
+ {
+ if (iter->second->GetId() == spellInfo->Id && iter->second->GetCasterGUID()==GetGUID())
+ target->RemoveAura(iter);
+ else
+ ++iter;
+ }
+} \ No newline at end of file