[4374] * Removed some wrong SubVersion properties.
[mangos-git.git] / src / game / SpellAuras.cpp
blob75a2ca8e5a19fb78d28cf3c5483a7cc210db16bd
1 /*
2 * Copyright (C) 2005,2006,2007 MaNGOS <http://www.mangosproject.org/>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 #include "Common.h"
20 #include "Database/DatabaseEnv.h"
21 #include "WorldPacket.h"
22 #include "WorldSession.h"
23 #include "Opcodes.h"
24 #include "Log.h"
25 #include "UpdateMask.h"
26 #include "World.h"
27 #include "ObjectMgr.h"
28 #include "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 "Policies/SingletonImp.h"
38 #include "Totem.h"
39 #include "Creature.h"
40 #include "ConfusedMovementGenerator.h"
41 #include "TargetedMovementGenerator.h"
42 #include "Formulas.h"
43 #include "BattleGround.h"
44 #include "BattleGroundAV.h"
45 #include "BattleGroundAB.h"
46 #include "BattleGroundEY.h"
47 #include "BattleGroundWS.h"
48 #include "CreatureAI.h"
50 pAuraHandler AuraHandler[TOTAL_AURAS]=
52 &Aura::HandleNULL, // 0 SPELL_AURA_NONE
53 &Aura::HandleBindSight, // 1 SPELL_AURA_BIND_SIGHT
54 &Aura::HandleModPossess, // 2 SPELL_AURA_MOD_POSSESS
55 &Aura::HandlePeriodicDamage, // 3 SPELL_AURA_PERIODIC_DAMAGE
56 &Aura::HandleAuraDummy, // 4 SPELL_AURA_DUMMY
57 &Aura::HandleModConfuse, // 5 SPELL_AURA_MOD_CONFUSE
58 &Aura::HandleModCharm, // 6 SPELL_AURA_MOD_CHARM
59 &Aura::HandleModFear, // 7 SPELL_AURA_MOD_FEAR
60 &Aura::HandlePeriodicHeal, // 8 SPELL_AURA_PERIODIC_HEAL
61 &Aura::HandleModAttackSpeed, // 9 SPELL_AURA_MOD_ATTACKSPEED
62 &Aura::HandleModThreat, // 10 SPELL_AURA_MOD_THREAT
63 &Aura::HandleModTaunt, // 11 SPELL_AURA_MOD_TAUNT
64 &Aura::HandleAuraModStun, // 12 SPELL_AURA_MOD_STUN
65 &Aura::HandleModDamageDone, // 13 SPELL_AURA_MOD_DAMAGE_DONE
66 &Aura::HandleNoImmediateEffect, // 14 SPELL_AURA_MOD_DAMAGE_TAKEN
67 &Aura::HandleAuraDamageShield, // 15 SPELL_AURA_DAMAGE_SHIELD
68 &Aura::HandleModStealth, // 16 SPELL_AURA_MOD_STEALTH
69 &Aura::HandleModStealthDetect, // 17 SPELL_AURA_MOD_STEALTH_DETECT
70 &Aura::HandleInvisibility, // 18 SPELL_AURA_MOD_INVISIBILITY
71 &Aura::HandleInvisibilityDetect, // 19 SPELL_AURA_MOD_INVISIBILITY_DETECTION
72 &Aura::HandleAuraModTotalHealthPercentRegen, // 20 SPELL_AURA_OBS_MOD_HEALTH
73 &Aura::HandleAuraModTotalManaPercentRegen, // 21 SPELL_AURA_OBS_MOD_MANA
74 &Aura::HandleAuraModResistance, // 22 SPELL_AURA_MOD_RESISTANCE
75 &Aura::HandlePeriodicTriggerSpell, // 23 SPELL_AURA_PERIODIC_TRIGGER_SPELL
76 &Aura::HandlePeriodicEnergize, // 24 SPELL_AURA_PERIODIC_ENERGIZE
77 &Aura::HandleAuraModPacify, // 25 SPELL_AURA_MOD_PACIFY
78 &Aura::HandleAuraModRoot, // 26 SPELL_AURA_MOD_ROOT
79 &Aura::HandleAuraModSilence, // 27 SPELL_AURA_MOD_SILENCE
80 &Aura::HandleNoImmediateEffect, // 28 SPELL_AURA_REFLECT_SPELLS
81 &Aura::HandleAuraModStat, // 29 SPELL_AURA_MOD_STAT
82 &Aura::HandleAuraModSkill, // 30 SPELL_AURA_MOD_SKILL
83 &Aura::HandleAuraModIncreaseSpeed, // 31 SPELL_AURA_MOD_INCREASE_SPEED
84 &Aura::HandleAuraModIncreaseMountedSpeed, // 32 SPELL_AURA_MOD_INCREASE_MOUNTED_SPEED
85 &Aura::HandleAuraModDecreaseSpeed, // 33 SPELL_AURA_MOD_DECREASE_SPEED
86 &Aura::HandleAuraModIncreaseHealth, // 34 SPELL_AURA_MOD_INCREASE_HEALTH
87 &Aura::HandleAuraModIncreaseEnergy, // 35 SPELL_AURA_MOD_INCREASE_ENERGY
88 &Aura::HandleAuraModShapeshift, // 36 SPELL_AURA_MOD_SHAPESHIFT
89 &Aura::HandleAuraModEffectImmunity, // 37 SPELL_AURA_EFFECT_IMMUNITY
90 &Aura::HandleAuraModStateImmunity, // 38 SPELL_AURA_STATE_IMMUNITY
91 &Aura::HandleAuraModSchoolImmunity, // 39 SPELL_AURA_SCHOOL_IMMUNITY
92 &Aura::HandleAuraModDmgImmunity, // 40 SPELL_AURA_DAMAGE_IMMUNITY
93 &Aura::HandleAuraModDispelImmunity, // 41 SPELL_AURA_DISPEL_IMMUNITY
94 &Aura::HandleAuraProcTriggerSpell, // 42 SPELL_AURA_PROC_TRIGGER_SPELL
95 &Aura::HandleAuraProcTriggerDamage, // 43 SPELL_AURA_PROC_TRIGGER_DAMAGE
96 &Aura::HandleAuraTrackCreatures, // 44 SPELL_AURA_TRACK_CREATURES
97 &Aura::HandleAuraTrackResources, // 45 SPELL_AURA_TRACK_RESOURCES
98 &Aura::HandleNULL, // 46 SPELL_AURA_MOD_PARRY_SKILL obsolete?
99 &Aura::HandleAuraModParryPercent, // 47 SPELL_AURA_MOD_PARRY_PERCENT
100 &Aura::HandleNULL, // 48 SPELL_AURA_MOD_DODGE_SKILL obsolete?
101 &Aura::HandleAuraModDodgePercent, // 49 SPELL_AURA_MOD_DODGE_PERCENT
102 &Aura::HandleNULL, // 50 SPELL_AURA_MOD_BLOCK_SKILL obsolete?
103 &Aura::HandleAuraModBlockPercent, // 51 SPELL_AURA_MOD_BLOCK_PERCENT
104 &Aura::HandleAuraModCritPercent, // 52 SPELL_AURA_MOD_CRIT_PERCENT
105 &Aura::HandlePeriodicLeech, // 53 SPELL_AURA_PERIODIC_LEECH
106 &Aura::HandleModHitChance, // 54 SPELL_AURA_MOD_HIT_CHANCE
107 &Aura::HandleModSpellHitChance, // 55 SPELL_AURA_MOD_SPELL_HIT_CHANCE
108 &Aura::HandleAuraTransform, // 56 SPELL_AURA_TRANSFORM
109 &Aura::HandleModSpellCritChance, // 57 SPELL_AURA_MOD_SPELL_CRIT_CHANCE
110 &Aura::HandleAuraModIncreaseSwimSpeed, // 58 SPELL_AURA_MOD_INCREASE_SWIM_SPEED
111 &Aura::HandleNoImmediateEffect, // 59 SPELL_AURA_MOD_DAMAGE_DONE_CREATURE
112 &Aura::HandleNULL, // 60 SPELL_AURA_MOD_PACIFY_SILENCE
113 &Aura::HandleAuraModScale, // 61 SPELL_AURA_MOD_SCALE
114 &Aura::HandleNULL, // 62 SPELL_AURA_PERIODIC_HEALTH_FUNNEL
115 &Aura::HandleNULL, // 63 SPELL_AURA_PERIODIC_MANA_FUNNEL
116 &Aura::HandlePeriodicManaLeech, // 64 SPELL_AURA_PERIODIC_MANA_LEECH
117 &Aura::HandleModCastingSpeed, // 65 SPELL_AURA_MOD_CASTING_SPEED
118 &Aura::HandleFeignDeath, // 66 SPELL_AURA_FEIGN_DEATH
119 &Aura::HandleAuraModDisarm, // 67 SPELL_AURA_MOD_DISARM
120 &Aura::HandleAuraModStalked, // 68 SPELL_AURA_MOD_STALKED
121 &Aura::HandleAuraSchoolAbsorb, // 69 SPELL_AURA_SCHOOL_ABSORB
122 &Aura::HandleNULL, // 70 SPELL_AURA_EXTRA_ATTACKS Useless
123 &Aura::HandleModSpellCritChanceShool, // 71 SPELL_AURA_MOD_SPELL_CRIT_CHANCE_SCHOOL
124 &Aura::HandleModPowerCost, // 72 SPELL_AURA_MOD_POWER_COST
125 &Aura::HandleNoImmediateEffect, // 73 SPELL_AURA_MOD_POWER_COST_SCHOOL
126 &Aura::HandleNoImmediateEffect, // 74 SPELL_AURA_REFLECT_SPELLS_SCHOOL
127 &Aura::HandleNoImmediateEffect, // 75 SPELL_AURA_MOD_LANGUAGE
128 &Aura::HandleFarSight, // 76 SPELL_AURA_FAR_SIGHT
129 &Aura::HandleModMechanicImmunity, // 77 SPELL_AURA_MECHANIC_IMMUNITY
130 &Aura::HandleAuraMounted, // 78 SPELL_AURA_MOUNTED
131 &Aura::HandleModDamagePercentDone, // 79 SPELL_AURA_MOD_DAMAGE_PERCENT_DONE
132 &Aura::HandleModPercentStat, // 80 SPELL_AURA_MOD_PERCENT_STAT
133 &Aura::HandleNULL, // 81 SPELL_AURA_SPLIT_DAMAGE
134 &Aura::HandleWaterBreathing, // 82 SPELL_AURA_WATER_BREATHING
135 &Aura::HandleModBaseResistance, // 83 SPELL_AURA_MOD_BASE_RESISTANCE
136 &Aura::HandleModRegen, // 84 SPELL_AURA_MOD_REGEN
137 &Aura::HandleModPowerRegen, // 85 SPELL_AURA_MOD_POWER_REGEN
138 &Aura::HandleChannelDeathItem, // 86 SPELL_AURA_CHANNEL_DEATH_ITEM
139 &Aura::HandleNoImmediateEffect, // 87 SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN
140 &Aura::HandleNoImmediateEffect, // 88 SPELL_AURA_MOD_HEALTH_REGEN_PERCENT
141 &Aura::HandlePeriodicDamagePCT, // 89 SPELL_AURA_PERIODIC_DAMAGE_PERCENT
142 &Aura::HandleNULL, // 90 SPELL_AURA_MOD_RESIST_CHANCE Useless
143 &Aura::HandleNoImmediateEffect, // 91 SPELL_AURA_MOD_DETECT_RANGE
144 &Aura::HandleNULL, // 92 SPELL_AURA_PREVENTS_FLEEING
145 &Aura::HandleNULL, // 93 SPELL_AURA_MOD_UNATTACKABLE
146 &Aura::HandleInterruptRegen, // 94 SPELL_AURA_INTERRUPT_REGEN
147 &Aura::HandleAuraGhost, // 95 SPELL_AURA_GHOST
148 &Aura::HandleNULL, // 96 SPELL_AURA_SPELL_MAGNET
149 &Aura::HandleAuraManaShield, // 97 SPELL_AURA_MANA_SHIELD
150 &Aura::HandleAuraModSkill, // 98 SPELL_AURA_MOD_SKILL_TALENT
151 &Aura::HandleAuraModAttackPower, // 99 SPELL_AURA_MOD_ATTACK_POWER
152 &Aura::HandleNULL, //100 SPELL_AURA_AURAS_VISIBLE
153 &Aura::HandleModResistancePercent, //101 SPELL_AURA_MOD_RESISTANCE_PCT
154 &Aura::HandleNoImmediateEffect, //102 SPELL_AURA_MOD_CREATURE_ATTACK_POWER
155 &Aura::HandleAuraModTotalThreat, //103 SPELL_AURA_MOD_TOTAL_THREAT
156 &Aura::HandleAuraWaterWalk, //104 SPELL_AURA_WATER_WALK
157 &Aura::HandleAuraFeatherFall, //105 SPELL_AURA_FEATHER_FALL
158 &Aura::HandleAuraHover, //106 SPELL_AURA_HOVER
159 &Aura::HandleAddModifier, //107 SPELL_AURA_ADD_FLAT_MODIFIER
160 &Aura::HandleAddModifier, //108 SPELL_AURA_ADD_PCT_MODIFIER
161 &Aura::HandleNoImmediateEffect, //109 SPELL_AURA_ADD_TARGET_TRIGGER
162 &Aura::HandleNoImmediateEffect, //110 SPELL_AURA_MOD_POWER_REGEN_PERCENT
163 &Aura::HandleNULL, //111 SPELL_AURA_ADD_CASTER_HIT_TRIGGER
164 &Aura::HandleNoImmediateEffect, //112 SPELL_AURA_OVERRIDE_CLASS_SCRIPTS
165 &Aura::HandleNoImmediateEffect, //113 SPELL_AURA_MOD_RANGED_DAMAGE_TAKEN
166 &Aura::HandleNoImmediateEffect, //114 SPELL_AURA_MOD_RANGED_DAMAGE_TAKEN_PCT
167 &Aura::HandleAuraHealing, //115 SPELL_AURA_MOD_HEALING
168 &Aura::HandleNoImmediateEffect, //116 SPELL_AURA_MOD_REGEN_DURING_COMBAT
169 &Aura::HandleNoImmediateEffect, //117 SPELL_AURA_MOD_MECHANIC_RESISTANCE
170 &Aura::HandleAuraHealingPct, //118 SPELL_AURA_MOD_HEALING_PCT
171 &Aura::HandleNULL, //119 SPELL_AURA_SHARE_PET_TRACKING useless
172 &Aura::HandleAuraUntrackable, //120 SPELL_AURA_UNTRACKABLE
173 &Aura::HandleAuraEmpathy, //121 SPELL_AURA_EMPATHY
174 &Aura::HandleModOffhandDamagePercent, //122 SPELL_AURA_MOD_OFFHAND_DAMAGE_PCT
175 &Aura::HandleModTargetResistance, //123 SPELL_AURA_MOD_TARGET_RESISTANCE
176 &Aura::HandleAuraModRangedAttackPower, //124 SPELL_AURA_MOD_RANGED_ATTACK_POWER
177 &Aura::HandleNoImmediateEffect, //125 SPELL_AURA_MOD_MELEE_DAMAGE_TAKEN
178 &Aura::HandleNoImmediateEffect, //126 SPELL_AURA_MOD_MELEE_DAMAGE_TAKEN_PCT
179 &Aura::HandleNoImmediateEffect, //127 SPELL_AURA_RANGED_ATTACK_POWER_ATTACKER_BONUS
180 &Aura::HandleModPossessPet, //128 SPELL_AURA_MOD_POSSESS_PET
181 &Aura::HandleAuraModIncreaseSpeedAlways, //129 SPELL_AURA_MOD_INCREASE_SPEED_ALWAYS
182 &Aura::HandleNULL, //130 SPELL_AURA_MOD_MOUNTED_SPEED_ALWAYS
183 &Aura::HandleNULL, //131 SPELL_AURA_MOD_CREATURE_RANGED_ATTACK_POWER
184 &Aura::HandleAuraModIncreaseEnergyPercent, //132 SPELL_AURA_MOD_INCREASE_ENERGY_PERCENT
185 &Aura::HandleAuraModIncreaseHealthPercent, //133 SPELL_AURA_MOD_INCREASE_HEALTH_PERCENT
186 &Aura::HandleNoImmediateEffect, //134 SPELL_AURA_MOD_MANA_REGEN_INTERRUPT
187 &Aura::HandleModHealingDone, //135 SPELL_AURA_MOD_HEALING_DONE
188 &Aura::HandleAuraHealingPct, //136 SPELL_AURA_MOD_HEALING_DONE_PERCENT implemented in Unit::SpellHealingBonus
189 &Aura::HandleModTotalPercentStat, //137 SPELL_AURA_MOD_TOTAL_STAT_PERCENTAGE
190 &Aura::HandleHaste, //138 SPELL_AURA_MOD_HASTE
191 &Aura::HandleForceReaction, //139 SPELL_AURA_FORCE_REACTION
192 &Aura::HandleAuraModRangedHaste, //140 SPELL_AURA_MOD_RANGED_HASTE
193 &Aura::HandleRangedAmmoHaste, //141 SPELL_AURA_MOD_RANGED_AMMO_HASTE
194 &Aura::HandleAuraModBaseResistancePCT, //142 SPELL_AURA_MOD_BASE_RESISTANCE_PCT
195 &Aura::HandleAuraModResistanceExclusive, //143 SPELL_AURA_MOD_RESISTANCE_EXCLUSIVE
196 &Aura::HandleAuraSafeFall, //144 SPELL_AURA_SAFE_FALL
197 &Aura::HandleNULL, //145 SPELL_AURA_CHARISMA
198 &Aura::HandleNULL, //146 SPELL_AURA_PERSUADED
199 &Aura::HandleNULL, //147 SPELL_AURA_ADD_CREATURE_IMMUNITY
200 &Aura::HandleAuraRetainComboPoints, //148 SPELL_AURA_RETAIN_COMBO_POINTS
201 &Aura::HandleNoImmediateEffect, //149 SPELL_AURA_RESIST_PUSHBACK
202 &Aura::HandleShieldBlockValue, //150 SPELL_AURA_MOD_SHIELD_BLOCKVALUE_PCT
203 &Aura::HandleAuraTrackStealthed, //151 SPELL_AURA_TRACK_STEALTHED
204 &Aura::HandleNULL, //152 SPELL_AURA_MOD_DETECTED_RANGE
205 &Aura::HandleNULL, //153 SPELL_AURA_SPLIT_DAMAGE_FLAT
206 &Aura::HandleNoImmediateEffect, //154 SPELL_AURA_MOD_STEALTH_LEVEL
207 &Aura::HandleNoImmediateEffect, //155 SPELL_AURA_MOD_WATER_BREATHING
208 &Aura::HandleNoImmediateEffect, //156 SPELL_AURA_MOD_REPUTATION_GAIN
209 &Aura::HandleNULL, //157 SPELL_AURA_PET_DAMAGE_MULTI
210 &Aura::HandleShieldBlockValue, //158 SPELL_AURA_MOD_SHIELD_BLOCKVALUE
211 &Aura::HandleNULL, //159 SPELL_AURA_NO_PVP_CREDIT only for Honorless Target spell
212 &Aura::HandleNULL, //160 SPELL_AURA_MOD_AOE_AVOIDANCE
213 &Aura::HandleNoImmediateEffect, //161 SPELL_AURA_MOD_HEALTH_REGEN_IN_COMBAT
214 &Aura::HandleNULL, //162 SPELL_AURA_POWER_BURN_MANA
215 &Aura::HandleNULL, //163 SPELL_AURA_MOD_CRIT_DAMAGE_BONUS_MELEE
216 &Aura::HandleNULL, //164
217 &Aura::HandleNULL, //165 SPELL_AURA_MELEE_ATTACK_POWER_ATTACKER_BONUS
218 &Aura::HandleAuraModAttackPowerPercent, //166 SPELL_AURA_MOD_ATTACK_POWER_PCT
219 &Aura::HandleAuraModRangedAttackPowerPercent, //167 SPELL_AURA_MOD_RANGED_ATTACK_POWER_PCT
220 &Aura::HandleNULL, //168 SPELL_AURA_MOD_DAMAGE_DONE_VERSUS
221 &Aura::HandleNULL, //169 SPELL_AURA_MOD_CRIT_PERCENT_VERSUS
222 &Aura::HandleNULL, //170 SPELL_AURA_DETECT_AMORE only for Detect Amore spell
223 &Aura::HandleNULL, //171 SPELL_AURA_MOD_PARTY_SPEED unused
224 &Aura::HandleNULL, //172 SPELL_AURA_MOD_PARTY_SPEED_MOUNTED
225 &Aura::HandleNULL, //173 SPELL_AURA_ALLOW_CHAMPION_SPELLS only for Proclaim Champion spell
226 &Aura::HandleNoImmediateEffect, //174 SPELL_AURA_MOD_SPELL_DAMAGE_OF_SPIRIT implemented in Unit::SpellDamageBonus
227 &Aura::HandleNoImmediateEffect, //175 SPELL_AURA_MOD_SPELL_HEALING_OF_SPIRIT implemented in Unit::SpellHealingBonus
228 &Aura::HandleNULL, //176 SPELL_AURA_SPIRIT_OF_REDEMPTION only for Spirit of Redemption spell
229 &Aura::HandleNULL, //177 SPELL_AURA_AOE_CHARM
230 &Aura::HandleNULL, //178 SPELL_AURA_MOD_DEBUFF_RESISTANCE
231 &Aura::HandleNoImmediateEffect, //179 SPELL_AURA_MOD_ATTACKER_SPELL_CRIT_CHANCE implemented in Unit::SpellCriticalBonus
232 &Aura::HandleNULL, //180 SPELL_AURA_MOD_SPELL_DAMAGE_VS_UNDEAD,
233 &Aura::HandleNULL, //181 unused
234 &Aura::HandleNULL, //182 SPELL_AURA_MOD_ARMOR_OF_INTELLECT
235 &Aura::HandleNULL, //183 SPELL_AURA_MOD_CRITICAL_THREAT
236 &Aura::HandleNULL, //184 SPELL_AURA_MOD_ATTACKER_MELEE_HIT_CHANCE
237 &Aura::HandleNULL, //185 SPELL_AURA_MOD_ATTACKER_RANGED_HIT_CHANCE
238 &Aura::HandleNULL, //186 SPELL_AURA_MOD_ATTACKER_SPELL_HIT_CHANCE
239 &Aura::HandleNULL, //187 SPELL_AURA_MOD_ATTACKER_MELEE_CRIT_CHANCE
240 &Aura::HandleNULL, //188 SPELL_AURA_MOD_ATTACKER_RANGED_CRIT_CHANCE
241 &Aura::HandleModRating, //189 SPELL_AURA_MOD_RATING
242 &Aura::HandleNULL, //190 SPELL_AURA_MOD_FACTION_REPUTATION_GAIN
243 &Aura::HandleNULL, //191 SPELL_AURA_USE_NORMAL_MOVEMENT_SPEED
244 &Aura::HandleNULL, //192 SPELL_AURA_HASTE_MELEE
245 &Aura::HandleNULL, //193 SPELL_AURA_MELEE_SLOW
246 &Aura::HandleNoImmediateEffect, //194 SPELL_AURA_MOD_SPELL_DAMAGE_OF_INTELLECT implemented in Unit::SpellDamageBonus
247 &Aura::HandleNoImmediateEffect, //195 SPELL_AURA_MOD_SPELL_HEALING_OF_INTELLECT implemented in Unit::SpellHealingBonus
248 &Aura::HandleNULL, //196
249 &Aura::HandleNoImmediateEffect, //197 SPELL_AURA_MOD_ATTACKER_SPELL_AND_WEAPON_CRIT_CHANCE implemented in Unit::SpellCriticalBonus Unit::RollMeleeOutcomeAgainst Unit::RollPhysicalOutcomeAgainst
250 &Aura::HandleNULL, //198 SPELL_AURA_MOD_ALL_WEAPON_SKILLS
251 &Aura::HandleNULL, //199 SPELL_AURA_MOD_INCREASES_SPELL_PCT_TO_HIT
252 &Aura::HandleNoImmediateEffect, //200 SPELL_AURA_MOD_XP_PCT
253 &Aura::HandleAuraAllowFlight, //201 SPELL_AURA_FLY this aura probably must enable flight mode...
254 &Aura::HandleNULL, //202 SPELL_AURA_CANNOT_BE_DODGED
255 &Aura::HandleNULL, //203 SPELL_AURA_MOD_ATTACKER_MELEE_CRIT_DAMAGE
256 &Aura::HandleNULL, //204 SPELL_AURA_MOD_ATTACKER_RANGED_CRIT_DAMAGE
257 &Aura::HandleNULL, //205
258 &Aura::HandleNULL, //206 SPELL_AURA_MOD_SPEED_MOUNTED
259 &Aura::HandleAuraModSpeedMountedFlight, //207 SPELL_AURA_MOD_SPEED_MOUNTED_FLIGHT
260 &Aura::HandleAuraModSpeedFlight, //208 SPELL_AURA_MOD_SPEED_FLIGHT, used only in spell: Flight Form (Passive)
261 &Aura::HandleNULL, //209
262 &Aura::HandleNULL, //210
263 &Aura::HandleNULL, //211
264 &Aura::HandleNULL, //212 SPELL_AURA_MOD_RANGED_ATTACK_POWER_OF_INTELLECT
265 &Aura::HandleNoImmediateEffect, //213 SPELL_AURA_MOD_RAGE_FROM_DAMAGE_DEALT
266 &Aura::HandleNULL, //214
267 &Aura::HandleNULL, //215
268 &Aura::HandleModCastingSpeed, //216 SPELL_AURA_HASTE_SPELLS
269 &Aura::HandleNULL, //217 unused
270 &Aura::HandleNULL, //218 ranged attack haste?
271 &Aura::HandleModManaRegen, //219 SPELL_AURA_MOD_MANA_REGEN
272 &Aura::HandleNoImmediateEffect, //220 SPELL_AURA_MOD_SPELL_HEALING_OF_STRENGTH
273 &Aura::HandleNULL, //221 ignored
274 &Aura::HandleNULL, //222 unused
275 &Aura::HandleNULL, //223 unused
276 &Aura::HandleNULL, //224 unused
277 &Aura::HandleNULL, //225
278 &Aura::HandleNULL, //226
279 &Aura::HandleNULL, //227
280 &Aura::HandleNULL, //228 detection
281 &Aura::HandleNULL, //228 avoidance
282 &Aura::HandleAuraModIncreaseHealth, //230 Commanding Shout
283 &Aura::HandleNULL, //231
284 &Aura::HandleNULL, //232
285 &Aura::HandleNULL, //233
286 &Aura::HandleNULL //234 SPELL_AURA_SILENCE_RESISTANCE
289 Aura::Aura(SpellEntry const* spellproto, uint32 eff, int32 *currentBasePoints, Unit *target, Unit *caster, Item* castItem) :
290 m_procCharges(0), m_absorbDmg(0), m_spellmod(NULL), m_spellId(spellproto->Id), m_effIndex(eff), m_caster_guid(0), m_target(target),
291 m_timeCla(1000), m_castItemGuid(castItem?castItem->GetGUID():0), m_auraSlot(MAX_AURAS),
292 m_positive(false), m_permanent(false), m_isPeriodic(false), m_isTrigger(false), m_isAreaAura(false), m_isPersistent(false),
293 m_periodicTimer(0), m_PeriodicEventId(0), m_updated(false), m_removeOnDeath(false),m_fearMoveAngle(0)
295 assert(target);
297 assert(spellproto && spellproto == sSpellStore.LookupEntry( spellproto->Id ) && "`info` must be pointer to sSpellStore element");
299 m_spellProto = spellproto;
301 m_currentBasePoints = currentBasePoints ? *currentBasePoints : m_spellProto->EffectBasePoints[eff];
303 m_isPassive = IsPassiveSpell(m_spellId);
304 m_positive = IsPositiveEffect(m_spellId, m_effIndex);
306 m_applyTime = time(NULL);
308 uint32 type = 0;
309 if(!m_positive)
310 type = 1;
312 int32 damage;
313 if(!caster)
315 m_caster_guid = target->GetGUID();
316 damage = m_currentBasePoints+1; // stored value-1
317 target->CalculateSpellDamageAndDuration(NULL,&m_duration,m_spellProto,m_effIndex,m_currentBasePoints);
319 else
321 m_caster_guid = caster->GetGUID();
323 caster->CalculateSpellDamageAndDuration(&damage,&m_duration,m_spellProto,m_effIndex,m_currentBasePoints);
325 if (!damage && castItem && castItem->GetItemSuffixFactor())
327 ItemRandomSuffixEntry const *item_rand_suffix = sItemRandomSuffixStore.LookupEntry(abs(castItem->GetItemRandomPropertyId()));
328 if(item_rand_suffix)
330 for (int k=0; k<3; k++)
332 SpellItemEnchantmentEntry const *pEnchant = sSpellItemEnchantmentStore.LookupEntry(item_rand_suffix->enchant_id[k]);
333 if(pEnchant)
335 for (int t=0; t<3; t++)
336 if(pEnchant->spellid[t] == spellproto->Id)
338 damage = uint32((item_rand_suffix->prefix[k]*castItem->GetItemSuffixFactor()) / 10000 );
339 break;
343 if(damage)
344 break;
350 if(m_duration == -1 || m_isPassive && spellproto->DurationIndex == 0)
351 m_permanent = true;
353 if(!m_permanent && caster && caster->GetTypeId() == TYPEID_PLAYER)
354 ((Player *)caster)->ApplySpellMod(m_spellId, SPELLMOD_DURATION, m_duration);
356 sLog.outDebug("Aura: construct Spellid : %u, Aura : %u Duration : %d Target : %d Damage : %d", spellproto->Id, spellproto->EffectApplyAuraName[eff], m_duration, spellproto->EffectImplicitTargetA[eff],damage);
358 m_effIndex = eff;
359 SetModifier(spellproto->EffectApplyAuraName[eff], damage, spellproto->EffectAmplitude[eff], spellproto->EffectMiscValue[eff], type);
362 Aura::~Aura()
366 AreaAura::AreaAura(SpellEntry const* spellproto, uint32 eff, int32 *currentBasePoints, Unit *target,
367 Unit *caster, Item* castItem) : Aura(spellproto, eff, currentBasePoints, target, caster, castItem)
369 m_isAreaAura = true;
372 AreaAura::~AreaAura()
376 PersistentAreaAura::PersistentAreaAura(SpellEntry const* spellproto, uint32 eff, int32 *currentBasePoints, Unit *target,
377 Unit *caster, Item* castItem) : Aura(spellproto, eff, currentBasePoints, target, caster, castItem)
379 m_isPersistent = true;
382 PersistentAreaAura::~PersistentAreaAura()
386 Unit* Aura::GetCaster() const
388 if(m_caster_guid==m_target->GetGUID())
389 return m_target;
391 return ObjectAccessor::Instance().GetUnit(*m_target,m_caster_guid);
394 void Aura::SetModifier(uint8 t, int32 a, uint32 pt, int32 miscValue, uint32 miscValue2)
396 m_modifier.m_auraname = t;
397 m_modifier.m_amount = a;
398 m_modifier.m_miscvalue = miscValue;
399 m_modifier.m_miscvalue2 = miscValue2;
400 m_modifier.periodictime = pt;
403 void Aura::Update(uint32 diff)
405 if (m_duration > 0)
407 m_duration -= diff;
408 if (m_duration < 0)
409 m_duration = 0;
410 m_timeCla -= diff;
412 Unit* caster = GetCaster();
413 if(caster && m_timeCla <= 0)
415 Powers powertype = caster->getPowerType();
416 int32 manaPerSecond = GetSpellProto()->manaPerSecond;
417 int32 manaPerSecondPerLevel = uint32(GetSpellProto()->manaPerSecondPerLevel*caster->getLevel());
418 m_timeCla = 1000;
419 caster->ModifyPower(powertype,-manaPerSecond);
420 caster->ModifyPower(powertype,-manaPerSecondPerLevel);
422 if(caster && m_target->isAlive() && m_target->HasFlag(UNIT_FIELD_FLAGS,(UNIT_STAT_FLEEING<<16)))
424 int q = rand() % 80;
425 if(q == 8) m_fearMoveAngle += (float)(urand(45, 90));
426 else if(q == 23) m_fearMoveAngle -= (float)(urand(45, 90));
428 // If the m_target is player,and if the speed is too slow,change it :P
429 float speed = m_target->GetSpeed(MOVE_RUN);
430 // Speed modifier, may need to find correct one
431 float mod = m_target->GetTypeId() != TYPEID_PLAYER ? 10 : 6;
432 float pos_x = m_target->GetPositionX();
433 float pos_y = m_target->GetPositionY();
434 uint32 mapid = m_target->GetMapId();
435 float pos_z = MapManager::Instance().GetMap(mapid, m_target)->GetHeight(pos_x,pos_y, m_target->GetPositionZ());
436 // Control the max Distance; 28 for temp.
437 if(m_target->IsWithinDistInMap(caster, 28))
439 float x = m_target->GetPositionX() - (speed*cosf(m_fearMoveAngle))/mod;
440 float y = m_target->GetPositionY() - (speed*sinf(m_fearMoveAngle))/mod;
441 float z = MapManager::Instance().GetMap(mapid, m_target)->GetHeight(x,y, m_target->GetPositionZ());
442 // Control the target to not climb or drop when dz > |x|,x = 1.3 for temp.
443 // fixed me if it needs checking when the position will be in water?
444 //+vmaps
445 if((z<=pos_z+1.3 && z>=pos_z-1.3) && m_target->IsWithinLOS(x,y,z))
447 m_target->SendMonsterMove(x,y,z,0,true,(diff*2));
448 if(m_target->GetTypeId() != TYPEID_PLAYER)
449 MapManager::Instance().GetMap(m_target->GetMapId(), m_target)->CreatureRelocation((Creature*)m_target,x,y,z,m_target->GetOrientation());
451 else
453 //Complete the move only if z coord is now correct
454 m_fearMoveAngle += 120;
455 x = m_target->GetPositionX() + (speed*sinf(m_fearMoveAngle))/mod;
456 y = m_target->GetPositionY() + (speed*cosf(m_fearMoveAngle))/mod;
457 z = MapManager::Instance().GetMap(mapid, m_target)->GetHeight(x,y, m_target->GetPositionZ());
458 //+vmaps
459 if((z<=pos_z+1.3 && z>=pos_z-1.3) && m_target->IsWithinLOS(x,y,z))
461 m_target->SendMonsterMove(x,y,z,0,true,(diff*2));
462 if(m_target->GetTypeId() != TYPEID_PLAYER)
463 MapManager::Instance().GetMap(m_target->GetMapId(), m_target)->CreatureRelocation((Creature*)m_target,x,y,z,m_target->GetOrientation());
470 if(m_isPeriodic && (m_duration >= 0 || m_isPassive || m_permanent))
472 m_periodicTimer -= diff;
473 if(m_periodicTimer <= 0) // tick also at m_periodicTimer==0 to prevent lost last tick in case max m_duration == (max m_periodicTimer)*N
475 if( m_modifier.m_auraname == SPELL_AURA_MOD_REGEN ||
476 m_modifier.m_auraname == SPELL_AURA_MOD_POWER_REGEN ||
477 // Cannibalize, eating items and other spells
478 m_modifier.m_auraname == SPELL_AURA_OBS_MOD_HEALTH ||
479 // Eating items and other spells
480 m_modifier.m_auraname == SPELL_AURA_OBS_MOD_MANA ||
481 m_modifier.m_auraname == SPELL_AURA_MOD_MANA_REGEN )
483 ApplyModifier(true);
484 return;
486 // update before applying (aura can be removed in TriggerSpell or PeriodicAuraLog calls)
487 m_periodicTimer += m_modifier.periodictime;
489 if(m_isTrigger)
491 TriggerSpell();
493 else
495 if(Unit* caster = GetCaster())
496 caster->PeriodicAuraLog(m_target, GetSpellProto(), &m_modifier,GetEffIndex());
497 else
498 m_target->PeriodicAuraLog(m_target, GetSpellProto(), &m_modifier,GetEffIndex());
504 void AreaAura::Update(uint32 diff)
506 // update for the caster of the aura
507 if(m_caster_guid == m_target->GetGUID())
509 Unit* caster = m_target;
511 Group *pGroup = NULL;
512 if (caster->GetTypeId() == TYPEID_PLAYER)
513 pGroup = ((Player*)caster)->GetGroup();
514 else if(caster->GetCharmerOrOwnerGUID() != 0)
516 Unit *owner = caster->GetCharmerOrOwner();
517 if (owner && owner->GetTypeId() == TYPEID_PLAYER)
518 pGroup = ((Player*)owner)->GetGroup();
521 float radius = GetRadius(sSpellRadiusStore.LookupEntry(GetSpellProto()->EffectRadiusIndex[m_effIndex]));
522 if(pGroup)
524 for(GroupReference *itr = pGroup->GetFirstMember(); itr != NULL; itr = itr->next())
526 Player* Target = itr->getSource();
527 if(!Target)
528 continue;
530 if (caster->GetTypeId() == TYPEID_PLAYER)
532 if(Target->GetGUID() == m_caster_guid || !Target->isAlive() || !pGroup->SameSubGroup((Player*)caster, Target))
533 continue;
535 else if(caster->GetCharmerOrOwnerGUID() != 0)
537 Unit *owner = caster->GetCharmerOrOwner();
538 if(!Target->isAlive() || (owner->GetTypeId() == TYPEID_PLAYER && !pGroup->SameSubGroup((Player*)owner, Target)))
539 continue;
542 Aura *t_aura = Target->GetAura(m_spellId, m_effIndex);
544 if(caster->IsWithinDistInMap(Target, radius) )
546 // apply aura to players in range that dont have it yet
547 if (!t_aura)
549 AreaAura *aur = new AreaAura(GetSpellProto(), m_effIndex, &m_currentBasePoints, Target, caster);
550 Target->AddAura(aur);
553 else
555 // remove auras of the same caster from out of range players
556 if (t_aura)
557 if (t_aura->GetCasterGUID() == m_caster_guid)
558 Target->RemoveAura(m_spellId, m_effIndex);
562 else if (caster->GetCharmerOrOwnerGUID() != 0)
564 // add / remove auras from the totem's owner
565 Unit *owner = caster->GetCharmerOrOwner();
566 if (owner)
568 Aura *o_aura = owner->GetAura(m_spellId, m_effIndex);
569 if(caster->IsWithinDistInMap(owner, radius))
571 if (!o_aura)
573 AreaAura *aur = new AreaAura(GetSpellProto(), m_effIndex, &m_currentBasePoints, owner, caster);
574 owner->AddAura(aur);
577 else
579 if (o_aura)
580 if (o_aura->GetCasterGUID() == m_caster_guid)
581 owner->RemoveAura(m_spellId, m_effIndex);
587 if(m_caster_guid != m_target->GetGUID()) // aura at non-caster
589 Unit * tmp_target = m_target;
590 Unit* caster = GetCaster();
591 float radius = GetRadius(sSpellRadiusStore.LookupEntry(GetSpellProto()->EffectRadiusIndex[m_effIndex]));
592 uint32 tmp_spellId = m_spellId, tmp_effIndex = m_effIndex;
594 // WARNING: the aura may get deleted during the update
595 // DO NOT access its members after update!
596 Aura::Update(diff);
598 // remove aura if out-of-range from caster (after teleport for example)
599 if(!caster || !caster->IsWithinDistInMap(tmp_target, radius) )
600 tmp_target->RemoveAura(tmp_spellId, tmp_effIndex);
602 else Aura::Update(diff);
605 void PersistentAreaAura::Update(uint32 diff)
607 bool remove = false;
609 // remove the aura if its caster or the dynamic object causing it was removed
610 // or if the target moves too far from the dynamic object
611 Unit *caster = GetCaster();
612 if (caster)
614 DynamicObject *dynObj = caster->GetDynObject(GetId(), GetEffIndex());
615 if (dynObj)
617 if (!m_target->IsWithinDistInMap(dynObj, dynObj->GetRadius()))
618 remove = true;
620 else
621 remove = true;
623 else
624 remove = true;
626 Unit *tmp_target = m_target;
627 uint32 tmp_id = GetId(), tmp_index = GetEffIndex();
629 // WARNING: the aura may get deleted during the update
630 // DO NOT access its members after update!
631 Aura::Update(diff);
633 if(remove)
634 tmp_target->RemoveAura(tmp_id, tmp_index);
637 void Aura::ApplyModifier(bool apply, bool Real)
639 uint8 aura = 0;
640 aura = m_modifier.m_auraname;
642 if(aura<TOTAL_AURAS)
643 (*this.*AuraHandler [aura])(apply,Real);
646 void Aura::UpdateAuraDuration()
648 if(m_auraSlot >= MAX_AURAS || m_isPassive)
649 return;
651 if( m_target->GetTypeId() == TYPEID_PLAYER)
653 WorldPacket data(SMSG_UPDATE_AURA_DURATION, 5);
654 data << (uint8)m_auraSlot << (uint32)m_duration;
655 ((Player*)m_target)->SendDirectMessage(&data);
658 Unit* caster = GetCaster();
660 if(caster && caster->GetTypeId() == TYPEID_PLAYER && caster != m_target)
662 WorldPacket data(SMSG_SET_AURA_SINGLE, (8+2+4+4+4));
663 data.append(m_target->GetPackGUID());
664 data << uint8(m_auraSlot);
665 data << uint32(GetSpellProto()->Id);
666 data << uint32(GetAuraDuration()); // full
667 data << uint32(GetAuraDuration()); // remain
668 ((Player*)caster)->GetSession()->SendPacket(&data);
672 void Aura::_AddAura()
674 if (!m_spellId)
675 return;
676 if(!m_target)
677 return;
679 bool samespell = false;
680 uint8 slot = 0xFF;
682 for(uint8 i = 0; i < 3; i++)
684 Aura* aura = m_target->GetAura(m_spellId, i);
685 if(aura)
687 samespell = true;
688 slot = aura->GetAuraSlot();
689 break;
693 //if(m_spellId == 23333 || m_spellId == 23335) // for BG
694 // m_positive = true;
696 // not call total regen auras at adding
697 if( m_modifier.m_auraname==SPELL_AURA_OBS_MOD_HEALTH || m_modifier.m_auraname==SPELL_AURA_OBS_MOD_MANA )
698 m_periodicTimer = m_modifier.periodictime;
699 else
700 if( m_modifier.m_auraname==SPELL_AURA_MOD_REGEN ||
701 m_modifier.m_auraname==SPELL_AURA_MOD_POWER_REGEN ||
702 m_modifier.m_auraname == SPELL_AURA_MOD_MANA_REGEN )
703 m_periodicTimer = 5000;
705 ApplyModifier(true,true);
707 sLog.outDebug("Aura %u now is in use", m_modifier.m_auraname);
709 Unit* caster = GetCaster();
711 // passive auras (except totem auras) do not get placed in the slots
712 if(!m_isPassive || (caster && caster->GetTypeId() == TYPEID_UNIT && ((Creature*)caster)->isTotem()))
714 if(!samespell)
716 if (IsPositive())
718 for (uint8 i = 0; i < MAX_POSITIVE_AURAS; i++)
720 if (m_target->GetUInt32Value((uint16)(UNIT_FIELD_AURA + i)) == 0)
722 slot = i;
723 break;
727 else
729 for (uint8 i = MAX_POSITIVE_AURAS; i < MAX_AURAS; i++)
731 if (m_target->GetUInt32Value((uint16)(UNIT_FIELD_AURA + i)) == 0)
733 slot = i;
734 break;
739 if(slot < MAX_AURAS)
741 m_target->SetUInt32Value((uint16)(UNIT_FIELD_AURA + slot), GetId());
743 uint8 flagslot = slot >> 3;
744 uint32 value = m_target->GetUInt32Value((uint16)(UNIT_FIELD_AURAFLAGS + flagslot));
746 uint8 value1 = (slot & 7) << 2;
747 value |= ((uint32)AFLAG_SET << value1);
749 m_target->SetUInt32Value((uint16)(UNIT_FIELD_AURAFLAGS + flagslot), value);
753 else
754 UpdateSlotCounter(slot,true);
756 // Update Seals information
757 if( IsSealSpell(GetId()) )
758 m_target->ModifyAuraState(AURA_STATE_JUDGEMENT,true);
760 // Conflagrate aura state
761 if (GetSpellProto()->SpellFamilyName == SPELLFAMILY_WARLOCK && (GetSpellProto()->SpellFamilyFlags & 4))
762 m_target->ModifyAuraState(AURA_STATE_IMMOLATE,true);
764 SetAuraSlot( slot );
765 UpdateAuraDuration();
769 void Aura::_RemoveAura()
771 sLog.outDebug("Aura %u now is remove", m_modifier.m_auraname);
772 ApplyModifier(false,true);
774 Unit* caster = GetCaster();
776 if(caster && IsPersistent())
778 DynamicObject *dynObj = caster->GetDynObject(GetId(), GetEffIndex());
779 if (dynObj)
780 dynObj->RemoveAffected(m_target);
783 //passive auras do not get put in slots
784 // Note: but totem can be not accessible for aura target in time remove (to far for find in grid)
785 //if(m_isPassive && !(caster && caster->GetTypeId() == TYPEID_UNIT && ((Creature*)caster)->isTotem()))
786 // return;
788 uint8 slot = GetAuraSlot();
790 // Aura added always to m_target
791 //Aura* aura = m_target->GetAura(m_spellId, m_effIndex);
792 //if(!aura)
793 // return;
795 if(slot >= MAX_AURAS) // slot not set
796 return;
798 if(m_target->GetUInt32Value((uint16)(UNIT_FIELD_AURA + slot)) == 0)
799 return;
801 bool samespell = false;
803 for(uint8 i = 0; i < 3; i++)
805 Aura* aura = m_target->GetAura(m_spellId, i);
806 if(aura)
808 samespell = true;
809 break;
813 // only remove icon when the last aura of the spell is removed (current aura already removed from list)
814 if (!samespell)
816 m_target->SetUInt32Value((uint16)(UNIT_FIELD_AURA + slot), 0);
818 uint8 flagslot = slot >> 3;
820 uint32 value = m_target->GetUInt32Value((uint16)(UNIT_FIELD_AURAFLAGS + flagslot));
822 uint8 aurapos = (slot & 7) << 2;
823 uint32 value1 = ~( AFLAG_SET << aurapos );
824 value &= value1;
826 m_target->SetUInt32Value((uint16)(UNIT_FIELD_AURAFLAGS + flagslot), value);
827 if( IsSealSpell(GetId()) )
828 m_target->ModifyAuraState(AURA_STATE_JUDGEMENT,false);
830 // Conflagrate aura state
831 if (GetSpellProto()->SpellFamilyName == SPELLFAMILY_WARLOCK && (GetSpellProto()->SpellFamilyFlags & 4))
832 m_target->ModifyAuraState(AURA_STATE_IMMOLATE, false);
834 // reset cooldown state for spells infinity/long aura (it's all self applied (?))
835 int32 duration = GetDuration(GetSpellProto());
836 if(caster==m_target && (duration < 0 || uint32(duration) > GetSpellProto()->RecoveryTime))
837 SendCoolDownEvent();
839 else // decrease count for spell
840 UpdateSlotCounter(slot,false);
843 void Aura::UpdateSlotCounter(uint8 slot, bool add)
845 if(slot >= MAX_AURAS)
846 return;
848 // calculate amount of similar auras by same effect index (similar different spells)
849 int8 count = 0;
851 Unit::AuraList const& aura_list = m_target->GetAurasByType(GetModifier()->m_auraname);
852 for(Unit::AuraList::const_iterator i = aura_list.begin();i != aura_list.end(); ++i)
853 if((*i)->m_spellId==m_spellId && (*i)->m_effIndex==m_effIndex)
854 ++count;
856 // at aura add aura not added yet, at aura remove aura already removed
857 // in field stored (count-1)
858 if(!add)
859 --count;
861 uint32 index = slot / 4;
862 uint32 byte = slot % 4;
863 uint32 val = m_target->GetUInt32Value(UNIT_FIELD_AURAAPPLICATIONS+index);
865 uint32 byte_bitpos = byte * 8;
866 uint32 byte_mask = 0xFF << (byte * 8);
868 val = (val & ~byte_mask) | (count << byte_bitpos);
870 m_target->SetUInt32Value(UNIT_FIELD_AURAAPPLICATIONS+index, val);
873 /*********************************************************/
874 /*** BASIC AURA FUNCTION ***/
875 /*********************************************************/
876 void Aura::HandleAddModifier(bool apply, bool Real)
878 if(m_target->GetTypeId() != TYPEID_PLAYER || !Real)
879 return;
881 SpellEntry const *spellInfo = GetSpellProto();
882 if(!spellInfo) return;
884 if(m_modifier.m_miscvalue >= SPELLMOD_COUNT)
885 return;
887 if (apply)
889 SpellModifier *mod = new SpellModifier;
890 mod->op = m_modifier.m_miscvalue;
891 mod->value = m_modifier.m_amount;
892 mod->type = m_modifier.m_auraname;
893 mod->spellId = m_spellId;
894 mod->effectId = m_effIndex;
895 mod->lastAffected = 0;
897 SpellAffection const *spellAffect = objmgr.GetSpellAffection(m_spellId, m_effIndex);
899 if (spellAffect && spellAffect->SpellFamilyMask)
900 mod->mask = spellAffect->SpellFamilyMask;
901 else
902 mod->mask = spellInfo->EffectItemType[m_effIndex];
904 if(spellAffect && spellAffect->Charges)
905 mod->charges = spellAffect->Charges;
906 else
907 mod->charges = spellInfo->procCharges;
909 m_spellmod = mod;
912 ((Player*)m_target)->AddSpellMod(m_spellmod, apply);
915 void Aura::TriggerSpell()
917 // custom triggering code (triggered spell not set or not exist
919 // Frenzied Regeneration
920 if (GetSpellProto()->Category == 1011)
922 int32 LifePerRage = GetModifier()->m_amount;
924 int32 lRage = m_target->GetPower(POWER_RAGE);
925 if(lRage > 100) // rage stored as rage*10
926 lRage = 100;
928 m_target->ModifyPower(POWER_RAGE, -lRage);
930 int32 FRTriggerBasePoints = int32(lRage*LifePerRage/10)-1;
931 m_target->CastCustomSpell(m_target,22845,&FRTriggerBasePoints,NULL,NULL,true,NULL,this);
932 return;
935 // generic casting code with custom spells and target/caster customs
936 uint32 trigger_spell_id = GetSpellProto()->EffectTriggerSpell[m_effIndex];
937 Unit* caster = GetCaster();
938 Unit* target = m_target;
939 uint64 originalCasterGUID = 0;
941 // specific code for cases with no trigger spell provided in field
942 switch(GetId())
944 case 29528: trigger_spell_id = 28713; break; // Inoculation
945 case 29917: trigger_spell_id = 29916; break; // Feed Captured Animal
946 case 768: // Cat Form (passive)
947 // trigger_spell_id not set and unknown effect triggered in this case, ignoring for while
948 return;
949 case 1515: // Tame Beast
951 // TODO: currently this used as hack for Tame beast triggered spell,
952 // BUT this can be correct way to provide target for ALL this function calls
953 // in case m_target==caster (or GetSpellProto()->EffectImplicitTargetA[m_effIndex]==TARGET_SELF )
954 target = ObjectAccessor::Instance().GetUnit(*m_target, m_target->GetUInt64Value(UNIT_FIELD_TARGET));
955 break;
957 case 1010: // Curse of Idiocy
959 // TODO: spell casted by result in correct way mostly
960 // BUT:
961 // 1) target show casting at each triggered cast: target don't must show casting animation for any triggered spell
962 // but must show affect apply like item casting
963 // 2) maybe aura must be replace by new with accumulative stat mods insteed stacking
965 // prevent cast by triggered auras
966 if(m_caster_guid == m_target->GetGUID())
967 return;
969 // stop triggering after each affected stats lost > 90
970 int32 intelectLoss = 0;
971 int32 spiritLoss = 0;
973 Unit::AuraList const& mModStat = m_target->GetAurasByType(SPELL_AURA_MOD_STAT);
974 for(Unit::AuraList::const_iterator i = mModStat.begin(); i != mModStat.end(); ++i)
976 if ((*i)->GetSpellProto()->Id == 1010)
978 switch((*i)->GetModifier()->m_miscvalue)
980 case STAT_INTELLECT: intelectLoss += (*i)->GetModifier()->m_amount; break;
981 case STAT_SPIRIT: spiritLoss += (*i)->GetModifier()->m_amount; break;
982 default: break;
987 if(intelectLoss <= -90 && spiritLoss <= -90)
988 return;
990 originalCasterGUID = GetCasterGUID();
991 caster = target;
992 break;
996 if(!trigger_spell_id)
998 sLog.outError("Aura::TriggerSpell: Spell %u have 0 in EffectTriggered[%d], not handled custom case?",GetSpellProto()->Id,GetEffIndex());
999 return;
1002 if(!caster || !target)
1003 return;
1005 caster->CastSpell(target,trigger_spell_id,true,NULL,this,originalCasterGUID);
1008 /*********************************************************/
1009 /*** AURA EFFECTS ***/
1010 /*********************************************************/
1012 void Aura::HandleInterruptRegen(bool apply, bool Real)
1014 Unit* caster = GetCaster();
1016 if(Real && apply)
1017 caster->SetInCombat();
1019 // Has no effect at removing
1022 void Aura::HandleAuraDummy(bool apply, bool Real)
1024 Unit* caster = GetCaster();
1026 // Must be processed before any auras code
1027 if(apply && Real && !m_procCharges)
1029 m_procCharges = GetSpellProto()->procCharges;
1030 if (!m_procCharges)
1031 m_procCharges = -1;
1034 // spells required only Real aura add/remove
1035 if(!Real)
1036 return;
1038 // Mangle (Cat) combo && damage
1039 if( m_spellProto->SpellFamilyName==SPELLFAMILY_DRUID && m_spellProto->SpellFamilyFlags == 0x40000000000LL &&
1040 caster && caster->GetTypeId()==TYPEID_PLAYER )
1042 if(apply)
1044 // 1 combo
1045 ((Player*)caster)->AddComboPoints(m_target->GetGUID(),1);
1047 // damage%
1048 SpellModifier *mod = new SpellModifier;
1049 mod->op = SPELLMOD_DAMAGE;
1050 mod->value = m_modifier.m_amount;
1051 mod->type = SPELL_AURA_ADD_PCT_MODIFIER;
1052 mod->spellId = m_spellId;
1053 mod->effectId = m_effIndex;
1054 mod->lastAffected = 0;
1055 mod->mask = 0x00000008000 | 0x00000001000;
1056 mod->charges = 0;
1058 m_spellmod = mod;
1061 ((Player*)caster)->AddSpellMod(m_spellmod, apply);
1064 // Tame beast
1065 if( GetId()==1515 && apply && caster && m_target->CanHaveThreatList())
1067 // FIX_ME: this is 2.0.12 threat effect relaced in 2.1.x by dummy aura, must be checked for correctness
1068 m_target->AddThreat(caster, 10.0f);
1071 if( m_target->GetTypeId() == TYPEID_PLAYER && !apply &&
1072 ( GetSpellProto()->Effect[0]==72 || GetSpellProto()->Effect[0]==6 &&
1073 ( GetSpellProto()->EffectApplyAuraName[0]==1 || GetSpellProto()->EffectApplyAuraName[0]==128 ) ) )
1075 // spells with SpellEffect=72 and aura=4: 6196, 6197, 21171, 21425
1076 m_target->SetUInt64Value(PLAYER_FARSIGHT, 0);
1077 WorldPacket data(SMSG_CLEAR_FAR_SIGHT_IMMEDIATE, 0);
1078 ((Player*)m_target)->GetSession()->SendPacket(&data);
1081 // net-o-matic
1082 if (GetId() == 13139 && apply && caster)
1084 // root to self part of (root_target->charge->root_self sequence
1085 caster->CastSpell(caster,13138,true,NULL,this);
1088 // seal of righteousness
1089 if(GetSpellProto()->SpellVisual == 7986 && caster && caster->GetTypeId() == TYPEID_PLAYER)
1091 if(GetEffIndex() == 0)
1092 m_target->ApplyAuraProcTriggerDamage(this,apply);
1095 if(GetSpellProto()->SpellVisual == 7395 && GetSpellProto()->SpellIconID == 278 && caster->GetTypeId() == TYPEID_PLAYER)
1096 m_target->ApplyAuraProcTriggerDamage(this,apply);
1098 // soulstone resurrection (only at real add/remove and can overwrite reincarnation spell setting)
1099 if(GetSpellProto()->SpellVisual == 99 && GetSpellProto()->SpellIconID == 92 &&
1100 caster && caster->GetTypeId() == TYPEID_PLAYER && m_target && m_target->GetTypeId() == TYPEID_PLAYER)
1102 Player * player = (Player*)m_target;
1104 uint32 spellid = 0;
1105 switch(GetId())
1107 case 20707:spellid = 3026;break;
1108 case 20762:spellid = 20758;break;
1109 case 20763:spellid = 20759;break;
1110 case 20764:spellid = 20760;break;
1111 case 20765:spellid = 20761;break;
1112 case 27239:spellid = 27240;break;
1113 default: return;
1116 if(apply)
1118 // overwrite any
1119 player->SetUInt32Value(PLAYER_SELF_RES_SPELL, spellid);
1121 else
1123 // remove only own spell
1124 if(player->GetUInt32Value(PLAYER_SELF_RES_SPELL)==spellid)
1125 player->SetUInt32Value(PLAYER_SELF_RES_SPELL, 0);
1129 if(!apply)
1131 if( (IsQuestTameSpell(GetId())) && caster && caster->isAlive() && m_target && m_target->isAlive())
1133 uint32 finalSpelId = 0;
1134 switch(GetId())
1136 case 19548: finalSpelId = 19597; break;
1137 case 19674: finalSpelId = 19677; break;
1138 case 19687: finalSpelId = 19676; break;
1139 case 19688: finalSpelId = 19678; break;
1140 case 19689: finalSpelId = 19679; break;
1141 case 19692: finalSpelId = 19680; break;
1142 case 19693: finalSpelId = 19684; break;
1143 case 19694: finalSpelId = 19681; break;
1144 case 19696: finalSpelId = 19682; break;
1145 case 19697: finalSpelId = 19683; break;
1146 case 19699: finalSpelId = 19685; break;
1147 case 19700: finalSpelId = 19686; break;
1148 case 30646: finalSpelId = 30647; break;
1149 case 30653: finalSpelId = 30648; break;
1150 case 30654: finalSpelId = 30652; break;
1151 case 30099: finalSpelId = 30100; break;
1152 case 30102: finalSpelId = 30103; break;
1153 case 30105: finalSpelId = 30104; break;
1156 if(finalSpelId)
1157 caster->CastSpell(m_target,finalSpelId,true,NULL,this);
1162 void Aura::HandleAuraMounted(bool apply, bool Real)
1164 if(apply)
1166 CreatureInfo const* ci = objmgr.GetCreatureTemplate(m_modifier.m_miscvalue);
1167 if(!ci)
1169 sLog.outErrorDb("AuraMounted: `creature_template`='%u' not found in database (only need it modelid)", m_modifier.m_miscvalue);
1170 return;
1173 // drop flag at mount in bg
1174 if(Real && m_target->GetTypeId()==TYPEID_PLAYER && ((Player*)m_target)->InBattleGround())
1175 if(BattleGround *bg = sBattleGroundMgr.GetBattleGround(((Player*)m_target)->GetBattleGroundId()))
1176 bg->HandleDropFlag((Player*)m_target);
1178 uint32 displayId = ci->randomDisplayID();
1179 if(displayId != 0)
1180 m_target->Mount(displayId);
1182 else
1184 m_target->Unmount();
1188 void Aura::HandleAuraWaterWalk(bool apply, bool Real)
1190 // only at real add/remove aura
1191 if(!Real)
1192 return;
1194 WorldPacket data;
1195 if(apply)
1196 data.Initialize(SMSG_MOVE_WATER_WALK, 8+4);
1197 else
1198 data.Initialize(SMSG_MOVE_LAND_WALK, 8+4);
1199 data.append(m_target->GetPackGUID());
1200 data << uint32(0);
1201 m_target->SendMessageToSet(&data,true);
1204 void Aura::HandleAuraFeatherFall(bool apply, bool Real)
1206 // only at real add/remove aura
1207 if(!Real)
1208 return;
1210 WorldPacket data;
1211 if(apply)
1212 data.Initialize(SMSG_MOVE_FEATHER_FALL, 8+4);
1213 else
1214 data.Initialize(SMSG_MOVE_NORMAL_FALL, 8+4);
1215 data.append(m_target->GetPackGUID());
1216 data << (uint32)0;
1217 m_target->SendMessageToSet(&data,true);
1220 void Aura::HandleAuraHover(bool apply, bool Real)
1222 // only at real add/remove aura
1223 if(!Real)
1224 return;
1226 WorldPacket data;
1227 if(apply)
1228 data.Initialize(SMSG_MOVE_SET_HOVER, 8+4);
1229 else
1230 data.Initialize(SMSG_MOVE_UNSET_HOVER, 8+4);
1231 data.append(m_target->GetPackGUID());
1232 data << uint32(0);
1233 m_target->SendMessageToSet(&data,true);
1236 void Aura::HandleWaterBreathing(bool apply, bool Real)
1238 m_target->waterbreath = apply;
1241 void Aura::HandleAuraModShapeshift(bool apply, bool Real)
1243 if(!m_target)
1244 return;
1245 if(!Real)
1246 return;
1248 Player* player = m_target->GetTypeId()==TYPEID_PLAYER ? ((Player*)m_target) : NULL;
1250 Unit *unit_target = m_target;
1251 uint32 modelid = 0;
1252 Powers PowerType = POWER_MANA;
1253 uint32 new_bytes_1 = m_modifier.m_miscvalue;
1254 switch(m_modifier.m_miscvalue)
1256 case FORM_CAT:
1257 if(unit_target->getRace() == RACE_NIGHTELF)
1258 modelid = 892;
1259 else if(unit_target->getRace() == RACE_TAUREN)
1260 modelid = 8571;
1261 PowerType = POWER_ENERGY;
1262 break;
1263 case FORM_TRAVEL:
1264 modelid = 632;
1265 break;
1266 case FORM_AQUA:
1267 if(unit_target->getRace() == RACE_NIGHTELF)
1268 modelid = 2428;
1269 else if(unit_target->getRace() == RACE_TAUREN)
1270 modelid = 2428;
1271 break;
1272 case FORM_BEAR:
1273 if(unit_target->getRace() == RACE_NIGHTELF)
1274 modelid = 2281;
1275 else if(unit_target->getRace() == RACE_TAUREN)
1276 modelid = 2289;
1277 PowerType = POWER_RAGE;
1278 break;
1279 case FORM_GHOUL:
1280 if(unit_target->getRace() == RACE_NIGHTELF)
1281 modelid = 10045;
1282 break;
1283 case FORM_DIREBEAR:
1284 if(unit_target->getRace() == RACE_NIGHTELF)
1285 modelid = 2281;
1286 else if(unit_target->getRace() == RACE_TAUREN)
1287 modelid = 2289;
1288 PowerType = POWER_RAGE;
1289 break;
1290 case FORM_CREATUREBEAR:
1291 modelid = 902;
1292 break;
1293 case FORM_GHOSTWOLF:
1294 modelid = 4613;
1295 break;
1296 case FORM_FLIGHT:
1297 modelid = 20013; //test it !! (20857, 20872, 20013)
1298 break;
1299 case FORM_MOONKIN:
1300 if(unit_target->getRace() == RACE_NIGHTELF)
1301 modelid = 15374;
1302 else if(unit_target->getRace() == RACE_TAUREN)
1303 modelid = 15375;
1304 break;
1305 case FORM_SWIFT_FLIGHT:
1306 if(unit_target->getRace() == RACE_NIGHTELF)
1307 modelid = 21243;
1308 else if(unit_target->getRace() == RACE_TAUREN)
1309 modelid = 21244;
1310 break;
1311 case FORM_AMBIENT:
1312 case FORM_SHADOW:
1313 case FORM_STEALTH:
1314 break;
1315 case FORM_TREE:
1316 modelid = 864;
1317 break;
1318 case FORM_BATTLESTANCE:
1319 case FORM_BERSERKERSTANCE:
1320 case FORM_DEFENSIVESTANCE:
1321 PowerType = POWER_RAGE;
1322 break;
1323 default:
1324 sLog.outError("Auras: Unknown Shapeshift Type: %u", m_modifier.m_miscvalue);
1327 if(apply)
1329 unit_target->SetFlag(UNIT_FIELD_BYTES_1, (new_bytes_1<<16) );
1330 if(modelid > 0)
1332 unit_target->SetUInt32Value(UNIT_FIELD_DISPLAYID,modelid);
1335 if(PowerType != POWER_MANA)
1337 // reset power to default values only at power change
1338 if(unit_target->getPowerType()!=PowerType)
1339 unit_target->setPowerType(PowerType);
1341 switch(m_modifier.m_miscvalue)
1343 case FORM_CAT:
1344 case FORM_BEAR:
1345 case FORM_DIREBEAR:
1347 // get furor proc chance
1348 uint32 FurorChance = 0;
1349 Unit::AuraList const& mDummy = m_target->GetAurasByType(SPELL_AURA_DUMMY);
1350 for(Unit::AuraList::const_iterator i = mDummy.begin(); i != mDummy.end(); ++i)
1351 if ((*i)->GetSpellProto()->SpellIconID == 238)
1352 FurorChance = (*i)->GetModifier()->m_amount;
1354 if (m_modifier.m_miscvalue == FORM_CAT)
1356 unit_target->SetPower(POWER_ENERGY,0);
1357 if(urand(1,100) <= FurorChance)
1359 unit_target->CastSpell(unit_target,17099,true,NULL,this);
1362 else
1364 unit_target->SetPower(POWER_RAGE,0);
1365 if(urand(1,100) <= FurorChance)
1367 unit_target->CastSpell(unit_target,17057,true,NULL,this);
1370 break;
1372 case FORM_BATTLESTANCE:
1373 case FORM_DEFENSIVESTANCE:
1374 case FORM_BERSERKERSTANCE:
1376 uint32 Rage_val = 0;
1377 // Stance mastery + Tactical mastery
1378 Unit::AuraList const& xDummy = m_target->GetAurasByType(SPELL_AURA_DUMMY);
1379 for(Unit::AuraList::const_iterator i = xDummy.begin(); i != xDummy.end(); ++i)
1380 if((*i)->GetSpellProto()->SpellIconID == 139)
1381 Rage_val += ( (*i)->GetModifier()->m_amount * 10 );
1383 if (unit_target->GetPower(POWER_RAGE) > Rage_val)
1384 unit_target->SetPower(POWER_RAGE,Rage_val);
1385 break;
1387 default:
1388 break;
1392 unit_target->m_ShapeShiftForm = m_spellId;
1393 unit_target->m_form = m_modifier.m_miscvalue;
1395 else
1397 unit_target->SetUInt32Value(UNIT_FIELD_DISPLAYID,unit_target->GetUInt32Value(UNIT_FIELD_NATIVEDISPLAYID));
1398 unit_target->RemoveFlag(UNIT_FIELD_BYTES_1, (new_bytes_1<<16) );
1399 if(unit_target->getClass() == CLASS_DRUID)
1400 unit_target->setPowerType(POWER_MANA);
1401 unit_target->m_ShapeShiftForm = 0;
1402 unit_target->m_form = 0;
1405 if(player)
1406 player->InitDataForForm();
1409 void Aura::HandleAuraTransform(bool apply, bool Real)
1411 // skip if player not added to map at loading or far teleport (to prevent client crash)
1412 // it will applied in Player::SendInitialPacketsAfterAddToMap after adding to map
1413 if(m_target->GetTypeId()==TYPEID_PLAYER && !((Player*)m_target)->IsInWorld())
1414 return;
1416 if (apply)
1418 // special case
1419 if(m_modifier.m_miscvalue==0)
1421 if(m_target->GetTypeId()!=TYPEID_PLAYER)
1422 return;
1424 uint32 orb_model = m_target->GetUInt32Value(UNIT_FIELD_NATIVEDISPLAYID);
1425 switch(orb_model)
1427 // Troll Female
1428 case 1479: m_target->SetUInt32Value(UNIT_FIELD_DISPLAYID, 10134); break;
1429 // Troll Male
1430 case 1478: m_target->SetUInt32Value(UNIT_FIELD_DISPLAYID, 10135); break;
1431 // Tauren Male
1432 case 59: m_target->SetUInt32Value(UNIT_FIELD_DISPLAYID, 10136); break;
1433 // Human Male
1434 case 49: m_target->SetUInt32Value(UNIT_FIELD_DISPLAYID, 10137); break;
1435 // Human Female
1436 case 50: m_target->SetUInt32Value(UNIT_FIELD_DISPLAYID, 10138); break;
1437 // Orc Male
1438 case 51: m_target->SetUInt32Value(UNIT_FIELD_DISPLAYID, 10139); break;
1439 // Orc Female
1440 case 52: m_target->SetUInt32Value(UNIT_FIELD_DISPLAYID, 10140); break;
1441 // Dwarf Male
1442 case 53: m_target->SetUInt32Value(UNIT_FIELD_DISPLAYID, 10141); break;
1443 // Dwarf Female
1444 case 54: m_target->SetUInt32Value(UNIT_FIELD_DISPLAYID, 10142); break;
1445 // NightElf Male
1446 case 55: m_target->SetUInt32Value(UNIT_FIELD_DISPLAYID, 10143); break;
1447 // NightElf Female
1448 case 56: m_target->SetUInt32Value(UNIT_FIELD_DISPLAYID, 10144); break;
1449 // Undead Female
1450 case 58: m_target->SetUInt32Value(UNIT_FIELD_DISPLAYID, 10145); break;
1451 // Undead Male
1452 case 57: m_target->SetUInt32Value(UNIT_FIELD_DISPLAYID, 10146); break;
1453 // Tauren Female
1454 case 60: m_target->SetUInt32Value(UNIT_FIELD_DISPLAYID, 10147); break;
1455 // Gnome Male
1456 case 1563: m_target->SetUInt32Value(UNIT_FIELD_DISPLAYID, 10148); break;
1457 // Gnome Female
1458 case 1564: m_target->SetUInt32Value(UNIT_FIELD_DISPLAYID, 10149); break;
1459 // BloodElf Female
1460 case 15475: m_target->SetUInt32Value(UNIT_FIELD_DISPLAYID, 17830); break;
1461 // BloodElf Male
1462 case 15476: m_target->SetUInt32Value(UNIT_FIELD_DISPLAYID, 17829); break;
1463 // Dranei Female
1464 case 16126: m_target->SetUInt32Value(UNIT_FIELD_DISPLAYID, 17828); break;
1465 // Dranei Male
1466 case 16125: m_target->SetUInt32Value(UNIT_FIELD_DISPLAYID, 17827); break;
1467 default: break;
1470 else
1472 CreatureInfo const * ci = objmgr.GetCreatureTemplate(m_modifier.m_miscvalue);
1473 if(!ci)
1475 //pig pink ^_^
1476 m_target->SetUInt32Value (UNIT_FIELD_DISPLAYID, 16358);
1477 sLog.outError("Auras: unknown creature id = %d (only need its modelid) Form Spell Aura Transform in Spell ID = %d", m_modifier.m_miscvalue, GetSpellProto()->Id);
1479 else
1481 m_target->SetUInt32Value (UNIT_FIELD_DISPLAYID, ci->randomDisplayID());
1483 m_target->setTransForm(GetSpellProto()->Id);
1486 else
1488 m_target->SetUInt32Value (UNIT_FIELD_DISPLAYID, m_target->GetUInt32Value(UNIT_FIELD_NATIVEDISPLAYID));
1489 m_target->setTransForm(0);
1492 Unit* caster = GetCaster();
1494 if(caster && caster->GetTypeId() == TYPEID_PLAYER)
1495 m_target->SendUpdateToPlayer((Player*)caster);
1498 void Aura::HandleForceReaction(bool Apply, bool Real)
1500 if(m_target->GetTypeId() != TYPEID_PLAYER)
1501 return;
1503 if(!Real)
1504 return;
1506 Player* player = (Player*)m_target;
1508 uint32 faction_id = m_modifier.m_miscvalue;
1509 uint32 faction_rank = m_modifier.m_amount;
1511 if(Apply)
1512 player->m_forcedReactions[m_modifier.m_miscvalue] = ReputationRank(faction_rank);
1513 else
1514 player->m_forcedReactions.erase(m_modifier.m_miscvalue);
1516 WorldPacket data;
1517 data.Initialize(SMSG_SET_FORCED_REACTIONS, 4+player->m_forcedReactions.size()*(4+4));
1518 data << uint32(player->m_forcedReactions.size());
1519 for(ForcedReactions::const_iterator itr = player->m_forcedReactions.begin(); itr != player->m_forcedReactions.end(); ++itr)
1521 data << uint32(itr->first); // faction_id (Faction.dbc)
1522 data << uint32(itr->second); // reputation rank
1524 player->SendDirectMessage(&data);
1527 void Aura::HandleAuraModSkill(bool apply, bool Real)
1529 if(m_target->GetTypeId() != TYPEID_PLAYER)
1530 return;
1532 uint32 prot=GetSpellProto()->EffectMiscValue[m_effIndex];
1533 int32 points = m_currentBasePoints+1;
1535 ((Player*)m_target)->ModifySkillBonus(prot,(apply ? points: -points));
1536 if(prot == SKILL_DEFENSE)
1537 ((Player*)m_target)->UpdateDefenseBonusesMod();
1540 void Aura::HandleChannelDeathItem(bool apply, bool Real)
1542 if(Real && !apply)
1544 Unit* caster = GetCaster();
1545 Unit* victim = GetTarget();
1546 if(!caster || caster->GetTypeId() != TYPEID_PLAYER || !victim || !m_removeOnDeath)
1547 return;
1549 SpellEntry const *spellInfo = GetSpellProto();
1550 if(spellInfo->EffectItemType[m_effIndex] == 0)
1551 return;
1553 // Soul Shard only from non-grey units
1554 if( victim->getLevel() <= MaNGOS::XP::GetGrayLevel(caster->getLevel()) && spellInfo->EffectItemType[m_effIndex] == 6265)
1555 return;
1557 uint16 dest;
1558 uint8 msg = ((Player*)caster)->CanStoreNewItem( NULL_BAG, NULL_SLOT, dest, spellInfo->EffectItemType[m_effIndex], 1, false);
1559 if( msg == EQUIP_ERR_OK )
1561 Item* newitem = ((Player*)caster)->StoreNewItem(dest, spellInfo->EffectItemType[m_effIndex], 1, true);
1562 ((Player*)caster)->SendNewItem(newitem, 1, true, false);
1564 else
1565 ((Player*)caster)->SendEquipError( msg, NULL, NULL );
1569 void Aura::HandleAuraSafeFall(bool apply, bool Real)
1571 // only at real add/remove aura
1572 if(!Real)
1573 return;
1575 WorldPacket data;
1576 if(apply)
1577 data.Initialize(SMSG_MOVE_FEATHER_FALL, 8+4);
1578 else
1579 data.Initialize(SMSG_MOVE_NORMAL_FALL, 8+4);
1580 data.append(m_target->GetPackGUID());
1581 data << uint32(0);
1582 m_target->SendMessageToSet(&data,true);
1585 void Aura::HandleBindSight(bool apply, bool Real)
1587 if(!m_target)
1588 return;
1590 Unit* caster = GetCaster();
1591 if(!caster || caster->GetTypeId() != TYPEID_PLAYER)
1592 return;
1594 caster->SetUInt64Value(PLAYER_FARSIGHT,apply ? m_target->GetGUID() : 0);
1597 void Aura::HandleFarSight(bool apply, bool Real)
1599 if(!m_target)
1600 return;
1602 Unit* caster = GetCaster();
1603 if(!caster || caster->GetTypeId() != TYPEID_PLAYER)
1604 return;
1606 caster->SetUInt64Value(PLAYER_FARSIGHT,apply ? m_modifier.m_miscvalue : 0);
1609 void Aura::HandleAuraTrackCreatures(bool apply, bool Real)
1611 if(m_target->GetTypeId()!=TYPEID_PLAYER)
1612 return;
1614 if(apply)
1615 m_target->RemoveNoStackAurasDueToAura(this);
1616 m_target->SetUInt32Value(PLAYER_TRACK_CREATURES, apply ? ((uint32)1)<<(m_modifier.m_miscvalue-1) : 0 );
1619 void Aura::HandleAuraTrackResources(bool apply, bool Real)
1621 if(m_target->GetTypeId()!=TYPEID_PLAYER)
1622 return;
1624 if(apply)
1625 m_target->RemoveNoStackAurasDueToAura(this);
1626 m_target->SetUInt32Value(PLAYER_TRACK_RESOURCES, apply ? ((uint32)1)<<(m_modifier.m_miscvalue-1): 0 );
1629 void Aura::HandleAuraTrackStealthed(bool apply, bool Real)
1631 if(m_target->GetTypeId()!=TYPEID_PLAYER)
1632 return;
1634 if(apply)
1635 m_target->RemoveNoStackAurasDueToAura(this);
1637 m_target->ApplyModFlag(PLAYER_FIELD_BYTES,0x02,apply);
1640 void Aura::HandleAuraModScale(bool apply, bool Real)
1642 m_target->ApplyPercentModFloatValue(OBJECT_FIELD_SCALE_X,m_modifier.m_amount,apply);
1645 void Aura::HandleModPossess(bool apply, bool Real)
1647 if(!m_target)
1648 return;
1649 if(!Real)
1650 return;
1652 if(m_target->GetCreatureType() != CREATURE_TYPE_HUMANOID)
1653 return;
1655 Unit* caster = GetCaster();
1656 if(!caster)
1657 return;
1659 if(int32(m_target->getLevel()) <= m_modifier.m_amount)
1661 if( apply )
1663 m_target->SetCharmerGUID(GetCasterGUID());
1664 m_target->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE,caster->getFaction());
1665 caster->SetCharm(m_target);
1667 if(caster->getVictim()==m_target)
1668 caster->AttackStop();
1669 m_target->CombatStop();
1670 m_target->DeleteThreatList();
1671 if(m_target->GetTypeId() == TYPEID_UNIT)
1673 ((Creature*)m_target)->StopMoving();
1674 (*(Creature*)m_target)->Clear();
1675 (*(Creature*)m_target)->Idle();
1676 CharmInfo *charmInfo = ((Creature*)m_target)->InitCharmInfo(m_target);
1677 charmInfo->InitPossessCreateSpells();
1680 if(caster->GetTypeId() == TYPEID_PLAYER)
1682 ((Player*)caster)->PossessSpellInitialize();
1685 else
1687 //remove area auras from charms
1688 Unit::AuraMap& tAuras = m_target->GetAuras();
1689 for (Unit::AuraMap::iterator itr = tAuras.begin(); itr != tAuras.end();)
1691 if (itr->second && itr->second->IsAreaAura())
1692 m_target->RemoveAura(itr);
1693 else
1694 ++itr;
1697 m_target->SetCharmerGUID(0);
1699 if(m_target->GetTypeId() == TYPEID_PLAYER)
1701 ((Player*)m_target)->setFactionForRace(m_target->getRace());
1703 else if(m_target->GetTypeId() == TYPEID_UNIT)
1705 CreatureInfo const *cinfo = ((Creature*)m_target)->GetCreatureInfo();
1706 m_target->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE,cinfo->faction);
1709 caster->SetCharm(0);
1711 if(caster->GetTypeId() == TYPEID_PLAYER)
1713 WorldPacket data(SMSG_PET_SPELLS, 8);
1714 data << uint64(0);
1715 ((Player*)caster)->GetSession()->SendPacket(&data);
1717 if(m_target->GetTypeId() == TYPEID_UNIT)
1719 ((Creature*)m_target)->AIM_Initialize();
1720 ((Creature*)m_target)->Attack(caster);
1723 if(caster->GetTypeId() == TYPEID_PLAYER)
1724 caster->SetUInt64Value(PLAYER_FARSIGHT,apply ? m_target->GetGUID() : 0);
1728 void Aura::HandleModPossessPet(bool apply, bool Real)
1730 if(!m_target)
1731 return;
1732 if(!Real)
1733 return;
1735 Unit* caster = GetCaster();
1736 if(!caster || caster->GetTypeId() != TYPEID_PLAYER)
1737 return;
1738 if(caster->GetPet() != m_target)
1739 return;
1741 if(apply)
1743 caster->SetUInt64Value(PLAYER_FARSIGHT, m_target->GetGUID());
1744 m_target->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNKNOWN5);
1746 else
1748 caster->SetUInt64Value(PLAYER_FARSIGHT, 0);
1749 m_target->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNKNOWN5);
1753 void Aura::HandleModCharm(bool apply, bool Real)
1755 if(!m_target)
1756 return;
1757 if(!Real)
1758 return;
1760 Unit* caster = GetCaster();
1761 if(!caster)
1762 return;
1764 if(int32(m_target->getLevel()) <= m_modifier.m_amount)
1766 if( apply )
1768 m_target->SetCharmerGUID(GetCasterGUID());
1769 m_target->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE,caster->getFaction());
1771 caster->SetCharm(m_target);
1773 if(caster->getVictim()==m_target)
1774 caster->AttackStop();
1775 m_target->CombatStop();
1776 m_target->DeleteThreatList();
1778 if(m_target->GetTypeId() == TYPEID_UNIT)
1780 ((Creature*)m_target)->AIM_Initialize();
1781 CharmInfo *charmInfo = ((Creature*)m_target)->InitCharmInfo(m_target);
1782 charmInfo->InitCharmCreateSpells();
1783 charmInfo->SetReactState( REACT_DEFENSIVE );
1784 charmInfo->SetCommandState( COMMAND_FOLLOW );
1786 if(caster->GetTypeId() == TYPEID_PLAYER && caster->getClass() == CLASS_WARLOCK)
1788 CreatureInfo const *cinfo = ((Creature*)m_target)->GetCreatureInfo();
1789 if(cinfo && cinfo->type == CREATURE_TYPE_DEMON)
1791 //to prevent client crash
1792 m_target->SetFlag(UNIT_FIELD_BYTES_0, 2048);
1793 //just to enable stat window
1794 charmInfo->SetPetNumber(objmgr.GeneratePetNumber(), true);
1795 //if charmed two demons the same session, the 2nd gets the 1st one's name
1796 m_target->SetUInt32Value(UNIT_FIELD_PET_NAME_TIMESTAMP, time(NULL));
1801 if(caster->GetTypeId() == TYPEID_PLAYER)
1803 ((Player*)caster)->CharmSpellInitialize();
1806 else
1808 //remove area auras from charms
1809 Unit::AuraMap& tAuras = m_target->GetAuras();
1810 for (Unit::AuraMap::iterator itr = tAuras.begin(); itr != tAuras.end();)
1812 if (itr->second && itr->second->IsAreaAura())
1813 m_target->RemoveAura(itr);
1814 else
1815 ++itr;
1818 m_target->SetCharmerGUID(0);
1820 if(m_target->GetTypeId() == TYPEID_PLAYER)
1822 ((Player*)m_target)->setFactionForRace(m_target->getRace());
1824 else
1826 CreatureInfo const *cinfo = ((Creature*)m_target)->GetCreatureInfo();
1828 // restore faction
1829 if(((Creature*)m_target)->isPet())
1831 if(Unit* owner = m_target->GetOwner())
1832 m_target->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE,owner->getFaction());
1833 else if(cinfo)
1834 m_target->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE,cinfo->faction);
1836 else if(cinfo) // normal creature
1837 m_target->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE,cinfo->faction);
1839 // restore UNIT_FIELD_BYTES_0
1840 if(cinfo && caster->GetTypeId() == TYPEID_PLAYER && caster->getClass() == CLASS_WARLOCK && cinfo->type == CREATURE_TYPE_DEMON)
1842 CreatureDataAddon const *cainfo = objmgr.GetCreatureAddon(m_target->GetGUIDLow());
1843 if(cainfo && cainfo->bytes0 != 0)
1844 m_target->SetUInt32Value(UNIT_FIELD_BYTES_0, cainfo->bytes0);
1845 else
1846 m_target->RemoveFlag(UNIT_FIELD_BYTES_0, 2048);
1848 if(m_target->GetCharmInfo())
1849 m_target->GetCharmInfo()->SetPetNumber(0, true);
1850 else
1851 sLog.outError("Aura::HandleModCharm: target="I64FMTD" with typeid=%d has a charm aura but no charm info!", m_target->GetGUID(), m_target->GetTypeId());
1855 caster->SetCharm(0);
1857 if(caster->GetTypeId() == TYPEID_PLAYER)
1859 WorldPacket data(SMSG_PET_SPELLS, 8);
1860 data << uint64(0);
1861 ((Player*)caster)->GetSession()->SendPacket(&data);
1863 if(m_target->GetTypeId() == TYPEID_UNIT)
1865 ((Creature*)m_target)->AIM_Initialize();
1866 ((Creature*)m_target)->Attack(caster);
1872 void Aura::HandleModConfuse(bool apply, bool Real)
1874 Unit* caster = GetCaster();
1875 uint32 apply_stat = UNIT_STAT_CONFUSED;
1877 if( apply )
1879 m_target->addUnitState(UNIT_STAT_CONFUSED);
1880 // probably wrong
1881 m_target->SetFlag(UNIT_FIELD_FLAGS,(apply_stat<<16));
1883 // Rogue/Blind ability stops attack
1884 // TODO: does all confuses ?
1885 if ( caster && (GetSpellProto()->Mechanic == MECHANIC_CONFUSED) && (GetSpellProto()->SpellFamilyName == SPELLFAMILY_ROGUE))
1886 caster->AttackStop();
1887 // only at real add aura
1888 if(Real)
1890 //This fixes blind so it doesn't continue to attack
1891 // TODO: may other spells casted confuse aura (but not all) stop attack
1892 if( caster && caster->GetTypeId() == TYPEID_PLAYER &&
1893 GetSpellProto()->Mechanic == MECHANIC_CONFUSED && GetSpellProto()->SpellFamilyName == SPELLFAMILY_ROGUE )
1895 caster->AttackStop();
1898 if (m_target->GetTypeId() == TYPEID_UNIT)
1899 (*((Creature*)m_target))->Mutate(new ConfusedMovementGenerator(*((Creature*)m_target)));
1902 else
1904 m_target->clearUnitState(UNIT_STAT_CONFUSED);
1905 // probably wrong
1906 m_target->RemoveFlag(UNIT_FIELD_FLAGS,(apply_stat<<16));
1908 // only at real remove aura
1909 if(Real)
1911 if (m_target->GetTypeId() == TYPEID_UNIT)
1913 Creature* c = (Creature*)m_target;
1914 (*c)->MovementExpired(false);
1916 // if in combat restore movement generator
1917 if(c->getVictim())
1918 (*c)->Mutate(new TargetedMovementGenerator(*c->getVictim()));
1924 void Aura::HandleModFear(bool Apply, bool Real)
1926 uint32 apply_stat = UNIT_STAT_FLEEING;
1927 if( Apply )
1929 m_target->addUnitState(UNIT_STAT_FLEEING);
1930 m_target->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_ROTATE | UNIT_FLAG_FLEEING);
1932 // only at real add aura
1933 if(Real)
1935 WorldPacket data(SMSG_DEATH_NOTIFY_OBSOLETE, 9);
1936 data.append(m_target->GetPackGUID());
1937 data << uint8(0x00);
1938 m_target->SendMessageToSet(&data,true);
1941 else
1943 m_target->clearUnitState(UNIT_STAT_FLEEING);
1944 m_target->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_ROTATE | UNIT_FLAG_FLEEING);
1946 // only at real remove aura
1947 if(Real)
1949 Unit* caster = GetCaster();
1950 if(m_target->GetTypeId() != TYPEID_PLAYER && caster)
1951 m_target->Attack(caster);
1952 WorldPacket data(SMSG_DEATH_NOTIFY_OBSOLETE, 9);
1953 data.append(m_target->GetPackGUID());
1954 data << uint8(0x01);
1955 m_target->SendMessageToSet(&data,true);
1960 void Aura::HandleFeignDeath(bool Apply, bool Real)
1962 if(!Real)
1963 return;
1965 if(!m_target || m_target->GetTypeId() == TYPEID_UNIT)
1966 return;
1968 if( Apply )
1971 WorldPacket data(SMSG_FEIGN_DEATH_RESISTED, 9);
1972 data<<m_target->GetGUID();
1973 data<<uint8(0);
1974 m_target->SendMessageToSet(&data,true);
1976 // blizz like 2.0.x
1977 m_target->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNKNOWN6);
1978 m_target->SetFlag(UNIT_FIELD_FLAGS_2, 0x00000001); // blizz like 2.0.x
1979 // blizz like 2.0.x
1980 m_target->SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_DEAD);
1982 m_target->addUnitState(UNIT_STAT_DIED);
1983 m_target->CombatStop();
1984 m_target->InterruptNonMeleeSpells(true);
1985 m_target->getHostilRefManager().deleteReferences();
1987 else
1990 WorldPacket data(SMSG_FEIGN_DEATH_RESISTED, 9);
1991 data<<m_target->GetGUID();
1992 data<<uint8(1);
1993 m_target->SendMessageToSet(&data,true);
1995 // blizz like 2.0.x
1996 m_target->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNKNOWN6);
1997 // blizz like 2.0.x
1998 m_target->RemoveFlag(UNIT_FIELD_FLAGS_2, 0x00000001);
1999 // blizz like 2.0.x
2000 m_target->RemoveFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_DEAD);
2002 m_target->clearUnitState(UNIT_STAT_DIED);
2006 void Aura::HandleAuraModDisarm(bool Apply, bool Real)
2008 if(!Real)
2009 return;
2011 // not sure for it's correctness
2012 if(Apply)
2013 m_target->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISARMED);
2014 else
2015 m_target->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISARMED);
2018 void Aura::HandleAuraModStun(bool apply, bool Real)
2020 // only at real add/remove aura
2021 if(!Real)
2022 return;
2024 Unit* caster = GetCaster();
2026 if (apply)
2028 m_target->addUnitState(UNIT_STAT_STUNDED);
2029 m_target->SetUInt64Value (UNIT_FIELD_TARGET, 0);
2030 m_target->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_ROTATE);
2032 // Stop attack if spell has knockout effect
2033 if (caster && (GetSpellProto()->Mechanic == MECHANIC_KNOCKOUT))
2034 caster->AttackStop();
2036 if( caster )
2038 //If this is a knockout spell for rogues attacker stops
2039 if( caster->GetTypeId() == TYPEID_PLAYER &&
2040 (GetSpellProto()->Mechanic == MECHANIC_KNOCKOUT || GetSpellProto()->Mechanic == MECHANIC_STUNDED) && GetSpellProto()->SpellFamilyName == SPELLFAMILY_ROGUE )
2042 caster->AttackStop();
2045 //Save last orientation
2046 m_target->SetOrientation(m_target->GetAngle(caster));
2049 // Creature specific
2050 if(m_target->GetTypeId() != TYPEID_PLAYER)
2052 ((Creature *)m_target)->StopMoving();
2055 WorldPacket data(SMSG_FORCE_MOVE_ROOT, 8);
2057 data.append(m_target->GetPackGUID());
2058 data << uint32(0);
2059 m_target->SendMessageToSet(&data,true);
2061 else
2063 // Real remove called after current aura remove from lists, check if other similar auras active
2064 if(m_target->HasAuraType(SPELL_AURA_MOD_STUN))
2065 return;
2067 m_target->clearUnitState(UNIT_STAT_STUNDED);
2068 m_target->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_ROTATE);
2070 if(caster && m_target->isAlive())
2071 m_target->SetUInt64Value (UNIT_FIELD_TARGET,GetCasterGUID());
2073 WorldPacket data(SMSG_FORCE_MOVE_UNROOT, 8+4);
2074 data.append(m_target->GetPackGUID());
2075 data << uint32(0);
2076 m_target->SendMessageToSet(&data,true);
2077 if (GetSpellProto()->SpellFamilyName == SPELLFAMILY_HUNTER && GetSpellProto()->SpellIconID == 1721)
2079 if( !caster || caster->GetTypeId()!=TYPEID_PLAYER )
2080 return;
2082 uint32 spell_id = 0;
2084 switch(GetSpellProto()->Id)
2086 case 19386: spell_id = 24131; break;
2087 case 24132: spell_id = 24134; break;
2088 case 24133: spell_id = 24135; break;
2089 case 27068: spell_id = 27069; break;
2090 default:
2091 sLog.outError("Spell selection called for unexpected original spell %u, new spell for this spell family?",GetSpellProto()->Id);
2092 return;
2095 SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell_id);
2097 if(!spellInfo)
2098 return;
2100 caster->CastSpell(m_target,spellInfo,true,NULL,this);
2101 return;
2106 void Aura::HandleModStealth(bool apply, bool Real)
2108 if(apply)
2110 m_target->m_stealthvalue = m_modifier.m_amount;
2112 // not apply flag for RACE_NIGHTELF stealth
2113 if(GetId()!=20580)
2114 m_target->SetFlag(UNIT_FIELD_BYTES_1, PLAYER_STATE_FLAG_CREEP);
2116 // only at real aura add
2117 if(Real)
2119 // apply only if not in GM invisibility
2120 if(m_target->GetVisibility()!=VISIBILITY_OFF)
2122 m_target->SetVisibility(VISIBILITY_GROUP_NO_DETECT);
2123 if(m_target->GetTypeId() == TYPEID_PLAYER)
2124 m_target->SendUpdateToPlayer((Player*)m_target);
2125 m_target->SetVisibility(VISIBILITY_GROUP_STEALTH);
2128 // for RACE_NIGHTELF stealth
2129 if(m_target->GetTypeId()==TYPEID_PLAYER && GetId()==20580)
2131 m_target->CastSpell(m_target, 21009, true, NULL, this);
2135 else
2137 // only at real aura remove
2138 if(Real)
2140 bool reallyRemove =true;
2141 SpellEntry const *spellInfo = GetSpellProto();
2142 if(spellInfo->SpellFamilyName == SPELLFAMILY_ROGUE &&
2143 (spellInfo->SpellFamilyFlags & SPELLFAMILYFLAG_ROGUE_VANISH) &&
2144 (m_target->HasStealthAura() ||
2145 m_target->HasInvisibilityAura()))
2146 reallyRemove = false; // vanish it timed out, but we have stealth active as well
2147 if(reallyRemove)
2149 m_target->m_stealthvalue = 0;
2150 m_target->RemoveFlag(UNIT_FIELD_BYTES_1, PLAYER_STATE_FLAG_CREEP);
2152 // apply only if not in GM invisibility
2153 if(m_target->GetVisibility()!=VISIBILITY_OFF)
2155 m_target->SetVisibility(VISIBILITY_ON);
2156 if(m_target->GetTypeId() == TYPEID_PLAYER)
2157 m_target->SendUpdateToPlayer((Player*)m_target);
2159 // for RACE_NIGHTELF stealth
2160 if(m_target->GetTypeId()==TYPEID_PLAYER && GetId()==20580)
2162 m_target->RemoveAurasDueToSpell(21009);
2169 void Aura::HandleModStealthDetect(bool apply, bool Real)
2171 if(apply)
2173 m_target->m_detectStealth = m_modifier.m_amount;
2175 else
2177 m_target->m_detectStealth = 0;
2181 void Aura::HandleInvisibility(bool Apply, bool Real)
2183 if(Apply)
2185 m_target->m_invisibilityvalue = m_modifier.m_amount;
2187 // only at real aura add
2188 if(Real)
2190 // apply only if not in GM invisibility
2191 if(m_target->GetVisibility()!=VISIBILITY_OFF)
2193 m_target->SetVisibility(VISIBILITY_GROUP_NO_DETECT);
2194 if(m_target->GetTypeId() == TYPEID_PLAYER)
2195 m_target->SendUpdateToPlayer((Player*)m_target);
2196 m_target->SetVisibility(VISIBILITY_GROUP_INVISIBILITY);
2200 else
2202 m_target->m_invisibilityvalue = 0;
2203 //m_target->RemoveFlag(UNIT_FIELD_BYTES_1, PLAYER_STATE_FLAG_CREEP );
2205 // only at real aura remove
2206 if(Real)
2208 // apply only if not in GM invisibility
2209 if(m_target->GetVisibility()!=VISIBILITY_OFF)
2211 m_target->SetVisibility(VISIBILITY_ON);
2212 if(m_target->GetTypeId() == TYPEID_PLAYER)
2213 m_target->SendUpdateToPlayer((Player*)m_target);
2219 void Aura::HandleInvisibilityDetect(bool Apply, bool Real)
2221 if(Apply)
2223 m_target->m_detectInvisibility = m_modifier.m_amount;
2225 else
2227 m_target->m_detectInvisibility = 0;
2230 if(Real && m_target->GetTypeId()==TYPEID_PLAYER)
2231 ObjectAccessor::UpdateVisibilityForPlayer((Player*)m_target);
2234 void Aura::HandleAuraModRoot(bool apply, bool Real)
2236 // only at real add/remove aura
2237 if(!Real)
2238 return;
2240 Unit* caster = GetCaster();
2241 uint32 apply_stat = UNIT_STAT_ROOT;
2242 if (apply)
2244 m_target->addUnitState(UNIT_STAT_ROOT);
2245 m_target->SetUInt64Value (UNIT_FIELD_TARGET, 0);
2246 // probably wrong
2247 m_target->SetFlag(UNIT_FIELD_FLAGS,(apply_stat<<16));
2249 //Save last orientation
2250 if (caster)
2251 m_target->SetOrientation(m_target->GetAngle(caster));
2253 if(m_target->GetTypeId() == TYPEID_PLAYER)
2255 WorldPacket data(SMSG_FORCE_MOVE_ROOT, 10);
2256 data.append(m_target->GetPackGUID());
2257 data << (uint32)2;
2258 m_target->SendMessageToSet(&data,true);
2260 else
2261 ((Creature *)m_target)->StopMoving();
2263 else
2265 // Real remove called after current aura remove from lists, check if other similar auras active
2266 if(m_target->HasAuraType(SPELL_AURA_MOD_ROOT))
2267 return;
2269 m_target->clearUnitState(UNIT_STAT_ROOT);
2270 // probably wrong
2271 m_target->RemoveFlag(UNIT_FIELD_FLAGS,(apply_stat<<16));
2272 if(caster && m_target->isAlive()) // set creature facing on root effect if alive
2273 m_target->SetUInt64Value (UNIT_FIELD_TARGET,GetCasterGUID());
2275 if(m_target->GetTypeId() == TYPEID_PLAYER)
2277 WorldPacket data(SMSG_FORCE_MOVE_UNROOT, 10);
2278 data.append(m_target->GetPackGUID());
2279 data << (uint32)2;
2280 m_target->SendMessageToSet(&data,true);
2285 void Aura::HandleAuraModSilence(bool apply, bool Real)
2287 // only at real add/remove aura
2288 if(!Real)
2289 return;
2291 if(apply)
2292 m_target->m_silenced = true;
2293 else
2295 // Real remove called after current aura remove from lists, check if other similar auras active
2296 if(m_target->HasAuraType(SPELL_AURA_MOD_SILENCE))
2297 return;
2299 m_target->m_silenced = false;
2303 void Aura::HandleModThreat(bool apply, bool Real)
2305 // only at real add/remove aura
2306 if(!Real)
2307 return;
2309 if(!m_target || !m_target->isAlive())
2310 return;
2312 Unit* caster = GetCaster();
2314 if(!caster || !caster->isAlive())
2315 return;
2317 if(m_modifier.m_miscvalue < SPELL_SCHOOL_NORMAL || m_modifier.m_miscvalue >= (1<<MAX_SPELL_SCHOOL))
2319 sLog.outError("WARNING: Misc Value for SPELL_AURA_MOD_THREAT not valid");
2320 return;
2323 bool positive = m_modifier.m_miscvalue2 == 0;
2325 for(int8 x=0;x < MAX_SPELL_SCHOOL;x++)
2327 if(m_modifier.m_miscvalue & int32(1<<x))
2329 if(m_target->GetTypeId() == TYPEID_PLAYER)
2330 ApplyPercentModFloatVar(m_target->m_threatModifier[x], positive ? m_modifier.m_amount : -m_modifier.m_amount, apply);
2335 void Aura::HandleAuraModTotalThreat(bool Apply, bool Real)
2337 // only at real add/remove aura
2338 if(!Real)
2339 return;
2341 if(!m_target || !m_target->isAlive() || m_target->GetTypeId()!= TYPEID_PLAYER)
2342 return;
2344 Unit* caster = GetCaster();
2346 if(!caster || !caster->isAlive())
2347 return;
2349 float threatMod = 0.0f;
2350 if(Apply)
2351 threatMod = float(m_modifier.m_amount);
2352 else
2353 threatMod = float(-m_modifier.m_amount);
2355 m_target->getHostilRefManager().threatAssist(caster, threatMod);
2358 void Aura::HandleModTaunt(bool apply, bool Real)
2360 // only at real add/remove aura
2361 if(!Real)
2362 return;
2364 if(!m_target || !m_target->isAlive() || !m_target->CanHaveThreatList())
2365 return;
2367 Unit* caster = GetCaster();
2369 if(!caster || !caster->isAlive() || caster->GetTypeId() != TYPEID_PLAYER)
2370 return;
2372 if(apply)
2374 m_target->TauntApply(caster);
2376 else
2378 // When taunt aura fades out, mob will switch to previous target if current has less than 1.1 * secondthreat
2379 m_target->TauntFadeOut(caster);
2383 /*********************************************************/
2384 /*** MODIDY SPEED ***/
2385 /*********************************************************/
2387 void Aura::HandleAuraModIncreaseSpeedAlways(bool apply, bool Real)
2389 // all applied/removed only at real aura add/remove
2390 if(!Real)
2391 return;
2393 sLog.outDebug("HandleAuraModIncreaseSpeedAlways: Current Speed:%f \tmodify percent:%f", m_target->GetSpeed(MOVE_RUN),(float)m_modifier.m_amount);
2394 if(m_modifier.m_amount<=1)
2395 return;
2397 float rate = (100.0f + m_modifier.m_amount)/100.0f;
2399 m_target->ApplySpeedMod(MOVE_RUN, rate, false, apply );
2400 sLog.outDebug("ChangeSpeedTo:%f", m_target->GetSpeed(MOVE_RUN));
2403 void Aura::HandleAuraModIncreaseSpeed(bool apply, bool Real)
2405 // all applied/removed only at real aura add/remove
2406 if(!Real)
2407 return;
2409 sLog.outDebug("HandleAuraModIncreaseSpeed: Current Speed:%f \tmodify percent:%f", m_target->GetSpeed(MOVE_RUN),(float)m_modifier.m_amount);
2410 if(m_modifier.m_amount<=1)
2411 return;
2413 float rate = (100.0f + m_modifier.m_amount)/100.0f;
2415 m_target->ApplySpeedMod(MOVE_RUN, rate, true, apply );
2417 sLog.outDebug("ChangeSpeedTo:%f", m_target->GetSpeed(MOVE_RUN));
2420 void Aura::HandleAuraModIncreaseMountedSpeed(bool apply, bool Real)
2422 // all applied/removed only at real aura add/remove
2423 if(!Real)
2424 return;
2426 sLog.outDebug("HandleAuraModIncreaseMountedSpeed: Current Speed:%f \tmodify percent:%f", m_target->GetSpeed(MOVE_RUN),(float)m_modifier.m_amount);
2427 if(m_modifier.m_amount<=1)
2428 return;
2430 float rate = (100.0f + m_modifier.m_amount)/100.0f;
2432 m_target->ApplySpeedMod(MOVE_RUN, rate, true, apply );
2434 sLog.outDebug("ChangeSpeedTo:%f", m_target->GetSpeed(MOVE_RUN));
2437 void Aura::HandleAuraModDecreaseSpeed(bool apply, bool Real)
2439 // all applied/removed only at real aura add/remove
2440 if(!Real)
2441 return;
2443 sLog.outDebug("HandleAuraModDecreaseSpeed: Current Speed:%f \tmodify percent:%f", m_target->GetSpeed(MOVE_RUN),(float)m_modifier.m_amount);
2444 if(m_modifier.m_amount <= 0)
2445 { //for new spell dbc
2446 float rate = (100.0f + m_modifier.m_amount)/100.0f;
2448 m_target->ApplySpeedMod(MOVE_RUN, rate, true, apply );
2450 else
2451 { //for old spell dbc
2452 float rate = m_modifier.m_amount / 100.0f;
2454 m_target->ApplySpeedMod(MOVE_RUN, rate, true, apply );
2456 sLog.outDebug("ChangeSpeedTo:%f", m_target->GetSpeed(MOVE_RUN));
2459 void Aura::HandleAuraModIncreaseSwimSpeed(bool apply, bool Real)
2461 // all applied/removed only at real aura add/remove
2462 if(!Real)
2463 return;
2465 sLog.outDebug("HandleAuraModIncreaseSwimSpeed: Current Speed:%f \tmodify percent:%f", m_target->GetSpeed(MOVE_SWIM),(float)m_modifier.m_amount);
2466 if(m_modifier.m_amount<=1)
2467 return;
2469 float rate = (100.0f + m_modifier.m_amount)/100.0f;
2471 m_target->ApplySpeedMod(MOVE_SWIM, rate, true, apply );
2473 sLog.outDebug("ChangeSpeedTo:%f", m_target->GetSpeed(MOVE_SWIM));
2476 /*********************************************************/
2477 /*** IMMUNITY ***/
2478 /*********************************************************/
2480 void Aura::HandleModMechanicImmunity(bool apply, bool Real)
2482 uint32 mechanic = m_modifier.m_miscvalue;
2484 if(apply)
2486 Unit::AuraMap& Auras = m_target->GetAuras();
2487 for(Unit::AuraMap::iterator iter = Auras.begin(), next; iter != Auras.end(); iter = next)
2489 next = iter;
2490 next++;
2491 SpellEntry const *spell = sSpellStore.LookupEntry(iter->second->GetId());
2492 if(spell->Mechanic == mechanic && !iter->second->IsPositive() && spell->Id != GetId())
2494 m_target->RemoveAurasDueToSpell(spell->Id);
2495 if(Auras.empty())
2496 break;
2497 else
2498 next = Auras.begin();
2503 m_target->ApplySpellImmune(GetId(),IMMUNITY_MECHANIC,m_modifier.m_miscvalue,apply);
2506 void Aura::HandleAuraModEffectImmunity(bool apply, bool Real)
2508 if(!apply)
2510 if(m_target->GetTypeId() == TYPEID_PLAYER)
2512 if(((Player*)m_target)->InBattleGround())
2514 BattleGround *bg = sBattleGroundMgr.GetBattleGround(((Player*)m_target)->GetBattleGroundId());
2515 if(bg)
2517 switch(bg->GetID())
2519 case BATTLEGROUND_AV:
2521 break;
2523 case BATTLEGROUND_WS:
2525 if(((BattleGroundWS*)bg)->IsHordeFlagPickedup())
2526 // Warsong Flag, horde
2527 if(GetSpellProto()->Id == 23333)
2528 // Horde Flag Drop
2529 m_target->CastSpell(m_target, 23334, true, NULL, this);
2530 if(((BattleGroundWS*)bg)->IsAllianceFlagPickedup())
2531 // Silverwing Flag, alliance
2532 if(GetSpellProto()->Id == 23335)
2533 // Alliance Flag Drop
2534 m_target->CastSpell(m_target, 23336, true, NULL, this);
2535 break;
2537 case BATTLEGROUND_AB:
2539 break;
2541 case BATTLEGROUND_EY:
2543 break;
2551 m_target->ApplySpellImmune(GetId(),IMMUNITY_EFFECT,m_modifier.m_miscvalue,apply);
2554 void Aura::HandleAuraModStateImmunity(bool apply, bool Real)
2556 m_target->ApplySpellImmune(GetId(),IMMUNITY_STATE,m_modifier.m_miscvalue,apply);
2559 void Aura::HandleAuraModSchoolImmunity(bool apply, bool Real)
2561 m_target->ApplySpellImmune(GetId(),IMMUNITY_SCHOOL,m_modifier.m_miscvalue,apply);
2564 void Aura::HandleAuraModDmgImmunity(bool apply, bool Real)
2566 m_target->ApplySpellImmune(GetId(),IMMUNITY_DAMAGE,m_modifier.m_miscvalue,apply);
2569 void Aura::HandleAuraModDispelImmunity(bool apply, bool Real)
2571 Unit* caster = GetCaster();
2572 if (!caster)
2573 return;
2575 m_target->ApplySpellImmune(GetId(),IMMUNITY_DISPEL,m_modifier.m_miscvalue,apply);
2577 if(m_target->IsHostileTo(caster) && (m_target->GetTypeId()!=TYPEID_PLAYER || !((Player*)m_target)->isGameMaster()))
2579 if (m_target->HasStealthAura() && m_modifier.m_miscvalue == 5)
2581 m_target->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH);
2584 if (m_target->HasInvisibilityAura() && m_modifier.m_miscvalue == 6)
2586 m_target->RemoveSpellsCausingAura(SPELL_AURA_MOD_INVISIBILITY);
2589 if( caster->GetTypeId()==TYPEID_PLAYER && !caster->IsPvP() && m_target->IsPvP())
2590 ((Player*)caster)->UpdatePvP(true, true);
2594 /*********************************************************/
2595 /*** MANA SHIELD ***/
2596 /*********************************************************/
2598 void Aura::HandleAuraDamageShield(bool apply, bool Real)
2600 /*if(apply)
2602 for(std::list<struct DamageShield>::iterator i = m_target->m_damageShields.begin();i != m_target->m_damageShields.end();i++)
2603 if(i->m_spellId == GetId() && i->m_caster_guid == m_caster_guid)
2605 m_target->m_damageShields.erase(i);
2606 break;
2608 DamageShield* ds = new DamageShield();
2609 ds->m_caster_guid = m_caster_guid;
2610 ds->m_damage = m_modifier.m_amount;
2611 ds->m_spellId = GetId();
2612 m_target->m_damageShields.push_back((*ds));
2614 else
2616 for(std::list<struct DamageShield>::iterator i = m_target->m_damageShields.begin();i != m_target->m_damageShields.end();i++)
2617 if(i->m_spellId == GetId() && i->m_caster_guid == m_caster_guid)
2619 m_target->m_damageShields.erase(i);
2620 break;
2625 void Aura::HandleAuraManaShield(bool apply, bool Real)
2627 if (apply && !m_absorbDmg)
2628 m_absorbDmg = m_modifier.m_amount;
2630 /*if(apply)
2633 for(std::list<struct DamageManaShield*>::iterator i = m_target->m_damageManaShield.begin();i != m_target->m_damageManaShield.end();i++)
2635 if(GetId() == (*i)->m_spellId)
2637 delete *i;
2638 m_target->m_damageManaShield.erase(i);
2642 DamageManaShield *dms = new DamageManaShield();
2644 dms->m_spellId = GetId();
2645 dms->m_modType = m_modifier.m_auraname;
2646 dms->m_totalAbsorb = m_modifier.m_amount;
2647 dms->m_currAbsorb = 0;
2648 dms->m_schoolType = m_modifier.m_miscvalue;
2649 m_target->m_damageManaShield.push_back(dms);
2651 else
2653 for(std::list<struct DamageManaShield*>::iterator i = m_target->m_damageManaShield.begin();i != m_target->m_damageManaShield.end();i++)
2655 if(GetId() == (*i)->m_spellId)
2657 delete *i;
2658 m_target->m_damageManaShield.erase(i);
2659 break;
2665 void Aura::HandleAuraModStalked(bool apply, bool Real)
2667 // used by spells: Hunter's Mark, Mind Vision, Syndicate Tracker (MURP) DND
2668 if(apply)
2669 m_target->SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_TRACK_UNIT);
2670 else
2671 m_target->RemoveFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_TRACK_UNIT);
2674 void Aura::HandleAuraSchoolAbsorb(bool apply, bool Real)
2676 if (apply && !m_absorbDmg)
2677 m_absorbDmg = m_modifier.m_amount;
2678 /*if(apply)
2681 for(std::list<struct DamageManaShield*>::iterator i = m_target->m_damageManaShield.begin();i != m_target->m_damageManaShield.end();i++)
2683 if(GetId() == (*i)->m_spellId)
2685 m_target->m_damageManaShield.erase(i);
2689 DamageManaShield *dms = new DamageManaShield();
2691 dms->m_spellId = GetId();
2692 dms->m_modType = m_modifier.m_auraname;
2693 dms->m_totalAbsorb = m_modifier.m_amount;
2694 dms->m_currAbsorb = 0;
2695 dms->m_schoolType = m_modifier.m_miscvalue;
2696 m_target->m_damageManaShield.push_back(dms);
2698 else
2700 for(std::list<struct DamageManaShield*>::iterator i = m_target->m_damageManaShield.begin();i != m_target->m_damageManaShield.end();i++)
2702 if(GetId() == (*i)->m_spellId)
2704 m_target->m_damageManaShield.erase(i);
2705 break;
2711 /*********************************************************/
2712 /*** PROC TRIGGER ***/
2713 /*********************************************************/
2715 void Aura::HandleAuraProcTriggerSpell(bool apply, bool Real)
2717 if(Real && apply && !m_procCharges)
2719 m_procCharges = GetSpellProto()->procCharges;
2720 if (!m_procCharges)
2721 m_procCharges = -1;
2725 void Aura::HandleAuraProcTriggerDamage(bool apply, bool Real)
2727 if(Real && apply && !m_procCharges)
2729 m_procCharges = GetSpellProto()->procCharges;
2730 if (!m_procCharges)
2731 m_procCharges = -1;
2735 /*********************************************************/
2736 /*** PERIODIC ***/
2737 /*********************************************************/
2739 void Aura::HandlePeriodicTriggerSpell(bool apply, bool Real)
2741 if (m_periodicTimer <= 0)
2742 m_periodicTimer += m_modifier.periodictime;
2744 m_isPeriodic = apply;
2745 m_isTrigger = apply;
2748 void Aura::HandlePeriodicEnergize(bool apply, bool Real)
2750 if (m_periodicTimer <= 0)
2751 m_periodicTimer += m_modifier.periodictime;
2753 m_isPeriodic = apply;
2756 void Aura::HandlePeriodicHeal(bool apply, bool Real)
2758 if (m_periodicTimer <= 0)
2759 m_periodicTimer += m_modifier.periodictime;
2761 m_isPeriodic = apply;
2763 // only at real apply
2764 if (Real && apply && GetSpellProto()->Mechanic == 16)
2766 m_target->CastSpell(m_target,11196,true,NULL,this);
2770 void Aura::HandlePeriodicDamage(bool apply, bool Real)
2772 if (m_periodicTimer <= 0)
2773 m_periodicTimer += m_modifier.periodictime;
2775 m_isPeriodic = apply;
2778 void Aura::HandlePeriodicDamagePCT(bool apply, bool Real)
2780 if (m_periodicTimer <= 0)
2781 m_periodicTimer += m_modifier.periodictime;
2783 m_isPeriodic = apply;
2786 void Aura::HandlePeriodicLeech(bool apply, bool Real)
2788 if (m_periodicTimer <= 0)
2789 m_periodicTimer += m_modifier.periodictime;
2791 m_isPeriodic = apply;
2794 void Aura::HandlePeriodicManaLeech(bool apply, bool Real)
2796 if (m_periodicTimer <= 0)
2797 m_periodicTimer += m_modifier.periodictime;
2799 m_isPeriodic = apply;
2802 /*********************************************************/
2803 /*** MODIFY STATS ***/
2804 /*********************************************************/
2806 /********************************/
2807 /*** RESISTANCE ***/
2808 /********************************/
2810 void Aura::HandleAuraModResistanceExclusive(bool apply, bool Real)
2812 if(m_modifier.m_miscvalue < IMMUNE_SCHOOL_PHYSICAL || m_modifier.m_miscvalue > 127)
2814 sLog.outError("WARNING: Misc Value for SPELL_AURA_MOD_BASE_RESISTANCE_PCT not valid");
2815 return;
2818 bool positive = m_modifier.m_miscvalue2 == 0;
2820 for(int8 x = SPELL_SCHOOL_NORMAL; x < MAX_SPELL_SCHOOL;x++)
2822 if(m_modifier.m_miscvalue & int32(1<<x))
2824 m_target->HandleStatModifier(UnitMods(UNIT_MOD_RESISTANCE_START + x), BASE_VALUE, float(m_modifier.m_amount), apply);
2825 if(m_target->GetTypeId() == TYPEID_PLAYER)
2826 m_target->ApplyResistanceBuffModsMod(SpellSchools(x),positive,m_modifier.m_amount, apply);
2831 void Aura::HandleAuraModResistance(bool apply, bool Real)
2833 if(m_modifier.m_miscvalue < IMMUNE_SCHOOL_PHYSICAL || m_modifier.m_miscvalue > 127)
2835 sLog.outError("WARNING: Misc Value for SPELL_AURA_MOD_RESISTANCE not valid");
2836 return;
2839 bool positive = m_modifier.m_miscvalue2 == 0;
2841 for(int8 x = SPELL_SCHOOL_NORMAL; x < MAX_SPELL_SCHOOL;x++)
2843 if(m_modifier.m_miscvalue & int32(1<<x))
2845 m_target->HandleStatModifier(UnitMods(UNIT_MOD_RESISTANCE_START + x), TOTAL_VALUE, float(m_modifier.m_amount), apply);
2846 if(m_target->GetTypeId() == TYPEID_PLAYER || ((Creature*)m_target)->isPet())
2847 m_target->ApplyResistanceBuffModsMod(SpellSchools(x),positive,m_modifier.m_amount, apply);
2852 void Aura::HandleAuraModBaseResistancePCT(bool apply, bool Real)
2854 if(m_modifier.m_miscvalue < IMMUNE_SCHOOL_PHYSICAL || m_modifier.m_miscvalue > 127)
2856 sLog.outError("WARNING: Misc Value for SPELL_AURA_MOD_BASE_RESISTANCE_PCT not valid");
2857 return;
2860 // only players have base stats
2861 if(m_target->GetTypeId() != TYPEID_PLAYER)
2863 //pets only have base armor
2864 if(((Creature*)m_target)->isPet() && m_modifier.m_miscvalue & IMMUNE_SCHOOL_PHYSICAL)
2866 m_target->HandleStatModifier(UNIT_MOD_ARMOR, BASE_PCT, float(m_modifier.m_amount), apply);
2869 else
2871 for(int8 x = SPELL_SCHOOL_NORMAL; x < MAX_SPELL_SCHOOL;x++)
2873 if(m_modifier.m_miscvalue & int32(1<<x))
2875 m_target->HandleStatModifier(UnitMods(UNIT_MOD_RESISTANCE_START + x), BASE_PCT, float(m_modifier.m_amount), apply);
2881 void Aura::HandleModResistancePercent(bool apply, bool Real)
2883 for(int8 i = SPELL_SCHOOL_NORMAL; i < MAX_SPELL_SCHOOL; i++)
2885 if(m_modifier.m_miscvalue & int32(1<<i))
2887 m_target->HandleStatModifier(UnitMods(UNIT_MOD_RESISTANCE_START + i), TOTAL_PCT, float(m_modifier.m_amount), apply);
2888 if(m_target->GetTypeId() == TYPEID_PLAYER || ((Creature*)m_target)->isPet())
2890 m_target->ApplyResistanceBuffModsPercentMod(SpellSchools(i),true,m_modifier.m_amount, apply);
2891 m_target->ApplyResistanceBuffModsPercentMod(SpellSchools(i),false,m_modifier.m_amount, apply);
2897 void Aura::HandleModBaseResistance(bool apply, bool Real)
2899 // only players have base stats
2900 if(m_target->GetTypeId() != TYPEID_PLAYER)
2902 //only pets have base stats
2903 if(((Creature*)m_target)->isPet() && m_modifier.m_miscvalue & IMMUNE_SCHOOL_PHYSICAL)
2904 m_target->HandleStatModifier(UNIT_MOD_ARMOR, TOTAL_VALUE, float(m_modifier.m_amount), apply);
2906 else
2908 for(int i = SPELL_SCHOOL_NORMAL; i < MAX_SPELL_SCHOOL; i++)
2909 if(m_modifier.m_miscvalue & (1<<i))
2910 m_target->HandleStatModifier(UnitMods(UNIT_MOD_RESISTANCE_START + i), TOTAL_VALUE, float(m_modifier.m_amount), apply);
2914 /********************************/
2915 /*** STAT ***/
2916 /********************************/
2918 void Aura::HandleAuraModStat(bool apply, bool Real)
2920 if (m_modifier.m_miscvalue < -1 || m_modifier.m_miscvalue > 4)
2922 sLog.outError("WARNING: Misc Value for SPELL_AURA_MOD_STAT not valid");
2923 return;
2926 for(int32 i = STAT_STRENGTH; i < MAX_STATS; i++)
2928 if (m_modifier.m_miscvalue == -1 || m_modifier.m_miscvalue == i)
2930 //m_target->ApplyStatMod(Stats(i), m_modifier.m_amount,apply);
2931 m_target->HandleStatModifier(UnitMods(UNIT_MOD_STAT_START + i), TOTAL_VALUE, float(m_modifier.m_amount), apply);
2932 if(m_target->GetTypeId() == TYPEID_PLAYER || ((Creature*)m_target)->isPet())
2934 if (m_modifier.m_miscvalue2 == 0)
2935 ((Player*)m_target)->ApplyPosStatMod(Stats(i),m_modifier.m_amount,apply);
2936 else
2937 ((Player*)m_target)->ApplyNegStatMod(Stats(i),m_modifier.m_amount,apply);
2943 void Aura::HandleModPercentStat(bool apply, bool Real)
2945 if (m_modifier.m_miscvalue < -1 || m_modifier.m_miscvalue > 4)
2947 sLog.outError("WARNING: Misc Value for SPELL_AURA_MOD_PERCENT_STAT not valid");
2948 return;
2951 // only players have base stats
2952 if (m_target->GetTypeId() != TYPEID_PLAYER)
2953 return;
2955 for (int32 i = STAT_STRENGTH; i < MAX_STATS; ++i)
2957 if(m_modifier.m_miscvalue == i || m_modifier.m_miscvalue == -1)
2959 m_target->HandleStatModifier(UnitMods(UNIT_MOD_STAT_START + i), BASE_PCT, float(m_modifier.m_amount), apply);
2964 void Aura::HandleModHealingDone(bool apply, bool Real)
2966 // implemented in Unit::SpellHealingBonus
2967 // this information is for client side only
2968 if(m_target->GetTypeId() == TYPEID_PLAYER)
2969 m_target->ApplyModUInt32Value(PLAYER_FIELD_MOD_HEALING_DONE_POS,m_modifier.m_amount,apply);
2972 void Aura::HandleModTotalPercentStat(bool apply, bool Real)
2974 if (m_modifier.m_miscvalue < -1 || m_modifier.m_miscvalue > 4)
2976 sLog.outError("WARNING: Misc Value for SPELL_AURA_MOD_PERCENT_STAT not valid");
2977 return;
2980 for (int32 i = STAT_STRENGTH; i < MAX_STATS; i++)
2982 if(m_modifier.m_miscvalue == i || m_modifier.m_miscvalue == -1)
2984 m_target->HandleStatModifier(UnitMods(UNIT_MOD_STAT_START + i), TOTAL_PCT, float(m_modifier.m_amount), apply);
2985 if (m_target->GetTypeId() == TYPEID_PLAYER)
2987 ((Player*)m_target)->ApplyPosStatPercentMod(Stats(i), m_modifier.m_amount, apply );
2988 ((Player*)m_target)->ApplyNegStatPercentMod(Stats(i), m_modifier.m_amount, apply );
2994 /********************************/
2995 /*** HEAL & ENERGIZE ***/
2996 /********************************/
2997 void Aura::HandleAuraModTotalHealthPercentRegen(bool apply, bool Real)
3000 Need additional checking for auras who reduce or increase healing, magic effect like Dumpen Magic,
3001 so this aura not fully working.
3003 if((GetSpellProto()->AuraInterruptFlags & AURA_INTERRUPT_FLAG_NOT_SEATED) && apply)
3005 m_target->SetFlag(UNIT_FIELD_BYTES_1, PLAYER_STATE_SIT);
3006 if(m_target->GetTypeId() == TYPEID_PLAYER)
3007 ((Player*)m_target)->SetStandState(PLAYER_STATE_SIT);
3010 if(apply && m_periodicTimer <= 0)
3012 m_periodicTimer += m_modifier.periodictime;
3013 float modifier = m_currentBasePoints+1;
3014 m_modifier.m_amount = uint32(m_target->GetMaxHealth() * modifier/100);
3016 if(m_target->GetHealth() < m_target->GetMaxHealth())
3018 // PeriodicAuraLog can cast triggered spells with stats changes
3019 m_target->PeriodicAuraLog(m_target, GetSpellProto(), &m_modifier,GetEffIndex());
3023 m_isPeriodic = apply;
3026 void Aura::HandleAuraModTotalManaPercentRegen(bool apply, bool Real)
3028 if((GetSpellProto()->AuraInterruptFlags & AURA_INTERRUPT_FLAG_NOT_SEATED) && apply)
3030 m_target->SetFlag(UNIT_FIELD_BYTES_1, PLAYER_STATE_SIT);
3031 if(m_target->GetTypeId() == TYPEID_PLAYER)
3032 ((Player*)m_target)->SetStandState(PLAYER_STATE_SIT);
3035 if(apply && m_periodicTimer <= 0 && m_target->getPowerType() == POWER_MANA)
3037 m_periodicTimer += m_modifier.periodictime;
3038 if (m_modifier.m_amount)
3040 float modifier = m_currentBasePoints+1;
3041 // take percent (m_modifier.m_amount) max mana
3042 m_modifier.m_amount = uint32((m_target->GetMaxPower(POWER_MANA) * modifier)/100);
3045 if(m_target->GetPower(POWER_MANA) < m_target->GetMaxPower(POWER_MANA))
3047 // PeriodicAuraLog can cast triggered spells with stats changes
3048 m_target->PeriodicAuraLog(m_target, GetSpellProto(), &m_modifier,GetEffIndex());
3052 m_isPeriodic = apply;
3055 void Aura::HandleModRegen(bool apply, bool Real) // eating
3057 if ((GetSpellProto()->AuraInterruptFlags & AURA_INTERRUPT_FLAG_NOT_SEATED) && apply)
3059 m_target->SetFlag(UNIT_FIELD_BYTES_1, PLAYER_STATE_SIT);
3060 if(m_target->GetTypeId() == TYPEID_PLAYER)
3061 ((Player*)m_target)->SetStandState(PLAYER_STATE_SIT);
3064 if(apply && m_periodicTimer <= 0)
3066 m_periodicTimer += 5000;
3067 int32 gain = m_target->ModifyHealth(m_modifier.m_amount);
3068 Unit *caster = GetCaster();
3069 if (caster)
3071 SpellEntry const *spellProto = GetSpellProto();
3072 if (spellProto)
3073 m_target->getHostilRefManager().threatAssist(caster, float(gain) * 0.5f, spellProto);
3077 m_isPeriodic = apply;
3080 void Aura::HandleModPowerRegen(bool apply, bool Real) // drinking
3082 if ((GetSpellProto()->AuraInterruptFlags & AURA_INTERRUPT_FLAG_NOT_SEATED) && apply)
3084 m_target->SetFlag(UNIT_FIELD_BYTES_1, PLAYER_STATE_SIT);
3085 if(m_target->GetTypeId() == TYPEID_PLAYER)
3086 ((Player*)m_target)->SetStandState(PLAYER_STATE_SIT);
3089 if(apply && m_periodicTimer <= 0)
3091 m_periodicTimer += 5000;
3093 Powers pt = m_target->getPowerType();
3094 if(int32(pt) != m_modifier.m_miscvalue)
3095 return;
3097 // Prevent rage regeneration in combat with rage loss slowdown warrior talent and 0<->1 switching range out combat.
3098 if( !(pt == POWER_RAGE && (m_target->isInCombat() || m_target->GetPower(POWER_RAGE) == 0)) )
3100 int32 gain = m_target->ModifyPower(pt, m_modifier.m_amount);
3101 Unit *caster = GetCaster();
3102 if (caster && pt == POWER_MANA)
3104 SpellEntry const *spellProto = GetSpellProto();
3105 if (spellProto)
3106 m_target->getHostilRefManager().threatAssist(caster, float(gain) * 0.5f, spellProto);
3111 m_isPeriodic = apply;
3114 void Aura::HandleModManaRegen(bool apply, bool Real)
3116 if(apply && m_periodicTimer <= 0)
3118 m_periodicTimer += 5000;
3120 Powers pt = m_target->getPowerType();
3121 if(int32(pt) != POWER_MANA)
3122 return;
3124 int32 gain = m_target->ModifyPower(POWER_MANA, int32(m_modifier.m_amount * m_target->GetStat(Stats(m_modifier.m_miscvalue)) / 100.0f));
3126 Unit *caster = GetCaster();
3127 if (caster)
3129 SpellEntry const *spellProto = GetSpellProto();
3130 if (spellProto)
3131 m_target->getHostilRefManager().threatAssist(caster, float(gain) * 0.5f, spellProto);
3135 m_isPeriodic = apply;
3138 void Aura::HandleAuraModIncreaseHealth(bool apply, bool Real)
3140 if(GetSpellProto()->Id == 12976) //Warrior Last Stand triggered spell
3142 if(Real)
3144 if(apply)
3146 m_target->HandleStatModifier(UNIT_MOD_HEALTH, TOTAL_VALUE, float(m_modifier.m_amount), apply);
3147 m_target->ModifyHealth(m_modifier.m_amount);
3149 else
3151 if (int32(m_target->GetHealth()) > m_modifier.m_amount)
3152 m_target->ModifyHealth(-m_modifier.m_amount);
3153 else
3154 m_target->SetHealth(1);
3155 m_target->HandleStatModifier(UNIT_MOD_HEALTH, TOTAL_VALUE, float(m_modifier.m_amount), apply);
3159 return;
3162 // generic case
3163 m_target->HandleStatModifier(UNIT_MOD_HEALTH, TOTAL_VALUE, float(m_modifier.m_amount), apply);
3166 void Aura::HandleAuraModIncreaseEnergy(bool apply, bool Real)
3168 Powers powerType = m_target->getPowerType();
3169 if(int32(powerType) != m_modifier.m_miscvalue)
3170 return;
3172 m_target->HandleStatModifier(UnitMods(UNIT_MOD_POWER_START + powerType), TOTAL_VALUE, float(m_modifier.m_amount), apply);
3175 void Aura::HandleAuraModIncreaseEnergyPercent(bool apply, bool Real)
3177 Powers powerType = m_target->getPowerType();
3178 if(int32(powerType) != m_modifier.m_miscvalue)
3179 return;
3181 m_target->HandleStatModifier(UnitMods(UNIT_MOD_POWER_START + powerType), TOTAL_PCT, float(m_modifier.m_amount), apply);
3184 void Aura::HandleAuraModIncreaseHealthPercent(bool apply, bool Real)
3186 //m_target->ApplyMaxHealthPercentMod(m_modifier.m_amount,apply);
3187 m_target->HandleStatModifier(UNIT_MOD_HEALTH, TOTAL_PCT, float(m_modifier.m_amount), apply);
3190 /********************************/
3191 /*** FIGHT ***/
3192 /********************************/
3194 void Aura::HandleAuraModParryPercent(bool apply, bool Real)
3196 if(m_target->GetTypeId()!=TYPEID_PLAYER)
3197 return;
3199 if(Real && apply && !m_procCharges)
3201 m_procCharges = GetSpellProto()->procCharges;
3202 if (!m_procCharges)
3203 m_procCharges = -1;
3206 ((Player*)m_target)->HandleBaseModValue(PARRY_PERCENTAGE, FLAT_MOD, float (m_modifier.m_amount), apply);
3209 void Aura::HandleAuraModDodgePercent(bool apply, bool Real)
3211 if(m_target->GetTypeId()!=TYPEID_PLAYER)
3212 return;
3214 ((Player*)m_target)->HandleBaseModValue(DODGE_PERCENTAGE, FLAT_MOD, float (m_modifier.m_amount), apply);
3215 //sLog.outError("BONUS DODGE CHANCE: + %f", float(m_modifier.m_amount));
3218 void Aura::HandleAuraModBlockPercent(bool apply, bool Real)
3220 if(m_target->GetTypeId()!=TYPEID_PLAYER)
3221 return;
3223 ((Player*)m_target)->HandleBaseModValue(BLOCK_PERCENTAGE, FLAT_MOD, float (m_modifier.m_amount), apply);
3224 //sLog.outError("BONUS BLOCK CHANCE: + %f", float(m_modifier.m_amount));
3227 void Aura::HandleAuraModCritPercent(bool apply, bool Real)
3229 if(m_target->GetTypeId()!=TYPEID_PLAYER)
3230 return;
3232 // apply item specific bonuses for already equipped weapon
3233 if(Real)
3235 if(Item* pItem = ((Player*)m_target)->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_MAINHAND))
3236 ((Player*)m_target)->_ApplyWeaponDependentAuraCritMod(pItem,EQUIPMENT_SLOT_MAINHAND,this,apply);
3238 if(Item* pItem = ((Player*)m_target)->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_OFFHAND))
3239 ((Player*)m_target)->_ApplyWeaponDependentAuraCritMod(pItem,EQUIPMENT_SLOT_OFFHAND,this,apply);
3241 if(Item* pItem = ((Player*)m_target)->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_RANGED))
3242 ((Player*)m_target)->_ApplyWeaponDependentAuraCritMod(pItem,EQUIPMENT_SLOT_RANGED,this,apply);
3245 // mods must be applied base at equipped weapon class and subclass comparison
3246 // with spell->EquippedItemClass and EquippedItemSubClassMask and EquippedItemInventoryTypeMask
3247 // m_modifier.m_miscvalue comparison with item generated damage types
3249 if (GetSpellProto()->EquippedItemClass == -1)
3251 ((Player*)m_target)->HandleBaseModValue(CRIT_PERCENTAGE, FLAT_MOD, float (m_modifier.m_amount), apply);
3252 ((Player*)m_target)->HandleBaseModValue(OFFHAND_CRIT_PERCENTAGE, FLAT_MOD, float (m_modifier.m_amount), apply);
3253 ((Player*)m_target)->HandleBaseModValue(RANGED_CRIT_PERCENTAGE, FLAT_MOD, float (m_modifier.m_amount), apply);
3255 else
3257 // done in Player::_ApplyWeaponDependentAuraMods
3261 void Aura::HandleModHitChance(bool Apply, bool Real)
3263 m_target->m_modHitChance += Apply?m_modifier.m_amount:(-m_modifier.m_amount);
3266 void Aura::HandleModSpellHitChance(bool Apply, bool Real)
3268 m_target->m_modSpellHitChance += Apply?m_modifier.m_amount:(-m_modifier.m_amount);
3271 void Aura::HandleModSpellCritChance(bool Apply, bool Real)
3273 if(m_target->GetTypeId() == TYPEID_PLAYER)
3275 ((Player*)m_target)->HandleBaseModValue(SPELL_CRIT_PERCENTAGE, FLAT_MOD, float(m_modifier.m_amount), Apply);
3277 else
3279 m_target->m_baseSpellCritChance += Apply?m_modifier.m_amount:(-m_modifier.m_amount);
3283 void Aura::HandleModSpellCritChanceShool(bool apply, bool Real)
3285 if(m_target->GetTypeId() != TYPEID_PLAYER)
3286 return;
3288 for(int i = SPELL_SCHOOL_HOLY; i < MAX_SPELL_SCHOOL; i++)
3290 if(m_modifier.m_miscvalue == -2 || (m_modifier.m_miscvalue & 1<<i) != 0)
3291 ((Player*)m_target)->HandleBaseModValue( BaseModGroup(SPELL_CRIT_PERCENTAGE + i), FLAT_MOD, float(m_modifier.m_amount), apply);
3295 /********************************/
3296 /*** ATTACK SPEED ***/
3297 /********************************/
3299 void Aura::HandleModCastingSpeed(bool apply, bool Real)
3301 m_target->ApplyPercentModFloatValue(UNIT_MOD_CAST_SPEED,-m_modifier.m_amount,apply);
3304 void Aura::HandleModAttackSpeed(bool apply, bool Real)
3306 if(!m_target || !m_target->isAlive() )
3307 return;
3309 m_target->ApplyAttackTimePercentMod(BASE_ATTACK,m_modifier.m_amount,apply);
3312 void Aura::HandleHaste(bool apply, bool Real)
3314 if(m_modifier.m_amount >= 0)
3316 // v*(1+percent/100)
3317 m_target->ApplyAttackTimePercentMod(BASE_ATTACK, m_modifier.m_amount,apply);
3318 m_target->ApplyAttackTimePercentMod(OFF_ATTACK, m_modifier.m_amount,apply);
3320 m_target->ApplyAttackTimePercentMod(RANGED_ATTACK,m_modifier.m_amount,apply);
3322 else
3324 // v/(1+abs(percent)/100)
3325 m_target->ApplyAttackTimePercentMod(BASE_ATTACK, -m_modifier.m_amount,!apply);
3326 m_target->ApplyAttackTimePercentMod(OFF_ATTACK, -m_modifier.m_amount,!apply);
3328 m_target->ApplyAttackTimePercentMod(RANGED_ATTACK,-m_modifier.m_amount,!apply);
3332 void Aura::HandleAuraModRangedHaste(bool apply, bool Real)
3334 if(m_modifier.m_amount >= 0)
3335 m_target->ApplyAttackTimePercentMod(RANGED_ATTACK, m_modifier.m_amount, apply);
3336 else
3337 m_target->ApplyAttackTimePercentMod(RANGED_ATTACK, -m_modifier.m_amount, !apply);
3340 void Aura::HandleRangedAmmoHaste(bool apply, bool Real)
3342 if(m_target->GetTypeId() != TYPEID_PLAYER)
3343 return;
3344 m_target->ApplyAttackTimePercentMod(RANGED_ATTACK,m_modifier.m_amount, apply);
3347 /********************************/
3348 /*** ATTACK POWER ***/
3349 /********************************/
3351 void Aura::HandleAuraModAttackPower(bool apply, bool Real)
3353 m_target->HandleStatModifier(UNIT_MOD_ATTACK_POWER, TOTAL_VALUE, float(m_modifier.m_amount), apply);
3356 void Aura::HandleAuraModRangedAttackPower(bool apply, bool Real)
3358 if((m_target->getClassMask() & CLASSMASK_WAND_USERS)!=0)
3359 return;
3361 m_target->HandleStatModifier(UNIT_MOD_ATTACK_POWER_RANGED, TOTAL_VALUE, float(m_modifier.m_amount), apply);
3364 void Aura::HandleAuraModAttackPowerPercent(bool apply, bool Real)
3366 //UNIT_FIELD_ATTACK_POWER_MULTIPLIER = multiplier - 1
3367 m_target->HandleStatModifier(UNIT_MOD_ATTACK_POWER, TOTAL_PCT, float(m_modifier.m_amount), apply);
3370 void Aura::HandleAuraModRangedAttackPowerPercent(bool apply, bool Real)
3372 if((m_target->getClassMask() & CLASSMASK_WAND_USERS)!=0)
3373 return;
3375 //UNIT_FIELD_RANGED_ATTACK_POWER_MULTIPLIER = multiplier - 1
3376 m_target->HandleStatModifier(UNIT_MOD_ATTACK_POWER_RANGED, TOTAL_PCT, float(m_modifier.m_amount), apply);
3379 /********************************/
3380 /*** DAMAGE BONUS ***/
3381 /********************************/
3382 void Aura::HandleModDamageDone(bool apply, bool Real)
3384 // apply item specific bonuses for already equipped weapon
3385 if(Real && m_target->GetTypeId()==TYPEID_PLAYER)
3387 if(Item* pItem = ((Player*)m_target)->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_MAINHAND))
3388 ((Player*)m_target)->_ApplyWeaponDependentAuraDamageMod(pItem,EQUIPMENT_SLOT_MAINHAND,this,apply);
3390 if(Item* pItem = ((Player*)m_target)->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_OFFHAND))
3391 ((Player*)m_target)->_ApplyWeaponDependentAuraDamageMod(pItem,EQUIPMENT_SLOT_OFFHAND,this,apply);
3393 if(Item* pItem = ((Player*)m_target)->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_RANGED))
3394 ((Player*)m_target)->_ApplyWeaponDependentAuraDamageMod(pItem,EQUIPMENT_SLOT_RANGED,this,apply);
3397 // m_modifier.m_miscvalue is bitmask of spell schools
3398 // 1 ( 0-bit ) - normal school damage (IMMUNE_SCHOOL_PHYSICAL)
3399 // 126 - full bitmask all magic damages (IMMUNE_SCHOOL_MAGIC) including wands
3400 // 127 - full bitmask any damages
3402 // mods must be applied base at equipped weapon class and subclass comparison
3403 // with spell->EquippedItemClass and EquippedItemSubClassMask and EquippedItemInventoryTypeMask
3404 // m_modifier.m_miscvalue comparison with item generated damage types
3406 if((m_modifier.m_miscvalue & IMMUNE_SCHOOL_PHYSICAL) != 0)
3408 // apply generic physical damage bonuses including wand case
3409 if (GetSpellProto()->EquippedItemClass == -1 || m_target->GetTypeId() != TYPEID_PLAYER)
3411 m_target->HandleStatModifier(UNIT_MOD_DAMAGE_MAINHAND, TOTAL_VALUE, float(m_modifier.m_amount), apply);
3412 m_target->HandleStatModifier(UNIT_MOD_DAMAGE_OFFHAND, TOTAL_VALUE, float(m_modifier.m_amount), apply);
3413 m_target->HandleStatModifier(UNIT_MOD_DAMAGE_RANGED, TOTAL_VALUE, float(m_modifier.m_amount), apply);
3415 else
3417 // done in Player::_ApplyWeaponDependentAuraMods
3420 if(m_target->GetTypeId() == TYPEID_PLAYER)
3422 if(m_modifier.m_miscvalue2)
3423 m_target->ApplyModUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_NEG,m_modifier.m_amount,apply);
3424 else
3425 m_target->ApplyModUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_POS,m_modifier.m_amount,apply);
3429 // Skip non magic case for speedup
3430 if((m_modifier.m_miscvalue & IMMUNE_SCHOOL_MAGIC) == 0)
3431 return;
3433 if( GetSpellProto()->EquippedItemClass != -1 || GetSpellProto()->EquippedItemInventoryTypeMask != 0 )
3435 // wand magic case (skip generic to all item spell bonuses)
3436 // done in Player::_ApplyWeaponDependentAuraMods
3438 // Skip item specific requirements for not wand magic damage
3439 return;
3442 // Magic damage modifiers implemented in Unit::SpellDamageBonus
3443 // This information for client side use only
3444 if(m_target->GetTypeId() == TYPEID_PLAYER)
3446 if(m_modifier.m_miscvalue2)
3448 for(int i = SPELL_SCHOOL_HOLY; i < MAX_SPELL_SCHOOL; i++)
3450 if((m_modifier.m_miscvalue & 1<<i) != 0)
3451 m_target->ApplyModUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_NEG+i,m_modifier.m_amount,apply);
3454 else
3456 for(int i = SPELL_SCHOOL_HOLY; i < MAX_SPELL_SCHOOL; i++)
3458 if((m_modifier.m_miscvalue & 1<<i) != 0)
3459 m_target->ApplyModUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_POS+i,m_modifier.m_amount,apply);
3462 Pet* pet = m_target->GetPet();
3463 if(pet)
3464 pet->UpdateAttackPowerAndDamage();
3468 void Aura::HandleModDamagePercentDone(bool apply, bool Real)
3470 sLog.outDebug("AURA MOD DAMAGE type:%u type2:%u", m_modifier.m_miscvalue, m_modifier.m_miscvalue2);
3472 // apply item specific bonuses for already equipped weapon
3473 if(Real && m_target->GetTypeId()==TYPEID_PLAYER)
3475 if(Item* pItem = ((Player*)m_target)->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_MAINHAND))
3476 ((Player*)m_target)->_ApplyWeaponDependentAuraDamageMod(pItem,EQUIPMENT_SLOT_MAINHAND,this,apply);
3478 if(Item* pItem = ((Player*)m_target)->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_OFFHAND))
3479 ((Player*)m_target)->_ApplyWeaponDependentAuraDamageMod(pItem,EQUIPMENT_SLOT_OFFHAND,this,apply);
3481 if(Item* pItem = ((Player*)m_target)->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_RANGED))
3482 ((Player*)m_target)->_ApplyWeaponDependentAuraDamageMod(pItem,EQUIPMENT_SLOT_RANGED,this,apply);
3485 // m_modifier.m_miscvalue is bitmask of spell schools
3486 // 1 ( 0-bit ) - normal school damage (IMMUNE_SCHOOL_PHYSICAL)
3487 // 126 - full bitmask all magic damages (IMMUNE_SCHOOL_MAGIC) including wand
3488 // 127 - full bitmask any damages
3490 // mods must be applied base at equipped weapon class and subclass comparison
3491 // with spell->EquippedItemClass and EquippedItemSubClassMask and EquippedItemInventoryTypeMask
3492 // m_modifier.m_miscvalue comparison with item generated damage types
3494 if((m_modifier.m_miscvalue & IMMUNE_SCHOOL_PHYSICAL) != 0)
3496 // apply generic physical damage bonuses including wand case
3497 if (GetSpellProto()->EquippedItemClass == -1 || m_target->GetTypeId() != TYPEID_PLAYER)
3499 m_target->HandleStatModifier(UNIT_MOD_DAMAGE_MAINHAND, TOTAL_PCT, float(m_modifier.m_amount), apply);
3500 m_target->HandleStatModifier(UNIT_MOD_DAMAGE_OFFHAND, TOTAL_PCT, float(m_modifier.m_amount), apply);
3501 m_target->HandleStatModifier(UNIT_MOD_DAMAGE_RANGED, TOTAL_PCT, float(m_modifier.m_amount), apply);
3503 else
3505 // done in Player::_ApplyWeaponDependentAuraMods
3509 // Skip non magic case for speedup
3510 if((m_modifier.m_miscvalue & IMMUNE_SCHOOL_MAGIC) == 0)
3511 return;
3513 if( GetSpellProto()->EquippedItemClass != -1 || GetSpellProto()->EquippedItemInventoryTypeMask != 0 )
3515 // wand magic case (skip generic to all item spell bonuses)
3516 // done in Player::_ApplyWeaponDependentAuraMods
3518 // Skip item specific requirements for not wand magic damage
3519 return;
3522 // Magic damage percent modifiers implemented in Unit::SpellDamageBonus
3523 // Client does not update visual spell damages when percentage aura is applied
3526 void Aura::HandleModOffhandDamagePercent(bool apply, bool Real)
3528 sLog.outDebug("AURA MOD OFFHAND DAMAGE");
3530 if (!m_target )
3531 return;
3533 m_target->HandleStatModifier(UNIT_MOD_DAMAGE_OFFHAND, TOTAL_PCT, float(m_modifier.m_amount), apply);
3536 /********************************/
3537 /*** POWER COST ***/
3538 /********************************/
3540 void Aura::HandleModPowerCost(bool apply, bool Real)
3542 //UNIT_FIELD_POWER_COST_MULTIPLIER = multiplier - 1
3543 float val = m_target->GetFloatValue(UNIT_FIELD_POWER_COST_MODIFIER) + 1.0f;
3544 ApplyPercentModFloatVar(val,m_modifier.m_amount,apply);
3545 m_target->SetFloatValue(UNIT_FIELD_POWER_COST_MODIFIER,val - 1.0f);
3548 /*********************************************************/
3549 /*** OTHERS ***/
3550 /*********************************************************/
3552 void Aura::SendCoolDownEvent()
3554 Unit* caster = GetCaster();
3555 if(caster)
3557 WorldPacket data(SMSG_COOLDOWN_EVENT, (4+8+4)); // last check 2.0.10
3558 data << uint32(m_spellId) << m_caster_guid;
3559 //data << uint32(0); // removed
3560 caster->SendMessageToSet(&data,true); // WTF? why we send cooldown message to set?
3564 void Aura::HandleShapeshiftBoosts(bool apply)
3566 if(!m_target)
3567 return;
3569 uint32 spellId = 0;
3570 uint32 spellId2 = 0;
3571 uint32 HotWSpellId = 0;
3573 switch(GetModifier()->m_miscvalue)
3575 case FORM_CAT:
3576 spellId = 3025;
3577 HotWSpellId = 24900;
3578 break;
3579 case FORM_TREE:
3580 spellId = 5420;
3581 break;
3582 case FORM_TRAVEL:
3583 spellId = 5419;
3584 break;
3585 case FORM_AQUA:
3586 spellId = 5421;
3587 break;
3588 case FORM_BEAR:
3589 spellId = 1178;
3590 spellId2 = 21178;
3591 HotWSpellId = 24899;
3592 break;
3593 case FORM_DIREBEAR:
3594 spellId = 9635;
3595 HotWSpellId = 24899;
3596 break;
3597 case FORM_CREATUREBEAR:
3598 spellId = 2882;
3599 break;
3600 case FORM_BATTLESTANCE:
3601 spellId = 21156;
3602 break;
3603 case FORM_DEFENSIVESTANCE:
3604 spellId = 7376;
3605 break;
3606 case FORM_BERSERKERSTANCE:
3607 spellId = 7381;
3608 break;
3609 case FORM_MOONKIN:
3610 spellId = 24905;
3611 // aura from effect trigger spell
3612 spellId2 = 24907;
3613 break;
3614 case FORM_FLIGHT:
3615 spellId = 33948;
3616 break;
3617 case FORM_SWIFT_FLIGHT:
3618 m_target->SetSpeed(MOVE_FLY,3.8f,true);
3619 spellId = 40122;
3620 break;
3621 case FORM_GHOSTWOLF:
3622 case FORM_AMBIENT:
3623 case FORM_GHOUL:
3624 case FORM_SHADOW:
3625 case FORM_STEALTH:
3626 case FORM_CREATURECAT:
3627 case FORM_SPIRITOFREDEMPTION:
3628 spellId = 0;
3629 break;
3632 uint32 form = GetModifier()->m_miscvalue-1;
3634 if(apply)
3636 if(m_target->m_ShapeShiftForm)
3638 m_target->RemoveAurasDueToSpell(m_target->m_ShapeShiftForm);
3641 if (spellId) m_target->CastSpell(m_target, spellId, true, NULL, this );
3642 if (spellId2) m_target->CastSpell(m_target, spellId2, true, NULL, this);
3644 if(m_target->GetTypeId() == TYPEID_PLAYER)
3646 const PlayerSpellMap& sp_list = ((Player *)m_target)->GetSpellMap();
3647 for (PlayerSpellMap::const_iterator itr = sp_list.begin(); itr != sp_list.end(); ++itr)
3649 if(itr->second->state == PLAYERSPELL_REMOVED) continue;
3650 if(itr->first==spellId || itr->first==spellId2) continue;
3651 SpellEntry const *spellInfo = sSpellStore.LookupEntry(itr->first);
3652 if (!spellInfo || !IsPassiveSpell(itr->first)) continue;
3653 if (spellInfo->Stances & (1<<form))
3654 m_target->CastSpell(m_target, itr->first, true, NULL, this);
3656 //LotP
3657 if (((Player*)m_target)->HasSpell(17007))
3659 SpellEntry const *spellInfo = sSpellStore.LookupEntry(24932);
3660 if (spellInfo && spellInfo->Stances & (1<<form))
3661 m_target->CastSpell(m_target, 24932, true, NULL, this);
3663 // HotW
3664 if (HotWSpellId)
3666 int32 HotWMod = 0;
3667 Unit::AuraList const& mModTotalStatPct = m_target->GetAurasByType(SPELL_AURA_MOD_TOTAL_STAT_PERCENTAGE);
3668 for(Unit::AuraList::const_iterator i = mModTotalStatPct.begin(); i != mModTotalStatPct.end(); ++i)
3669 if ((*i)->GetSpellProto()->SpellIconID == 240 && (*i)->GetModifier()->m_miscvalue == 3)
3670 HotWMod = (*i)->GetModifier()->m_amount;
3671 if (HotWMod)
3672 m_target->CastSpell(m_target, HotWSpellId, &HotWMod, NULL, this, true);
3676 else
3678 m_target->RemoveAurasDueToSpell(spellId);
3679 m_target->RemoveAurasDueToSpell(spellId2);
3681 Unit::AuraMap& tAuras = m_target->GetAuras();
3682 for (Unit::AuraMap::iterator itr = tAuras.begin(); itr != tAuras.end();)
3684 if ((*itr).second->GetSpellProto()->Stances & uint32(1<<form))
3685 m_target->RemoveAura(itr);
3686 else
3687 ++itr;
3691 /*double healthPercentage = (double)m_target->GetHealth() / (double)m_target->GetMaxHealth();
3692 m_target->SetHealth(uint32(ceil((double)m_target->GetMaxHealth() * healthPercentage)));*/
3695 void Aura::HandleAuraEmpathy(bool apply, bool Real)
3697 if(m_target->GetTypeId() != TYPEID_UNIT)
3698 return;
3700 CreatureInfo const * ci = objmgr.GetCreatureTemplate(m_target->GetEntry());
3701 if(ci && ci->type == CREATURE_TYPE_BEAST)
3703 m_target->ApplyModUInt32Value(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_SPECIALINFO, apply);
3707 void Aura::HandleAuraUntrackable(bool apply, bool Real)
3709 // value 100% blizz like (2.0.10)
3710 m_target->ApplyModUInt32Value(UNIT_FIELD_BYTES_1, 0x4000000, apply);
3712 Packet offset 00
3713 Packet number: 1
3714 Opcode: 00A9
3715 Object count: 1
3716 Unk: 0
3717 Update block for object 1:
3718 Block offset 07
3719 Updatetype: UPDATETYPE_VALUES
3720 Object guid: 00000000004765CE
3721 === values_update_block_start ===
3722 Bit mask blocks count: 45
3723 UNIT_FIELD_POWER1 (23): 1105
3724 UNIT_FIELD_AURA1 (48): 13161
3725 UNIT_FIELD_AURAFLAGS1 (104): 9
3726 UNIT_FIELD_BYTES_1 (152): 67108864
3727 === values_update_block_end ===
3729 Packet offset 00
3730 Packet number: 1
3731 Opcode: 00A9
3732 Object count: 1
3733 Unk: 0
3734 Update block for object 1:
3735 Block offset 07
3736 Updatetype: UPDATETYPE_VALUES
3737 Object guid: 00000000004765CE
3738 === values_update_block_start ===
3739 Bit mask blocks count: 45
3740 UNIT_FIELD_AURA1 (48): 0
3741 UNIT_FIELD_AURAFLAGS1 (104): 0
3742 UNIT_FIELD_BYTES_1 (152): 0
3743 === values_update_block_end ===
3747 void Aura::HandleAuraModPacify(bool apply, bool Real)
3749 if(m_target->GetTypeId() != TYPEID_PLAYER)
3750 return;
3752 if(apply)
3753 m_target->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PACIFIED);
3754 else
3755 m_target->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PACIFIED);
3758 void Aura::HandleAuraGhost(bool apply, bool Real)
3760 if(m_target->GetTypeId() != TYPEID_PLAYER)
3761 return;
3763 if(apply)
3765 m_target->SetFlag(PLAYER_FLAGS, PLAYER_FLAGS_GHOST);
3767 else
3769 m_target->RemoveFlag(PLAYER_FLAGS, PLAYER_FLAGS_GHOST);
3773 void Aura::HandleAuraAllowFlight(bool apply, bool Real)
3775 // all applied/removed only at real aura add/remove
3776 if(!Real)
3777 return;
3779 // allow fly
3780 sLog.outDebug("%u %u %u %u %u", m_modifier.m_amount, m_modifier.m_auraname, m_modifier.m_miscvalue, m_modifier.m_miscvalue2, m_modifier.periodictime);
3782 WorldPacket data;
3783 if(apply)
3784 data.Initialize(SMSG_FLY_MODE_START, 12);
3785 else
3786 data.Initialize(SMSG_FLY_MODE_STOP, 12);
3787 data.append(m_target->GetPackGUID());
3788 data << uint32(0); // unk
3789 m_target->SendMessageToSet(&data, true);
3792 void Aura::HandleAuraModSpeedMountedFlight(bool apply, bool Real)
3794 // all applied/removed only at real aura add/remove
3795 if(!Real)
3796 return;
3798 sLog.outDebug("HandleAuraModSpeedMountedFlight: Current Speed:%f \tmodify percent:%f", m_target->GetSpeed(MOVE_FLY),(float)m_modifier.m_amount);
3799 if(m_modifier.m_amount<=1)
3800 return;
3802 float rate = (100.0f + m_modifier.m_amount)/100.0f;
3804 m_target->ApplySpeedMod(MOVE_FLY, rate, true, apply );
3806 sLog.outDebug("ChangeSpeedTo:%f", m_target->GetSpeed(MOVE_FLY));
3808 // allow fly
3809 sLog.outDebug("%u %u %u %u %u", m_modifier.m_amount, m_modifier.m_auraname, m_modifier.m_miscvalue, m_modifier.m_miscvalue2, m_modifier.periodictime);
3811 // FIXME: is later code need?
3812 WorldPacket data;
3813 if(apply)
3814 data.Initialize(SMSG_FLY_MODE_START, 12);
3815 else
3816 data.Initialize(SMSG_FLY_MODE_STOP, 12);
3817 data.append(m_target->GetPackGUID());
3818 data << uint32(0); // unk
3819 m_target->SendMessageToSet(&data, true);
3822 void Aura::HandleAuraModSpeedFlight(bool apply, bool Real)
3824 // all applied/removed only at real aura add/remove
3825 if(!Real)
3826 return;
3828 sLog.outDebug("HandleAuraModSpeedFlight: Current Speed:%f \tmodify percent:%f", m_target->GetSpeed(MOVE_FLY),(float)m_modifier.m_amount);
3829 if(m_modifier.m_amount<=1)
3830 return;
3832 float rate = (100.0f + m_modifier.m_amount)/100.0f;
3834 m_target->ApplySpeedMod(MOVE_FLY, rate, true, apply );
3836 sLog.outDebug("ChangeSpeedTo:%f", m_target->GetSpeed(MOVE_FLY));
3839 void Aura::HandleModRating(bool apply, bool Real)
3841 if(m_target->GetTypeId() == TYPEID_PLAYER)
3843 if (m_modifier.m_miscvalue & SPELL_RATING_SKILL)
3845 /*Item* pItem = ((Player*)m_target)->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_MAINHAND);
3846 if (pItem && pItem->IsFitToSpellRequirements(GetSpellProto()))
3847 ((Player*)m_target)->ApplyRatingMod(PLAYER_FIELD_MELEE_WEAPON_SKILL_RATING,m_modifier.m_amount,apply);
3849 pItem = ((Player*)m_target)->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_OFFHAND);
3850 if (pItem && pItem->IsFitToSpellRequirements(GetSpellProto()))
3851 ((Player*)m_target)->ApplyRatingMod(PLAYER_FIELD_OFFHAND_WEAPON_SKILL_RATING,m_modifier.m_amount,apply);
3853 pItem = ((Player*)m_target)->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_RANGED);
3854 if (pItem && pItem->IsFitToSpellRequirements(GetSpellProto()))
3855 ((Player*)m_target)->ApplyRatingMod(PLAYER_FIELD_RANGED_WEAPON_SKILL_RATING,m_modifier.m_amount,apply);*/
3858 if (m_modifier.m_miscvalue & SPELL_RATING_DEFENCE)
3859 ((Player*)m_target)->ApplyRatingMod(PLAYER_FIELD_DEFENCE_RATING,m_modifier.m_amount,apply);
3861 if (m_modifier.m_miscvalue & SPELL_RATING_DODGE)
3862 ((Player*)m_target)->ApplyRatingMod(PLAYER_FIELD_DODGE_RATING,m_modifier.m_amount,apply);
3864 if (m_modifier.m_miscvalue & SPELL_RATING_PARRY)
3865 ((Player*)m_target)->ApplyRatingMod(PLAYER_FIELD_PARRY_RATING,m_modifier.m_amount,apply);
3867 if (m_modifier.m_miscvalue & SPELL_RATING_BLOCK)
3868 ((Player*)m_target)->ApplyRatingMod(PLAYER_FIELD_BLOCK_RATING,m_modifier.m_amount,apply);
3870 if (m_modifier.m_miscvalue & SPELL_RATING_MELEE_HIT)
3871 ((Player*)m_target)->ApplyRatingMod(PLAYER_FIELD_MELEE_HIT_RATING,m_modifier.m_amount,apply);
3873 if (m_modifier.m_miscvalue & SPELL_RATING_RANGED_HIT)
3874 ((Player*)m_target)->ApplyRatingMod(PLAYER_FIELD_RANGED_HIT_RATING,m_modifier.m_amount,apply);
3876 if (m_modifier.m_miscvalue & SPELL_RATING_SPELL_HIT)
3877 ((Player*)m_target)->ApplyRatingMod(PLAYER_FIELD_SPELL_HIT_RATING,m_modifier.m_amount,apply);
3879 if (m_modifier.m_miscvalue & SPELL_RATING_MELEE_CRIT_HIT)
3880 ((Player*)m_target)->ApplyRatingMod(PLAYER_FIELD_MELEE_CRIT_RATING,m_modifier.m_amount,apply);
3882 if (m_modifier.m_miscvalue & SPELL_RATING_RANGED_CRIT_HIT)
3883 ((Player*)m_target)->ApplyRatingMod(PLAYER_FIELD_RANGED_CRIT_RATING,m_modifier.m_amount,apply);
3885 if (m_modifier.m_miscvalue & SPELL_RATING_SPELL_CRIT_HIT)
3886 ((Player*)m_target)->ApplyRatingMod(PLAYER_FIELD_SPELL_CRIT_RATING,m_modifier.m_amount,apply);
3888 if (m_modifier.m_miscvalue & SPELL_RATING_MELEE_HASTE)
3889 ((Player*)m_target)->ApplyRatingMod(PLAYER_FIELD_MELEE_HASTE_RATING,m_modifier.m_amount,apply);
3891 if (m_modifier.m_miscvalue & SPELL_RATING_RANGED_HASTE)
3892 ((Player*)m_target)->ApplyRatingMod(PLAYER_FIELD_RANGED_HASTE_RATING,m_modifier.m_amount,apply);
3894 if (m_modifier.m_miscvalue & SPELL_RATING_SPELL_HASTE)
3895 ((Player*)m_target)->ApplyRatingMod(PLAYER_FIELD_SPELL_HASTE_RATING,m_modifier.m_amount,apply);
3897 if (m_modifier.m_miscvalue & SPELL_RATING_HIT)
3898 ((Player*)m_target)->ApplyRatingMod(PLAYER_FIELD_HIT_RATING,m_modifier.m_amount,apply);
3900 if (m_modifier.m_miscvalue & SPELL_RATING_CRIT_HIT)
3901 ((Player*)m_target)->ApplyRatingMod(PLAYER_FIELD_CRIT_RATING,m_modifier.m_amount,apply);
3903 /*if (m_modifier.m_miscvalue & SPELL_RATING_HIT_AVOIDANCE)
3904 ((Player*)m_target)->ApplyRatingMod(PLAYER_FIELD_HIT_AVOIDANCE_RATING,m_modifier.m_amount,apply);
3906 if (m_modifier.m_miscvalue & SPELL_RATING_CRIT_AVOIDANCE)
3907 ((Player*)m_target)->ApplyRatingMod(PLAYER_FIELD_CRIT_AVOIDANCE_RATING,m_modifier.m_amount,apply);*/
3909 if (m_modifier.m_miscvalue & SPELL_RATING_RESILIENCE)
3910 ((Player*)m_target)->ApplyRatingMod(PLAYER_FIELD_RESILIENCE_RATING,m_modifier.m_amount,apply);
3914 void Aura::HandleModTargetResistance(bool apply, bool Real)
3916 // applied to damage as HandleNoImmediateEffect in Unit::CalcAbsorbResist
3918 // show as spell penetration only full spell penetration bonuses (all resistances except armor and holy
3919 if (m_target->GetTypeId() == TYPEID_PLAYER && (m_modifier.m_miscvalue & 124)==124)
3920 m_target->ApplyModInt32Value(PLAYER_FIELD_MOD_TARGET_RESISTANCE,m_modifier.m_amount, apply);
3923 //HandleNoImmediateEffect auras implementation to support new stat system
3924 void Aura::HandleAuraHealing(bool apply, bool Real)
3926 //m_target->HandleStatModifier(UNIT_MOD_HEALING, TOTAL_VALUE, float(m_modifier.m_amount), apply);
3929 void Aura::HandleAuraHealingPct(bool apply, bool Real)
3931 //m_target->HandleStatModifier(UNIT_MOD_HEALING, TOTAL_PCT, float(m_modifier.m_amount), apply);
3934 void Aura::HandleShieldBlockValue(bool apply, bool Real)
3936 BaseModType modType = FLAT_MOD;
3937 if(m_modifier.m_auraname == SPELL_AURA_MOD_SHIELD_BLOCKVALUE_PCT)
3938 modType = PCT_MOD;
3940 if(m_target->GetTypeId() == TYPEID_PLAYER)
3941 ((Player*)m_target)->HandleBaseModValue(SHIELD_BLOCK_VALUE, modType, float(m_modifier.m_amount), apply);
3944 void Aura::HandleAuraRetainComboPoints(bool apply, bool Real)
3946 if(m_target->GetTypeId() != TYPEID_PLAYER)
3947 return;
3949 Player *target = (Player*)m_target;
3951 if(!apply) // combo points was added in SPELL_EFFECT_ADD_COMBO_POINTS handler
3952 target->AddComboPoints(target->GetSelection(), -m_modifier.m_amount);