OregonCore  revision fb2a440-git
Your Favourite TBC server
SpellAuras.cpp
Go to the documentation of this file.
1 /*
2  * This file is part of the OregonCore Project. See AUTHORS file for Copyright information
3  *
4  * This program is free software; you can redistribute it and/or modify it
5  * under the terms of the GNU General Public License as published by the
6  * Free Software Foundation; either version 2 of the License, or (at your
7  * option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12  * more details.
13  *
14  * You should have received a copy of the GNU General Public License along
15  * with this program. If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 #include "Common.h"
19 #include "Database/DatabaseEnv.h"
20 #include "WorldPacket.h"
21 #include "WorldSession.h"
22 #include "Opcodes.h"
23 #include "Log.h"
24 #include "UpdateMask.h"
25 #include "World.h"
26 #include "ObjectMgr.h"
27 #include "SpellMgr.h"
28 #include "Player.h"
29 #include "Unit.h"
30 #include "Spell.h"
31 #include "SpellAuras.h"
32 #include "DynamicObject.h"
33 #include "Group.h"
34 #include "UpdateData.h"
35 #include "MapManager.h"
36 #include "ObjectAccessor.h"
37 #include "Totem.h"
38 #include "Creature.h"
39 #include "Formulas.h"
40 #include "Battleground.h"
41 #include "OutdoorPvP.h"
42 #include "OutdoorPvPMgr.h"
43 #include "CreatureAI.h"
44 #include "Utilities/Util.h"
45 #include "GridNotifiers.h"
46 #include "GridNotifiersImpl.h"
47 #include "ScriptMgr.h"
48 #include "CellImpl.h"
49 
50 #define NULL_AURA_SLOT 0xFF
51 
53 {
54  &Aura::HandleNULL, // 0 SPELL_AURA_NONE
55  &Aura::HandleBindSight, // 1 SPELL_AURA_BIND_SIGHT
56  &Aura::HandleModPossess, // 2 SPELL_AURA_MOD_POSSESS
57  &Aura::HandlePeriodicDamage, // 3 SPELL_AURA_PERIODIC_DAMAGE
58  &Aura::HandleAuraDummy, // 4 SPELL_AURA_DUMMY
59  &Aura::HandleModConfuse, // 5 SPELL_AURA_MOD_CONFUSE
60  &Aura::HandleModCharm, // 6 SPELL_AURA_MOD_CHARM
61  &Aura::HandleModFear, // 7 SPELL_AURA_MOD_FEAR
62  &Aura::HandlePeriodicHeal, // 8 SPELL_AURA_PERIODIC_HEAL
63  &Aura::HandleModAttackSpeed, // 9 SPELL_AURA_MOD_ATTACKSPEED
64  &Aura::HandleModThreat, // 10 SPELL_AURA_MOD_THREAT
65  &Aura::HandleModTaunt, // 11 SPELL_AURA_MOD_TAUNT
66  &Aura::HandleAuraModStun, // 12 SPELL_AURA_MOD_STUN
67  &Aura::HandleModDamageDone, // 13 SPELL_AURA_MOD_DAMAGE_DONE
68  &Aura::HandleNoImmediateEffect, // 14 SPELL_AURA_MOD_DAMAGE_TAKEN implemented in Unit::MeleeDamageBonus and Unit::SpellDamageBonus
69  &Aura::HandleNoImmediateEffect, // 15 SPELL_AURA_DAMAGE_SHIELD implemented in Unit::DoAttackDamage
70  &Aura::HandleModStealth, // 16 SPELL_AURA_MOD_STEALTH
71  &Aura::HandleModStealthDetect, // 17 SPELL_AURA_MOD_STEALTH_DETECT
72  &Aura::HandleModInvisibility, // 18 SPELL_AURA_MOD_INVISIBILITY
73  &Aura::HandleModInvisibilityDetect, // 19 SPELL_AURA_MOD_INVISIBILITY_DETECTION
74  &Aura::HandleAuraModTotalHealthPercentRegen, // 20 SPELL_AURA_OBS_MOD_HEALTH
75  &Aura::HandleAuraModTotalManaPercentRegen, // 21 SPELL_AURA_OBS_MOD_MANA
76  &Aura::HandleAuraModResistance, // 22 SPELL_AURA_MOD_RESISTANCE
77  &Aura::HandlePeriodicTriggerSpell, // 23 SPELL_AURA_PERIODIC_TRIGGER_SPELL
78  &Aura::HandlePeriodicEnergize, // 24 SPELL_AURA_PERIODIC_ENERGIZE
79  &Aura::HandleAuraModPacify, // 25 SPELL_AURA_MOD_PACIFY
80  &Aura::HandleAuraModRoot, // 26 SPELL_AURA_MOD_ROOT
81  &Aura::HandleAuraModSilence, // 27 SPELL_AURA_MOD_SILENCE
82  &Aura::HandleNoImmediateEffect, // 28 SPELL_AURA_REFLECT_SPELLS implement in Unit::SpellHitResult
83  &Aura::HandleAuraModStat, // 29 SPELL_AURA_MOD_STAT
84  &Aura::HandleAuraModSkill, // 30 SPELL_AURA_MOD_SKILL
85  &Aura::HandleAuraModIncreaseSpeed, // 31 SPELL_AURA_MOD_INCREASE_SPEED
86  &Aura::HandleAuraModIncreaseMountedSpeed, // 32 SPELL_AURA_MOD_INCREASE_MOUNTED_SPEED
87  &Aura::HandleAuraModDecreaseSpeed, // 33 SPELL_AURA_MOD_DECREASE_SPEED
88  &Aura::HandleAuraModIncreaseHealth, // 34 SPELL_AURA_MOD_INCREASE_HEALTH
89  &Aura::HandleAuraModIncreaseEnergy, // 35 SPELL_AURA_MOD_INCREASE_ENERGY
90  &Aura::HandleAuraModShapeshift, // 36 SPELL_AURA_MOD_SHAPESHIFT
91  &Aura::HandleAuraModEffectImmunity, // 37 SPELL_AURA_EFFECT_IMMUNITY
92  &Aura::HandleAuraModStateImmunity, // 38 SPELL_AURA_STATE_IMMUNITY
93  &Aura::HandleAuraModSchoolImmunity, // 39 SPELL_AURA_SCHOOL_IMMUNITY
94  &Aura::HandleAuraModDmgImmunity, // 40 SPELL_AURA_DAMAGE_IMMUNITY
95  &Aura::HandleAuraModDispelImmunity, // 41 SPELL_AURA_DISPEL_IMMUNITY
96  &Aura::HandleAuraProcTriggerSpell, // 42 SPELL_AURA_PROC_TRIGGER_SPELL implemented in Unit::ProcDamageAndSpellFor and Unit::HandleProcTriggerSpell
97  &Aura::HandleNoImmediateEffect, // 43 SPELL_AURA_PROC_TRIGGER_DAMAGE implemented in Unit::ProcDamageAndSpellFor
98  &Aura::HandleAuraTrackCreatures, // 44 SPELL_AURA_TRACK_CREATURES
99  &Aura::HandleAuraTrackResources, // 45 SPELL_AURA_TRACK_RESOURCES
100  &Aura::HandleUnused, // 46 SPELL_AURA_MOD_PARRY_SKILL obsolete?
101  &Aura::HandleAuraModParryPercent, // 47 SPELL_AURA_MOD_PARRY_PERCENT
102  &Aura::HandleUnused, // 48 SPELL_AURA_MOD_DODGE_SKILL obsolete?
103  &Aura::HandleAuraModDodgePercent, // 49 SPELL_AURA_MOD_DODGE_PERCENT
104  &Aura::HandleUnused, // 50 SPELL_AURA_MOD_BLOCK_SKILL obsolete?
105  &Aura::HandleAuraModBlockPercent, // 51 SPELL_AURA_MOD_BLOCK_PERCENT
106  &Aura::HandleAuraModCritPercent, // 52 SPELL_AURA_MOD_CRIT_PERCENT
107  &Aura::HandlePeriodicLeech, // 53 SPELL_AURA_PERIODIC_LEECH
108  &Aura::HandleModHitChance, // 54 SPELL_AURA_MOD_HIT_CHANCE
109  &Aura::HandleModSpellHitChance, // 55 SPELL_AURA_MOD_SPELL_HIT_CHANCE
110  &Aura::HandleAuraTransform, // 56 SPELL_AURA_TRANSFORM
111  &Aura::HandleModSpellCritChance, // 57 SPELL_AURA_MOD_SPELL_CRIT_CHANCE
112  &Aura::HandleAuraModIncreaseSwimSpeed, // 58 SPELL_AURA_MOD_INCREASE_SWIM_SPEED
113  &Aura::HandleNoImmediateEffect, // 59 SPELL_AURA_MOD_DAMAGE_DONE_CREATURE implemented in Unit::MeleeDamageBonus and Unit::SpellDamageBonus
114  &Aura::HandleAuraModPacifyAndSilence, // 60 SPELL_AURA_MOD_PACIFY_SILENCE
115  &Aura::HandleAuraModScale, // 61 SPELL_AURA_MOD_SCALE
116  &Aura::HandleNULL, // 62 SPELL_AURA_PERIODIC_HEALTH_FUNNEL
117  &Aura::HandleUnused, // 63 SPELL_AURA_PERIODIC_MANA_FUNNEL obsolete?
118  &Aura::HandlePeriodicManaLeech, // 64 SPELL_AURA_PERIODIC_MANA_LEECH
119  &Aura::HandleModCastingSpeed, // 65 SPELL_AURA_MOD_CASTING_SPEED
120  &Aura::HandleFeignDeath, // 66 SPELL_AURA_FEIGN_DEATH
121  &Aura::HandleAuraModDisarm, // 67 SPELL_AURA_MOD_DISARM
122  &Aura::HandleAuraModStalked, // 68 SPELL_AURA_MOD_STALKED
123  &Aura::HandleSchoolAbsorb, // 69 SPELL_AURA_SCHOOL_ABSORB implemented in Unit::CalcAbsorbResist
124  &Aura::HandleUnused, // 70 SPELL_AURA_EXTRA_ATTACKS Useless, used by only one spell that has only visual effect
125  &Aura::HandleModSpellCritChanceShool, // 71 SPELL_AURA_MOD_SPELL_CRIT_CHANCE_SCHOOL
126  &Aura::HandleModPowerCostPCT, // 72 SPELL_AURA_MOD_POWER_COST_SCHOOL_PCT
127  &Aura::HandleModPowerCost, // 73 SPELL_AURA_MOD_POWER_COST_SCHOOL
128  &Aura::HandleAuraReflectSpellSchool, // 74 SPELL_AURA_REFLECT_SPELLS_SCHOOL implemented in Unit::SpellHitResult
129  &Aura::HandleNoImmediateEffect, // 75 SPELL_AURA_MOD_LANGUAGE
130  &Aura::HandleFarSight, // 76 SPELL_AURA_FAR_SIGHT
131  &Aura::HandleModMechanicImmunity, // 77 SPELL_AURA_MECHANIC_IMMUNITY
132  &Aura::HandleAuraMounted, // 78 SPELL_AURA_MOUNTED
133  &Aura::HandleModDamagePercentDone, // 79 SPELL_AURA_MOD_DAMAGE_PERCENT_DONE
134  &Aura::HandleModPercentStat, // 80 SPELL_AURA_MOD_PERCENT_STAT
135  &Aura::HandleNoImmediateEffect, // 81 SPELL_AURA_SPLIT_DAMAGE_PCT
136  &Aura::HandleWaterBreathing, // 82 SPELL_AURA_WATER_BREATHING
137  &Aura::HandleModBaseResistance, // 83 SPELL_AURA_MOD_BASE_RESISTANCE
138  &Aura::HandleModRegen, // 84 SPELL_AURA_MOD_REGEN
139  &Aura::HandleModPowerRegen, // 85 SPELL_AURA_MOD_POWER_REGEN
140  &Aura::HandleChannelDeathItem, // 86 SPELL_AURA_CHANNEL_DEATH_ITEM
141  &Aura::HandleNoImmediateEffect, // 87 SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN implemented in Unit::MeleeDamageBonus and Unit::SpellDamageBonus
142  &Aura::HandleNoImmediateEffect, // 88 SPELL_AURA_MOD_HEALTH_REGEN_PERCENT
143  &Aura::HandlePeriodicDamagePCT, // 89 SPELL_AURA_PERIODIC_DAMAGE_PERCENT
144  &Aura::HandleUnused, // 90 SPELL_AURA_MOD_RESIST_CHANCE Useless
145  &Aura::HandleNoImmediateEffect, // 91 SPELL_AURA_MOD_DETECT_RANGE implemented in Creature::GetAttackDistance
146  &Aura::HandlePreventFleeing, // 92 SPELL_AURA_PREVENTS_FLEEING
147  &Aura::HandleModUnattackable, // 93 SPELL_AURA_MOD_UNATTACKABLE
148  &Aura::HandleNoImmediateEffect, // 94 SPELL_AURA_INTERRUPT_REGEN implemented in Player::RegenerateAll
149  &Aura::HandleAuraGhost, // 95 SPELL_AURA_GHOST
150  &Aura::HandleNoImmediateEffect, // 96 SPELL_AURA_SPELL_MAGNET implemented in Spell::SelectMagnetTarget
151  &Aura::HandleManaShield, // 97 SPELL_AURA_MANA_SHIELD implemented in Unit::CalcAbsorbResist
152  &Aura::HandleAuraModSkill, // 98 SPELL_AURA_MOD_SKILL_TALENT
153  &Aura::HandleAuraModAttackPower, // 99 SPELL_AURA_MOD_ATTACK_POWER
154  &Aura::HandleUnused, //100 SPELL_AURA_AURAS_VISIBLE obsolete? all player can see all auras now
155  &Aura::HandleModResistancePercent, //101 SPELL_AURA_MOD_RESISTANCE_PCT
156  &Aura::HandleNoImmediateEffect, //102 SPELL_AURA_MOD_MELEE_ATTACK_POWER_VERSUS implemented in Unit::MeleeDamageBonus
157  &Aura::HandleAuraModTotalThreat, //103 SPELL_AURA_MOD_TOTAL_THREAT
158  &Aura::HandleAuraWaterWalk, //104 SPELL_AURA_WATER_WALK
159  &Aura::HandleAuraFeatherFall, //105 SPELL_AURA_FEATHER_FALL
160  &Aura::HandleAuraHover, //106 SPELL_AURA_HOVER
161  &Aura::HandleAddModifier, //107 SPELL_AURA_ADD_FLAT_MODIFIER
162  &Aura::HandleAddModifier, //108 SPELL_AURA_ADD_PCT_MODIFIER
163  &Aura::HandleNoImmediateEffect, //109 SPELL_AURA_ADD_TARGET_TRIGGER
164  &Aura::HandleModPowerRegenPCT, //110 SPELL_AURA_MOD_POWER_REGEN_PERCENT
165  &Aura::HandleNoImmediateEffect, //111 SPELL_AURA_ADD_CASTER_HIT_TRIGGER implemented in Spell::HandleHitTriggerAura
166  &Aura::HandleNoImmediateEffect, //112 SPELL_AURA_OVERRIDE_CLASS_SCRIPTS another Dummy spells
167  &Aura::HandleNoImmediateEffect, //113 SPELL_AURA_MOD_RANGED_DAMAGE_TAKEN implemented in Unit::MeleeDamageBonus
168  &Aura::HandleNoImmediateEffect, //114 SPELL_AURA_MOD_RANGED_DAMAGE_TAKEN_PCT implemented in Unit::MeleeDamageBonus
169  &Aura::HandleNoImmediateEffect, //115 SPELL_AURA_MOD_HEALING implemented in Unit::SpellBaseHealingBonusForVictim
170  &Aura::HandleNoImmediateEffect, //116 SPELL_AURA_MOD_REGEN_DURING_COMBAT
171  &Aura::HandleNoImmediateEffect, //117 SPELL_AURA_MOD_MECHANIC_RESISTANCE implemented in Unit::MagicSpellHitResult
172  &Aura::HandleNoImmediateEffect, //118 SPELL_AURA_MOD_HEALING_PCT implemented in Unit::SpellHealingBonus
173  &Aura::HandleUnused, //119 SPELL_AURA_SHARE_PET_TRACKING useless
174  &Aura::HandleAuraUntrackable, //120 SPELL_AURA_UNTRACKABLE
175  &Aura::HandleAuraEmpathy, //121 SPELL_AURA_EMPATHY
176  &Aura::HandleModOffhandDamagePercent, //122 SPELL_AURA_MOD_OFFHAND_DAMAGE_PCT
177  &Aura::HandleModTargetResistance, //123 SPELL_AURA_MOD_TARGET_RESISTANCE
178  &Aura::HandleAuraModRangedAttackPower, //124 SPELL_AURA_MOD_RANGED_ATTACK_POWER
179  &Aura::HandleNoImmediateEffect, //125 SPELL_AURA_MOD_MELEE_DAMAGE_TAKEN implemented in Unit::MeleeDamageBonus
180  &Aura::HandleNoImmediateEffect, //126 SPELL_AURA_MOD_MELEE_DAMAGE_TAKEN_PCT implemented in Unit::MeleeDamageBonus
181  &Aura::HandleNoImmediateEffect, //127 SPELL_AURA_RANGED_ATTACK_POWER_ATTACKER_BONUS implemented in Unit::MeleeDamageBonus
182  &Aura::HandleModPossessPet, //128 SPELL_AURA_MOD_POSSESS_PET
183  &Aura::HandleAuraModIncreaseSpeed, //129 SPELL_AURA_MOD_SPEED_ALWAYS
184  &Aura::HandleAuraModIncreaseMountedSpeed, //130 SPELL_AURA_MOD_MOUNTED_SPEED_ALWAYS
185  &Aura::HandleNoImmediateEffect, //131 SPELL_AURA_MOD_RANGED_ATTACK_POWER_VERSUS implemented in Unit::MeleeDamageBonus
186  &Aura::HandleAuraModIncreaseEnergyPercent, //132 SPELL_AURA_MOD_INCREASE_ENERGY_PERCENT
187  &Aura::HandleAuraModIncreaseHealthPercent, //133 SPELL_AURA_MOD_INCREASE_HEALTH_PERCENT
188  &Aura::HandleAuraModRegenInterrupt, //134 SPELL_AURA_MOD_MANA_REGEN_INTERRUPT
189  &Aura::HandleModHealingDone, //135 SPELL_AURA_MOD_HEALING_DONE
190  &Aura::HandleNoImmediateEffect, //136 SPELL_AURA_MOD_HEALING_DONE_PERCENT implemented in Unit::SpellHealingBonus
191  &Aura::HandleModTotalPercentStat, //137 SPELL_AURA_MOD_TOTAL_STAT_PERCENTAGE
192  &Aura::HandleHaste, //138 SPELL_AURA_MOD_HASTE
193  &Aura::HandleForceReaction, //139 SPELL_AURA_FORCE_REACTION
194  &Aura::HandleAuraModRangedHaste, //140 SPELL_AURA_MOD_RANGED_HASTE
195  &Aura::HandleRangedAmmoHaste, //141 SPELL_AURA_MOD_RANGED_AMMO_HASTE
196  &Aura::HandleAuraModBaseResistancePCT, //142 SPELL_AURA_MOD_BASE_RESISTANCE_PCT
197  &Aura::HandleAuraModResistanceExclusive, //143 SPELL_AURA_MOD_RESISTANCE_EXCLUSIVE
198  &Aura::HandleNoImmediateEffect, //144 SPELL_AURA_SAFE_FALL implemented in WorldSession::HandleMovementOpcodes
199  &Aura::HandleUnused, //145 SPELL_AURA_CHARISMA obsolete?
200  &Aura::HandleUnused, //146 SPELL_AURA_PERSUADED obsolete?
201  &Aura::HandleNULL, //147 SPELL_AURA_MECHANIC_IMMUNITY_MASK
202  &Aura::HandleAuraRetainComboPoints, //148 SPELL_AURA_RETAIN_COMBO_POINTS
203  &Aura::HandleNoImmediateEffect, //149 SPELL_AURA_RESIST_PUSHBACK
204  &Aura::HandleShieldBlockValue, //150 SPELL_AURA_MOD_SHIELD_BLOCKVALUE_PCT
205  &Aura::HandleAuraTrackStealthed, //151 SPELL_AURA_TRACK_STEALTHED
206  &Aura::HandleNoImmediateEffect, //152 SPELL_AURA_MOD_DETECTED_RANGE implemented in Creature::GetAttackDistance
207  &Aura::HandleNoImmediateEffect, //153 SPELL_AURA_SPLIT_DAMAGE_FLAT
208  &Aura::HandleModStealthLevel, //154 SPELL_AURA_MOD_STEALTH_LEVEL
209  &Aura::HandleNoImmediateEffect, //155 SPELL_AURA_MOD_WATER_BREATHING
210  &Aura::HandleNoImmediateEffect, //156 SPELL_AURA_MOD_REPUTATION_GAIN
211  &Aura::HandleNULL, //157 SPELL_AURA_PET_DAMAGE_MULTI
212  &Aura::HandleShieldBlockValue, //158 SPELL_AURA_MOD_SHIELD_BLOCKVALUE
213  &Aura::HandleNoImmediateEffect, //159 SPELL_AURA_NO_PVP_CREDIT only for Honorless Target spell
214  &Aura::HandleNoImmediateEffect, //160 SPELL_AURA_MOD_AOE_AVOIDANCE implemented in Unit::MagicSpellHitResult
215  &Aura::HandleNoImmediateEffect, //161 SPELL_AURA_MOD_HEALTH_REGEN_IN_COMBAT
216  &Aura::HandleAuraPowerBurn, //162 SPELL_AURA_POWER_BURN_MANA
217  &Aura::HandleNoImmediateEffect, //163 SPELL_AURA_MOD_CRIT_DAMAGE_BONUS_MELEE
218  &Aura::HandleUnused, //164 useless, only one test spell
219  &Aura::HandleNoImmediateEffect, //165 SPELL_AURA_MELEE_ATTACK_POWER_ATTACKER_BONUS implemented in Unit::MeleeDamageBonus
220  &Aura::HandleAuraModAttackPowerPercent, //166 SPELL_AURA_MOD_ATTACK_POWER_PCT
221  &Aura::HandleAuraModRangedAttackPowerPercent, //167 SPELL_AURA_MOD_RANGED_ATTACK_POWER_PCT
222  &Aura::HandleNoImmediateEffect, //168 SPELL_AURA_MOD_DAMAGE_DONE_VERSUS implemented in Unit::SpellDamageBonus, Unit::MeleeDamageBonus
223  &Aura::HandleNoImmediateEffect, //169 SPELL_AURA_MOD_CRIT_PERCENT_VERSUS implemented in Unit::DealDamageBySchool, Unit::DoAttackDamage, Unit::SpellCriticalBonus
224  &Aura::HandleNULL, //170 SPELL_AURA_DETECT_AMORE only for Detect Amore spell
225  &Aura::HandleAuraModIncreaseSpeed, //171 SPELL_AURA_MOD_SPEED_NOT_STACK
226  &Aura::HandleAuraModIncreaseMountedSpeed, //172 SPELL_AURA_MOD_MOUNTED_SPEED_NOT_STACK
227  &Aura::HandleUnused, //173 SPELL_AURA_ALLOW_CHAMPION_SPELLS only for Proclaim Champion spell
228  &Aura::HandleModSpellDamagePercentFromStat, //174 SPELL_AURA_MOD_SPELL_DAMAGE_OF_STAT_PERCENT implemented in Unit::SpellBaseDamageBonus (by default intellect, dependent from SPELL_AURA_MOD_SPELL_HEALING_OF_STAT_PERCENT)
229  &Aura::HandleModSpellHealingPercentFromStat, //175 SPELL_AURA_MOD_SPELL_HEALING_OF_STAT_PERCENT implemented in Unit::SpellBaseHealingBonus
230  &Aura::HandleSpiritOfRedemption, //176 SPELL_AURA_SPIRIT_OF_REDEMPTION only for Spirit of Redemption spell, die at aura end
231  &Aura::HandleNULL, //177 SPELL_AURA_AOE_CHARM
232  &Aura::HandleNoImmediateEffect, //178 SPELL_AURA_MOD_DEBUFF_RESISTANCE implemented in Unit::MagicSpellHitResult
233  &Aura::HandleNoImmediateEffect, //179 SPELL_AURA_MOD_ATTACKER_SPELL_CRIT_CHANCE implemented in Unit::SpellCriticalBonus
234  &Aura::HandleNoImmediateEffect, //180 SPELL_AURA_MOD_FLAT_SPELL_DAMAGE_VERSUS implemented in Unit::SpellDamageBonus
235  &Aura::HandleUnused, //181 SPELL_AURA_MOD_FLAT_SPELL_CRIT_DAMAGE_VERSUS unused
236  &Aura::HandleAuraModResistenceOfStatPercent, //182 SPELL_AURA_MOD_RESISTANCE_OF_STAT_PERCENT
237  &Aura::HandleNULL, //183 SPELL_AURA_MOD_CRITICAL_THREAT
238  &Aura::HandleNoImmediateEffect, //184 SPELL_AURA_MOD_ATTACKER_MELEE_HIT_CHANCE implemented in Unit::RollMeleeOutcomeAgainst
239  &Aura::HandleNoImmediateEffect, //185 SPELL_AURA_MOD_ATTACKER_RANGED_HIT_CHANCE implemented in Unit::RollMeleeOutcomeAgainst
240  &Aura::HandleNoImmediateEffect, //186 SPELL_AURA_MOD_ATTACKER_SPELL_HIT_CHANCE implemented in Unit::MagicSpellHitResult
241  &Aura::HandleNoImmediateEffect, //187 SPELL_AURA_MOD_ATTACKER_MELEE_CRIT_CHANCE implemented in Unit::GetUnitCriticalChance
242  &Aura::HandleNoImmediateEffect, //188 SPELL_AURA_MOD_ATTACKER_RANGED_CRIT_CHANCE implemented in Unit::GetUnitCriticalChance
243  &Aura::HandleModRating, //189 SPELL_AURA_MOD_RATING
244  &Aura::HandleNULL, //190 SPELL_AURA_MOD_FACTION_REPUTATION_GAIN
245  &Aura::HandleAuraModUseNormalSpeed, //191 SPELL_AURA_USE_NORMAL_MOVEMENT_SPEED
246  &Aura::HandleModMeleeRangedSpeedPct, //192 SPELL_AURA_HASTE_MELEE
247  &Aura::HandleModCombatSpeedPct, //193 SPELL_AURA_MELEE_SLOW (in fact combat (any type attack) speed pct)
248  &Aura::HandleUnused, //194 SPELL_AURA_MOD_DEPRICATED_1 not used now (old SPELL_AURA_MOD_SPELL_DAMAGE_OF_INTELLECT)
249  &Aura::HandleUnused, //195 SPELL_AURA_MOD_DEPRICATED_2 not used now (old SPELL_AURA_MOD_SPELL_HEALING_OF_INTELLECT)
250  &Aura::HandleNULL, //196 SPELL_AURA_MOD_COOLDOWN
251  &Aura::HandleNoImmediateEffect, //197 SPELL_AURA_MOD_ATTACKER_SPELL_AND_WEAPON_CRIT_CHANCE implemented in Unit::SpellCriticalBonus Unit::GetUnitCriticalChance
252  &Aura::HandleUnused, //198 SPELL_AURA_MOD_ALL_WEAPON_SKILLS
253  &Aura::HandleNoImmediateEffect, //199 SPELL_AURA_MOD_INCREASES_SPELL_PCT_TO_HIT implemented in Unit::MagicSpellHitResult
254  &Aura::HandleNoImmediateEffect, //200 SPELL_AURA_MOD_XP_PCT implemented in Player::GiveXP
255  &Aura::HandleAuraAllowFlight, //201 SPELL_AURA_FLY this aura enable flight mode...
256  &Aura::HandleNoImmediateEffect, //202 SPELL_AURA_CANNOT_BE_DODGED implemented in Unit::RollPhysicalOutcomeAgainst
257  &Aura::HandleNoImmediateEffect, //203 SPELL_AURA_MOD_ATTACKER_MELEE_CRIT_DAMAGE implemented in Unit::CalculateMeleeDamage and Unit::CalculateSpellDamage
258  &Aura::HandleNoImmediateEffect, //204 SPELL_AURA_MOD_ATTACKER_RANGED_CRIT_DAMAGE implemented in Unit::CalculateMeleeDamage and Unit::CalculateSpellDamage
259  &Aura::HandleNULL, //205 vulnerable to school dmg?
260  &Aura::HandleAuraModIncreaseFlightSpeed, //206 SPELL_AURA_MOD_FLIGHT_SPEED
261  &Aura::HandleAuraModIncreaseFlightSpeed, //207 SPELL_AURA_MOD_FLIGHT_SPEED_MOUNTED
262  &Aura::HandleAuraModIncreaseFlightSpeed, //208 SPELL_AURA_MOD_FLIGHT_SPEED_STACKING
263  &Aura::HandleAuraModIncreaseFlightSpeed, //209 SPELL_AURA_MOD_FLIGHT_SPEED_MOUNTED_STACKING
264  &Aura::HandleAuraModIncreaseFlightSpeed, //210 SPELL_AURA_MOD_FLIGHT_SPEED_NOT_STACKING
265  &Aura::HandleAuraModIncreaseFlightSpeed, //211 SPELL_AURA_MOD_FLIGHT_SPEED_MOUNTED_NOT_STACKING
266  &Aura::HandleAuraModRangedAttackPowerOfStatPercent, //212 SPELL_AURA_MOD_RANGED_ATTACK_POWER_OF_STAT_PERCENT
267  &Aura::HandleNoImmediateEffect, //213 SPELL_AURA_MOD_RAGE_FROM_DAMAGE_DEALT implemented in Player::RewardRage
268  &Aura::HandleNULL, //214 Tamed Pet Passive
269  &Aura::HandleArenaPreparation, //215 SPELL_AURA_ARENA_PREPARATION
270  &Aura::HandleModCastingSpeed, //216 SPELL_AURA_HASTE_SPELLS
271  &Aura::HandleUnused, //217 unused
272  &Aura::HandleAuraModRangedHaste, //218 SPELL_AURA_HASTE_RANGED
273  &Aura::HandleModManaRegen, //219 SPELL_AURA_MOD_MANA_REGEN_FROM_STAT
274  &Aura::HandleNULL, //220 SPELL_AURA_MOD_RATING_FROM_STAT
275  &Aura::HandleNULL, //221 ignored
276  &Aura::HandleUnused, //222 unused
277  &Aura::HandleNULL, //223 Cold Stare
278  &Aura::HandleUnused, //224 unused
279  &Aura::HandleNoImmediateEffect, //225 SPELL_AURA_PRAYER_OF_MENDING
280  &Aura::HandleAuraPeriodicDummy, //226 SPELL_AURA_PERIODIC_DUMMY
281  &Aura::HandlePeriodicTriggerSpellWithValue, //227 SPELL_AURA_PERIODIC_TRIGGER_SPELL_WITH_VALUE
282  &Aura::HandleNoImmediateEffect, //228 stealth detection
283  &Aura::HandleNULL, //229 SPELL_AURA_MOD_AOE_DAMAGE_AVOIDANCE
284  &Aura::HandleAuraModIncreaseMaxHealth, //230 Commanding Shout
285  &Aura::HandleNoImmediateEffect, //231 SPELL_AURA_PROC_TRIGGER_SPELL_WITH_VALUE
286  &Aura::HandleNoImmediateEffect, //232 SPELL_AURA_MECHANIC_DURATION_MOD implement in Unit::CalculateSpellDuration
287  &Aura::HandleNULL, //233 set model id to the one of the creature with id m_modifier.m_miscvalue
288  &Aura::HandleNoImmediateEffect, //234 SPELL_AURA_MECHANIC_DURATION_MOD_NOT_STACK implement in Unit::CalculateSpellDuration
289  &Aura::HandleAuraModDispelResist, //235 SPELL_AURA_MOD_DISPEL_RESIST implement in Unit::MagicSpellHitResult
290  &Aura::HandleUnused, //236 unused
291  &Aura::HandleModSpellDamagePercentFromAttackPower, //237 SPELL_AURA_MOD_SPELL_DAMAGE_OF_ATTACK_POWER implemented in Unit::SpellBaseDamageBonus
292  &Aura::HandleModSpellHealingPercentFromAttackPower, //238 SPELL_AURA_MOD_SPELL_HEALING_OF_ATTACK_POWER implemented in Unit::SpellBaseHealingBonus
293  &Aura::HandleAuraModScale, //239 SPELL_AURA_MOD_SCALE_2 only in Noggenfogger Elixir (16595) before 2.3.0 aura 61
294  &Aura::HandleAuraModExpertise, //240 SPELL_AURA_MOD_EXPERTISE
295  &Aura::HandleForceMoveForward, //241 Forces the player to move forward
296  &Aura::HandleUnused, //242 SPELL_AURA_MOD_SPELL_DAMAGE_FROM_HEALING
297  &Aura::HandleUnused, //243 used by two test spells
298  &Aura::HandleComprehendLanguage, //244 Comprehend language
299  &Aura::HandleUnused, //245 SPELL_AURA_MOD_DURATION_OF_MAGIC_EFFECTS
300  &Aura::HandleUnused, //246 unused
301  &Aura::HandleAuraCloneCaster, //247 SPELL_AURA_CLONE_CASTER
302  &Aura::HandleNoImmediateEffect, //248 SPELL_AURA_MOD_COMBAT_RESULT_CHANCE implemented in Unit::RollMeleeOutcomeAgainst
303  &Aura::HandleNULL, //249
304  &Aura::HandleAuraModIncreaseHealth, //250 SPELL_AURA_MOD_INCREASE_HEALTH_2
305  &Aura::HandleNULL, //251 SPELL_AURA_MOD_ENEMY_DODGE
306  &Aura::HandleNoImmediateEffect, //252 SPELL_AURA_REUSED_BLESSED_LIFE
307  &Aura::HandleIncreasePetOutdoorSpeed, //253 SPELL_INCREASE_PET_OUTDOOR_SPEED (used for bestial swiftness)
308  &Aura::HandleUnused, //254 unused
309  &Aura::HandleUnused, //255 unused
310  &Aura::HandleUnused, //256 unused
311  &Aura::HandleUnused, //257 unused
312  &Aura::HandleUnused, //258 unused
313  &Aura::HandleUnused, //259 unused
314  &Aura::HandleUnused, //260 unused
315  &Aura::HandlePhase //261 SPELL_AURA_261 some phased state (44856 spell)
316 };
317 
318 Aura::Aura(SpellEntry const* spellproto, uint32 eff, int32* currentBasePoints, Unit* target, Unit* caster, Item* castItem) :
319  m_procCharges(0), m_spellmod(NULL), m_effIndex(eff), m_caster_guid(0), m_target(target), m_tickNumber(0),
320  m_timeCla(1000), m_castItemGuid(castItem ? castItem->GetGUID() : 0), m_removeMode(AURA_REMOVE_BY_DEFAULT), m_auraSlot(MAX_AURAS),
321  m_positive(false), m_permanent(false), m_isPeriodic(false), m_isAreaAura(false),
322  m_isPersistent(false), m_isRemovedOnShapeLost(true), m_isRemoved(false), m_in_use(false),
323  m_periodicTimer(0), m_amplitude(0), m_PeriodicEventId(0), m_AuraDRGroup(DIMINISHING_NONE)
324  , m_stackAmount(1)
325 {
326  ASSERT(target);
327 
328  ASSERT(spellproto && spellproto == sSpellStore.LookupEntry(spellproto->Id) && "`info` must be pointer to sSpellStore element");
329 
330  m_spellProto = spellproto;
331 
332  int32 damage;
333  if (currentBasePoints)
334  {
335  damage = *currentBasePoints;
336  m_currentBasePoints = damage - 1;
337  }
338  else
339  {
340  m_currentBasePoints = m_spellProto->EffectBasePoints[eff];
341  if (caster)
342  damage = caster->CalculateSpellDamage(m_spellProto, m_effIndex, m_currentBasePoints, target);
343  else
344  damage = m_currentBasePoints + 1;
345  }
346 
349 
350  m_applyTime = time(NULL);
351 
353 
354  if (!caster)
355  {
356  m_caster_guid = target->GetGUID();
357  //damage = m_currentBasePoints+1; // stored value-1
358  m_maxduration = target->CalculateSpellDuration(m_spellProto, m_effIndex, target);
359  }
360  else
361  {
362  m_caster_guid = caster->GetGUID();
363 
364  //damage = caster->CalculateSpellDamage(m_spellProto,m_effIndex,m_currentBasePoints,target);
365  m_maxduration = caster->CalculateSpellDuration(m_spellProto, m_effIndex, target);
366 
367  if (!damage && castItem && castItem->GetItemSuffixFactor())
368  {
369  ItemRandomSuffixEntry const* item_rand_suffix = sItemRandomSuffixStore.LookupEntry(abs(castItem->GetItemRandomPropertyId()));
370  if (item_rand_suffix)
371  {
372  for (int k = 0; k < 3; k++)
373  {
374  SpellItemEnchantmentEntry const* pEnchant = sSpellItemEnchantmentStore.LookupEntry(item_rand_suffix->enchant_id[k]);
375  if (pEnchant)
376  {
377  for (int t = 0; t < 3; t++)
378  if (pEnchant->spellid[t] == m_spellProto->Id)
379  {
380  damage = uint32((item_rand_suffix->prefix[k] * castItem->GetItemSuffixFactor()) / 10000);
381  break;
382  }
383  }
384 
385  if (damage)
386  break;
387  }
388  }
389  }
390  }
391 
392  if (m_maxduration == -1 || (m_isPassive && m_spellProto->DurationIndex == 0))
393  m_permanent = true;
394 
395  Player* modOwner = caster ? caster->GetSpellModOwner() : NULL;
396 
397  if (!m_permanent && modOwner)
399 
401 
402  DEBUG_LOG("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);
403 
404  m_effIndex = eff;
405  SetModifier(AuraType(m_spellProto->EffectApplyAuraName[eff]), damage, m_spellProto->EffectAmplitude[eff], m_spellProto->EffectMiscValue[eff]);
406 
407  if (modOwner)
409 
410  // Start periodic on next tick or at aura apply
411  if (!(m_spellProto->AttributesEx5 & SPELL_ATTR5_START_PERIODIC_AT_APPLY))
413 
415 
416  if (m_spellProto->procCharges)
417  {
418  m_procCharges = m_spellProto->procCharges;
419 
420  if (modOwner)
422  }
423  else
424  m_procCharges = -1;
425 
427  if (IsChanneledSpell(m_spellProto) && caster)
428  caster->ModSpellDurationTime(m_spellProto, m_amplitude, NULL);
429 
430  m_isRemovedOnShapeLost = (m_caster_guid == m_target->GetGUID() && m_spellProto->Stances &&
431  !(m_spellProto->AttributesEx2 & 0x80000) && !(m_spellProto->Attributes & 0x10000));
432 
433  // WeakenedSoul Sweeping Strikes
434  if (GetId() == 6788 || GetId() == 12328)
435  m_isRemovedOnShapeLost = false;
436 }
437 
439 {
440 }
441 
442 AreaAura::AreaAura(SpellEntry const* spellproto, uint32 eff, int32* currentBasePoints, Unit* target,
443  Unit* caster, Item* castItem) : Aura(spellproto, eff, currentBasePoints, target, caster, castItem)
444 {
445  m_isAreaAura = true;
446 
447  // caster == NULL in constructor args if target == caster in fact
448  Unit* caster_ptr = caster ? caster : target;
449 
450  if (spellproto->Effect[eff] == SPELL_EFFECT_APPLY_AREA_AURA_ENEMY)
451  m_radius = GetSpellRadius(spellproto, m_effIndex, false);
452  else
453  m_radius = GetSpellRadius(spellproto, m_effIndex, true);
454 
455  if (Player* modOwner = caster_ptr->GetSpellModOwner())
456  modOwner->ApplySpellMod(GetId(), SPELLMOD_RADIUS, m_radius);
457 
458  switch (spellproto->Effect[eff])
459  {
462  if (target->GetTypeId() == TYPEID_UNIT && target->ToCreature()->IsTotem())
464  break;
467  break;
470  if (target == caster_ptr)
471  m_modifier.m_auraname = SPELL_AURA_NONE; // Do not do any effect on self
472  break;
475  break;
478  if (target == caster_ptr)
480  break;
481  default:
482  sLog.outError("Wrong spell effect in AreaAura constructor");
483  ASSERT(false);
484  break;
485  }
486 }
487 
489 {
490 }
491 
492 PersistentAreaAura::PersistentAreaAura(SpellEntry const* spellproto, uint32 eff, int32* currentBasePoints, Unit* target,
493  Unit* caster, Item* castItem) : Aura(spellproto, eff, currentBasePoints, target, caster, castItem)
494 {
495  m_isPersistent = true;
496 }
497 
499 {
500 }
501 
502 Aura* CreateAura(SpellEntry const* spellproto, uint32 eff, int32* currentBasePoints, Unit* target, Unit* caster, Item* castItem)
503 {
504  if (IsAreaAuraEffect(spellproto->Effect[eff]))
505  return new AreaAura(spellproto, eff, currentBasePoints, target, caster, castItem);
506 
507  return new Aura(spellproto, eff, currentBasePoints, target, caster, castItem);
508 }
509 
511 {
512  if (m_caster_guid == m_target->GetGUID())
513  return m_target;
514 
515  //return ObjectAccessor::GetUnit(*m_target,m_caster_guid);
516  //must return caster even if it's in another grid/map
518  return unit && unit->IsInWorld() ? unit : NULL;
519 }
520 
521 void Aura::SetModifier(AuraType t, int32 a, uint32 pt, int32 miscValue)
522 {
524  m_modifier.m_amount = a;
525  m_modifier.m_miscvalue = miscValue;
527 }
528 
530 {
531  if (m_duration > 0)
532  {
533  m_duration -= diff;
534  if (m_duration < 0)
535  m_duration = 0;
536  m_timeCla -= diff;
537 
538  // GetEffIndex() == 0 prevent double/triple apply manaPerSecond/manaPerSecondPerLevel to same spell with many auras
539  // all spells with manaPerSecond/manaPerSecondPerLevel have aura in effect 0
540  if (GetEffIndex() == 0 && m_timeCla <= 0)
541  {
542  if (Unit* caster = GetCaster())
543  {
544  Powers powertype = Powers(m_spellProto->powerType);
545  int32 manaPerSecond = m_spellProto->manaPerSecond + m_spellProto->manaPerSecondPerLevel * caster->getLevel();
547  if (manaPerSecond)
548  {
549  if (powertype == POWER_HEALTH)
550  caster->ModifyHealth(-manaPerSecond);
551  else
552  caster->ModifyPower(powertype, -manaPerSecond);
553  }
554  }
555  }
556  }
557 
558  // Channeled aura required check distance from caster except in possessed cases
560  sSpellStore.LookupEntry(GetSpellProto()->EffectTriggerSpell[m_effIndex]) &&
561  !IsAreaOfEffectSpell(sSpellStore.LookupEntry(GetSpellProto()->EffectTriggerSpell[m_effIndex])) &&
563 
564  if (IsChanneledSpell(m_spellProto) && !pRealTarget->isPossessed() && pRealTarget->GetGUID() != GetCasterGUID())
565  {
566  Unit* caster = GetCaster();
567  if (!caster)
568  {
570  return;
571  }
572 
573  // Get spell range
574  float radius;
575  SpellModOp mod;
577  {
578  radius = GetSpellRadius(m_spellProto, GetEffIndex(), false);
579  mod = SPELLMOD_RADIUS;
580  }
581  else
582  {
584  mod = SPELLMOD_RANGE;
585  }
586 
587  if (Player* modOwner = caster->GetSpellModOwner())
588  modOwner->ApplySpellMod(GetId(), mod, radius, NULL);
589 
590  if (!caster->IsWithinDistInMap(pRealTarget, radius))
591  return;
592  }
593 
594  if (m_isPeriodic && (m_duration >= 0 || m_isPassive || m_permanent))
595  {
596  m_periodicTimer -= diff;
597  if (m_periodicTimer <= 0) // tick also at m_periodicTimer == 0 to prevent lost last tick in case max m_duration == (max m_periodicTimer)*N
598  {
599  ++m_tickNumber;
600 
603  // Cannibalize, eating items and other spells
605  // Eating items and other spells
607  {
608  ApplyModifier(true);
609  return;
610  }
611  // update before applying (aura can be removed in TriggerSpell or PeriodicTick calls)
612  m_periodicTimer += m_amplitude;//m_modifier.periodictime;
613 
615  PeriodicTick();
616  }
617  }
618 }
619 
621 {
622  if (target->HasAura(GetId(), m_effIndex))
623  return false;
624 
625  // Skip some targets (TODO: Might require better checks, also unclear how the actual caster must/can be handled)
627  return false;
628 
629  // some special cases
630  switch (GetId())
631  {
632  case 45828: // AV Marshal's HP/DMG auras
633  case 45829:
634  case 45831:
635  case 45830:
636  case 45822: // AV Warmaster's HP/DMG auras
637  case 45823:
638  case 45824:
639  case 45826:
640  {
641  switch (target->GetEntry())
642  {
643  // alliance
644  case 14762: // Dun Baldar North Marshal
645  case 14763: // Dun Baldar South Marshal
646  case 14764: // Icewing Marshal
647  case 14765: // Stonehearth Marshal
648  case 11948: // Vandar Stormspike
649  // horde
650  case 14772: // East Frostwolf Warmaster
651  case 14776: // Tower Point Warmaster
652  case 14773: // Iceblood Warmaster
653  case 14777: // West Frostwolf Warmaster
654  case 11946: // Drek'thar
655  return true;
656  default:
657  break;
658  }
659  return false;
660  }
661  break;
662  default:
663  break;
664  }
665  return true;
666 }
667 
669 {
670  // update for the caster of the aura
671  if (m_caster_guid == m_target->GetGUID())
672  {
673  Unit* caster = m_target;
674 
675  if (!caster->HasUnitState(UNIT_STATE_ISOLATED))
676  {
677  std::list<Unit* > targets;
678 
679  switch (m_areaAuraType)
680  {
681  case AREA_AURA_PARTY:
682  caster->GetPartyMember(targets, m_radius);
683  break;
684  case AREA_AURA_FRIEND:
685  {
686  Oregon::AnyFriendlyUnitInObjectRangeCheck u_check(caster, caster, m_radius);
688  caster->VisitNearbyObject(m_radius, searcher);
689  break;
690  }
691  case AREA_AURA_ENEMY:
692  {
693  Oregon::AnyAoETargetUnitInObjectRangeCheck u_check(caster, caster, m_radius); // No GetCharmer in searcher
695  caster->VisitNearbyObject(m_radius, searcher);
696  break;
697  }
698  case AREA_AURA_OWNER:
699  case AREA_AURA_PET:
700  {
701  if (Unit* owner = caster->GetCharmerOrOwner())
702  targets.push_back(owner);
703  break;
704  }
705  }
706 
707  for (std::list<Unit* >::iterator tIter = targets.begin(); tIter != targets.end(); tIter++)
708  {
709  if (!CheckTarget(*tIter))
710  continue;
711 
712  if (SpellEntry const* actualSpellInfo = sSpellMgr.SelectAuraRankForPlayerLevel(GetSpellProto(), (*tIter)->getLevel()))
713  {
714  //int32 actualBasePoints = m_currentBasePoints;
715  // recalculate basepoints for lower rank (all AreaAura spell not use custom basepoints?)
716  //if (actualSpellInfo != GetSpellProto())
717  // actualBasePoints = actualSpellInfo->EffectBasePoints[m_effIndex];
718  AreaAura* aur;
719  if (actualSpellInfo == GetSpellProto())
720  aur = new AreaAura(actualSpellInfo, m_effIndex, &m_modifier.m_amount, (*tIter), caster, NULL);
721  else
722  aur = new AreaAura(actualSpellInfo, m_effIndex, NULL, (*tIter), caster, NULL);
723  (*tIter)->AddAura(aur);
724 
725  if (m_areaAuraType == AREA_AURA_ENEMY)
726  caster->CombatStart(*tIter);
727  }
728  }
729  }
730  Aura::Update(diff);
731  }
732  else // aura at non-caster
733  {
734  Unit* tmp_target = m_target;
735  Unit* caster = GetCaster();
736  uint32 tmp_spellId = GetId(), tmp_effIndex = m_effIndex;
737 
738  // WARNING: the aura may get deleted during the update
739  // DO NOT access its members after update!
740  Aura::Update(diff);
741 
742  // remove aura if out-of-range from caster (after teleport for example)
743  // or caster is isolated or caster no longer has the aura
744  // or caster is (no longer) friendly
745  bool needFriendly = (m_areaAuraType == AREA_AURA_ENEMY ? false : true);
746  if (!caster || caster->HasUnitState(UNIT_STATE_ISOLATED) ||
747  !caster->IsWithinDistInMap(tmp_target, m_radius) ||
748  !caster->HasAura(tmp_spellId, tmp_effIndex) ||
749  caster->IsFriendlyTo(tmp_target) != needFriendly
750  )
751  tmp_target->RemoveAura(tmp_spellId, tmp_effIndex);
752  else if (m_areaAuraType == AREA_AURA_PARTY) // check if in same sub group
753  {
754  if (!tmp_target->IsInPartyWith(caster))
755  tmp_target->RemoveAura(tmp_spellId, tmp_effIndex);
756  }
757  else if (m_areaAuraType == AREA_AURA_PET || m_areaAuraType == AREA_AURA_OWNER)
758  {
759  if (tmp_target->GetGUID() != caster->GetCharmerOrOwnerGUID())
760  tmp_target->RemoveAura(tmp_spellId, tmp_effIndex);
761  }
762  }
763 }
764 
766 {
767  bool remove = false;
768 
769  // remove the aura if its caster or the dynamic object causing it was removed
770  // or if the target moves too far from the dynamic object
771  Unit* caster = GetCaster();
772  if (caster)
773  {
774  DynamicObject* dynObj = caster->GetDynObject(GetId(), GetEffIndex());
775  if (dynObj)
776  {
777  if (!m_target->IsWithinDistInMap(dynObj, dynObj->GetRadius()))
778  remove = true;
779  }
780  else
781  remove = true;
782  }
783  else
784  remove = true;
785 
786  Unit* tmp_target = m_target;
787  uint32 tmp_id = GetId(), tmp_index = GetEffIndex();
788 
789  // WARNING: the aura may get deleted during the update
790  // DO NOT access its members after update!
791  Aura::Update(diff);
792 
793  if (remove)
794  tmp_target->RemoveAura(tmp_id, tmp_index);
795 }
796 
797 void Aura::ApplyModifier(bool apply, bool Real)
798 {
799  if (IsRemoved())
800  return;
801 
803 
804  m_in_use = true;
805  if (aura < TOTAL_AURAS)
806  (*this.*AuraHandler [aura])(apply, Real);
807  m_in_use = false;
808 }
809 
811 {
812  if (m_auraSlot >= MAX_AURAS || m_isPassive)
813  return;
814 
815  if (m_target->GetTypeId() == TYPEID_PLAYER)
816  {
818  data << (uint8)m_auraSlot << (uint32)m_duration;
820 
821  data.Initialize(SMSG_SET_EXTRA_AURA_INFO, (8 + 1 + 4 + 4 + 4));
822  data << m_target->GetPackGUID();
823  data << uint8(m_auraSlot);
824  data << uint32(GetId());
825  data << uint32(GetAuraMaxDuration());
826  data << uint32(GetAuraDuration());
828  }
829 
830  // not send in case player loading (will not work anyway until player not added to map), sent in visibility change code
832  return;
833 
834  Unit* caster = GetCaster();
835 
836  if (caster && caster->GetTypeId() == TYPEID_PLAYER)
837  {
839 
840  Group* CasterGroup = caster->ToPlayer()->GetGroup();
841  if (CasterGroup && (sSpellMgr.GetSpellCustomAttr(GetId()) & SPELL_ATTR_CU_AURA_CC))
842  {
843  for (GroupReference* itr = CasterGroup->GetFirstMember(); itr != NULL; itr = itr->next())
844  {
845  Player* player = itr->GetSource();
846  if (player && player != caster)
848  }
849  }
850  }
851 }
852 
854 {
855  if (caster == m_target)
856  return;
857 
858  WorldPacket data(SMSG_SET_EXTRA_AURA_INFO_NEED_UPDATE, (8 + 1 + 4 + 4 + 4));
859  data << m_target->GetPackGUID();
860  data << uint8(m_auraSlot);
861  data << uint32(GetId());
862  data << uint32(GetAuraMaxDuration()); // full
863  data << uint32(GetAuraDuration()); // remain
864  caster->GetSession()->SendPacket(&data);
865 }
866 
868 {
869  if (!GetId())
870  return;
871  if (!m_target)
872  return;
873 
874  // we can found aura in NULL_AURA_SLOT and then need store state instead check slot != NULL_AURA_SLOT
875  bool secondaura = false;
876  uint8 slot = NULL_AURA_SLOT;
877 
878  for (uint8 i = 0; i < 3; i++)
879  {
881  for (Unit::AuraMap::const_iterator itr = m_target->GetAuras().lower_bound(spair); itr != m_target->GetAuras().upper_bound(spair); ++itr)
882  {
883  // allow use single slot only by auras from same caster and item
884  if (itr->second->GetCasterGUID() == GetCasterGUID() && itr->second->GetCastItemGUID() == GetCastItemGUID())
885  {
886  secondaura = true;
887  slot = itr->second->GetAuraSlot();
888  break;
889  }
890  }
891 
892  if (secondaura)
893  break;
894  }
895 
896  Unit* caster = GetCaster();
897 
898  // not call total regen auras at adding
899  switch (m_modifier.m_auraname)
900  {
903  m_periodicTimer = m_amplitude;//m_modifier.periodictime;
904  break;
908  m_amplitude = 5000;
910  break;
911  default:
912  break;
913  }
914 
915  // register aura
918 
919  // Show the buff (if any) on the target
922  {
923  if (!secondaura) // new slot need
924  {
925  if (IsPositive()) // empty positive slot
926  {
927  for (uint8 i = 0; i < MAX_POSITIVE_AURAS; i++)
928  {
929  if (m_target->GetUInt32Value((uint16)(UNIT_FIELD_AURA + i)) == 0)
930  {
931  slot = i;
932  break;
933  }
934  }
935  }
936  else // empty negative slot
937  {
938  for (uint8 i = MAX_POSITIVE_AURAS; i < MAX_AURAS; i++)
939  {
940  if (m_target->GetUInt32Value((uint16)(UNIT_FIELD_AURA + i)) == 0)
941  {
942  slot = i;
943  break;
944  }
945  }
946  }
947 
948  SetAuraSlot(slot);
949 
950  // Not update fields for not first spell's aura, all data already in fields
951  if (slot < MAX_AURAS) // slot found
952  {
953  SetAura(slot, false);
954  SetAuraFlag(slot, true);
955  SetAuraLevel(slot, caster ? caster->getLevel() : sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL));
957 
958  // update for out of range group members
960  }
961  }
962  else // use found slot
963  SetAuraSlot(slot);
964 
966 
967  // Update Seals information
968  if (IsSealSpell(GetSpellProto()))
970 
971  // Conflagrate aura state
972  if (GetSpellProto()->SpellFamilyName == SPELLFAMILY_WARLOCK && (GetSpellProto()->SpellFamilyFlags & 4))
974 
975  if (GetSpellProto()->SpellFamilyName == SPELLFAMILY_DRUID
976  && (GetSpellProto()->SpellFamilyFlags == 0x40 || GetSpellProto()->SpellFamilyFlags == 0x10))
978  }
979 }
980 
982 {
983  Unit* caster = GetCaster();
984 
985  if (caster && IsPersistent())
986  {
987  DynamicObject* dynObj = caster->GetDynObject(GetId(), GetEffIndex());
988  if (dynObj)
989  dynObj->RemoveAffected(m_target);
990  }
991 
992  // unregister aura
995 
996  //passive auras do not get put in slots
997  // Note: but totem can be not accessible for aura target in time remove (to far for find in grid)
998  //if (m_isPassive && !(caster && caster->GetTypeId() == TYPEID_UNIT && caster->ToCreature()->IsTotem()))
999  // return;
1000 
1001  uint8 slot = GetAuraSlot();
1002 
1003  if (slot >= MAX_AURAS) // slot not set
1004  return;
1005 
1006  if (m_target->GetUInt32Value((uint16)(UNIT_FIELD_AURA + slot)) == 0)
1007  return;
1008 
1009  bool samespell = false;
1010 
1011  // find other aura in same slot (current already removed from list)
1012  for (uint8 i = 0; i < 3; i++)
1013  {
1015  for (Unit::AuraMap::const_iterator itr = m_target->GetAuras().lower_bound(spair); itr != m_target->GetAuras().upper_bound(spair); ++itr)
1016  {
1017  if (itr->second->GetAuraSlot() == slot)
1018  {
1019  samespell = true;
1020  break;
1021  }
1022  }
1023  if (samespell)
1024  break;
1025  }
1026 
1027  // only remove icon when the last aura of the spell is removed (current aura already removed from list)
1028  if (!samespell)
1029  {
1030  SetAura(slot, true);
1031  SetAuraFlag(slot, false);
1032  SetAuraLevel(slot, caster ? caster->getLevel() : sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL));
1033 
1034  SetAuraApplication(slot, 0);
1035  // update for out of range group members
1037 
1038  if (IsSealSpell(GetSpellProto()))
1040 
1041  // Conflagrate aura state
1042  if (GetSpellProto()->SpellFamilyName == SPELLFAMILY_WARLOCK && (GetSpellProto()->SpellFamilyFlags & 4))
1044 
1045  // Swiftmend aura state
1046  if (GetSpellProto()->SpellFamilyName == SPELLFAMILY_DRUID
1047  && (GetSpellProto()->SpellFamilyFlags == 0x40 || GetSpellProto()->SpellFamilyFlags == 0x10))
1048  {
1049  bool found = false;
1051  for (Unit::AuraList::const_iterator i = RejorRegr.begin(); i != RejorRegr.end(); ++i)
1052  {
1053  if ((*i)->GetSpellProto()->SpellFamilyName == SPELLFAMILY_DRUID
1054  && ((*i)->GetSpellProto()->SpellFamilyFlags == 0x40 || (*i)->GetSpellProto()->SpellFamilyFlags == 0x10))
1055  {
1056  found = true;
1057  break;
1058  }
1059  }
1060  if (!found)
1062  }
1063 
1064  // reset cooldown state for spells
1065  if (caster && caster->GetTypeId() == TYPEID_PLAYER)
1066  {
1069  }
1070  }
1071  m_isRemoved = true;
1072 }
1073 
1074 void Aura::SetAuraFlag(uint32 slot, bool add)
1075 {
1076  uint32 index = slot / 4;
1077  uint32 byte = (slot % 4) * 8;
1079  val &= ~((uint32)AFLAG_MASK << byte);
1080  if (add)
1081  {
1082  if (IsPositive())
1083  val |= ((uint32)AFLAG_POSITIVE << byte);
1084  else
1085  val |= ((uint32)AFLAG_NEGATIVE << byte);
1086  }
1088 }
1089 
1091 {
1092  uint32 index = slot / 4;
1093  uint32 byte = (slot % 4) * 8;
1095  val &= ~(0xFF << byte);
1096  val |= (level << byte);
1098 }
1099 
1101 {
1102  uint32 index = slot / 4;
1103  uint32 byte = (slot % 4) * 8;
1105  val &= ~(0xFF << byte);
1106  val |= ((uint8(count)) << byte);
1108 }
1109 
1111 {
1112  uint8 slot = GetAuraSlot();
1113  if (slot >= MAX_AURAS)
1114  return;
1115 
1116  // Three possibilities:
1117  // Charge = 0; Stack >= 0
1118  // Charge = 1; Stack >= 0
1119  // Charge > 1; Stack = 0
1120  if (m_procCharges < 2)
1121  SetAuraApplication(slot, m_stackAmount - 1);
1122 
1124 }
1125 
1126 /*********************************************************/
1127 /*** BASIC AURA FUNCTION ***/
1128 /*********************************************************/
1129 void Aura::HandleAddModifier(bool apply, bool Real)
1130 {
1131  if (m_target->GetTypeId() != TYPEID_PLAYER || !Real)
1132  return;
1133 
1134  SpellEntry const* spellInfo = GetSpellProto();
1135  if (!spellInfo)
1136  return;
1137 
1139  return;
1140 
1141  if (apply)
1142  {
1143  // Add custom charges for some mod aura
1144  switch (m_spellProto->Id)
1145  {
1146  case 17941: // Shadow Trance
1147  case 22008: // Netherwind Focus
1148  case 34754: // Clearcasting
1149  case 34936: // Backlash
1150 
1151  m_procCharges = 1;
1152  break;
1153  }
1154 
1155  SpellModifier* mod = new SpellModifier;
1157  mod->value = GetModifierValue();
1158  mod->type = SpellModType(m_modifier.m_auraname); // SpellModType value == spell aura types
1159  mod->spellId = GetId();
1160  mod->effectId = m_effIndex;
1161  mod->lastAffected = NULL;
1162 
1163  uint64 spellAffectMask = sSpellMgr.GetSpellAffectMask(GetId(), m_effIndex);
1164 
1165  if (spellAffectMask)
1166  mod->mask = spellAffectMask;
1167  else
1168  mod->mask = spellInfo->EffectItemType[m_effIndex];
1169 
1170  if (m_procCharges > 0)
1171  mod->charges = m_procCharges;
1172  else
1173  mod->charges = 0;
1174 
1175  m_spellmod = mod;
1176  }
1177 
1178  uint64 spellFamilyMask = m_spellmod->mask;
1179 
1181 
1182  // reapply some passive spells after add/remove related spellmods
1183  if (spellInfo->SpellFamilyName == SPELLFAMILY_WARRIOR && (spellFamilyMask & 0x0000100000000000LL))
1184  {
1186 
1187  if (apply)
1188  m_target->CastSpell(m_target, 45471, true);
1189  }
1190 
1191  if (spellInfo->SpellFamilyName == SPELLFAMILY_PALADIN && (spellFamilyMask & 0x0000100000000000LL)) // Spiritual Attunement
1192  {
1193  if (m_target->HasAura(31785, 0)) // rank 1
1194  {
1196  m_target->CastSpell(m_target, 31785, true);
1197  }
1198  if (m_target->HasAura(33776, 0)) // rank 2
1199  {
1201  m_target->CastSpell(m_target, 33776, true);
1202  }
1203  }
1204 }
1205 
1207 {
1208  Unit* caster = GetCaster();
1209  Unit* target = GetTriggerTarget();
1210 
1211  if (!caster || !target)
1212  return;
1213 
1214  // generic casting code with custom spells and target/caster customs
1215  uint32 trigger_spell_id = GetSpellProto()->EffectTriggerSpell[m_effIndex];
1216 
1217  uint64 originalCasterGUID = GetCasterGUID();
1218 
1219  SpellEntry const* triggeredSpellInfo = sSpellStore.LookupEntry(trigger_spell_id);
1220  SpellEntry const* auraSpellInfo = GetSpellProto();
1221  uint32 auraId = auraSpellInfo->Id;
1222 
1223  // specific code for cases with no trigger spell provided in field
1224  if (triggeredSpellInfo == NULL)
1225  {
1226  switch (auraSpellInfo->SpellFamilyName)
1227  {
1228  case SPELLFAMILY_GENERIC:
1229  {
1230  switch (auraId)
1231  {
1232  // Firestone Passive (1-5 ranks)
1233  case 758:
1234  case 17945:
1235  case 17947:
1236  case 17949:
1237  case 27252:
1238  {
1239  if (caster->GetTypeId() != TYPEID_PLAYER)
1240  return;
1241  Item* item = caster->ToPlayer()->GetWeaponForAttack(BASE_ATTACK);
1242  if (!item)
1243  return;
1244  uint32 enchant_id = 0;
1245  switch (GetId())
1246  {
1247  case 758:
1248  enchant_id = 1803;
1249  break; // Rank 1
1250  case 17945:
1251  enchant_id = 1823;
1252  break; // Rank 2
1253  case 17947:
1254  enchant_id = 1824;
1255  break; // Rank 3
1256  case 17949:
1257  enchant_id = 1825;
1258  break; // Rank 4
1259  case 27252:
1260  enchant_id = 2645;
1261  break; // Rank 5
1262  default:
1263  return;
1264  }
1265  // remove old enchanting before applying new
1266  caster->ToPlayer()->ApplyEnchantment(item, TEMP_ENCHANTMENT_SLOT, false);
1267  item->SetEnchantment(TEMP_ENCHANTMENT_SLOT, enchant_id, m_modifier.periodictime + 1000, 0);
1268  // add new enchanting
1269  caster->ToPlayer()->ApplyEnchantment(item, TEMP_ENCHANTMENT_SLOT, true);
1270  return;
1271  }
1272  // // Periodic Mana Burn
1273  // case 812: break;
1274  // // Polymorphic Ray
1275  // case 6965: break;
1276  // // Fire Nova (1-7 ranks)
1277  // case 8350:
1278  // case 8508:
1279  // case 8509:
1280  // case 11312:
1281  // case 11313:
1282  // case 25540:
1283  // case 25544:
1284  // break;
1285  // Thaumaturgy Channel
1286  //dont work, used db support (see on spell_linked_spell)
1287  case 9712:
1288  trigger_spell_id = 21029;
1289  break;
1290  // // Egan's Blaster
1291  // case 17368: break;
1292  // // Haunted
1293  // case 18347: break;
1294  // // Ranshalla Waiting
1295  // case 18953: break;
1296  // // Inferno
1297  // case 19695: break;
1298  // // Frostwolf Muzzle DND
1299  // case 21794: break;
1300  // // Alterac Ram Collar DND
1301  // case 21866: break;
1302  // // Celebras Waiting
1303  // case 21916: break;
1304  // Brood Affliction: Bronze
1305  case 23170:
1306  {
1307  m_target->CastSpell(m_target, 23171, true, 0, this);
1308  return;
1309  }
1310  // // Mark of Frost
1311  // case 23184: break;
1312  // Restoration
1313  case 23493:
1314  {
1315  int32 heal = caster->GetMaxHealth() / 10;
1316  caster->ModifyHealth(heal);
1317  caster->SendHealSpellLog(caster, 23493, heal);
1318 
1319  if (int32 mana = caster->GetMaxPower(POWER_MANA))
1320  {
1321  mana /= 10;
1322  caster->EnergizeBySpell(caster, 23493, mana, POWER_MANA);
1323  }
1324  break;
1325  }
1326  // // Stoneclaw Totem Passive TEST
1327  // case 23792: break;
1328  // // Axe Flurry
1329  // case 24018: break;
1330  // // Mark of Arlokk
1331  // case 24210: break;
1332  // // Restoration
1333  // case 24379: break;
1334  // // Happy Pet
1335  // case 24716: break;
1336  // // Dream Fog
1337  // case 24780: break;
1338  // // Cannon Prep
1339  // case 24832: break;
1340  // // Shadow Bolt Whirl
1341  case 24834:
1342  {
1343  uint32 spellForTick[8] = { 24820, 24821, 24822, 24823, 24835, 24836, 24837, 24838 };
1345  if (totalTick < 8)
1346  {
1347  trigger_spell_id = spellForTick[totalTick];
1348 
1349  // casted in left/right (but triggered spell have wide forward cone)
1350  float forward = m_target->GetOrientation();
1351  float angle = m_target->GetOrientation() + ( totalTick % 2 == 0 ? M_PI / 2 : - M_PI / 2);
1352  m_target->SetOrientation(angle);
1353  target->CastSpell(target, trigger_spell_id, true, NULL, this);
1354  m_target->SetOrientation(forward);
1355  }
1356  return;
1357  }
1358  // // Stink Trap
1359  // case 24918: break;
1360  // // Mark of Nature
1361  // case 25041: break;
1362  // // Agro Drones
1363  // case 25152: break;
1364  // // Consume
1365  // case 25371: break;
1366  // // Pain Spike
1367  // case 25572: break;
1368  // // Rotate 360
1369  // case 26009: break;
1370  // // Rotate -360
1371  // case 26136: break;
1372  // // Consume
1373  // case 26196: break;
1374  // // Berserk
1375  // case 26615: break;
1376  // // Defile
1377  // case 27177: break;
1378  // // Teleport: IF/UC
1379  // case 27601: break;
1380  // // Five Fat Finger Exploding Heart Technique
1381  // case 27673: break;
1382  // Nitrous Boost
1383  case 27746:
1384  {
1385  if (caster->GetPower(POWER_MANA) >= 10)
1386  caster->EnergizeBySpell(caster, 27746, -10, POWER_MANA);
1387  else
1388  {
1389  caster->RemoveAurasDueToSpell(27746);
1390  return;
1391  }
1392  }
1393  break;
1394  // // Steam Tank Passive
1395  // case 27747: break;
1396  // // Frost Blast
1397  // case 27808: break;
1398  // // Detonate Mana
1399  // case 27819: break;
1400  // // Controller Timer
1401  // case 28095: break;
1402  // // Stalagg Chain
1403  // case 28096: break;
1404  // // Stalagg Tesla Passive
1405  // case 28097: break;
1406  // // Feugen Tesla Passive
1407  // case 28109: break;
1408  // // Feugen Chain
1409  // case 28111: break;
1410  // // Mark of Didier
1411  // case 28114: break;
1412  // // Communique Timer, camp
1413  // case 28346: break;
1414  // // Icebolt
1415  // case 28522: break;
1416  // // Silithyst
1417  // case 29519: break;
1418  // // Inoculate Nestlewood Owlkin
1419  case 29528:
1420  trigger_spell_id = 28713;
1421  break;
1422  // // Overload
1423  case 29768:
1424  {
1425  int32 BasePoints = int32(GetModifier()->m_amount);
1426  m_target->CastCustomSpell(m_target, 29766, &BasePoints, NULL, NULL, true, NULL, this);
1427  return;
1428  }
1429  // // Return Fire
1430  // case 29788: break;
1431  // // Return Fire
1432  // case 29793: break;
1433  // // Return Fire
1434  // case 29794: break;
1435  // // Guardian of Icecrown Passive
1436  // case 29897: break;
1437  // Feed Captured Animal
1438  case 29917:
1439  trigger_spell_id = 29916;
1440  break;
1441  // // Flame Wreath
1442  // case 29946: break;
1443  // // Flame Wreath
1444  // case 29947: break;
1445  // // Mind Exhaustion Passive
1446  // case 30025: break;
1447  // // Nether Beam - Serenity
1448  // case 30401: break;
1449  // Extract Gas
1450  case 30427:
1451  {
1452  // move loot to player inventory and despawn target
1453  if (caster->GetTypeId() == TYPEID_PLAYER &&
1454  target->GetTypeId() == TYPEID_UNIT &&
1456  {
1457  Player* player = caster->ToPlayer();
1458  Creature* creature = target->ToCreature();
1459  // missing lootid has been reported on startup - just return
1460  if (!creature->GetCreatureTemplate()->SkinLootId)
1461  return;
1462  Loot* loot = &creature->loot;
1463  loot->clear();
1464  loot->FillLoot(creature->GetCreatureTemplate()->SkinLootId, LootTemplates_Skinning, player, true);
1465  for (uint8 i = 0; i < loot->items.size(); i++)
1466  {
1467  LootItem* item = loot->LootItemInSlot(i, player);
1468  ItemPosCountVec dest;
1469  uint8 msg = player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, item->itemid, item->count);
1470  if (msg == EQUIP_ERR_OK)
1471  {
1472  Item* newitem = player->StoreNewItem(dest, item->itemid, true, item->randomPropertyId);
1473 
1474  player->SendNewItem(newitem, uint32(item->count), false, false, true);
1475  }
1476  else
1477  player->SendEquipError(msg, NULL, NULL);
1478  }
1479  creature->ForcedDespawn();
1480  }
1481  return;
1482  break;
1483  }
1484  // Quake
1485  case 30576:
1486  trigger_spell_id = 30571;
1487  break;
1488  // // Burning Maul
1489  // case 30598: break;
1490  // // Regeneration
1491  // case 30799:
1492  // case 30800:
1493  // case 30801:
1494  // break;
1495  // // Despawn Self - Smoke cloud
1496  // case 31269: break;
1497  // // Time Rift Periodic
1498  // case 31320: break;
1499  // // Corrupt Medivh
1500  // case 31326: break;
1501  // Doom
1502  case 31347:
1503  {
1504  m_target->CastSpell(m_target, 31350, true);
1506  return;
1507  }
1508  // Spellcloth
1509  case 31373:
1510  {
1511  // Summon Elemental after create item
1512  caster->SummonCreature(17870, 0, 0, 0, caster->GetOrientation(), TEMPSUMMON_DEAD_DESPAWN, 0);
1513  return;
1514  }
1515  // // Bloodmyst Tesla
1516  // case 31611: break;
1517  // Doomfire dot
1518  case 31944:
1519  {
1520  int32 BasePoints = int32(GetModifier()->m_amount);
1521  m_target->CastCustomSpell( m_target, 31969, &BasePoints, NULL, NULL, true, NULL, this, m_target->GetGUID() ); /* X */
1522 
1523  ApplyModifier(false);
1524  GetModifier()->m_amount -= 150;
1525  ApplyModifier(true);
1526  return;
1527  }
1528  // // Teleport Test
1529  // case 32236: break;
1530  // // Earthquake
1531  // case 32686: break;
1532  // // Possess
1533  // case 33401: break;
1534  // // Draw Shadows
1535  // case 33563: break;
1536  // // Murmur's Touch
1537  // case 33711: break;
1538  // Flame Quills
1539  case 34229:
1540  {
1541  // cast 24 spells 34269-34289, 34314-34316
1542  for (uint32 spell_id = 34269; spell_id != 34290; ++spell_id)
1543  caster->CastSpell(m_target, spell_id, true);
1544  for (uint32 spell_id = 34314; spell_id != 34317; ++spell_id)
1545  caster->CastSpell(m_target, spell_id, true);
1546  return;
1547  }
1548  // // Gravity Lapse
1549  // case 34480: break;
1550  // // Tornado
1551  // case 34683: break;
1552  // // Frostbite Rotate
1553  // case 34748: break;
1554  // // Arcane Flurry
1555  // case 34821: break;
1556  // // Interrupt Shutdown
1557  // case 35016: break;
1558  // // Interrupt Shutdown
1559  // case 35176: break;
1560  // // Inferno
1561  // case 35268: break;
1562  // // Salaadin's Tesla
1563  // case 35515: break;
1564  // // Ethereal Channel (Red)
1565  // case 35518: break;
1566  // // Nether Vapor
1567  // case 35879: break;
1568  // // Dark Portal Storm
1569  // case 36018: break;
1570  // // Burning Maul
1571  // case 36056: break;
1572  // // Living Grove Defender Lifespan
1573  // case 36061: break;
1574  // // Professor Dabiri Talks
1575  // case 36064: break;
1576  // // Kael Gaining Power
1577  // case 36091: break;
1578  // // They Must Burn Bomb Aura
1579  // case 36344: break;
1580  // // They Must Burn Bomb Aura (self)
1581  // case 36350: break;
1582  // // Stolen Ravenous Ravager Egg
1583  // case 36401: break;
1584  // // Activated Cannon
1585  // case 36410: break;
1586  // // Stolen Ravenous Ravager Egg
1587  // case 36418: break;
1588  // // Enchanted Weapons
1589  // case 36510: break;
1590  // // Cursed Scarab Periodic
1591  // case 36556: break;
1592  // // Cursed Scarab Despawn Periodic
1593  // case 36561: break;
1594  // // Vision Guide
1595  // case 36573: break;
1596  // // Cannon Charging (platform)
1597  // case 36785: break;
1598  // // Cannon Charging (self)
1599  // case 36860: break;
1600  // Remote Toy
1601  case 37027:
1602  trigger_spell_id = 37029;
1603  break;
1604  // // Mark of Death
1605  // case 37125: break;
1606  // // Arcane Flurry
1607  // case 37268: break;
1608  // // Spout
1609  // case 37429: break;
1610  // // Spout
1611  // case 37430: break;
1612  // // Karazhan - Chess NPC AI, Snapshot timer
1613  // case 37440: break;
1614  // // Karazhan - Chess NPC AI, action timer
1615  // case 37504: break;
1616  // // Karazhan - Chess: Is Square OCCUPIED aura (DND)
1617  // case 39400: break;
1618  // // Banish
1619  // case 37546: break;
1620  // // Shriveling Gaze
1621  // case 37589: break;
1622  // // Fake Aggro Radius (2 yd)
1623  // case 37815: break;
1624  // // Corrupt Medivh
1625  // case 37853: break;
1626  // Eye of Grillok
1627  case 38495:
1628  {
1629  if (m_target->FindNearestCreature(22177, 10.0f, true))
1630  {
1631  if (caster->GetTypeId() == TYPEID_PLAYER)
1632  {
1633  Creature* bunny = caster->FindNearestCreature(22177, 10.0f, true);
1634  caster->CastSpell(bunny, 38530, true);
1635  caster->RemoveAura(38495, 0);
1636  }
1637  }
1638  return;
1639  }
1640  // Absorb Eye of Grillok (Zezzak's Shard)
1641  case 38554:
1642  {
1643  if (m_target->GetTypeId() != TYPEID_UNIT)
1644  return;
1645 
1646  caster->CastSpell(caster, 38495, true);
1647 
1648  Creature* creatureTarget = m_target->ToCreature();
1649 
1650  creatureTarget->ForcedDespawn();
1651  return;
1652  }
1653  // // Magic Sucker Device timer
1654  // case 38672: break;
1655  // // Tomb Guarding Charging
1656  // case 38751: break;
1657  // // Murmur's Touch
1658  // case 38794: break;
1659  // // Activate Nether-wraith Beacon (31742 Nether-wraith Beacon item)
1660  // case 39105: break;
1661  // // Drain World Tree Visual
1662  // case 39140: break;
1663  // // Quest - Dustin's Undead Dragon Visual aura
1664  // case 39259: break;
1665  // // Hellfire - The Exorcism, Jules releases darkness, aura
1666  // case 39306: break;
1667  // // Inferno
1668  case 39346:
1669  {
1670  int32 BasePoints = int32(GetModifier()->m_amount);
1671  m_target->CastCustomSpell(m_target, 35283, &BasePoints, NULL, NULL, true, NULL, this);
1672  return;
1673  }
1674  // // Enchanted Weapons
1675  // case 39489: break;
1676  // // Shadow Bolt Whirl
1677  // case 39630: break;
1678  // // Shadow Bolt Whirl
1679  // case 39634: break;
1680  // // Shadow Inferno
1681  case 39645:
1682  {
1683  int32 BasePoints = int32(GetModifier()->m_amount);
1684  m_target->CastCustomSpell(m_target, 39646, &BasePoints, NULL, NULL, true, NULL, this);
1685  return;
1686  }
1687  // Tear of Azzinoth Summon Channel - it's not really supposed to do anything,and this only prevents the console spam
1688  case 39857:
1689  trigger_spell_id = 39856;
1690  break;
1691  // // Soulgrinder Ritual Visual (Smashed)
1692  // case 39974: break;
1693  // // Simon Game Pre-game timer
1694  // case 40041: break;
1695  // // Knockdown Fel Cannon: The Aggro Check Aura
1696  // case 40113: break;
1697  // // Spirit Lance
1698  // case 40157: break;
1699  // // Demon Transform 2
1700  // case 40398: break;
1701  // // Demon Transform 1
1702  // case 40511: break;
1703  // // Ancient Flames
1704  // case 40657: break;
1705  // // Ethereal Ring Cannon: Cannon Aura
1706  // case 40734: break;
1707  // // Cage Trap
1708  // case 40760: break;
1709  // // Random Periodic
1710  // case 40867: break;
1711  // Prismatic Shield
1712  case 40879:
1713  {
1714  switch (rand() % 6)
1715  {
1716  case 0:
1717  trigger_spell_id = 40880;
1718  break;
1719  case 1:
1720  trigger_spell_id = 40882;
1721  break;
1722  case 2:
1723  trigger_spell_id = 40883;
1724  break;
1725  case 3:
1726  trigger_spell_id = 40891;
1727  break;
1728  case 4:
1729  trigger_spell_id = 40896;
1730  break;
1731  case 5:
1732  trigger_spell_id = 40897;
1733  break;
1734  }
1735  }
1736  break;
1737  // Aura of Desire
1738  case 41350:
1739  {
1741  for (Unit::AuraList::const_iterator i = mMod.begin(); i != mMod.end(); ++i)
1742  {
1743  if ((*i)->GetId() == 41350)
1744  {
1745  (*i)->ApplyModifier(false);
1746  (*i)->GetModifier()->m_amount -= 5;
1747  (*i)->ApplyModifier(true);
1748  break;
1749  }
1750  }
1751  }
1752  break;
1753  // // Dementia
1754  case 41404:
1755  {
1756  if (rand() % 2)
1757  trigger_spell_id = 41406;
1758  else
1759  trigger_spell_id = 41409;
1760  }
1761  break;
1762  // // Chaos Form
1763  // case 41629: break;
1764  // // Alert Drums
1765  // case 42177: break;
1766  // // Spout
1767  // case 42581: break;
1768  // // Spout
1769  // case 42582: break;
1770  // // Return to the Spirit Realm
1771  // case 44035: break;
1772  // // Curse of Boundless Agony
1773  // case 45050: break;
1774  // // Earthquake
1775  // case 46240: break;
1776  // Personalized Weather
1777  case 46736:
1778  trigger_spell_id = 46737;
1779  break;
1780  // // Stay Submerged
1781  // case 46981: break;
1782  // // Dragonblight Ram
1783  // case 47015: break;
1784  // // Party G.R.E.N.A.D.E.
1785  // case 51510: break;
1786  default:
1787  break;
1788  }
1789  break;
1790  }
1791  case SPELLFAMILY_MAGE:
1792  {
1793  switch (auraId)
1794  {
1795  // Invisibility
1796  case 66:
1797  {
1798  if (!m_duration)
1799  m_target->CastSpell(m_target, 32612, true, NULL, this);
1800  return;
1801  }
1802  default:
1803  break;
1804  }
1805  break;
1806  }
1807  // case SPELLFAMILY_WARRIOR:
1808  // {
1809  // switch(auraId)
1810  // {
1811  // // Wild Magic
1812  // case 23410: break;
1813  // // Corrupted Totems
1814  // case 23425: break;
1815  // default:
1816  // break;
1817  // }
1818  // break;
1819  // }
1820  // case SPELLFAMILY_PRIEST:
1821  // {
1822  // switch(auraId)
1823  // {
1824  // // Blue Beam
1825  // case 32930: break;
1826  // // Fury of the Dreghood Elders
1827  // case 35460: break;
1828  // default:
1829  // break;
1830  // }
1831  // break;
1832  // }
1833  case SPELLFAMILY_DRUID:
1834  {
1835  switch (auraId)
1836  {
1837  // Cat Form
1838  // trigger_spell_id not set and unknown effect triggered in this case, ignoring for while
1839  case 768:
1840  return;
1841  // Frenzied Regeneration
1842  case 22842:
1843  case 22895:
1844  case 22896:
1845  case 26999:
1846  {
1847  int32 LifePerRage = GetModifier()->m_amount;
1848 
1849  int32 lRage = m_target->GetPower(POWER_RAGE);
1850  if (lRage > 100) // rage stored as rage*10
1851  lRage = 100;
1852  m_target->ModifyPower(POWER_RAGE, -lRage);
1853  int32 FRTriggerBasePoints = int32(lRage * LifePerRage / 10);
1854  m_target->CastCustomSpell(m_target, 22845, &FRTriggerBasePoints, NULL, NULL, true, NULL, this);
1855  return;
1856  }
1857  default:
1858  break;
1859  }
1860  break;
1861  }
1862  case SPELLFAMILY_HUNTER:
1863  {
1864  switch (auraId)
1865  {
1866  //Frost Trap Aura
1867  case 13810:
1868  if (caster->GetTypeId() == TYPEID_PLAYER)
1869  {
1870  float f_chance = 0;
1871  Unit::AuraList const& auraTriggerSpell = caster->GetAurasByType(SPELL_AURA_PROC_TRIGGER_SPELL);
1872  for (Unit::AuraList::const_iterator itr = auraTriggerSpell.begin(); itr != auraTriggerSpell.end(); ++itr)
1873  {
1874  switch ((*itr)->GetSpellProto()->Id)
1875  {
1876  case 19184:
1877  case 19387:
1878  case 19388:
1879  f_chance = (*itr)->GetSpellProto()->procChance;
1880  break;
1881  }
1882  }
1883 
1884  if (roll_chance_f(f_chance))
1885  {
1886  target = m_target;
1887  trigger_spell_id = 19185;
1888  }
1889  else
1890  return;
1891  }
1892  break;
1893  default:
1894  break;
1895  }
1896  break;
1897  }
1898  case SPELLFAMILY_SHAMAN:
1899  {
1900  switch (auraId)
1901  {
1902  // Lightning Shield (The Earthshatterer set trigger after cast Lighting Shield)
1903  case 28820:
1904  {
1905  // Need remove self if Lightning Shield not active
1906  Unit::AuraMap const& auras = target->GetAuras();
1907  for (Unit::AuraMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
1908  {
1909  SpellEntry const* spell = itr->second->GetSpellProto();
1910  if (spell->SpellFamilyName == SPELLFAMILY_SHAMAN &&
1911  spell->SpellFamilyFlags & 0x0000000000000400L)
1912  return;
1913  }
1914  target->RemoveAurasDueToSpell(28820);
1915  return;
1916  }
1917  // Totemic Mastery (Skyshatter Regalia (Shaman Tier 6) - bonus)
1918  case 38443:
1919  {
1920  bool all = true;
1921  for (int i = SUMMON_SLOT_TOTEM; i < MAX_TOTEM_SLOT; ++i)
1922  {
1923  if (!caster->m_SummonSlot[i])
1924  {
1925  all = false;
1926  break;
1927  }
1928  }
1929 
1930  if (all)
1931  caster->CastSpell(caster, 38437, true);
1932  else
1933  caster->RemoveAurasDueToSpell(38437);
1934  return;
1935  }
1936  default:
1937  break;
1938  }
1939  break;
1940  }
1941  default:
1942  break;
1943  }
1944  // Reget trigger spell proto
1945  triggeredSpellInfo = sSpellStore.LookupEntry(trigger_spell_id);
1946  if (triggeredSpellInfo == NULL)
1947  {
1948  Creature* c = target->ToCreature();
1949  if (!c || !caster || !sScriptMgr.EffectDummyCreature(caster, GetId(), SpellEffIndex(GetEffIndex()), target->ToCreature()) ||
1950  !c->AI()->sOnDummyEffect(caster, GetId(), SpellEffIndex(GetEffIndex())))
1951 
1952  sLog.outError("Aura::TriggerSpell: Spell %u has 0 in EffectTriggered[%d], unhandled custom case?", GetId(), GetEffIndex());
1953  return;
1954  }
1955  }
1956  else
1957  {
1958  // Spell exist but require custom code
1959  switch (auraId)
1960  {
1961  // Curse of Idiocy
1962  case 1010:
1963  {
1964  // @todo spell casted by result in correct way mostly
1965  // BUT:
1966  // 1) target show casting at each triggered cast: target don't must show casting animation for any triggered spell
1967  // but must show affect apply like item casting
1968  // 2) maybe aura must be replace by new with accumulative stat mods instead stacking
1969 
1970  // prevent cast by triggered auras
1971  if (m_caster_guid == m_target->GetGUID())
1972  return;
1973 
1974  // stop triggering after each affected stats lost > 90
1975  int32 intellectLoss = 0;
1976  int32 spiritLoss = 0;
1977 
1979  for (Unit::AuraList::const_iterator i = mModStat.begin(); i != mModStat.end(); ++i)
1980  {
1981  if ((*i)->GetId() == 1010)
1982  {
1983  switch ((*i)->GetModifier()->m_miscvalue)
1984  {
1985  case STAT_INTELLECT:
1986  intellectLoss += (*i)->GetModifierValue();
1987  break;
1988  case STAT_SPIRIT:
1989  spiritLoss += (*i)->GetModifierValue();
1990  break;
1991  default:
1992  break;
1993  }
1994  }
1995  }
1996 
1997  if (intellectLoss <= -90 && spiritLoss <= -90)
1998  return;
1999 
2000  caster = target;
2001  originalCasterGUID = 0;
2002  break;
2003  }
2004  // Mana Tide
2005  case 16191:
2006  {
2007  caster->CastCustomSpell(target, trigger_spell_id, &m_modifier.m_amount, NULL, NULL, true, NULL, this, originalCasterGUID);
2008  return;
2009  }
2010  // Negative Energy Periodic
2011  case 46284:
2012  {
2013  caster->CastCustomSpell(trigger_spell_id, SPELLVALUE_MAX_TARGETS, m_tickNumber / 10 + 1, NULL, true, NULL, this, originalCasterGUID);
2014  return;
2015  }
2016  // Rod of Purification - for quest 10839 (Veil Skith: Darkstone of Terokk)
2017  case 38736:
2018  {
2019  if (Unit* caster = GetCaster())
2020  caster->CastSpell(target, trigger_spell_id, true, NULL, this);
2021  return;
2022  }
2023  }
2024  }
2025  if (!GetSpellMaxRange(sSpellRangeStore.LookupEntry(triggeredSpellInfo->rangeIndex)))
2026  target = m_target; //for druid dispel poison
2027  m_target->CastSpell(target, triggeredSpellInfo, true, 0, this, originalCasterGUID);
2028 }
2029 
2031 {
2033  /*m_target->GetTypeId() == TYPEID_PLAYER ?
2034  m_target->ToPlayer()->GetSelection() :*/
2036  return target ? target : m_target;
2037 }
2038 
2040 {
2041  const uint64& casterGUID = GetCasterGUID();
2042  Unit* target = GetTriggerTarget();
2043 
2044  if (!casterGUID || !target)
2045  return;
2046 
2047  // generic casting code with custom spells and target/caster customs
2048  uint32 trigger_spell_id = GetSpellProto()->EffectTriggerSpell[m_effIndex];
2049  int32 basepoints0 = GetModifier()->m_amount;
2050 
2051  target->CastCustomSpell(target, trigger_spell_id, &basepoints0, NULL, NULL, true, NULL, this, casterGUID);
2052 }
2053 
2054 /*********************************************************/
2055 /*** AURA EFFECTS ***/
2056 /*********************************************************/
2057 
2058 void Aura::HandleAuraDummy(bool apply, bool Real)
2059 {
2060  // spells required only Real aura add/remove
2061  if (!Real)
2062  return;
2063 
2064  Unit* caster = GetCaster();
2065 
2066  // AT APPLY
2067  if (apply)
2068  {
2069  switch (GetId())
2070  {
2071  case 31261:
2072  case 29266:
2077  return;
2078  case 1515: // Tame beast
2079  // FIX_ME: this is 2.0.12 threat effect replaced in 2.1.x by dummy aura, must be checked for correctness
2080  if (caster && m_target->CanHaveThreatList())
2081  m_target->AddThreat(caster, 10.0f);
2082  return;
2083  case 7057: // Haunting Spirits
2084  // expected to tick with 30 sec period (tick part see in Aura::PeriodicTick)
2085  m_isPeriodic = true;
2088  return;
2089  case 13139: // net-o-matic
2090  // root to self part of (root_target->charge->root_self sequence
2091  if (caster)
2092  caster->CastSpell(caster, 13138, true, NULL, this);
2093  return;
2094  case 37096: // Blood Elf Disguise
2095  if (caster)
2096  {
2097  if (caster->getGender() == GENDER_FEMALE)
2098  caster->CastSpell(m_target, 37095, true, NULL, this);
2099  else
2100  caster->CastSpell(m_target, 37093, true, NULL, this);
2101  }
2102  return;
2103  case 30019: //control piece
2104  if (caster && caster->GetTypeId() == TYPEID_PLAYER)
2105  caster->ToPlayer()->TeleportTo(532, -11105.08f, -1845.65f, 229.65f, 5.42f);
2106  if (caster && caster->GetCharm())
2107  caster->GetCharm()->GetCharmInfo()->SetIsAtStay(true);
2108  return;
2109  case 39850: // Rocket Blast
2110  if (roll_chance_i(20)) // backfire stun
2111  m_target->CastSpell(m_target, 51581, true, NULL, this);
2112  return;
2113  case 43873: // Headless Horseman Laugh
2114  m_target->PlayDistanceSound(11965);
2115  return;
2116  case 46354: // Blood Elf Illusion
2117  {
2118  if (caster)
2119  {
2120  if (caster->getGender() == GENDER_FEMALE)
2121  caster->CastSpell(m_target, 46356, true, NULL, this);
2122  else
2123  caster->CastSpell(m_target, 46355, true, NULL, this);
2124  break;
2125  }
2126  return;
2127  }
2128  case 32260: //Chess: Deactivate Own Field
2129  {
2130  //Set No_Movement Flag, to disable Field
2132  //Add Tempsummon
2134  return;
2135  }
2136  case 32261: //Chess: Create Move Marker
2137  {
2138  if (m_target->GetEntry() == 17305 || m_target->GetEntry() == 17208) //Only white or black squares are valid targets
2140  return;
2141  }
2142  case 46699: // Requires No Ammo
2143  if (m_target->GetTypeId() == TYPEID_PLAYER)
2144  m_target->ToPlayer()->RemoveAmmo(); // not use ammo and not allow use
2145  return;
2146  case 39246: // Q: The Big Bone Worm
2147  {
2148  if (!m_target)
2149  return;
2150 
2151  if (Unit* caster = GetCaster())
2152  {
2153  if (urand(0, 10) > 2)
2154  {
2155  int32 count = urand(0, 1) ? 2 : 4;
2156  for (int i = 0; i < count; ++i)
2158  }
2159  else
2161  }
2162  return;
2163  }
2164  case 39238: // Fumping
2165  {
2166  if (!m_target)
2167  return;
2168 
2169  if (Unit* caster = GetCaster())
2170  {
2171  if (urand(0, 1) == 0)
2173  else
2174  {
2178  }
2179  }
2180  return;
2181  }
2182  }
2183 
2184  // Earth Shield
2185  if (caster && GetSpellProto()->SpellFamilyName == SPELLFAMILY_SHAMAN && (GetSpellProto()->SpellFamilyFlags & 0x40000000000LL))
2186  {
2187  // prevent double apply bonuses
2190  return;
2191  }
2192  }
2193  // AT REMOVE
2194  else
2195  {
2196  if ((IsQuestTameSpell(GetId())) && caster && caster->IsAlive() && m_target->IsAlive())
2197  {
2198  uint32 finalSpellId = 0;
2199  switch (GetId())
2200  {
2201  case 19548: finalSpellId = 19597; break;
2202  case 19674: finalSpellId = 19677; break;
2203  case 19687: finalSpellId = 19676; break;
2204  case 19688: finalSpellId = 19678; break;
2205  case 19689: finalSpellId = 19679; break;
2206  case 19692: finalSpellId = 19680; break;
2207  case 19693: finalSpellId = 19684; break;
2208  case 19694: finalSpellId = 19681; break;
2209  case 19696: finalSpellId = 19682; break;
2210  case 19697: finalSpellId = 19683; break;
2211  case 19699: finalSpellId = 19685; break;
2212  case 19700: finalSpellId = 19686; break;
2213  case 30646: finalSpellId = 30647; break;
2214  case 30653: finalSpellId = 30648; break;
2215  case 30654: finalSpellId = 30652; break;
2216  case 30099: finalSpellId = 30100; break;
2217  case 30102: finalSpellId = 30103; break;
2218  case 30105: finalSpellId = 30104; break;
2219  }
2220 
2221  if (finalSpellId)
2222  caster->CastSpell(m_target, finalSpellId, true, NULL, this);
2223 
2224  return;
2225  }
2226 
2227  switch (GetId())
2228  {
2229  case 2584: // Waiting to Resurrect
2230  {
2231  // Waiting to resurrect spell cancel, we must remove player from resurrect queue
2232  if (m_target->GetTypeId() == TYPEID_PLAYER)
2234  bg->RemovePlayerFromResurrectQueue(m_target->GetGUID());
2235  return;
2236  }
2237  case 28169: // Mutating Injection
2238  {
2239  // Mutagen Explosion
2240  m_target->CastSpell(m_target, 28206, true, NULL, this);
2241  // Poison Cloud
2242  m_target->CastSpell(m_target, 28240, true, NULL, this);
2243  return;
2244  }
2245  case 36730: // Flame Strike
2246  {
2247  m_target->CastSpell(m_target, 36731, true, NULL, this);
2248  return;
2249  }
2250  case 44191: // Flame Strike
2251  {
2252  if (m_target->GetMap()->IsDungeon())
2253  {
2254  uint32 spellId = m_target->GetMap()->IsHeroic() ? 46163 : 44190;
2255 
2256  m_target->CastSpell(m_target, spellId, true, NULL, this);
2257  }
2258  return;
2259  }
2260  case 45934: // Dark Fiend
2261  {
2262  // Kill target if dispelled
2265  return;
2266  }
2267  case 43681: // Inactive
2268  {
2270  return;
2271 
2272  if (m_target->GetMap()->IsBattleground())
2274  break;
2275  }
2276  case 46308: // Burning Winds - casted only at creatures at spawn
2277  m_target->CastSpell(m_target, 47287, true, NULL, this);
2278  break;
2279  case 34477: // Misdirection
2280  {
2282  return;
2283  }
2284  case 30019: //control piece
2285  {
2286  m_target->CastSpell(m_target, 30529, true, NULL, this); //conrol piece debuff
2287  if (m_target->GetTypeId() == TYPEID_PLAYER)
2289  return;
2290  }
2291  case 31261:
2292  case 29266:
2293  {
2298  return;
2299  }
2300  }
2301  }
2302 
2303  // AT APPLY & REMOVE
2304 
2305  switch (m_spellProto->SpellFamilyName)
2306  {
2307  case SPELLFAMILY_GENERIC:
2308  {
2309  // Unstable Power
2310  if (GetId() == 24658)
2311  {
2312  uint32 spellId = 24659;
2313  if (apply)
2314  {
2315  const SpellEntry* spell = sSpellStore.LookupEntry(spellId);
2316  if (!spell)
2317  return;
2318  for (uint32 i = 0; i < spell->StackAmount; ++i)
2319  caster->CastSpell(m_target, spell->Id, true, NULL, NULL, GetCasterGUID());
2320  return;
2321  }
2322  m_target->RemoveAurasDueToSpell(spellId);
2323  return;
2324  }
2325  // Restless Strength
2326  if (GetId() == 24661)
2327  {
2328  uint32 spellId = 24662;
2329  if (apply)
2330  {
2331  const SpellEntry* spell = sSpellStore.LookupEntry(spellId);
2332  if (!spell)
2333  return;
2334  for (uint32 i = 0; i < spell->StackAmount; ++i)
2335  caster->CastSpell(m_target, spell->Id, true, NULL, NULL, GetCasterGUID());
2336  return;
2337  }
2338  m_target->RemoveAurasDueToSpell(spellId);
2339  return;
2340  }
2341  // Victorious
2342  if (GetId() == 32216 && m_target->getClass() == CLASS_WARRIOR)
2343  {
2345  return;
2346  }
2347  //Summon Fire Elemental
2348  if (GetId() == 40133 && caster)
2349  {
2350  Unit* owner = caster->GetOwner();
2351  if (owner && owner->GetTypeId() == TYPEID_PLAYER)
2352  {
2353  if (apply)
2354  owner->CastSpell(owner, 8985, true);
2355  else
2356  owner->ToPlayer()->RemovePet(NULL, PET_SAVE_NOT_IN_SLOT, true);
2357  }
2358  return;
2359  }
2360 
2361  //Summon Earth Elemental
2362  if (GetId() == 40132 && caster)
2363  {
2364  Unit* owner = caster->GetOwner();
2365  if (owner && owner->GetTypeId() == TYPEID_PLAYER)
2366  {
2367  if (apply)
2368  owner->CastSpell(owner, 19704, true);
2369  else
2370  owner->ToPlayer()->RemovePet(NULL, PET_SAVE_NOT_IN_SLOT, true);
2371  }
2372  return;
2373  }
2374 
2375  if (GetId() == 126 && caster) // Eye of Kilrogg (Temporarily UnSumoon Main Pet)
2376  {
2377  Player* player = caster->ToPlayer();
2378  if (!player)
2379  return;
2380 
2381  if (apply)
2382  player->UnsummonPetTemporaryIfAny();
2383  else
2385  return;
2386  }
2387 
2388  // As the crow flies
2389  if (GetId() == 31606)
2390  {
2391  if (apply)
2392  SetAuraDuration(110000);
2393  else if (Player* player = m_target->ToPlayer())
2394  player->AreaExploredOrEventHappens(9718);
2395  }
2396 
2397  // Zul'Aman Object Visual (Strange Gong)
2398  if (GetId() == 45222)
2399  if (apply)
2400  m_target->CastSpell(m_target, 45225, false, NULL, this);
2401  break;
2402  }
2403  case SPELLFAMILY_MAGE:
2404  {
2405  // Hypothermia
2406  if (GetId() == 41425)
2407  {
2409  return;
2410  }
2411  break;
2412  }
2413  case SPELLFAMILY_DRUID:
2414  {
2415  // Lifebloom
2416  if (GetSpellProto()->SpellFamilyFlags & 0x1000000000LL)
2417  {
2418  if (apply)
2419  {
2420  if (caster)
2421  // prevent double apply bonuses
2424  }
2425  // Do final heal for real !apply
2426  else if (Real)
2427  {
2429  {
2430  // final heal
2431  if (m_target->IsInWorld())
2432  m_target->CastCustomSpell(m_target, 33778, &m_modifier.m_amount, NULL, NULL, true, NULL, this, GetCasterGUID());
2433  }
2434  }
2435  return;
2436  }
2437 
2438  // Predatory Strikes
2439  if (m_target->GetTypeId() == TYPEID_PLAYER && GetSpellProto()->SpellIconID == 1563)
2440  {
2442  return;
2443  }
2444  // Idol of the Emerald Queen
2445  if (GetId() == 34246 && m_target->GetTypeId() == TYPEID_PLAYER)
2446  {
2447  if (apply)
2448  {
2449  SpellModifier* mod = new SpellModifier;
2450  mod->op = SPELLMOD_DOT;
2451  mod->value = m_modifier.m_amount / 7;
2452  mod->type = SPELLMOD_FLAT;
2453  mod->spellId = GetId();
2454  mod->effectId = m_effIndex;
2455  mod->lastAffected = NULL;
2456  mod->mask = 0x001000000000LL;
2457  mod->charges = 0;
2458 
2459  m_spellmod = mod;
2460  }
2461 
2463  return;
2464  }
2465  break;
2466  }
2467  case SPELLFAMILY_HUNTER:
2468  {
2469  // Improved Aspect of the Viper
2470  if (GetId() == 38390 && m_target->GetTypeId() == TYPEID_PLAYER)
2471  {
2472  if (apply)
2473  {
2474  // + effect value for Aspect of the Viper
2475  SpellModifier* mod = new SpellModifier;
2476  mod->op = SPELLMOD_EFFECT1;
2477  mod->value = m_modifier.m_amount;
2478  mod->type = SPELLMOD_FLAT;
2479  mod->spellId = GetId();
2480  mod->effectId = m_effIndex;
2481  mod->lastAffected = NULL;
2482  mod->mask = 0x4000000000000LL;
2483  mod->charges = 0;
2484 
2485  m_spellmod = mod;
2486  }
2487 
2489  return;
2490  }
2491  break;
2492  }
2493  case SPELLFAMILY_SHAMAN:
2494  {
2495  // Improved Weapon Totems
2496  if (GetSpellProto()->SpellIconID == 57 && m_target->GetTypeId() == TYPEID_PLAYER)
2497  {
2498  if (apply)
2499  {
2500  SpellModifier* mod = new SpellModifier;
2501  mod->op = SPELLMOD_EFFECT1;
2502  mod->value = m_modifier.m_amount;
2503  mod->type = SPELLMOD_PCT;
2504  mod->spellId = GetId();
2505  mod->effectId = m_effIndex;
2506  mod->lastAffected = NULL;
2507  switch (m_effIndex)
2508  {
2509  case 0:
2510  mod->mask = 0x00200000000LL; // Windfury Totem
2511  break;
2512  case 1:
2513  mod->mask = 0x00400000000LL; // Flametongue Totem
2514  break;
2515  }
2516  mod->charges = 0;
2517 
2518  m_spellmod = mod;
2519  }
2520 
2522  return;
2523  }
2524 
2525  // Sentry Totem
2526  if (GetId() == 6495 && caster->GetTypeId() == TYPEID_PLAYER)
2527  {
2528  if (apply)
2529  {
2530  uint64 guid = caster->m_SummonSlot[3];
2531  if (guid)
2532  {
2533  Creature* totem = caster->GetMap()->GetCreature(guid);
2534  if (totem && totem->IsTotem())
2535  caster->ToPlayer()->CastSpell(totem, 6277, true);
2536  }
2537  }
2538  else
2539  caster->ToPlayer()->StopCastingBindSight();
2540  return;
2541  }
2542  break;
2543  }
2544  }
2545 
2546  // pet auras
2547  if (PetAura const* petSpell = sSpellMgr.GetPetAura(GetId()))
2548  {
2549  if (apply)
2550  m_target->AddPetAura(petSpell);
2551  else
2552  m_target->RemovePetAura(petSpell);
2553  return;
2554  }
2555 }
2556 
2557 void Aura::HandleAuraMounted(bool apply, bool Real)
2558 {
2559  // only at real add/remove aura
2560  if (!Real)
2561  return;
2562 
2563  if (apply)
2564  {
2565  CreatureInfo const* ci = sObjectMgr.GetCreatureTemplate(m_modifier.m_miscvalue);
2566  if (!ci)
2567  {
2568  sLog.outErrorDb("AuraMounted: creature_template='%u' not found in database (only need it modelid)", m_modifier.m_miscvalue);
2569  return;
2570  }
2571 
2572  uint32 team = 0;
2573  if (m_target->GetTypeId() == TYPEID_PLAYER)
2574  team = m_target->ToPlayer()->GetTeam();
2575 
2576  uint32 display_id = sObjectMgr.ChooseDisplayId(team, ci);
2577  CreatureModelInfo const* minfo = sObjectMgr.GetCreatureModelRandomGender(display_id);
2578  if (minfo)
2579  display_id = minfo->modelid;
2580 
2581  m_target->Mount(display_id, m_spellProto->Id);
2582  }
2583  else
2584  {
2585  m_target->Dismount();
2587  }
2588 }
2589 
2590 void Aura::HandleAuraWaterWalk(bool apply, bool Real)
2591 {
2592  // only at real add/remove aura
2593  if (!Real)
2594  return;
2595 
2596  if (!apply)
2597  {
2598  // do not remove unit flag if there are more than this auraEffect of that kind on unit
2600  return;
2601  }
2602 
2603  m_target->SetWaterWalking(apply);
2604 }
2605 
2606 void Aura::HandleAuraFeatherFall(bool apply, bool Real)
2607 {
2608  // only at real add/remove aura
2609  if (!Real)
2610  return;
2611 
2612  if (!apply)
2613  {
2614  // do not remove unit flag if there are more than this auraEffect of that kind on unit
2616  return;
2617  }
2618 
2619  m_target->SetFeatherFall(apply);
2620 
2621  // start fall from current height
2622  if (!apply && m_target->GetTypeId() == TYPEID_PLAYER)
2623  ((Player*)m_target)->SetFallInformation(0, m_target->GetPositionZ());
2624 }
2625 
2626 void Aura::HandleAuraHover(bool apply, bool Real)
2627 {
2628  // only at real add/remove aura
2629  if (!Real)
2630  return;
2631 
2632  if (!apply)
2633  {
2634  // do not remove unit flag if there are more than this auraEffect of that kind on unit
2636  return;
2637  }
2638 
2639  m_target->SetHover(apply);
2640 }
2641 
2642 void Aura::HandleWaterBreathing(bool /*apply*/, bool /*Real*/)
2643 {
2644  // update timers in client
2645  if (m_target->GetTypeId() == TYPEID_PLAYER)
2647 }
2648 
2650 {
2651  if (!Real)
2652  return;
2653 
2654  uint32 modelid = 0;
2655  Powers PowerType = POWER_MANA;
2657 
2658  switch (form)
2659  {
2660  case FORM_CAT:
2662  modelid = 892;
2663  else
2664  modelid = 8571;
2665  PowerType = POWER_ENERGY;
2666  break;
2667  case FORM_TRAVEL:
2668  modelid = 918;
2669  break;
2670  case FORM_AQUA:
2672  modelid = 2428;
2673  else
2674  modelid = 2428;
2675  break;
2676  case FORM_BEAR:
2678  modelid = 2281;
2679  else
2680  modelid = 2289;
2681  PowerType = POWER_RAGE;
2682  break;
2683  case FORM_DIREBEAR:
2685  modelid = 2281;
2686  else
2687  modelid = 2289;
2688  PowerType = POWER_RAGE;
2689  break;
2690  case FORM_FLIGHT:
2692  modelid = 20857;
2693  else
2694  modelid = 20872;
2695  break;
2696  case FORM_MOONKIN:
2698  modelid = 15374;
2699  else
2700  modelid = 15375;
2701  break;
2702  case FORM_FLIGHT_EPIC:
2704  modelid = 21243;
2705  else
2706  modelid = 21244;
2707  break;
2708  case FORM_BATTLESTANCE:
2709  case FORM_BERSERKERSTANCE:
2710  case FORM_DEFENSIVESTANCE:
2711  PowerType = POWER_RAGE;
2712  break;
2713  default:
2714  SpellShapeshiftEntry const* formEntry = sSpellShapeshiftStore.LookupEntry(form);
2715  if (formEntry && formEntry->modelID_A)
2716  modelid = formEntry->modelID_A;
2717  }
2718 
2719  // remove polymorph before changing display id to keep new display id
2720  switch (form)
2721  {
2722  case FORM_CAT:
2723  case FORM_TREE:
2724  case FORM_TRAVEL:
2725  case FORM_AQUA:
2726  case FORM_BEAR:
2727  case FORM_DIREBEAR:
2728  case FORM_FLIGHT_EPIC:
2729  case FORM_FLIGHT:
2730  case FORM_MOONKIN:
2731  {
2732  // remove movement affects
2734 
2735  // and polymorphic affects
2736  if (m_target->IsPolymorphed())
2738  }
2739  case FORM_GHOSTWOLF:
2740  {
2741  // remove water walk aura. @todo there is probably better way to do this
2743  break;
2744  }
2745  default:
2746  break;
2747  }
2748 
2749  if (apply)
2750  {
2751  // remove other shapeshift before applying a new one
2754 
2756  // force update as too quick shapeshifting and back
2757  // causes the value to stay the same serverside
2758  // causes issues clientside (player gets stuck)
2760 
2761  if (modelid > 0)
2762  m_target->SetDisplayId(modelid);
2763 
2764  if (PowerType != POWER_MANA)
2765  {
2766  // reset power to default values only at power change
2767  if (m_target->getPowerType() != PowerType)
2768  m_target->setPowerType(PowerType);
2769 
2770  switch (form)
2771  {
2772  case FORM_CAT:
2773  case FORM_BEAR:
2774  case FORM_DIREBEAR:
2775  {
2776  // get furor proc chance
2777  uint32 FurorChance = 0;
2779  for (Unit::AuraList::const_iterator i = mDummy.begin(); i != mDummy.end(); ++i)
2780  {
2781  if ((*i)->GetSpellProto()->SpellIconID == 238)
2782  {
2783  FurorChance = (*i)->GetModifier()->m_amount;
2784  break;
2785  }
2786  }
2787 
2789  {
2791  if (urand(1, 100) <= FurorChance)
2792  m_target->CastSpell(m_target, 17099, true, NULL, this);
2793  }
2794  else
2795  {
2797  if (urand(1, 100) <= FurorChance)
2798  m_target->CastSpell(m_target, 17057, true, NULL, this);
2799  }
2800  break;
2801  }
2802  case FORM_BATTLESTANCE:
2803  case FORM_DEFENSIVESTANCE:
2804  case FORM_BERSERKERSTANCE:
2805  {
2806  uint32 Rage_val = 0;
2807  // Stance mastery + Tactical mastery (both passive, and last have aura only in defense stance, but need apply at any stance switch)
2808  if (m_target->GetTypeId() == TYPEID_PLAYER)
2809  {
2810  PlayerSpellMap const& sp_list = m_target->ToPlayer()->GetSpellMap();
2811  for (PlayerSpellMap::const_iterator itr = sp_list.begin(); itr != sp_list.end(); ++itr)
2812  {
2813  if (itr->second.state == PLAYERSPELL_REMOVED) continue;
2814  SpellEntry const* spellInfo = sSpellStore.LookupEntry(itr->first);
2815  if (spellInfo && spellInfo->SpellFamilyName == SPELLFAMILY_WARRIOR && spellInfo->SpellIconID == 139)
2816  Rage_val += m_target->CalculateSpellDamage(spellInfo, 0, spellInfo->EffectBasePoints[0], m_target) * 10;
2817  }
2818  }
2819 
2820  if (m_target->GetPower(POWER_RAGE) > Rage_val)
2821  m_target->SetPower(POWER_RAGE, Rage_val);
2822  break;
2823  }
2824  default:
2825  break;
2826  }
2827  }
2828 
2830  m_target->m_ShapeShiftModelId = modelid;
2831  m_target->m_form = form;
2832  }
2833  else
2834  {
2835  if (modelid > 0)
2838  if (m_target->getClass() == CLASS_DRUID)
2842 
2843  switch (form)
2844  {
2845  // Nordrassil Harness - bonus
2846  case FORM_BEAR:
2847  case FORM_DIREBEAR:
2848  case FORM_CAT:
2849  if (Aura* dummy = m_target->GetDummyAura(37315))
2850  m_target->CastSpell(m_target, 37316, true, NULL, dummy);
2851  break;
2852  // Nordrassil Regalia - bonus
2853  case FORM_MOONKIN:
2854  if (Aura* dummy = m_target->GetDummyAura(37324))
2855  m_target->CastSpell(m_target, 37325, true, NULL, dummy);
2856  break;
2857  default:
2858  break;
2859  }
2860 
2861  // Remove auras linked to forms, such as Vanish and Stealth
2863 
2864  /* We need to re-apply any of transform auras:
2865  Great example is OHF, when you are in cat form and unshapeshift,
2866  you should be a human not your original model */
2868  for (Unit::AuraList::const_iterator i = trans.begin(); i != trans.end(); i++)
2869  (*i)->ApplyModifier(true, true);
2870  }
2871 
2872  // adding/removing linked auras
2873  // add/remove the shapeshift aura's boosts
2874  HandleShapeshiftBoosts(apply);
2875 
2876  if (m_target->GetTypeId() == TYPEID_PLAYER)
2878 }
2879 
2880 void Aura::HandleAuraTransform(bool apply, bool Real)
2881 {
2882  if (apply)
2883  {
2884  // Shapeshifts (that change model) have higher priority than transforms (if not negative)
2886  return;
2887 
2888  // special case (spell specific functionality)
2889  if (m_modifier.m_miscvalue == 0)
2890  {
2891  switch (GetId())
2892  {
2893  case 16739: // Orb of Deception
2894  {
2895  if (m_target->GetTypeId() != TYPEID_PLAYER)
2896  return;
2897 
2898  switch (m_target->getRace())
2899  {
2900  // Blood Elf
2901  case RACE_BLOODELF:
2902  m_target->SetDisplayId(m_target->getGender() == GENDER_FEMALE ? 17830 : 17829);
2903  break;
2904  // Orc
2905  case RACE_ORC:
2906  m_target->SetDisplayId(m_target->getGender() == GENDER_FEMALE ? 10140 : 10139);
2907  break;
2908  // Troll
2909  case RACE_TROLL:
2910  m_target->SetDisplayId(m_target->getGender() == GENDER_FEMALE ? 10134 : 10135);
2911  break;
2912  // Tauren
2913  case RACE_TAUREN:
2914  m_target->SetDisplayId(m_target->getGender() == GENDER_FEMALE ? 10147 : 10136);
2915  break;
2916  // Undead
2917  case RACE_UNDEAD_PLAYER:
2918  m_target->SetDisplayId(m_target->getGender() == GENDER_FEMALE ? 10145 : 10146);
2919  break;
2920  // Draenei
2921  case RACE_DRAENEI:
2922  m_target->SetDisplayId(m_target->getGender() == GENDER_FEMALE ? 17828 : 17827);
2923  break;
2924  // Dwarf
2925  case RACE_DWARF:
2926  m_target->SetDisplayId(m_target->getGender() == GENDER_FEMALE ? 10142 : 10141);
2927  break;
2928  // Gnome
2929  case RACE_GNOME:
2930  m_target->SetDisplayId(m_target->getGender() == GENDER_FEMALE ? 10149 : 10148);
2931  break;
2932  // Human
2933  case RACE_HUMAN:
2934  m_target->SetDisplayId(m_target->getGender() == GENDER_FEMALE ? 10138 : 10137);
2935  break;
2936  // Night Elf
2937  case RACE_NIGHTELF:
2938  m_target->SetDisplayId(m_target->getGender() == GENDER_FEMALE ? 10144 : 10143);
2939  break;
2940  default:
2941  break;
2942  }
2943  break;
2944  }
2945  // Murloc costume
2946  case 42365:
2947  m_target->SetDisplayId(21723);
2948  break;
2949  // Dread Corsair - Pirate Day
2950  case 50531:
2951  case 50517:
2952  {
2953  if (m_target->GetTypeId() != TYPEID_PLAYER)
2954  return;
2955 
2956  switch (m_target->getRace())
2957  {
2958  // Blood Elf
2959  case RACE_BLOODELF:
2960  m_target->SetDisplayId(m_target->getGender() == GENDER_MALE ? 25032 : 25043);
2961  break;
2962  // Orc
2963  case RACE_ORC:
2964  m_target->SetDisplayId(m_target->getGender() == GENDER_MALE ? 25039 : 25050);
2965  break;
2966  // Troll
2967  case RACE_TROLL:
2968  m_target->SetDisplayId(m_target->getGender() == GENDER_MALE ? 25041 : 25052);
2969  break;
2970  // Tauren
2971  case RACE_TAUREN:
2972  m_target->SetDisplayId(m_target->getGender() == GENDER_MALE ? 25040 : 25051);
2973  break;
2974  // Undead
2975  case RACE_UNDEAD_PLAYER:
2976  m_target->SetDisplayId(m_target->getGender() == GENDER_MALE ? 25042 : 25053);
2977  break;
2978  // Draenei
2979  case RACE_DRAENEI:
2980  m_target->SetDisplayId(m_target->getGender() == GENDER_MALE ? 25033 : 25044);
2981  break;
2982  // Dwarf
2983  case RACE_DWARF:
2984  m_target->SetDisplayId(m_target->getGender() == GENDER_MALE ? 25034 : 25045);
2985  break;
2986  // Gnome
2987  case RACE_GNOME:
2988  m_target->SetDisplayId(m_target->getGender() == GENDER_MALE ? 25035 : 25046);
2989  break;
2990  // Human
2991  case RACE_HUMAN:
2992  m_target->SetDisplayId(m_target->getGender() == GENDER_MALE ? 25037 : 25048);
2993  break;
2994  // Night Elf
2995  case RACE_NIGHTELF:
2996  m_target->SetDisplayId(m_target->getGender() == GENDER_MALE ? 25038 : 25049);
2997  break;
2998  default:
2999  break;
3000  }
3001  break;
3002  }
3003  default:
3004  break;
3005  }
3006  }
3007  else
3008  {
3009  uint32 model_id;
3010 
3011  CreatureInfo const* ci = sObjectMgr.GetCreatureTemplate(m_modifier.m_miscvalue);
3012  if (!ci)
3013  {
3014  model_id = 16358; //pig pink ^_^
3015  sLog.outError("Auras: unknown creature id = %d (only need its modelid) Form Spell Aura Transform in Spell ID = %d", m_modifier.m_miscvalue, GetId());
3016  }
3017  else
3018  model_id = ci->GetRandomValidModelId();
3019 
3020  m_target->SetDisplayId(model_id);
3021 
3022  // Dragonmaw Illusion (set mount model also)
3025  }
3026 
3027  // update active transform spell only not set or not overwriting negative by positive case
3030 
3031  // polymorph case
3032  if (Real && m_target->GetTypeId() == TYPEID_PLAYER && m_target->IsPolymorphed())
3033  {
3034  // for players, start regeneration after 1s (in polymorph fast regeneration case)
3035  // only if caster is Player (after patch 2.4.2)
3036  if (GetCaster()->IsPlayer())
3038 
3039  //dismount polymorphed target (after patch 2.4.2)
3040  if (m_target->IsMounted())
3042  }
3043  }
3044  else
3045  {
3046  if (m_target->getTransForm() == GetId())
3047  m_target->setTransForm(0);
3048 
3051  else
3053 
3054  // apply default equipment for creature case
3055  if (m_target->GetTypeId() == TYPEID_UNIT)
3056  ((Creature*)m_target)->LoadEquipment(((Creature*)m_target)->GetCreatureTemplate()->equipmentId, true);
3057 
3058  // re-apply some from still active with preference negative cases
3059  Unit::AuraList const& otherTransforms = m_target->GetAurasByType(SPELL_AURA_TRANSFORM);
3060  if (!otherTransforms.empty())
3061  {
3062  // look for other transform auras
3063  Aura* handledAura = *otherTransforms.begin();
3064  for (Unit::AuraList::const_iterator i = otherTransforms.begin(); i != otherTransforms.end(); ++i)
3065  {
3066  // negative auras are preferred
3067  if (!IsPositiveSpell((*i)->GetSpellProto()->Id))
3068  {
3069  handledAura = *i;
3070  break;
3071  }
3072  }
3073  handledAura->ApplyModifier(true);
3074  }
3075 
3076  // Dragonmaw Illusion (restore mount model)
3077  if (GetId() == 42016 && m_target->GetMountID() == 16314)
3078  {
3080  {
3081  uint32 cr_id = m_target->GetAurasByType(SPELL_AURA_MOUNTED).front()->GetModifier()->m_miscvalue;
3082  if (CreatureInfo const* ci = sObjectMgr.GetCreatureTemplate(cr_id))
3083  {
3084  uint32 team = 0;
3085  if (m_target->GetTypeId() == TYPEID_PLAYER)
3086  team = m_target->ToPlayer()->GetTeam();
3087 
3088  uint32 display_id = sObjectMgr.ChooseDisplayId(team, ci);
3089  CreatureModelInfo const* minfo = sObjectMgr.GetCreatureModelRandomGender(display_id);
3090  if (minfo)
3091  display_id = minfo->modelid;
3092 
3094  }
3095  }
3096  }
3097  }
3098 }
3099 
3100 void Aura::HandleForceReaction(bool apply, bool Real)
3101 {
3102  if (!Real)
3103  return;
3104 
3105  Player* player = m_target->ToPlayer();
3106  if (!player)
3107  return;
3108 
3109  uint32 factionId = m_modifier.m_miscvalue;
3110  uint32 factionRank = m_modifier.m_amount;
3111 
3112  player->GetReputationMgr().ApplyForceReaction(factionId, ReputationRank(factionRank), apply);
3114 }
3115 
3116 void Aura::HandleAuraModSkill(bool apply, bool /*Real*/)
3117 {
3118  if (m_target->GetTypeId() != TYPEID_PLAYER)
3119  return;
3120 
3122  int32 points = GetModifierValue();
3123 
3124  m_target->ToPlayer()->ModifySkillBonus(prot, ((apply) ? points: -points), GetAuraType() == SPELL_AURA_MOD_SKILL_TALENT);
3125  if (prot == SKILL_DEFENSE)
3127 }
3128 
3130 {
3131  if (apply || m_removeMode != AURA_REMOVE_BY_DEATH)
3132  return;
3133 
3134  Unit* caster = GetCaster();
3135  if (!caster || caster->GetTypeId() != TYPEID_PLAYER)
3136  return;
3137 
3138  Player* plCaster = caster->ToPlayer();
3139  Unit* target = GetTarget();
3140 
3141  if (Real)
3142  {
3143  if (!target)
3144  return;
3145 
3146  // Item amount
3147  if (GetAmount() <= 0)
3148  return;
3149 
3150  SpellEntry const* spellInfo = GetSpellProto();
3151  if (spellInfo->EffectItemType[m_effIndex] == 0)
3152  return;
3153 
3154  // Soul Shard
3155  if (GetSpellProto()->EffectItemType[m_effIndex] == 6265)
3156  {
3157  // Soul Shard only from units that grant XP or honor
3158  if (!plCaster->isHonorOrXPTarget(target) ||
3159  (target->GetTypeId() == TYPEID_UNIT && !target->ToCreature()->isTappedBy(plCaster)))
3160  return;
3161  }
3162 
3163  //Adding items
3164  uint32 noSpaceForCount = 0;
3165  uint32 count = m_modifier.m_amount;
3166 
3167  ItemPosCountVec dest;
3168  uint8 msg = plCaster->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, spellInfo->EffectItemType[m_effIndex], count, &noSpaceForCount);
3169  if (msg != EQUIP_ERR_OK)
3170  {
3171  count-=noSpaceForCount;
3172  plCaster->SendEquipError(msg, NULL, NULL);
3173  if (count == 0)
3174  return;
3175  }
3176 
3177  Item* newitem = plCaster->StoreNewItem(dest, spellInfo->EffectItemType[m_effIndex], true);
3178  if (!newitem)
3179  {
3180  plCaster->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, NULL, NULL);
3181  return;
3182  }
3183  plCaster->SendNewItem(newitem, count, true, true);
3184  }
3185 }
3186 
3187 void Aura::HandleBindSight(bool apply, bool /*Real*/)
3188 {
3189  Unit* caster = GetCaster();
3190  if (!caster || caster->GetTypeId() != TYPEID_PLAYER)
3191  return;
3192 
3193  caster->ToPlayer()->SetViewpoint(m_target, apply);
3194 }
3195 
3196 //@todo complete
3197 void Aura::HandleFarSight(bool /*apply*/, bool /*Real*/)
3198 {
3199  /*Unit* caster = GetCaster();
3200  if (!caster || caster->GetTypeId() != TYPEID_PLAYER)
3201  return;
3202 
3203  caster->ToPlayer()->SetFarSight(apply ? m_target->GetGUID() : NULL);*/
3204 }
3205 
3206 void Aura::HandleAuraTrackCreatures(bool apply, bool /*Real*/)
3207 {
3208  if (m_target->GetTypeId() != TYPEID_PLAYER)
3209  return;
3210 
3211  if (apply)
3214 }
3215 
3216 void Aura::HandleAuraTrackResources(bool apply, bool /*Real*/)
3217 {
3218  if (m_target->GetTypeId() != TYPEID_PLAYER)
3219  return;
3220 
3221  if (apply)
3224 }
3225 
3226 void Aura::HandleAuraTrackStealthed(bool apply, bool /*Real*/)
3227 {
3228  if (m_target->GetTypeId() != TYPEID_PLAYER)
3229  return;
3230 
3231  if (apply)
3233  else
3234  {
3235  // do not remove unit flag if there are more than this auraEffect of that kind on unit
3237  return;
3238  }
3239 
3241 }
3242 
3243 void Aura::HandleAuraModScale(bool apply, bool /*Real*/)
3244 {
3245  float scale = m_target->GetObjectScale();
3246  ApplyPercentModFloatVar(scale, float(GetModifierValue()), apply);
3247  m_target->SetObjectScale(scale);
3248 }
3249 
3250 void Aura::HandleModPossess(bool apply, bool Real)
3251 {
3252  if (!Real)
3253  return;
3254 
3255  Unit* caster = GetCaster();
3256  if (caster && caster->GetTypeId() == TYPEID_UNIT)
3257  {
3258  HandleModCharm(apply, Real);
3259  return;
3260  }
3261 
3262  if (apply)
3263  {
3265  return;
3266 
3268  }
3269  else
3270  m_target->RemoveCharmedBy(caster);
3271 }
3272 
3273 void Aura::HandleModPossessPet(bool apply, bool Real)
3274 {
3275  if (!Real)
3276  return;
3277 
3278  Unit* caster = GetCaster();
3279  if (!caster || caster->GetTypeId() != TYPEID_PLAYER)
3280  return;
3281 
3282  if (m_target->GetTypeId() != TYPEID_UNIT || !m_target->IsPet())
3283  return;
3284 
3285  Pet* pet = m_target->ToPet();
3286 
3287  if (apply)
3288  {
3289  if (caster->ToPlayer()->GetPet() != pet)
3290  return;
3291 
3292  // Must clear current motion or pet leashes back to owner after a few yards
3293  // when under spell 'Eyes of the Beast'
3294  pet->GetMotionMaster()->Clear();
3295  pet->SetCharmedBy(caster, CHARM_TYPE_POSSESS);
3296  }
3297  else
3298  {
3299  pet->RemoveCharmedBy(caster);
3300 
3301  if (!pet->IsWithinDistInMap(caster, pet->GetMap()->GetVisibilityRange()))
3302  pet->Remove(PET_SAVE_NOT_IN_SLOT, true);
3303  else
3304  {
3305  // Reinitialize the pet bar and make the pet come back to the owner
3306  caster->ToPlayer()->PetSpellInitialize();
3307 
3308  // Follow owner only if not fighting or owner didn't click "stay" at new location
3309  // This may be confusing because pet bar shows "stay" when under the spell but it retains
3310  // the "follow" flag. Player MUST click "stay" while under the spell.
3311  if (!pet->GetVictim() && !pet->GetCharmInfo()->HasCommandState(COMMAND_STAY))
3312  {
3315  }
3316  }
3317  }
3318 }
3319 
3320 void Aura::HandleModCharm(bool apply, bool Real)
3321 {
3322  if (!Real)
3323  return;
3324 
3325  Unit* caster = GetCaster();
3326 
3327  if (apply)
3328  {
3330  return;
3331 
3333  }
3334  else
3335  m_target->RemoveCharmedBy(caster);
3336 }
3337 
3338 void Aura::HandleModConfuse(bool apply, bool Real)
3339 {
3340  if (!Real)
3341  return;
3342 
3344 }
3345 
3346 void Aura::HandleModFear(bool apply, bool Real)
3347 {
3348  if (!Real)
3349  return;
3350 
3352 }
3353 
3354 void Aura::HandleFeignDeath(bool apply, bool Real)
3355 {
3356  if (!Real)
3357  return;
3358 
3359  if (apply)
3360  {
3361  /*
3362  WorldPacket data(SMSG_FEIGN_DEATH_RESISTED, 9);
3363  data<<m_target->GetGUID();
3364  data<<uint8(0);
3365  m_target->SendMessageToSet(&data,true);
3366  */
3367 
3368  std::list<Unit*> targets;
3372  for (std::list<Unit*>::iterator iter = targets.begin(); iter != targets.end(); ++iter)
3373  {
3374  if (!(*iter)->HasUnitState(UNIT_STATE_CASTING))
3375  continue;
3376 
3378  {
3379  if ((*iter)->GetCurrentSpell(i)
3380  && (*iter)->GetCurrentSpell(i)->m_targets.getUnitTargetGUID() == m_target->GetGUID())
3381  (*iter)->InterruptSpell(CurrentSpellTypes(i), false);
3382  }
3383  }
3384  m_target->CombatStop();
3386 
3387  // prevent interrupt message
3392 
3393  m_target->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNK_29); // blizz like 2.0.x
3395  m_target->SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_DEAD); // blizz like 2.0.x
3397 
3398  if (Creature* creature = m_target->ToCreature())
3399  creature->SetReactState(REACT_PASSIVE);
3400  }
3401  else
3402  {
3403  /*
3404  WorldPacket data(SMSG_FEIGN_DEATH_RESISTED, 9);
3405  data<<m_target->GetGUID();
3406  data<<uint8(1);
3407  m_target->SendMessageToSet(&data,true);
3408  */
3409 
3410  m_target->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNK_29); // blizz like 2.0.x
3414 
3415  if (Creature* creature = m_target->ToCreature())
3416  creature->InitializeReactState();
3417  }
3418 }
3419 
3420 void Aura::HandleAuraModDisarm(bool apply, bool Real)
3421 {
3422  if (!Real)
3423  return;
3424 
3425  if (!apply && m_target->HasAuraType(SPELL_AURA_MOD_DISARM))
3426  return;
3427 
3428  // not sure for it's correctness
3429  if (apply)
3431  else
3433 
3434  if (m_target->GetTypeId() == TYPEID_PLAYER)
3435  {
3436  // main-hand attack speed already set to special value for feral form already and don't must change and reset at remove.
3437  if (m_target->ToPlayer()->IsInFeralForm())
3438  return;
3439 
3440  if (apply)
3442  else
3444  }
3445  else
3446  {
3447  // creature does not have equipment
3448  if (apply && !m_target->ToCreature()->GetCurrentEquipmentId())
3449  return;
3450  }
3451 
3453 }
3454 
3455 void Aura::HandleAuraModStun(bool apply, bool Real)
3456 {
3457  if (!Real)
3458  return;
3459 
3461 }
3462 
3463 void Aura::HandleModStealth(bool apply, bool Real)
3464 {
3466 
3467  if (apply)
3468  {
3469  // only at real aura add
3470  if (Real)
3471  {
3472  m_target->m_stealth.AddFlag(type);
3474 
3476  if (m_target->GetTypeId() == TYPEID_PLAYER)
3478 
3479  // for RACE_NIGHTELF stealth
3480  if (m_target->GetTypeId() == TYPEID_PLAYER && GetId() == 20580)
3481  m_target->CastSpell(m_target, 21009, true, NULL, this);
3482  }
3483  }
3484  else
3485  {
3486  // only at real aura remove
3487  if (Real)
3488  {
3489  // for RACE_NIGHTELF stealth
3490  if (m_target->GetTypeId() == TYPEID_PLAYER && GetId() == 20580)
3492 
3493  m_target->m_stealth.AddValue(type, -GetAmount());
3494 
3495  if (!m_target->HasAuraType(SPELL_AURA_MOD_STEALTH)) // if last SPELL_AURA_MOD_STEALTH
3496  {
3497  m_target->m_stealth.DelFlag(type);
3498 
3500  if (m_target->GetTypeId() == TYPEID_PLAYER)
3502  }
3503  }
3504  }
3505 
3506  // Master of Subtlety
3507  Unit::AuraList const& mDummyAuras = m_target->GetAurasByType(SPELL_AURA_DUMMY);
3508  for (Unit::AuraList::const_iterator i = mDummyAuras.begin(); i != mDummyAuras.end(); ++i)
3509  {
3510  if ((*i)->GetSpellProto()->SpellIconID == 2114 && Real)
3511  {
3512  if (apply)
3513  {
3514  int32 bp = (*i)->GetModifier()->m_amount;
3515  m_target->CastCustomSpell(m_target, 31665, &bp, NULL, NULL, true);
3516  }
3517  else
3518  m_target->CastSpell(m_target, 31666, true);
3519  break;
3520  }
3521  }
3522 
3523  // call functions which may have additional effects after chainging state of unit
3524  if (apply && Real)
3525  {
3526  // drop flag at stealth in bg
3528  }
3529 
3531 }
3532 
3533 void Aura::HandleModStealthLevel(bool apply, bool Real)
3534 {
3536 
3537  if (apply)
3539  else
3540  m_target->m_stealth.AddValue(type, -GetAmount());
3541 
3543 }
3544 
3545 void Aura::HandleModInvisibility(bool apply, bool Real)
3546 {
3548 
3549  if (apply)
3550  {
3551  if (Real && m_target->GetTypeId() == TYPEID_PLAYER)
3553 
3556  }
3557  else
3558  {
3560  {
3561  // if not have different invisibility auras.
3562  // remove glow vision
3563  if (m_target->GetTypeId() == TYPEID_PLAYER)
3565 
3567  }
3568  else
3569  {
3570  bool found = false;
3572  for (Unit::AuraList::const_iterator i = invisAuras.begin(); i != invisAuras.end(); ++i)
3573  {
3574  if (GetMiscValue() == (*i)->GetMiscValue())
3575  {
3576  found = true;
3577  break;
3578  }
3579  }
3580  if (!found)
3582  }
3583 
3585  }
3586 
3587  // call functions which may have additional effects after chainging state of unit
3588  if (apply && Real)
3589  m_target->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_UNATTACKABLE); // drop flag at invisibiliy in bg
3590 
3592 }
3593 
3595 {
3597 
3598  if (apply)
3599  {
3602  }
3603  else
3604  {
3607 
3609  }
3610 
3612 }
3613 
3615 {
3617 
3618  if (apply)
3619  {
3622  }
3623  else
3624  {
3627 
3629  }
3630 
3632 }
3633 
3634 void Aura::HandleAuraModRoot(bool apply, bool Real)
3635 {
3636  // only at real add/remove aura
3637  if (!Real)
3638  return;
3639 
3641 }
3642 
3643 void Aura::HandleAuraModSilence(bool apply, bool Real)
3644 {
3645  // only at real add/remove aura
3646  if (!Real)
3647  return;
3648 
3649  if (apply)
3650  {
3652 
3653  // call functions which may have additional effects after chainging state of unit
3654  // Stop cast only spells vs PreventionType == SPELL_PREVENTION_TYPE_SILENCE
3655  for (uint32 i = CURRENT_MELEE_SPELL; i < CURRENT_MAX_SPELL; ++i)
3656  if (Spell* spell = m_target->GetCurrentSpell(i))
3657  if (spell->m_spellInfo->PreventionType == SPELL_PREVENTION_TYPE_SILENCE)
3658  // Stop spells on prepare or casting state
3660  }
3661  else
3662  {
3663  // do not remove unit flag if there are more than this auraEffect of that kind on unit
3665  return;
3666 
3668  }
3669 }
3670 
3671 void Aura::HandleModThreat(bool apply, bool Real)
3672 {
3673  // only at real add/remove aura
3674  if (!Real)
3675  return;
3676 
3677  if (!m_target->IsAlive())
3678  return;
3679 
3680  Unit* caster = GetCaster();
3681 
3682  if (!caster || !caster->IsAlive())
3683  return;
3684 
3685  int level_diff = 0;
3686  int multiplier = 0;
3687  switch (GetId())
3688  {
3689  // Arcane Shroud
3690  case 26400:
3691  level_diff = m_target->getLevel() - 60;
3692  multiplier = 2;
3693  break;
3694  // The Eye of Diminution
3695  case 28862:
3696  level_diff = m_target->getLevel() - 60;
3697  multiplier = 1;
3698  break;
3699  }
3700  if (level_diff > 0)
3701  m_modifier.m_amount += multiplier * level_diff;
3702 
3703  if (m_target->GetTypeId() == TYPEID_PLAYER)
3704  for (int8 i = 0; i < MAX_SPELL_SCHOOL; i++)
3705  if (GetMiscValue() & int32(1 << i))
3707 
3708 }
3709 
3711 {
3712  // only at real add/remove aura
3713  if (!Real)
3714  return;
3715 
3716  if (!m_target->IsAlive() || m_target->GetTypeId() != TYPEID_PLAYER)
3717  return;
3718 
3719  Unit* caster = GetCaster();
3720 
3721  if (caster && caster->IsAlive())
3723 }
3724 
3725 void Aura::HandleModTaunt(bool apply, bool Real)
3726 {
3727  // only at real add/remove aura
3728  if (!Real)
3729  return;
3730 
3731  if (!m_target->IsAlive() || !m_target->CanHaveThreatList())
3732  return;
3733 
3734  Unit* caster = GetCaster();
3735 
3736  if (!caster || !caster->IsAlive())
3737  return;
3738 
3739  if (apply)
3740  m_target->TauntApply(caster);
3741  else
3742  {
3743  // When taunt aura fades out, mob will switch to previous target if current has less than 1.1 * secondthreat
3744  m_target->TauntFadeOut(caster);
3745  }
3746 }
3747 
3748 /*********************************************************/
3749 /*** MODIFY SPEED ***/
3750 /*********************************************************/
3751 void Aura::HandleAuraModIncreaseSpeed(bool /*apply*/, bool Real)
3752 {
3753  // all applied/removed only at real aura add/remove
3754  if (!Real)
3755  return;
3756 
3757  m_target->UpdateSpeed(MOVE_RUN, true);
3758 }
3759 
3761 {
3762  HandleAuraModIncreaseSpeed(apply, Real);
3763 }
3764 
3766 {
3767  // all applied/removed only at real aura add/remove
3768  if (!Real)
3769  return;
3770 
3771  // Enable Fly mode for flying mounts
3773  {
3774  if (m_target->SetCanFly(apply))
3775  if (!apply && !m_target->IsLevitating())
3777 
3778  if (!apply && m_target->GetTypeId() == TYPEID_UNIT && !m_target->IsLevitating())
3780 
3781  // Players on flying mounts must be immune to polymorph
3782  if (m_target->GetTypeId() == TYPEID_PLAYER)
3784 
3785  // Dragonmaw Illusion (overwrite mount model, mounted aura already applied)
3786  if (apply && m_target->HasAura(42016, 0) && m_target->GetMountID())
3788  }
3789 
3791 }
3792 
3793 void Aura::HandleAuraModIncreaseSwimSpeed(bool /*apply*/, bool Real)
3794 {
3795  // all applied/removed only at real aura add/remove
3796  if (!Real)
3797  return;
3798 
3799  m_target->UpdateSpeed(MOVE_SWIM, true);
3800 }
3801 
3803 {
3804  // all applied/removed only at real aura add/remove
3805  if (!Real)
3806  return;
3807 
3810  switch (m_spellProto->Id)
3811  {
3812  case 12323: // Piercing Howl
3813  if (apply)
3815  break;
3816  }
3817 
3818  m_target->UpdateSpeed(MOVE_RUN, true);
3819  m_target->UpdateSpeed(MOVE_SWIM, true);
3824 }
3825 
3826 void Aura::HandleAuraModUseNormalSpeed(bool /*apply*/, bool Real)
3827 {
3828  // all applied/removed only at real aura add/remove
3829  if (!Real)
3830  return;
3831 
3832  m_target->UpdateSpeed(MOVE_RUN, true);
3833  m_target->UpdateSpeed(MOVE_SWIM, true);
3835 }
3836 
3837 /*********************************************************/
3838 /*** IMMUNITY ***/
3839 /*********************************************************/
3840 
3841 void Aura::HandleModMechanicImmunity(bool apply, bool /*Real*/)
3842 {
3843  uint32 mechanic = 1 << m_modifier.m_miscvalue;
3844 
3845  //immune movement impairment and loss of control
3848 
3849  if (apply && GetSpellProto()->AttributesEx & SPELL_ATTR1_DISPEL_AURAS_ON_IMMUNITY)
3850  {
3851  Unit::AuraMap& Auras = m_target->GetAuras();
3852  for (Unit::AuraMap::iterator iter = Auras.begin(), next; iter != Auras.end(); iter = next)
3853  {
3854  next = iter;
3855  ++next;
3856  SpellEntry const* spell = iter->second->GetSpellProto();
3857  if (!(spell->Attributes & SPELL_ATTR0_UNAFFECTED_BY_INVULNERABILITY) // spells unaffected by invulnerability
3858  && !iter->second->IsPositive() // only remove negative spells
3859  && spell->Id != GetId())
3860  {
3861  //check for mechanic mask
3862  if (GetSpellMechanicMask(spell, iter->second->GetEffIndex()) & mechanic)
3863  {
3865  if (Auras.empty())
3866  break;
3867  else
3868  next = Auras.begin();
3869  }
3870  }
3871  }
3872  }
3873 
3875 
3876  // special cases
3877  switch (m_modifier.m_miscvalue)
3878  {
3881  break;
3882  case MECHANIC_SHIELD:
3884  break;
3885  }
3886 
3887  // Bestial Wrath
3888  if (GetSpellProto()->SpellFamilyName == SPELLFAMILY_HUNTER && GetSpellProto()->Id == 19574)
3889  {
3890  // The Beast Within cast on owner if talent present
3891  if (Unit* owner = m_target->GetOwner())
3892  {
3893  // Search talent
3894  Unit::AuraList const& m_dummyAuras = owner->GetAurasByType(SPELL_AURA_DUMMY);
3895  for (Unit::AuraList::const_iterator i = m_dummyAuras.begin(); i != m_dummyAuras.end(); ++i)
3896  {
3897  if ((*i)->GetSpellProto()->SpellIconID == 2229)
3898  {
3899  if (apply)
3900  owner->CastSpell(owner, 34471, true, 0, this);
3901  else
3902  owner->RemoveAurasDueToSpell(34471);
3903  break;
3904  }
3905  }
3906  }
3907  }
3908 
3909  // The Beast Within and Bestial Wrath - immunity
3910  if (GetId() == 19574 || GetId() == 34471)
3911  {
3912  if (apply)
3913  {
3914  m_target->CastSpell(m_target, 24395, true);
3915  m_target->CastSpell(m_target, 24396, true);
3916  m_target->CastSpell(m_target, 24397, true);
3917  m_target->CastSpell(m_target, 26592, true);
3918  }
3919  else
3920  {
3925  }
3926  }
3927 }
3928 
3930 {
3931  if (!Real)
3932  return;
3933 
3935 
3936  // when removing flag aura, handle flag drop
3937  Player* player = m_target->ToPlayer();
3938  if (!apply && player && (GetSpellProto()->AuraInterruptFlags & AURA_INTERRUPT_FLAG_UNATTACKABLE))
3939  {
3940  if (player->InBattleground())
3941  {
3942  if (Battleground* bg = player->GetBattleground())
3943  bg->EventPlayerDroppedFlag(player);
3944  }
3945  else
3946  sOutdoorPvPMgr.HandleDropFlag(player, GetSpellProto()->Id);
3947  }
3948 }
3949 
3951 {
3952  if (!Real)
3953  return;
3954 
3955  if (apply && GetSpellProto()->AttributesEx & SPELL_ATTR1_DISPEL_AURAS_ON_IMMUNITY)
3956  {
3958  for (Unit::AuraList::const_iterator itr = auraList.begin(); itr != auraList.end();)
3959  {
3960  if (auraList.front() != this) // skip itself aura (it already added)
3961  {
3962  m_target->RemoveAurasDueToSpell(auraList.front()->GetId());
3963  itr = auraList.begin();
3964  }
3965  else
3966  ++itr;
3967  }
3968  }
3969 
3971 }
3972 
3974 {
3977 
3979 
3980  if (Real && apply && GetSpellProto()->AttributesEx & SPELL_ATTR1_DISPEL_AURAS_ON_IMMUNITY)
3981  {
3982  if (IsPositiveSpell(GetId())) //Only positive immunity removes auras
3983  {
3984  uint32 school_mask = m_modifier.m_miscvalue;
3985  Unit::AuraMap& Auras = m_target->GetAuras();
3986  for (Unit::AuraMap::iterator iter = Auras.begin(), next; iter != Auras.end(); iter = next)
3987  {
3988  next = iter;
3989  ++next;
3990  SpellEntry const* spell = iter->second->GetSpellProto();
3991  if ((GetSpellSchoolMask(spell) & school_mask)//Check for school mask
3992  && !(spell->Attributes & SPELL_ATTR0_UNAFFECTED_BY_INVULNERABILITY) //Spells unaffected by invulnerability
3993  && !iter->second->IsPositive() //Don't remove positive spells
3994  && spell->Id != GetId()) //Don't remove self
3995  {
3997  if (Auras.empty())
3998  break;
3999  else
4000  next = Auras.begin();
4001  }
4002  }
4003  }
4004  }
4005  if (Real && GetSpellProto()->Mechanic == MECHANIC_BANISH)
4006  {
4007  if (apply)
4009  else
4011  }
4012 }
4013 
4014 void Aura::HandleAuraModDmgImmunity(bool apply, bool /*Real*/)
4015 {
4017 }
4018 
4020 {
4021  // all applied/removed only at real aura add/remove
4022  if (!Real)
4023  return;
4024 
4026 
4027  if (GetId() == 20594) //stoneform
4028  {
4029  //handle diseases
4031 
4032  //remove bleed auras
4033  const uint32 mechanic = 1 << MECHANIC_BLEED;
4034 
4035  if (apply)
4036  {
4037  Unit::AuraMap& Auras = m_target->GetAuras();
4038  for (Unit::AuraMap::iterator iter = Auras.begin(); iter != Auras.end(); ++iter)
4039  {
4040  SpellEntry const* spell = iter->second->GetSpellProto();
4041  if (!(spell->Attributes & SPELL_ATTR0_UNAFFECTED_BY_INVULNERABILITY) // spells unaffected by invulnerability
4042  && !iter->second->IsPositive() // only remove negative spells
4043  && spell->Id != GetId()
4044  && (GetSpellMechanicMask(spell, iter->second->GetEffIndex()) & mechanic))
4045  {
4047  iter = Auras.begin();
4048  }
4049  }
4050  }
4051 
4053  }
4054 }
4055 
4057 {
4058  if (!Real)
4059  return;
4060 
4061  if (apply)
4062  {
4063  // some spell have charges by functionality not have its in spell data
4064  switch (GetId())
4065  {
4066  case 28200: // Ascendance (Talisman of Ascendance trinket)
4067  m_procCharges = 6;
4069  break;
4070  default:
4071  break;
4072  }
4073  }
4074 }
4075 
4076 void Aura::HandleAuraModStalked(bool apply, bool /*Real*/)
4077 {
4078  // used by spells: Hunter's Mark, Mind Vision, Syndicate Tracker (MURP) DND
4079  if (apply)
4081  else
4082  {
4083  // do not remove unit flag if there are more than this auraEffect of that kind on unit
4084  if (!m_target->HasAuraType(GetAuraType()))
4086  }
4087 
4088  // call functions which may have additional effects after chainging state of unit
4090 }
4091 
4092 /*********************************************************/
4093 /*** PERIODIC ***/
4094 /*********************************************************/
4095 
4096 void Aura::HandlePeriodicTriggerSpell(bool apply, bool /*Real*/)
4097 {
4098  if (m_periodicTimer <= 0)
4100 
4101  m_isPeriodic = apply;
4102 
4103  // Curse of the Plaguebringer
4104  if (!apply && m_spellProto->Id == 29213 && m_removeMode != AURA_REMOVE_BY_DISPEL)
4105  {
4106  // Cast Wrath of the Plaguebringer if not dispelled
4107  m_target->CastSpell(m_target, 29214, true, 0, this);
4108  }
4109 
4110  // Wrath of the Astromancer
4111  if (!apply && m_spellProto->Id == 42783)
4112  m_target->CastSpell(m_target, 42787, true, 0, this);
4113 }
4114 
4116 {
4117  if (m_periodicTimer <= 0)
4119 
4120  m_isPeriodic = apply;
4121 }
4122 
4123 void Aura::HandlePeriodicEnergize(bool apply, bool /*Real*/)
4124 {
4125  if (m_periodicTimer <= 0)
4127 
4128  m_isPeriodic = apply;
4129 
4130  if (GetId() == 5229)
4131  m_target->UpdateArmor();
4132 
4133 }
4134 
4136 {
4137  // spells required only Real aura add/remove
4138  if (!Real)
4139  return;
4140 
4141  SpellEntry const* spell = GetSpellProto();
4142  switch (spell->SpellFamilyName)
4143  {
4144  case SPELLFAMILY_ROGUE:
4145  {
4146  // Master of Subtlety
4147  if (spell->Id == 31666 && !apply && Real)
4148  {
4150  break;
4151  }
4152  break;
4153  }
4154  case SPELLFAMILY_HUNTER:
4155  {
4156  // Aspect of the Viper
4157  if (spell->SpellFamilyFlags & 0x0004000000000000LL)
4158  {
4159  // Update regen on remove
4160  if (!apply && m_target->GetTypeId() == TYPEID_PLAYER)
4162  break;
4163  }
4164  break;
4165  }
4166  }
4167 
4168  m_isPeriodic = apply;
4169 }
4170 
4171 void Aura::HandlePeriodicHeal(bool apply, bool Real)
4172 {
4173  if (m_periodicTimer <= 0)
4175 
4176  m_isPeriodic = apply;
4177 
4178  // only at real apply
4179  if (Real && apply && GetSpellProto()->Mechanic == MECHANIC_BANDAGE)
4180  {
4181  // provided m_target as original caster to prevent apply aura caster selection for this negative buff
4182  m_target->CastSpell(m_target, 11196, true, NULL, this, m_target->GetGUID());
4183  }
4184 
4185  // For prevent double apply bonuses
4186  bool loading = (m_target->GetTypeId() == TYPEID_PLAYER && m_target->ToPlayer()->GetSession()->PlayerLoading());
4187 
4188  if (!loading && apply)
4189  {
4190  switch (m_spellProto->SpellFamilyName)
4191  {
4192  case SPELLFAMILY_DRUID:
4193  {
4194  // Rejuvenation
4195  if (m_spellProto->SpellFamilyFlags & 0x0000000000000010LL)
4196  {
4197  if (Unit* caster = GetCaster())
4198  {
4199  Unit::AuraList const& classScripts = caster->GetAurasByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS);
4200  for (Unit::AuraList::const_iterator k = classScripts.begin(); k != classScripts.end(); ++k)
4201  {
4203  switch ((*k)->GetModifier()->m_miscvalue)
4204  {
4205  case 4953: // Increased Rejuvenation Healing - Harold's Rejuvenating Broach Aura
4206  case 4415: // Increased Rejuvenation Healing - Idol of Rejuvenation Aura
4207  {
4208  m_modifier.m_amount += (*k)->GetModifier()->m_amount / tickcount;
4209  break;
4210  }
4211  }
4212  }
4213  }
4214  }
4215  }
4216  }
4217  }
4218 }
4219 
4220 void Aura::HandlePeriodicDamage(bool apply, bool Real)
4221 {
4222  // spells required only Real aura add/remove
4223  if (!Real)
4224  return;
4225 
4226  if (m_periodicTimer <= 0)
4228 
4229  m_isPeriodic = apply;
4230 
4231  // For prevent double apply bonuses
4232  bool loading = (m_target->GetTypeId() == TYPEID_PLAYER && m_target->ToPlayer()->GetSession()->PlayerLoading());
4233 
4234  Unit* caster = GetCaster();
4235 
4236  switch (m_spellProto->SpellFamilyName)
4237  {
4238  case SPELLFAMILY_GENERIC:
4239  {
4240  // Pounce Bleed
4241  if (m_spellProto->SpellIconID == 147 && m_spellProto->SpellVisual == 0)
4242  {
4243  // $AP*0.18/6 bonus per tick
4244  if (apply && !loading && caster)
4246  return;
4247  }
4248  break;
4249  }
4250  case SPELLFAMILY_WARRIOR:
4251  {
4252  // Rend
4253  if (m_spellProto->SpellFamilyFlags & 0x0000000000000020LL)
4254  {
4255  // 0.00743*(($MWB+$mwb)/2+$AP/14*$MWS) bonus per tick
4256  if (apply && !loading && caster)
4257  {
4258  float ap = caster->GetTotalAttackPowerValue(BASE_ATTACK);
4259  int32 mws = caster->GetAttackTime(BASE_ATTACK);
4260  float mwb_min = caster->GetWeaponDamageRange(BASE_ATTACK, MINDAMAGE);
4261  float mwb_max = caster->GetWeaponDamageRange(BASE_ATTACK, MAXDAMAGE);
4262  // WARNING! in 3.0 multiplier 0.00743f change to 0.6
4263  m_modifier.m_amount += int32(((mwb_min + mwb_max) / 2 + ap * mws / 14000) * 0.00743f);
4264  }
4265  return;
4266  }
4267  break;
4268  }
4269  case SPELLFAMILY_DRUID:
4270  {
4271  // Rake
4272  if (m_spellProto->SpellFamilyFlags & 0x0000000000001000LL)
4273  {
4274  // $AP*0.06/3 bonus per tick
4275  if (apply && !loading && caster)
4277  return;
4278  }
4279  // Lacerate
4280  if (m_spellProto->SpellFamilyFlags & 0x000000010000000000LL)
4281  {
4282  // $AP*0.05/5 bonus per tick
4283  if (apply && !loading && caster)
4285  return;
4286  }
4287  // Rip
4288  if (m_spellProto->SpellFamilyFlags & 0x000000000000800000LL)
4289  {
4290  // $AP * min(0.06*$cp, 0.24)/6 [Yes, there is no difference, whether 4 or 5 CPs are being used]
4291  if (apply && !loading && caster && caster->GetTypeId() == TYPEID_PLAYER)
4292  {
4293  uint8 cp = caster->ToPlayer()->GetComboPoints();
4294 
4295  // Idol of Feral Shadows. Cant be handled as SpellMod in SpellAura:Dummy due its dependency from CPs
4296  Unit::AuraList const& dummyAuras = caster->GetAurasByType(SPELL_AURA_DUMMY);
4297  for (Unit::AuraList::const_iterator itr = dummyAuras.begin(); itr != dummyAuras.end(); ++itr)
4298  {
4299  if ((*itr)->GetId() == 34241)
4300  {
4301  m_modifier.m_amount += cp * (*itr)->GetModifier()->m_amount;
4302  break;
4303  }
4304  }
4305 
4306  if (cp > 4) cp = 4;
4308  }
4309  return;
4310  }
4311  break;
4312  }
4313  case SPELLFAMILY_ROGUE:
4314  {
4315  // Deadly poison aura state
4316  if ((m_spellProto->SpellFamilyFlags & 0x10000) && m_spellProto->SpellVisual == 5100)
4317  {
4318  if (apply)
4320  else
4321  {
4322  // current aura already removed, search present of another
4323  bool found = false;
4325  for (Unit::AuraList::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
4326  {
4327  SpellEntry const* itr_spell = (*itr)->GetSpellProto();
4328  if (itr_spell && itr_spell->SpellFamilyName == SPELLFAMILY_ROGUE && (itr_spell->SpellFamilyFlags & 0x10000) && itr_spell->SpellVisual == 5100)
4329  {
4330  found = true;
4331  break;
4332  }
4333  }
4334  // this has been last deadly poison aura
4335  if (!found)
4337  }
4338  return;
4339  }
4340  // Rupture
4341  if (m_spellProto->SpellFamilyFlags & 0x000000000000100000LL)
4342  {
4343  // Dmg/tick = $AP*min(0.01*$cp, 0.03) [Like Rip: only the first three CP increase the contribution from AP]
4344  if (apply && !loading && caster && caster->GetTypeId() == TYPEID_PLAYER)
4345  {
4346  uint8 cp = caster->ToPlayer()->GetComboPoints();
4347  if (cp > 3) cp = 3;
4349  }
4350  return;
4351  }
4352  // Garrote
4353  if (m_spellProto->SpellFamilyFlags & 0x000000000000000100LL)
4354  {
4355  // $AP*0.18/6 bonus per tick
4356  if (apply && !loading && caster)
4358  return;
4359  }
4360  break;
4361  }
4362  case SPELLFAMILY_HUNTER:
4363  {
4364  // Serpent Sting
4365  if (m_spellProto->SpellFamilyFlags & 0x0000000000004000LL)
4366  {
4367  // $RAP*0.1/5 bonus per tick
4368  if (apply && !loading && caster)
4370  return;
4371  }
4372  // Immolation Trap
4373  if (m_spellProto->SpellFamilyFlags & 0x0000000000000004LL && m_spellProto->SpellIconID == 678)
4374  {
4375  // $RAP*0.1/5 bonus per tick
4376  if (apply && !loading && caster)
4378  return;
4379  }
4380  break;
4381  }
4382  case SPELLFAMILY_PALADIN:
4383  {
4384  // Consecration
4385  if (m_spellProto->SpellFamilyFlags & 0x0000000000000020LL)
4386  {
4387  if (apply && !loading)
4388  {
4389  if (Unit* caster = GetCaster())
4390  {
4391  Unit::AuraList const& classScripts = caster->GetAurasByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS);
4392  for (Unit::AuraList::const_iterator k = classScripts.begin(); k != classScripts.end(); ++k)
4393  {
4395  switch ((*k)->GetModifier()->m_miscvalue)
4396  {
4397  case 5147: // Improved Consecration - Libram of the Eternal Rest
4398  {
4399  m_modifier.m_amount += (*k)->GetModifier()->m_amount / tickcount;
4400  break;
4401  }
4402  }
4403  }
4404  }
4405  }
4406  return;
4407  }
4408  break;
4409  }
4410  default:
4411  break;
4412  }
4413 }
4414 
4415 void Aura::HandlePeriodicDamagePCT(bool apply, bool /*Real*/)
4416 {
4417  if (m_periodicTimer <= 0)
4419 
4420  m_isPeriodic = apply;
4421 }
4422 
4423 void Aura::HandlePeriodicLeech(bool apply, bool /*Real*/)
4424 {
4425  if (m_periodicTimer <= 0)
4427 
4428  m_isPeriodic = apply;
4429 }
4430 
4431 void Aura::HandlePeriodicManaLeech(bool apply, bool /*Real*/)
4432 {
4433  if (m_periodicTimer <= 0)
4435 
4436  m_isPeriodic = apply;
4437 }
4438 
4439 /*********************************************************/
4440 /*** MODIFY STATS ***/
4441 /*********************************************************/
4442 
4443 /********************************/
4444 /*** RESISTANCE ***/
4445 /********************************/
4446 
4448 {
4449  for (int8 x = SPELL_SCHOOL_NORMAL; x < MAX_SPELL_SCHOOL; x++)
4450  {
4451  if (m_modifier.m_miscvalue & int32(1 << x))
4452  {
4454  if (m_target->GetTypeId() == TYPEID_PLAYER)
4456  }
4457  }
4458 }
4459 
4460 void Aura::HandleAuraModResistance(bool apply, bool /*Real*/)
4461 {
4462  for (int8 x = SPELL_SCHOOL_NORMAL; x < MAX_SPELL_SCHOOL; x++)
4463  {
4464  if (m_modifier.m_miscvalue & int32(1 << x))
4465  {
4467  if (m_target->GetTypeId() == TYPEID_PLAYER || m_target->IsPet())
4469  }
4470  }
4471 
4472  // Faerie Fire (druid versions)
4473  if ((m_spellProto->SpellIconID == 109 &&
4475  m_spellProto->SpellFamilyFlags & 0x0000000000000400LL)
4476  || m_spellProto->Id == 35325)
4478 }
4479 
4481 {
4482  // only players have base stats
4483  if (m_target->GetTypeId() != TYPEID_PLAYER)
4484  {
4485  //pets only have base armor
4488  }
4489  else
4490  {
4491  for (int8 x = SPELL_SCHOOL_NORMAL; x < MAX_SPELL_SCHOOL; x++)
4492  {
4493  if (m_modifier.m_miscvalue & int32(1 << x))
4495  }
4496  }
4497 }
4498 
4499 void Aura::HandleModResistancePercent(bool apply, bool /*Real*/)
4500 {
4501  for (int8 i = SPELL_SCHOOL_NORMAL; i < MAX_SPELL_SCHOOL; i++)
4502  {
4503  if (m_modifier.m_miscvalue & int32(1 << i))
4504  {
4506  if (m_target->GetTypeId() == TYPEID_PLAYER || m_target->IsPet())
4507  {
4510  }
4511  }
4512  }
4513 }
4514 
4515 void Aura::HandleModBaseResistance(bool apply, bool /*Real*/)
4516 {
4517  // only players have base stats
4518  if (m_target->GetTypeId() != TYPEID_PLAYER)
4519  {
4520  //only pets have base stats
4523  }
4524  else
4525  {
4526  for (int i = SPELL_SCHOOL_NORMAL; i < MAX_SPELL_SCHOOL; i++)
4527  if (m_modifier.m_miscvalue & (1 << i))
4529  }
4530 }
4531 
4532 /********************************/
4533 /*** STAT ***/
4534 /********************************/
4535 
4536 void Aura::HandleAuraModStat(bool apply, bool /*Real*/)
4537 {
4538  if (m_modifier.m_miscvalue < -2 || m_modifier.m_miscvalue > 4)
4539  {
4540  sLog.outError("WARNING: Spell %u effect %u has unsupported misc value (%i) for SPELL_AURA_MOD_STAT ", GetId(), GetEffIndex(), m_modifier.m_miscvalue);
4541  return;
4542  }
4543 
4544  if (apply && GetId() == 20007) // Crusader enchant proc: Holy Strength
4545  {
4546  uint32 lvldiff = m_target->getLevel() - 60;
4547  uint32 diff = lvldiff > 0 ? lvldiff * 4 : 0;
4549  }
4550 
4551  for (int32 i = STAT_STRENGTH; i < MAX_STATS; i++)
4552  {
4553  // -1 or -2 is all stats (misc < -2 checked in function beginning)
4554  if (m_modifier.m_miscvalue < 0 || m_modifier.m_miscvalue == i)
4555  {
4556  //m_target->ApplyStatMod(Stats(i), m_modifier.m_amount,apply);
4558  if (m_target->GetTypeId() == TYPEID_PLAYER || m_target->IsPet())
4559  m_target->ApplyStatBuffMod(Stats(i), (float)GetModifierValue(), apply);
4560  }
4561  }
4562 }
4563 
4564 void Aura::HandleModPercentStat(bool apply, bool /*Real*/)
4565 {
4566  if (m_modifier.m_miscvalue < -1 || m_modifier.m_miscvalue > 4)
4567  {
4568  sLog.outError("WARNING: Misc Value for SPELL_AURA_MOD_PERCENT_STAT not valid");
4569  return;
4570  }
4571 
4572  // only players have base stats
4573  if (m_target->GetTypeId() != TYPEID_PLAYER)
4574  return;
4575 
4576  for (int32 i = STAT_STRENGTH; i < MAX_STATS; ++i)
4577  {
4578  if (m_modifier.m_miscvalue == i || m_modifier.m_miscvalue == -1)
4580  }
4581 }
4582 
4583 void Aura::HandleModSpellDamagePercentFromStat(bool /*apply*/, bool /*Real*/)
4584 {
4585  if (m_target->GetTypeId() != TYPEID_PLAYER)
4586  return;
4587 
4588  // Magic damage modifiers implemented in Unit::SpellDamageBonus
4589  // This information for client side use only
4590  // Recalculate bonus
4592 }
4593 
4594 void Aura::HandleModSpellHealingPercentFromStat(bool /*apply*/, bool /*Real*/)
4595 {
4596  if (m_target->GetTypeId() != TYPEID_PLAYER)
4597  return;
4598 
4599  // Recalculate bonus
4601 }
4602 
4604 {
4605  if (!Real || !apply)
4606  return;
4607 
4608  if (GetId() == 33206)
4609  m_target->CastSpell(m_target, 44416, true, NULL, this, GetCasterGUID());
4610 }
4611 
4612 void Aura::HandleModSpellDamagePercentFromAttackPower(bool /*apply*/, bool /*Real*/)
4613 {
4614  if (m_target->GetTypeId() != TYPEID_PLAYER)
4615  return;
4616 
4617  // Magic damage modifiers implemented in Unit::SpellDamageBonus
4618  // This information for client side use only
4619  // Recalculate bonus
4621 }
4622 
4623 void Aura::HandleModSpellHealingPercentFromAttackPower(bool /*apply*/, bool /*Real*/)
4624 {
4625  if (m_target->GetTypeId() != TYPEID_PLAYER)
4626  return;
4627 
4628  // Recalculate bonus
4630 }
4631 
4632 void Aura::HandleModHealingDone(bool /*apply*/, bool /*Real*/)
4633 {
4634  if (m_target->GetTypeId() != TYPEID_PLAYER)
4635  return;
4636  // implemented in Unit::SpellHealingBonus
4637  // this information is for client side only
4639 }
4640 
4641 void Aura::HandleModTotalPercentStat(bool apply, bool /*Real*/)
4642 {
4643  if (m_modifier.m_miscvalue < -1 || m_modifier.m_miscvalue > 4)
4644  {
4645  sLog.outError("WARNING: Misc Value for SPELL_AURA_MOD_PERCENT_STAT not valid");
4646  return;
4647  }
4648 
4649  // save current health state
4650  float healthPct = m_target->GetHealthPct();
4651  bool alive = m_target->IsAlive();
4652 
4653  for (int32 i = STAT_STRENGTH; i < MAX_STATS; ++i)
4654  {
4655  if (m_modifier.m_miscvalue == i || m_modifier.m_miscvalue == -1)
4656  {
4658  if (m_target->GetTypeId() == TYPEID_PLAYER || m_target->IsPet())
4660  }
4661  }
4662 
4663  //recalculate current HP/MP after applying aura modifications (only for spells with 0x10 flag)
4665  m_target->SetHealth(std::max<uint32>(uint32(healthPct * m_target->GetMaxHealth() * 0.01f), (alive ? 1 : 0)));
4666 }
4667 
4668 void Aura::HandleAuraModResistenceOfStatPercent(bool /*apply*/, bool /*Real*/)
4669 {
4670  if (