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

Revision 2, 248.0 kB (checked in by yumileroy, 17 years ago)

[svn] * Proper SVN structure

Original author: Neo2003
Date: 2008-10-02 16:23:55-05:00

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