OregonCore  revision 3611e8a-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 "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::HandleNULL //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  m_target->Dismount();
2585 }
2586 
2587 void Aura::HandleAuraWaterWalk(bool apply, bool Real)
2588 {
2589  // only at real add/remove aura
2590  if (!Real)
2591  return;
2592 
2593  if (!apply)
2594  {
2595  // do not remove unit flag if there are more than this auraEffect of that kind on unit
2597  return;
2598  }
2599 
2600  m_target->SetWaterWalking(apply);
2601 }
2602 
2603 void Aura::HandleAuraFeatherFall(bool apply, bool Real)
2604 {
2605  // only at real add/remove aura
2606  if (!Real)
2607  return;
2608 
2609  if (!apply)
2610  {
2611  // do not remove unit flag if there are more than this auraEffect of that kind on unit
2613  return;
2614  }
2615 
2616  m_target->SetFeatherFall(apply);
2617 
2618  // start fall from current height
2619  if (!apply && m_target->GetTypeId() == TYPEID_PLAYER)
2620  ((Player*)m_target)->SetFallInformation(0, m_target->GetPositionZ());
2621 }
2622 
2623 void Aura::HandleAuraHover(bool apply, bool Real)
2624 {
2625  // only at real add/remove aura
2626  if (!Real)
2627  return;
2628 
2629  if (!apply)
2630  {
2631  // do not remove unit flag if there are more than this auraEffect of that kind on unit
2633  return;
2634  }
2635 
2636  m_target->SetHover(apply);
2637 }
2638 
2639 void Aura::HandleWaterBreathing(bool /*apply*/, bool /*Real*/)
2640 {
2641  // update timers in client
2642  if (m_target->GetTypeId() == TYPEID_PLAYER)
2644 }
2645 
2647 {
2648  if (!Real)
2649  return;
2650 
2651  uint32 modelid = 0;
2652  Powers PowerType = POWER_MANA;
2654 
2655  switch (form)
2656  {
2657  case FORM_CAT:
2659  modelid = 892;
2660  else
2661  modelid = 8571;
2662  PowerType = POWER_ENERGY;
2663  break;
2664  case FORM_TRAVEL:
2665  modelid = 918;
2666  break;
2667  case FORM_AQUA:
2669  modelid = 2428;
2670  else
2671  modelid = 2428;
2672  break;
2673  case FORM_BEAR:
2675  modelid = 2281;
2676  else
2677  modelid = 2289;
2678  PowerType = POWER_RAGE;
2679  break;
2680  case FORM_DIREBEAR:
2682  modelid = 2281;
2683  else
2684  modelid = 2289;
2685  PowerType = POWER_RAGE;
2686  break;
2687  case FORM_FLIGHT:
2689  modelid = 20857;
2690  else
2691  modelid = 20872;
2692  break;
2693  case FORM_MOONKIN:
2695  modelid = 15374;
2696  else
2697  modelid = 15375;
2698  break;
2699  case FORM_FLIGHT_EPIC:
2701  modelid = 21243;
2702  else
2703  modelid = 21244;
2704  break;
2705  case FORM_BATTLESTANCE:
2706  case FORM_BERSERKERSTANCE:
2707  case FORM_DEFENSIVESTANCE:
2708  PowerType = POWER_RAGE;
2709  break;
2710  default:
2711  SpellShapeshiftEntry const* formEntry = sSpellShapeshiftStore.LookupEntry(form);
2712  if (formEntry && formEntry->modelID_A)
2713  modelid = formEntry->modelID_A;
2714  }
2715 
2716  // remove polymorph before changing display id to keep new display id
2717  switch (form)
2718  {
2719  case FORM_CAT:
2720  case FORM_TREE:
2721  case FORM_TRAVEL:
2722  case FORM_AQUA:
2723  case FORM_BEAR:
2724  case FORM_DIREBEAR:
2725  case FORM_FLIGHT_EPIC:
2726  case FORM_FLIGHT:
2727  case FORM_MOONKIN:
2728  {
2729  // remove movement affects
2731 
2732  // and polymorphic affects
2733  if (m_target->IsPolymorphed())
2735  }
2736  case FORM_GHOSTWOLF:
2737  {
2738  // remove water walk aura. @todo there is probably better way to do this
2740  break;
2741  }
2742  default:
2743  break;
2744  }
2745 
2746  if (apply)
2747  {
2748  // remove other shapeshift before applying a new one
2751 
2753  // force update as too quick shapeshifting and back
2754  // causes the value to stay the same serverside
2755  // causes issues clientside (player gets stuck)
2757 
2758  if (modelid > 0)
2759  m_target->SetDisplayId(modelid);
2760 
2761  if (PowerType != POWER_MANA)
2762  {
2763  // reset power to default values only at power change
2764  if (m_target->getPowerType() != PowerType)
2765  m_target->setPowerType(PowerType);
2766 
2767  switch (form)
2768  {
2769  case FORM_CAT:
2770  case FORM_BEAR:
2771  case FORM_DIREBEAR:
2772  {
2773  // get furor proc chance
2774  uint32 FurorChance = 0;
2776  for (Unit::AuraList::const_iterator i = mDummy.begin(); i != mDummy.end(); ++i)
2777  {
2778  if ((*i)->GetSpellProto()->SpellIconID == 238)
2779  {
2780  FurorChance = (*i)->GetModifier()->m_amount;
2781  break;
2782  }
2783  }
2784 
2786  {
2788  if (urand(1, 100) <= FurorChance)
2789  m_target->CastSpell(m_target, 17099, true, NULL, this);
2790  }
2791  else
2792  {
2794  if (urand(1, 100) <= FurorChance)
2795  m_target->CastSpell(m_target, 17057, true, NULL, this);
2796  }
2797  break;
2798  }
2799  case FORM_BATTLESTANCE:
2800  case FORM_DEFENSIVESTANCE:
2801  case FORM_BERSERKERSTANCE:
2802  {
2803  uint32 Rage_val = 0;
2804  // Stance mastery + Tactical mastery (both passive, and last have aura only in defense stance, but need apply at any stance switch)
2805  if (m_target->GetTypeId() == TYPEID_PLAYER)
2806  {
2807  PlayerSpellMap const& sp_list = m_target->ToPlayer()->GetSpellMap();
2808  for (PlayerSpellMap::const_iterator itr = sp_list.begin(); itr != sp_list.end(); ++itr)
2809  {
2810  if (itr->second.state == PLAYERSPELL_REMOVED) continue;
2811  SpellEntry const* spellInfo = sSpellStore.LookupEntry(itr->first);
2812  if (spellInfo && spellInfo->SpellFamilyName == SPELLFAMILY_WARRIOR && spellInfo->SpellIconID == 139)
2813  Rage_val += m_target->CalculateSpellDamage(spellInfo, 0, spellInfo->EffectBasePoints[0], m_target) * 10;
2814  }
2815  }
2816 
2817  if (m_target->GetPower(POWER_RAGE) > Rage_val)
2818  m_target->SetPower(POWER_RAGE, Rage_val);
2819  break;
2820  }
2821  default:
2822  break;
2823  }
2824  }
2825 
2827  m_target->m_ShapeShiftModelId = modelid;
2828  m_target->m_form = form;
2829  }
2830  else
2831  {
2832  if (modelid > 0)
2835  if (m_target->getClass() == CLASS_DRUID)
2839 
2840  switch (form)
2841  {
2842  // Nordrassil Harness - bonus
2843  case FORM_BEAR:
2844  case FORM_DIREBEAR:
2845  case FORM_CAT:
2846  if (Aura* dummy = m_target->GetDummyAura(37315))
2847  m_target->CastSpell(m_target, 37316, true, NULL, dummy);
2848  break;
2849  // Nordrassil Regalia - bonus
2850  case FORM_MOONKIN:
2851  if (Aura* dummy = m_target->GetDummyAura(37324))
2852  m_target->CastSpell(m_target, 37325, true, NULL, dummy);
2853  break;
2854  default:
2855  break;
2856  }
2857 
2858  // Remove auras linked to forms, such as Vanish and Stealth
2860 
2861  /* We need to re-apply any of transform auras:
2862  Great example is OHF, when you are in cat form and unshapeshift,
2863  you should be a human not your original model */
2865  for (Unit::AuraList::const_iterator i = trans.begin(); i != trans.end(); i++)
2866  (*i)->ApplyModifier(true, true);
2867  }
2868 
2869  // adding/removing linked auras
2870  // add/remove the shapeshift aura's boosts
2871  HandleShapeshiftBoosts(apply);
2872 
2873  if (m_target->GetTypeId() == TYPEID_PLAYER)
2875 }
2876 
2877 void Aura::HandleAuraTransform(bool apply, bool Real)
2878 {
2879  if (apply)
2880  {
2881  // Shapeshifts (that change model) have higher priority than transforms (if not negative)
2883  return;
2884 
2885  // special case (spell specific functionality)
2886  if (m_modifier.m_miscvalue == 0)
2887  {
2888  switch (GetId())
2889  {
2890  case 16739: // Orb of Deception
2891  {
2892  if (m_target->GetTypeId() != TYPEID_PLAYER)
2893  return;
2894 
2895  switch (m_target->getRace())
2896  {
2897  // Blood Elf
2898  case RACE_BLOODELF:
2899  m_target->SetDisplayId(m_target->getGender() == GENDER_FEMALE ? 17830 : 17829);
2900  break;
2901  // Orc
2902  case RACE_ORC:
2903  m_target->SetDisplayId(m_target->getGender() == GENDER_FEMALE ? 10140 : 10139);
2904  break;
2905  // Troll
2906  case RACE_TROLL:
2907  m_target->SetDisplayId(m_target->getGender() == GENDER_FEMALE ? 10134 : 10135);
2908  break;
2909  // Tauren
2910  case RACE_TAUREN:
2911  m_target->SetDisplayId(m_target->getGender() == GENDER_FEMALE ? 10147 : 10136);
2912  break;
2913  // Undead
2914  case RACE_UNDEAD_PLAYER:
2915  m_target->SetDisplayId(m_target->getGender() == GENDER_FEMALE ? 10145 : 10146);
2916  break;
2917  // Draenei
2918  case RACE_DRAENEI:
2919  m_target->SetDisplayId(m_target->getGender() == GENDER_FEMALE ? 17828 : 17827);
2920  break;
2921  // Dwarf
2922  case RACE_DWARF:
2923  m_target->SetDisplayId(m_target->getGender() == GENDER_FEMALE ? 10142 : 10141);
2924  break;
2925  // Gnome
2926  case RACE_GNOME:
2927  m_target->SetDisplayId(m_target->getGender() == GENDER_FEMALE ? 10149 : 10148);
2928  break;
2929  // Human
2930  case RACE_HUMAN:
2931  m_target->SetDisplayId(m_target->getGender() == GENDER_FEMALE ? 10138 : 10137);
2932  break;
2933  // Night Elf
2934  case RACE_NIGHTELF:
2935  m_target->SetDisplayId(m_target->getGender() == GENDER_FEMALE ? 10144 : 10143);
2936  break;
2937  default:
2938  break;
2939  }
2940  break;
2941  }
2942  // Murloc costume
2943  case 42365:
2944  m_target->SetDisplayId(21723);
2945  break;
2946  // Dread Corsair - Pirate Day
2947  case 50531:
2948  case 50517:
2949  {
2950  if (m_target->GetTypeId() != TYPEID_PLAYER)
2951  return;
2952 
2953  switch (m_target->getRace())
2954  {
2955  // Blood Elf
2956  case RACE_BLOODELF:
2957  m_target->SetDisplayId(m_target->getGender() == GENDER_MALE ? 25032 : 25043);
2958  break;
2959  // Orc
2960  case RACE_ORC:
2961  m_target->SetDisplayId(m_target->getGender() == GENDER_MALE ? 25039 : 25050);
2962  break;
2963  // Troll
2964  case RACE_TROLL:
2965  m_target->SetDisplayId(m_target->getGender() == GENDER_MALE ? 25041 : 25052);
2966  break;
2967  // Tauren
2968  case RACE_TAUREN:
2969  m_target->SetDisplayId(m_target->getGender() == GENDER_MALE ? 25040 : 25051);
2970  break;
2971  // Undead
2972  case RACE_UNDEAD_PLAYER:
2973  m_target->SetDisplayId(m_target->getGender() == GENDER_MALE ? 25042 : 25053);
2974  break;
2975  // Draenei
2976  case RACE_DRAENEI:
2977  m_target->SetDisplayId(m_target->getGender() == GENDER_MALE ? 25033 : 25044);
2978  break;
2979  // Dwarf
2980  case RACE_DWARF:
2981  m_target->SetDisplayId(m_target->getGender() == GENDER_MALE ? 25034 : 25045);
2982  break;
2983  // Gnome
2984  case RACE_GNOME:
2985  m_target->SetDisplayId(m_target->getGender() == GENDER_MALE ? 25035 : 25046);
2986  break;
2987  // Human
2988  case RACE_HUMAN:
2989  m_target->SetDisplayId(m_target->getGender() == GENDER_MALE ? 25037 : 25048);
2990  break;
2991  // Night Elf
2992  case RACE_NIGHTELF:
2993  m_target->SetDisplayId(m_target->getGender() == GENDER_MALE ? 25038 : 25049);
2994  break;
2995  default:
2996  break;
2997  }
2998  break;
2999  }
3000  default:
3001  break;
3002  }
3003  }
3004  else
3005  {
3006  uint32 model_id;
3007 
3008  CreatureInfo const* ci = sObjectMgr.GetCreatureTemplate(m_modifier.m_miscvalue);
3009  if (!ci)
3010  {
3011  model_id = 16358; //pig pink ^_^
3012  sLog.outError("Auras: unknown creature id = %d (only need its modelid) Form Spell Aura Transform in Spell ID = %d", m_modifier.m_miscvalue, GetId());
3013  }
3014  else
3015  model_id = ci->GetRandomValidModelId();
3016 
3017  m_target->SetDisplayId(model_id);
3018 
3019  // Dragonmaw Illusion (set mount model also)
3022  }
3023 
3024  // update active transform spell only not set or not overwriting negative by positive case
3027 
3028  // polymorph case
3029  if (Real && m_target->GetTypeId() == TYPEID_PLAYER && m_target->IsPolymorphed())
3030  {
3031  // for players, start regeneration after 1s (in polymorph fast regeneration case)
3032  // only if caster is Player (after patch 2.4.2)
3033  if (GetCaster()->isPlayer())
3035 
3036  //dismount polymorphed target (after patch 2.4.2)
3037  if (m_target->IsMounted())
3039  }
3040  }
3041  else
3042  {
3043  if (m_target->getTransForm() == GetId())
3044  m_target->setTransForm(0);
3045 
3048  else
3050 
3051  // apply default equipment for creature case
3052  if (m_target->GetTypeId() == TYPEID_UNIT)
3053  ((Creature*)m_target)->LoadEquipment(((Creature*)m_target)->GetCreatureTemplate()->equipmentId, true);
3054 
3055  // re-apply some from still active with preference negative cases
3056  Unit::AuraList const& otherTransforms = m_target->GetAurasByType(SPELL_AURA_TRANSFORM);
3057  if (!otherTransforms.empty())
3058  {
3059  // look for other transform auras
3060  Aura* handledAura = *otherTransforms.begin();
3061  for (Unit::AuraList::const_iterator i = otherTransforms.begin(); i != otherTransforms.end(); ++i)
3062  {
3063  // negative auras are preferred
3064  if (!IsPositiveSpell((*i)->GetSpellProto()->Id))
3065  {
3066  handledAura = *i;
3067  break;
3068  }
3069  }
3070  handledAura->ApplyModifier(true);
3071  }
3072 
3073  // Dragonmaw Illusion (restore mount model)
3074  if (GetId() == 42016 && m_target->GetMountID() == 16314)
3075  {
3077  {
3078  uint32 cr_id = m_target->GetAurasByType(SPELL_AURA_MOUNTED).front()->GetModifier()->m_miscvalue;
3079  if (CreatureInfo const* ci = sObjectMgr.GetCreatureTemplate(cr_id))
3080  {
3081  uint32 team = 0;
3082  if (m_target->GetTypeId() == TYPEID_PLAYER)
3083  team = m_target->ToPlayer()->GetTeam();
3084 
3085  uint32 display_id = sObjectMgr.ChooseDisplayId(team, ci);
3086  CreatureModelInfo const* minfo = sObjectMgr.GetCreatureModelRandomGender(display_id);
3087  if (minfo)
3088  display_id = minfo->modelid;
3089 
3091  }
3092  }
3093  }
3094  }
3095 }
3096 
3097 void Aura::HandleForceReaction(bool apply, bool Real)
3098 {
3099  if (!Real)
3100  return;
3101 
3102  Player* player = m_target->ToPlayer();
3103  if (!player)
3104  return;
3105 
3106  uint32 factionId = m_modifier.m_miscvalue;
3107  uint32 factionRank = m_modifier.m_amount;
3108 
3109  player->GetReputationMgr().ApplyForceReaction(factionId, ReputationRank(factionRank), apply);
3111 }
3112 
3113 void Aura::HandleAuraModSkill(bool apply, bool /*Real*/)
3114 {
3115  if (m_target->GetTypeId() != TYPEID_PLAYER)
3116  return;
3117 
3119  int32 points = GetModifierValue();
3120 
3121  m_target->ToPlayer()->ModifySkillBonus(prot, ((apply) ? points: -points), GetAuraType() == SPELL_AURA_MOD_SKILL_TALENT);
3122  if (prot == SKILL_DEFENSE)
3124 }
3125 
3127 {
3128  if (apply || m_removeMode != AURA_REMOVE_BY_DEATH)
3129  return;
3130 
3131  Unit* caster = GetCaster();
3132  if (!caster || caster->GetTypeId() != TYPEID_PLAYER)
3133  return;
3134 
3135  Player* plCaster = caster->ToPlayer();
3136  Unit* target = GetTarget();
3137 
3138  if (Real)
3139  {
3140  if (!target)
3141  return;
3142 
3143  // Item amount
3144  if (GetAmount() <= 0)
3145  return;
3146 
3147  SpellEntry const* spellInfo = GetSpellProto();
3148  if (spellInfo->EffectItemType[m_effIndex] == 0)
3149  return;
3150 
3151  // Soul Shard
3152  if (GetSpellProto()->EffectItemType[m_effIndex] == 6265)
3153  {
3154  // Soul Shard only from units that grant XP or honor
3155  if (!plCaster->isHonorOrXPTarget(target) ||
3156  (target->GetTypeId() == TYPEID_UNIT && !target->ToCreature()->isTappedBy(plCaster)))
3157  return;
3158  }
3159 
3160  //Adding items
3161  uint32 noSpaceForCount = 0;
3162  uint32 count = m_modifier.m_amount;
3163 
3164  ItemPosCountVec dest;
3165  uint8 msg = plCaster->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, spellInfo->EffectItemType[m_effIndex], count, &noSpaceForCount);
3166  if (msg != EQUIP_ERR_OK)
3167  {
3168  count-=noSpaceForCount;
3169  plCaster->SendEquipError(msg, NULL, NULL);
3170  if (count == 0)
3171  return;
3172  }
3173 
3174  Item* newitem = plCaster->StoreNewItem(dest, spellInfo->EffectItemType[m_effIndex], true);
3175  if (!newitem)
3176  {
3177  plCaster->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, NULL, NULL);
3178  return;
3179  }
3180  plCaster->SendNewItem(newitem, count, true, true);
3181  }
3182 }
3183 
3184 void Aura::HandleBindSight(bool apply, bool /*Real*/)
3185 {
3186  Unit* caster = GetCaster();
3187  if (!caster || caster->GetTypeId() != TYPEID_PLAYER)
3188  return;
3189 
3190  caster->ToPlayer()->SetViewpoint(m_target, apply);
3191 }
3192 
3193 //@todo complete
3194 void Aura::HandleFarSight(bool /*apply*/, bool /*Real*/)
3195 {
3196  /*Unit* caster = GetCaster();
3197  if (!caster || caster->GetTypeId() != TYPEID_PLAYER)
3198  return;
3199 
3200  caster->ToPlayer()->SetFarSight(apply ? m_target->GetGUID() : NULL);*/
3201 }
3202 
3203 void Aura::HandleAuraTrackCreatures(bool apply, bool /*Real*/)
3204 {
3205  if (m_target->GetTypeId() != TYPEID_PLAYER)
3206  return;
3207 
3208  if (apply)
3211 }
3212 
3213 void Aura::HandleAuraTrackResources(bool apply, bool /*Real*/)
3214 {
3215  if (m_target->GetTypeId() != TYPEID_PLAYER)
3216  return;
3217 
3218  if (apply)
3221 }
3222 
3223 void Aura::HandleAuraTrackStealthed(bool apply, bool /*Real*/)
3224 {
3225  if (m_target->GetTypeId() != TYPEID_PLAYER)
3226  return;
3227 
3228  if (apply)
3230  else
3231  {
3232  // do not remove unit flag if there are more than this auraEffect of that kind on unit
3234  return;
3235  }
3236 
3238 }
3239 
3240 void Aura::HandleAuraModScale(bool apply, bool /*Real*/)
3241 {
3242  float scale = m_target->GetObjectScale();
3243  ApplyPercentModFloatVar(scale, float(GetModifierValue()), apply);
3244  m_target->SetObjectScale(scale);
3245 }
3246 
3247 void Aura::HandleModPossess(bool apply, bool Real)
3248 {
3249  if (!Real)
3250  return;
3251 
3252  Unit* caster = GetCaster();
3253  if (caster && caster->GetTypeId() == TYPEID_UNIT)
3254  {
3255  HandleModCharm(apply, Real);
3256  return;
3257  }
3258 
3259  if (apply)
3260  {
3262  return;
3263 
3265  }
3266  else
3267  m_target->RemoveCharmedBy(caster);
3268 }
3269 
3270 void Aura::HandleModPossessPet(bool apply, bool Real)
3271 {
3272  if (!Real)
3273  return;
3274 
3275  Unit* caster = GetCaster();
3276  if (!caster || caster->GetTypeId() != TYPEID_PLAYER)
3277  return;
3278 
3279  if (m_target->GetTypeId() != TYPEID_UNIT || !m_target->IsPet())
3280  return;
3281 
3282  Pet* pet = m_target->ToPet();
3283 
3284  if (apply)
3285  {
3286  if (caster->ToPlayer()->GetPet() != pet)
3287  return;
3288 
3289  // Must clear current motion or pet leashes back to owner after a few yards
3290  // when under spell 'Eyes of the Beast'
3291  pet->GetMotionMaster()->Clear();
3292  pet->SetCharmedBy(caster, CHARM_TYPE_POSSESS);
3293  }
3294  else
3295  {
3296  pet->RemoveCharmedBy(caster);
3297 
3298  if (!pet->IsWithinDistInMap(caster, pet->GetMap()->GetVisibilityRange()))
3299  pet->Remove(PET_SAVE_NOT_IN_SLOT, true);
3300  else
3301  {
3302  // Reinitialize the pet bar and make the pet come back to the owner
3303  caster->ToPlayer()->PetSpellInitialize();
3304 
3305  // Follow owner only if not fighting or owner didn't click "stay" at new location
3306  // This may be confusing because pet bar shows "stay" when under the spell but it retains
3307  // the "follow" flag. Player MUST click "stay" while under the spell.
3308  if (!pet->GetVictim() && !pet->GetCharmInfo()->HasCommandState(COMMAND_STAY))
3309  {
3312  }
3313  }
3314  }
3315 }
3316 
3317 void Aura::HandleModCharm(bool apply, bool Real)
3318 {
3319  if (!Real)
3320  return;
3321 
3322  Unit* caster = GetCaster();
3323 
3324  if (apply)
3325  {
3327  return;
3328 
3330  }
3331  else
3332  m_target->RemoveCharmedBy(caster);
3333 }
3334 
3335 void Aura::HandleModConfuse(bool apply, bool Real)
3336 {
3337  if (!Real)
3338  return;
3339 
3341 }
3342 
3343 void Aura::HandleModFear(bool apply, bool Real)
3344 {
3345  if (!Real)
3346  return;
3347 
3349 }
3350 
3351 void Aura::HandleFeignDeath(bool apply, bool Real)
3352 {
3353  if (!Real)
3354  return;
3355 
3356  if (apply)
3357  {
3358  /*
3359  WorldPacket data(SMSG_FEIGN_DEATH_RESISTED, 9);
3360  data<<m_target->GetGUID();
3361  data<<uint8(0);
3362  m_target->SendMessageToSet(&data,true);
3363  */
3364 
3365  std::list<Unit*> targets;
3369  for (std::list<Unit*>::iterator iter = targets.begin(); iter != targets.end(); ++iter)
3370  {
3371  if (!(*iter)->HasUnitState(UNIT_STATE_CASTING))
3372  continue;
3373 
3375  {
3376  if ((*iter)->GetCurrentSpell(i)
3377  && (*iter)->GetCurrentSpell(i)->m_targets.getUnitTargetGUID() == m_target->GetGUID())
3378  (*iter)->InterruptSpell(CurrentSpellTypes(i), false);
3379  }
3380  }
3381  m_target->CombatStop();
3383 
3384  // prevent interrupt message
3389 
3390  m_target->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNK_29); // blizz like 2.0.x
3392  m_target->SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_DEAD); // blizz like 2.0.x
3394 
3395  if (Creature* creature = m_target->ToCreature())
3396  creature->SetReactState(REACT_PASSIVE);
3397  }
3398  else
3399  {
3400  /*
3401  WorldPacket data(SMSG_FEIGN_DEATH_RESISTED, 9);
3402  data<<m_target->GetGUID();
3403  data<<uint8(1);
3404  m_target->SendMessageToSet(&data,true);
3405  */
3406 
3407  m_target->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNK_29); // blizz like 2.0.x
3411 
3412  if (Creature* creature = m_target->ToCreature())
3413  creature->InitializeReactState();
3414  }
3415 }
3416 
3417 void Aura::HandleAuraModDisarm(bool apply, bool Real)
3418 {
3419  if (!Real)
3420  return;
3421 
3422  if (!apply && m_target->HasAuraType(SPELL_AURA_MOD_DISARM))
3423  return;
3424 
3425  // not sure for it's correctness
3426  if (apply)
3428  else
3430 
3431  if (m_target->GetTypeId() == TYPEID_PLAYER)
3432  {
3433  // main-hand attack speed already set to special value for feral form already and don't must change and reset at remove.
3434  if (m_target->ToPlayer()->IsInFeralForm())
3435  return;
3436 
3437  if (apply)
3439  else
3441  }
3442  else
3443  {
3444  // creature does not have equipment
3445  if (apply && !m_target->ToCreature()->GetCurrentEquipmentId())
3446  return;
3447  }
3448 
3450 }
3451 
3452 void Aura::HandleAuraModStun(bool apply, bool Real)
3453 {
3454  if (!Real)
3455  return;
3456 
3458 }
3459 
3460 void Aura::HandleModStealth(bool apply, bool Real)
3461 {
3463 
3464  if (apply)
3465  {
3466  // only at real aura add
3467  if (Real)
3468  {
3469  m_target->m_stealth.AddFlag(type);
3471 
3473  if (m_target->GetTypeId() == TYPEID_PLAYER)
3475 
3476  // for RACE_NIGHTELF stealth
3477  if (m_target->GetTypeId() == TYPEID_PLAYER && GetId() == 20580)
3478  m_target->CastSpell(m_target, 21009, true, NULL, this);
3479  }
3480  }
3481  else
3482  {
3483  // only at real aura remove
3484  if (Real)
3485  {
3486  // for RACE_NIGHTELF stealth
3487  if (m_target->GetTypeId() == TYPEID_PLAYER && GetId() == 20580)
3489 
3490  m_target->m_stealth.AddValue(type, -GetAmount());
3491 
3492  if (!m_target->HasAuraType(SPELL_AURA_MOD_STEALTH)) // if last SPELL_AURA_MOD_STEALTH
3493  {
3494  m_target->m_stealth.DelFlag(type);
3495 
3497  if (m_target->GetTypeId() == TYPEID_PLAYER)
3499  }
3500  }
3501  }
3502 
3503  // Master of Subtlety
3504  Unit::AuraList const& mDummyAuras = m_target->GetAurasByType(SPELL_AURA_DUMMY);
3505  for (Unit::AuraList::const_iterator i = mDummyAuras.begin(); i != mDummyAuras.end(); ++i)
3506  {
3507  if ((*i)->GetSpellProto()->SpellIconID == 2114 && Real)
3508  {
3509  if (apply)
3510  {
3511  int32 bp = (*i)->GetModifier()->m_amount;
3512  m_target->CastCustomSpell(m_target, 31665, &bp, NULL, NULL, true);
3513  }
3514  else
3515  m_target->CastSpell(m_target, 31666, true);
3516  break;
3517  }
3518  }
3519 
3520  // call functions which may have additional effects after chainging state of unit
3521  if (apply && Real)
3522  {
3523  // drop flag at stealth in bg
3525  }
3526 
3528 }
3529 
3530 void Aura::HandleModStealthLevel(bool apply, bool Real)
3531 {
3533 
3534  if (apply)
3536  else
3537  m_target->m_stealth.AddValue(type, -GetAmount());
3538 
3540 }
3541 
3542 void Aura::HandleModInvisibility(bool apply, bool Real)
3543 {
3545 
3546  if (apply)
3547  {
3548  if (Real && m_target->GetTypeId() == TYPEID_PLAYER)
3550 
3553  }
3554  else
3555  {
3557  {
3558  // if not have different invisibility auras.
3559  // remove glow vision
3560  if (m_target->GetTypeId() == TYPEID_PLAYER)
3562 
3564  }
3565  else
3566  {
3567  bool found = false;
3569  for (Unit::AuraList::const_iterator i = invisAuras.begin(); i != invisAuras.end(); ++i)
3570  {
3571  if (GetMiscValue() == (*i)->GetMiscValue())
3572  {
3573  found = true;
3574  break;
3575  }
3576  }
3577  if (!found)
3579  }
3580 
3582  }
3583 
3584  // call functions which may have additional effects after chainging state of unit
3585  if (apply && Real)
3586  m_target->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_UNATTACKABLE); // drop flag at invisibiliy in bg
3587 
3589 }
3590 
3592 {
3594 
3595  if (apply)
3596  {
3599  }
3600  else
3601  {
3604 
3606  }
3607 
3609 }
3610 
3612 {
3614 
3615  if (apply)
3616  {
3619  }
3620  else
3621  {
3624 
3626  }
3627 
3629 }
3630 
3631 void Aura::HandleAuraModRoot(bool apply, bool Real)
3632 {
3633  // only at real add/remove aura
3634  if (!Real)
3635  return;
3636 
3638 }
3639 
3640 void Aura::HandleAuraModSilence(bool apply, bool Real)
3641 {
3642  // only at real add/remove aura
3643  if (!Real)
3644  return;
3645 
3646  if (apply)
3647  {
3649 
3650  // call functions which may have additional effects after chainging state of unit
3651  // Stop cast only spells vs PreventionType == SPELL_PREVENTION_TYPE_SILENCE
3652  for (uint32 i = CURRENT_MELEE_SPELL; i < CURRENT_MAX_SPELL; ++i)
3653  if (Spell* spell = m_target->GetCurrentSpell(i))
3654  if (spell->m_spellInfo->PreventionType == SPELL_PREVENTION_TYPE_SILENCE)
3655  // Stop spells on prepare or casting state
3657  }
3658  else
3659  {
3660  // do not remove unit flag if there are more than this auraEffect of that kind on unit
3662  return;
3663 
3665  }
3666 }
3667 
3668 void Aura::HandleModThreat(bool apply, bool Real)
3669 {
3670  // only at real add/remove aura
3671  if (!Real)
3672  return;
3673 
3674  if (!m_target->IsAlive())
3675  return;
3676 
3677  Unit* caster = GetCaster();
3678 
3679  if (!caster || !caster->IsAlive())
3680  return;
3681 
3682  int level_diff = 0;
3683  int multiplier = 0;
3684  switch (GetId())
3685  {
3686  // Arcane Shroud
3687  case 26400:
3688  level_diff = m_target->getLevel() - 60;
3689  multiplier = 2;
3690  break;
3691  // The Eye of Diminution
3692  case 28862:
3693  level_diff = m_target->getLevel() - 60;
3694  multiplier = 1;
3695  break;
3696  }
3697  if (level_diff > 0)
3698  m_modifier.m_amount += multiplier * level_diff;
3699 
3700  if (m_target->GetTypeId() == TYPEID_PLAYER)
3701  for (int8 i = 0; i < MAX_SPELL_SCHOOL; i++)
3702  if (GetMiscValue() & int32(1 << i))
3704 
3705 }
3706 
3708 {
3709  // only at real add/remove aura
3710  if (!Real)
3711  return;
3712 
3713  if (!m_target->IsAlive() || m_target->GetTypeId() != TYPEID_PLAYER)
3714  return;
3715 
3716  Unit* caster = GetCaster();
3717 
3718  if (caster && caster->IsAlive())
3720 }
3721 
3722 void Aura::HandleModTaunt(bool apply, bool Real)
3723 {
3724  // only at real add/remove aura
3725  if (!Real)
3726  return;
3727 
3728  if (!m_target->IsAlive() || !m_target->CanHaveThreatList())
3729  return;
3730 
3731  Unit* caster = GetCaster();
3732 
3733  if (!caster || !caster->IsAlive())
3734  return;
3735 
3736  if (apply)
3737  m_target->TauntApply(caster);
3738  else
3739  {
3740  // When taunt aura fades out, mob will switch to previous target if current has less than 1.1 * secondthreat
3741  m_target->TauntFadeOut(caster);
3742  }
3743 }
3744 
3745 /*********************************************************/
3746 /*** MODIFY SPEED ***/
3747 /*********************************************************/
3748 void Aura::HandleAuraModIncreaseSpeed(bool /*apply*/, bool Real)
3749 {
3750  // all applied/removed only at real aura add/remove
3751  if (!Real)
3752  return;
3753 
3754  m_target->UpdateSpeed(MOVE_RUN, true);
3755 }
3756 
3758 {
3759  HandleAuraModIncreaseSpeed(apply, Real);
3760 }
3761 
3763 {
3764  // all applied/removed only at real aura add/remove
3765  if (!Real)
3766  return;
3767 
3768  // Enable Fly mode for flying mounts
3770  {
3771  if (m_target->SetCanFly(apply))
3772  if (!apply && !m_target->IsLevitating())
3774 
3775  if (!apply && m_target->GetTypeId() == TYPEID_UNIT && !m_target->IsLevitating())
3777 
3778  // Players on flying mounts must be immune to polymorph
3779  if (m_target->GetTypeId() == TYPEID_PLAYER)
3781 
3782  // Dragonmaw Illusion (overwrite mount model, mounted aura already applied)
3783  if (apply && m_target->HasAura(42016, 0) && m_target->GetMountID())
3785  }
3786 
3788 }
3789 
3790 void Aura::HandleAuraModIncreaseSwimSpeed(bool /*apply*/, bool Real)
3791 {
3792  // all applied/removed only at real aura add/remove
3793  if (!Real)
3794  return;
3795 
3796  m_target->UpdateSpeed(MOVE_SWIM, true);
3797 }
3798 
3800 {
3801  // all applied/removed only at real aura add/remove
3802  if (!Real)
3803  return;
3804 
3807  switch (m_spellProto->Id)
3808  {
3809  case 12323: // Piercing Howl
3810  if (apply)
3812  break;
3813  }
3814 
3815  m_target->UpdateSpeed(MOVE_RUN, true);
3816  m_target->UpdateSpeed(MOVE_SWIM, true);
3821 }
3822 
3823 void Aura::HandleAuraModUseNormalSpeed(bool /*apply*/, bool Real)
3824 {
3825  // all applied/removed only at real aura add/remove
3826  if (!Real)
3827  return;
3828 
3829  m_target->UpdateSpeed(MOVE_RUN, true);
3830  m_target->UpdateSpeed(MOVE_SWIM, true);
3832 }
3833 
3834 /*********************************************************/
3835 /*** IMMUNITY ***/
3836 /*********************************************************/
3837 
3838 void Aura::HandleModMechanicImmunity(bool apply, bool /*Real*/)
3839 {
3840  uint32 mechanic = 1 << m_modifier.m_miscvalue;
3841 
3842  //immune movement impairment and loss of control
3845 
3846  if (apply && GetSpellProto()->AttributesEx & SPELL_ATTR1_DISPEL_AURAS_ON_IMMUNITY)
3847  {
3848  Unit::AuraMap& Auras = m_target->GetAuras();
3849  for (Unit::AuraMap::iterator iter = Auras.begin(), next; iter != Auras.end(); iter = next)
3850  {
3851  next = iter;
3852  ++next;
3853  SpellEntry const* spell = iter->second->GetSpellProto();
3854  if (!(spell->Attributes & SPELL_ATTR0_UNAFFECTED_BY_INVULNERABILITY) // spells unaffected by invulnerability
3855  && !iter->second->IsPositive() // only remove negative spells
3856  && spell->Id != GetId())
3857  {
3858  //check for mechanic mask
3859  if (GetSpellMechanicMask(spell, iter->second->GetEffIndex()) & mechanic)
3860  {
3862  if (Auras.empty())
3863  break;
3864  else
3865  next = Auras.begin();
3866  }
3867  }
3868  }
3869  }
3870 
3872 
3873  // special cases
3874  switch (m_modifier.m_miscvalue)
3875  {
3878  break;
3879  case MECHANIC_SHIELD:
3881  break;
3882  }
3883 
3884  // Bestial Wrath
3885  if (GetSpellProto()->SpellFamilyName == SPELLFAMILY_HUNTER && GetSpellProto()->Id == 19574)
3886  {
3887  // The Beast Within cast on owner if talent present
3888  if (Unit* owner = m_target->GetOwner())
3889  {
3890  // Search talent
3891  Unit::AuraList const& m_dummyAuras = owner->GetAurasByType(SPELL_AURA_DUMMY);
3892  for (Unit::AuraList::const_iterator i = m_dummyAuras.begin(); i != m_dummyAuras.end(); ++i)
3893  {
3894  if ((*i)->GetSpellProto()->SpellIconID == 2229)
3895  {
3896  if (apply)
3897  owner->CastSpell(owner, 34471, true, 0, this);
3898  else
3899  owner->RemoveAurasDueToSpell(34471);
3900  break;
3901  }
3902  }
3903  }
3904  }
3905 
3906  // The Beast Within and Bestial Wrath - immunity
3907  if (GetId() == 19574 || GetId() == 34471)
3908  {
3909  if (apply)
3910  {
3911  m_target->CastSpell(m_target, 24395, true);
3912  m_target->CastSpell(m_target, 24396, true);
3913  m_target->CastSpell(m_target, 24397, true);
3914  m_target->CastSpell(m_target, 26592, true);
3915  }
3916  else
3917  {
3922  }
3923  }
3924 }
3925 
3927 {
3928  if (!Real)
3929  return;
3930 
3932 
3933  // when removing flag aura, handle flag drop
3934  Player* player = m_target->ToPlayer();
3935  if (!apply && player && (GetSpellProto()->AuraInterruptFlags & AURA_INTERRUPT_FLAG_UNATTACKABLE))
3936  {
3937  if (player->InBattleground())
3938  {
3939  if (Battleground* bg = player->GetBattleground())
3940  bg->EventPlayerDroppedFlag(player);
3941  }
3942  else
3943  sOutdoorPvPMgr.HandleDropFlag(player, GetSpellProto()->Id);
3944  }
3945 }
3946 
3948 {
3949  if (!Real)
3950  return;
3951 
3952  if (apply && GetSpellProto()->AttributesEx & SPELL_ATTR1_DISPEL_AURAS_ON_IMMUNITY)
3953  {
3955  for (Unit::AuraList::const_iterator itr = auraList.begin(); itr != auraList.end();)
3956  {
3957  if (auraList.front() != this) // skip itself aura (it already added)
3958  {
3959  m_target->RemoveAurasDueToSpell(auraList.front()->GetId());
3960  itr = auraList.begin();
3961  }
3962  else
3963  ++itr;
3964  }
3965  }
3966 
3968 }
3969 
3971 {
3974 
3976 
3977  if (Real && apply && GetSpellProto()->AttributesEx & SPELL_ATTR1_DISPEL_AURAS_ON_IMMUNITY)
3978  {
3979  if (IsPositiveSpell(GetId())) //Only positive immunity removes auras
3980  {
3981  uint32 school_mask = m_modifier.m_miscvalue;
3982  Unit::AuraMap& Auras = m_target->GetAuras();
3983  for (Unit::AuraMap::iterator iter = Auras.begin(), next; iter != Auras.end(); iter = next)
3984  {
3985  next = iter;
3986  ++next;
3987  SpellEntry const* spell = iter->second->GetSpellProto();
3988  if ((GetSpellSchoolMask(spell) & school_mask)//Check for school mask
3989  && !(spell->Attributes & SPELL_ATTR0_UNAFFECTED_BY_INVULNERABILITY) //Spells unaffected by invulnerability
3990  && !iter->second->IsPositive() //Don't remove positive spells
3991  && spell->Id != GetId()) //Don't remove self
3992  {
3994  if (Auras.empty())
3995  break;
3996  else
3997  next = Auras.begin();
3998  }
3999  }
4000  }
4001  }
4002  if (Real && GetSpellProto()->Mechanic == MECHANIC_BANISH)
4003  {
4004  if (apply)
4006  else
4008  }
4009 }
4010 
4011 void Aura::HandleAuraModDmgImmunity(bool apply, bool /*Real*/)
4012 {
4014 }
4015 
4017 {
4018  // all applied/removed only at real aura add/remove
4019  if (!Real)
4020  return;
4021 
4023 
4024  if (GetId() == 20594) //stoneform
4025  {
4026  //handle diseases
4028 
4029  //remove bleed auras
4030  const uint32 mechanic = 1 << MECHANIC_BLEED;
4031 
4032  if (apply)
4033  {
4034  Unit::AuraMap& Auras = m_target->GetAuras();
4035  for (Unit::AuraMap::iterator iter = Auras.begin(); iter != Auras.end(); ++iter)
4036  {
4037  SpellEntry const* spell = iter->second->GetSpellProto();
4038  if (!(spell->Attributes & SPELL_ATTR0_UNAFFECTED_BY_INVULNERABILITY) // spells unaffected by invulnerability
4039  && !iter->second->IsPositive() // only remove negative spells
4040  && spell->Id != GetId()
4041  && (GetSpellMechanicMask(spell, iter->second->GetEffIndex()) & mechanic))
4042  {
4044  iter = Auras.begin();
4045  }
4046  }
4047  }
4048 
4050  }
4051 }
4052 
4054 {
4055  if (!Real)
4056  return;
4057 
4058  if (apply)
4059  {
4060  // some spell have charges by functionality not have its in spell data
4061  switch (GetId())
4062  {
4063  case 28200: // Ascendance (Talisman of Ascendance trinket)
4064  m_procCharges = 6;
4066  break;
4067  default:
4068  break;
4069  }
4070  }
4071 }
4072 
4073 void Aura::HandleAuraModStalked(bool apply, bool /*Real*/)
4074 {
4075  // used by spells: Hunter's Mark, Mind Vision, Syndicate Tracker (MURP) DND
4076  if (apply)
4078  else
4079  {
4080  // do not remove unit flag if there are more than this auraEffect of that kind on unit
4081  if (!m_target->HasAuraType(GetAuraType()))
4083  }
4084 
4085  // call functions which may have additional effects after chainging state of unit
4087 }
4088 
4089 /*********************************************************/
4090 /*** PERIODIC ***/
4091 /*********************************************************/
4092 
4093 void Aura::HandlePeriodicTriggerSpell(bool apply, bool /*Real*/)
4094 {
4095  if (m_periodicTimer <= 0)
4097 
4098  m_isPeriodic = apply;
4099 
4100  // Curse of the Plaguebringer
4101  if (!apply && m_spellProto->Id == 29213 && m_removeMode != AURA_REMOVE_BY_DISPEL)
4102  {
4103  // Cast Wrath of the Plaguebringer if not dispelled
4104  m_target->CastSpell(m_target, 29214, true, 0, this);
4105  }
4106 
4107  // Wrath of the Astromancer
4108  if (!apply && m_spellProto->Id == 42783)
4109  m_target->CastSpell(m_target, 42787, true, 0, this);
4110 }
4111 
4113 {
4114  if (m_periodicTimer <= 0)
4116 
4117  m_isPeriodic = apply;
4118 }
4119 
4120 void Aura::HandlePeriodicEnergize(bool apply, bool /*Real*/)
4121 {
4122  if (m_periodicTimer <= 0)
4124 
4125  m_isPeriodic = apply;
4126 
4127  if (GetId() == 5229)
4128  m_target->UpdateArmor();
4129 
4130 }
4131 
4133 {
4134  // spells required only Real aura add/remove
4135  if (!Real)
4136  return;
4137 
4138  SpellEntry const* spell = GetSpellProto();
4139  switch (spell->SpellFamilyName)
4140  {
4141  case SPELLFAMILY_ROGUE:
4142  {
4143  // Master of Subtlety
4144  if (spell->Id == 31666 && !apply && Real)
4145  {
4147  break;
4148  }
4149  break;
4150  }
4151  case SPELLFAMILY_HUNTER:
4152  {
4153  // Aspect of the Viper
4154  if (spell->SpellFamilyFlags & 0x0004000000000000LL)
4155  {
4156  // Update regen on remove
4157  if (!apply && m_target->GetTypeId() == TYPEID_PLAYER)
4159  break;
4160  }
4161  break;
4162  }
4163  }
4164 
4165  m_isPeriodic = apply;
4166 }
4167 
4168 void Aura::HandlePeriodicHeal(bool apply, bool Real)
4169 {
4170  if (m_periodicTimer <= 0)
4172 
4173  m_isPeriodic = apply;
4174 
4175  // only at real apply
4176  if (Real && apply && GetSpellProto()->Mechanic == MECHANIC_BANDAGE)
4177  {
4178  // provided m_target as original caster to prevent apply aura caster selection for this negative buff
4179  m_target->CastSpell(m_target, 11196, true, NULL, this, m_target->GetGUID());
4180  }
4181 
4182  // For prevent double apply bonuses
4183  bool loading = (m_target->GetTypeId() == TYPEID_PLAYER && m_target->ToPlayer()->GetSession()->PlayerLoading());
4184 
4185  if (!loading && apply)
4186  {
4187  switch (m_spellProto->SpellFamilyName)
4188  {
4189  case SPELLFAMILY_DRUID:
4190  {
4191  // Rejuvenation
4192  if (m_spellProto->SpellFamilyFlags & 0x0000000000000010LL)
4193  {
4194  if (Unit* caster = GetCaster())
4195  {
4196  Unit::AuraList const& classScripts = caster->GetAurasByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS);
4197  for (Unit::AuraList::const_iterator k = classScripts.begin(); k != classScripts.end(); ++k)
4198  {
4200  switch ((*k)->GetModifier()->m_miscvalue)
4201  {
4202  case 4953: // Increased Rejuvenation Healing - Harold's Rejuvenating Broach Aura
4203  case 4415: // Increased Rejuvenation Healing - Idol of Rejuvenation Aura
4204  {
4205  m_modifier.m_amount += (*k)->GetModifier()->m_amount / tickcount;
4206  break;
4207  }
4208  }
4209  }
4210  }
4211  }
4212  }
4213  }
4214  }
4215 }
4216 
4217 void Aura::HandlePeriodicDamage(bool apply, bool Real)
4218 {
4219  // spells required only Real aura add/remove
4220  if (!Real)
4221  return;
4222 
4223  if (m_periodicTimer <= 0)
4225 
4226  m_isPeriodic = apply;
4227 
4228  // For prevent double apply bonuses
4229  bool loading = (m_target->GetTypeId() == TYPEID_PLAYER && m_target->ToPlayer()->GetSession()->PlayerLoading());
4230 
4231  Unit* caster = GetCaster();
4232 
4233  switch (m_spellProto->SpellFamilyName)
4234  {
4235  case SPELLFAMILY_GENERIC:
4236  {
4237  // Pounce Bleed
4238  if (m_spellProto->SpellIconID == 147 && m_spellProto->SpellVisual == 0)
4239  {
4240  // $AP*0.18/6 bonus per tick
4241  if (apply && !loading && caster)
4243  return;
4244  }
4245  break;
4246  }
4247  case SPELLFAMILY_WARRIOR:
4248  {
4249  // Rend
4250  if (m_spellProto->SpellFamilyFlags & 0x0000000000000020LL)
4251  {
4252  // 0.00743*(($MWB+$mwb)/2+$AP/14*$MWS) bonus per tick
4253  if (apply && !loading && caster)
4254  {
4255  float ap = caster->GetTotalAttackPowerValue(BASE_ATTACK);
4256  int32 mws = caster->GetAttackTime(BASE_ATTACK);
4257  float mwb_min = caster->GetWeaponDamageRange(BASE_ATTACK, MINDAMAGE);
4258  float mwb_max = caster->GetWeaponDamageRange(BASE_ATTACK, MAXDAMAGE);
4259  // WARNING! in 3.0 multiplier 0.00743f change to 0.6
4260  m_modifier.m_amount += int32(((mwb_min + mwb_max) / 2 + ap * mws / 14000) * 0.00743f);
4261  }
4262  return;
4263  }
4264  break;
4265  }
4266  case SPELLFAMILY_DRUID:
4267  {
4268  // Rake
4269  if (m_spellProto->SpellFamilyFlags & 0x0000000000001000LL)
4270  {
4271  // $AP*0.06/3 bonus per tick
4272  if (apply && !loading && caster)
4274  return;
4275  }
4276  // Lacerate
4277  if (m_spellProto->SpellFamilyFlags & 0x000000010000000000LL)
4278  {
4279  // $AP*0.05/5 bonus per tick
4280  if (apply && !loading && caster)
4282  return;
4283  }
4284  // Rip
4285  if (m_spellProto->SpellFamilyFlags & 0x000000000000800000LL)
4286  {
4287  // $AP * min(0.06*$cp, 0.24)/6 [Yes, there is no difference, whether 4 or 5 CPs are being used]
4288  if (apply && !loading && caster && caster->GetTypeId() == TYPEID_PLAYER)
4289  {
4290  uint8 cp = caster->ToPlayer()->GetComboPoints();
4291 
4292  // Idol of Feral Shadows. Cant be handled as SpellMod in SpellAura:Dummy due its dependency from CPs
4293  Unit::AuraList const& dummyAuras = caster->GetAurasByType(SPELL_AURA_DUMMY);
4294  for (Unit::AuraList::const_iterator itr = dummyAuras.begin(); itr != dummyAuras.end(); ++itr)
4295  {
4296  if ((*itr)->GetId() == 34241)
4297  {
4298  m_modifier.m_amount += cp * (*itr)->GetModifier()->m_amount;
4299  break;
4300  }
4301  }
4302 
4303  if (cp > 4) cp = 4;
4305  }
4306  return;
4307  }
4308  break;
4309  }
4310  case SPELLFAMILY_ROGUE:
4311  {
4312  // Deadly poison aura state
4313  if ((m_spellProto->SpellFamilyFlags & 0x10000) && m_spellProto->SpellVisual == 5100)
4314  {
4315  if (apply)
4317  else
4318  {
4319  // current aura already removed, search present of another
4320  bool found = false;
4322  for (Unit::AuraList::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
4323  {
4324  SpellEntry const* itr_spell = (*itr)->GetSpellProto();
4325  if (itr_spell && itr_spell->SpellFamilyName == SPELLFAMILY_ROGUE && (itr_spell->SpellFamilyFlags & 0x10000) && itr_spell->SpellVisual == 5100)
4326  {
4327  found = true;
4328  break;
4329  }
4330  }
4331  // this has been last deadly poison aura
4332  if (!found)
4334  }
4335  return;
4336  }
4337  // Rupture
4338  if (m_spellProto->SpellFamilyFlags & 0x000000000000100000LL)
4339  {
4340  // Dmg/tick = $AP*min(0.01*$cp, 0.03) [Like Rip: only the first three CP increase the contribution from AP]
4341  if (apply && !loading && caster && caster->GetTypeId() == TYPEID_PLAYER)
4342  {
4343  uint8 cp = caster->ToPlayer()->GetComboPoints();
4344  if (cp > 3) cp = 3;
4346  }
4347  return;
4348  }
4349  // Garrote
4350  if (m_spellProto->SpellFamilyFlags & 0x000000000000000100LL)
4351  {
4352  // $AP*0.18/6 bonus per tick
4353  if (apply && !loading && caster)
4355  return;
4356  }
4357  break;
4358  }
4359  case SPELLFAMILY_HUNTER:
4360  {
4361  // Serpent Sting
4362  if (m_spellProto->SpellFamilyFlags & 0x0000000000004000LL)
4363  {
4364  // $RAP*0.1/5 bonus per tick
4365  if (apply && !loading && caster)
4367  return;
4368  }
4369  // Immolation Trap
4370  if (m_spellProto->SpellFamilyFlags & 0x0000000000000004LL && m_spellProto->SpellIconID == 678)
4371  {
4372  // $RAP*0.1/5 bonus per tick
4373  if (apply && !loading && caster)
4375  return;
4376  }
4377  break;
4378  }
4379  case SPELLFAMILY_PALADIN:
4380  {
4381  // Consecration
4382  if (m_spellProto->SpellFamilyFlags & 0x0000000000000020LL)
4383  {
4384  if (apply && !loading)
4385  {
4386  if (Unit* caster = GetCaster())
4387  {
4388  Unit::AuraList const& classScripts = caster->GetAurasByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS);
4389  for (Unit::AuraList::const_iterator k = classScripts.begin(); k != classScripts.end(); ++k)
4390  {
4392  switch ((*k)->GetModifier()->m_miscvalue)
4393  {
4394  case 5147: // Improved Consecration - Libram of the Eternal Rest
4395  {
4396  m_modifier.m_amount += (*k)->GetModifier()->m_amount / tickcount;
4397  break;
4398  }
4399  }
4400  }
4401  }
4402  }
4403  return;
4404  }
4405  break;
4406  }
4407  default:
4408  break;
4409  }
4410 }
4411 
4412 void Aura::HandlePeriodicDamagePCT(bool apply, bool /*Real*/)
4413 {
4414  if (m_periodicTimer <= 0)
4416 
4417  m_isPeriodic = apply;
4418 }
4419 
4420 void Aura::HandlePeriodicLeech(bool apply, bool /*Real*/)
4421 {
4422  if (m_periodicTimer <= 0)
4424 
4425  m_isPeriodic = apply;
4426 }
4427 
4428 void Aura::HandlePeriodicManaLeech(bool apply, bool /*Real*/)
4429 {
4430  if (m_periodicTimer <= 0)
4432 
4433  m_isPeriodic = apply;
4434 }
4435 
4436 /*********************************************************/
4437 /*** MODIFY STATS ***/
4438 /*********************************************************/
4439 
4440 /********************************/
4441 /*** RESISTANCE ***/
4442 /********************************/
4443 
4445 {
4446  for (int8 x = SPELL_SCHOOL_NORMAL; x < MAX_SPELL_SCHOOL; x++)
4447  {
4448  if (m_modifier.m_miscvalue & int32(1 << x))
4449  {
4451  if (m_target->GetTypeId() == TYPEID_PLAYER)
4453  }
4454  }
4455 }
4456 
4457 void Aura::HandleAuraModResistance(bool apply, bool /*Real*/)
4458 {
4459  for (int8 x = SPELL_SCHOOL_NORMAL; x < MAX_SPELL_SCHOOL; x++)
4460  {
4461  if (m_modifier.m_miscvalue & int32(1 << x))
4462  {
4464  if (m_target->GetTypeId() == TYPEID_PLAYER || m_target->IsPet())
4466  }
4467  }
4468 
4469  // Faerie Fire (druid versions)
4470  if ((m_spellProto->SpellIconID == 109 &&
4472  m_spellProto->SpellFamilyFlags & 0x0000000000000400LL)
4473  || m_spellProto->Id == 35325)
4475 }
4476 
4478 {
4479  // only players have base stats
4480  if (m_target->GetTypeId() != TYPEID_PLAYER)
4481  {
4482  //pets only have base armor
4485  }
4486  else
4487  {
4488  for (int8 x = SPELL_SCHOOL_NORMAL; x < MAX_SPELL_SCHOOL; x++)
4489  {
4490  if (m_modifier.m_miscvalue & int32(1 << x))
4492  }
4493  }
4494 }
4495 
4496 void Aura::HandleModResistancePercent(bool apply, bool /*Real*/)
4497 {
4498  for (int8 i = SPELL_SCHOOL_NORMAL; i < MAX_SPELL_SCHOOL; i++)
4499  {
4500  if (m_modifier.m_miscvalue & int32(1 << i))
4501  {
4503  if (m_target->GetTypeId() == TYPEID_PLAYER || m_target->IsPet())
4504  {
4507  }
4508  }
4509  }
4510 }
4511 
4512 void Aura::HandleModBaseResistance(bool apply, bool /*Real*/)
4513 {
4514  // only players have base stats
4515  if (m_target->GetTypeId() != TYPEID_PLAYER)
4516  {
4517  //only pets have base stats
4520  }
4521  else
4522  {
4523  for (int i = SPELL_SCHOOL_NORMAL; i < MAX_SPELL_SCHOOL; i++)
4524  if (m_modifier.m_miscvalue & (1 << i))
4526  }
4527 }
4528 
4529 /********************************/
4530 /*** STAT ***/
4531 /********************************/
4532 
4533 void Aura::HandleAuraModStat(bool apply, bool /*Real*/)
4534 {
4535  if (m_modifier.m_miscvalue < -2 || m_modifier.m_miscvalue > 4)
4536  {
4537  sLog.outError("WARNING: Spell %u effect %u has unsupported misc value (%i) for SPELL_AURA_MOD_STAT ", GetId(), GetEffIndex(), m_modifier.m_miscvalue);
4538  return;
4539  }
4540 
4541  if (apply && GetId() == 20007) // Crusader enchant proc: Holy Strength
4542  {
4543  uint32 lvldiff = m_target->getLevel() - 60;
4544  uint32 diff = lvldiff > 0 ? lvldiff * 4 : 0;
4546  }
4547 
4548  for (int32 i = STAT_STRENGTH; i < MAX_STATS; i++)
4549  {
4550  // -1 or -2 is all stats (misc < -2 checked in function beginning)
4551  if (m_modifier.m_miscvalue < 0 || m_modifier.m_miscvalue == i)
4552  {
4553  //m_target->ApplyStatMod(Stats(i), m_modifier.m_amount,apply);
4555  if (m_target->GetTypeId() == TYPEID_PLAYER || m_target->IsPet())
4556  m_target->ApplyStatBuffMod(Stats(i), (float)GetModifierValue(), apply);
4557  }
4558  }
4559 }
4560 
4561 void Aura::HandleModPercentStat(bool apply, bool /*Real*/)
4562 {
4563  if (m_modifier.m_miscvalue < -1 || m_modifier.m_miscvalue > 4)
4564  {
4565  sLog.outError("WARNING: Misc Value for SPELL_AURA_MOD_PERCENT_STAT not valid");
4566  return;
4567  }
4568 
4569  // only players have base stats
4570  if (m_target->GetTypeId() != TYPEID_PLAYER)
4571  return;
4572 
4573  for (int32 i = STAT_STRENGTH; i < MAX_STATS; ++i)
4574  {
4575  if (m_modifier.m_miscvalue == i || m_modifier.m_miscvalue == -1)
4577  }
4578 }
4579 
4580 void Aura::HandleModSpellDamagePercentFromStat(bool /*apply*/, bool /*Real*/)
4581 {
4582  if (m_target->GetTypeId() != TYPEID_PLAYER)
4583  return;
4584 
4585  // Magic damage modifiers implemented in Unit::SpellDamageBonus
4586  // This information for client side use only
4587  // Recalculate bonus
4589 }
4590 
4591 void Aura::HandleModSpellHealingPercentFromStat(bool /*apply*/, bool /*Real*/)
4592 {
4593  if (m_target->GetTypeId() != TYPEID_PLAYER)
4594  return;
4595 
4596  // Recalculate bonus
4598 }
4599 
4601 {
4602  if (!Real || !apply)
4603  return;
4604 
4605  if (GetId() == 33206)
4606  m_target->CastSpell(m_target, 44416, true, NULL, this, GetCasterGUID());
4607 }
4608 
4609 void Aura::HandleModSpellDamagePercentFromAttackPower(bool /*apply*/, bool /*Real*/)
4610 {
4611  if (m_target->GetTypeId() != TYPEID_PLAYER)
4612  return;
4613 
4614  // Magic damage modifiers implemented in Unit::SpellDamageBonus
4615  // This information for client side use only
4616  // Recalculate bonus
4618 }
4619 
4620 void Aura::HandleModSpellHealingPercentFromAttackPower(bool /*apply*/, bool /*Real*/)
4621 {
4622  if (m_target->GetTypeId() != TYPEID_PLAYER)
4623  return;
4624 
4625  // Recalculate bonus
4627 }
4628 
4629 void Aura::HandleModHealingDone(bool /*apply*/, bool /*Real*/)
4630 {
4631  if (m_target->GetTypeId() != TYPEID_PLAYER)
4632  return;
4633  // implemented in Unit::SpellHealingBonus
4634  // this information is for client side only
4636 }
4637 
4638 void Aura::HandleModTotalPercentStat(bool apply, bool /*Real*/)
4639 {
4640  if (m_modifier.m_miscvalue < -1 || m_modifier.m_miscvalue > 4)
4641  {
4642  sLog.outError("WARNING: Misc Value for SPELL_AURA_MOD_PERCENT_STAT not valid");
4643  return;
4644  }
4645 
4646  // save current health state
4647  float healthPct = m_target->GetHealthPct();
4648  bool alive = m_target->IsAlive();
4649 
4650  for (int32 i = STAT_STRENGTH; i < MAX_STATS; ++i)
4651  {
4652  if (m_modifier.m_miscvalue == i || m_modifier.m_miscvalue == -1)
4653  {
4655  if (m_target->GetTypeId() == TYPEID_PLAYER || m_target->IsPet())
4657  }
4658  }
4659 
4660  //recalculate current HP/MP after applying aura modifications (only for spells with 0x10 flag)
4662  m_target->SetHealth(std::max<uint32>(uint32(healthPct * m_target->GetMaxHealth() * 0.01f), (alive ? 1 : 0)));
4663 }
4664 
4665 void Aura::HandleAuraModResistenceOfStatPercent(bool /*apply*/, bool /*Real*/)
4666 {
4667  if (m_target->GetTypeId() != TYPEID_PLAYER)