root/trunk/src/game/SpellAuras.cpp @ 277

Revision 274, 247.7 kB (checked in by yumileroy, 17 years ago)

* Implemented new summon possessed summon type for spell 49352.
* Unsummon all summon possessed units on summoning aura cancel.

Original author: gvcoman
Date: 2008-11-17 18:57:16-05:00

Line 
1/*
2 * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
3 *
4 * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19 */
20
21#include "Common.h"
22#include "Database/DatabaseEnv.h"
23#include "WorldPacket.h"
24#include "WorldSession.h"
25#include "Opcodes.h"
26#include "Log.h"
27#include "UpdateMask.h"
28#include "World.h"
29#include "ObjectMgr.h"
30#include "SpellMgr.h"
31#include "Player.h"
32#include "Unit.h"
33#include "Spell.h"
34#include "SpellAuras.h"
35#include "DynamicObject.h"
36#include "Group.h"
37#include "UpdateData.h"
38#include "MapManager.h"
39#include "ObjectAccessor.h"
40#include "Policies/SingletonImp.h"
41#include "Totem.h"
42#include "Creature.h"
43#include "Formulas.h"
44#include "BattleGround.h"
45#include "OutdoorPvP.h"
46#include "OutdoorPvPMgr.h"
47#include "CreatureAI.h"
48#include "Util.h"
49#include "GridNotifiers.h"
50#include "GridNotifiersImpl.h"
51#include "CellImpl.h"
52
53#define NULL_AURA_SLOT 0xFF
54
55pAuraHandler AuraHandler[TOTAL_AURAS]=
56{
57    &Aura::HandleNULL,                                      //  0 SPELL_AURA_NONE
58    &Aura::HandleBindSight,                                 //  1 SPELL_AURA_BIND_SIGHT
59    &Aura::HandleModPossess,                                //  2 SPELL_AURA_MOD_POSSESS
60    &Aura::HandlePeriodicDamage,                            //  3 SPELL_AURA_PERIODIC_DAMAGE
61    &Aura::HandleAuraDummy,                                 //  4 SPELL_AURA_DUMMY
62    &Aura::HandleModConfuse,                                //  5 SPELL_AURA_MOD_CONFUSE
63    &Aura::HandleModCharm,                                  //  6 SPELL_AURA_MOD_CHARM
64    &Aura::HandleModFear,                                   //  7 SPELL_AURA_MOD_FEAR
65    &Aura::HandlePeriodicHeal,                              //  8 SPELL_AURA_PERIODIC_HEAL
66    &Aura::HandleModAttackSpeed,                            //  9 SPELL_AURA_MOD_ATTACKSPEED
67    &Aura::HandleModThreat,                                 // 10 SPELL_AURA_MOD_THREAT
68    &Aura::HandleModTaunt,                                  // 11 SPELL_AURA_MOD_TAUNT
69    &Aura::HandleAuraModStun,                               // 12 SPELL_AURA_MOD_STUN
70    &Aura::HandleModDamageDone,                             // 13 SPELL_AURA_MOD_DAMAGE_DONE
71    &Aura::HandleNoImmediateEffect,                         // 14 SPELL_AURA_MOD_DAMAGE_TAKEN implemented in Unit::MeleeDamageBonus and Unit::SpellDamageBonus
72    &Aura::HandleNoImmediateEffect,                         // 15 SPELL_AURA_DAMAGE_SHIELD    implemented in Unit::DoAttackDamage
73    &Aura::HandleModStealth,                                // 16 SPELL_AURA_MOD_STEALTH
74    &Aura::HandleNoImmediateEffect,                         // 17 SPELL_AURA_MOD_STEALTH_DETECT
75    &Aura::HandleInvisibility,                              // 18 SPELL_AURA_MOD_INVISIBILITY
76    &Aura::HandleInvisibilityDetect,                        // 19 SPELL_AURA_MOD_INVISIBILITY_DETECTION
77    &Aura::HandleAuraModTotalHealthPercentRegen,            // 20 SPELL_AURA_OBS_MOD_HEALTH
78    &Aura::HandleAuraModTotalManaPercentRegen,              // 21 SPELL_AURA_OBS_MOD_MANA
79    &Aura::HandleAuraModResistance,                         // 22 SPELL_AURA_MOD_RESISTANCE
80    &Aura::HandlePeriodicTriggerSpell,                      // 23 SPELL_AURA_PERIODIC_TRIGGER_SPELL
81    &Aura::HandlePeriodicEnergize,                          // 24 SPELL_AURA_PERIODIC_ENERGIZE
82    &Aura::HandleAuraModPacify,                             // 25 SPELL_AURA_MOD_PACIFY
83    &Aura::HandleAuraModRoot,                               // 26 SPELL_AURA_MOD_ROOT
84    &Aura::HandleAuraModSilence,                            // 27 SPELL_AURA_MOD_SILENCE
85    &Aura::HandleNoImmediateEffect,                         // 28 SPELL_AURA_REFLECT_SPELLS        implement in Unit::SpellHitResult
86    &Aura::HandleAuraModStat,                               // 29 SPELL_AURA_MOD_STAT
87    &Aura::HandleAuraModSkill,                              // 30 SPELL_AURA_MOD_SKILL
88    &Aura::HandleAuraModIncreaseSpeed,                      // 31 SPELL_AURA_MOD_INCREASE_SPEED
89    &Aura::HandleAuraModIncreaseMountedSpeed,               // 32 SPELL_AURA_MOD_INCREASE_MOUNTED_SPEED
90    &Aura::HandleAuraModDecreaseSpeed,                      // 33 SPELL_AURA_MOD_DECREASE_SPEED
91    &Aura::HandleAuraModIncreaseHealth,                     // 34 SPELL_AURA_MOD_INCREASE_HEALTH
92    &Aura::HandleAuraModIncreaseEnergy,                     // 35 SPELL_AURA_MOD_INCREASE_ENERGY
93    &Aura::HandleAuraModShapeshift,                         // 36 SPELL_AURA_MOD_SHAPESHIFT
94    &Aura::HandleAuraModEffectImmunity,                     // 37 SPELL_AURA_EFFECT_IMMUNITY
95    &Aura::HandleAuraModStateImmunity,                      // 38 SPELL_AURA_STATE_IMMUNITY
96    &Aura::HandleAuraModSchoolImmunity,                     // 39 SPELL_AURA_SCHOOL_IMMUNITY
97    &Aura::HandleAuraModDmgImmunity,                        // 40 SPELL_AURA_DAMAGE_IMMUNITY
98    &Aura::HandleAuraModDispelImmunity,                     // 41 SPELL_AURA_DISPEL_IMMUNITY
99    &Aura::HandleAuraProcTriggerSpell,                      // 42 SPELL_AURA_PROC_TRIGGER_SPELL  implemented in Unit::ProcDamageAndSpellFor and Unit::HandleProcTriggerSpell
100    &Aura::HandleNoImmediateEffect,                         // 43 SPELL_AURA_PROC_TRIGGER_DAMAGE implemented in Unit::ProcDamageAndSpellFor
101    &Aura::HandleAuraTrackCreatures,                        // 44 SPELL_AURA_TRACK_CREATURES
102    &Aura::HandleAuraTrackResources,                        // 45 SPELL_AURA_TRACK_RESOURCES
103    &Aura::HandleUnused,                                    // 46 SPELL_AURA_MOD_PARRY_SKILL    obsolete?
104    &Aura::HandleAuraModParryPercent,                       // 47 SPELL_AURA_MOD_PARRY_PERCENT
105    &Aura::HandleUnused,                                    // 48 SPELL_AURA_MOD_DODGE_SKILL    obsolete?
106    &Aura::HandleAuraModDodgePercent,                       // 49 SPELL_AURA_MOD_DODGE_PERCENT
107    &Aura::HandleUnused,                                    // 50 SPELL_AURA_MOD_BLOCK_SKILL    obsolete?
108    &Aura::HandleAuraModBlockPercent,                       // 51 SPELL_AURA_MOD_BLOCK_PERCENT
109    &Aura::HandleAuraModCritPercent,                        // 52 SPELL_AURA_MOD_CRIT_PERCENT
110    &Aura::HandlePeriodicLeech,                             // 53 SPELL_AURA_PERIODIC_LEECH
111    &Aura::HandleModHitChance,                              // 54 SPELL_AURA_MOD_HIT_CHANCE
112    &Aura::HandleModSpellHitChance,                         // 55 SPELL_AURA_MOD_SPELL_HIT_CHANCE
113    &Aura::HandleAuraTransform,                             // 56 SPELL_AURA_TRANSFORM
114    &Aura::HandleModSpellCritChance,                        // 57 SPELL_AURA_MOD_SPELL_CRIT_CHANCE
115    &Aura::HandleAuraModIncreaseSwimSpeed,                  // 58 SPELL_AURA_MOD_INCREASE_SWIM_SPEED
116    &Aura::HandleNoImmediateEffect,                         // 59 SPELL_AURA_MOD_DAMAGE_DONE_CREATURE implemented in Unit::MeleeDamageBonus and Unit::SpellDamageBonus
117    &Aura::HandleAuraModPacifyAndSilence,                   // 60 SPELL_AURA_MOD_PACIFY_SILENCE
118    &Aura::HandleAuraModScale,                              // 61 SPELL_AURA_MOD_SCALE
119    &Aura::HandleNULL,                                      // 62 SPELL_AURA_PERIODIC_HEALTH_FUNNEL
120    &Aura::HandleUnused,                                    // 63 SPELL_AURA_PERIODIC_MANA_FUNNEL obsolete?
121    &Aura::HandlePeriodicManaLeech,                         // 64 SPELL_AURA_PERIODIC_MANA_LEECH
122    &Aura::HandleModCastingSpeed,                           // 65 SPELL_AURA_MOD_CASTING_SPEED
123    &Aura::HandleFeignDeath,                                // 66 SPELL_AURA_FEIGN_DEATH
124    &Aura::HandleAuraModDisarm,                             // 67 SPELL_AURA_MOD_DISARM
125    &Aura::HandleAuraModStalked,                            // 68 SPELL_AURA_MOD_STALKED
126    &Aura::HandleSchoolAbsorb,                              // 69 SPELL_AURA_SCHOOL_ABSORB implemented in Unit::CalcAbsorbResist
127    &Aura::HandleUnused,                                    // 70 SPELL_AURA_EXTRA_ATTACKS      Useless, used by only one spell that has only visual effect
128    &Aura::HandleModSpellCritChanceShool,                   // 71 SPELL_AURA_MOD_SPELL_CRIT_CHANCE_SCHOOL
129    &Aura::HandleModPowerCostPCT,                           // 72 SPELL_AURA_MOD_POWER_COST_SCHOOL_PCT
130    &Aura::HandleModPowerCost,                              // 73 SPELL_AURA_MOD_POWER_COST_SCHOOL
131    &Aura::HandleNoImmediateEffect,                         // 74 SPELL_AURA_REFLECT_SPELLS_SCHOOL  implemented in Unit::SpellHitResult
132    &Aura::HandleNoImmediateEffect,                         // 75 SPELL_AURA_MOD_LANGUAGE
133    &Aura::HandleFarSight,                                  // 76 SPELL_AURA_FAR_SIGHT
134    &Aura::HandleModMechanicImmunity,                       // 77 SPELL_AURA_MECHANIC_IMMUNITY
135    &Aura::HandleAuraMounted,                               // 78 SPELL_AURA_MOUNTED
136    &Aura::HandleModDamagePercentDone,                      // 79 SPELL_AURA_MOD_DAMAGE_PERCENT_DONE
137    &Aura::HandleModPercentStat,                            // 80 SPELL_AURA_MOD_PERCENT_STAT
138    &Aura::HandleNoImmediateEffect,                         // 81 SPELL_AURA_SPLIT_DAMAGE_PCT
139    &Aura::HandleWaterBreathing,                            // 82 SPELL_AURA_WATER_BREATHING
140    &Aura::HandleModBaseResistance,                         // 83 SPELL_AURA_MOD_BASE_RESISTANCE
141    &Aura::HandleModRegen,                                  // 84 SPELL_AURA_MOD_REGEN
142    &Aura::HandleModPowerRegen,                             // 85 SPELL_AURA_MOD_POWER_REGEN
143    &Aura::HandleChannelDeathItem,                          // 86 SPELL_AURA_CHANNEL_DEATH_ITEM
144    &Aura::HandleNoImmediateEffect,                         // 87 SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN implemented in Unit::MeleeDamageBonus and Unit::SpellDamageBonus
145    &Aura::HandleNoImmediateEffect,                         // 88 SPELL_AURA_MOD_HEALTH_REGEN_PERCENT
146    &Aura::HandlePeriodicDamagePCT,                         // 89 SPELL_AURA_PERIODIC_DAMAGE_PERCENT
147    &Aura::HandleUnused,                                    // 90 SPELL_AURA_MOD_RESIST_CHANCE  Useless
148    &Aura::HandleNoImmediateEffect,                         // 91 SPELL_AURA_MOD_DETECT_RANGE implemented in Creature::GetAttackDistance
149    &Aura::HandlePreventFleeing,                            // 92 SPELL_AURA_PREVENTS_FLEEING
150    &Aura::HandleModUnattackable,                           // 93 SPELL_AURA_MOD_UNATTACKABLE
151    &Aura::HandleNoImmediateEffect,                         // 94 SPELL_AURA_INTERRUPT_REGEN implemented in Player::RegenerateAll
152    &Aura::HandleAuraGhost,                                 // 95 SPELL_AURA_GHOST
153    &Aura::HandleNoImmediateEffect,                         // 96 SPELL_AURA_SPELL_MAGNET implemented in Spell::SelectMagnetTarget
154    &Aura::HandleManaShield,                                // 97 SPELL_AURA_MANA_SHIELD implemented in Unit::CalcAbsorbResist
155    &Aura::HandleAuraModSkill,                              // 98 SPELL_AURA_MOD_SKILL_TALENT
156    &Aura::HandleAuraModAttackPower,                        // 99 SPELL_AURA_MOD_ATTACK_POWER
157    &Aura::HandleUnused,                                    //100 SPELL_AURA_AURAS_VISIBLE obsolete? all player can see all auras now
158    &Aura::HandleModResistancePercent,                      //101 SPELL_AURA_MOD_RESISTANCE_PCT
159    &Aura::HandleNoImmediateEffect,                         //102 SPELL_AURA_MOD_MELEE_ATTACK_POWER_VERSUS implemented in Unit::MeleeDamageBonus
160    &Aura::HandleAuraModTotalThreat,                        //103 SPELL_AURA_MOD_TOTAL_THREAT
161    &Aura::HandleAuraWaterWalk,                             //104 SPELL_AURA_WATER_WALK
162    &Aura::HandleAuraFeatherFall,                           //105 SPELL_AURA_FEATHER_FALL
163    &Aura::HandleAuraHover,                                 //106 SPELL_AURA_HOVER
164    &Aura::HandleAddModifier,                               //107 SPELL_AURA_ADD_FLAT_MODIFIER
165    &Aura::HandleAddModifier,                               //108 SPELL_AURA_ADD_PCT_MODIFIER
166    &Aura::HandleNoImmediateEffect,                         //109 SPELL_AURA_ADD_TARGET_TRIGGER
167    &Aura::HandleModPowerRegenPCT,                          //110 SPELL_AURA_MOD_POWER_REGEN_PERCENT
168    &Aura::HandleNULL,                                      //111 SPELL_AURA_ADD_CASTER_HIT_TRIGGER
169    &Aura::HandleNoImmediateEffect,                         //112 SPELL_AURA_OVERRIDE_CLASS_SCRIPTS
170    &Aura::HandleNoImmediateEffect,                         //113 SPELL_AURA_MOD_RANGED_DAMAGE_TAKEN implemented in Unit::MeleeDamageBonus
171    &Aura::HandleNoImmediateEffect,                         //114 SPELL_AURA_MOD_RANGED_DAMAGE_TAKEN_PCT implemented in Unit::MeleeDamageBonus
172    &Aura::HandleAuraHealing,                               //115 SPELL_AURA_MOD_HEALING
173    &Aura::HandleNoImmediateEffect,                         //116 SPELL_AURA_MOD_REGEN_DURING_COMBAT
174    &Aura::HandleNoImmediateEffect,                         //117 SPELL_AURA_MOD_MECHANIC_RESISTANCE     implemented in Unit::MagicSpellHitResult
175    &Aura::HandleAuraHealingPct,                            //118 SPELL_AURA_MOD_HEALING_PCT
176    &Aura::HandleUnused,                                    //119 SPELL_AURA_SHARE_PET_TRACKING useless
177    &Aura::HandleAuraUntrackable,                           //120 SPELL_AURA_UNTRACKABLE
178    &Aura::HandleAuraEmpathy,                               //121 SPELL_AURA_EMPATHY
179    &Aura::HandleModOffhandDamagePercent,                   //122 SPELL_AURA_MOD_OFFHAND_DAMAGE_PCT
180    &Aura::HandleModTargetResistance,                       //123 SPELL_AURA_MOD_TARGET_RESISTANCE
181    &Aura::HandleAuraModRangedAttackPower,                  //124 SPELL_AURA_MOD_RANGED_ATTACK_POWER
182    &Aura::HandleNoImmediateEffect,                         //125 SPELL_AURA_MOD_MELEE_DAMAGE_TAKEN implemented in Unit::MeleeDamageBonus
183    &Aura::HandleNoImmediateEffect,                         //126 SPELL_AURA_MOD_MELEE_DAMAGE_TAKEN_PCT implemented in Unit::MeleeDamageBonus
184    &Aura::HandleNoImmediateEffect,                         //127 SPELL_AURA_RANGED_ATTACK_POWER_ATTACKER_BONUS implemented in Unit::MeleeDamageBonus
185    &Aura::HandleModPossessPet,                             //128 SPELL_AURA_MOD_POSSESS_PET
186    &Aura::HandleAuraModIncreaseSpeed,                      //129 SPELL_AURA_MOD_SPEED_ALWAYS
187    &Aura::HandleAuraModIncreaseMountedSpeed,               //130 SPELL_AURA_MOD_MOUNTED_SPEED_ALWAYS
188    &Aura::HandleNoImmediateEffect,                         //131 SPELL_AURA_MOD_RANGED_ATTACK_POWER_VERSUS implemented in Unit::MeleeDamageBonus
189    &Aura::HandleAuraModIncreaseEnergyPercent,              //132 SPELL_AURA_MOD_INCREASE_ENERGY_PERCENT
190    &Aura::HandleAuraModIncreaseHealthPercent,              //133 SPELL_AURA_MOD_INCREASE_HEALTH_PERCENT
191    &Aura::HandleAuraModRegenInterrupt,                     //134 SPELL_AURA_MOD_MANA_REGEN_INTERRUPT
192    &Aura::HandleModHealingDone,                            //135 SPELL_AURA_MOD_HEALING_DONE
193    &Aura::HandleAuraHealingPct,                            //136 SPELL_AURA_MOD_HEALING_DONE_PERCENT   implemented in Unit::SpellHealingBonus
194    &Aura::HandleModTotalPercentStat,                       //137 SPELL_AURA_MOD_TOTAL_STAT_PERCENTAGE
195    &Aura::HandleHaste,                                     //138 SPELL_AURA_MOD_HASTE
196    &Aura::HandleForceReaction,                             //139 SPELL_AURA_FORCE_REACTION
197    &Aura::HandleAuraModRangedHaste,                        //140 SPELL_AURA_MOD_RANGED_HASTE
198    &Aura::HandleRangedAmmoHaste,                           //141 SPELL_AURA_MOD_RANGED_AMMO_HASTE
199    &Aura::HandleAuraModBaseResistancePCT,                  //142 SPELL_AURA_MOD_BASE_RESISTANCE_PCT
200    &Aura::HandleAuraModResistanceExclusive,                //143 SPELL_AURA_MOD_RESISTANCE_EXCLUSIVE
201    &Aura::HandleNoImmediateEffect,                         //144 SPELL_AURA_SAFE_FALL                  implemented in WorldSession::HandleMovementOpcodes
202    &Aura::HandleUnused,                                    //145 SPELL_AURA_CHARISMA obsolete?
203    &Aura::HandleUnused,                                    //146 SPELL_AURA_PERSUADED obsolete?
204    &Aura::HandleNULL,                                      //147 SPELL_AURA_ADD_CREATURE_IMMUNITY
205    &Aura::HandleAuraRetainComboPoints,                     //148 SPELL_AURA_RETAIN_COMBO_POINTS
206    &Aura::HandleNoImmediateEffect,                         //149 SPELL_AURA_RESIST_PUSHBACK
207    &Aura::HandleShieldBlockValue,                          //150 SPELL_AURA_MOD_SHIELD_BLOCKVALUE_PCT
208    &Aura::HandleAuraTrackStealthed,                        //151 SPELL_AURA_TRACK_STEALTHED
209    &Aura::HandleNoImmediateEffect,                         //152 SPELL_AURA_MOD_DETECTED_RANGE implemented in Creature::GetAttackDistance
210    &Aura::HandleNoImmediateEffect,                         //153 SPELL_AURA_SPLIT_DAMAGE_FLAT
211    &Aura::HandleNoImmediateEffect,                         //154 SPELL_AURA_MOD_STEALTH_LEVEL
212    &Aura::HandleNoImmediateEffect,                         //155 SPELL_AURA_MOD_WATER_BREATHING
213    &Aura::HandleNoImmediateEffect,                         //156 SPELL_AURA_MOD_REPUTATION_GAIN
214    &Aura::HandleNULL,                                      //157 SPELL_AURA_PET_DAMAGE_MULTI
215    &Aura::HandleShieldBlockValue,                          //158 SPELL_AURA_MOD_SHIELD_BLOCKVALUE
216    &Aura::HandleNoImmediateEffect,                         //159 SPELL_AURA_NO_PVP_CREDIT      only for Honorless Target spell
217    &Aura::HandleNoImmediateEffect,                         //160 SPELL_AURA_MOD_AOE_AVOIDANCE                 implemented in Unit::MagicSpellHitResult
218    &Aura::HandleNoImmediateEffect,                         //161 SPELL_AURA_MOD_HEALTH_REGEN_IN_COMBAT
219    &Aura::HandleAuraPowerBurn,                             //162 SPELL_AURA_POWER_BURN_MANA
220    &Aura::HandleNoImmediateEffect,                         //163 SPELL_AURA_MOD_CRIT_DAMAGE_BONUS_MELEE
221    &Aura::HandleUnused,                                    //164 useless, only one test spell
222    &Aura::HandleAuraAttackPowerAttacker,                   //165 SPELL_AURA_MELEE_ATTACK_POWER_ATTACKER_BONUS implemented in Unit::MeleeDamageBonus
223    &Aura::HandleAuraModAttackPowerPercent,                 //166 SPELL_AURA_MOD_ATTACK_POWER_PCT
224    &Aura::HandleAuraModRangedAttackPowerPercent,           //167 SPELL_AURA_MOD_RANGED_ATTACK_POWER_PCT
225    &Aura::HandleNoImmediateEffect,                         //168 SPELL_AURA_MOD_DAMAGE_DONE_VERSUS            implemented in Unit::SpellDamageBonus, Unit::MeleeDamageBonus
226    &Aura::HandleNoImmediateEffect,                         //169 SPELL_AURA_MOD_CRIT_PERCENT_VERSUS           implemented in Unit::DealDamageBySchool, Unit::DoAttackDamage, Unit::SpellCriticalBonus
227    &Aura::HandleNULL,                                      //170 SPELL_AURA_DETECT_AMORE       only for Detect Amore spell
228    &Aura::HandleAuraModIncreaseSpeed,                      //171 SPELL_AURA_MOD_SPEED_NOT_STACK
229    &Aura::HandleAuraModIncreaseMountedSpeed,               //172 SPELL_AURA_MOD_MOUNTED_SPEED_NOT_STACK
230    &Aura::HandleUnused,                                    //173 SPELL_AURA_ALLOW_CHAMPION_SPELLS  only for Proclaim Champion spell
231    &Aura::HandleModSpellDamagePercentFromStat,             //174 SPELL_AURA_MOD_SPELL_DAMAGE_OF_STAT_PERCENT  implemented in Unit::SpellBaseDamageBonus (by default intellect, dependent from SPELL_AURA_MOD_SPELL_HEALING_OF_STAT_PERCENT)
232    &Aura::HandleModSpellHealingPercentFromStat,            //175 SPELL_AURA_MOD_SPELL_HEALING_OF_STAT_PERCENT implemented in Unit::SpellBaseHealingBonus
233    &Aura::HandleSpiritOfRedemption,                        //176 SPELL_AURA_SPIRIT_OF_REDEMPTION   only for Spirit of Redemption spell, die at aura end
234    &Aura::HandleNULL,                                      //177 SPELL_AURA_AOE_CHARM
235    &Aura::HandleNoImmediateEffect,                         //178 SPELL_AURA_MOD_DEBUFF_RESISTANCE          implemented in Unit::MagicSpellHitResult
236    &Aura::HandleNoImmediateEffect,                         //179 SPELL_AURA_MOD_ATTACKER_SPELL_CRIT_CHANCE implemented in Unit::SpellCriticalBonus
237    &Aura::HandleNoImmediateEffect,                         //180 SPELL_AURA_MOD_FLAT_SPELL_DAMAGE_VERSUS   implemented in Unit::SpellDamageBonus
238    &Aura::HandleUnused,                                    //181 SPELL_AURA_MOD_FLAT_SPELL_CRIT_DAMAGE_VERSUS unused
239    &Aura::HandleAuraModResistenceOfStatPercent,            //182 SPELL_AURA_MOD_RESISTANCE_OF_STAT_PERCENT
240    &Aura::HandleNULL,                                      //183 SPELL_AURA_MOD_CRITICAL_THREAT
241    &Aura::HandleNoImmediateEffect,                         //184 SPELL_AURA_MOD_ATTACKER_MELEE_HIT_CHANCE  implemented in Unit::RollMeleeOutcomeAgainst
242    &Aura::HandleNoImmediateEffect,                         //185 SPELL_AURA_MOD_ATTACKER_RANGED_HIT_CHANCE implemented in Unit::RollMeleeOutcomeAgainst
243    &Aura::HandleNoImmediateEffect,                         //186 SPELL_AURA_MOD_ATTACKER_SPELL_HIT_CHANCE  implemented in Unit::MagicSpellHitResult
244    &Aura::HandleNoImmediateEffect,                         //187 SPELL_AURA_MOD_ATTACKER_MELEE_CRIT_CHANCE  implemented in Unit::GetUnitCriticalChance
245    &Aura::HandleNoImmediateEffect,                         //188 SPELL_AURA_MOD_ATTACKER_RANGED_CRIT_CHANCE implemented in Unit::GetUnitCriticalChance
246    &Aura::HandleModRating,                                 //189 SPELL_AURA_MOD_RATING
247    &Aura::HandleNULL,                                      //190 SPELL_AURA_MOD_FACTION_REPUTATION_GAIN
248    &Aura::HandleAuraModUseNormalSpeed,                     //191 SPELL_AURA_USE_NORMAL_MOVEMENT_SPEED
249    &Aura::HandleModMeleeRangedSpeedPct,                    //192 SPELL_AURA_HASTE_MELEE
250    &Aura::HandleModCombatSpeedPct,                         //193 SPELL_AURA_MELEE_SLOW (in fact combat (any type attack) speed pct)
251    &Aura::HandleUnused,                                    //194 SPELL_AURA_MOD_DEPRICATED_1 not used now (old SPELL_AURA_MOD_SPELL_DAMAGE_OF_INTELLECT)
252    &Aura::HandleUnused,                                    //195 SPELL_AURA_MOD_DEPRICATED_2 not used now (old SPELL_AURA_MOD_SPELL_HEALING_OF_INTELLECT)
253    &Aura::HandleNULL,                                      //196 SPELL_AURA_MOD_COOLDOWN
254    &Aura::HandleNoImmediateEffect,                         //197 SPELL_AURA_MOD_ATTACKER_SPELL_AND_WEAPON_CRIT_CHANCE implemented in Unit::SpellCriticalBonus Unit::GetUnitCriticalChance
255    &Aura::HandleUnused,                                    //198 SPELL_AURA_MOD_ALL_WEAPON_SKILLS
256    &Aura::HandleNoImmediateEffect,                         //199 SPELL_AURA_MOD_INCREASES_SPELL_PCT_TO_HIT  implemented in Unit::MagicSpellHitResult
257    &Aura::HandleNoImmediateEffect,                         //200 SPELL_AURA_MOD_XP_PCT implemented in Player::GiveXP
258    &Aura::HandleAuraAllowFlight,                           //201 SPELL_AURA_FLY                             this aura enable flight mode...
259    &Aura::HandleNoImmediateEffect,                         //202 SPELL_AURA_CANNOT_BE_DODGED                implemented in Unit::RollPhysicalOutcomeAgainst
260    &Aura::HandleNoImmediateEffect,                         //203 SPELL_AURA_MOD_ATTACKER_MELEE_CRIT_DAMAGE  implemented in Unit::DoAttackDamage
261    &Aura::HandleNoImmediateEffect,                         //204 SPELL_AURA_MOD_ATTACKER_RANGED_CRIT_DAMAGE implemented in Unit::DoAttackDamage
262    &Aura::HandleNULL,                                      //205 vulnerable to school dmg?
263    &Aura::HandleNULL,                                      //206 SPELL_AURA_MOD_SPEED_MOUNTED
264    &Aura::HandleAuraModIncreaseFlightSpeed,                //207 SPELL_AURA_MOD_INCREASE_FLIGHT_SPEED
265    &Aura::HandleAuraModIncreaseFlightSpeed,                //208 SPELL_AURA_MOD_SPEED_FLIGHT, used only in spell: Flight Form (Passive)
266    &Aura::HandleAuraModIncreaseFlightSpeed,                //209 SPELL_AURA_MOD_FLIGHT_SPEED_ALWAYS
267    &Aura::HandleNULL,                                      //210 Commentator's Command
268    &Aura::HandleAuraModIncreaseFlightSpeed,                //211 SPELL_AURA_MOD_FLIGHT_SPEED_NOT_STACK
269    &Aura::HandleAuraModRangedAttackPowerOfStatPercent,     //212 SPELL_AURA_MOD_RANGED_ATTACK_POWER_OF_STAT_PERCENT
270    &Aura::HandleNoImmediateEffect,                         //213 SPELL_AURA_MOD_RAGE_FROM_DAMAGE_DEALT implemented in Player::RewardRage
271    &Aura::HandleNULL,                                      //214 Tamed Pet Passive
272    &Aura::HandleArenaPreparation,                          //215 SPELL_AURA_ARENA_PREPARATION
273    &Aura::HandleModCastingSpeed,                           //216 SPELL_AURA_HASTE_SPELLS
274    &Aura::HandleUnused,                                    //217                                   unused
275    &Aura::HandleAuraModRangedHaste,                        //218 SPELL_AURA_HASTE_RANGED
276    &Aura::HandleModManaRegen,                              //219 SPELL_AURA_MOD_MANA_REGEN_FROM_STAT
277    &Aura::HandleNULL,                                      //220 SPELL_AURA_MOD_RATING_FROM_STAT
278    &Aura::HandleNULL,                                      //221 ignored
279    &Aura::HandleUnused,                                    //222 unused
280    &Aura::HandleNULL,                                      //223 Cold Stare
281    &Aura::HandleUnused,                                    //224 unused
282    &Aura::HandleNoImmediateEffect,                         //225 SPELL_AURA_PRAYER_OF_MENDING
283    &Aura::HandleAuraPeriodicDummy,                         //226 SPELL_AURA_PERIODIC_DUMMY
284    &Aura::HandleNULL,                                      //227 periodic trigger spell
285    &Aura::HandleNoImmediateEffect,                         //228 stealth detection
286    &Aura::HandleNULL,                                      //229 SPELL_AURA_MOD_AOE_DAMAGE_AVOIDANCE
287    &Aura::HandleAuraModIncreaseMaxHealth,                  //230 Commanding Shout
288    &Aura::HandleNULL,                                      //231
289    &Aura::HandleNoImmediateEffect,                         //232 SPELL_AURA_MECHANIC_DURATION_MOD           implement in Unit::CalculateSpellDuration
290    &Aura::HandleNULL,                                      //233 set model id to the one of the creature with id m_modifier.m_miscvalue
291    &Aura::HandleNoImmediateEffect,                         //234 SPELL_AURA_MECHANIC_DURATION_MOD_NOT_STACK implement in Unit::CalculateSpellDuration
292    &Aura::HandleAuraModDispelResist,                       //235 SPELL_AURA_MOD_DISPEL_RESIST               implement in Unit::MagicSpellHitResult
293    &Aura::HandleUnused,                                    //236 unused
294    &Aura::HandleModSpellDamagePercentFromAttackPower,      //237 SPELL_AURA_MOD_SPELL_DAMAGE_OF_ATTACK_POWER  implemented in Unit::SpellBaseDamageBonus
295    &Aura::HandleModSpellHealingPercentFromAttackPower,     //238 SPELL_AURA_MOD_SPELL_HEALING_OF_ATTACK_POWER implemented in Unit::SpellBaseHealingBonus
296    &Aura::HandleAuraModScale,                              //239 SPELL_AURA_MOD_SCALE_2 only in Noggenfogger Elixir (16595) before 2.3.0 aura 61
297    &Aura::HandleAuraModExpertise,                          //240 SPELL_AURA_MOD_EXPERTISE
298    &Aura::HandleForceMoveForward,                          //241 Forces the player to move forward
299    &Aura::HandleUnused,                                    //242 SPELL_AURA_MOD_SPELL_DAMAGE_FROM_HEALING
300    &Aura::HandleUnused,                                    //243 used by two test spells
301    &Aura::HandleComprehendLanguage,                        //244 Comprehend language
302    &Aura::HandleUnused,                                    //245 SPELL_AURA_MOD_DURATION_OF_MAGIC_EFFECTS
303    &Aura::HandleUnused,                                    //246 unused
304    &Aura::HandleUnused,                                    //247 unused
305    &Aura::HandleNoImmediateEffect,                         //248 SPELL_AURA_MOD_COMBAT_RESULT_CHANCE         implemented in Unit::RollMeleeOutcomeAgainst
306    &Aura::HandleNULL,                                      //249
307    &Aura::HandleAuraModIncreaseHealth,                     //250 SPELL_AURA_MOD_INCREASE_HEALTH_2
308    &Aura::HandleNULL,                                      //251 SPELL_AURA_MOD_ENEMY_DODGE
309    &Aura::HandleUnused,                                    //252 unused
310    &Aura::HandleUnused,                                    //253 unused
311    &Aura::HandleUnused,                                    //254 unused
312    &Aura::HandleUnused,                                    //255 unused
313    &Aura::HandleUnused,                                    //256 unused
314    &Aura::HandleUnused,                                    //257 unused
315    &Aura::HandleUnused,                                    //258 unused
316    &Aura::HandleUnused,                                    //259 unused
317    &Aura::HandleUnused,                                    //260 unused
318    &Aura::HandleNULL                                       //261 SPELL_AURA_261 some phased state (44856 spell)
319};
320
321Aura::Aura(SpellEntry const* spellproto, uint32 eff, int32 *currentBasePoints, Unit *target, Unit *caster, Item* castItem) :
322m_procCharges(0), m_spellmod(NULL), m_effIndex(eff), m_caster_guid(0), m_target(target),
323m_timeCla(1000), m_castItemGuid(castItem?castItem->GetGUID():0), m_auraSlot(MAX_AURAS),
324m_positive(false), m_permanent(false), m_isPeriodic(false), m_isTrigger(false), m_isAreaAura(false),
325m_isPersistent(false), m_updated(false), m_removeMode(AURA_REMOVE_BY_DEFAULT), m_isRemovedOnShapeLost(true), m_in_use(false),
326m_periodicTimer(0), m_PeriodicEventId(0), m_AuraDRGroup(DIMINISHING_NONE)
327{
328    assert(target);
329
330    assert(spellproto && spellproto == sSpellStore.LookupEntry( spellproto->Id ) && "`info` must be pointer to sSpellStore element");
331
332    m_spellProto = spellproto;
333
334    m_currentBasePoints = currentBasePoints ? *currentBasePoints : m_spellProto->EffectBasePoints[eff];
335
336    m_isPassive = IsPassiveSpell(GetId());
337    m_positive = IsPositiveEffect(GetId(), m_effIndex);
338
339    m_applyTime = time(NULL);
340
341    int32 damage;
342    if(!caster)
343    {
344        m_caster_guid = target->GetGUID();
345        damage = m_currentBasePoints+1;                     // stored value-1
346        m_maxduration = target->CalculateSpellDuration(m_spellProto, m_effIndex, target);
347    }
348    else
349    {
350        m_caster_guid = caster->GetGUID();
351
352        damage        = caster->CalculateSpellDamage(m_spellProto,m_effIndex,m_currentBasePoints,target);
353        m_maxduration = caster->CalculateSpellDuration(m_spellProto, m_effIndex, target);
354
355        if (!damage && castItem && castItem->GetItemSuffixFactor())
356        {
357            ItemRandomSuffixEntry const *item_rand_suffix = sItemRandomSuffixStore.LookupEntry(abs(castItem->GetItemRandomPropertyId()));
358            if(item_rand_suffix)
359            {
360                for (int k=0; k<3; k++)
361                {
362                    SpellItemEnchantmentEntry const *pEnchant = sSpellItemEnchantmentStore.LookupEntry(item_rand_suffix->enchant_id[k]);
363                    if(pEnchant)
364                    {
365                        for (int t=0; t<3; t++)
366                            if(pEnchant->spellid[t] == m_spellProto->Id)
367                        {
368                            damage = uint32((item_rand_suffix->prefix[k]*castItem->GetItemSuffixFactor()) / 10000 );
369                            break;
370                        }
371                    }
372
373                    if(damage)
374                        break;
375                }
376            }
377        }
378    }
379
380    if(m_maxduration == -1 || m_isPassive && m_spellProto->DurationIndex == 0)
381        m_permanent = true;
382
383    Player* modOwner = caster ? caster->GetSpellModOwner() : NULL;
384
385    if(!m_permanent && modOwner)
386        modOwner->ApplySpellMod(GetId(), SPELLMOD_DURATION, m_maxduration);
387
388    m_duration = m_maxduration;
389
390    if(modOwner)
391        modOwner->ApplySpellMod(GetId(), SPELLMOD_ACTIVATION_TIME, m_periodicTimer);
392
393    sLog.outDebug("Aura: construct Spellid : %u, Aura : %u Duration : %d Target : %d Damage : %d", m_spellProto->Id, m_spellProto->EffectApplyAuraName[eff], m_maxduration, m_spellProto->EffectImplicitTargetA[eff],damage);
394
395    m_effIndex = eff;
396    SetModifier(AuraType(m_spellProto->EffectApplyAuraName[eff]), damage, m_spellProto->EffectAmplitude[eff], m_spellProto->EffectMiscValue[eff]);
397
398    m_isDeathPersist = IsDeathPersistentSpell(m_spellProto);
399
400    if(m_spellProto->procCharges)
401    {
402        m_procCharges = m_spellProto->procCharges;
403
404        if(modOwner)
405            modOwner->ApplySpellMod(GetId(), SPELLMOD_CHARGES, m_procCharges);
406    }
407    else
408        m_procCharges = -1;
409
410    m_isRemovedOnShapeLost = (m_caster_guid==m_target->GetGUID() && m_spellProto->Stances &&
411                            !(m_spellProto->AttributesEx2 & 0x80000) && !(m_spellProto->Attributes & 0x10000));
412}
413
414Aura::~Aura()
415{
416}
417
418AreaAura::AreaAura(SpellEntry const* spellproto, uint32 eff, int32 *currentBasePoints, Unit *target,
419Unit *caster, Item* castItem) : Aura(spellproto, eff, currentBasePoints, target, caster, castItem)
420{
421    m_isAreaAura = true;
422
423    // caster==NULL in constructor args if target==caster in fact
424    Unit* caster_ptr = caster ? caster : target;
425
426    m_radius = GetSpellRadius(sSpellRadiusStore.LookupEntry(GetSpellProto()->EffectRadiusIndex[m_effIndex]));
427    if(Player* modOwner = caster_ptr->GetSpellModOwner())
428        modOwner->ApplySpellMod(GetId(), SPELLMOD_RADIUS, m_radius);
429
430    switch(spellproto->Effect[eff])
431    {
432        case SPELL_EFFECT_APPLY_AREA_AURA_PARTY:
433            m_areaAuraType = AREA_AURA_PARTY;
434            if(target->GetTypeId() == TYPEID_UNIT && ((Creature*)target)->isTotem())
435                m_modifier.m_auraname = SPELL_AURA_NONE;
436            break;
437        case SPELL_EFFECT_APPLY_AREA_AURA_FRIEND:
438            m_areaAuraType = AREA_AURA_FRIEND;
439            break;
440        case SPELL_EFFECT_APPLY_AREA_AURA_ENEMY:
441            m_areaAuraType = AREA_AURA_ENEMY;
442            if(target == caster_ptr)
443                m_modifier.m_auraname = SPELL_AURA_NONE;    // Do not do any effect on self
444            break;
445        case SPELL_EFFECT_APPLY_AREA_AURA_PET:
446            m_areaAuraType = AREA_AURA_PET;
447            break;
448        case SPELL_EFFECT_APPLY_AREA_AURA_OWNER:
449            m_areaAuraType = AREA_AURA_OWNER;
450            if(target == caster_ptr)
451                m_modifier.m_auraname = SPELL_AURA_NONE;
452            break;
453        default:
454            sLog.outError("Wrong spell effect in AreaAura constructor");
455            ASSERT(false);
456            break;
457    }
458}
459
460AreaAura::~AreaAura()
461{
462}
463
464PersistentAreaAura::PersistentAreaAura(SpellEntry const* spellproto, uint32 eff, int32 *currentBasePoints, Unit *target,
465Unit *caster, Item* castItem) : Aura(spellproto, eff, currentBasePoints, target, caster, castItem)
466{
467    m_isPersistent = true;
468}
469
470PersistentAreaAura::~PersistentAreaAura()
471{
472}
473
474Aura* CreateAura(SpellEntry const* spellproto, uint32 eff, int32 *currentBasePoints, Unit *target, Unit *caster, Item* castItem)
475{
476    if (IsAreaAuraEffect(spellproto->Effect[eff]))
477        return new AreaAura(spellproto, eff, currentBasePoints, target, caster, castItem);
478
479    return new Aura(spellproto, eff, currentBasePoints, target, caster, castItem);
480}
481
482Unit* Aura::GetCaster() const
483{
484    if(m_caster_guid==m_target->GetGUID())
485        return m_target;
486
487    //return ObjectAccessor::GetUnit(*m_target,m_caster_guid);
488    //must return caster even if it's in another grid/map
489    Unit *unit = ObjectAccessor::GetObjectInWorld(m_caster_guid, (Unit*)NULL);
490    return unit && unit->IsInWorld() ? unit : NULL;
491}
492
493void Aura::SetModifier(AuraType t, int32 a, uint32 pt, int32 miscValue)
494{
495    m_modifier.m_auraname = t;
496    m_modifier.m_amount   = a;
497    m_modifier.m_miscvalue = miscValue;
498    m_modifier.periodictime = pt;
499}
500
501void Aura::Update(uint32 diff)
502{
503    if (m_duration > 0)
504    {
505        m_duration -= diff;
506        if (m_duration < 0)
507            m_duration = 0;
508        m_timeCla -= diff;
509
510        // GetEffIndex()==0 prevent double/triple apply manaPerSecond/manaPerSecondPerLevel to same spell with many auras
511        // all spells with manaPerSecond/manaPerSecondPerLevel have aura in effect 0
512        if(GetEffIndex()==0 && m_timeCla <= 0)
513        {
514            if(Unit* caster = GetCaster())
515            {
516                Powers powertype = Powers(m_spellProto->powerType);
517                int32 manaPerSecond = m_spellProto->manaPerSecond + m_spellProto->manaPerSecondPerLevel * caster->getLevel();
518                m_timeCla = 1000;
519                if (manaPerSecond)
520                {
521                    if(powertype==POWER_HEALTH)
522                        caster->ModifyHealth(-manaPerSecond);
523                    else
524                        caster->ModifyPower(powertype,-manaPerSecond);
525                }
526            }
527        }
528    }
529
530    // Channeled aura required check distance from caster except in possessed cases
531    if(IsChanneledSpell(m_spellProto) && m_caster_guid != m_target->GetGUID() && !m_target->isPossessed())
532    {
533        Unit* caster = GetCaster();
534        if(!caster)
535        {
536            m_target->RemoveAura(GetId(),GetEffIndex());
537            return;
538        }
539
540        // Get spell range
541        float radius;
542        SpellModOp mod;
543        if (m_spellProto->EffectRadiusIndex[GetEffIndex()])
544        {
545            radius = GetSpellRadius(sSpellRadiusStore.LookupEntry(m_spellProto->EffectRadiusIndex[GetEffIndex()]));
546            mod = SPELLMOD_RADIUS;
547        }
548        else
549        {
550            radius = GetSpellMaxRange(sSpellRangeStore.LookupEntry(m_spellProto->rangeIndex));
551            mod = SPELLMOD_RANGE;
552        }
553
554        if(Player* modOwner = caster->GetSpellModOwner())
555            modOwner->ApplySpellMod(GetId(), mod, radius,NULL);
556
557        if(!caster->IsWithinDistInMap(m_target,radius))
558        {
559            m_target->RemoveAura(GetId(),GetEffIndex());
560            return;
561        }
562    }
563
564    if(m_isPeriodic && (m_duration >= 0 || m_isPassive || m_permanent))
565    {
566        m_periodicTimer -= diff;
567        if(m_periodicTimer <= 0)                            // tick also at m_periodicTimer==0 to prevent lost last tick in case max m_duration == (max m_periodicTimer)*N
568        {
569            if( m_modifier.m_auraname == SPELL_AURA_MOD_REGEN ||
570                m_modifier.m_auraname == SPELL_AURA_MOD_POWER_REGEN ||
571                                                            // Cannibalize, eating items and other spells
572                m_modifier.m_auraname == SPELL_AURA_OBS_MOD_HEALTH ||
573                                                            // Eating items and other spells
574                m_modifier.m_auraname == SPELL_AURA_OBS_MOD_MANA )
575            {
576                ApplyModifier(true);
577                return;
578            }
579            // update before applying (aura can be removed in TriggerSpell or PeriodicTick calls)
580            m_periodicTimer += m_modifier.periodictime;
581
582            if(m_isTrigger)
583                TriggerSpell();
584            else
585                PeriodicTick();
586        }
587    }
588}
589
590void AreaAura::Update(uint32 diff)
591{
592    // update for the caster of the aura
593    if(m_caster_guid == m_target->GetGUID())
594    {
595        Unit* caster = m_target;
596
597        if( !caster->hasUnitState(UNIT_STAT_ISOLATED) )
598        {
599            Unit* owner = caster->GetCharmerOrOwner();
600            if (!owner)
601                owner = caster;
602            std::list<Unit *> targets;
603
604            switch(m_areaAuraType)
605            {
606                case AREA_AURA_PARTY:
607                {
608                    Group *pGroup = NULL;
609
610                    if (owner->GetTypeId() == TYPEID_PLAYER)
611                        pGroup = ((Player*)owner)->GetGroup();
612
613                    if( pGroup)
614                    {
615                        uint8 subgroup = ((Player*)owner)->GetSubGroup();
616                        for(GroupReference *itr = pGroup->GetFirstMember(); itr != NULL; itr = itr->next())
617                        {
618                            Player* Target = itr->getSource();
619                            if(Target && Target->isAlive() && Target->GetSubGroup()==subgroup && caster->IsFriendlyTo(Target))
620                            {
621                                if(caster->IsWithinDistInMap(Target, m_radius))
622                                    targets.push_back(Target);
623                                Pet *pet = Target->GetPet();
624                                if(pet && pet->isAlive() && caster->IsWithinDistInMap(pet, m_radius))
625                                    targets.push_back(pet);
626                            }
627                        }
628                    }
629                    else
630                    {
631                        // add owner
632                        if( owner != caster && caster->IsWithinDistInMap(owner, m_radius) )
633                            targets.push_back(owner);
634                        // add caster's pet
635                        Unit* pet = caster->GetPet();
636                        if( pet && caster->IsWithinDistInMap(pet, m_radius))
637                            targets.push_back(pet);
638                    }
639                    break;
640                }
641                case AREA_AURA_FRIEND:
642                {
643                    CellPair p(Trinity::ComputeCellPair(caster->GetPositionX(), caster->GetPositionY()));
644                    Cell cell(p);
645                    cell.data.Part.reserved = ALL_DISTRICT;
646                    cell.SetNoCreate();
647
648                    Trinity::AnyFriendlyUnitInObjectRangeCheck u_check(caster, owner, m_radius);
649                    Trinity::UnitListSearcher<Trinity::AnyFriendlyUnitInObjectRangeCheck> searcher(targets, u_check);
650                    TypeContainerVisitor<Trinity::UnitListSearcher<Trinity::AnyFriendlyUnitInObjectRangeCheck>, WorldTypeMapContainer > world_unit_searcher(searcher);
651                    TypeContainerVisitor<Trinity::UnitListSearcher<Trinity::AnyFriendlyUnitInObjectRangeCheck>, GridTypeMapContainer >  grid_unit_searcher(searcher);
652                    CellLock<GridReadGuard> cell_lock(cell, p);
653                    cell_lock->Visit(cell_lock, world_unit_searcher, *MapManager::Instance().GetMap(caster->GetMapId(), caster));
654                    cell_lock->Visit(cell_lock, grid_unit_searcher, *MapManager::Instance().GetMap(caster->GetMapId(), caster));
655                    break;
656                }
657                case AREA_AURA_ENEMY:
658                {
659                    CellPair p(Trinity::ComputeCellPair(caster->GetPositionX(), caster->GetPositionY()));
660                    Cell cell(p);
661                    cell.data.Part.reserved = ALL_DISTRICT;
662                    cell.SetNoCreate();
663
664                    Trinity::AnyAoETargetUnitInObjectRangeCheck u_check(caster, owner, m_radius); // No GetCharmer in searcher
665                    Trinity::UnitListSearcher<Trinity::AnyAoETargetUnitInObjectRangeCheck> searcher(targets, u_check);
666                    TypeContainerVisitor<Trinity::UnitListSearcher<Trinity::AnyAoETargetUnitInObjectRangeCheck>, WorldTypeMapContainer > world_unit_searcher(searcher);
667                    TypeContainerVisitor<Trinity::UnitListSearcher<Trinity::AnyAoETargetUnitInObjectRangeCheck>, GridTypeMapContainer >  grid_unit_searcher(searcher);
668                    CellLock<GridReadGuard> cell_lock(cell, p);
669                    cell_lock->Visit(cell_lock, world_unit_searcher, *MapManager::Instance().GetMap(caster->GetMapId(), caster));
670                    cell_lock->Visit(cell_lock, grid_unit_searcher, *MapManager::Instance().GetMap(caster->GetMapId(), caster));
671                    break;
672                }
673                case AREA_AURA_OWNER:
674                case AREA_AURA_PET:
675                {
676                    if(owner != caster)
677                        targets.push_back(owner);
678                    break;
679                }
680            }
681
682            for(std::list<Unit *>::iterator tIter = targets.begin(); tIter != targets.end(); tIter++)
683            {
684                if((*tIter)->HasAura(GetId(), m_effIndex))
685                    continue;
686
687                if(SpellEntry const *actualSpellInfo = spellmgr.SelectAuraRankForPlayerLevel(GetSpellProto(), (*tIter)->getLevel()))
688                {
689                    int32 actualBasePoints = m_currentBasePoints;
690                    // recalculate basepoints for lower rank (all AreaAura spell not use custom basepoints?)
691                    if(actualSpellInfo != GetSpellProto())
692                        actualBasePoints = actualSpellInfo->EffectBasePoints[m_effIndex];
693                    AreaAura *aur = new AreaAura(actualSpellInfo, m_effIndex, &actualBasePoints, (*tIter), caster, NULL);
694                    (*tIter)->AddAura(aur);
695                }
696            }
697        }
698        Aura::Update(diff);
699    }
700    else                                                    // aura at non-caster
701    {
702        Unit * tmp_target = m_target;
703        Unit* caster = GetCaster();
704        uint32 tmp_spellId = GetId(), tmp_effIndex = m_effIndex;
705
706        // WARNING: the aura may get deleted during the update
707        // DO NOT access its members after update!
708        Aura::Update(diff);
709
710        // remove aura if out-of-range from caster (after teleport for example)
711        // or caster is isolated or caster no longer has the aura
712        // or caster is (no longer) friendly
713        bool needFriendly = (m_areaAuraType == AREA_AURA_ENEMY ? false : true);
714        if( !caster || caster->hasUnitState(UNIT_STAT_ISOLATED) ||
715            !caster->IsWithinDistInMap(tmp_target, m_radius)    ||
716            !caster->HasAura(tmp_spellId, tmp_effIndex)         ||
717            caster->IsFriendlyTo(tmp_target) != needFriendly
718           )
719        {
720            tmp_target->RemoveAura(tmp_spellId, tmp_effIndex);
721        }
722        else if( m_areaAuraType == AREA_AURA_PARTY)         // check if in same sub group
723        {
724            // not check group if target == owner or target == pet
725            if (caster->GetCharmerOrOwnerGUID() != tmp_target->GetGUID() && caster->GetGUID() != tmp_target->GetCharmerOrOwnerGUID())
726            {
727                Player* check = caster->GetCharmerOrOwnerPlayerOrPlayerItself();
728
729                Group *pGroup = check ? check->GetGroup() : NULL;
730                if( pGroup )
731                {
732                    Player* checkTarget = tmp_target->GetCharmerOrOwnerPlayerOrPlayerItself();
733                    if(!checkTarget || !pGroup->SameSubGroup(check, checkTarget))
734                        tmp_target->RemoveAura(tmp_spellId, tmp_effIndex);
735                }
736                else
737                    tmp_target->RemoveAura(tmp_spellId, tmp_effIndex);
738            }
739        }
740        else if( m_areaAuraType == AREA_AURA_PET || m_areaAuraType == AREA_AURA_OWNER )
741        {
742            if( tmp_target->GetGUID() != caster->GetCharmerOrOwnerGUID() )
743                tmp_target->RemoveAura(tmp_spellId, tmp_effIndex);
744        }
745    }
746}
747
748void PersistentAreaAura::Update(uint32 diff)
749{
750    bool remove = false;
751
752    // remove the aura if its caster or the dynamic object causing it was removed
753    // or if the target moves too far from the dynamic object
754    Unit *caster = GetCaster();
755    if (caster)
756    {
757        DynamicObject *dynObj = caster->GetDynObject(GetId(), GetEffIndex());
758        if (dynObj)
759        {
760            if (!m_target->IsWithinDistInMap(dynObj, dynObj->GetRadius()))
761                remove = true;
762        }
763        else
764            remove = true;
765    }
766    else
767        remove = true;
768
769    Unit *tmp_target = m_target;
770    uint32 tmp_id = GetId(), tmp_index = GetEffIndex();
771
772    // WARNING: the aura may get deleted during the update
773    // DO NOT access its members after update!
774    Aura::Update(diff);
775
776    if(remove)
777        tmp_target->RemoveAura(tmp_id, tmp_index);
778}
779
780void Aura::ApplyModifier(bool apply, bool Real)
781{
782    AuraType aura = m_modifier.m_auraname;
783
784    m_in_use = true;
785    if(aura<TOTAL_AURAS)
786        (*this.*AuraHandler [aura])(apply,Real);
787    m_in_use = false;
788}
789
790void Aura::UpdateAuraDuration()
791{
792    if(m_auraSlot >= MAX_AURAS || m_isPassive)
793        return;
794
795    if( m_target->GetTypeId() == TYPEID_PLAYER)
796    {
797        WorldPacket data(SMSG_UPDATE_AURA_DURATION, 5);
798        data << (uint8)m_auraSlot << (uint32)m_duration;
799        ((Player*)m_target)->SendDirectMessage(&data);
800
801        data.Initialize(SMSG_SET_EXTRA_AURA_INFO, (8+1+4+4+4));
802        data.append(m_target->GetPackGUID());
803        data << uint8(m_auraSlot);
804        data << uint32(GetId());
805        data << uint32(GetAuraMaxDuration());
806        data << uint32(GetAuraDuration());
807        ((Player*)m_target)->SendDirectMessage(&data);
808    }
809
810    // not send in case player loading (will not work anyway until player not added to map), sent in visibility change code
811    if(m_target->GetTypeId() == TYPEID_PLAYER && ((Player*)m_target)->GetSession()->PlayerLoading())
812        return;
813
814    Unit* caster = GetCaster();
815
816    if(caster && caster->GetTypeId() == TYPEID_PLAYER && caster != m_target)
817        SendAuraDurationForCaster((Player*)caster);
818}
819
820void Aura::SendAuraDurationForCaster(Player* caster)
821{
822    WorldPacket data(SMSG_SET_EXTRA_AURA_INFO_NEED_UPDATE, (8+1+4+4+4));
823    data.append(m_target->GetPackGUID());
824    data << uint8(m_auraSlot);
825    data << uint32(GetId());
826    data << uint32(GetAuraMaxDuration());                   // full
827    data << uint32(GetAuraDuration());                      // remain
828    caster->GetSession()->SendPacket(&data);
829}
830
831void Aura::_AddAura()
832{
833    if (!GetId())
834        return;
835    if(!m_target)
836        return;
837
838    // we can found aura in NULL_AURA_SLOT and then need store state instead check slot != NULL_AURA_SLOT
839    bool samespell = false;
840    bool secondaura = false;
841    uint8 slot = NULL_AURA_SLOT;
842
843    for(uint8 i = 0; i < 3; i++)
844    {
845        Unit::spellEffectPair spair = Unit::spellEffectPair(GetId(), i);
846        for(Unit::AuraMap::const_iterator itr = m_target->GetAuras().lower_bound(spair); itr != m_target->GetAuras().upper_bound(spair); ++itr)
847        {
848            // allow use single slot only by auras from same caster
849            if(itr->second->GetCasterGUID()==GetCasterGUID())
850            {
851                samespell = true;
852                if (m_effIndex > itr->second->GetEffIndex())
853                     secondaura = true;
854                slot = itr->second->GetAuraSlot();
855                break;
856            }
857        }
858
859        if(samespell)
860            break;
861    }
862
863    // not call total regen auras at adding
864    switch (m_modifier.m_auraname)
865    {
866        case SPELL_AURA_OBS_MOD_HEALTH:
867        case SPELL_AURA_OBS_MOD_MANA:
868            m_periodicTimer = m_modifier.periodictime;
869            break;
870        case SPELL_AURA_MOD_REGEN:
871        case SPELL_AURA_MOD_POWER_REGEN:
872        case SPELL_AURA_MOD_MANA_REGEN_FROM_STAT:
873            m_periodicTimer = 5000;
874            break;
875    }
876
877    // register aura
878    if (getDiminishGroup() != DIMINISHING_NONE )
879        m_target->ApplyDiminishingAura(getDiminishGroup(),true);
880
881    Unit* caster = GetCaster();
882
883    // passive auras (except totem auras) do not get placed in the slots
884    // area auras with SPELL_AURA_NONE are not shown on target
885    if((!m_isPassive || (caster && caster->GetTypeId() == TYPEID_UNIT && ((Creature*)caster)->isTotem())) &&
886        (m_spellProto->Effect[GetEffIndex()] != SPELL_EFFECT_APPLY_AREA_AURA_ENEMY || m_target != caster))
887    {
888        if(!samespell)                                      // new slot need
889        {
890            if (IsPositive())                               // empty positive slot
891            {
892                for (uint8 i = 0; i < MAX_POSITIVE_AURAS; i++)
893                {
894                    if (m_target->GetUInt32Value((uint16)(UNIT_FIELD_AURA + i)) == 0)
895                    {
896                        slot = i;
897                        break;
898                    }
899                }
900            }
901            else                                            // empty negative slot
902            {
903                for (uint8 i = MAX_POSITIVE_AURAS; i < MAX_AURAS; i++)
904                {
905                    if (m_target->GetUInt32Value((uint16)(UNIT_FIELD_AURA + i)) == 0)
906                    {
907                        slot = i;
908                        break;
909                    }
910                }
911            }
912
913            SetAuraSlot( slot );
914
915            // Not update fields for not first spell's aura, all data already in fields
916            if(!secondaura)
917            {
918                if(slot < MAX_AURAS)                        // slot found
919                {
920                    SetAura(slot, false);
921                    SetAuraFlag(slot, true);
922                    SetAuraLevel(slot,caster ? caster->getLevel() : sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL));
923                    UpdateAuraCharges();
924
925                    // update for out of range group members
926                    m_target->UpdateAuraForGroup(slot);
927                }
928
929                UpdateAuraDuration();
930            }
931        }
932        else                                                // use found slot
933        {
934            SetAuraSlot( slot );
935            // Not recalculate stack count for second aura of the same spell
936            if (!secondaura)
937                UpdateSlotCounterAndDuration(true);
938        }
939
940        // Update Seals information
941        if( IsSealSpell(GetSpellProto()) )
942            m_target->ModifyAuraState(AURA_STATE_JUDGEMENT, true);
943
944        // Conflagrate aura state
945        if (GetSpellProto()->SpellFamilyName == SPELLFAMILY_WARLOCK && (GetSpellProto()->SpellFamilyFlags & 4))
946            m_target->ModifyAuraState(AURA_STATE_IMMOLATE, true);
947
948        if(GetSpellProto()->SpellFamilyName == SPELLFAMILY_DRUID
949            && (GetSpellProto()->SpellFamilyFlags == 0x40 || GetSpellProto()->SpellFamilyFlags == 0x10))
950        {
951            m_target->ModifyAuraState(AURA_STATE_SWIFTMEND, true);
952        }
953    }
954}
955
956void Aura::_RemoveAura()
957{
958    // Remove all triggered by aura spells vs unlimited duration
959    // except same aura replace case
960    if(m_removeMode!=AURA_REMOVE_BY_STACK)
961        CleanupTriggeredSpells();
962
963    Unit* caster = GetCaster();
964
965    if(caster && IsPersistent())
966    {
967        DynamicObject *dynObj = caster->GetDynObject(GetId(), GetEffIndex());
968        if (dynObj)
969            dynObj->RemoveAffected(m_target);
970    }
971
972    // unregister aura
973    if (getDiminishGroup() != DIMINISHING_NONE )
974        m_target->ApplyDiminishingAura(getDiminishGroup(),false);
975
976    //passive auras do not get put in slots
977    // Note: but totem can be not accessible for aura target in time remove (to far for find in grid)
978    //if(m_isPassive && !(caster && caster->GetTypeId() == TYPEID_UNIT && ((Creature*)caster)->isTotem()))
979    //    return;
980
981    uint8 slot = GetAuraSlot();
982
983    if(slot >= MAX_AURAS)                                   // slot not set
984        return;
985
986    if(m_target->GetUInt32Value((uint16)(UNIT_FIELD_AURA + slot)) == 0)
987        return;
988
989    bool samespell = false;
990    bool sameaura = false;
991
992    // find other aura in same slot (current already removed from list)
993    for(uint8 i = 0; i < 3; i++)
994    {
995        Unit::spellEffectPair spair = Unit::spellEffectPair(GetId(), i);
996        for(Unit::AuraMap::const_iterator itr = m_target->GetAuras().lower_bound(spair); itr != m_target->GetAuras().upper_bound(spair); ++itr)
997        {
998            if(itr->second->GetAuraSlot()==slot)
999            {
1000                samespell = true;
1001
1002                if(GetEffIndex()==i)
1003                    sameaura = true;
1004
1005                break;
1006            }
1007        }
1008        if(samespell)
1009            break;
1010    }
1011
1012    // only remove icon when the last aura of the spell is removed (current aura already removed from list)
1013    if (!samespell)
1014    {
1015        SetAura(slot, true);
1016        SetAuraFlag(slot, false);
1017        SetAuraLevel(slot,caster ? caster->getLevel() : sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL));
1018
1019        SetAuraApplication(slot, 0);
1020        // update for out of range group members
1021        m_target->UpdateAuraForGroup(slot);
1022
1023        if( IsSealSpell(GetSpellProto()) )
1024            m_target->ModifyAuraState(AURA_STATE_JUDGEMENT,false);
1025
1026        // Conflagrate aura state
1027        if (GetSpellProto()->SpellFamilyName == SPELLFAMILY_WARLOCK && (GetSpellProto()->SpellFamilyFlags & 4))
1028            m_target->ModifyAuraState(AURA_STATE_IMMOLATE, false);
1029
1030        // Swiftmend aura state
1031        if(GetSpellProto()->SpellFamilyName == SPELLFAMILY_DRUID
1032            && (GetSpellProto()->SpellFamilyFlags == 0x40 || GetSpellProto()->SpellFamilyFlags == 0x10))
1033        {
1034            bool found = false;
1035            Unit::AuraList const& RejorRegr = m_target->GetAurasByType(SPELL_AURA_PERIODIC_HEAL);
1036            for(Unit::AuraList::const_iterator i = RejorRegr.begin(); i != RejorRegr.end(); ++i)
1037            {
1038                if((*i)->GetSpellProto()->SpellFamilyName == SPELLFAMILY_DRUID
1039                    && ((*i)->GetSpellProto()->SpellFamilyFlags == 0x40 || (*i)->GetSpellProto()->SpellFamilyFlags == 0x10) )
1040                {
1041                    found = true;
1042                    break;
1043                }
1044            }
1045            if(!found)
1046                m_target->ModifyAuraState(AURA_STATE_SWIFTMEND, false);
1047        }
1048
1049        // reset cooldown state for spells
1050        if(caster && caster->GetTypeId() == TYPEID_PLAYER)
1051        {
1052            if ( GetSpellProto()->Attributes & SPELL_ATTR_DISABLED_WHILE_ACTIVE )
1053                ((Player*)caster)->SendCooldownEvent(GetSpellProto());
1054        }
1055    }
1056    else if(sameaura)                                       // decrease count for spell, only for same aura effect, or this spell auras in remove process.
1057        UpdateSlotCounterAndDuration(false);
1058}
1059
1060void Aura::SetAuraFlag(uint32 slot, bool add)
1061{
1062    uint32 index    = slot / 4;
1063    uint32 byte     = (slot % 4) * 8;
1064    uint32 val      = m_target->GetUInt32Value(UNIT_FIELD_AURAFLAGS + index);
1065    val &= ~((uint32)AFLAG_MASK << byte);
1066    if(add)
1067    {
1068        if (IsPositive())
1069            val |= ((uint32)AFLAG_POSITIVE << byte);
1070        else
1071            val |= ((uint32)AFLAG_NEGATIVE << byte);
1072    }
1073    m_target->SetUInt32Value(UNIT_FIELD_AURAFLAGS + index, val);
1074}
1075
1076void Aura::SetAuraLevel(uint32 slot,uint32 level)
1077{
1078    uint32 index    = slot / 4;
1079    uint32 byte     = (slot % 4) * 8;
1080    uint32 val      = m_target->GetUInt32Value(UNIT_FIELD_AURALEVELS + index);
1081    val &= ~(0xFF << byte);
1082    val |= (level << byte);
1083    m_target->SetUInt32Value(UNIT_FIELD_AURALEVELS + index, val);
1084}
1085
1086void Aura::SetAuraApplication(uint32 slot, int8 count)
1087{
1088    uint32 index    = slot / 4;
1089    uint32 byte     = (slot % 4) * 8;
1090    uint32 val      = m_target->GetUInt32Value(UNIT_FIELD_AURAAPPLICATIONS + index);
1091    val &= ~(0xFF << byte);
1092    val |= ((uint8(count)) << byte);
1093    m_target->SetUInt32Value(UNIT_FIELD_AURAAPPLICATIONS + index, val);
1094}
1095
1096void Aura::UpdateSlotCounterAndDuration(bool add)
1097{
1098    uint8 slot = GetAuraSlot();
1099    if(slot >= MAX_AURAS)
1100        return;
1101
1102    // calculate amount of similar auras by same effect index (similar different spells)
1103    int8 count = 0;
1104
1105    // calculate auras and update durations in case aura adding
1106    Unit::AuraList const& aura_list = m_target->GetAurasByType(GetModifier()->m_auraname);
1107    for(Unit::AuraList::const_iterator i = aura_list.begin();i != aura_list.end(); ++i)
1108    {
1109        if( (*i)->GetId()==GetId() && (*i)->GetEffIndex()==m_effIndex &&
1110            (*i)->GetCasterGUID()==GetCasterGUID() )
1111        {
1112            ++count;
1113
1114            if(add)
1115                (*i)->SetAuraDuration(GetAuraDuration());
1116        }
1117    }
1118
1119    // at aura add aura not added yet, at aura remove aura already removed
1120    // in field stored (count-1)
1121    if(!add)
1122        --count;
1123
1124    SetAuraApplication(slot, count);
1125
1126    UpdateAuraDuration();
1127}
1128
1129/*********************************************************/
1130/***               BASIC AURA FUNCTION                 ***/
1131/*********************************************************/
1132void Aura::HandleAddModifier(bool apply, bool Real)
1133{
1134    if(m_target->GetTypeId() != TYPEID_PLAYER || !Real)
1135        return;
1136
1137    SpellEntry const *spellInfo = GetSpellProto();
1138    if(!spellInfo)
1139        return;
1140
1141    if(m_modifier.m_miscvalue >= MAX_SPELLMOD)
1142        return;
1143
1144    if (apply)
1145    {
1146        // Add custom charges for some mod aura
1147        switch (m_spellProto->Id)
1148        {
1149            case 17941:    // Shadow Trance
1150            case 22008:    // Netherwind Focus
1151            case 34936:    // Backlash
1152                m_procCharges = 1;
1153                break;
1154        }
1155
1156        SpellModifier *mod = new SpellModifier;
1157        mod->op = SpellModOp(m_modifier.m_miscvalue);
1158        mod->value = m_modifier.m_amount;
1159        mod->type = SpellModType(m_modifier.m_auraname);    // SpellModType value == spell aura types
1160        mod->spellId = GetId();
1161        mod->effectId = m_effIndex;
1162        mod->lastAffected = NULL;
1163
1164        uint64 spellAffectMask = spellmgr.GetSpellAffectMask(GetId(), m_effIndex);
1165
1166        if (spellAffectMask)
1167            mod->mask = spellAffectMask;
1168        else
1169            mod->mask = spellInfo->EffectItemType[m_effIndex];
1170
1171        if (m_procCharges > 0)
1172            mod->charges = m_procCharges;
1173        else
1174            mod->charges = 0;
1175
1176        m_spellmod = mod;
1177    }
1178
1179    uint64 spellFamilyMask = m_spellmod->mask;
1180
1181    ((Player*)m_target)->AddSpellMod(m_spellmod, apply);
1182
1183    // reapply some passive spells after add/remove related spellmods
1184    if(spellInfo->SpellFamilyName==SPELLFAMILY_WARRIOR && (spellFamilyMask & 0x0000100000000000LL))
1185    {
1186        m_target->RemoveAurasDueToSpell(45471);
1187
1188        if(apply)
1189            m_target->CastSpell(m_target,45471,true);
1190    }
1191}
1192
1193void Aura::TriggerSpell()
1194{
1195    Unit* caster = GetCaster();
1196    Unit* target = GetTriggerTarget();
1197
1198    if(!caster || !target)
1199        return;
1200
1201    // generic casting code with custom spells and target/caster customs
1202    uint32 trigger_spell_id = GetSpellProto()->EffectTriggerSpell[m_effIndex];
1203
1204    uint64 originalCasterGUID = GetCasterGUID();
1205
1206    SpellEntry const *triggeredSpellInfo = sSpellStore.LookupEntry(trigger_spell_id);
1207    SpellEntry const *auraSpellInfo = GetSpellProto();
1208    uint32 auraId = auraSpellInfo->Id;
1209
1210    // specific code for cases with no trigger spell provided in field
1211    if (triggeredSpellInfo == NULL)
1212    {
1213        switch(auraSpellInfo->SpellFamilyName)
1214        {
1215            case SPELLFAMILY_GENERIC:
1216            {
1217                switch(auraId)
1218                {
1219                    // Firestone Passive (1-5 ranks)
1220                    case 758:
1221                    case 17945:
1222                    case 17947:
1223                    case 17949:
1224                    case 27252:
1225                    {
1226                        if (caster->GetTypeId()!=TYPEID_PLAYER)
1227                            return;
1228                        Item* item = ((Player*)caster)->GetWeaponForAttack(BASE_ATTACK);
1229                        if (!item)
1230                            return;
1231                        uint32 enchant_id = 0;
1232                        switch (GetId())
1233                        {
1234                             case   758: enchant_id = 1803; break;   // Rank 1
1235                             case 17945: enchant_id = 1823; break;   // Rank 2
1236                             case 17947: enchant_id = 1824; break;   // Rank 3
1237                             case 17949: enchant_id = 1825; break;   // Rank 4
1238                             case 27252: enchant_id = 2645; break;   // Rank 5
1239                             default:
1240                                 return;
1241                        }
1242                        // remove old enchanting before applying new
1243                        ((Player*)caster)->ApplyEnchantment(item,TEMP_ENCHANTMENT_SLOT,false);
1244                        item->SetEnchantment(TEMP_ENCHANTMENT_SLOT, enchant_id, m_modifier.periodictime+1000, 0);
1245                        // add new enchanting
1246                        ((Player*)caster)->ApplyEnchantment(item,TEMP_ENCHANTMENT_SLOT,true);
1247                        return;
1248                    }
1249//                    // Periodic Mana Burn
1250//                    case 812: break;
1251//                    // Polymorphic Ray
1252//                    case 6965: break;
1253//                    // Fire Nova (1-7 ranks)
1254//                    case 8350:
1255//                    case 8508:
1256//                    case 8509:
1257//                    case 11312:
1258//                    case 11313:
1259//                    case 25540:
1260//                    case 25544:
1261//                        break;
1262                    // Thaumaturgy Channel
1263                    case 9712: trigger_spell_id = 21029; break;
1264//                    // Egan's Blaster
1265//                    case 17368: break;
1266//                    // Haunted
1267//                    case 18347: break;
1268//                    // Ranshalla Waiting
1269//                    case 18953: break;
1270//                    // Inferno
1271//                    case 19695: break;
1272//                    // Frostwolf Muzzle DND
1273//                    case 21794: break;
1274//                    // Alterac Ram Collar DND
1275//                    case 21866: break;
1276//                    // Celebras Waiting
1277//                    case 21916: break;
1278                    // Brood Affliction: Bronze
1279                    case 23170:
1280                    {
1281                        m_target->CastSpell(m_target, 23171, true, 0, this);
1282                        return;
1283                    }
1284//                    // Mark of Frost
1285//                    case 23184: break;
1286                    // Restoration
1287                    case 23493:
1288                    {
1289                        int32 heal = caster->GetMaxHealth() / 10;
1290                        caster->ModifyHealth( heal );
1291                        caster->SendHealSpellLog(caster, 23493, heal);
1292
1293                        int32 mana = caster->GetMaxPower(POWER_MANA);
1294                        if (mana)
1295                        {
1296                            mana /= 10;
1297                            caster->ModifyPower( POWER_MANA, mana );
1298                            caster->SendEnergizeSpellLog(caster, 23493, mana, POWER_MANA);
1299                        }
1300                        break;
1301                    }
1302//                    // Stoneclaw Totem Passive TEST
1303//                    case 23792: break;
1304//                    // Axe Flurry
1305//                    case 24018: break;
1306//                    // Mark of Arlokk
1307//                    case 24210: break;
1308//                    // Restoration
1309//                    case 24379: break;
1310//                    // Happy Pet
1311//                    case 24716: break;
1312//                    // Dream Fog
1313//                    case 24780: break;
1314//                    // Cannon Prep
1315//                    case 24832: break;
1316//                    // Shadow Bolt Whirl
1317//                    case 24834: break;
1318//                    // Stink Trap
1319//                    case 24918: break;
1320//                    // Mark of Nature
1321//                    case 25041: break;
1322//                    // Agro Drones
1323//                    case 25152: break;
1324//                    // Consume
1325//                    case 25371: break;
1326//                    // Pain Spike
1327//                    case 25572: break;
1328//                    // Rotate 360
1329//                    case 26009: break;
1330//                    // Rotate -360
1331//                    case 26136: break;
1332//                    // Consume
1333//                    case 26196: break;
1334//                    // Berserk
1335//                    case 26615: break;
1336//                    // Defile
1337//                    case 27177: break;
1338//                    // Teleport: IF/UC
1339//                    case 27601: break;
1340//                    // Five Fat Finger Exploding Heart Technique
1341//                    case 27673: break;
1342//                    // Nitrous Boost
1343//                    case 27746: break;
1344//                    // Steam Tank Passive
1345//                    case 27747: break;
1346//                    // Frost Blast
1347//                    case 27808: break;
1348//                    // Detonate Mana
1349//                    case 27819: break;
1350//                    // Controller Timer
1351//                    case 28095: break;
1352//                    // Stalagg Chain
1353//                    case 28096: break;
1354//                    // Stalagg Tesla Passive
1355//                    case 28097: break;
1356//                    // Feugen Tesla Passive
1357//                    case 28109: break;
1358//                    // Feugen Chain
1359//                    case 28111: break;
1360//                    // Mark of Didier
1361//                    case 28114: break;
1362//                    // Communique Timer, camp
1363//                    case 28346: break;
1364//                    // Icebolt
1365//                    case 28522: break;
1366//                    // Silithyst
1367//                    case 29519: break;
1368//                    // Inoculate Nestlewood Owlkin
1369                    case 29528: trigger_spell_id = 28713; break;
1370//                    // Overload
1371//                    case 29768: break;
1372//                    // Return Fire
1373//                    case 29788: break;
1374//                    // Return Fire
1375//                    case 29793: break;
1376//                    // Return Fire
1377//                    case 29794: break;
1378//                    // Guardian of Icecrown Passive
1379//                    case 29897: break;
1380                    // Feed Captured Animal
1381                    case 29917: trigger_spell_id = 29916; break;
1382//                    // Flame Wreath
1383//                    case 29946: break;
1384//                    // Flame Wreath
1385//                    case 29947: break;
1386//                    // Mind Exhaustion Passive
1387//                    case 30025: break;
1388//                    // Nether Beam - Serenity
1389//                    case 30401: break;
1390                    // Extract Gas
1391                    case 30427:
1392                    {
1393                        // move loot to player inventory and despawn target
1394                        if(caster->GetTypeId() ==TYPEID_PLAYER &&
1395                                target->GetTypeId() == TYPEID_UNIT &&
1396                                ((Creature*)target)->GetCreatureInfo()->type == CREATURE_TYPE_GAS_CLOUD)
1397                        {
1398                            Player* player = (Player*)caster;
1399                            Creature* creature = (Creature*)target;
1400                            // missing lootid has been reported on startup - just return
1401                            if (!creature->GetCreatureInfo()->SkinLootId)
1402                            {
1403                                return;
1404                            }
1405                            Loot *loot = &creature->loot;
1406                            loot->clear();
1407                            loot->FillLoot(creature->GetCreatureInfo()->SkinLootId, LootTemplates_Skinning, NULL);
1408                            for(uint8 i=0;i<loot->items.size();i++)
1409                            {
1410                                LootItem *item = loot->LootItemInSlot(i,player);
1411                                ItemPosCountVec dest;
1412                                uint8 msg = player->CanStoreNewItem( NULL_BAG, NULL_SLOT, dest, item->itemid, item->count );
1413                                if ( msg == EQUIP_ERR_OK )
1414                                {
1415                                    Item * newitem = player->StoreNewItem( dest, item->itemid, true, item->randomPropertyId);
1416
1417                                    player->SendNewItem(newitem, uint32(item->count), false, false, true);
1418                                }
1419                                else
1420                                    player->SendEquipError( msg, NULL, NULL );
1421                            }
1422                            creature->setDeathState(JUST_DIED);
1423                            creature->RemoveCorpse();
1424                            creature->SetHealth(0);         // just for nice GM-mode view
1425                        }
1426                        return;
1427                        break;
1428                    }
1429                    // Quake
1430                    case 30576: trigger_spell_id = 30571; break;
1431//                    // Burning Maul
1432//                    case 30598: break;
1433//                    // Regeneration
1434//                    case 30799:
1435//                    case 30800:
1436//                    case 30801:
1437//                        break;
1438//                    // Despawn Self - Smoke cloud
1439//                    case 31269: break;
1440//                    // Time Rift Periodic
1441//                    case 31320: break;
1442//                    // Corrupt Medivh
1443//                    case 31326: break;
1444                    // Doom
1445                    case 31347:
1446                    {
1447                        m_target->CastSpell(m_target,31350,true);
1448                        m_target->DealDamage(m_target, m_target->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
1449                        return;
1450                    }
1451                    // Spellcloth
1452                    case 31373:
1453                    {
1454                        // Summon Elemental after create item
1455                        caster->SummonCreature(17870, 0, 0, 0, caster->GetOrientation(), TEMPSUMMON_DEAD_DESPAWN, 0);
1456                        return;
1457                    }
1458//                    // Bloodmyst Tesla
1459//                    case 31611: break;
1460//                    // Doomfire
1461//                    case 31944: break;
1462//                    // Teleport Test
1463//                    case 32236: break;
1464//                    // Earthquake
1465//                    case 32686: break;
1466//                    // Possess
1467//                    case 33401: break;
1468//                    // Draw Shadows
1469//                    case 33563: break;
1470//                    // Murmur's Touch
1471//                    case 33711: break;
1472                    // Flame Quills
1473                    case 34229:
1474                    {
1475                        // cast 24 spells 34269-34289, 34314-34316
1476                        for(uint32 spell_id = 34269; spell_id != 34290; ++spell_id)
1477                            caster->CastSpell(m_target,spell_id,true);
1478                        for(uint32 spell_id = 34314; spell_id != 34317; ++spell_id)
1479                            caster->CastSpell(m_target,spell_id,true);
1480                        return;
1481                    }
1482//                    // Gravity Lapse
1483//                    case 34480: break;
1484//                    // Tornado
1485//                    case 34683: break;
1486//                    // Frostbite Rotate
1487//                    case 34748: break;
1488//                    // Arcane Flurry
1489//                    case 34821: break;
1490//                    // Interrupt Shutdown
1491//                    case 35016: break;
1492//                    // Interrupt Shutdown
1493//                    case 35176: break;
1494//                    // Inferno
1495//                    case 35268: break;
1496//                    // Salaadin's Tesla
1497//                    case 35515: break;
1498//                    // Ethereal Channel (Red)
1499//                    case 35518: break;
1500//                    // Nether Vapor
1501//                    case 35879: break;
1502//                    // Dark Portal Storm
1503//                    case 36018: break;
1504//                    // Burning Maul
1505//                    case 36056: break;
1506//                    // Living Grove Defender Lifespan
1507//                    case 36061: break;
1508//                    // Professor Dabiri Talks
1509//                    case 36064: break;
1510//                    // Kael Gaining Power
1511//                    case 36091: break;
1512//                    // They Must Burn Bomb Aura
1513//                    case 36344: break;
1514//                    // They Must Burn Bomb Aura (self)
1515//                    case 36350: break;
1516//                    // Stolen Ravenous Ravager Egg
1517//                    case 36401: break;
1518//                    // Activated Cannon
1519//                    case 36410: break;
1520//                    // Stolen Ravenous Ravager Egg
1521//                    case 36418: break;
1522//                    // Enchanted Weapons
1523//                    case 36510: break;
1524//                    // Cursed Scarab Periodic
1525//                    case 36556: break;
1526//                    // Cursed Scarab Despawn Periodic
1527//                    case 36561: break;
1528//                    // Vision Guide
1529//                    case 36573: break;
1530//                    // Cannon Charging (platform)
1531//                    case 36785: break;
1532//                    // Cannon Charging (self)
1533//                    case 36860: break;
1534                    // Remote Toy
1535                    case 37027: trigger_spell_id = 37029; break;
1536//                    // Mark of Death
1537//                    case 37125: break;
1538//                    // Arcane Flurry
1539//                    case 37268: break;
1540//                    // Spout
1541//                    case 37429: break;
1542//                    // Spout
1543//                    case 37430: break;
1544//                    // Karazhan - Chess NPC AI, Snapshot timer
1545//                    case 37440: break;
1546//                    // Karazhan - Chess NPC AI, action timer
1547//                    case 37504: break;
1548//                    // Karazhan - Chess: Is Square OCCUPIED aura (DND)
1549//                    case 39400: break;
1550//                    // Banish
1551//                    case 37546: break;
1552//                    // Shriveling Gaze
1553//                    case 37589: break;
1554//                    // Fake Aggro Radius (2 yd)
1555//                    case 37815: break;
1556//                    // Corrupt Medivh
1557//                    case 37853: break;
1558                    // Eye of Grillok
1559                    case 38495:
1560                    {
1561                        m_target->CastSpell(m_target, 38530, true);
1562                        return;
1563                    }
1564                    // Absorb Eye of Grillok (Zezzak's Shard)
1565                    case 38554:
1566                    {
1567                        if(m_target->GetTypeId() != TYPEID_UNIT)
1568                            return;
1569
1570                        caster->CastSpell(caster, 38495, true);
1571
1572                        Creature* creatureTarget = (Creature*)m_target;
1573
1574                        creatureTarget->setDeathState(JUST_DIED);
1575                        creatureTarget->RemoveCorpse();
1576                        creatureTarget->SetHealth(0);       // just for nice GM-mode view
1577                        return;
1578                    }
1579//                    // Magic Sucker Device timer
1580//                    case 38672: break;
1581//                    // Tomb Guarding Charging
1582//                    case 38751: break;
1583//                    // Murmur's Touch
1584//                    case 38794: break;
1585//                    // Activate Nether-wraith Beacon (31742 Nether-wraith Beacon item)
1586//                    case 39105: break;
1587//                    // Drain World Tree Visual
1588//                    case 39140: break;
1589//                    // Quest - Dustin's Undead Dragon Visual aura
1590//                    case 39259: break;
1591//                    // Hellfire - The Exorcism, Jules releases darkness, aura
1592//                    case 39306: break;
1593//                    // Inferno
1594//                    case 39346: break;
1595//                    // Enchanted Weapons
1596//                    case 39489: break;
1597//                    // Shadow Bolt Whirl
1598//                    case 39630: break;
1599//                    // Shadow Bolt Whirl
1600//                    case 39634: break;
1601//                    // Shadow Inferno
1602//                    case 39645: break;
1603                    // Tear of Azzinoth Summon Channel - it's not really supposed to do anything,and this only prevents the console spam
1604                    case 39857: trigger_spell_id = 39856; break;
1605//                    // Soulgrinder Ritual Visual (Smashed)
1606//                    case 39974: break;
1607//                    // Simon Game Pre-game timer
1608//                    case 40041: break;
1609//                    // Knockdown Fel Cannon: The Aggro Check Aura
1610//                    case 40113: break;
1611//                    // Spirit Lance
1612//                    case 40157: break;
1613//                    // Demon Transform 2
1614//                    case 40398: break;
1615//                    // Demon Transform 1
1616//                    case 40511: break;
1617//                    // Ancient Flames
1618//                    case 40657: break;
1619//                    // Ethereal Ring Cannon: Cannon Aura
1620//                    case 40734: break;
1621//                    // Cage Trap
1622//                    case 40760: break;
1623//                    // Random Periodic
1624//                    case 40867: break;
1625//                    // Prismatic Shield
1626//                    case 40879: break;
1627                    // Aura of Desire
1628                    case 41350:
1629                    {
1630                        Unit::AuraList const& mMod = m_target->GetAurasByType(SPELL_AURA_MOD_INCREASE_ENERGY_PERCENT);
1631                        for(Unit::AuraList::const_iterator i = mMod.begin(); i != mMod.end(); ++i)
1632                        {
1633                            if ((*i)->GetId() == 41350)
1634                            {
1635                                (*i)->ApplyModifier(false);
1636                                (*i)->GetModifier()->m_amount -= 5;
1637                                (*i)->ApplyModifier(true);
1638                                break;
1639                            }
1640                        }                       
1641                    }break;
1642//                    // Dementia
1643//                    case 41404: break;
1644//                    // Chaos Form
1645//                    case 41629: break;
1646//                    // Alert Drums
1647//                    case 42177: break;
1648//                    // Spout
1649//                    case 42581: break;
1650//                    // Spout
1651//                    case 42582: break;
1652//                    // Return to the Spirit Realm
1653//                    case 44035: break;
1654//                    // Curse of Boundless Agony
1655//                    case 45050: break;
1656//                    // Earthquake
1657//                    case 46240: break;
1658                    // Personalized Weather
1659                    case 46736: trigger_spell_id = 46737; break;
1660//                    // Stay Submerged
1661//                    case 46981: break;
1662//                    // Dragonblight Ram
1663//                    case 47015: break;
1664//                    // Party G.R.E.N.A.D.E.
1665//                    case 51510: break;
1666                    default:
1667                        break;
1668                }
1669                break;
1670            }
1671            case SPELLFAMILY_MAGE:
1672            {
1673                switch(auraId)
1674                {
1675                    // Invisibility
1676                    case 66:
1677                    {
1678                        if(!m_duration)
1679                            m_target->CastSpell(m_target, 32612, true, NULL, this);
1680                        return;
1681                    }
1682                    default:
1683                        break;
1684                }
1685                break;
1686            }
1687//            case SPELLFAMILY_WARRIOR:
1688//            {
1689//                switch(auraId)
1690//                {
1691//                    // Wild Magic
1692//                    case 23410: break;
1693//                    // Corrupted Totems
1694//                    case 23425: break;
1695//                    default:
1696//                        break;
1697//                }
1698//                break;
1699//            }
1700//            case SPELLFAMILY_PRIEST:
1701//            {
1702//                switch(auraId)
1703//                {
1704//                    // Blue Beam
1705//                    case 32930: break;
1706//                    // Fury of the Dreghood Elders
1707//                    case 35460: break;
1708//                    default:
1709//                        break;
1710//                }
1711 //               break;
1712 //           }
1713            case SPELLFAMILY_DRUID:
1714            {
1715                switch(auraId)
1716                {
1717                    // Cat Form
1718                    // trigger_spell_id not set and unknown effect triggered in this case, ignoring for while
1719                    case 768:
1720                        return;
1721                    // Frenzied Regeneration
1722                    case 22842:
1723                    case 22895:
1724                    case 22896:
1725                    case 26999:
1726                    {
1727                        int32 LifePerRage = GetModifier()->m_amount;
1728
1729                        int32 lRage = m_target->GetPower(POWER_RAGE);
1730                        if(lRage > 100)                                     // rage stored as rage*10
1731                            lRage = 100;
1732                        m_target->ModifyPower(POWER_RAGE, -lRage);
1733                        int32 FRTriggerBasePoints = int32(lRage*LifePerRage/10);
1734                        m_target->CastCustomSpell(m_target,22845,&FRTriggerBasePoints,NULL,NULL,true,NULL,this);
1735                        return;
1736                    }
1737                    default:
1738                        break;
1739                }
1740                break;
1741            }
1742
1743//            case SPELLFAMILY_HUNTER:
1744//            {
1745//                switch(auraId)
1746//                {
1747//                    //Frost Trap Aura
1748//                    case 13810:
1749//                        return;
1750//                    //Rizzle's Frost Trap
1751//                    case 39900:
1752//                        return;
1753//                    // Tame spells
1754//                    case 19597:         // Tame Ice Claw Bear
1755//                    case 19676:         // Tame Snow Leopard
1756//                    case 19677:         // Tame Large Crag Boar
1757//                    case 19678:         // Tame Adult Plainstrider
1758//                    case 19679:         // Tame Prairie Stalker
1759//                    case 19680:         // Tame Swoop
1760//                    case 19681:         // Tame Dire Mottled Boar
1761//                    case 19682:         // Tame Surf Crawler
1762//                    case 19683:         // Tame Armored Scorpid
1763//                    case 19684:         // Tame Webwood Lurker
1764//                    case 19685:         // Tame Nightsaber Stalker
1765//                    case 19686:         // Tame Strigid Screecher
1766//                    case 30100:         // Tame Crazed Dragonhawk
1767//                    case 30103:         // Tame Elder Springpaw
1768//                    case 30104:         // Tame Mistbat
1769//                    case 30647:         // Tame Barbed Crawler
1770//                    case 30648:         // Tame Greater Timberstrider
1771//                    case 30652:         // Tame Nightstalker
1772//                        return;
1773//                    default:
1774//                        break;
1775//                }
1776//                break;
1777//            }
1778            case SPELLFAMILY_SHAMAN:
1779            {
1780                switch(auraId)
1781                {
1782                    // Lightning Shield (The Earthshatterer set trigger after cast Lighting Shield)
1783                    case 28820:
1784                    {
1785                        // Need remove self if Lightning Shield not active
1786                        Unit::AuraMap const& auras = target->GetAuras();
1787                        for(Unit::AuraMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
1788                        {
1789                            SpellEntry const* spell = itr->second->GetSpellProto();
1790                            if( spell->SpellFamilyName == SPELLFAMILY_SHAMAN &&
1791                                spell->SpellFamilyFlags & 0x0000000000000400L)
1792                                return;
1793                        }
1794                        target->RemoveAurasDueToSpell(28820);
1795                        return;
1796                    }
1797                    // Totemic Mastery (Skyshatter Regalia (Shaman Tier 6) - bonus)
1798                    case 38443:
1799                    {
1800                        bool all = true;
1801                        for(int i = 0; i < MAX_TOTEM; ++i)
1802                        {
1803                            if(!caster->m_TotemSlot[i])
1804                            {
1805                                all = false;
1806                                break;
1807                            }
1808                        }
1809
1810                        if(all)
1811                            caster->CastSpell(caster,38437,true);
1812                        else
1813                            caster->RemoveAurasDueToSpell(38437);
1814                        return;
1815                    }
1816                    default:
1817                        break;
1818                }
1819                break;
1820            }
1821            default:
1822                break;
1823        }
1824        // Reget trigger spell proto
1825        triggeredSpellInfo = sSpellStore.LookupEntry(trigger_spell_id);
1826        if(triggeredSpellInfo == NULL)
1827        {
1828            sLog.outError("Aura::TriggerSpell: Spell %u have 0 in EffectTriggered[%d], not handled custom case?",GetId(),GetEffIndex());
1829            return;
1830        }
1831    }
1832    else
1833    {
1834        // Spell exist but require custom code
1835        switch(auraId)
1836        {
1837            // Curse of Idiocy
1838            case 1010:
1839            {
1840                // TODO: spell casted by result in correct way mostly
1841                // BUT:
1842                // 1) target show casting at each triggered cast: target don't must show casting animation for any triggered spell
1843                //      but must show affect apply like item casting
1844                // 2) maybe aura must be replace by new with accumulative stat mods instead stacking
1845
1846                // prevent cast by triggered auras
1847                if(m_caster_guid == m_target->GetGUID())
1848                    return;
1849
1850                // stop triggering after each affected stats lost > 90
1851                int32 intellectLoss = 0;
1852                int32 spiritLoss = 0;
1853
1854                Unit::AuraList const& mModStat = m_target->GetAurasByType(SPELL_AURA_MOD_STAT);
1855                for(Unit::AuraList::const_iterator i = mModStat.begin(); i != mModStat.end(); ++i)
1856                {
1857                    if ((*i)->GetId() == 1010)
1858                    {
1859                        switch((*i)->GetModifier()->m_miscvalue)
1860                        {
1861                            case STAT_INTELLECT: intellectLoss += (*i)->GetModifier()->m_amount; break;
1862                            case STAT_SPIRIT:    spiritLoss   += (*i)->GetModifier()->m_amount; break;
1863                            default: break;
1864                        }
1865                    }
1866                }
1867
1868                if(intellectLoss <= -90 && spiritLoss <= -90)
1869                    return;
1870
1871                caster = target;
1872                originalCasterGUID = 0;
1873                break;
1874            }
1875            // Mana Tide
1876            case 16191:
1877            {
1878                caster->CastCustomSpell(target, trigger_spell_id, &m_modifier.m_amount, NULL, NULL, true, NULL, this, originalCasterGUID);
1879                return;
1880            }
1881        }
1882    }
1883    m_target->CastSpell(target, triggeredSpellInfo, true, 0, this, originalCasterGUID);
1884}
1885
1886Unit* Aura::GetTriggerTarget() const
1887{
1888    Unit* target = ObjectAccessor::GetUnit(*m_target,
1889        /*m_target->GetTypeId()==TYPEID_PLAYER ?
1890        ((Player*)m_target)->GetSelection() :*/
1891        m_target->GetUInt64Value(UNIT_FIELD_TARGET));
1892    return target ? target : m_target;
1893}
1894
1895/*********************************************************/
1896/***                  AURA EFFECTS                     ***/
1897/*********************************************************/
1898
1899void Aura::HandleAuraDummy(bool apply, bool Real)
1900{
1901    // spells required only Real aura add/remove
1902    if(!Real)
1903        return;
1904
1905    Unit* caster = GetCaster();
1906
1907    // AT APPLY
1908    if(apply)
1909    {
1910        switch(GetId())
1911        {
1912            case 1515:                                      // Tame beast
1913                // FIX_ME: this is 2.0.12 threat effect replaced in 2.1.x by dummy aura, must be checked for correctness
1914                if( caster && m_target->CanHaveThreatList())
1915                    m_target->AddThreat(caster, 10.0f);
1916                return;
1917            case 13139:                                     // net-o-matic
1918                // root to self part of (root_target->charge->root_self sequence
1919                if(caster)
1920                    caster->CastSpell(caster,13138,true,NULL,this);
1921                return;
1922            case 39850:                                     // Rocket Blast
1923                if(roll_chance_i(20))                       // backfire stun
1924                    m_target->CastSpell(m_target, 51581, true, NULL, this);
1925                return;
1926            case 43873:                                     // Headless Horseman Laugh
1927                if(caster->GetTypeId() == TYPEID_PLAYER)
1928                    ((Player*)caster)->SendPlaySound(11965, false);
1929                return;
1930            case 46354:                                     // Blood Elf Illusion
1931                if(caster)
1932                {
1933                    switch(caster->getGender())
1934                    {
1935                        case GENDER_FEMALE:
1936                            caster->CastSpell(m_target,46356,true,NULL,this);
1937                            break;
1938                        case GENDER_MALE:
1939                            caster->CastSpell(m_target,46355,true,NULL,this);
1940                            break;
1941                        default:
1942                            break;
1943                    }
1944                }
1945                return;
1946            case 46699:                                     // Requires No Ammo
1947                if(m_target->GetTypeId()==TYPEID_PLAYER)
1948                    ((Player*)m_target)->RemoveAmmo();      // not use ammo and not allow use
1949                return;
1950        }
1951
1952        // Earth Shield
1953        if ( caster && GetSpellProto()->SpellFamilyName == SPELLFAMILY_SHAMAN && (GetSpellProto()->SpellFamilyFlags & 0x40000000000LL))
1954        {
1955            // prevent double apply bonuses
1956            if(m_target->GetTypeId()!=TYPEID_PLAYER || !((Player*)m_target)->GetSession()->PlayerLoading())
1957                m_modifier.m_amount = caster->SpellHealingBonus(GetSpellProto(), m_modifier.m_amount, SPELL_DIRECT_DAMAGE, m_target);
1958            return;
1959        }
1960    }
1961    // AT REMOVE
1962    else
1963    {
1964        if( m_target->GetTypeId() == TYPEID_PLAYER && GetSpellProto()->Effect[0]==72 )
1965        {
1966            // spells with SpellEffect=72 and aura=4: 6196, 6197, 21171, 21425
1967            ((Player*)m_target)->ClearFarsight();
1968            return;
1969        }
1970
1971        if( (IsQuestTameSpell(GetId())) && caster && caster->isAlive() && m_target->isAlive())
1972        {
1973            uint32 finalSpelId = 0;
1974            switch(GetId())
1975            {
1976                case 19548: finalSpelId = 19597; break;
1977                case 19674: finalSpelId = 19677; break;
1978                case 19687: finalSpelId = 19676; break;
1979                case 19688: finalSpelId = 19678; break;
1980                case 19689: finalSpelId = 19679; break;
1981                case 19692: finalSpelId = 19680; break;
1982                case 19693: finalSpelId = 19684; break;
1983                case 19694: finalSpelId = 19681; break;
1984                case 19696: finalSpelId = 19682; break;
1985                case 19697: finalSpelId = 19683; break;
1986                case 19699: finalSpelId = 19685; break;
1987                case 19700: finalSpelId = 19686; break;
1988                case 30646: finalSpelId = 30647; break;
1989                case 30653: finalSpelId = 30648; break;
1990                case 30654: finalSpelId = 30652; break;
1991                case 30099: finalSpelId = 30100; break;
1992                case 30102: finalSpelId = 30103; break;
1993                case 30105: finalSpelId = 30104; break;
1994            }
1995
1996            if(finalSpelId)
1997                caster->CastSpell(m_target,finalSpelId,true,NULL,this);
1998            return;
1999        }
2000
2001        // Dark Fiend
2002        if(GetId()==45934)
2003        {
2004            // Kill target if dispelled
2005            if (m_removeMode==AURA_REMOVE_BY_DISPEL)
2006                m_target->DealDamage(m_target, m_target->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
2007            return;
2008        }
2009
2010        // Burning Winds
2011        if(GetId()==46308)                                  // casted only at creatures at spawn
2012        {
2013            m_target->CastSpell(m_target,47287,true,NULL,this);
2014            return;
2015        }
2016    }
2017
2018    // AT APPLY & REMOVE
2019
2020    switch(m_spellProto->SpellFamilyName)
2021    {
2022        case SPELLFAMILY_GENERIC:
2023        {
2024            // Unstable Power
2025            if( GetId()==24658 )
2026            {
2027                uint32 spellId = 24659;
2028                if (apply)
2029                {
2030                    const SpellEntry *spell = sSpellStore.LookupEntry(spellId);
2031                    if (!spell)
2032                        return;
2033                    for (int i=0; i < spell->StackAmount; ++i)
2034                        caster->CastSpell(m_target, spell->Id, true, NULL, NULL, GetCasterGUID());
2035                    return;
2036                }
2037                m_target->RemoveAurasDueToSpell(spellId);
2038                return;
2039            }
2040            // Restless Strength
2041            if( GetId()==24661 )
2042            {
2043                uint32 spellId = 24662;
2044                if (apply)
2045                {
2046                    const SpellEntry *spell = sSpellStore.LookupEntry(spellId);
2047                    if (!spell)
2048                        return;
2049                    for (int i=0; i < spell->StackAmount; ++i)
2050                        caster->CastSpell(m_target, spell->Id, true, NULL, NULL, GetCasterGUID());
2051                    return;
2052                }
2053                m_target->RemoveAurasDueToSpell(spellId);
2054                return;
2055            }
2056            // Victorious
2057            if(GetId()==32216 && m_target->getClass()==CLASS_WARRIOR)
2058            {
2059                m_target->ModifyAuraState(AURA_STATE_WARRIOR_VICTORY_RUSH, apply);
2060                return;
2061            }
2062            //Summon Fire Elemental
2063            if (GetId() == 40133 && caster)
2064            {
2065                Unit *owner = caster->GetOwner();
2066                if (owner && owner->GetTypeId() == TYPEID_PLAYER)
2067                {
2068                    if(apply)
2069                        owner->CastSpell(owner,8985,true);
2070                    else
2071                        ((Player*)owner)->RemovePet(NULL, PET_SAVE_NOT_IN_SLOT, true);
2072                }
2073                return;
2074            }
2075
2076            //Summon Earth Elemental
2077            if (GetId() == 40132 && caster)
2078            {
2079                Unit *owner = caster->GetOwner();
2080                if (owner && owner->GetTypeId() == TYPEID_PLAYER)
2081                {
2082                    if(apply)
2083                        owner->CastSpell(owner,19704,true);
2084                    else
2085                        ((Player*)owner)->RemovePet(NULL, PET_SAVE_NOT_IN_SLOT, true);
2086                }
2087                return;
2088            }
2089            break;
2090        }
2091        case SPELLFAMILY_MAGE:
2092        {
2093            // Hypothermia
2094            if( GetId()==41425 )
2095            {
2096                m_target->ModifyAuraState(AURA_STATE_HYPOTHERMIA,apply);
2097                return;
2098            }
2099            break;
2100        }
2101        case SPELLFAMILY_DRUID:
2102        {
2103            // Lifebloom
2104            if ( GetSpellProto()->SpellFamilyFlags & 0x1000000000LL )
2105            {
2106                if ( apply )
2107                {
2108                    if ( caster )
2109                        // prevent double apply bonuses
2110                        if(m_target->GetTypeId()!=TYPEID_PLAYER || !((Player*)m_target)->GetSession()->PlayerLoading())
2111                            m_modifier.m_amount = caster->SpellHealingBonus(GetSpellProto(), m_modifier.m_amount, SPELL_DIRECT_DAMAGE, m_target);
2112                }
2113                else
2114                {
2115                    // Final heal only on dispelled or duration end
2116                    if ( !(GetAuraDuration() <= 0 || m_removeMode==AURA_REMOVE_BY_DISPEL) )
2117                        return;
2118
2119                    // have a look if there is still some other Lifebloom dummy aura
2120                    Unit::AuraList auras = m_target->GetAurasByType(SPELL_AURA_DUMMY);
2121                    for(Unit::AuraList::iterator itr = auras.begin(); itr!=auras.end(); itr++)
2122                        if((*itr)->GetSpellProto()->SpellFamilyName == SPELLFAMILY_DRUID &&
2123                            (*itr)->GetSpellProto()->SpellFamilyFlags & 0x1000000000LL)
2124                            return;
2125
2126                    // final heal
2127                    m_target->CastCustomSpell(m_target,33778,&m_modifier.m_amount,NULL,NULL,true,NULL,this,GetCasterGUID());
2128                }
2129                return;
2130            }
2131
2132            // Predatory Strikes
2133            if(m_target->GetTypeId()==TYPEID_PLAYER && GetSpellProto()->SpellIconID == 1563)
2134            {
2135                ((Player*)m_target)->UpdateAttackPowerAndDamage();
2136                return;
2137            }
2138            // Idol of the Emerald Queen
2139            if ( GetId() == 34246 && m_target->GetTypeId()==TYPEID_PLAYER )
2140            {
2141                if(apply)
2142                {
2143                    SpellModifier *mod = new SpellModifier;
2144                    mod->op = SPELLMOD_DOT;
2145                    mod->value = m_modifier.m_amount/7;
2146                    mod->type = SPELLMOD_FLAT;
2147                    mod->spellId = GetId();
2148                    mod->effectId = m_effIndex;
2149                    mod->lastAffected = NULL;
2150                    mod->mask = 0x001000000000LL;
2151                    mod->charges = 0;
2152
2153                    m_spellmod = mod;
2154                }
2155
2156                ((Player*)m_target)->AddSpellMod(m_spellmod, apply);
2157                return;
2158            }
2159            break;
2160        }
2161        case SPELLFAMILY_HUNTER:
2162        {
2163            // Improved Aspect of the Viper
2164            if( GetId()==38390 && m_target->GetTypeId()==TYPEID_PLAYER )
2165            {
2166                if(apply)
2167                {
2168                    // + effect value for Aspect of the Viper
2169                    SpellModifier *mod = new SpellModifier;
2170                    mod->op = SPELLMOD_EFFECT1;
2171                    mod->value = m_modifier.m_amount;
2172                    mod->type = SPELLMOD_FLAT;
2173                    mod->spellId = GetId();
2174                    mod->effectId = m_effIndex;
2175                    mod->lastAffected = NULL;
2176                    mod->mask = 0x4000000000000LL;
2177                    mod->charges = 0;
2178
2179                    m_spellmod = mod;
2180                }
2181
2182                ((Player*)m_target)->AddSpellMod(m_spellmod, apply);
2183                return;
2184            }
2185            break;
2186        }
2187        case SPELLFAMILY_SHAMAN:
2188        {
2189            // Improved Weapon Totems
2190            if( GetSpellProto()->SpellIconID == 57 && m_target->GetTypeId()==TYPEID_PLAYER )
2191            {
2192                if(apply)
2193                {
2194                    SpellModifier *mod = new SpellModifier;
2195                    mod->op = SPELLMOD_EFFECT1;
2196                    mod->value = m_modifier.m_amount;
2197                    mod->type = SPELLMOD_PCT;
2198                    mod->spellId = GetId();
2199                    mod->effectId = m_effIndex;
2200                    mod->lastAffected = NULL;
2201                    switch (m_effIndex)
2202                    {
2203                        case 0:
2204                            mod->mask = 0x00200000000LL;    // Windfury Totem
2205                            break;
2206                        case 1:
2207                            mod->mask = 0x00400000000LL;    // Flametongue Totem
2208                            break;
2209                    }
2210                    mod->charges = 0;
2211
2212                    m_spellmod = mod;
2213                }
2214
2215                ((Player*)m_target)->AddSpellMod(m_spellmod, apply);
2216                return;
2217            }
2218
2219            // Sentry Totem
2220            if (GetId() == 6495 && caster->GetTypeId() == TYPEID_PLAYER)
2221            {
2222                if (apply)
2223                {
2224                    uint64 guid = caster->m_TotemSlot[3];
2225                    if (guid)
2226                    {
2227                        Creature *totem = ObjectAccessor::GetCreature(*caster, guid);
2228                        if (totem && totem->isTotem())
2229                            totem->AddPlayerToVision((Player*)caster);
2230                    }
2231                } 
2232                else
2233                    ((Player*)caster)->RemoveFarsightTarget();
2234                return;
2235            }
2236            break;
2237        }
2238    }
2239
2240    // pet auras
2241    if(PetAura const* petSpell = spellmgr.GetPetAura(GetId()))
2242    {
2243        if(apply)
2244            m_target->AddPetAura(petSpell);
2245        else
2246            m_target->RemovePetAura(petSpell);
2247        return;
2248    }
2249}
2250
2251void Aura::HandleAuraPeriodicDummy(bool apply, bool Real)
2252{
2253    // spells required only Real aura add/remove
2254    if(!Real)
2255        return;
2256
2257    SpellEntry const*spell = GetSpellProto();
2258    switch( spell->SpellFamilyName)
2259    {
2260        case SPELLFAMILY_ROGUE:
2261        {
2262            // Master of Subtlety
2263            if (spell->Id==31666 && !apply && Real)
2264            {
2265                m_target->RemoveAurasDueToSpell(31665);
2266                break;
2267            }
2268            break;
2269        }
2270        case SPELLFAMILY_HUNTER:
2271        {
2272            // Aspect of the Viper
2273            if (spell->SpellFamilyFlags&0x0004000000000000LL)
2274            {
2275                // Update regen on remove
2276                if (!apply && m_target->GetTypeId() == TYPEID_PLAYER)
2277                    ((Player*)m_target)->UpdateManaRegen();
2278                break;
2279            }
2280            break;
2281        }
2282    }
2283
2284    m_isPeriodic = apply;
2285}
2286
2287void Aura::HandleAuraMounted(bool apply, bool Real)
2288{
2289    if(apply)
2290    {
2291        CreatureInfo const* ci = objmgr.GetCreatureTemplate(m_modifier.m_miscvalue);
2292        if(!ci)
2293        {
2294            sLog.outErrorDb("AuraMounted: `creature_template`='%u' not found in database (only need it modelid)", m_modifier.m_miscvalue);
2295            return;
2296        }
2297
2298        uint32 team = 0;
2299        if (m_target->GetTypeId()==TYPEID_PLAYER)
2300            team = ((Player*)m_target)->GetTeam();
2301
2302        uint32 display_id = objmgr.ChooseDisplayId(team,ci);
2303        CreatureModelInfo const *minfo = objmgr.GetCreatureModelRandomGender(display_id);
2304        if (minfo)
2305            display_id = minfo->modelid;
2306
2307        m_target->Mount(display_id);
2308    }
2309    else
2310    {
2311        m_target->Unmount();
2312    }
2313}
2314
2315void Aura::HandleAuraWaterWalk(bool apply, bool Real)
2316{
2317    // only at real add/remove aura
2318    if(!Real)
2319        return;
2320
2321    WorldPacket data;
2322    if(apply)
2323        data.Initialize(SMSG_MOVE_WATER_WALK, 8+4);
2324    else
2325        data.Initialize(SMSG_MOVE_LAND_WALK, 8+4);
2326    data.append(m_target->GetPackGUID());
2327    data << uint32(0);
2328    m_target->SendMessageToSet(&data,true);
2329}
2330
2331void Aura::HandleAuraFeatherFall(bool apply, bool Real)
2332{
2333    // only at real add/remove aura
2334    if(!Real)
2335        return;
2336
2337    WorldPacket data;
2338    if(apply)
2339        data.Initialize(SMSG_MOVE_FEATHER_FALL, 8+4);
2340    else
2341        data.Initialize(SMSG_MOVE_NORMAL_FALL, 8+4);
2342    data.append(m_target->GetPackGUID());
2343    data << (uint32)0;
2344    m_target->SendMessageToSet(&data,true);
2345}
2346
2347void Aura::HandleAuraHover(bool apply, bool Real)
2348{
2349    // only at real add/remove aura
2350    if(!Real)
2351        return;
2352
2353    WorldPacket data;
2354    if(apply)
2355        data.Initialize(SMSG_MOVE_SET_HOVER, 8+4);
2356    else
2357        data.Initialize(SMSG_MOVE_UNSET_HOVER, 8+4);
2358    data.append(m_target->GetPackGUID());
2359    data << uint32(0);
2360    m_target->SendMessageToSet(&data,true);
2361}
2362
2363void Aura::HandleWaterBreathing(bool apply, bool Real)
2364{
2365    if(apply)
2366        m_target->waterbreath = true;
2367    else if(m_target->GetAurasByType(SPELL_AURA_WATER_BREATHING).empty())
2368    {
2369        m_target->waterbreath = false;
2370
2371        // update for enable timer in case not moving target
2372        if(m_target->GetTypeId()==TYPEID_PLAYER && m_target->IsInWorld())
2373        {
2374            ((Player*)m_target)->UpdateUnderwaterState(m_target->GetMap(),m_target->GetPositionX(),m_target->GetPositionY(),m_target->GetPositionZ());
2375            ((Player*)m_target)->HandleDrowning();
2376        }
2377    }
2378}
2379
2380void Aura::HandleAuraModShapeshift(bool apply, bool Real)
2381{
2382    if(!Real)
2383        return;
2384
2385    uint32 modelid = 0;
2386    Powers PowerType = POWER_MANA;
2387    ShapeshiftForm form = ShapeshiftForm(m_modifier.m_miscvalue);
2388    switch(form)
2389    {
2390        case FORM_CAT:
2391            if(Player::TeamForRace(m_target->getRace())==ALLIANCE)
2392                modelid = 892;
2393            else
2394                modelid = 8571;
2395            PowerType = POWER_ENERGY;
2396            break;
2397        case FORM_TRAVEL:
2398            modelid = 632;
2399            break;
2400        case FORM_AQUA:
2401            if(Player::TeamForRace(m_target->getRace())==ALLIANCE)
2402                modelid = 2428;
2403            else
2404                modelid = 2428;
2405            break;
2406        case FORM_BEAR:
2407            if(Player::TeamForRace(m_target->getRace())==ALLIANCE)
2408                modelid = 2281;
2409            else
2410                modelid = 2289;
2411            PowerType = POWER_RAGE;
2412            break;
2413        case FORM_GHOUL:
2414            if(Player::TeamForRace(m_target->getRace())==ALLIANCE)
2415                modelid = 10045;
2416            break;
2417        case FORM_DIREBEAR:
2418            if(Player::TeamForRace(m_target->getRace())==ALLIANCE)
2419                modelid = 2281;
2420            else
2421                modelid = 2289;
2422            PowerType = POWER_RAGE;
2423            break;
2424        case FORM_CREATUREBEAR:
2425            modelid = 902;
2426            break;
2427        case FORM_GHOSTWOLF:
2428            modelid = 4613;
2429            break;
2430        case FORM_FLIGHT:
2431            if(Player::TeamForRace(m_target->getRace())==ALLIANCE)
2432                modelid = 20857;
2433            else
2434                modelid = 20872;
2435            break;
2436        case FORM_MOONKIN:
2437            if(Player::TeamForRace(m_target->getRace())==ALLIANCE)
2438                modelid = 15374;
2439            else
2440                modelid = 15375;
2441            break;
2442        case FORM_FLIGHT_EPIC:
2443            if(Player::TeamForRace(m_target->getRace())==ALLIANCE)
2444                modelid = 21243;
2445            else
2446                modelid = 21244;
2447            break;
2448        case FORM_AMBIENT:
2449        case FORM_SHADOW:
2450        case FORM_STEALTH:
2451            break;
2452        case FORM_TREE:
2453            modelid = 864;
2454            break;
2455        case FORM_BATTLESTANCE:
2456        case FORM_BERSERKERSTANCE:
2457        case FORM_DEFENSIVESTANCE:
2458            PowerType = POWER_RAGE;
2459            break;
2460        case FORM_SPIRITOFREDEMPTION:
2461            modelid = 16031;
2462            break;
2463        default:
2464            sLog.outError("Auras: Unknown Shapeshift Type: %u", m_modifier.m_miscvalue);
2465    }
2466
2467    // remove polymorph before changing display id to keep new display id
2468    switch ( form )
2469    {
2470        case FORM_CAT:
2471        case FORM_TREE:
2472        case FORM_TRAVEL:
2473        case FORM_AQUA:
2474        case FORM_BEAR:
2475        case FORM_DIREBEAR:
2476        case FORM_FLIGHT_EPIC:
2477        case FORM_FLIGHT:
2478        case FORM_MOONKIN:
2479            // remove movement affects
2480            m_target->RemoveSpellsCausingAura(SPELL_AURA_MOD_ROOT);
2481            m_target->RemoveSpellsCausingAura(SPELL_AURA_MOD_DECREASE_SPEED);
2482
2483            // and polymorphic affects
2484            if(m_target->IsPolymorphed())
2485                m_target->RemoveAurasDueToSpell(m_target->getTransForm());
2486            break;
2487        default:
2488           break;
2489    }
2490
2491    if(apply)
2492    {
2493        // remove other shapeshift before applying a new one
2494        if(m_target->m_ShapeShiftFormSpellId)
2495            m_target->RemoveAurasDueToSpell(m_target->m_ShapeShiftFormSpellId,this);
2496
2497        m_target->SetByteValue(UNIT_FIELD_BYTES_2, 3, form);
2498
2499        if(modelid > 0)
2500            m_target->SetDisplayId(modelid);
2501
2502        if(PowerType != POWER_MANA)
2503        {
2504            // reset power to default values only at power change
2505            if(m_target->getPowerType()!=PowerType)
2506                m_target->setPowerType(PowerType);
2507
2508            switch(form)
2509            {
2510                case FORM_CAT:
2511                case FORM_BEAR:
2512                case FORM_DIREBEAR:
2513                {
2514                    // get furor proc chance
2515                    uint32 FurorChance = 0;
2516                    Unit::AuraList const& mDummy = m_target->GetAurasByType(SPELL_AURA_DUMMY);
2517                    for(Unit::AuraList::const_iterator i = mDummy.begin(); i != mDummy.end(); ++i)
2518                    {
2519                        if ((*i)->GetSpellProto()->SpellIconID == 238)
2520                        {
2521                            FurorChance = (*i)->GetModifier()->m_amount;
2522                            break;
2523                        }
2524                    }
2525
2526                    if (m_modifier.m_miscvalue == FORM_CAT)
2527                    {
2528                        m_target->SetPower(POWER_ENERGY,0);
2529                        if(urand(1,100) <= FurorChance)
2530                            m_target->CastSpell(m_target,17099,true,NULL,this);
2531                    }
2532                    else
2533                    {
2534                        m_target->SetPower(POWER_RAGE,0);
2535                        if(urand(1,100) <= FurorChance)
2536                            m_target->CastSpell(m_target,17057,true,NULL,this);
2537                    }
2538                    break;
2539                }
2540                case FORM_BATTLESTANCE:
2541                case FORM_DEFENSIVESTANCE:
2542                case FORM_BERSERKERSTANCE:
2543                {
2544                    uint32 Rage_val = 0;
2545                    // Stance mastery + Tactical mastery (both passive, and last have aura only in defense stance, but need apply at any stance switch)
2546                    if(m_target->GetTypeId() == TYPEID_PLAYER)
2547                    {
2548                        PlayerSpellMap const& sp_list = ((Player *)m_target)->GetSpellMap();
2549                        for (PlayerSpellMap::const_iterator itr = sp_list.begin(); itr != sp_list.end(); ++itr)
2550                        {
2551                            if(itr->second->state == PLAYERSPELL_REMOVED) continue;
2552                            SpellEntry const *spellInfo = sSpellStore.LookupEntry(itr->first);
2553                            if (spellInfo && spellInfo->SpellFamilyName == SPELLFAMILY_WARRIOR && spellInfo->SpellIconID == 139)
2554                                Rage_val += m_target->CalculateSpellDamage(spellInfo,0,spellInfo->EffectBasePoints[0],m_target) * 10;
2555                        }
2556                    }
2557
2558                    if (m_target->GetPower(POWER_RAGE) > Rage_val)
2559                        m_target->SetPower(POWER_RAGE,Rage_val);
2560                    break;
2561                }
2562                default:
2563                    break;
2564            }
2565        }
2566
2567        m_target->m_ShapeShiftFormSpellId = GetId();
2568        m_target->m_form = form;
2569    }
2570    else
2571    {
2572        if(modelid > 0)
2573            m_target->SetDisplayId(m_target->GetNativeDisplayId());
2574        m_target->SetByteValue(UNIT_FIELD_BYTES_2, 3, FORM_NONE);
2575        if(m_target->getClass() == CLASS_DRUID)
2576            m_target->setPowerType(POWER_MANA);
2577        m_target->m_ShapeShiftFormSpellId = 0;
2578        m_target->m_form = FORM_NONE;
2579
2580        switch(form)
2581        {
2582            // Nordrassil Harness - bonus
2583            case FORM_BEAR:
2584            case FORM_DIREBEAR:
2585            case FORM_CAT:
2586            {
2587                if(Aura* dummy = m_target->GetDummyAura(37315) )
2588                    m_target->CastSpell(m_target,37316,true,NULL,dummy);
2589                break;
2590            }
2591            // Nordrassil Regalia - bonus
2592            case FORM_MOONKIN:
2593            {
2594                if(Aura* dummy = m_target->GetDummyAura(37324) )
2595                    m_target->CastSpell(m_target,37325,true,NULL,dummy);
2596                break;
2597            }
2598        }
2599    }
2600
2601    // adding/removing linked auras
2602    // add/remove the shapeshift aura's boosts
2603    HandleShapeshiftBoosts(apply);
2604
2605    if(m_target->GetTypeId()==TYPEID_PLAYER)
2606        ((Player*)m_target)->InitDataForForm();
2607}
2608
2609void Aura::HandleAuraTransform(bool apply, bool Real)
2610{
2611    if (apply)
2612    {
2613        // special case (spell specific functionality)
2614        if(m_modifier.m_miscvalue==0)
2615        {
2616            // player applied only
2617            if(m_target->GetTypeId()!=TYPEID_PLAYER)
2618                return;
2619
2620            switch(GetId())
2621            {
2622                // Orb of Deception
2623                case 16739:
2624                {
2625                    uint32 orb_model = m_target->GetNativeDisplayId();
2626                    switch(orb_model)
2627                    {
2628                        // Troll Female
2629                        case 1479: m_target->SetDisplayId(10134); break;
2630                        // Troll Male
2631                        case 1478: m_target->SetDisplayId(10135); break;
2632                        // Tauren Male
2633                        case 59:   m_target->SetDisplayId(10136); break;
2634                        // Human Male
2635                        case 49:   m_target->SetDisplayId(10137); break;
2636                        // Human Female
2637                        case 50:   m_target->SetDisplayId(10138); break;
2638                        // Orc Male
2639                        case 51:   m_target->SetDisplayId(10139); break;
2640                        // Orc Female
2641                        case 52:   m_target->SetDisplayId(10140); break;
2642                        // Dwarf Male
2643                        case 53:   m_target->SetDisplayId(10141); break;
2644                        // Dwarf Female
2645                        case 54:   m_target->SetDisplayId(10142); break;
2646                        // NightElf Male
2647                        case 55:   m_target->SetDisplayId(10143); break;
2648                        // NightElf Female
2649                        case 56:   m_target->SetDisplayId(10144); break;
2650                        // Undead Female
2651                        case 58:   m_target->SetDisplayId(10145); break;
2652                        // Undead Male
2653                        case 57:   m_target->SetDisplayId(10146); break;
2654                        // Tauren Female
2655                        case 60:   m_target->SetDisplayId(10147); break;
2656                        // Gnome Male
2657                        case 1563: m_target->SetDisplayId(10148); break;
2658                        // Gnome Female
2659                        case 1564: m_target->SetDisplayId(10149); break;
2660                        // BloodElf Female
2661                        case 15475: m_target->SetDisplayId(17830); break;
2662                        // BloodElf Male
2663                        case 15476: m_target->SetDisplayId(17829); break;
2664                        // Dranei Female
2665                        case 16126: m_target->SetDisplayId(17828); break;
2666                        // Dranei Male
2667                        case 16125: m_target->SetDisplayId(17827); break;
2668                        default: break;
2669                    }
2670                    break;
2671                }
2672                // Murloc costume
2673                case 42365: m_target->SetDisplayId(21723); break;
2674                default: break;
2675            }
2676        }
2677        else
2678        {
2679            CreatureInfo const * ci = objmgr.GetCreatureTemplate(m_modifier.m_miscvalue);
2680            if(!ci)
2681            {
2682                                                            //pig pink ^_^
2683                m_target->SetDisplayId(16358);
2684                sLog.outError("Auras: unknown creature id = %d (only need its modelid) Form Spell Aura Transform in Spell ID = %d", m_modifier.m_miscvalue, GetId());
2685            }
2686            else
2687            {
2688                if (uint32 modelid = ci->GetRandomValidModelId()) m_target->SetDisplayId(modelid);
2689
2690                // Dragonmaw Illusion (set mount model also)
2691                if(GetId()==42016 && m_target->GetMountID() && !m_target->GetAurasByType(SPELL_AURA_MOD_INCREASE_FLIGHT_SPEED).empty())
2692                    m_target->SetUInt32Value(UNIT_FIELD_MOUNTDISPLAYID,16314);
2693            }
2694            m_target->setTransForm(GetId());
2695        }
2696
2697        // polymorph case
2698        if( Real && m_target->GetTypeId() == TYPEID_PLAYER && m_target->IsPolymorphed())
2699        {
2700            // for players, start regeneration after 1s (in polymorph fast regeneration case)
2701            // only if caster is Player (after patch 2.4.2)
2702            if(IS_PLAYER_GUID(GetCasterGUID()) )
2703                ((Player*)m_target)->setRegenTimer(1000);
2704
2705            //dismount polymorphed target (after patch 2.4.2)
2706            if (m_target->IsMounted())
2707                m_target->RemoveSpellsCausingAura(SPELL_AURA_MOUNTED);
2708        }
2709    }
2710    else
2711    {
2712        Unit::AuraList const& otherTransforms = m_target->GetAurasByType(SPELL_AURA_TRANSFORM);
2713        if(otherTransforms.empty())
2714        {
2715            m_target->SetDisplayId(m_target->GetNativeDisplayId());
2716            m_target->setTransForm(0);
2717        }
2718        else
2719        {
2720            // look for other transform auras
2721            Aura* handledAura = *otherTransforms.begin();
2722            for(Unit::AuraList::const_iterator i = otherTransforms.begin();i != otherTransforms.end(); ++i)
2723            {
2724                // negative auras are preferred
2725                if(!IsPositiveSpell((*i)->GetSpellProto()->Id))
2726                {
2727                    handledAura = *i;
2728                    break;
2729                }
2730            }
2731            handledAura->ApplyModifier(true);
2732        }
2733
2734        // Dragonmaw Illusion (restore mount model)
2735        if(GetId()==42016 && m_target->GetMountID()==16314)
2736        {
2737            if(!m_target->GetAurasByType(SPELL_AURA_MOUNTED).empty())
2738            {
2739                uint32 cr_id = m_target->GetAurasByType(SPELL_AURA_MOUNTED).front()->GetModifier()->m_miscvalue;
2740                if(CreatureInfo const* ci = objmgr.GetCreatureTemplate(cr_id))
2741                {
2742                    uint32 team = 0;
2743                    if (m_target->GetTypeId()==TYPEID_PLAYER)
2744                        team = ((Player*)m_target)->GetTeam();
2745
2746                    uint32 display_id = objmgr.ChooseDisplayId(team,ci);
2747                    CreatureModelInfo const *minfo = objmgr.GetCreatureModelRandomGender(display_id);
2748                    if (minfo)
2749                        display_id = minfo->modelid;
2750
2751                    m_target->SetUInt32Value(UNIT_FIELD_MOUNTDISPLAYID,display_id);
2752                }
2753            }
2754        }
2755    }
2756}
2757
2758void Aura::HandleForceReaction(bool apply, bool Real)
2759{
2760    if(m_target->GetTypeId() != TYPEID_PLAYER)
2761        return;
2762
2763    if(!Real)
2764        return;
2765
2766    Player* player = (Player*)m_target;
2767
2768    uint32 faction_id = m_modifier.m_miscvalue;
2769    uint32 faction_rank = m_modifier.m_amount;
2770
2771    if(apply)
2772        player->m_forcedReactions[faction_id] = ReputationRank(faction_rank);
2773    else
2774        player->m_forcedReactions.erase(faction_id);
2775
2776    WorldPacket data;
2777    data.Initialize(SMSG_SET_FORCED_REACTIONS, 4+player->m_forcedReactions.size()*(4+4));
2778    data << uint32(player->m_forcedReactions.size());
2779    for(ForcedReactions::const_iterator itr = player->m_forcedReactions.begin(); itr != player->m_forcedReactions.end(); ++itr)
2780    {
2781        data << uint32(itr->first);                         // faction_id (Faction.dbc)
2782        data << uint32(itr->second);                        // reputation rank
2783    }
2784    player->SendDirectMessage(&data);
2785}
2786
2787void Aura::HandleAuraModSkill(bool apply, bool Real)
2788{
2789    if(m_target->GetTypeId() != TYPEID_PLAYER)
2790        return;
2791
2792    uint32 prot=GetSpellProto()->EffectMiscValue[m_effIndex];
2793    int32 points = GetModifier()->m_amount;
2794
2795    ((Player*)m_target)->ModifySkillBonus(prot,(apply ? points: -points),m_modifier.m_auraname==SPELL_AURA_MOD_SKILL_TALENT);
2796    if(prot == SKILL_DEFENSE)
2797        ((Player*)m_target)->UpdateDefenseBonusesMod();
2798}
2799
2800void Aura::HandleChannelDeathItem(bool apply, bool Real)
2801{
2802    if(Real && !apply)
2803    {
2804        Unit* caster = GetCaster();
2805        Unit* victim = GetTarget();
2806        if(!caster || caster->GetTypeId() != TYPEID_PLAYER || !victim || m_removeMode!=AURA_REMOVE_BY_DEATH)
2807            return;
2808
2809        SpellEntry const *spellInfo = GetSpellProto();
2810        if(spellInfo->EffectItemType[m_effIndex] == 0)
2811            return;
2812
2813        // Soul Shard only from non-grey units
2814        if( spellInfo->EffectItemType[m_effIndex] == 6265 &&
2815            (victim->getLevel() <= Trinity::XP::GetGrayLevel(caster->getLevel()) ||
2816             victim->GetTypeId()==TYPEID_UNIT && !((Player*)caster)->isAllowedToLoot((Creature*)victim)) )
2817            return;
2818        ItemPosCountVec dest;
2819        uint8 msg = ((Player*)caster)->CanStoreNewItem( NULL_BAG, NULL_SLOT, dest, spellInfo->EffectItemType[m_effIndex], 1 );
2820        if( msg != EQUIP_ERR_OK )
2821        {
2822            ((Player*)caster)->SendEquipError( msg, NULL, NULL );
2823            return;
2824        }
2825
2826        Item* newitem = ((Player*)caster)->StoreNewItem(dest, spellInfo->EffectItemType[m_effIndex], true);
2827        ((Player*)caster)->SendNewItem(newitem, 1, true, false);
2828    }
2829}
2830
2831void Aura::HandleBindSight(bool apply, bool Real)
2832{
2833    Unit* caster = GetCaster();
2834    if(!caster || caster->GetTypeId() != TYPEID_PLAYER)
2835        return;
2836
2837    if (apply)
2838        m_target->AddPlayerToVision((Player*)caster);
2839    else
2840        m_target->RemovePlayerFromVision((Player*)caster);
2841}
2842
2843void Aura::HandleFarSight(bool apply, bool Real)
2844{
2845    Unit* caster = GetCaster();
2846    if(!caster || caster->GetTypeId() != TYPEID_PLAYER)
2847        return;
2848
2849    caster->SetUInt64Value(PLAYER_FARSIGHT,apply ? m_modifier.m_miscvalue : 0);
2850}
2851
2852void Aura::HandleAuraTrackCreatures(bool apply, bool Real)
2853{
2854    if(m_target->GetTypeId()!=TYPEID_PLAYER)
2855        return;
2856
2857    if(apply)
2858        m_target->RemoveNoStackAurasDueToAura(this);
2859    m_target->SetUInt32Value(PLAYER_TRACK_CREATURES, apply ? ((uint32)1)<<(m_modifier.m_miscvalue-1) : 0 );
2860}
2861
2862void Aura::HandleAuraTrackResources(bool apply, bool Real)
2863{
2864    if(m_target->GetTypeId()!=TYPEID_PLAYER)
2865        return;
2866
2867    if(apply)
2868        m_target->RemoveNoStackAurasDueToAura(this);
2869    m_target->SetUInt32Value(PLAYER_TRACK_RESOURCES, apply ? ((uint32)1)<<(m_modifier.m_miscvalue-1): 0 );
2870}
2871
2872void Aura::HandleAuraTrackStealthed(bool apply, bool Real)
2873{
2874    if(m_target->GetTypeId()!=TYPEID_PLAYER)
2875        return;
2876
2877    if(apply)
2878        m_target->RemoveNoStackAurasDueToAura(this);
2879
2880    m_target->ApplyModFlag(PLAYER_FIELD_BYTES,PLAYER_FIELD_BYTE_TRACK_STEALTHED,apply);
2881}
2882
2883void Aura::HandleAuraModScale(bool apply, bool Real)
2884{
2885    m_target->ApplyPercentModFloatValue(OBJECT_FIELD_SCALE_X,m_modifier.m_amount,apply);
2886}
2887
2888void Aura::HandleModPossess(bool apply, bool Real)
2889{
2890    if(!Real)
2891        return;
2892
2893    if(m_target->getLevel() > m_modifier.m_amount)
2894        return;
2895
2896    // not possess yourself
2897    if(GetCasterGUID() == m_target->GetGUID())
2898        return;
2899
2900    Unit* caster = GetCaster();
2901    if(!caster)
2902        return;
2903
2904    if( apply )
2905    {
2906        if (caster->GetTypeId() == TYPEID_PLAYER)
2907            ((Player*)caster)->Possess(m_target);
2908    }
2909    else
2910        m_target->UnpossessSelf(true);
2911}
2912
2913void Aura::HandleModPossessPet(bool apply, bool Real)
2914{
2915    if(!Real)
2916        return;
2917
2918    Unit* caster = GetCaster();
2919    if(!caster || caster->GetTypeId() != TYPEID_PLAYER)
2920        return;
2921    if(caster->GetPet() != m_target)
2922        return;
2923
2924    if(apply)
2925    {
2926        ((Player*)caster)->Possess(m_target);
2927    }
2928    else
2929    {
2930        ((Player*)caster)->RemovePossess(false);
2931    }
2932}
2933
2934void Aura::HandleModCharm(bool apply, bool Real)
2935{
2936    if(!Real)
2937        return;
2938
2939    // not charm yourself
2940    if(GetCasterGUID() == m_target->GetGUID())
2941        return;
2942
2943    Unit* caster = GetCaster();
2944    if(!caster)
2945        return;
2946
2947    if(int32(m_target->getLevel()) <= m_modifier.m_amount)
2948    {
2949        if( apply )
2950        {
2951            m_target->SetCharmerGUID(GetCasterGUID());
2952            m_target->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE,caster->getFaction());
2953            m_target->CastStop(m_target==caster ? GetId() : 0);
2954            caster->SetCharm(m_target);
2955
2956            m_target->CombatStop();
2957            m_target->DeleteThreatList();
2958
2959            if(m_target->GetTypeId() == TYPEID_UNIT)
2960            {
2961                ((Creature*)m_target)->AIM_Initialize();
2962                CharmInfo *charmInfo = ((Creature*)m_target)->InitCharmInfo(m_target);
2963                charmInfo->InitCharmCreateSpells();
2964                charmInfo->SetReactState( REACT_DEFENSIVE );
2965
2966                if(caster->GetTypeId() == TYPEID_PLAYER && caster->getClass() == CLASS_WARLOCK)
2967                {
2968                    CreatureInfo const *cinfo = ((Creature*)m_target)->GetCreatureInfo();
2969                    if(cinfo && cinfo->type == CREATURE_TYPE_DEMON)
2970                    {
2971                        //to prevent client crash
2972                        m_target->SetFlag(UNIT_FIELD_BYTES_0, 2048);
2973                        //just to enable stat window
2974                        charmInfo->SetPetNumber(objmgr.GeneratePetNumber(), true);
2975                        //if charmed two demons the same session, the 2nd gets the 1st one's name
2976                        m_target->SetUInt32Value(UNIT_FIELD_PET_NAME_TIMESTAMP, time(NULL));
2977                    }
2978                }
2979            }
2980
2981            if(caster->GetTypeId() == TYPEID_PLAYER)
2982            {
2983                ((Player*)caster)->CharmSpellInitialize();
2984            }
2985        }
2986        else
2987        {
2988            m_target->SetCharmerGUID(0);
2989
2990            if(m_target->GetTypeId() == TYPEID_PLAYER)
2991                ((Player*)m_target)->setFactionForRace(m_target->getRace());
2992            else
2993            {
2994                CreatureInfo const *cinfo = ((Creature*)m_target)->GetCreatureInfo();
2995
2996                // restore faction
2997                if(((Creature*)m_target)->isPet())
2998                {
2999                    if(Unit* owner = m_target->GetOwner())
3000                        m_target->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE,owner->getFaction());
3001                    else if(cinfo)
3002                        m_target->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE,cinfo->faction_A);
3003                }
3004                else if(cinfo)                              // normal creature
3005                    m_target->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE,cinfo->faction_A);
3006
3007                // restore UNIT_FIELD_BYTES_0
3008                if(cinfo && caster->GetTypeId() == TYPEID_PLAYER && caster->getClass() == CLASS_WARLOCK && cinfo->type == CREATURE_TYPE_DEMON)
3009                {
3010                    CreatureDataAddon const *cainfo = ((Creature*)m_target)->GetCreatureAddon();
3011                    if(cainfo && cainfo->bytes0 != 0)
3012                        m_target->SetUInt32Value(UNIT_FIELD_BYTES_0, cainfo->bytes0);
3013                    else
3014                        m_target->RemoveFlag(UNIT_FIELD_BYTES_0, 2048);
3015
3016                    if(m_target->GetCharmInfo())
3017                        m_target->GetCharmInfo()->SetPetNumber(0, true);
3018                    else
3019                        sLog.outError("Aura::HandleModCharm: target="I64FMTD" with typeid=%d has a charm aura but no charm info!", m_target->GetGUID(), m_target->GetTypeId());
3020                }
3021            }
3022
3023            caster->SetCharm(0);
3024
3025            if(caster->GetTypeId() == TYPEID_PLAYER)
3026            {
3027                WorldPacket data(SMSG_PET_SPELLS, 8);
3028                data << uint64(0);
3029                ((Player*)caster)->GetSession()->SendPacket(&data);
3030            }
3031            if(m_target->GetTypeId() == TYPEID_UNIT)
3032            {
3033                ((Creature*)m_target)->AIM_Initialize();
3034                if (((Creature*)m_target)->AI())
3035                    ((Creature*)m_target)->AI()->AttackStart(caster);
3036            }
3037        }
3038    }
3039}
3040
3041void Aura::HandleModConfuse(bool apply, bool Real)
3042{
3043    if(!Real)
3044        return;
3045
3046    m_target->SetConfused(apply, GetCasterGUID(), GetId());
3047}
3048
3049void Aura::HandleModFear(bool apply, bool Real)
3050{
3051    if (!Real)
3052        return;
3053
3054    m_target->SetFeared(apply, GetCasterGUID(), GetId());
3055}
3056
3057void Aura::HandleFeignDeath(bool apply, bool Real)
3058{
3059    if(!Real)
3060        return;
3061
3062    if(m_target->GetTypeId() != TYPEID_PLAYER)
3063        return;
3064
3065    if( apply )
3066    {
3067        /*
3068        WorldPacket data(SMSG_FEIGN_DEATH_RESISTED, 9);
3069        data<<m_target->GetGUID();
3070        data<<uint8(0);
3071        m_target->SendMessageToSet(&data,true);
3072        */
3073                                                            // blizz like 2.0.x
3074        m_target->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNKNOWN6);
3075                                                            // blizz like 2.0.x
3076        m_target->SetFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_FEIGN_DEATH);
3077                                                            // blizz like 2.0.x
3078        m_target->SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_DEAD);
3079
3080        m_target->addUnitState(UNIT_STAT_DIED);
3081        m_target->CombatStop();
3082        m_target->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_UNATTACKABLE);
3083
3084        // prevent interrupt message
3085        if(m_caster_guid==m_target->GetGUID() && m_target->m_currentSpells[CURRENT_GENERIC_SPELL])
3086            m_target->m_currentSpells[CURRENT_GENERIC_SPELL]->finish();
3087        m_target->InterruptNonMeleeSpells(true);
3088        m_target->getHostilRefManager().deleteReferences();
3089    }
3090    else
3091    {
3092        /*
3093        WorldPacket data(SMSG_FEIGN_DEATH_RESISTED, 9);
3094        data<<m_target->GetGUID();
3095        data<<uint8(1);
3096        m_target->SendMessageToSet(&data,true);
3097        */
3098                                                            // blizz like 2.0.x
3099        m_target->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNKNOWN6);
3100                                                            // blizz like 2.0.x
3101        m_target->RemoveFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_FEIGN_DEATH);
3102                                                            // blizz like 2.0.x
3103        m_target->RemoveFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_DEAD);
3104
3105        m_target->clearUnitState(UNIT_STAT_DIED);
3106    }
3107}
3108
3109void Aura::HandleAuraModDisarm(bool apply, bool Real)
3110{
3111    if(!Real)
3112        return;
3113
3114    if(!apply && m_target->HasAuraType(SPELL_AURA_MOD_DISARM))
3115        return;
3116
3117    // not sure for it's correctness
3118    if(apply)
3119        m_target->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISARMED);
3120    else
3121        m_target->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISARMED);
3122
3123    // only at real add/remove aura
3124    if (m_target->GetTypeId() != TYPEID_PLAYER)
3125        return;
3126
3127    // main-hand attack speed already set to special value for feral form already and don't must change and reset at remove.
3128    if (((Player *)m_target)->IsInFeralForm())
3129        return;
3130
3131    if (apply)
3132        m_target->SetAttackTime(BASE_ATTACK,BASE_ATTACK_TIME);
3133    else
3134        ((Player *)m_target)->SetRegularAttackTime();
3135
3136    m_target->UpdateDamagePhysical(BASE_ATTACK);
3137}
3138
3139void Aura::HandleAuraModStun(bool apply, bool Real)
3140{
3141    if(!Real)
3142        return;
3143
3144    if (apply)
3145    {
3146        m_target->addUnitState(UNIT_STAT_STUNNED);
3147        m_target->SetUInt64Value(UNIT_FIELD_TARGET, 0);
3148
3149        m_target->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_ROTATE);
3150        m_target->CastStop(m_target->GetGUID() == GetCasterGUID() ? GetId() : 0);
3151
3152        // Creature specific
3153        if(m_target->GetTypeId() != TYPEID_PLAYER)
3154            ((Creature*)m_target)->StopMoving();
3155        else
3156            m_target->SetUnitMovementFlags(0);    //Clear movement flags
3157
3158        WorldPacket data(SMSG_FORCE_MOVE_ROOT, 8);
3159
3160        data.append(m_target->GetPackGUID());
3161        data << uint32(0);
3162        m_target->SendMessageToSet(&data,true);
3163    }
3164    else
3165    {
3166        // Real remove called after current aura remove from lists, check if other similar auras active
3167        if(m_target->HasAuraType(SPELL_AURA_MOD_STUN))
3168            return;
3169
3170        m_target->clearUnitState(UNIT_STAT_STUNNED);
3171        m_target->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_ROTATE);
3172
3173        if(!m_target->hasUnitState(UNIT_STAT_ROOT))         // prevent allow move if have also root effect
3174        {
3175            if(m_target->getVictim() && m_target->isAlive())
3176                m_target->SetUInt64Value(UNIT_FIELD_TARGET,m_target->getVictim()->GetGUID() );
3177
3178            WorldPacket data(SMSG_FORCE_MOVE_UNROOT, 8+4);
3179            data.append(m_target->GetPackGUID());
3180            data << uint32(0);
3181            m_target->SendMessageToSet(&data,true);
3182        }
3183
3184        // Wyvern Sting
3185        if (GetSpellProto()->SpellFamilyName == SPELLFAMILY_HUNTER && GetSpellProto()->SpellIconID == 1721)
3186        {
3187            Unit* caster = GetCaster();
3188            if( !caster || caster->GetTypeId()!=TYPEID_PLAYER )
3189                return;
3190
3191            uint32 spell_id = 0;
3192
3193            switch(GetId())
3194            {
3195                case 19386: spell_id = 24131; break;
3196                case 24132: spell_id = 24134; break;
3197                case 24133: spell_id = 24135; break;
3198                case 27068: spell_id = 27069; break;
3199                default:
3200                    sLog.outError("Spell selection called for unexpected original spell %u, new spell for this spell family?",GetId());
3201                    return;
3202            }
3203
3204            SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell_id);
3205
3206            if(!spellInfo)
3207                return;
3208
3209            caster->CastSpell(m_target,spellInfo,true,NULL,this);
3210            return;
3211        }
3212    }
3213}
3214
3215void Aura::HandleModStealth(bool apply, bool Real)
3216{
3217    if(apply)
3218    {
3219        if(Real && m_target->GetTypeId()==TYPEID_PLAYER)
3220        {
3221            // drop flag at stealth in bg
3222            m_target->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_UNATTACKABLE);
3223
3224            // remove player from the objective's active player count at stealth
3225            if(OutdoorPvP * pvp = ((Player*)m_target)->GetOutdoorPvP())
3226                pvp->HandlePlayerActivityChanged((Player*)m_target);
3227        }
3228
3229        // only at real aura add
3230        if(Real)
3231        {
3232            m_target->SetByteValue(UNIT_FIELD_BYTES_1, 2, 0x02);
3233            if(m_target->GetTypeId()==TYPEID_PLAYER)
3234                m_target->SetFlag(PLAYER_FIELD_BYTES2, 0x2000);
3235
3236            // apply only if not in GM invisibility (and overwrite invisibility state)
3237            if(m_target->GetVisibility()!=VISIBILITY_OFF)
3238            {
3239                //m_target->SetVisibility(VISIBILITY_GROUP_NO_DETECT);
3240                m_target->SetVisibility(VISIBILITY_OFF);
3241                m_target->SetVisibility(VISIBILITY_GROUP_STEALTH);
3242            }
3243
3244            // for RACE_NIGHTELF stealth
3245            if(m_target->GetTypeId()==TYPEID_PLAYER && GetId()==20580)
3246                m_target->CastSpell(m_target, 21009, true, NULL, this);
3247        }
3248    }
3249    else
3250    {
3251        // only at real aura remove
3252        if(Real)
3253        {
3254            // for RACE_NIGHTELF stealth
3255            if(m_target->GetTypeId()==TYPEID_PLAYER && GetId()==20580)
3256                m_target->RemoveAurasDueToSpell(21009);
3257
3258            // if last SPELL_AURA_MOD_STEALTH and no GM invisibility
3259            if(!m_target->HasAuraType(SPELL_AURA_MOD_STEALTH) && m_target->GetVisibility()!=VISIBILITY_OFF)
3260            {
3261                m_target->SetByteValue(UNIT_FIELD_BYTES_1, 2, 0x00);
3262                if(m_target->GetTypeId()==TYPEID_PLAYER)
3263                    m_target->RemoveFlag(PLAYER_FIELD_BYTES2, 0x2000);
3264
3265                // restore invisibility if any
3266                if(m_target->HasAuraType(SPELL_AURA_MOD_INVISIBILITY))
3267                {
3268                    //m_target->SetVisibility(VISIBILITY_GROUP_NO_DETECT);
3269                    //m_target->SetVisibility(VISIBILITY_GROUP_INVISIBILITY);
3270                    m_target->SetVisibility(VISIBILITY_ON);
3271                }
3272                else
3273                {
3274                    m_target->SetVisibility(VISIBILITY_ON);
3275                    if(m_target->GetTypeId() == TYPEID_PLAYER)
3276                        if(OutdoorPvP * pvp = ((Player*)m_target)->GetOutdoorPvP())
3277                            pvp->HandlePlayerActivityChanged((Player*)m_target);
3278                }
3279            }
3280        }
3281    }
3282
3283    // Master of Subtlety
3284    Unit::AuraList const& mDummyAuras = m_target->GetAurasByType(SPELL_AURA_DUMMY);
3285    for(Unit::AuraList::const_iterator i = mDummyAuras.begin();i != mDummyAuras.end(); ++i)
3286    {
3287        if ((*i)->GetSpellProto()->SpellIconID == 2114)
3288        {
3289            if (apply)
3290            {
3291                int32 bp = (*i)->GetModifier()->m_amount;
3292                m_target->CastCustomSpell(m_target,31665,&bp,NULL,NULL,true);
3293            }
3294            else
3295                m_target->CastSpell(m_target,31666,true);
3296            break;
3297        }
3298    }
3299}
3300
3301void Aura::HandleInvisibility(bool apply, bool Real)
3302{
3303    if(apply)
3304    {
3305        m_target->m_invisibilityMask |= (1 << m_modifier.m_miscvalue);
3306
3307        m_target->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_UNATTACKABLE);
3308
3309        if(Real && m_target->GetTypeId()==TYPEID_PLAYER)
3310        {
3311            // apply glow vision
3312            m_target->SetFlag(PLAYER_FIELD_BYTES2,PLAYER_FIELD_BYTE2_INVISIBILITY_GLOW);
3313            // remove player from the objective's active player count at invisibility
3314            if(OutdoorPvP * pvp = ((Player*)m_target)->GetOutdoorPvP())
3315                pvp->HandlePlayerActivityChanged((Player*)m_target);
3316        }
3317
3318        // apply only if not in GM invisibility and not stealth
3319        if(m_target->GetVisibility()==VISIBILITY_ON)
3320        {
3321            // Aura not added yet but visibility code expect temporary add aura
3322            //m_target->SetVisibility(VISIBILITY_GROUP_NO_DETECT);
3323            //m_target->SetVisibility(VISIBILITY_GROUP_INVISIBILITY);
3324            m_target->SetVisibility(VISIBILITY_ON);
3325        }
3326    }
3327    else
3328    {
3329        // recalculate value at modifier remove (current aura already removed)
3330        m_target->m_invisibilityMask = 0;
3331        Unit::AuraList const& auras = m_target->GetAurasByType(SPELL_AURA_MOD_INVISIBILITY);
3332        for(Unit::AuraList::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
3333            m_target->m_invisibilityMask |= (1 << m_modifier.m_miscvalue);
3334
3335        // only at real aura remove and if not have different invisibility auras.
3336        if(Real && m_target->m_invisibilityMask==0)
3337        {
3338            // remove glow vision
3339            if(m_target->GetTypeId() == TYPEID_PLAYER)
3340                m_target->RemoveFlag(PLAYER_FIELD_BYTES2,PLAYER_FIELD_BYTE2_INVISIBILITY_GLOW);
3341
3342            // apply only if not in GM invisibility & not stealthed while invisible
3343            if(m_target->GetVisibility()!=VISIBILITY_OFF)
3344            {
3345                // if have stealth aura then already have stealth visibility
3346                if(!m_target->HasAuraType(SPELL_AURA_MOD_STEALTH))
3347                {
3348                    m_target->SetVisibility(VISIBILITY_ON);
3349                    if(m_target->GetTypeId() == TYPEID_PLAYER)
3350                        if(OutdoorPvP * pvp = ((Player*)m_target)->GetOutdoorPvP())
3351                            pvp->HandlePlayerActivityChanged((Player*)m_target);
3352                }
3353            }
3354        }
3355    }
3356}
3357
3358void Aura::HandleInvisibilityDetect(bool apply, bool Real)
3359{
3360    if(apply)
3361    {
3362        m_target->m_detectInvisibilityMask |= (1 << m_modifier.m_miscvalue);
3363    }
3364    else
3365    {
3366        // recalculate value at modifier remove (current aura already removed)
3367        m_target->m_detectInvisibilityMask = 0;
3368        Unit::AuraList const& auras = m_target->GetAurasByType(SPELL_AURA_MOD_INVISIBILITY_DETECTION);
3369        for(Unit::AuraList::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
3370            m_target->m_detectInvisibilityMask |= (1 << m_modifier.m_miscvalue);
3371    }
3372    if(Real && m_target->GetTypeId()==TYPEID_PLAYER)
3373        ObjectAccessor::UpdateVisibilityForPlayer((Player*)m_target);
3374}
3375
3376void Aura::HandleAuraModRoot(bool apply, bool Real)
3377{
3378    // only at real add/remove aura
3379    if(!Real)
3380        return;
3381
3382    uint32 apply_stat = UNIT_STAT_ROOT;
3383    if (apply)
3384    {
3385        m_target->addUnitState(UNIT_STAT_ROOT);
3386        m_target->SetUInt64Value (UNIT_FIELD_TARGET, 0);
3387                                                            // probably wrong
3388        m_target->SetFlag(UNIT_FIELD_FLAGS,(apply_stat<<16));
3389
3390        //Save last orientation
3391        if( m_target->getVictim() )
3392            m_target->SetOrientation(m_target->GetAngle(m_target->getVictim()));
3393
3394        if(m_target->GetTypeId() == TYPEID_PLAYER)
3395        {
3396            WorldPacket data(SMSG_FORCE_MOVE_ROOT, 10);
3397            data.append(m_target->GetPackGUID());
3398            data << (uint32)2;
3399            m_target->SendMessageToSet(&data,true);
3400
3401            //Clear unit movement flags
3402            m_target->SetUnitMovementFlags(0);
3403        }
3404        else
3405            ((Creature *)m_target)->StopMoving();
3406    }
3407    else
3408    {
3409        // Real remove called after current aura remove from lists, check if other similar auras active
3410        if(m_target->HasAuraType(SPELL_AURA_MOD_ROOT))
3411            return;
3412
3413        m_target->clearUnitState(UNIT_STAT_ROOT);
3414                                                            // probably wrong
3415        m_target->RemoveFlag(UNIT_FIELD_FLAGS,(apply_stat<<16));
3416
3417        if(!m_target->hasUnitState(UNIT_STAT_STUNNED))      // prevent allow move if have also stun effect
3418        {
3419            if(m_target->getVictim() && m_target->isAlive())
3420                m_target->SetUInt64Value (UNIT_FIELD_TARGET,m_target->getVictim()->GetGUID() );
3421
3422            if(m_target->GetTypeId() == TYPEID_PLAYER)
3423            {
3424                WorldPacket data(SMSG_FORCE_MOVE_UNROOT, 10);
3425                data.append(m_target->GetPackGUID());
3426                data << (uint32)2;
3427                m_target->SendMessageToSet(&data,true);
3428            }
3429        }
3430    }
3431}
3432
3433void Aura::HandleAuraModSilence(bool apply, bool Real)
3434{
3435    // only at real add/remove aura
3436    if(!Real)
3437        return;
3438
3439    if(apply)
3440    {
3441        m_target->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SILENCED);
3442        // Stop cast only spells vs PreventionType == SPELL_PREVENTION_TYPE_SILENCE
3443        for (uint32 i = CURRENT_MELEE_SPELL; i < CURRENT_MAX_SPELL;i++)
3444        {
3445            Spell* currentSpell = m_target->m_currentSpells[i];
3446            if (currentSpell && currentSpell->m_spellInfo->PreventionType == SPELL_PREVENTION_TYPE_SILENCE)
3447            {
3448                uint32 state = currentSpell->getState();
3449                // Stop spells on prepare or casting state
3450                if ( state == SPELL_STATE_PREPARING || state == SPELL_STATE_CASTING )
3451                {
3452                    currentSpell->cancel();
3453                    currentSpell->SetReferencedFromCurrent(false);
3454                    m_target->m_currentSpells[i] = NULL;
3455                }
3456            }
3457        }
3458
3459        switch (GetId())
3460        {
3461            // Arcane Torrent (Energy)
3462            case 25046:
3463            {
3464                Unit * caster = GetCaster();
3465                if (!caster)
3466                    return;
3467
3468                // Search Mana Tap auras on caster
3469                int32 energy = 0;
3470                Unit::AuraList const& m_dummyAuras = caster->GetAurasByType(SPELL_AURA_DUMMY);
3471                for(Unit::AuraList::const_iterator i = m_dummyAuras.begin(); i != m_dummyAuras.end(); ++i)
3472                    if ((*i)->GetId() == 28734)
3473                        ++energy;
3474                if (energy)
3475                {
3476                    energy *= 10;
3477                    caster->CastCustomSpell(caster, 25048, &energy, NULL, NULL, true);
3478                    caster->RemoveAurasDueToSpell(28734);
3479                }
3480            }
3481        }
3482    }
3483    else
3484    {
3485        // Real remove called after current aura remove from lists, check if other similar auras active
3486        if(m_target->HasAuraType(SPELL_AURA_MOD_SILENCE))
3487            return;
3488
3489        m_target->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SILENCED);
3490    }
3491}
3492
3493void Aura::HandleModThreat(bool apply, bool Real)
3494{
3495    // only at real add/remove aura
3496    if(!Real)
3497        return;
3498
3499    if(!m_target->isAlive())
3500        return;
3501
3502    Unit* caster = GetCaster();
3503
3504    if(!caster || !caster->isAlive())
3505        return;
3506
3507    int level_diff = 0;
3508    int multiplier = 0;
3509    switch (GetId())
3510    {
3511        // Arcane Shroud
3512        case 26400:
3513            level_diff = m_target->getLevel() - 60;
3514            multiplier = 2;
3515            break;
3516        // The Eye of Diminution
3517        case 28862:
3518            level_diff = m_target->getLevel() - 60;
3519            multiplier = 1;
3520            break;
3521    }
3522    if (level_diff > 0)
3523        m_modifier.m_amount += multiplier * level_diff;
3524
3525    for(int8 x=0;x < MAX_SPELL_SCHOOL;x++)
3526    {
3527        if(m_modifier.m_miscvalue & int32(1<<x))
3528        {
3529            if(m_target->GetTypeId() == TYPEID_PLAYER)
3530                ApplyPercentModFloatVar(m_target->m_threatModifier[x], m_positive ? m_modifier.m_amount : -m_modifier.m_amount, apply);
3531        }
3532    }
3533}
3534
3535void Aura::HandleAuraModTotalThreat(bool apply, bool Real)
3536{
3537    // only at real add/remove aura
3538    if(!Real)
3539        return;
3540
3541    if(!m_target->isAlive() || m_target->GetTypeId()!= TYPEID_PLAYER)
3542        return;
3543
3544    Unit* caster = GetCaster();
3545
3546    if(!caster || !caster->isAlive())
3547        return;
3548
3549    float threatMod = 0.0f;
3550    if(apply)
3551        threatMod = float(m_modifier.m_amount);
3552    else
3553        threatMod =  float(-m_modifier.m_amount);
3554
3555    m_target->getHostilRefManager().threatAssist(caster, threatMod);
3556}
3557
3558void Aura::HandleModTaunt(bool apply, bool Real)
3559{
3560    // only at real add/remove aura
3561    if(!Real)
3562        return;
3563
3564    if(!m_target->isAlive() || !m_target->CanHaveThreatList())
3565        return;
3566
3567    Unit* caster = GetCaster();
3568
3569    if(!caster || !caster->isAlive() || caster->GetTypeId() != TYPEID_PLAYER)
3570        return;
3571
3572    if(apply)
3573        m_target->TauntApply(caster);
3574    else
3575    {
3576        // When taunt aura fades out, mob will switch to previous target if current has less than 1.1 * secondthreat
3577        m_target->TauntFadeOut(caster);
3578    }
3579}
3580
3581/*********************************************************/
3582/***                  MODIFY SPEED                     ***/
3583/*********************************************************/
3584void Aura::HandleAuraModIncreaseSpeed(bool apply, bool Real)
3585{
3586    // all applied/removed only at real aura add/remove
3587    if(!Real)
3588        return;
3589
3590    m_target->UpdateSpeed(MOVE_RUN, true);
3591}
3592
3593void Aura::HandleAuraModIncreaseMountedSpeed(bool apply, bool Real)
3594{
3595    // all applied/removed only at real aura add/remove
3596    if(!Real)
3597        return;
3598
3599    m_target->UpdateSpeed(MOVE_RUN, true);
3600}
3601
3602void Aura::HandleAuraModIncreaseFlightSpeed(bool apply, bool Real)
3603{
3604    // all applied/removed only at real aura add/remove
3605    if(!Real)
3606        return;
3607
3608    // Enable Fly mode for flying mounts
3609    if (m_modifier.m_auraname == SPELL_AURA_MOD_INCREASE_FLIGHT_SPEED)
3610    {
3611        WorldPacket data;
3612        if(apply)
3613            data.Initialize(SMSG_MOVE_SET_CAN_FLY, 12);
3614        else
3615            data.Initialize(SMSG_MOVE_UNSET_CAN_FLY, 12);
3616        data.append(m_target->GetPackGUID());
3617        data << uint32(0);                                      // unknown
3618        m_target->SendMessageToSet(&data, true);
3619
3620        //Players on flying mounts must be immune to polymorph
3621        if (m_target->GetTypeId()==TYPEID_PLAYER)
3622            m_target->ApplySpellImmune(GetId(),IMMUNITY_MECHANIC,MECHANIC_POLYMORPH,apply);
3623
3624        // Dragonmaw Illusion (overwrite mount model, mounted aura already applied)
3625        if( apply && m_target->HasAura(42016,0) && m_target->GetMountID())
3626            m_target->SetUInt32Value(UNIT_FIELD_MOUNTDISPLAYID,16314);
3627    }
3628
3629    m_target->UpdateSpeed(MOVE_FLY, true);
3630}
3631
3632void Aura::HandleAuraModIncreaseSwimSpeed(bool apply, bool Real)
3633{
3634    // all applied/removed only at real aura add/remove
3635    if(!Real)
3636        return;
3637
3638    m_target->UpdateSpeed(MOVE_SWIM, true);
3639}
3640
3641void Aura::HandleAuraModDecreaseSpeed(bool apply, bool Real)
3642{
3643    // all applied/removed only at real aura add/remove
3644    if(!Real)
3645        return;
3646
3647    m_target->UpdateSpeed(MOVE_RUN, true);
3648    m_target->UpdateSpeed(MOVE_SWIM, true);
3649    m_target->UpdateSpeed(MOVE_FLY, true);
3650}
3651
3652void Aura::HandleAuraModUseNormalSpeed(bool apply, bool Real)
3653{
3654    // all applied/removed only at real aura add/remove
3655    if(!Real)
3656        return;
3657
3658    m_target->UpdateSpeed(MOVE_RUN,  true);
3659    m_target->UpdateSpeed(MOVE_SWIM, true);
3660    m_target->UpdateSpeed(MOVE_FLY,  true);
3661}
3662
3663/*********************************************************/
3664/***                     IMMUNITY                      ***/
3665/*********************************************************/
3666
3667void Aura::HandleModMechanicImmunity(bool apply, bool Real)
3668{
3669    uint32 mechanic = 1 << m_modifier.m_miscvalue;
3670
3671    //immune movement impairment and loss of control
3672    if(GetId()==42292)
3673        mechanic=IMMUNE_TO_MOVEMENT_IMPAIRMENT_AND_LOSS_CONTROL_MASK;
3674
3675    if(apply && GetSpellProto()->AttributesEx & SPELL_ATTR_EX_DISPEL_AURAS_ON_IMMUNITY)
3676    {
3677        Unit::AuraMap& Auras = m_target->GetAuras();
3678        for(Unit::AuraMap::iterator iter = Auras.begin(), next; iter != Auras.end(); iter = next)
3679        {
3680            next = iter;
3681            ++next;
3682            SpellEntry const *spell = iter->second->GetSpellProto();
3683            if (!( spell->Attributes & SPELL_ATTR_UNAFFECTED_BY_INVULNERABILITY)  // spells unaffected by invulnerability
3684                && !iter->second->IsPositive()                                    // only remove negative spells
3685                && spell->Id != GetId())
3686            {
3687                //check for mechanic mask
3688                if(GetSpellMechanicMask(spell, iter->second->GetEffIndex()) & mechanic)
3689                {
3690                    m_target->RemoveAurasDueToSpell(spell->Id);
3691                    if(Auras.empty())
3692                        break;
3693                    else
3694                        next = Auras.begin();
3695                }
3696            }
3697        }
3698    }
3699
3700    m_target->ApplySpellImmune(GetId(),IMMUNITY_MECHANIC,m_modifier.m_miscvalue,apply);
3701
3702    // special cases
3703    switch(m_modifier.m_miscvalue)
3704    {
3705        case MECHANIC_INVULNERABILITY:
3706            m_target->ModifyAuraState(AURA_STATE_FORBEARANCE,apply);
3707            break;
3708        case MECHANIC_SHIELD:
3709            m_target->ModifyAuraState(AURA_STATE_WEAKENED_SOUL,apply);
3710            break;
3711    }
3712
3713    // Bestial Wrath
3714    if ( GetSpellProto()->SpellFamilyName == SPELLFAMILY_HUNTER && GetSpellProto()->Id == 19574)
3715    {
3716        // The Beast Within cast on owner if talent present
3717        if ( Unit* owner = m_target->GetOwner() )
3718        {
3719            // Search talent
3720            Unit::AuraList const& m_dummyAuras = owner->GetAurasByType(SPELL_AURA_DUMMY);
3721            for(Unit::AuraList::const_iterator i = m_dummyAuras.begin(); i != m_dummyAuras.end(); ++i)
3722            {
3723                if ( (*i)->GetSpellProto()->SpellIconID == 2229 )
3724                {
3725                    if (apply)
3726                        owner->CastSpell(owner, 34471, true, 0, this);
3727                    else
3728                        owner->RemoveAurasDueToSpell(34471);
3729                    break;
3730                }
3731            }
3732        }
3733    }
3734
3735    // The Beast Within and Bestial Wrath - immunity
3736    if(GetId() == 19574 || GetId() == 34471)
3737    {
3738        if(apply)
3739        {
3740            m_target->CastSpell(m_target,24395,true);
3741            m_target->CastSpell(m_target,24396,true);
3742            m_target->CastSpell(m_target,24397,true);
3743            m_target->CastSpell(m_target,26592,true);
3744        }
3745        else
3746        {
3747            m_target->RemoveAurasDueToSpell(24395);
3748            m_target->RemoveAurasDueToSpell(24396);
3749            m_target->RemoveAurasDueToSpell(24397);
3750            m_target->RemoveAurasDueToSpell(26592);
3751        }
3752    }
3753}
3754
3755void Aura::HandleAuraModEffectImmunity(bool apply, bool Real)
3756{
3757    if(!apply)
3758    {
3759        if(m_target->GetTypeId() == TYPEID_PLAYER)
3760        {
3761            if(((Player*)m_target)->InBattleGround())
3762            {
3763                BattleGround *bg = ((Player*)m_target)->GetBattleGround();
3764                if(bg)
3765                {
3766                    switch(bg->GetTypeID())
3767                    {
3768                        case BATTLEGROUND_AV:
3769                        {
3770                            break;
3771                        }
3772                        case BATTLEGROUND_WS:
3773                        {
3774                            // Warsong Flag, horde               // Silverwing Flag, alliance
3775                            if(GetId() == 23333 || GetId() == 23335)
3776                                    bg->EventPlayerDroppedFlag(((Player*)m_target));
3777                            break;
3778                        }
3779                        case BATTLEGROUND_AB:
3780                        {
3781                            break;
3782                        }
3783                        case BATTLEGROUND_EY:
3784                        {
3785                           if(GetId() == 34976)
3786                                bg->EventPlayerDroppedFlag(((Player*)m_target));
3787                            break;
3788                        }
3789                    }
3790                }
3791            }
3792            else
3793                sOutdoorPvPMgr.HandleDropFlag((Player*)m_target,GetSpellProto()->Id);
3794        }
3795    }
3796
3797    m_target->ApplySpellImmune(GetId(),IMMUNITY_EFFECT,m_modifier.m_miscvalue,apply);
3798}
3799
3800void Aura::HandleAuraModStateImmunity(bool apply, bool Real)
3801{
3802    if(apply && Real && GetSpellProto()->AttributesEx & SPELL_ATTR_EX_DISPEL_AURAS_ON_IMMUNITY)
3803    {
3804        Unit::AuraList const& auraList = m_target->GetAurasByType(AuraType(m_modifier.m_miscvalue));
3805        for(Unit::AuraList::const_iterator itr = auraList.begin(); itr != auraList.end();)
3806        {
3807            if (auraList.front() != this)                   // skip itself aura (it already added)
3808            {
3809                m_target->RemoveAurasDueToSpell(auraList.front()->GetId());
3810                itr = auraList.begin();
3811            }
3812            else
3813                ++itr;
3814        }
3815    }
3816
3817    m_target->ApplySpellImmune(GetId(),IMMUNITY_STATE,m_modifier.m_miscvalue,apply);
3818}
3819
3820void Aura::HandleAuraModSchoolImmunity(bool apply, bool Real)
3821{
3822    if(apply && m_modifier.m_miscvalue == SPELL_SCHOOL_MASK_NORMAL)
3823        m_target->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_UNATTACKABLE);
3824 
3825    m_target->ApplySpellImmune(GetId(),IMMUNITY_SCHOOL,m_modifier.m_miscvalue,apply);
3826
3827    if(Real && apply && GetSpellProto()->AttributesEx & SPELL_ATTR_EX_DISPEL_AURAS_ON_IMMUNITY)
3828    {
3829        if(IsPositiveSpell(GetId()))                        //Only positive immunity removes auras
3830        {
3831            uint32 school_mask = m_modifier.m_miscvalue;
3832            Unit::AuraMap& Auras = m_target->GetAuras();
3833            for(Unit::AuraMap::iterator iter = Auras.begin(), next; iter != Auras.end(); iter = next)
3834            {
3835                next = iter;
3836                ++next;
3837                SpellEntry const *spell = iter->second->GetSpellProto();
3838                if((GetSpellSchoolMask(spell) & school_mask)//Check for school mask
3839                    && !( spell->Attributes & SPELL_ATTR_UNAFFECTED_BY_INVULNERABILITY)   //Spells unaffected by invulnerability
3840                    && !iter->second->IsPositive()          //Don't remove positive spells
3841                    && spell->Id != GetId() )               //Don't remove self
3842                {
3843                    m_target->RemoveAurasDueToSpell(spell->Id);
3844                    if(Auras.empty())
3845                        break;
3846                    else
3847                        next = Auras.begin();
3848                }
3849            }
3850        }
3851    }
3852    if( Real && GetSpellProto()->Mechanic == MECHANIC_BANISH )
3853    {
3854        if( apply )
3855            m_target->addUnitState(UNIT_STAT_ISOLATED);
3856        else
3857            m_target->clearUnitState(UNIT_STAT_ISOLATED);
3858    }
3859}
3860
3861void Aura::HandleAuraModDmgImmunity(bool apply, bool Real)
3862{
3863    m_target->ApplySpellImmune(GetId(),IMMUNITY_DAMAGE,m_modifier.m_miscvalue,apply);
3864}
3865
3866void Aura::HandleAuraModDispelImmunity(bool apply, bool Real)
3867{
3868    // all applied/removed only at real aura add/remove
3869    if(!Real)
3870        return;
3871
3872    m_target->ApplySpellDispelImmunity(m_spellProto, DispelType(m_modifier.m_miscvalue), apply);
3873}
3874
3875void Aura::HandleAuraProcTriggerSpell(bool apply, bool Real)
3876{
3877    if(!Real)
3878        return;
3879
3880    if(apply)
3881    {
3882        // some spell have charges by functionality not have its in spell data
3883        switch (GetId())
3884        {
3885            case 28200:                                     // Ascendance (Talisman of Ascendance trinket)
3886                m_procCharges = 6;
3887                UpdateAuraCharges();
3888                break;
3889            default: break;
3890        }
3891    }
3892}
3893
3894void Aura::HandleAuraModStalked(bool apply, bool Real)
3895{
3896    // used by spells: Hunter's Mark, Mind Vision, Syndicate Tracker (MURP) DND
3897    if(apply)
3898        m_target->SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_TRACK_UNIT);
3899    else
3900        m_target->RemoveFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_TRACK_UNIT);
3901}
3902
3903/*********************************************************/
3904/***                   PERIODIC                        ***/
3905/*********************************************************/
3906
3907void Aura::HandlePeriodicTriggerSpell(bool apply, bool Real)
3908{
3909    if (m_periodicTimer <= 0)
3910        m_periodicTimer += m_modifier.periodictime;
3911
3912    m_isPeriodic = apply;
3913    m_isTrigger = apply;
3914
3915    // Curse of the Plaguebringer
3916    if (!apply && m_spellProto->Id == 29213 && m_removeMode!=AURA_REMOVE_BY_DISPEL)
3917    {
3918        // Cast Wrath of the Plaguebringer if not dispelled
3919        m_target->CastSpell(m_target, 29214, true, 0, this);
3920    }
3921}
3922
3923void Aura::HandlePeriodicEnergize(bool apply, bool Real)
3924{
3925    if (m_periodicTimer <= 0)
3926        m_periodicTimer += m_modifier.periodictime;
3927
3928    m_isPeriodic = apply;
3929}
3930
3931void Aura::HandlePeriodicHeal(bool apply, bool Real)
3932{
3933    if (m_periodicTimer <= 0)
3934        m_periodicTimer += m_modifier.periodictime;
3935
3936    m_isPeriodic = apply;
3937
3938    // only at real apply
3939    if (Real && apply && GetSpellProto()->Mechanic == MECHANIC_BANDAGE)
3940    {
3941        // provided m_target as original caster to prevent apply aura caster selection for this negative buff
3942        m_target->CastSpell(m_target,11196,true,NULL,this,m_target->GetGUID());
3943    }
3944
3945    // For prevent double apply bonuses
3946    bool loading = (m_target->GetTypeId() == TYPEID_PLAYER && ((Player*)m_target)->GetSession()->PlayerLoading());
3947
3948    if(!loading && apply)
3949    {
3950        switch (m_spellProto->SpellFamilyName)
3951        {
3952            case SPELLFAMILY_DRUID:
3953            {
3954                // Rejuvenation
3955                if(m_spellProto->SpellFamilyFlags & 0x0000000000000010LL)
3956                {
3957                    if(Unit* caster = GetCaster())
3958                    {
3959                        Unit::AuraList const& classScripts = caster->GetAurasByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS);
3960                        for(Unit::AuraList::const_iterator k = classScripts.begin(); k != classScripts.end(); ++k)
3961                        {
3962                            int32 tickcount = GetSpellDuration(m_spellProto) / m_spellProto->EffectAmplitude[m_effIndex];
3963                            switch((*k)->GetModifier()->m_miscvalue)
3964                            {
3965                                case 4953:                          // Increased Rejuvenation Healing - Harold's Rejuvenating Broach Aura
3966                                case 4415:                          // Increased Rejuvenation Healing - Idol of Rejuvenation Aura
3967                                {
3968                                    m_modifier.m_amount += (*k)->GetModifier()->m_amount / tickcount;
3969                                    break;
3970                                }
3971                            }
3972                        }
3973                    }
3974                }
3975            }
3976        }
3977    }
3978}
3979
3980void Aura::HandlePeriodicDamage(bool apply, bool Real)
3981{
3982    // spells required only Real aura add/remove
3983    if(!Real)
3984        return;
3985
3986    if (m_periodicTimer <= 0)
3987        m_periodicTimer += m_modifier.periodictime;
3988
3989    m_isPeriodic = apply;
3990
3991    // For prevent double apply bonuses
3992    bool loading = (m_target->GetTypeId() == TYPEID_PLAYER && ((Player*)m_target)->GetSession()->PlayerLoading());
3993
3994    Unit *caster = GetCaster();
3995
3996    switch (m_spellProto->SpellFamilyName)
3997    {
3998        case SPELLFAMILY_GENERIC:
3999        {
4000            // Pounce Bleed
4001            if ( m_spellProto->SpellIconID == 147 && m_spellProto->SpellVisual == 0 )
4002            {
4003                // $AP*0.18/6 bonus per tick
4004                if (apply && !loading && caster)
4005                    m_modifier.m_amount += int32(caster->GetTotalAttackPowerValue(BASE_ATTACK) * 3 / 100);
4006                return;
4007            }
4008            break;
4009        }
4010        case SPELLFAMILY_WARRIOR:
4011        {
4012            // Rend
4013            if (m_spellProto->SpellFamilyFlags & 0x0000000000000020LL)
4014            {
4015                // 0.00743*(($MWB+$mwb)/2+$AP/14*$MWS) bonus per tick
4016                if (apply && !loading && caster)
4017                {
4018                    float ap = caster->GetTotalAttackPowerValue(BASE_ATTACK);
4019                    int32 mws = caster->GetAttackTime(BASE_ATTACK);
4020                    float mwb_min = caster->GetWeaponDamageRange(BASE_ATTACK,MINDAMAGE);
4021                    float mwb_max = caster->GetWeaponDamageRange(BASE_ATTACK,MAXDAMAGE);
4022                    // WARNING! in 3.0 multiplier 0.00743f change to 0.6
4023                    m_modifier.m_amount+=int32(((mwb_min+mwb_max)/2+ap*mws/14000)*0.00743f);
4024                }
4025                return;
4026            }
4027            break;
4028        }
4029        case SPELLFAMILY_DRUID:
4030        {
4031            // Rake
4032            if (m_spellProto->SpellFamilyFlags & 0x0000000000001000LL)
4033            {
4034                // $AP*0.06/3 bonus per tick
4035                if (apply && !loading && caster)
4036                    m_modifier.m_amount += int32(caster->GetTotalAttackPowerValue(BASE_ATTACK) * 2 / 100);
4037                return;
4038            }
4039            // Lacerate
4040            if (m_spellProto->SpellFamilyFlags & 0x000000010000000000LL)
4041            {
4042                // $AP*0.05/5 bonus per tick
4043                if (apply && !loading && caster)
4044                    m_modifier.m_amount += int32(caster->GetTotalAttackPowerValue(BASE_ATTACK) / 100);
4045                return;
4046            }
4047            // Rip
4048            if (m_spellProto->SpellFamilyFlags & 0x000000000000800000LL)
4049            {
4050                // $AP * min(0.06*$cp, 0.24)/6 [Yes, there is no difference, whether 4 or 5 CPs are being used]
4051                if (apply && !loading && caster && caster->GetTypeId() == TYPEID_PLAYER)
4052                {
4053                    uint8 cp = ((Player*)caster)->GetComboPoints();
4054
4055                    // Idol of Feral Shadows. Cant be handled as SpellMod in SpellAura:Dummy due its dependency from CPs
4056                    Unit::AuraList const& dummyAuras = caster->GetAurasByType(SPELL_AURA_DUMMY);
4057                    for(Unit::AuraList::const_iterator itr = dummyAuras.begin(); itr != dummyAuras.end(); ++itr)
4058                    {
4059                        if((*itr)->GetId()==34241)
4060                        {
4061                            m_modifier.m_amount += cp * (*itr)->GetModifier()->m_amount;
4062                            break;
4063                        }
4064                    }
4065
4066                    if (cp > 4) cp = 4;
4067                    m_modifier.m_amount += int32(caster->GetTotalAttackPowerValue(BASE_ATTACK) * cp / 100);
4068                }
4069                return;
4070            }
4071            break;
4072        }
4073        case SPELLFAMILY_ROGUE:
4074        {
4075            // Deadly poison aura state
4076            if((m_spellProto->SpellFamilyFlags & 0x10000) && m_spellProto->SpellVisual==5100)
4077            {
4078                if(apply)
4079                    m_target->ModifyAuraState(AURA_STATE_DEADLY_POISON,true);
4080                else
4081                {
4082                    // current aura already removed, search present of another
4083                    bool found = false;
4084                    Unit::AuraList const& auras = m_target->GetAurasByType(SPELL_AURA_PERIODIC_DAMAGE);
4085                    for(Unit::AuraList::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
4086                    {
4087                        SpellEntry const* itr_spell = (*itr)->GetSpellProto();
4088                        if(itr_spell && itr_spell->SpellFamilyName==SPELLFAMILY_ROGUE && (itr_spell->SpellFamilyFlags & 0x10000) && itr_spell->SpellVisual==5100)
4089                        {
4090                            found = true;
4091                            break;
4092                        }
4093                    }
4094                    // this has been last deadly poison aura
4095                    if(!found)
4096                        m_target->ModifyAuraState(AURA_STATE_DEADLY_POISON,false);
4097                }
4098                return;
4099            }
4100            // Rupture
4101            if (m_spellProto->SpellFamilyFlags & 0x000000000000100000LL)
4102            {
4103                // Dmg/tick = $AP*min(0.01*$cp, 0.03) [Like Rip: only the first three CP increase the contribution from AP]
4104                if (apply && !loading && caster && caster->GetTypeId() == TYPEID_PLAYER)
4105                {
4106                    uint8 cp = ((Player*)caster)->GetComboPoints();
4107                    if (cp > 3) cp = 3;
4108                    m_modifier.m_amount += int32(caster->GetTotalAttackPowerValue(BASE_ATTACK) * cp / 100);
4109                }
4110                return;
4111            }
4112            // Garrote
4113            if (m_spellProto->SpellFamilyFlags & 0x000000000000000100LL)
4114            {
4115                // $AP*0.18/6 bonus per tick
4116                if (apply && !loading && caster)
4117                    m_modifier.m_amount += int32(caster->GetTotalAttackPowerValue(BASE_ATTACK) * 3 / 100);
4118                return;
4119            }
4120            break;
4121        }
4122        case SPELLFAMILY_HUNTER:
4123        {
4124            // Serpent Sting
4125            if (m_spellProto->SpellFamilyFlags & 0x0000000000004000LL)
4126            {
4127                // $RAP*0.1/5 bonus per tick
4128                if (apply && !loading && caster)
4129                    m_modifier.m_amount += int32(caster->GetTotalAttackPowerValue(RANGED_ATTACK) * 10 / 500);
4130                return;
4131            }
4132            // Immolation Trap
4133            if (m_spellProto->SpellFamilyFlags & 0x0000000000000004LL && m_spellProto->SpellIconID == 678)
4134            {
4135                // $RAP*0.1/5 bonus per tick
4136                if (apply && !loading && caster)
4137                    m_modifier.m_amount += int32(caster->GetTotalAttackPowerValue(RANGED_ATTACK) * 10 / 500);
4138                return;
4139            }
4140            break;
4141        }
4142        case SPELLFAMILY_PALADIN:
4143        {
4144            // Consecration
4145            if (m_spellProto->SpellFamilyFlags & 0x0000000000000020LL)
4146            {
4147                if (apply && !loading)
4148                {
4149                    if(Unit* caster = GetCaster())
4150                    {
4151                        Unit::AuraList const& classScripts = caster->GetAurasByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS);
4152                        for(Unit::AuraList::const_iterator k = classScripts.begin(); k != classScripts.end(); ++k)
4153                        {
4154                            int32 tickcount = GetSpellDuration(m_spellProto) / m_spellProto->EffectAmplitude[m_effIndex];
4155                            switch((*k)->GetModifier()->m_miscvalue)
4156                            {
4157                                case 5147:                  // Improved Consecration - Libram of the Eternal Rest
4158                                {
4159                                    m_modifier.m_amount += (*k)->GetModifier()->m_amount / tickcount;
4160                                    break;
4161                                }
4162                            }
4163                        }
4164                    }
4165                }
4166                return;
4167            }
4168            break;
4169        }
4170        default:
4171            break;
4172    }
4173}
4174
4175void Aura::HandlePeriodicDamagePCT(bool apply, bool Real)
4176{
4177    if (m_periodicTimer <= 0)
4178        m_periodicTimer += m_modifier.periodictime;
4179
4180    m_isPeriodic = apply;
4181}
4182
4183void Aura::HandlePeriodicLeech(bool apply, bool Real)
4184{
4185    if (m_periodicTimer <= 0)
4186        m_periodicTimer += m_modifier.periodictime;
4187
4188    m_isPeriodic = apply;
4189}
4190
4191void Aura::HandlePeriodicManaLeech(bool apply, bool Real)
4192{
4193    if (m_periodicTimer <= 0)
4194        m_periodicTimer += m_modifier.periodictime;
4195
4196    m_isPeriodic = apply;
4197}
4198
4199/*********************************************************/
4200/***                  MODIFY STATS                     ***/
4201/*********************************************************/
4202
4203/********************************/
4204/***        RESISTANCE        ***/
4205/********************************/
4206
4207void Aura::HandleAuraModResistanceExclusive(bool apply, bool Real)
4208{
4209    for(int8 x = SPELL_SCHOOL_NORMAL; x < MAX_SPELL_SCHOOL;x++)
4210    {
4211        if(m_modifier.m_miscvalue & int32(1<<x))
4212        {
4213            m_target->HandleStatModifier(UnitMods(UNIT_MOD_RESISTANCE_START + x), BASE_VALUE, float(m_modifier.m_amount), apply);
4214            if(m_target->GetTypeId() == TYPEID_PLAYER)
4215                m_target->ApplyResistanceBuffModsMod(SpellSchools(x),m_positive,m_modifier.m_amount, apply);
4216        }
4217    }
4218}
4219
4220void Aura::HandleAuraModResistance(bool apply, bool Real)
4221{
4222    for(int8 x = SPELL_SCHOOL_NORMAL; x < MAX_SPELL_SCHOOL;x++)
4223    {
4224        if(m_modifier.m_miscvalue & int32(1<<x))
4225        {
4226            m_target->HandleStatModifier(UnitMods(UNIT_MOD_RESISTANCE_START + x), TOTAL_VALUE, float(m_modifier.m_amount), apply);
4227            if(m_target->GetTypeId() == TYPEID_PLAYER || ((Creature*)m_target)->isPet())
4228                m_target->ApplyResistanceBuffModsMod(SpellSchools(x),m_positive,m_modifier.m_amount, apply);
4229        }
4230    }
4231
4232    // Faerie Fire (druid versions)
4233    if( m_spellProto->SpellIconID == 109 &&
4234        m_spellProto->SpellFamilyName == SPELLFAMILY_DRUID &&
4235        m_spellProto->SpellFamilyFlags & 0x0000000000000400LL )
4236    {
4237        m_target->ModifyAuraState(AURA_STATE_FAERIE_FIRE,apply);
4238    }
4239}
4240
4241void Aura::HandleAuraModBaseResistancePCT(bool apply, bool Real)
4242{
4243    // only players have base stats
4244    if(m_target->GetTypeId() != TYPEID_PLAYER)
4245    {
4246        //pets only have base armor
4247        if(((Creature*)m_target)->isPet() && (m_modifier.m_miscvalue & SPELL_SCHOOL_MASK_NORMAL))
4248            m_target->HandleStatModifier(UNIT_MOD_ARMOR, BASE_PCT, float(m_modifier.m_amount), apply);
4249    }
4250    else
4251    {
4252        for(int8 x = SPELL_SCHOOL_NORMAL; x < MAX_SPELL_SCHOOL;x++)
4253        {
4254            if(m_modifier.m_miscvalue & int32(1<<x))
4255                m_target->HandleStatModifier(UnitMods(UNIT_MOD_RESISTANCE_START + x), BASE_PCT, float(m_modifier.m_amount), apply);
4256        }
4257    }
4258}
4259
4260void Aura::HandleModResistancePercent(bool apply, bool Real)
4261{
4262    for(int8 i = SPELL_SCHOOL_NORMAL; i < MAX_SPELL_SCHOOL; i++)
4263    {
4264        if(m_modifier.m_miscvalue & int32(1<<i))
4265        {
4266            m_target->HandleStatModifier(UnitMods(UNIT_MOD_RESISTANCE_START + i), TOTAL_PCT, float(m_modifier.m_amount), apply);
4267            if(m_target->GetTypeId() == TYPEID_PLAYER || ((Creature*)m_target)->isPet())
4268            {
4269                m_target->ApplyResistanceBuffModsPercentMod(SpellSchools(i),true,m_modifier.m_amount, apply);
4270                m_target->ApplyResistanceBuffModsPercentMod(SpellSchools(i),false,m_modifier.m_amount, apply);
4271            }
4272        }
4273    }
4274}
4275
4276void Aura::HandleModBaseResistance(bool apply, bool Real)
4277{
4278    // only players have base stats
4279    if(m_target->GetTypeId() != TYPEID_PLAYER)
4280    {
4281        //only pets have base stats
4282        if(((Creature*)m_target)->isPet() && (m_modifier.m_miscvalue & SPELL_SCHOOL_MASK_NORMAL))
4283            m_target->HandleStatModifier(UNIT_MOD_ARMOR, TOTAL_VALUE, float(m_modifier.m_amount), apply);
4284    }
4285    else
4286    {
4287        for(int i = SPELL_SCHOOL_NORMAL; i < MAX_SPELL_SCHOOL; i++)
4288            if(m_modifier.m_miscvalue & (1<<i))
4289                m_target->HandleStatModifier(UnitMods(UNIT_MOD_RESISTANCE_START + i), TOTAL_VALUE, float(m_modifier.m_amount), apply);
4290    }
4291}
4292
4293/********************************/
4294/***           STAT           ***/
4295/********************************/
4296
4297void Aura::HandleAuraModStat(bool apply, bool Real)
4298{
4299    if (m_modifier.m_miscvalue < -2 || m_modifier.m_miscvalue > 4)
4300    {
4301        sLog.outError("WARNING: Spell %u effect %u have unsupported misc value (%i) for SPELL_AURA_MOD_STAT ",GetId(),GetEffIndex(),m_modifier.m_miscvalue);
4302        return;
4303    }
4304
4305    for(int32 i = STAT_STRENGTH; i < MAX_STATS; i++)
4306    {
4307        // -1 or -2 is all stats ( misc < -2 checked in function beginning )
4308        if (m_modifier.m_miscvalue < 0 || m_modifier.m_miscvalue == i)
4309        {
4310            //m_target->ApplyStatMod(Stats(i), m_modifier.m_amount,apply);
4311            m_target->HandleStatModifier(UnitMods(UNIT_MOD_STAT_START + i), TOTAL_VALUE, float(m_modifier.m_amount), apply);
4312            if(m_target->GetTypeId() == TYPEID_PLAYER || ((Creature*)m_target)->isPet())
4313                m_target->ApplyStatBuffMod(Stats(i),m_modifier.m_amount,apply);
4314        }
4315    }
4316}
4317
4318void Aura::HandleModPercentStat(bool apply, bool Real)
4319{
4320    if (m_modifier.m_miscvalue < -1 || m_modifier.m_miscvalue > 4)
4321    {
4322        sLog.outError("WARNING: Misc Value for SPELL_AURA_MOD_PERCENT_STAT not valid");
4323        return;
4324    }
4325
4326    // only players have base stats
4327    if (m_target->GetTypeId() != TYPEID_PLAYER)
4328        return;
4329
4330    for (int32 i = STAT_STRENGTH; i < MAX_STATS; ++i)
4331    {
4332        if(m_modifier.m_miscvalue == i || m_modifier.m_miscvalue == -1)
4333            m_target->HandleStatModifier(UnitMods(UNIT_MOD_STAT_START + i), BASE_PCT, float(m_modifier.m_amount), apply);
4334    }
4335}
4336
4337void Aura::HandleModSpellDamagePercentFromStat(bool apply, bool Real)
4338{
4339    if(m_target->GetTypeId() != TYPEID_PLAYER)
4340        return;
4341
4342    // Magic damage modifiers implemented in Unit::SpellDamageBonus
4343    // This information for client side use only
4344    // Recalculate bonus
4345    ((Player*)m_target)->UpdateSpellDamageAndHealingBonus();
4346}
4347
4348void Aura::HandleModSpellHealingPercentFromStat(bool apply, bool Real)
4349{
4350    if(m_target->GetTypeId() != TYPEID_PLAYER)
4351        return;
4352
4353    // Recalculate bonus
4354    ((Player*)m_target)->UpdateSpellDamageAndHealingBonus();
4355}
4356
4357void Aura::HandleAuraModDispelResist(bool apply, bool Real)
4358{
4359    if(!Real || !apply)
4360        return;
4361
4362    if(GetId()==33206)
4363        m_target->CastSpell(m_target,44416,true,NULL,this,GetCasterGUID());
4364}
4365
4366void Aura::HandleModSpellDamagePercentFromAttackPower(bool apply, bool Real)
4367{
4368    if(m_target->GetTypeId() != TYPEID_PLAYER)
4369        return;
4370
4371    // Magic damage modifiers implemented in Unit::SpellDamageBonus
4372    // This information for client side use only
4373    // Recalculate bonus
4374    ((Player*)m_target)->UpdateSpellDamageAndHealingBonus();
4375}
4376
4377void Aura::HandleModSpellHealingPercentFromAttackPower(bool apply, bool Real)
4378{
4379    if(m_target->GetTypeId() != TYPEID_PLAYER)
4380        return;
4381
4382    // Recalculate bonus
4383    ((Player*)m_target)->UpdateSpellDamageAndHealingBonus();
4384}
4385
4386void Aura::HandleModHealingDone(bool apply, bool Real)
4387{
4388    if(m_target->GetTypeId() != TYPEID_PLAYER)
4389        return;
4390    // implemented in Unit::SpellHealingBonus
4391    // this information is for client side only
4392    ((Player*)m_target)->UpdateSpellDamageAndHealingBonus();
4393}
4394
4395void Aura::HandleModTotalPercentStat(bool apply, bool Real)
4396{
4397    if (m_modifier.m_miscvalue < -1 || m_modifier.m_miscvalue > 4)
4398    {
4399        sLog.outError("WARNING: Misc Value for SPELL_AURA_MOD_PERCENT_STAT not valid");
4400        return;
4401    }
4402
4403    //save current and max HP before applying aura
4404    uint32 curHPValue = m_target->GetHealth();
4405    uint32 maxHPValue = m_target->GetMaxHealth();
4406
4407    for (int32 i = STAT_STRENGTH; i < MAX_STATS; i++)
4408    {
4409        if(m_modifier.m_miscvalue == i || m_modifier.m_miscvalue == -1)
4410        {
4411            m_target->HandleStatModifier(UnitMods(UNIT_MOD_STAT_START + i), TOTAL_PCT, float(m_modifier.m_amount), apply);
4412            if(m_target->GetTypeId() == TYPEID_PLAYER || ((Creature*)m_target)->isPet())
4413                m_target->ApplyStatPercentBuffMod(Stats(i), m_modifier.m_amount, apply );
4414        }
4415    }
4416
4417    //recalculate current HP/MP after applying aura modifications (only for spells with 0x10 flag)
4418    if ((m_modifier.m_miscvalue == STAT_STAMINA) && (maxHPValue > 0) && (m_spellProto->Attributes & 0x10))
4419    {
4420        // newHP = (curHP / maxHP) * newMaxHP = (newMaxHP * curHP) / maxHP -> which is better because no int -> double -> int conversion is needed
4421        uint32 newHPValue = (m_target->GetMaxHealth() * curHPValue) / maxHPValue;
4422        m_target->SetHealth(newHPValue);
4423    }
4424}
4425
4426void Aura::HandleAuraModResistenceOfStatPercent(bool apply, bool Real)
4427{
4428    if(m_target->GetTypeId() != TYPEID_PLAYER)
4429        return;
4430
4431    if(m_modifier.m_miscvalue != SPELL_SCHOOL_MASK_NORMAL)
4432    {
4433        // support required adding replace UpdateArmor by loop by UpdateResistence at intellect update
4434        // and include in UpdateResistence same code as in UpdateArmor for aura mod apply.
4435        sLog.outError("Aura SPELL_AURA_MOD_RESISTANCE_OF_STAT_PERCENT(182) need adding support for non-armor resistances!");
4436        return;
4437    }
4438
4439    // Recalculate Armor
4440    m_target->UpdateArmor();
4441}
4442
4443/********************************/
4444/***      HEAL & ENERGIZE     ***/
4445/********************************/
4446void Aura::HandleAuraModTotalHealthPercentRegen(bool apply, bool Real)
4447{
4448    /*
4449    Need additional checking for auras who reduce or increase healing, magic effect like Dumpen Magic,
4450    so this aura not fully working.
4451    */
4452    if(apply)
4453    {
4454        if(!m_target->isAlive())
4455            return;
4456
4457        if((GetSpellProto()->AuraInterruptFlags & AURA_INTERRUPT_FLAG_NOT_SEATED) && !m_target->IsSitState())
4458            m_target->SetStandState(PLAYER_STATE_SIT);
4459
4460        if(m_periodicTimer <= 0)
4461        {
4462            m_periodicTimer += m_modifier.periodictime;
4463
4464            if(m_target->GetHealth() < m_target->GetMaxHealth())
4465            {
4466                // PeriodicTick can cast triggered spells with stats changes
4467                PeriodicTick();
4468            }
4469        }
4470    }
4471
4472    m_isPeriodic = apply;
4473}
4474
4475void Aura::HandleAuraModTotalManaPercentRegen(bool apply, bool Real)
4476{
4477    if((GetSpellProto()->AuraInterruptFlags & AURA_INTERRUPT_FLAG_NOT_SEATED) && apply  && !m_target->IsSitState())
4478        m_target->SetStandState(PLAYER_STATE_SIT);
4479    if(apply)
4480    {
4481        if(m_modifier.periodictime == 0)
4482            m_modifier.periodictime = 1000;
4483        if(m_periodicTimer <= 0 && m_target->getPowerType() == POWER_MANA)
4484        {
4485            m_periodicTimer += m_modifier.periodictime;
4486
4487            if(m_target->GetPower(POWER_MANA) < m_target->GetMaxPower(POWER_MANA))
4488            {
4489                // PeriodicTick can cast triggered spells with stats changes
4490                PeriodicTick();
4491            }
4492        }
4493    }
4494
4495    m_isPeriodic = apply;
4496}
4497
4498void Aura::HandleModRegen(bool apply, bool Real)            // eating
4499{
4500    if(apply)
4501    {
4502        if(!m_target->isAlive())
4503            return;
4504
4505        if ((GetSpellProto()->AuraInterruptFlags & AURA_INTERRUPT_FLAG_NOT_SEATED)  && !m_target->IsSitState())
4506            m_target->SetStandState(PLAYER_STATE_SIT);
4507
4508        if(m_periodicTimer <= 0)
4509        {
4510            m_periodicTimer += 5000;
4511            int32 gain = m_target->ModifyHealth(m_modifier.m_amount);
4512            Unit *caster = GetCaster();
4513            if (caster)
4514            {
4515                SpellEntry const *spellProto = GetSpellProto();
4516                if (spellProto)
4517                    m_target->getHostilRefManager().threatAssist(caster, float(gain) * 0.5f, spellProto);
4518            }
4519        }
4520    }
4521
4522    m_isPeriodic = apply;
4523}
4524
4525void Aura::HandleModPowerRegen(bool apply, bool Real)       // drinking
4526{
4527    if ((GetSpellProto()->AuraInterruptFlags & AURA_INTERRUPT_FLAG_NOT_SEATED) && apply && !m_target->IsSitState())
4528        m_target->SetStandState(PLAYER_STATE_SIT);
4529
4530    if(apply && m_periodicTimer <= 0)
4531    {
4532        m_periodicTimer += 2000;
4533
4534        Powers pt = m_target->getPowerType();
4535        if(int32(pt) != m_modifier.m_miscvalue)
4536            return;
4537
4538        if ( GetSpellProto()->AuraInterruptFlags & AURA_INTERRUPT_FLAG_NOT_SEATED )
4539        {
4540            // eating anim
4541            m_target->HandleEmoteCommand(EMOTE_ONESHOT_EAT);
4542        }
4543        else if( GetId() == 20577 )
4544        {
4545            // cannibalize anim
4546            m_target->HandleEmoteCommand(398);
4547        }
4548
4549        // Warrior talent, gain 1 rage every 3 seconds while in combat
4550        if(pt == POWER_RAGE && m_target->isInCombat())
4551        {
4552            m_target->ModifyPower(pt, m_modifier.m_amount*10/17);
4553            m_periodicTimer += 1000;
4554        }
4555    }
4556    m_isPeriodic = apply;
4557    if (Real && m_target->GetTypeId() == TYPEID_PLAYER && m_modifier.m_miscvalue == POWER_MANA)
4558        ((Player*)m_target)->UpdateManaRegen();
4559}
4560
4561void Aura::HandleModPowerRegenPCT(bool apply, bool Real)
4562{
4563    // spells required only Real aura add/remove
4564    if(!Real)
4565        return;
4566
4567    if (m_target->GetTypeId() != TYPEID_PLAYER)
4568        return;
4569
4570    // Update manaregen value
4571    if (m_modifier.m_miscvalue == POWER_MANA)
4572        ((Player*)m_target)->UpdateManaRegen();
4573}
4574
4575void Aura::HandleModManaRegen(bool apply, bool Real)
4576{
4577    // spells required only Real aura add/remove
4578    if(!Real)
4579        return;
4580
4581    if (m_target->GetTypeId() != TYPEID_PLAYER)
4582        return;
4583
4584    //Note: an increase in regen does NOT cause threat.
4585    ((Player*)m_target)->UpdateManaRegen();
4586}
4587
4588void Aura::HandleComprehendLanguage(bool apply, bool Real)
4589{
4590    if(apply)
4591        m_target->SetFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_COMPREHEND_LANG);
4592    else
4593        m_target->RemoveFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_COMPREHEND_LANG);
4594}
4595
4596void Aura::HandleAuraModIncreaseHealth(bool apply, bool Real)
4597{
4598    if(Real)
4599    {
4600        if(apply)
4601        {
4602            m_target->HandleStatModifier(UNIT_MOD_HEALTH, TOTAL_VALUE, float(m_modifier.m_amount), apply);
4603            m_target->ModifyHealth(m_modifier.m_amount);
4604        }
4605        else
4606        {
4607            if (int32(m_target->GetHealth()) > m_modifier.m_amount)
4608                m_target->ModifyHealth(-m_modifier.m_amount);
4609            else
4610                m_target->SetHealth(1);
4611            m_target->HandleStatModifier(UNIT_MOD_HEALTH, TOTAL_VALUE, float(m_modifier.m_amount), apply);
4612        }
4613    }
4614}
4615
4616void  Aura::HandleAuraModIncreaseMaxHealth(bool apply, bool Real)
4617{
4618    uint32 oldhealth = m_target->GetHealth();
4619    double healthPercentage = (double)oldhealth / (double)m_target->GetMaxHealth();
4620
4621    m_target->HandleStatModifier(UNIT_MOD_HEALTH, TOTAL_VALUE, float(m_modifier.m_amount), apply);
4622
4623    // refresh percentage
4624    if(oldhealth > 0)
4625    {
4626        uint32 newhealth = uint32(ceil((double)m_target->GetMaxHealth() * healthPercentage));
4627        if(newhealth==0)
4628            newhealth = 1;
4629
4630        m_target->SetHealth(newhealth);
4631    }
4632}
4633
4634void Aura::HandleAuraModIncreaseEnergy(bool apply, bool Real)
4635{
4636    Powers powerType = m_target->getPowerType();
4637    if(int32(powerType) != m_modifier.m_miscvalue)
4638        return;
4639
4640    m_target->HandleStatModifier(UnitMods(UNIT_MOD_POWER_START + powerType), TOTAL_VALUE, float(m_modifier.m_amount), apply);
4641}
4642
4643void Aura::HandleAuraModIncreaseEnergyPercent(bool apply, bool Real)
4644{
4645    Powers powerType = m_target->getPowerType();
4646    if(int32(powerType) != m_modifier.m_miscvalue)
4647        return;
4648
4649    m_target->HandleStatModifier(UnitMods(UNIT_MOD_POWER_START + powerType), TOTAL_PCT, float(m_modifier.m_amount), apply);
4650}
4651
4652void Aura::HandleAuraModIncreaseHealthPercent(bool apply, bool Real)
4653{
4654    //m_target->ApplyMaxHealthPercentMod(m_modifier.m_amount,apply);
4655    m_target->HandleStatModifier(UNIT_MOD_HEALTH, TOTAL_PCT, float(m_modifier.m_amount), apply);
4656}
4657
4658/********************************/
4659/***          FIGHT           ***/
4660/********************************/
4661
4662void Aura::HandleAuraModParryPercent(bool apply, bool Real)
4663{
4664    if(m_target->GetTypeId()!=TYPEID_PLAYER)
4665        return;
4666
4667    ((Player*)m_target)->UpdateParryPercentage();
4668}
4669
4670void Aura::HandleAuraModDodgePercent(bool apply, bool Real)
4671{
4672    if(m_target->GetTypeId()!=TYPEID_PLAYER)
4673        return;
4674
4675    ((Player*)m_target)->UpdateDodgePercentage();
4676    //sLog.outError("BONUS DODGE CHANCE: + %f", float(m_modifier.m_amount));
4677}
4678
4679void Aura::HandleAuraModBlockPercent(bool apply, bool Real)
4680{
4681    if(m_target->GetTypeId()!=TYPEID_PLAYER)
4682        return;
4683
4684    ((Player*)m_target)->UpdateBlockPercentage();
4685    //sLog.outError("BONUS BLOCK CHANCE: + %f", float(m_modifier.m_amount));
4686}
4687
4688void Aura::HandleAuraModRegenInterrupt(bool apply, bool Real)
4689{
4690    // spells required only Real aura add/remove
4691    if(!Real)
4692        return;
4693
4694    if(m_target->GetTypeId()!=TYPEID_PLAYER)
4695        return;
4696
4697    ((Player*)m_target)->UpdateManaRegen();
4698}
4699
4700void Aura::HandleAuraModCritPercent(bool apply, bool Real)
4701{
4702    if(m_target->GetTypeId()!=TYPEID_PLAYER)
4703        return;
4704
4705    // apply item specific bonuses for already equipped weapon
4706    if(Real)
4707    {
4708        for(int i = 0; i < MAX_ATTACK; ++i)
4709            if(Item* pItem = ((Player*)m_target)->GetWeaponForAttack(WeaponAttackType(i)))
4710                ((Player*)m_target)->_ApplyWeaponDependentAuraCritMod(pItem,WeaponAttackType(i),this,apply);
4711    }
4712
4713    // mods must be applied base at equipped weapon class and subclass comparison
4714    // with spell->EquippedItemClass and  EquippedItemSubClassMask and EquippedItemInventoryTypeMask
4715    // m_modifier.m_miscvalue comparison with item generated damage types
4716
4717    if (GetSpellProto()->EquippedItemClass == -1)
4718    {
4719        ((Player*)m_target)->HandleBaseModValue(CRIT_PERCENTAGE,         FLAT_MOD, float (m_modifier.m_amount), apply);
4720        ((Player*)m_target)->HandleBaseModValue(OFFHAND_CRIT_PERCENTAGE, FLAT_MOD, float (m_modifier.m_amount), apply);
4721        ((Player*)m_target)->HandleBaseModValue(RANGED_CRIT_PERCENTAGE,  FLAT_MOD, float (m_modifier.m_amount), apply);
4722    }
4723    else
4724    {
4725        // done in Player::_ApplyWeaponDependentAuraMods
4726    }
4727}
4728
4729void Aura::HandleModHitChance(bool apply, bool Real)
4730{
4731    m_target->m_modMeleeHitChance += apply ? m_modifier.m_amount : (-m_modifier.m_amount);
4732    m_target->m_modRangedHitChance += apply ? m_modifier.m_amount : (-m_modifier.m_amount);
4733}
4734
4735void Aura::HandleModSpellHitChance(bool apply, bool Real)
4736{
4737    m_target->m_modSpellHitChance += apply ? m_modifier.m_amount: (-m_modifier.m_amount);
4738}
4739
4740void Aura::HandleModSpellCritChance(bool apply, bool Real)
4741{
4742    // spells required only Real aura add/remove
4743    if(!Real)
4744        return;
4745
4746    if(m_target->GetTypeId() == TYPEID_PLAYER)
4747    {
4748        ((Player*)m_target)->UpdateAllSpellCritChances();
4749    }
4750    else
4751    {
4752        m_target->m_baseSpellCritChance += apply ? m_modifier.m_amount:(-m_modifier.m_amount);
4753    }
4754}
4755
4756void Aura::HandleModSpellCritChanceShool(bool apply, bool Real)
4757{
4758    // spells required only Real aura add/remove
4759    if(!Real)
4760        return;
4761
4762    if(m_target->GetTypeId() != TYPEID_PLAYER)
4763        return;
4764
4765    for(int school = SPELL_SCHOOL_NORMAL; school < MAX_SPELL_SCHOOL; ++school)
4766        if (m_modifier.m_miscvalue & (1<<school))
4767            ((Player*)m_target)->UpdateSpellCritChance(school);
4768}
4769
4770/********************************/
4771/***         ATTACK SPEED     ***/
4772/********************************/
4773
4774void Aura::HandleModCastingSpeed(bool apply, bool Real)
4775{
4776    m_target->ApplyCastTimePercentMod(m_modifier.m_amount,apply);
4777}
4778
4779void Aura::HandleModMeleeRangedSpeedPct(bool apply, bool Real)
4780{
4781    m_target->ApplyAttackTimePercentMod(BASE_ATTACK,m_modifier.m_amount,apply);
4782    m_target->ApplyAttackTimePercentMod(OFF_ATTACK,m_modifier.m_amount,apply);
4783    m_target->ApplyAttackTimePercentMod(RANGED_ATTACK, m_modifier.m_amount, apply);
4784}
4785
4786void Aura::HandleModCombatSpeedPct(bool apply, bool Real)
4787{
4788    m_target->ApplyCastTimePercentMod(m_modifier.m_amount,apply);
4789    m_target->ApplyAttackTimePercentMod(BASE_ATTACK,m_modifier.m_amount,apply);
4790    m_target->ApplyAttackTimePercentMod(OFF_ATTACK,m_modifier.m_amount,apply);
4791    m_target->ApplyAttackTimePercentMod(RANGED_ATTACK, m_modifier.m_amount, apply);
4792}
4793
4794void Aura::HandleModAttackSpeed(bool apply, bool Real)
4795{
4796    if(!m_target->isAlive() )
4797        return;
4798
4799    m_target->ApplyAttackTimePercentMod(BASE_ATTACK,m_modifier.m_amount,apply);
4800}
4801
4802void Aura::HandleHaste(bool apply, bool Real)
4803{
4804    m_target->ApplyAttackTimePercentMod(BASE_ATTACK,  m_modifier.m_amount,apply);
4805    m_target->ApplyAttackTimePercentMod(OFF_ATTACK,   m_modifier.m_amount,apply);
4806    m_target->ApplyAttackTimePercentMod(RANGED_ATTACK,m_modifier.m_amount,apply);
4807}
4808
4809void Aura::HandleAuraModRangedHaste(bool apply, bool Real)
4810{
4811    m_target->ApplyAttackTimePercentMod(RANGED_ATTACK, m_modifier.m_amount, apply);
4812}
4813
4814void Aura::HandleRangedAmmoHaste(bool apply, bool Real)
4815{
4816    if(m_target->GetTypeId() != TYPEID_PLAYER)
4817        return;
4818    m_target->ApplyAttackTimePercentMod(RANGED_ATTACK,m_modifier.m_amount, apply);
4819}
4820
4821/********************************/
4822/***        ATTACK POWER      ***/
4823/********************************/
4824
4825void Aura::HandleAuraModAttackPower(bool apply, bool Real)
4826{
4827    m_target->HandleStatModifier(UNIT_MOD_ATTACK_POWER, TOTAL_VALUE, float(m_modifier.m_amount), apply);
4828}
4829
4830void Aura::HandleAuraModRangedAttackPower(bool apply, bool Real)
4831{
4832    if((m_target->getClassMask() & CLASSMASK_WAND_USERS)!=0)
4833        return;
4834
4835    m_target->HandleStatModifier(UNIT_MOD_ATTACK_POWER_RANGED, TOTAL_VALUE, float(m_modifier.m_amount), apply);
4836}
4837
4838void Aura::HandleAuraAttackPowerAttacker(bool apply, bool Real)
4839{
4840    // spells required only Real aura add/remove
4841    if(!Real)
4842        return;
4843    Unit *caster = GetCaster();
4844
4845    if (!caster)
4846        return;
4847
4848    // Hunter's Mark
4849    if (m_spellProto->SpellFamilyName == SPELLFAMILY_HUNTER && m_spellProto->SpellFamilyFlags & 0x0000000000000400LL)
4850    {
4851        // Check Improved Hunter's Mark bonus on caster
4852        Unit::AuraList const& mOverrideClassScript = caster->GetAurasByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS);
4853        for(Unit::AuraList::const_iterator i = mOverrideClassScript.begin(); i != mOverrideClassScript.end(); ++i)
4854        {
4855            Modifier* mod = (*i)->GetModifier();
4856            // mproved Hunter's Mark script from 5236 to 5240
4857            if (mod->m_miscvalue >= 5236 && mod->m_miscvalue <= 5240)
4858            {
4859                // Get amount of ranged bonus for this spell..
4860                int32 ranged_bonus = caster->CalculateSpellDamage(m_spellProto, 1, m_spellProto->EffectBasePoints[1], m_target);
4861                // Set melee attack power bonus % from ranged depends from Improved mask aura
4862                m_modifier.m_amount = mod->m_amount * ranged_bonus / 100;
4863                m_currentBasePoints = m_modifier.m_amount;
4864                break;
4865            }
4866        }
4867        return;
4868    }
4869}
4870
4871void Aura::HandleAuraModAttackPowerPercent(bool apply, bool Real)
4872{
4873    //UNIT_FIELD_ATTACK_POWER_MULTIPLIER = multiplier - 1
4874    m_target->HandleStatModifier(UNIT_MOD_ATTACK_POWER, TOTAL_PCT, float(m_modifier.m_amount), apply);
4875}
4876
4877void Aura::HandleAuraModRangedAttackPowerPercent(bool apply, bool Real)
4878{
4879    if((m_target->getClassMask() & CLASSMASK_WAND_USERS)!=0)
4880        return;
4881
4882    //UNIT_FIELD_RANGED_ATTACK_POWER_MULTIPLIER = multiplier - 1
4883    m_target->HandleStatModifier(UNIT_MOD_ATTACK_POWER_RANGED, TOTAL_PCT, float(m_modifier.m_amount), apply);
4884}
4885
4886void Aura::HandleAuraModRangedAttackPowerOfStatPercent(bool apply, bool Real)
4887{
4888    // spells required only Real aura add/remove
4889    if(!Real)
4890        return;
4891
4892    if(m_target->GetTypeId() == TYPEID_PLAYER && (m_target->getClassMask() & CLASSMASK_WAND_USERS)!=0)
4893        return;
4894
4895    if(m_modifier.m_miscvalue != STAT_INTELLECT)
4896    {
4897        // support required adding UpdateAttackPowerAndDamage calls at stat update
4898        sLog.outError("Aura SPELL_AURA_MOD_RANGED_ATTACK_POWER_OF_STAT_PERCENT (212) need support non-intellect stats!");
4899        return;
4900    }
4901
4902    // Recalculate bonus
4903    ((Player*)m_target)->UpdateAttackPowerAndDamage(true);
4904}
4905
4906/********************************/
4907/***        DAMAGE BONUS      ***/
4908/********************************/
4909void Aura::HandleModDamageDone(bool apply, bool Real)
4910{
4911    // apply item specific bonuses for already equipped weapon
4912    if(Real && m_target->GetTypeId()==TYPEID_PLAYER)
4913    {
4914        for(int i = 0; i < MAX_ATTACK; ++i)
4915            if(Item* pItem = ((Player*)m_target)->GetWeaponForAttack(WeaponAttackType(i)))
4916                ((Player*)m_target)->_ApplyWeaponDependentAuraDamageMod(pItem,WeaponAttackType(i),this,apply);
4917    }
4918
4919    // m_modifier.m_miscvalue is bitmask of spell schools
4920    // 1 ( 0-bit ) - normal school damage (SPELL_SCHOOL_MASK_NORMAL)
4921    // 126 - full bitmask all magic damages (SPELL_SCHOOL_MASK_MAGIC) including wands
4922    // 127 - full bitmask any damages
4923    //
4924    // mods must be applied base at equipped weapon class and subclass comparison
4925    // with spell->EquippedItemClass and  EquippedItemSubClassMask and EquippedItemInventoryTypeMask
4926    // m_modifier.m_miscvalue comparison with item generated damage types
4927
4928    if((m_modifier.m_miscvalue & SPELL_SCHOOL_MASK_NORMAL) != 0)
4929    {
4930        // apply generic physical damage bonuses including wand case
4931        if (GetSpellProto()->EquippedItemClass == -1 || m_target->GetTypeId() != TYPEID_PLAYER)
4932        {
4933            m_target->HandleStatModifier(UNIT_MOD_DAMAGE_MAINHAND, TOTAL_VALUE, float(m_modifier.m_amount), apply);
4934            m_target->HandleStatModifier(UNIT_MOD_DAMAGE_OFFHAND, TOTAL_VALUE, float(m_modifier.m_amount), apply);
4935            m_target->HandleStatModifier(UNIT_MOD_DAMAGE_RANGED, TOTAL_VALUE, float(m_modifier.m_amount), apply);
4936        }
4937        else
4938        {
4939            // done in Player::_ApplyWeaponDependentAuraMods
4940        }
4941
4942        if(m_target->GetTypeId() == TYPEID_PLAYER)
4943        {
4944            if(m_positive)
4945                m_target->ApplyModUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_POS,m_modifier.m_amount,apply);
4946            else
4947                m_target->ApplyModUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_NEG,m_modifier.m_amount,apply);
4948        }
4949    }
4950
4951    // Skip non magic case for speedup
4952    if((m_modifier.m_miscvalue & SPELL_SCHOOL_MASK_MAGIC) == 0)
4953        return;
4954
4955    if( GetSpellProto()->EquippedItemClass != -1 || GetSpellProto()->EquippedItemInventoryTypeMask != 0 )
4956    {
4957        // wand magic case (skip generic to all item spell bonuses)
4958        // done in Player::_ApplyWeaponDependentAuraMods
4959
4960        // Skip item specific requirements for not wand magic damage
4961        return;
4962    }
4963
4964    // Magic damage modifiers implemented in Unit::SpellDamageBonus
4965    // This information for client side use only
4966    if(m_target->GetTypeId() == TYPEID_PLAYER)
4967    {
4968        if(m_positive)
4969        {
4970            for(int i = SPELL_SCHOOL_HOLY; i < MAX_SPELL_SCHOOL; i++)
4971            {
4972                if((m_modifier.m_miscvalue & (1<<i)) != 0)
4973                    m_target->ApplyModUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_POS+i,m_modifier.m_amount,apply);
4974            }
4975        }
4976        else
4977        {
4978            for(int i = SPELL_SCHOOL_HOLY; i < MAX_SPELL_SCHOOL; i++)
4979            {
4980                if((m_modifier.m_miscvalue & (1<<i)) != 0)
4981                    m_target->ApplyModUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_NEG+i,m_modifier.m_amount,apply);
4982            }
4983        }
4984        Pet* pet = m_target->GetPet();
4985        if(pet)
4986            pet->UpdateAttackPowerAndDamage();
4987    }
4988}
4989
4990void Aura::HandleModDamagePercentDone(bool apply, bool Real)
4991{
4992    sLog.outDebug("AURA MOD DAMAGE type:%u negative:%u", m_modifier.m_miscvalue, m_positive ? 0 : 1);
4993
4994    // apply item specific bonuses for already equipped weapon
4995    if(Real && m_target->GetTypeId()==TYPEID_PLAYER)
4996    {
4997        for(int i = 0; i < MAX_ATTACK; ++i)
4998            if(Item* pItem = ((Player*)m_target)->GetWeaponForAttack(WeaponAttackType(i)))
4999                ((Player*)m_target)->_ApplyWeaponDependentAuraDamageMod(pItem,WeaponAttackType(i),this,apply);
5000    }
5001
5002    // m_modifier.m_miscvalue is bitmask of spell schools
5003    // 1 ( 0-bit ) - normal school damage (SPELL_SCHOOL_MASK_NORMAL)
5004    // 126 - full bitmask all magic damages (SPELL_SCHOOL_MASK_MAGIC) including wand
5005    // 127 - full bitmask any damages
5006    //
5007    // mods must be applied base at equipped weapon class and subclass comparison
5008    // with spell->EquippedItemClass and  EquippedItemSubClassMask and EquippedItemInventoryTypeMask
5009    // m_modifier.m_miscvalue comparison with item generated damage types
5010
5011    if((m_modifier.m_miscvalue & SPELL_SCHOOL_MASK_NORMAL) != 0)
5012    {
5013        // apply generic physical damage bonuses including wand case
5014        if (GetSpellProto()->EquippedItemClass == -1 || m_target->GetTypeId() != TYPEID_PLAYER)
5015        {
5016            m_target->HandleStatModifier(UNIT_MOD_DAMAGE_MAINHAND, TOTAL_PCT, float(m_modifier.m_amount), apply);
5017            m_target->HandleStatModifier(UNIT_MOD_DAMAGE_OFFHAND, TOTAL_PCT, float(m_modifier.m_amount), apply);
5018            m_target->HandleStatModifier(UNIT_MOD_DAMAGE_RANGED, TOTAL_PCT, float(m_modifier.m_amount), apply);
5019        }
5020        else
5021        {
5022            // done in Player::_ApplyWeaponDependentAuraMods
5023        }
5024        // For show in client
5025        if(m_target->GetTypeId() == TYPEID_PLAYER)
5026            m_target->ApplyModSignedFloatValue(PLAYER_FIELD_MOD_DAMAGE_DONE_PCT,m_modifier.m_amount/100.0f,apply);
5027    }
5028
5029    // Skip non magic case for speedup
5030    if((m_modifier.m_miscvalue & SPELL_SCHOOL_MASK_MAGIC) == 0)
5031        return;
5032
5033    if( GetSpellProto()->EquippedItemClass != -1 || GetSpellProto()->EquippedItemInventoryTypeMask != 0 )
5034    {
5035        // wand magic case (skip generic to all item spell bonuses)
5036        // done in Player::_ApplyWeaponDependentAuraMods
5037
5038        // Skip item specific requirements for not wand magic damage
5039        return;
5040    }
5041
5042    // Magic damage percent modifiers implemented in Unit::SpellDamageBonus
5043    // Send info to client
5044    if(m_target->GetTypeId() == TYPEID_PLAYER)
5045        for(int i = SPELL_SCHOOL_HOLY; i < MAX_SPELL_SCHOOL; ++i)
5046            m_target->ApplyModSignedFloatValue(PLAYER_FIELD_MOD_DAMAGE_DONE_PCT+i,m_modifier.m_amount/100.0f,apply);
5047}
5048
5049void Aura::HandleModOffhandDamagePercent(bool apply, bool Real)
5050{
5051    // spells required only Real aura add/remove
5052    if(!Real)
5053        return;
5054
5055    sLog.outDebug("AURA MOD OFFHAND DAMAGE");
5056
5057    m_target->HandleStatModifier(UNIT_MOD_DAMAGE_OFFHAND, TOTAL_PCT, float(m_modifier.m_amount), apply);
5058}
5059
5060/********************************/
5061/***        POWER COST        ***/
5062/********************************/
5063
5064void Aura::HandleModPowerCostPCT(bool apply, bool Real)
5065{
5066    // spells required only Real aura add/remove
5067    if(!Real)
5068        return;
5069
5070    float amount = m_modifier.m_amount/100.0f;
5071    for(int i = 0; i < MAX_SPELL_SCHOOL; ++i)
5072        if(m_modifier.m_miscvalue & (1<<i))
5073            m_target->ApplyModSignedFloatValue(UNIT_FIELD_POWER_COST_MULTIPLIER+i,amount,apply);
5074}
5075
5076void Aura::HandleModPowerCost(bool apply, bool Real)
5077{
5078    // spells required only Real aura add/remove
5079    if(!Real)
5080        return;
5081
5082    for(int i = 0; i < MAX_SPELL_SCHOOL; ++i)
5083        if(m_modifier.m_miscvalue & (1<<i))
5084            m_target->ApplyModInt32Value(UNIT_FIELD_POWER_COST_MODIFIER+i,m_modifier.m_amount,apply);
5085}
5086
5087/*********************************************************/
5088/***                    OTHERS                         ***/
5089/*********************************************************/
5090
5091void Aura::HandleShapeshiftBoosts(bool apply)
5092{
5093    uint32 spellId = 0;
5094    uint32 spellId2 = 0;
5095    uint32 HotWSpellId = 0;
5096
5097    switch(GetModifier()->m_miscvalue)
5098    {
5099        case FORM_CAT:
5100            spellId = 3025;
5101            HotWSpellId = 24900;
5102            break;
5103        case FORM_TREE:
5104            spellId = 5420;
5105            break;
5106        case FORM_TRAVEL:
5107            spellId = 5419;
5108            break;
5109        case FORM_AQUA:
5110            spellId = 5421;
5111            break;
5112        case FORM_BEAR:
5113            spellId = 1178;
5114            spellId2 = 21178;
5115            HotWSpellId = 24899;
5116            break;
5117        case FORM_DIREBEAR:
5118            spellId = 9635;
5119            spellId2 = 21178;
5120            HotWSpellId = 24899;
5121            break;
5122        case FORM_BATTLESTANCE:
5123            spellId = 21156;
5124            break;
5125        case FORM_DEFENSIVESTANCE:
5126            spellId = 7376;
5127            break;
5128        case FORM_BERSERKERSTANCE:
5129            spellId = 7381;
5130            break;
5131        case FORM_MOONKIN:
5132            spellId = 24905;
5133            // aura from effect trigger spell
5134            spellId2 = 24907;
5135            break;
5136        case FORM_FLIGHT:
5137            spellId = 33948;
5138            break;
5139        case FORM_FLIGHT_EPIC:
5140            spellId  = 40122;
5141            spellId2 = 40121;
5142            break;
5143        case FORM_SPIRITOFREDEMPTION:
5144            spellId  = 27792;
5145            spellId2 = 27795;                               // must be second, this important at aura remove to prevent to early iterator invalidation.
5146            break;
5147        case FORM_GHOSTWOLF:
5148        case FORM_AMBIENT:
5149        case FORM_GHOUL:
5150        case FORM_SHADOW:
5151        case FORM_STEALTH:
5152        case FORM_CREATURECAT:
5153        case FORM_CREATUREBEAR:
5154            spellId = 0;
5155            break;
5156    }
5157
5158    uint32 form = GetModifier()->m_miscvalue-1;
5159
5160    if(apply)
5161    {
5162        if (spellId) m_target->CastSpell(m_target, spellId, true, NULL, this );
5163        if (spellId2) m_target->CastSpell(m_target, spellId2, true, NULL, this);
5164
5165        if(m_target->GetTypeId() == TYPEID_PLAYER)
5166        {
5167            const PlayerSpellMap& sp_list = ((Player *)m_target)->GetSpellMap();
5168            for (PlayerSpellMap::const_iterator itr = sp_list.begin(); itr != sp_list.end(); ++itr)
5169            {
5170                if(itr->second->state == PLAYERSPELL_REMOVED) continue;
5171                if(itr->first==spellId || itr->first==spellId2) continue;
5172                SpellEntry const *spellInfo = sSpellStore.LookupEntry(itr->first);
5173                if (!spellInfo || !(spellInfo->Attributes & ((1<<6) | (1<<7)))) continue;
5174                if (spellInfo->Stances & (1<<form))
5175                    m_target->CastSpell(m_target, itr->first, true, NULL, this);
5176            }
5177            //LotP
5178            if (((Player*)m_target)->HasSpell(17007))
5179            {
5180                SpellEntry const *spellInfo = sSpellStore.LookupEntry(24932);
5181                if (spellInfo && spellInfo->Stances & (1<<form))
5182                    m_target->CastSpell(m_target, 24932, true, NULL, this);
5183            }
5184            // HotW
5185            if (HotWSpellId)
5186            {
5187                Unit::AuraList const& mModTotalStatPct = m_target->GetAurasByType(SPELL_AURA_MOD_TOTAL_STAT_PERCENTAGE);
5188                for(Unit::AuraList::const_iterator i = mModTotalStatPct.begin(); i != mModTotalStatPct.end(); ++i)
5189                {
5190                    if ((*i)->GetSpellProto()->SpellIconID == 240 && (*i)->GetModifier()->m_miscvalue == 3)
5191                    {
5192                        int32 HotWMod = (*i)->GetModifier()->m_amount;
5193                        if(GetModifier()->m_miscvalue == FORM_CAT)
5194                            HotWMod /= 2;
5195
5196                        m_target->CastCustomSpell(m_target, HotWSpellId, &HotWMod, NULL, NULL, true, NULL, this);
5197                        break;
5198                    }
5199                }
5200            }
5201        }
5202    }
5203    else
5204    {
5205        m_target->RemoveAurasDueToSpell(spellId);
5206        m_target->RemoveAurasDueToSpell(spellId2);
5207
5208        Unit::AuraMap& tAuras = m_target->GetAuras();
5209        for (Unit::AuraMap::iterator itr = tAuras.begin(); itr != tAuras.end();)
5210        {
5211            if (itr->second->IsRemovedOnShapeLost())
5212            {
5213                m_target->RemoveAurasDueToSpell(itr->second->GetId());
5214                itr = tAuras.begin();
5215            }
5216            else
5217            {
5218                ++itr;
5219            }
5220        }
5221    }
5222
5223    /*double healthPercentage = (double)m_target->GetHealth() / (double)m_target->GetMaxHealth();
5224    m_target->SetHealth(uint32(ceil((double)m_target->GetMaxHealth() * healthPercentage)));*/
5225}
5226
5227void Aura::HandleAuraEmpathy(bool apply, bool Real)
5228{
5229    if(m_target->GetTypeId() != TYPEID_UNIT)
5230        return;
5231
5232    CreatureInfo const * ci = objmgr.GetCreatureTemplate(m_target->GetEntry());
5233    if(ci && ci->type == CREATURE_TYPE_BEAST)
5234        m_target->ApplyModUInt32Value(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_SPECIALINFO, apply);
5235}
5236
5237void Aura::HandleAuraUntrackable(bool apply, bool Real)
5238{
5239    if(apply)
5240        m_target->SetFlag(UNIT_FIELD_BYTES_1, PLAYER_STATE_FLAG_UNTRACKABLE);
5241    else
5242        m_target->RemoveFlag(UNIT_FIELD_BYTES_1, PLAYER_STATE_FLAG_UNTRACKABLE);
5243}
5244
5245void Aura::HandleAuraModPacify(bool apply, bool Real)
5246{
5247    if(m_target->GetTypeId() != TYPEID_PLAYER)
5248        return;
5249
5250    if(apply)
5251        m_target->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PACIFIED);
5252    else
5253        m_target->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PACIFIED);
5254}
5255
5256void Aura::HandleAuraModPacifyAndSilence(bool apply, bool Real)
5257{
5258    HandleAuraModPacify(apply,Real);
5259    HandleAuraModSilence(apply,Real);
5260}
5261
5262void Aura::HandleAuraGhost(bool apply, bool Real)
5263{
5264    if(m_target->GetTypeId() != TYPEID_PLAYER)
5265        return;
5266
5267    if(apply)
5268    {
5269        m_target->SetFlag(PLAYER_FLAGS, PLAYER_FLAGS_GHOST);
5270    }
5271    else
5272    {
5273        m_target->RemoveFlag(PLAYER_FLAGS, PLAYER_FLAGS_GHOST);
5274    }
5275}
5276
5277void Aura::HandleAuraAllowFlight(bool apply, bool Real)
5278{
5279    // all applied/removed only at real aura add/remove
5280    if(!Real)
5281        return;
5282
5283    // allow fly
5284    WorldPacket data;
5285    if(apply)
5286        data.Initialize(SMSG_MOVE_SET_CAN_FLY, 12);
5287    else
5288        data.Initialize(SMSG_MOVE_UNSET_CAN_FLY, 12);
5289    data.append(m_target->GetPackGUID());
5290    data << uint32(0);                                      // unk
5291    m_target->SendMessageToSet(&data, true);
5292}
5293
5294void Aura::HandleModRating(bool apply, bool Real)
5295{
5296    // spells required only Real aura add/remove
5297    if(!Real)
5298        return;
5299
5300    if(m_target->GetTypeId() != TYPEID_PLAYER)
5301        return;
5302
5303    for (uint32 rating = 0; rating < MAX_COMBAT_RATING; ++rating)
5304        if (m_modifier.m_miscvalue & (1 << rating))
5305            ((Player*)m_target)->ApplyRatingMod(CombatRating(rating), m_modifier.m_amount, apply);
5306}
5307
5308void Aura::HandleForceMoveForward(bool apply, bool Real)
5309{
5310    if(!Real || m_target->GetTypeId() != TYPEID_PLAYER)
5311        return;
5312    if(apply)
5313        m_target->SetFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_FORCE_MOVE);
5314    else
5315        m_target->RemoveFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_FORCE_MOVE);
5316}
5317
5318void Aura::HandleAuraModExpertise(bool apply, bool Real)
5319{
5320    if(m_target->GetTypeId() != TYPEID_PLAYER)
5321        return;
5322
5323    ((Player*)m_target)->UpdateExpertise(BASE_ATTACK);
5324    ((Player*)m_target)->UpdateExpertise(OFF_ATTACK);
5325}
5326
5327void Aura::HandleModTargetResistance(bool apply, bool Real)
5328{
5329    // spells required only Real aura add/remove
5330    if(!Real)
5331        return;
5332    // applied to damage as HandleNoImmediateEffect in Unit::CalcAbsorbResist and Unit::CalcArmorReducedDamage
5333
5334    // show armor penetration
5335    if (m_target->GetTypeId() == TYPEID_PLAYER && (m_modifier.m_miscvalue & SPELL_SCHOOL_MASK_NORMAL))
5336        m_target->ApplyModInt32Value(PLAYER_FIELD_MOD_TARGET_PHYSICAL_RESISTANCE,m_modifier.m_amount, apply);
5337
5338    // show as spell penetration only full spell penetration bonuses (all resistances except armor and holy
5339    if (m_target->GetTypeId() == TYPEID_PLAYER && (m_modifier.m_miscvalue & SPELL_SCHOOL_MASK_SPELL)==SPELL_SCHOOL_MASK_SPELL)
5340        m_target->ApplyModInt32Value(PLAYER_FIELD_MOD_TARGET_RESISTANCE,m_modifier.m_amount, apply);
5341}
5342
5343//HandleNoImmediateEffect auras implementation to support new stat system
5344void Aura::HandleAuraHealing(bool apply, bool Real)
5345{
5346    //m_target->HandleStatModifier(UNIT_MOD_HEALING, TOTAL_VALUE, float(m_modifier.m_amount), apply);
5347}
5348
5349void Aura::HandleAuraHealingPct(bool apply, bool Real)
5350{
5351    //m_target->HandleStatModifier(UNIT_MOD_HEALING, TOTAL_PCT, float(m_modifier.m_amount), apply);
5352}
5353
5354void Aura::HandleShieldBlockValue(bool apply, bool Real)
5355{
5356    BaseModType modType = FLAT_MOD;
5357    if(m_modifier.m_auraname == SPELL_AURA_MOD_SHIELD_BLOCKVALUE_PCT)
5358        modType = PCT_MOD;
5359
5360    if(m_target->GetTypeId() == TYPEID_PLAYER)
5361        ((Player*)m_target)->HandleBaseModValue(SHIELD_BLOCK_VALUE, modType, float(m_modifier.m_amount), apply);
5362}
5363
5364void Aura::HandleAuraRetainComboPoints(bool apply, bool Real)
5365{
5366    // spells required only Real aura add/remove
5367    if(!Real)
5368        return;
5369
5370    if(m_target->GetTypeId() != TYPEID_PLAYER)
5371        return;
5372
5373    Player *target = (Player*)m_target;
5374
5375    // combo points was added in SPELL_EFFECT_ADD_COMBO_POINTS handler
5376    // remove only if aura expire by time (in case combo points amount change aura removed without combo points lost)
5377    if( !apply && m_duration==0 && target->GetComboTarget())
5378        if(Unit* unit = ObjectAccessor::GetUnit(*m_target,target->GetComboTarget()))
5379            target->AddComboPoints(unit, -m_modifier.m_amount);
5380}
5381
5382void Aura::HandleModUnattackable( bool Apply, bool Real )
5383{
5384    if(Real && Apply)
5385    {
5386        m_target->CombatStop();
5387        m_target->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_UNATTACKABLE);
5388    }
5389
5390    m_target->ApplyModFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE,Apply);
5391}
5392
5393void Aura::HandleSpiritOfRedemption( bool apply, bool Real )
5394{
5395    // spells required only Real aura add/remove
5396    if(!Real)
5397        return;
5398
5399    // prepare spirit state
5400    if(apply)
5401    {
5402        if(m_target->GetTypeId()==TYPEID_PLAYER)
5403        {
5404            // disable breath/etc timers
5405            ((Player*)m_target)->StopMirrorTimers();
5406
5407            // set stand state (expected in this form)
5408            if(!m_target->IsStandState())
5409                m_target->SetStandState(PLAYER_STATE_NONE);
5410        }
5411
5412        m_target->SetHealth(1);
5413    }
5414    // die at aura end
5415    else
5416        m_target->DealDamage(m_target, m_target->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, GetSpellProto(), false);
5417}
5418
5419void Aura::CleanupTriggeredSpells()
5420{
5421    uint32 tSpellId = m_spellProto->EffectTriggerSpell[GetEffIndex()];
5422    if(!tSpellId)
5423        return;
5424
5425    SpellEntry const* tProto = sSpellStore.LookupEntry(tSpellId);
5426    if(!tProto)
5427        return;
5428
5429    if(GetSpellDuration(tProto) != -1)
5430        return;
5431
5432    // needed for spell 43680, maybe others
5433    // TODO: is there a spell flag, which can solve this in a more sophisticated way?
5434    if(m_spellProto->EffectApplyAuraName[GetEffIndex()] == SPELL_AURA_PERIODIC_TRIGGER_SPELL &&
5435            GetSpellDuration(m_spellProto) == m_spellProto->EffectAmplitude[GetEffIndex()])
5436        return;
5437    m_target->RemoveAurasDueToSpell(tSpellId);
5438}
5439
5440void Aura::HandleAuraPowerBurn(bool apply, bool Real)
5441{
5442    if (m_periodicTimer <= 0)
5443        m_periodicTimer += m_modifier.periodictime;
5444
5445    m_isPeriodic = apply;
5446}
5447
5448void Aura::HandleSchoolAbsorb(bool apply, bool Real)
5449{
5450    if(!Real)
5451        return;
5452
5453    // prevent double apply bonuses
5454    if(apply && (m_target->GetTypeId()!=TYPEID_PLAYER || !((Player*)m_target)->GetSession()->PlayerLoading()))
5455    {
5456        if(Unit* caster = GetCaster())
5457        {
5458            float DoneActualBenefit = 0.0f;
5459            switch(m_spellProto->SpellFamilyName)
5460            {
5461                case SPELLFAMILY_PRIEST:
5462                    if(m_spellProto->SpellFamilyFlags == 0x1) //PW:S
5463                    {
5464                        //+30% from +healing bonus
5465                        DoneActualBenefit = caster->SpellBaseHealingBonus(GetSpellSchoolMask(m_spellProto)) * 0.3f;
5466                        break;
5467                    }
5468                    break;
5469                case SPELLFAMILY_MAGE:
5470                    if(m_spellProto->SpellFamilyFlags == 0x80100 || m_spellProto->SpellFamilyFlags == 0x8 || m_spellProto->SpellFamilyFlags == 0x100000000LL)
5471                    {
5472                        //frost ward, fire ward, ice barrier
5473                        //+10% from +spd bonus
5474                        DoneActualBenefit = caster->SpellBaseDamageBonus(GetSpellSchoolMask(m_spellProto)) * 0.1f;
5475                        break;
5476                    }
5477                    break;
5478                case SPELLFAMILY_WARLOCK:
5479                    if(m_spellProto->SpellFamilyFlags == 0x00)
5480                    {
5481                        //shadow ward
5482                        //+10% from +spd bonus
5483                        DoneActualBenefit = caster->SpellBaseDamageBonus(GetSpellSchoolMask(m_spellProto)) * 0.1f;
5484                        break;
5485                    }
5486                    break;
5487                default:
5488                    break;
5489            }
5490
5491            DoneActualBenefit *= caster->CalculateLevelPenalty(GetSpellProto());
5492
5493            m_modifier.m_amount += (int32)DoneActualBenefit;
5494        }
5495    }
5496}
5497
5498void Aura::PeriodicTick()
5499{
5500    if(!m_target->isAlive())
5501        return;
5502
5503    switch(m_modifier.m_auraname)
5504    {
5505        case SPELL_AURA_PERIODIC_DAMAGE:
5506        case SPELL_AURA_PERIODIC_DAMAGE_PERCENT:
5507        {
5508            Unit *pCaster = GetCaster();
5509            if(!pCaster)
5510                return;
5511
5512            if( GetSpellProto()->Effect[GetEffIndex()]==SPELL_EFFECT_PERSISTENT_AREA_AURA &&
5513                pCaster->SpellHitResult(m_target,GetSpellProto(),false)!=SPELL_MISS_NONE)
5514                return;
5515
5516            // Check for immune (not use charges)
5517            if(m_target->IsImmunedToDamage(GetSpellSchoolMask(GetSpellProto())))
5518                return;
5519
5520            // some auras remove at specific health level or more
5521            if(m_modifier.m_auraname==SPELL_AURA_PERIODIC_DAMAGE)
5522            {
5523                switch(GetId())
5524                {
5525                    case 43093: case 31956: case 38801:
5526                    case 35321: case 38363: case 39215:
5527                        if(m_target->GetHealth() == m_target->GetMaxHealth() )
5528                        {
5529                            m_target->RemoveAurasDueToSpell(GetId());
5530                            return;
5531                        }
5532                        break;
5533                    case 38772:
5534                    {
5535                        uint32 percent =
5536                            GetEffIndex() < 2 && GetSpellProto()->Effect[GetEffIndex()]==SPELL_EFFECT_DUMMY ?
5537                            pCaster->CalculateSpellDamage(GetSpellProto(),GetEffIndex()+1,GetSpellProto()->EffectBasePoints[GetEffIndex()+1],m_target) :
5538                            100;
5539                        if(m_target->GetHealth()*100 >= m_target->GetMaxHealth()*percent )
5540                        {
5541                            m_target->RemoveAurasDueToSpell(GetId());
5542                            return;
5543                        }
5544                        break;
5545                    }
5546                    case 41337:// aura of anger
5547                    {                       
5548                        Unit::AuraList const& mMod = m_target->GetAurasByType(SPELL_AURA_MOD_DAMAGE_PERCENT_DONE);
5549                        for(Unit::AuraList::const_iterator i = mMod.begin(); i != mMod.end(); ++i)
5550                        {
5551                            if ((*i)->GetId() == 41337)
5552                            {
5553                                (*i)->ApplyModifier(false);
5554                                (*i)->GetModifier()->m_amount += 5;
5555                                (*i)->ApplyModifier(true);
5556                                break;
5557                            }
5558                        }                       
5559                        m_modifier.m_amount += 100;
5560                    }break;
5561                    default:
5562                        break;
5563                }
5564            }
5565
5566            uint32 absorb=0;
5567            uint32 resist=0;
5568            CleanDamage cleanDamage =  CleanDamage(0, BASE_ATTACK, MELEE_HIT_NORMAL );
5569
5570            // ignore non positive values (can be result apply spellmods to aura damage
5571            uint32 amount = m_modifier.m_amount > 0 ? m_modifier.m_amount : 0;
5572
5573            uint32 pdamage;
5574
5575            if(m_modifier.m_auraname == SPELL_AURA_PERIODIC_DAMAGE)
5576            {
5577                pdamage = amount;
5578
5579                // Calculate armor mitigation if it is a physical spell
5580                // But not for bleed mechanic spells
5581                if ( GetSpellSchoolMask(GetSpellProto()) & SPELL_SCHOOL_MASK_NORMAL &&
5582                     GetEffectMechanic(GetSpellProto(), m_effIndex) != MECHANIC_BLEED)
5583                {
5584                    uint32 pdamageReductedArmor = pCaster->CalcArmorReducedDamage(m_target, pdamage);
5585                    cleanDamage.damage += pdamage - pdamageReductedArmor;
5586                    pdamage = pdamageReductedArmor;
5587                }
5588
5589                pdamage = pCaster->SpellDamageBonus(m_target,GetSpellProto(),pdamage,DOT);
5590
5591                // Curse of Agony damage-per-tick calculation
5592                if (GetSpellProto()->SpellFamilyName==SPELLFAMILY_WARLOCK && (GetSpellProto()->SpellFamilyFlags & 0x0000000000000400LL) && GetSpellProto()->SpellIconID==544)
5593                {
5594                    // 1..4 ticks, 1/2 from normal tick damage
5595                    if (m_duration>=((m_maxduration-m_modifier.periodictime)*2/3))
5596                        pdamage = pdamage/2;
5597                    // 9..12 ticks, 3/2 from normal tick damage
5598                    else if(m_duration<((m_maxduration-m_modifier.periodictime)/3))
5599                        pdamage += (pdamage+1)/2;           // +1 prevent 0.5 damage possible lost at 1..4 ticks
5600                    // 5..8 ticks have normal tick damage
5601                }
5602            }
5603            else
5604                pdamage = uint32(m_target->GetMaxHealth()*amount/100);
5605
5606            //As of 2.2 resilience reduces damage from DoT ticks as much as the chance to not be critically hit
5607            // Reduce dot damage from resilience for players
5608            if (m_target->GetTypeId()==TYPEID_PLAYER)
5609                pdamage-=((Player*)m_target)->GetDotDamageReduction(pdamage);
5610
5611            pCaster->CalcAbsorbResist(m_target, GetSpellSchoolMask(GetSpellProto()), DOT, pdamage, &absorb, &resist);
5612
5613            sLog.outDetail("PeriodicTick: %u (TypeId: %u) attacked %u (TypeId: %u) for %u dmg inflicted by %u abs is %u",
5614                GUID_LOPART(GetCasterGUID()), GuidHigh2TypeId(GUID_HIPART(GetCasterGUID())), m_target->GetGUIDLow(), m_target->GetTypeId(), pdamage, GetId(),absorb);
5615
5616            WorldPacket data(SMSG_PERIODICAURALOG, (21+16));// we guess size
5617            data.append(m_target->GetPackGUID());
5618            data.appendPackGUID(GetCasterGUID());
5619            data << uint32(GetId());
5620            data << uint32(1);
5621            data << uint32(m_modifier.m_auraname);
5622            data << (uint32)pdamage;
5623            data << (uint32)GetSpellSchoolMask(GetSpellProto()); // will be mask in 2.4.x
5624            data << (uint32)absorb;
5625            data << (uint32)resist;
5626            m_target->SendMessageToSet(&data,true);
5627
5628            Unit* target = m_target;                        // aura can be deleted in DealDamage
5629            SpellEntry const* spellProto = GetSpellProto();
5630
5631            pCaster->DealDamage(m_target, (pdamage <= absorb+resist) ? 0 : (pdamage-absorb-resist), &cleanDamage, DOT, GetSpellSchoolMask(GetSpellProto()), GetSpellProto(), true);
5632
5633            // DO NOT ACCESS MEMBERS OF THE AURA FROM NOW ON (DealDamage can delete aura)
5634
5635            pCaster->ProcDamageAndSpell(target, PROC_FLAG_NONE, PROC_FLAG_TAKE_DAMAGE, (pdamage <= absorb+resist) ? 0 : (pdamage-absorb-resist), GetSpellSchoolMask(spellProto), spellProto);
5636            break;
5637        }
5638        case SPELL_AURA_PERIODIC_LEECH:
5639        {
5640            Unit *pCaster = GetCaster();
5641            if(!pCaster)
5642                return;
5643
5644            if(!pCaster->isAlive())
5645                return;
5646
5647            if( GetSpellProto()->Effect[GetEffIndex()]==SPELL_EFFECT_PERSISTENT_AREA_AURA &&
5648                pCaster->SpellHitResult(m_target,GetSpellProto(),false)!=SPELL_MISS_NONE)
5649                return;
5650
5651            // Check for immune (not use charges)
5652            if(m_target->IsImmunedToDamage(GetSpellSchoolMask(GetSpellProto())))
5653                return;
5654
5655            uint32 absorb=0;
5656            uint32 resist=0;
5657            CleanDamage cleanDamage =  CleanDamage(0, BASE_ATTACK, MELEE_HIT_NORMAL );
5658
5659            uint32 pdamage = m_modifier.m_amount > 0 ? m_modifier.m_amount : 0;
5660
5661            //Calculate armor mitigation if it is a physical spell
5662            if (GetSpellSchoolMask(GetSpellProto()) & SPELL_SCHOOL_MASK_NORMAL)
5663            {
5664                uint32 pdamageReductedArmor = pCaster->CalcArmorReducedDamage(m_target, pdamage);
5665                cleanDamage.damage += pdamage - pdamageReductedArmor;
5666                pdamage = pdamageReductedArmor;
5667            }
5668
5669            pdamage = pCaster->SpellDamageBonus(m_target,GetSpellProto(),pdamage,DOT);
5670
5671            // talent Soul Siphon add bonus to Drain Life spells
5672            if( GetSpellProto()->SpellFamilyName == SPELLFAMILY_WARLOCK && (GetSpellProto()->SpellFamilyFlags & 0x8) )
5673            {
5674                // find talent max bonus percentage
5675                Unit::AuraList const& mClassScriptAuras = pCaster->GetAurasByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS);
5676                for(Unit::AuraList::const_iterator i = mClassScriptAuras.begin(); i != mClassScriptAuras.end(); ++i)
5677                {
5678                    if ((*i)->GetModifier()->m_miscvalue == 4992 || (*i)->GetModifier()->m_miscvalue == 4993)
5679                    {
5680                        if((*i)->GetEffIndex()!=1)
5681                        {
5682                            sLog.outError("Expected spell %u structure change, need code update",(*i)->GetId());
5683                            break;
5684                        }
5685
5686                        // effect 1 m_amount
5687                        int32 maxPercent = (*i)->GetModifier()->m_amount;
5688                        // effect 0 m_amount
5689                        int32 stepPercent = pCaster->CalculateSpellDamage((*i)->GetSpellProto(),0,(*i)->GetSpellProto()->EffectBasePoints[0],pCaster);
5690
5691                        // count affliction effects and calc additional damage in percentage
5692                        int32 modPercent = 0;
5693                        Unit::AuraMap const& victimAuras = m_target->GetAuras();
5694                        for (Unit::AuraMap::const_iterator itr = victimAuras.begin(); itr != victimAuras.end(); ++itr)
5695                        {
5696                            Aura* aura = itr->second;
5697                            if (aura->IsPositive())continue;
5698                            SpellEntry const* m_spell = aura->GetSpellProto();
5699                            if (m_spell->SpellFamilyName != SPELLFAMILY_WARLOCK)
5700                                continue;
5701
5702                            SkillLineAbilityMap::const_iterator lower = spellmgr.GetBeginSkillLineAbilityMap(m_spell->Id);
5703                            SkillLineAbilityMap::const_iterator upper = spellmgr.GetEndSkillLineAbilityMap(m_spell->Id);
5704
5705                            for(SkillLineAbilityMap::const_iterator _spell_idx = lower; _spell_idx != upper; ++_spell_idx)
5706                            {
5707                                if(_spell_idx->second->skillId == SKILL_AFFLICTION)
5708                                {
5709                                    modPercent += stepPercent;
5710                                    if (modPercent >= maxPercent)
5711                                    {
5712                                        modPercent = maxPercent;
5713                                        break;
5714                                    }
5715                                }
5716                            }
5717                        }
5718                        pdamage += (pdamage*modPercent/100);
5719                        break;
5720                    }
5721                }
5722            }
5723
5724            //As of 2.2 resilience reduces damage from DoT ticks as much as the chance to not be critically hit
5725            // Reduce dot damage from resilience for players
5726            if (m_target->GetTypeId()==TYPEID_PLAYER)
5727                pdamage-=((Player*)m_target)->GetDotDamageReduction(pdamage);
5728
5729            pCaster->CalcAbsorbResist(m_target, GetSpellSchoolMask(GetSpellProto()), DOT, pdamage, &absorb, &resist);
5730
5731            if(m_target->GetHealth() < pdamage)
5732                pdamage = uint32(m_target->GetHealth());
5733
5734            sLog.outDetail("PeriodicTick: %u (TypeId: %u) health leech of %u (TypeId: %u) for %u dmg inflicted by %u abs is %u",
5735                GUID_LOPART(GetCasterGUID()), GuidHigh2TypeId(GUID_HIPART(GetCasterGUID())), m_target->GetGUIDLow(), m_target->GetTypeId(), pdamage, GetId(),absorb);
5736
5737            pCaster->SendSpellNonMeleeDamageLog(m_target, GetId(), pdamage, GetSpellSchoolMask(GetSpellProto()), absorb, resist, false, 0);
5738
5739
5740            Unit* target = m_target;                        // aura can be deleted in DealDamage
5741            SpellEntry const* spellProto = GetSpellProto();
5742            float multiplier = spellProto->EffectMultipleValue[GetEffIndex()] > 0 ? spellProto->EffectMultipleValue[GetEffIndex()] : 1;
5743
5744            uint32 new_damage = pCaster->DealDamage(m_target, (pdamage <= absorb+resist) ? 0 : (pdamage-absorb-resist), &cleanDamage, DOT, GetSpellSchoolMask(GetSpellProto()), GetSpellProto(), false);
5745
5746            // DO NOT ACCESS MEMBERS OF THE AURA FROM NOW ON (DealDamage can delete aura)
5747
5748            pCaster->ProcDamageAndSpell(target, PROC_FLAG_HEALED, PROC_FLAG_TAKE_DAMAGE, new_damage, GetSpellSchoolMask(spellProto), spellProto);
5749            if (!target->isAlive() && pCaster->IsNonMeleeSpellCasted(false))
5750            {
5751                for (uint32 i = CURRENT_FIRST_NON_MELEE_SPELL; i < CURRENT_MAX_SPELL; i++)
5752                {
5753                    if (pCaster->m_currentSpells[i] && pCaster->m_currentSpells[i]->m_spellInfo->Id == spellProto->Id)
5754                        pCaster->m_currentSpells[i]->cancel();
5755                }
5756            }
5757
5758
5759            if(Player *modOwner = pCaster->GetSpellModOwner())
5760                modOwner->ApplySpellMod(spellProto->Id, SPELLMOD_MULTIPLE_VALUE, multiplier);
5761
5762            uint32 heal = pCaster->SpellHealingBonus(spellProto, uint32(new_damage * multiplier), DOT, pCaster);
5763
5764            int32 gain = pCaster->ModifyHealth(heal);
5765            pCaster->getHostilRefManager().threatAssist(pCaster, gain * 0.5f, spellProto);
5766
5767            pCaster->SendHealSpellLog(pCaster, spellProto->Id, heal);
5768            break;
5769        }
5770        case SPELL_AURA_PERIODIC_HEAL:
5771        case SPELL_AURA_OBS_MOD_HEALTH:
5772        {
5773            Unit *pCaster = GetCaster();
5774            if(!pCaster)
5775                return;
5776
5777            // heal for caster damage (must be alive)
5778            if(m_target != pCaster && GetSpellProto()->SpellVisual==163 && !pCaster->isAlive())
5779                return;
5780
5781            // ignore non positive values (can be result apply spellmods to aura damage
5782            uint32 amount = m_modifier.m_amount > 0 ? m_modifier.m_amount : 0;
5783
5784            uint32 pdamage;
5785
5786            if(m_modifier.m_auraname==SPELL_AURA_OBS_MOD_HEALTH)
5787                pdamage = uint32(m_target->GetMaxHealth() * amount/100);
5788            else
5789                pdamage = amount;
5790
5791            pdamage = pCaster->SpellHealingBonus(GetSpellProto(), pdamage, DOT, m_target);
5792
5793            sLog.outDetail("PeriodicTick: %u (TypeId: %u) heal of %u (TypeId: %u) for %u health inflicted by %u",
5794                GUID_LOPART(GetCasterGUID()), GuidHigh2TypeId(GUID_HIPART(GetCasterGUID())), m_target->GetGUIDLow(), m_target->GetTypeId(), pdamage, GetId());
5795
5796            WorldPacket data(SMSG_PERIODICAURALOG, (21+16));// we guess size
5797            data.append(m_target->GetPackGUID());
5798            data.appendPackGUID(GetCasterGUID());
5799            data << uint32(GetId());
5800            data << uint32(1);
5801            data << uint32(m_modifier.m_auraname);
5802            data << (uint32)pdamage;
5803            m_target->SendMessageToSet(&data,true);
5804
5805            int32 gain = m_target->ModifyHealth(pdamage);
5806
5807            // add HoTs to amount healed in bgs
5808            if( pCaster->GetTypeId() == TYPEID_PLAYER )
5809                if( BattleGround *bg = ((Player*)pCaster)->GetBattleGround() )
5810                    bg->UpdatePlayerScore(((Player*)pCaster), SCORE_HEALING_DONE, gain);
5811
5812            //Do check before because m_modifier.auraName can be invalidate by DealDamage.
5813            bool procSpell = (m_modifier.m_auraname == SPELL_AURA_PERIODIC_HEAL && m_target != pCaster);
5814
5815            m_target->getHostilRefManager().threatAssist(pCaster, float(gain) * 0.5f, GetSpellProto());
5816
5817            Unit* target = m_target;                        // aura can be deleted in DealDamage
5818            SpellEntry const* spellProto = GetSpellProto();
5819            bool haveCastItem = GetCastItemGUID()!=0;
5820
5821            // heal for caster damage
5822            if(m_target!=pCaster && spellProto->SpellVisual==163)
5823            {
5824                uint32 dmg = spellProto->manaPerSecond;
5825                if(pCaster->GetHealth() <= dmg && pCaster->GetTypeId()==TYPEID_PLAYER)
5826                {
5827                    pCaster->RemoveAurasDueToSpell(GetId());
5828
5829                    // finish current generic/channeling spells, don't affect autorepeat
5830                    if(pCaster->m_currentSpells[CURRENT_GENERIC_SPELL])
5831                    {
5832                        pCaster->m_currentSpells[CURRENT_GENERIC_SPELL]->finish();
5833                    }
5834                    if(pCaster->m_currentSpells[CURRENT_CHANNELED_SPELL])
5835                    {
5836                        pCaster->m_currentSpells[CURRENT_CHANNELED_SPELL]->SendChannelUpdate(0);
5837                        pCaster->m_currentSpells[CURRENT_CHANNELED_SPELL]->finish();
5838                    }
5839                }
5840                else
5841                {
5842                    pCaster->SendSpellNonMeleeDamageLog(pCaster, GetId(), gain, GetSpellSchoolMask(GetSpellProto()), 0, 0, false, 0, false);
5843
5844                    CleanDamage cleanDamage =  CleanDamage(0, BASE_ATTACK, MELEE_HIT_NORMAL );
5845                    pCaster->DealDamage(pCaster, gain, &cleanDamage, NODAMAGE, GetSpellSchoolMask(GetSpellProto()), GetSpellProto(), true);
5846                }
5847            }
5848
5849            // ignore item heals
5850            if(procSpell && !haveCastItem)
5851                pCaster->ProcDamageAndSpell(target,PROC_FLAG_NONE, PROC_FLAG_HEALED, pdamage, SPELL_SCHOOL_MASK_NONE, spellProto);
5852            break;
5853        }
5854        case SPELL_AURA_PERIODIC_MANA_LEECH:
5855        {
5856            Unit *pCaster = GetCaster();
5857            if(!pCaster)
5858                return;
5859
5860            if(!pCaster->isAlive())
5861                return;
5862
5863            if( GetSpellProto()->Effect[GetEffIndex()]==SPELL_EFFECT_PERSISTENT_AREA_AURA &&
5864                pCaster->SpellHitResult(m_target,GetSpellProto(),false)!=SPELL_MISS_NONE)
5865                return;
5866
5867            // Check for immune (not use charges)
5868            if(m_target->IsImmunedToDamage(GetSpellSchoolMask(GetSpellProto())))
5869                return;
5870
5871            // ignore non positive values (can be result apply spellmods to aura damage
5872            uint32 pdamage = m_modifier.m_amount > 0 ? m_modifier.m_amount : 0;
5873
5874            sLog.outDetail("PeriodicTick: %u (TypeId: %u) power leech of %u (TypeId: %u) for %u dmg inflicted by %u",
5875                GUID_LOPART(GetCasterGUID()), GuidHigh2TypeId(GUID_HIPART(GetCasterGUID())), m_target->GetGUIDLow(), m_target->GetTypeId(), pdamage, GetId());
5876
5877            if(m_modifier.m_miscvalue < 0 || m_modifier.m_miscvalue > 4)
5878                break;
5879
5880            Powers power = Powers(m_modifier.m_miscvalue);
5881
5882            // power type might have changed between aura applying and tick (druid's shapeshift)
5883            if(m_target->getPowerType() != power)
5884                break;
5885
5886            int32 drain_amount = m_target->GetPower(power) > pdamage ? pdamage : m_target->GetPower(power);
5887
5888            // resilience reduce mana draining effect at spell crit damage reduction (added in 2.4)
5889            if (power == POWER_MANA && m_target->GetTypeId() == TYPEID_PLAYER)
5890                drain_amount -= ((Player*)m_target)->GetSpellCritDamageReduction(drain_amount);
5891
5892            m_target->ModifyPower(power, -drain_amount);
5893
5894            float gain_multiplier = 0;
5895
5896            if(pCaster->GetMaxPower(power) > 0)
5897            {
5898                gain_multiplier = GetSpellProto()->EffectMultipleValue[GetEffIndex()];
5899
5900                if(Player *modOwner = pCaster->GetSpellModOwner())
5901                    modOwner->ApplySpellMod(GetId(), SPELLMOD_MULTIPLE_VALUE, gain_multiplier);
5902            }
5903
5904            WorldPacket data(SMSG_PERIODICAURALOG, (21+16));// we guess size
5905            data.append(m_target->GetPackGUID());
5906            data.appendPackGUID(GetCasterGUID());
5907            data << uint32(GetId());
5908            data << uint32(1);
5909            data << uint32(m_modifier.m_auraname);
5910            data << (uint32)power;                          // power type
5911            data << (uint32)drain_amount;
5912            data << (float)gain_multiplier;
5913            m_target->SendMessageToSet(&data,true);
5914
5915            int32 gain_amount = int32(drain_amount*gain_multiplier);
5916
5917            if(gain_amount)
5918            {
5919                int32 gain = pCaster->ModifyPower(power,gain_amount);
5920                m_target->AddThreat(pCaster, float(gain) * 0.5f, GetSpellSchoolMask(GetSpellProto()), GetSpellProto());
5921            }
5922            break;
5923        }
5924        case SPELL_AURA_PERIODIC_ENERGIZE:
5925        {
5926            // ignore non positive values (can be result apply spellmods to aura damage
5927            uint32 pdamage = m_modifier.m_amount > 0 ? m_modifier.m_amount : 0;
5928
5929            sLog.outDetail("PeriodicTick: %u (TypeId: %u) energize %u (TypeId: %u) for %u dmg inflicted by %u",
5930                GUID_LOPART(GetCasterGUID()), GuidHigh2TypeId(GUID_HIPART(GetCasterGUID())), m_target->GetGUIDLow(), m_target->GetTypeId(), pdamage, GetId());
5931
5932            if(m_modifier.m_miscvalue < 0 || m_modifier.m_miscvalue > 4)
5933                break;
5934
5935            Powers power = Powers(m_modifier.m_miscvalue);
5936
5937            if(m_target->GetMaxPower(power) == 0)
5938                break;
5939
5940            WorldPacket data(SMSG_PERIODICAURALOG, (21+16));// we guess size
5941            data.append(m_target->GetPackGUID());
5942            data.appendPackGUID(GetCasterGUID());
5943            data << uint32(GetId());
5944            data << uint32(1);
5945            data << uint32(m_modifier.m_auraname);
5946            data << (uint32)power;                          // power type
5947            data << (uint32)pdamage;
5948            m_target->SendMessageToSet(&data,true);
5949
5950            int32 gain = m_target->ModifyPower(power,pdamage);
5951
5952            if(Unit* pCaster = GetCaster())
5953                m_target->getHostilRefManager().threatAssist(pCaster, float(gain) * 0.5f, GetSpellProto());
5954            break;
5955        }
5956        case SPELL_AURA_OBS_MOD_MANA:
5957        {
5958            // ignore non positive values (can be result apply spellmods to aura damage
5959            uint32 amount = m_modifier.m_amount > 0 ? m_modifier.m_amount : 0;
5960
5961            uint32 pdamage = uint32(m_target->GetMaxPower(POWER_MANA) * amount/100);
5962
5963            sLog.outDetail("PeriodicTick: %u (TypeId: %u) energize %u (TypeId: %u) for %u mana inflicted by %u",
5964                GUID_LOPART(GetCasterGUID()), GuidHigh2TypeId(GUID_HIPART(GetCasterGUID())), m_target->GetGUIDLow(), m_target->GetTypeId(), pdamage, GetId());
5965
5966            if(m_target->GetMaxPower(POWER_MANA) == 0)
5967                break;
5968
5969            WorldPacket data(SMSG_PERIODICAURALOG, (21+16));// we guess size
5970            data.append(m_target->GetPackGUID());
5971            data.appendPackGUID(GetCasterGUID());
5972            data << uint32(GetId());
5973            data << uint32(1);
5974            data << uint32(m_modifier.m_auraname);
5975            data << (uint32)0;                              // ?
5976            data << (uint32)pdamage;
5977            m_target->SendMessageToSet(&data,true);
5978
5979            int32 gain = m_target->ModifyPower(POWER_MANA, pdamage);
5980
5981            if(Unit* pCaster = GetCaster())
5982                m_target->getHostilRefManager().threatAssist(pCaster, float(gain) * 0.5f, GetSpellProto());
5983            break;
5984        }
5985        case SPELL_AURA_POWER_BURN_MANA:
5986        {
5987            Unit *pCaster = GetCaster();
5988            if(!pCaster)
5989                return;
5990
5991            // Check for immune (not use charges)
5992            if(m_target->IsImmunedToDamage(GetSpellSchoolMask(GetSpellProto())))
5993                return;
5994
5995            int32 pdamage = m_modifier.m_amount > 0 ? m_modifier.m_amount : 0;
5996
5997            Powers powerType = Powers(m_modifier.m_miscvalue);
5998
5999            if(!m_target->isAlive() || m_target->getPowerType() != powerType)
6000                return;
6001
6002            // resilience reduce mana draining effect at spell crit damage reduction (added in 2.4)
6003            if (powerType == POWER_MANA && m_target->GetTypeId() == TYPEID_PLAYER)
6004                pdamage -= ((Player*)m_target)->GetSpellCritDamageReduction(pdamage);
6005
6006            uint32 gain = uint32(-m_target->ModifyPower(powerType, -pdamage));
6007
6008            gain = uint32(gain * GetSpellProto()->EffectMultipleValue[GetEffIndex()]);
6009
6010            //maybe has to be sent different to client, but not by SMSG_PERIODICAURALOG
6011            pCaster->SpellNonMeleeDamageLog(m_target, GetId(), gain);
6012            break;
6013        }
6014        // Here tick dummy auras
6015        case SPELL_AURA_PERIODIC_DUMMY:
6016        {
6017            PeriodicDummyTick();
6018            break;
6019        }
6020        default:
6021            break;
6022    }
6023}
6024
6025void Aura::PeriodicDummyTick()
6026{
6027    SpellEntry const* spell = GetSpellProto();
6028    switch (spell->Id)
6029    {
6030        // Drink
6031        case 430:
6032        case 431:
6033        case 432:
6034        case 1133:
6035        case 1135:
6036        case 1137:
6037        case 10250:
6038        case 22734:
6039        case 27089:
6040        case 34291:
6041        case 43706:
6042        case 46755:
6043        {
6044            if (m_target->GetTypeId() != TYPEID_PLAYER)
6045                return;
6046            // Search SPELL_AURA_MOD_POWER_REGEN aura for this spell and add bonus
6047            Unit::AuraList const& aura = m_target->GetAurasByType(SPELL_AURA_MOD_POWER_REGEN);
6048            for(Unit::AuraList::const_iterator i = aura.begin(); i != aura.end(); ++i)
6049            {
6050                if ((*i)->GetId() == GetId())
6051                {
6052                    // Get tick number
6053                    int32 tick = (m_maxduration - m_duration) / m_modifier.periodictime;
6054                    // Default case (not on arenas)
6055                    if (tick == 0)
6056                    {
6057                        (*i)->GetModifier()->m_amount = m_modifier.m_amount;
6058                        ((Player*)m_target)->UpdateManaRegen();
6059                        // Disable continue
6060                        m_isPeriodic = false;
6061                    }
6062                    return;
6063                    //**********************************************
6064                    // Code commended since arena patch not added
6065                    // This feature uses only in arenas
6066                    //**********************************************
6067                    // Here need increase mana regen per tick (6 second rule)
6068                    // on 0 tick -   0  (handled in 2 second)
6069                    // on 1 tick - 166% (handled in 4 second)
6070                    // on 2 tick - 133% (handled in 6 second)
6071                    // Not need update after 3 tick
6072                    /*
6073                    if (tick > 3)
6074                        return;
6075                    // Apply bonus for 0 - 3 tick
6076                    switch (tick)
6077                    {
6078                        case 0:   // 0%
6079                            (*i)->GetModifier()->m_amount = m_modifier.m_amount = 0;
6080                            break;
6081                        case 1:   // 166%
6082                            (*i)->GetModifier()->m_amount = m_modifier.m_amount * 5 / 3;
6083                            break;
6084                        case 2:   // 133%
6085                            (*i)->GetModifier()->m_amount = m_modifier.m_amount * 4 / 3;
6086                            break;
6087                        default:  // 100% - normal regen
6088                            (*i)->GetModifier()->m_amount = m_modifier.m_amount;
6089                            break;
6090                    }
6091                    ((Player*)m_target)->UpdateManaRegen();
6092                    return;*/
6093                }
6094            }
6095            return;
6096        }
6097//        // Panda
6098//        case 19230: break;
6099//        // Master of Subtlety
6100//        case 31666: break;
6101//        // Gossip NPC Periodic - Talk
6102//        case 33208: break;
6103//        // Gossip NPC Periodic - Despawn
6104//        case 33209: break;
6105//        // Force of Nature
6106//        case 33831: break;
6107        // Aspect of the Viper
6108        case 34074:
6109        {
6110            if (m_target->GetTypeId() != TYPEID_PLAYER)
6111                return;
6112            // Should be manauser
6113            if (m_target->getPowerType()!=POWER_MANA)
6114                return;
6115            Unit *caster = GetCaster();
6116            if (!caster)
6117                return;
6118            // Regen amount is max (100% from spell) on 21% or less mana and min on 92.5% or greater mana (20% from spell)
6119            int mana = m_target->GetPower(POWER_MANA);
6120            int max_mana = m_target->GetMaxPower(POWER_MANA);
6121            int32 base_regen = caster->CalculateSpellDamage(m_spellProto, m_effIndex, m_currentBasePoints, m_target);
6122            float regen_pct = 1.20f - 1.1f * mana / max_mana;
6123            if      (regen_pct > 1.0f) regen_pct = 1.0f;
6124            else if (regen_pct < 0.2f) regen_pct = 0.2f;
6125            m_modifier.m_amount = int32 (base_regen * regen_pct);
6126            ((Player*)m_target)->UpdateManaRegen();
6127            return;
6128        }
6129//        // Steal Weapon
6130//        case 36207: break;
6131//        // Simon Game START timer, (DND)
6132//        case 39993: break;
6133//        // Harpooner's Mark
6134//        case 40084: break;
6135//        // Knockdown Fel Cannon: break; The Aggro Burst
6136//        case 40119: break;
6137//        // Old Mount Spell
6138//        case 40154: break;
6139//        // Magnetic Pull
6140//        case 40581: break;
6141//        // Ethereal Ring: break; The Bolt Burst
6142//        case 40801: break;
6143//        // Crystal Prison
6144//        case 40846: break;
6145//        // Copy Weapon
6146//        case 41054: break;
6147//        // Ethereal Ring Visual, Lightning Aura
6148//        case 41477: break;
6149//        // Ethereal Ring Visual, Lightning Aura (Fork)
6150//        case 41525: break;
6151//        // Ethereal Ring Visual, Lightning Jumper Aura
6152//        case 41567: break;
6153//        // No Man's Land
6154//        case 41955: break;
6155//        // Headless Horseman - Fire
6156//        case 42074: break;
6157//        // Headless Horseman - Visual - Large Fire
6158//        case 42075: break;
6159//        // Headless Horseman - Start Fire, Periodic Aura
6160//        case 42140: break;
6161//        // Ram Speed Boost
6162//        case 42152: break;
6163//        // Headless Horseman - Fires Out Victory Aura
6164//        case 42235: break;
6165//        // Pumpkin Life Cycle
6166//        case 42280: break;
6167//        // Brewfest Request Chick Chuck Mug Aura
6168//        case 42537: break;
6169//        // Squashling
6170//        case 42596: break;
6171//        // Headless Horseman Climax, Head: Periodic
6172//        case 42603: break;
6173//        // Fire Bomb
6174//        case 42621: break;
6175//        // Headless Horseman - Conflagrate, Periodic Aura
6176//        case 42637: break;
6177//        // Headless Horseman - Create Pumpkin Treats Aura
6178//        case 42774: break;
6179//        // Headless Horseman Climax - Summoning Rhyme Aura
6180//        case 42879: break;
6181//        // Tricky Treat
6182//        case 42919: break;
6183//        // Giddyup!
6184//        case 42924: break;
6185//        // Ram - Trot
6186//        case 42992: break;
6187//        // Ram - Canter
6188//        case 42993: break;
6189//        // Ram - Gallop
6190//        case 42994: break;
6191//        // Ram Level - Neutral
6192//        case 43310: break;
6193//        // Headless Horseman - Maniacal Laugh, Maniacal, Delayed 17
6194//        case 43884: break;
6195//        // Headless Horseman - Maniacal Laugh, Maniacal, other, Delayed 17
6196//        case 44000: break;
6197//        // Energy Feedback
6198//        case 44328: break;
6199//        // Romantic Picnic
6200//        case 45102: break;
6201//        // Romantic Picnic
6202//        case 45123: break;
6203//        // Looking for Love
6204//        case 45124: break;
6205//        // Kite - Lightning Strike Kite Aura
6206//        case 45197: break;
6207//        // Rocket Chicken
6208//        case 45202: break;
6209//        // Copy Offhand Weapon
6210//        case 45205: break;
6211//        // Upper Deck - Kite - Lightning Periodic Aura
6212//        case 45207: break;
6213//        // Kite -Sky  Lightning Strike Kite Aura
6214//        case 45251: break;
6215//        // Ribbon Pole Dancer Check Aura
6216//        case 45390: break;
6217//        // Holiday - Midsummer, Ribbon Pole Periodic Visual
6218//        case 45406: break;
6219//        // Parachute
6220//        case 45472: break;
6221//        // Alliance Flag, Extra Damage Debuff
6222//        case 45898: break;
6223//        // Horde Flag, Extra Damage Debuff
6224//        case 45899: break;
6225//        // Ahune - Summoning Rhyme Aura
6226//        case 45926: break;
6227//        // Ahune - Slippery Floor
6228//        case 45945: break;
6229//        // Ahune's Shield
6230//        case 45954: break;
6231//        // Nether Vapor Lightning
6232//        case 45960: break;
6233//        // Darkness
6234//        case 45996: break;
6235//        // Summon Blood Elves Periodic
6236//        case 46041: break;
6237//        // Transform Visual Missile Periodic
6238//        case 46205: break;
6239//        // Find Opening Beam End
6240//        case 46333: break;
6241//        // Ice Spear Control Aura
6242//        case 46371: break;
6243//        // Hailstone Chill
6244//        case 46458: break;
6245//        // Hailstone Chill, Internal
6246//        case 46465: break;
6247//        // Chill, Internal Shifter
6248//        case 46549: break;
6249//        // Summon Ice Spear Knockback Delayer
6250//        case 46878: break;
6251//        // Burninate Effect
6252//        case 47214: break;
6253//        // Fizzcrank Practice Parachute
6254//        case 47228: break;
6255//        // Send Mug Control Aura
6256//        case 47369: break;
6257//        // Direbrew's Disarm (precast)
6258//        case 47407: break;
6259//        // Mole Machine Port Schedule
6260//        case 47489: break;
6261//        // Mole Machine Portal Schedule
6262//        case 49466: break;
6263//        // Drink Coffee
6264//        case 49472: break;
6265//        // Listening to Music
6266//        case 50493: break;
6267//        // Love Rocket Barrage
6268//        case 50530: break;
6269        default:
6270            break;
6271    }
6272}
6273
6274void Aura::HandlePreventFleeing(bool apply, bool Real)
6275{
6276    if(!Real)
6277        return;
6278
6279    Unit::AuraList const& fearAuras = m_target->GetAurasByType(SPELL_AURA_MOD_FEAR);
6280    if( !fearAuras.empty() )
6281    {
6282        if (apply)
6283            m_target->SetFeared(false, fearAuras.front()->GetCasterGUID());
6284        else
6285            m_target->SetFeared(true);
6286    }
6287}
6288
6289void Aura::HandleManaShield(bool apply, bool Real)
6290{
6291    if(!Real)
6292        return;
6293
6294    // prevent double apply bonuses
6295    if(apply && (m_target->GetTypeId()!=TYPEID_PLAYER || !((Player*)m_target)->GetSession()->PlayerLoading()))
6296    {
6297        if(Unit* caster = GetCaster())
6298        {
6299            float DoneActualBenefit = 0.0f;
6300            switch(m_spellProto->SpellFamilyName)
6301            {
6302                case SPELLFAMILY_MAGE:
6303                    if(m_spellProto->SpellFamilyFlags & 0x8000)
6304                    {
6305                        // Mana Shield
6306                        // +50% from +spd bonus
6307                        DoneActualBenefit = caster->SpellBaseDamageBonus(GetSpellSchoolMask(m_spellProto)) * 0.5f;
6308                        break;
6309                    }
6310                    break;
6311                default:
6312                    break;
6313            }
6314
6315            DoneActualBenefit *= caster->CalculateLevelPenalty(GetSpellProto());
6316
6317            m_modifier.m_amount += (int32)DoneActualBenefit;
6318        }
6319    }
6320}
6321
6322void Aura::HandleArenaPreparation(bool apply, bool Real)
6323{
6324    if(!Real)
6325        return;
6326
6327    if(apply)
6328        m_target->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PREPARATION);
6329    else
6330        m_target->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PREPARATION);
6331}
Note: See TracBrowser for help on using the browser.