[6982] Implemented gmlevel-based command security
[getmangos.git] / src / game / SpellAuras.cpp
blob21593a5f20f38d21a6306da5f000021c4f25370e
1 /*
2 * Copyright (C) 2005-2008 MaNGOS <http://getmangos.com/>
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 "SpellMgr.h"
29 #include "Player.h"
30 #include "Unit.h"
31 #include "Spell.h"
32 #include "SpellAuras.h"
33 #include "DynamicObject.h"
34 #include "Group.h"
35 #include "UpdateData.h"
36 #include "MapManager.h"
37 #include "ObjectAccessor.h"
38 #include "Policies/SingletonImp.h"
39 #include "Totem.h"
40 #include "Creature.h"
41 #include "Formulas.h"
42 #include "BattleGround.h"
43 #include "CreatureAI.h"
44 #include "Util.h"
45 #include "GridNotifiers.h"
46 #include "GridNotifiersImpl.h"
47 #include "CellImpl.h"
49 #define NULL_AURA_SLOT 0xFF
51 pAuraHandler AuraHandler[TOTAL_AURAS]=
53 &Aura::HandleNULL, // 0 SPELL_AURA_NONE
54 &Aura::HandleBindSight, // 1 SPELL_AURA_BIND_SIGHT
55 &Aura::HandleModPossess, // 2 SPELL_AURA_MOD_POSSESS
56 &Aura::HandlePeriodicDamage, // 3 SPELL_AURA_PERIODIC_DAMAGE
57 &Aura::HandleAuraDummy, // 4 SPELL_AURA_DUMMY
58 &Aura::HandleModConfuse, // 5 SPELL_AURA_MOD_CONFUSE
59 &Aura::HandleModCharm, // 6 SPELL_AURA_MOD_CHARM
60 &Aura::HandleModFear, // 7 SPELL_AURA_MOD_FEAR
61 &Aura::HandlePeriodicHeal, // 8 SPELL_AURA_PERIODIC_HEAL
62 &Aura::HandleModAttackSpeed, // 9 SPELL_AURA_MOD_ATTACKSPEED
63 &Aura::HandleModThreat, // 10 SPELL_AURA_MOD_THREAT
64 &Aura::HandleModTaunt, // 11 SPELL_AURA_MOD_TAUNT
65 &Aura::HandleAuraModStun, // 12 SPELL_AURA_MOD_STUN
66 &Aura::HandleModDamageDone, // 13 SPELL_AURA_MOD_DAMAGE_DONE
67 &Aura::HandleNoImmediateEffect, // 14 SPELL_AURA_MOD_DAMAGE_TAKEN implemented in Unit::MeleeDamageBonus and Unit::SpellDamageBonus
68 &Aura::HandleNoImmediateEffect, // 15 SPELL_AURA_DAMAGE_SHIELD implemented in Unit::DoAttackDamage
69 &Aura::HandleModStealth, // 16 SPELL_AURA_MOD_STEALTH
70 &Aura::HandleNoImmediateEffect, // 17 SPELL_AURA_MOD_STEALTH_DETECT
71 &Aura::HandleInvisibility, // 18 SPELL_AURA_MOD_INVISIBILITY
72 &Aura::HandleInvisibilityDetect, // 19 SPELL_AURA_MOD_INVISIBILITY_DETECTION
73 &Aura::HandleAuraModTotalHealthPercentRegen, // 20 SPELL_AURA_OBS_MOD_HEALTH
74 &Aura::HandleAuraModTotalManaPercentRegen, // 21 SPELL_AURA_OBS_MOD_MANA
75 &Aura::HandleAuraModResistance, // 22 SPELL_AURA_MOD_RESISTANCE
76 &Aura::HandlePeriodicTriggerSpell, // 23 SPELL_AURA_PERIODIC_TRIGGER_SPELL
77 &Aura::HandlePeriodicEnergize, // 24 SPELL_AURA_PERIODIC_ENERGIZE
78 &Aura::HandleAuraModPacify, // 25 SPELL_AURA_MOD_PACIFY
79 &Aura::HandleAuraModRoot, // 26 SPELL_AURA_MOD_ROOT
80 &Aura::HandleAuraModSilence, // 27 SPELL_AURA_MOD_SILENCE
81 &Aura::HandleNoImmediateEffect, // 28 SPELL_AURA_REFLECT_SPELLS implement in Unit::SpellHitResult
82 &Aura::HandleAuraModStat, // 29 SPELL_AURA_MOD_STAT
83 &Aura::HandleAuraModSkill, // 30 SPELL_AURA_MOD_SKILL
84 &Aura::HandleAuraModIncreaseSpeed, // 31 SPELL_AURA_MOD_INCREASE_SPEED
85 &Aura::HandleAuraModIncreaseMountedSpeed, // 32 SPELL_AURA_MOD_INCREASE_MOUNTED_SPEED
86 &Aura::HandleAuraModDecreaseSpeed, // 33 SPELL_AURA_MOD_DECREASE_SPEED
87 &Aura::HandleAuraModIncreaseHealth, // 34 SPELL_AURA_MOD_INCREASE_HEALTH
88 &Aura::HandleAuraModIncreaseEnergy, // 35 SPELL_AURA_MOD_INCREASE_ENERGY
89 &Aura::HandleAuraModShapeshift, // 36 SPELL_AURA_MOD_SHAPESHIFT
90 &Aura::HandleAuraModEffectImmunity, // 37 SPELL_AURA_EFFECT_IMMUNITY
91 &Aura::HandleAuraModStateImmunity, // 38 SPELL_AURA_STATE_IMMUNITY
92 &Aura::HandleAuraModSchoolImmunity, // 39 SPELL_AURA_SCHOOL_IMMUNITY
93 &Aura::HandleAuraModDmgImmunity, // 40 SPELL_AURA_DAMAGE_IMMUNITY
94 &Aura::HandleAuraModDispelImmunity, // 41 SPELL_AURA_DISPEL_IMMUNITY
95 &Aura::HandleAuraProcTriggerSpell, // 42 SPELL_AURA_PROC_TRIGGER_SPELL implemented in Unit::ProcDamageAndSpellFor and Unit::HandleProcTriggerSpell
96 &Aura::HandleNoImmediateEffect, // 43 SPELL_AURA_PROC_TRIGGER_DAMAGE implemented in Unit::ProcDamageAndSpellFor
97 &Aura::HandleAuraTrackCreatures, // 44 SPELL_AURA_TRACK_CREATURES
98 &Aura::HandleAuraTrackResources, // 45 SPELL_AURA_TRACK_RESOURCES
99 &Aura::HandleUnused, // 46 SPELL_AURA_MOD_PARRY_SKILL obsolete?
100 &Aura::HandleAuraModParryPercent, // 47 SPELL_AURA_MOD_PARRY_PERCENT
101 &Aura::HandleUnused, // 48 SPELL_AURA_MOD_DODGE_SKILL obsolete?
102 &Aura::HandleAuraModDodgePercent, // 49 SPELL_AURA_MOD_DODGE_PERCENT
103 &Aura::HandleUnused, // 50 SPELL_AURA_MOD_BLOCK_SKILL obsolete?
104 &Aura::HandleAuraModBlockPercent, // 51 SPELL_AURA_MOD_BLOCK_PERCENT
105 &Aura::HandleAuraModCritPercent, // 52 SPELL_AURA_MOD_CRIT_PERCENT
106 &Aura::HandlePeriodicLeech, // 53 SPELL_AURA_PERIODIC_LEECH
107 &Aura::HandleModHitChance, // 54 SPELL_AURA_MOD_HIT_CHANCE
108 &Aura::HandleModSpellHitChance, // 55 SPELL_AURA_MOD_SPELL_HIT_CHANCE
109 &Aura::HandleAuraTransform, // 56 SPELL_AURA_TRANSFORM
110 &Aura::HandleModSpellCritChance, // 57 SPELL_AURA_MOD_SPELL_CRIT_CHANCE
111 &Aura::HandleAuraModIncreaseSwimSpeed, // 58 SPELL_AURA_MOD_INCREASE_SWIM_SPEED
112 &Aura::HandleNoImmediateEffect, // 59 SPELL_AURA_MOD_DAMAGE_DONE_CREATURE implemented in Unit::MeleeDamageBonus and Unit::SpellDamageBonus
113 &Aura::HandleAuraModPacifyAndSilence, // 60 SPELL_AURA_MOD_PACIFY_SILENCE
114 &Aura::HandleAuraModScale, // 61 SPELL_AURA_MOD_SCALE
115 &Aura::HandleNULL, // 62 SPELL_AURA_PERIODIC_HEALTH_FUNNEL
116 &Aura::HandleUnused, // 63 SPELL_AURA_PERIODIC_MANA_FUNNEL obsolete?
117 &Aura::HandlePeriodicManaLeech, // 64 SPELL_AURA_PERIODIC_MANA_LEECH
118 &Aura::HandleModCastingSpeed, // 65 SPELL_AURA_MOD_CASTING_SPEED
119 &Aura::HandleFeignDeath, // 66 SPELL_AURA_FEIGN_DEATH
120 &Aura::HandleAuraModDisarm, // 67 SPELL_AURA_MOD_DISARM
121 &Aura::HandleAuraModStalked, // 68 SPELL_AURA_MOD_STALKED
122 &Aura::HandleSchoolAbsorb, // 69 SPELL_AURA_SCHOOL_ABSORB implemented in Unit::CalcAbsorbResist
123 &Aura::HandleUnused, // 70 SPELL_AURA_EXTRA_ATTACKS Useless, used by only one spell that has only visual effect
124 &Aura::HandleModSpellCritChanceShool, // 71 SPELL_AURA_MOD_SPELL_CRIT_CHANCE_SCHOOL
125 &Aura::HandleModPowerCostPCT, // 72 SPELL_AURA_MOD_POWER_COST_SCHOOL_PCT
126 &Aura::HandleModPowerCost, // 73 SPELL_AURA_MOD_POWER_COST_SCHOOL
127 &Aura::HandleNoImmediateEffect, // 74 SPELL_AURA_REFLECT_SPELLS_SCHOOL implemented in Unit::SpellHitResult
128 &Aura::HandleNoImmediateEffect, // 75 SPELL_AURA_MOD_LANGUAGE
129 &Aura::HandleFarSight, // 76 SPELL_AURA_FAR_SIGHT
130 &Aura::HandleModMechanicImmunity, // 77 SPELL_AURA_MECHANIC_IMMUNITY
131 &Aura::HandleAuraMounted, // 78 SPELL_AURA_MOUNTED
132 &Aura::HandleModDamagePercentDone, // 79 SPELL_AURA_MOD_DAMAGE_PERCENT_DONE
133 &Aura::HandleModPercentStat, // 80 SPELL_AURA_MOD_PERCENT_STAT
134 &Aura::HandleNoImmediateEffect, // 81 SPELL_AURA_SPLIT_DAMAGE_PCT
135 &Aura::HandleWaterBreathing, // 82 SPELL_AURA_WATER_BREATHING
136 &Aura::HandleModBaseResistance, // 83 SPELL_AURA_MOD_BASE_RESISTANCE
137 &Aura::HandleModRegen, // 84 SPELL_AURA_MOD_REGEN
138 &Aura::HandleModPowerRegen, // 85 SPELL_AURA_MOD_POWER_REGEN
139 &Aura::HandleChannelDeathItem, // 86 SPELL_AURA_CHANNEL_DEATH_ITEM
140 &Aura::HandleNoImmediateEffect, // 87 SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN implemented in Unit::MeleeDamageBonus and Unit::SpellDamageBonus
141 &Aura::HandleNoImmediateEffect, // 88 SPELL_AURA_MOD_HEALTH_REGEN_PERCENT
142 &Aura::HandlePeriodicDamagePCT, // 89 SPELL_AURA_PERIODIC_DAMAGE_PERCENT
143 &Aura::HandleUnused, // 90 SPELL_AURA_MOD_RESIST_CHANCE Useless
144 &Aura::HandleNoImmediateEffect, // 91 SPELL_AURA_MOD_DETECT_RANGE implemented in Creature::GetAttackDistance
145 &Aura::HandlePreventFleeing, // 92 SPELL_AURA_PREVENTS_FLEEING
146 &Aura::HandleModUnattackable, // 93 SPELL_AURA_MOD_UNATTACKABLE
147 &Aura::HandleNoImmediateEffect, // 94 SPELL_AURA_INTERRUPT_REGEN implemented in Player::RegenerateAll
148 &Aura::HandleAuraGhost, // 95 SPELL_AURA_GHOST
149 &Aura::HandleNoImmediateEffect, // 96 SPELL_AURA_SPELL_MAGNET implemented in Spell::SelectMagnetTarget
150 &Aura::HandleManaShield, // 97 SPELL_AURA_MANA_SHIELD implemented in Unit::CalcAbsorbResist
151 &Aura::HandleAuraModSkill, // 98 SPELL_AURA_MOD_SKILL_TALENT
152 &Aura::HandleAuraModAttackPower, // 99 SPELL_AURA_MOD_ATTACK_POWER
153 &Aura::HandleUnused, //100 SPELL_AURA_AURAS_VISIBLE obsolete? all player can see all auras now
154 &Aura::HandleModResistancePercent, //101 SPELL_AURA_MOD_RESISTANCE_PCT
155 &Aura::HandleNoImmediateEffect, //102 SPELL_AURA_MOD_MELEE_ATTACK_POWER_VERSUS implemented in Unit::MeleeDamageBonus
156 &Aura::HandleAuraModTotalThreat, //103 SPELL_AURA_MOD_TOTAL_THREAT
157 &Aura::HandleAuraWaterWalk, //104 SPELL_AURA_WATER_WALK
158 &Aura::HandleAuraFeatherFall, //105 SPELL_AURA_FEATHER_FALL
159 &Aura::HandleAuraHover, //106 SPELL_AURA_HOVER
160 &Aura::HandleAddModifier, //107 SPELL_AURA_ADD_FLAT_MODIFIER
161 &Aura::HandleAddModifier, //108 SPELL_AURA_ADD_PCT_MODIFIER
162 &Aura::HandleAddTargetTrigger, //109 SPELL_AURA_ADD_TARGET_TRIGGER
163 &Aura::HandleModPowerRegenPCT, //110 SPELL_AURA_MOD_POWER_REGEN_PERCENT
164 &Aura::HandleNULL, //111 SPELL_AURA_ADD_CASTER_HIT_TRIGGER
165 &Aura::HandleNoImmediateEffect, //112 SPELL_AURA_OVERRIDE_CLASS_SCRIPTS
166 &Aura::HandleNoImmediateEffect, //113 SPELL_AURA_MOD_RANGED_DAMAGE_TAKEN implemented in Unit::MeleeDamageBonus
167 &Aura::HandleNoImmediateEffect, //114 SPELL_AURA_MOD_RANGED_DAMAGE_TAKEN_PCT implemented in Unit::MeleeDamageBonus
168 &Aura::HandleNoImmediateEffect, //115 SPELL_AURA_MOD_HEALING implemented in Unit::SpellBaseHealingBonusForVictim
169 &Aura::HandleNoImmediateEffect, //116 SPELL_AURA_MOD_REGEN_DURING_COMBAT
170 &Aura::HandleNoImmediateEffect, //117 SPELL_AURA_MOD_MECHANIC_RESISTANCE implemented in Unit::MagicSpellHitResult
171 &Aura::HandleNoImmediateEffect, //118 SPELL_AURA_MOD_HEALING_PCT implemented in Unit::SpellHealingBonus
172 &Aura::HandleUnused, //119 SPELL_AURA_SHARE_PET_TRACKING useless
173 &Aura::HandleAuraUntrackable, //120 SPELL_AURA_UNTRACKABLE
174 &Aura::HandleAuraEmpathy, //121 SPELL_AURA_EMPATHY
175 &Aura::HandleModOffhandDamagePercent, //122 SPELL_AURA_MOD_OFFHAND_DAMAGE_PCT
176 &Aura::HandleModTargetResistance, //123 SPELL_AURA_MOD_TARGET_RESISTANCE
177 &Aura::HandleAuraModRangedAttackPower, //124 SPELL_AURA_MOD_RANGED_ATTACK_POWER
178 &Aura::HandleNoImmediateEffect, //125 SPELL_AURA_MOD_MELEE_DAMAGE_TAKEN implemented in Unit::MeleeDamageBonus
179 &Aura::HandleNoImmediateEffect, //126 SPELL_AURA_MOD_MELEE_DAMAGE_TAKEN_PCT implemented in Unit::MeleeDamageBonus
180 &Aura::HandleNoImmediateEffect, //127 SPELL_AURA_RANGED_ATTACK_POWER_ATTACKER_BONUS implemented in Unit::MeleeDamageBonus
181 &Aura::HandleModPossessPet, //128 SPELL_AURA_MOD_POSSESS_PET
182 &Aura::HandleAuraModIncreaseSpeed, //129 SPELL_AURA_MOD_SPEED_ALWAYS
183 &Aura::HandleAuraModIncreaseMountedSpeed, //130 SPELL_AURA_MOD_MOUNTED_SPEED_ALWAYS
184 &Aura::HandleNoImmediateEffect, //131 SPELL_AURA_MOD_RANGED_ATTACK_POWER_VERSUS implemented in Unit::MeleeDamageBonus
185 &Aura::HandleAuraModIncreaseEnergyPercent, //132 SPELL_AURA_MOD_INCREASE_ENERGY_PERCENT
186 &Aura::HandleAuraModIncreaseHealthPercent, //133 SPELL_AURA_MOD_INCREASE_HEALTH_PERCENT
187 &Aura::HandleAuraModRegenInterrupt, //134 SPELL_AURA_MOD_MANA_REGEN_INTERRUPT
188 &Aura::HandleModHealingDone, //135 SPELL_AURA_MOD_HEALING_DONE
189 &Aura::HandleNoImmediateEffect, //136 SPELL_AURA_MOD_HEALING_DONE_PERCENT implemented in Unit::SpellHealingBonus
190 &Aura::HandleModTotalPercentStat, //137 SPELL_AURA_MOD_TOTAL_STAT_PERCENTAGE
191 &Aura::HandleHaste, //138 SPELL_AURA_MOD_HASTE
192 &Aura::HandleForceReaction, //139 SPELL_AURA_FORCE_REACTION
193 &Aura::HandleAuraModRangedHaste, //140 SPELL_AURA_MOD_RANGED_HASTE
194 &Aura::HandleRangedAmmoHaste, //141 SPELL_AURA_MOD_RANGED_AMMO_HASTE
195 &Aura::HandleAuraModBaseResistancePCT, //142 SPELL_AURA_MOD_BASE_RESISTANCE_PCT
196 &Aura::HandleAuraModResistanceExclusive, //143 SPELL_AURA_MOD_RESISTANCE_EXCLUSIVE
197 &Aura::HandleNoImmediateEffect, //144 SPELL_AURA_SAFE_FALL implemented in WorldSession::HandleMovementOpcodes
198 &Aura::HandleUnused, //145 SPELL_AURA_CHARISMA obsolete?
199 &Aura::HandleUnused, //146 SPELL_AURA_PERSUADED obsolete?
200 &Aura::HandleNULL, //147 SPELL_AURA_ADD_CREATURE_IMMUNITY
201 &Aura::HandleAuraRetainComboPoints, //148 SPELL_AURA_RETAIN_COMBO_POINTS
202 &Aura::HandleNoImmediateEffect, //149 SPELL_AURA_RESIST_PUSHBACK
203 &Aura::HandleShieldBlockValue, //150 SPELL_AURA_MOD_SHIELD_BLOCKVALUE_PCT
204 &Aura::HandleAuraTrackStealthed, //151 SPELL_AURA_TRACK_STEALTHED
205 &Aura::HandleNoImmediateEffect, //152 SPELL_AURA_MOD_DETECTED_RANGE implemented in Creature::GetAttackDistance
206 &Aura::HandleNoImmediateEffect, //153 SPELL_AURA_SPLIT_DAMAGE_FLAT
207 &Aura::HandleNoImmediateEffect, //154 SPELL_AURA_MOD_STEALTH_LEVEL
208 &Aura::HandleNoImmediateEffect, //155 SPELL_AURA_MOD_WATER_BREATHING
209 &Aura::HandleNoImmediateEffect, //156 SPELL_AURA_MOD_REPUTATION_GAIN
210 &Aura::HandleNULL, //157 SPELL_AURA_PET_DAMAGE_MULTI
211 &Aura::HandleShieldBlockValue, //158 SPELL_AURA_MOD_SHIELD_BLOCKVALUE
212 &Aura::HandleNoImmediateEffect, //159 SPELL_AURA_NO_PVP_CREDIT only for Honorless Target spell
213 &Aura::HandleNoImmediateEffect, //160 SPELL_AURA_MOD_AOE_AVOIDANCE implemented in Unit::MagicSpellHitResult
214 &Aura::HandleNoImmediateEffect, //161 SPELL_AURA_MOD_HEALTH_REGEN_IN_COMBAT
215 &Aura::HandleAuraPowerBurn, //162 SPELL_AURA_POWER_BURN_MANA
216 &Aura::HandleNoImmediateEffect, //163 SPELL_AURA_MOD_CRIT_DAMAGE_BONUS_MELEE
217 &Aura::HandleUnused, //164 useless, only one test spell
218 &Aura::HandleNoImmediateEffect, //165 SPELL_AURA_MELEE_ATTACK_POWER_ATTACKER_BONUS implemented in Unit::MeleeDamageBonus
219 &Aura::HandleAuraModAttackPowerPercent, //166 SPELL_AURA_MOD_ATTACK_POWER_PCT
220 &Aura::HandleAuraModRangedAttackPowerPercent, //167 SPELL_AURA_MOD_RANGED_ATTACK_POWER_PCT
221 &Aura::HandleNoImmediateEffect, //168 SPELL_AURA_MOD_DAMAGE_DONE_VERSUS implemented in Unit::SpellDamageBonus, Unit::MeleeDamageBonus
222 &Aura::HandleNoImmediateEffect, //169 SPELL_AURA_MOD_CRIT_PERCENT_VERSUS implemented in Unit::DealDamageBySchool, Unit::DoAttackDamage, Unit::SpellCriticalBonus
223 &Aura::HandleNULL, //170 SPELL_AURA_DETECT_AMORE only for Detect Amore spell
224 &Aura::HandleAuraModIncreaseSpeed, //171 SPELL_AURA_MOD_SPEED_NOT_STACK
225 &Aura::HandleAuraModIncreaseMountedSpeed, //172 SPELL_AURA_MOD_MOUNTED_SPEED_NOT_STACK
226 &Aura::HandleUnused, //173 SPELL_AURA_ALLOW_CHAMPION_SPELLS only for Proclaim Champion spell
227 &Aura::HandleModSpellDamagePercentFromStat, //174 SPELL_AURA_MOD_SPELL_DAMAGE_OF_STAT_PERCENT implemented in Unit::SpellBaseDamageBonus
228 &Aura::HandleModSpellHealingPercentFromStat, //175 SPELL_AURA_MOD_SPELL_HEALING_OF_STAT_PERCENT implemented in Unit::SpellBaseHealingBonus
229 &Aura::HandleSpiritOfRedemption, //176 SPELL_AURA_SPIRIT_OF_REDEMPTION only for Spirit of Redemption spell, die at aura end
230 &Aura::HandleNULL, //177 SPELL_AURA_AOE_CHARM
231 &Aura::HandleNoImmediateEffect, //178 SPELL_AURA_MOD_DEBUFF_RESISTANCE implemented in Unit::MagicSpellHitResult
232 &Aura::HandleNoImmediateEffect, //179 SPELL_AURA_MOD_ATTACKER_SPELL_CRIT_CHANCE implemented in Unit::SpellCriticalBonus
233 &Aura::HandleNoImmediateEffect, //180 SPELL_AURA_MOD_FLAT_SPELL_DAMAGE_VERSUS implemented in Unit::SpellDamageBonus
234 &Aura::HandleUnused, //181 SPELL_AURA_MOD_FLAT_SPELL_CRIT_DAMAGE_VERSUS unused
235 &Aura::HandleAuraModResistenceOfStatPercent, //182 SPELL_AURA_MOD_RESISTANCE_OF_STAT_PERCENT
236 &Aura::HandleNULL, //183 SPELL_AURA_MOD_CRITICAL_THREAT
237 &Aura::HandleNoImmediateEffect, //184 SPELL_AURA_MOD_ATTACKER_MELEE_HIT_CHANCE implemented in Unit::RollMeleeOutcomeAgainst
238 &Aura::HandleNoImmediateEffect, //185 SPELL_AURA_MOD_ATTACKER_RANGED_HIT_CHANCE implemented in Unit::RollMeleeOutcomeAgainst
239 &Aura::HandleNoImmediateEffect, //186 SPELL_AURA_MOD_ATTACKER_SPELL_HIT_CHANCE implemented in Unit::MagicSpellHitResult
240 &Aura::HandleNoImmediateEffect, //187 SPELL_AURA_MOD_ATTACKER_MELEE_CRIT_CHANCE implemented in Unit::GetUnitCriticalChance
241 &Aura::HandleNoImmediateEffect, //188 SPELL_AURA_MOD_ATTACKER_RANGED_CRIT_CHANCE implemented in Unit::GetUnitCriticalChance
242 &Aura::HandleModRating, //189 SPELL_AURA_MOD_RATING
243 &Aura::HandleNULL, //190 SPELL_AURA_MOD_FACTION_REPUTATION_GAIN
244 &Aura::HandleAuraModUseNormalSpeed, //191 SPELL_AURA_USE_NORMAL_MOVEMENT_SPEED
245 &Aura::HandleModMeleeRangedSpeedPct, //192 SPELL_AURA_HASTE_MELEE
246 &Aura::HandleModCombatSpeedPct, //193 SPELL_AURA_MELEE_SLOW (in fact combat (any type attack) speed pct)
247 &Aura::HandleUnused, //194 SPELL_AURA_MOD_IGNORE_ABSORB_SCHOOL
248 &Aura::HandleUnused, //195 SPELL_AURA_MOD_DEPRICATED_2 not used now (old SPELL_AURA_MOD_SPELL_HEALING_OF_INTELLECT)
249 &Aura::HandleNULL, //196 SPELL_AURA_MOD_COOLDOWN
250 &Aura::HandleNoImmediateEffect, //197 SPELL_AURA_MOD_ATTACKER_SPELL_AND_WEAPON_CRIT_CHANCE implemented in Unit::SpellCriticalBonus Unit::GetUnitCriticalChance
251 &Aura::HandleUnused, //198 SPELL_AURA_MOD_ALL_WEAPON_SKILLS
252 &Aura::HandleNoImmediateEffect, //199 SPELL_AURA_MOD_INCREASES_SPELL_PCT_TO_HIT implemented in Unit::MagicSpellHitResult
253 &Aura::HandleNoImmediateEffect, //200 SPELL_AURA_MOD_XP_PCT implemented in Player::GiveXP
254 &Aura::HandleAuraAllowFlight, //201 SPELL_AURA_FLY this aura enable flight mode...
255 &Aura::HandleNoImmediateEffect, //202 SPELL_AURA_CANNOT_BE_DODGED implemented in Unit::RollPhysicalOutcomeAgainst
256 &Aura::HandleNoImmediateEffect, //203 SPELL_AURA_MOD_ATTACKER_MELEE_CRIT_DAMAGE implemented in Unit::CalculateMeleeDamage and Unit::CalculateSpellDamage
257 &Aura::HandleNoImmediateEffect, //204 SPELL_AURA_MOD_ATTACKER_RANGED_CRIT_DAMAGE implemented in Unit::CalculateMeleeDamage and Unit::CalculateSpellDamage
258 &Aura::HandleNULL, //205 vulnerable to school dmg?
259 &Aura::HandleNULL, //206 SPELL_AURA_MOD_SPEED_MOUNTED
260 &Aura::HandleAuraModIncreaseFlightSpeed, //207 SPELL_AURA_MOD_INCREASE_FLIGHT_SPEED
261 &Aura::HandleAuraModIncreaseFlightSpeed, //208 SPELL_AURA_MOD_SPEED_FLIGHT, used only in spell: Flight Form (Passive)
262 &Aura::HandleAuraModIncreaseFlightSpeed, //209 SPELL_AURA_MOD_FLIGHT_SPEED_ALWAYS
263 &Aura::HandleNULL, //210 Commentator's Command
264 &Aura::HandleAuraModIncreaseFlightSpeed, //211 SPELL_AURA_MOD_FLIGHT_SPEED_NOT_STACK
265 &Aura::HandleAuraModRangedAttackPowerOfStatPercent, //212 SPELL_AURA_MOD_RANGED_ATTACK_POWER_OF_STAT_PERCENT
266 &Aura::HandleNoImmediateEffect, //213 SPELL_AURA_MOD_RAGE_FROM_DAMAGE_DEALT implemented in Player::RewardRage
267 &Aura::HandleNULL, //214 Tamed Pet Passive
268 &Aura::HandleArenaPreparation, //215 SPELL_AURA_ARENA_PREPARATION
269 &Aura::HandleModCastingSpeed, //216 SPELL_AURA_HASTE_SPELLS
270 &Aura::HandleUnused, //217 unused
271 &Aura::HandleAuraModRangedHaste, //218 SPELL_AURA_HASTE_RANGED
272 &Aura::HandleModManaRegen, //219 SPELL_AURA_MOD_MANA_REGEN_FROM_STAT
273 &Aura::HandleModRatingFromStat, //220 SPELL_AURA_MOD_RATING_FROM_STAT
274 &Aura::HandleNULL, //221 ignored
275 &Aura::HandleUnused, //222 unused
276 &Aura::HandleNULL, //223 Cold Stare
277 &Aura::HandleUnused, //224 unused
278 &Aura::HandleNoImmediateEffect, //225 SPELL_AURA_PRAYER_OF_MENDING
279 &Aura::HandleAuraPeriodicDummy, //226 SPELL_AURA_PERIODIC_DUMMY
280 &Aura::HandleNULL, //227 periodic trigger spell
281 &Aura::HandleNoImmediateEffect, //228 stealth detection
282 &Aura::HandleNULL, //229 SPELL_AURA_MOD_AOE_DAMAGE_AVOIDANCE
283 &Aura::HandleAuraModIncreaseMaxHealth, //230 Commanding Shout
284 &Aura::HandleNoImmediateEffect, //231 SPELL_AURA_PROC_TRIGGER_SPELL_WITH_VALUE
285 &Aura::HandleNoImmediateEffect, //232 SPELL_AURA_MECHANIC_DURATION_MOD implement in Unit::CalculateSpellDuration
286 &Aura::HandleNULL, //233 set model id to the one of the creature with id m_modifier.m_miscvalue
287 &Aura::HandleNoImmediateEffect, //234 SPELL_AURA_MECHANIC_DURATION_MOD_NOT_STACK implement in Unit::CalculateSpellDuration
288 &Aura::HandleAuraModDispelResist, //235 SPELL_AURA_MOD_DISPEL_RESIST implement in Unit::MagicSpellHitResult
289 &Aura::HandleAuraControlVehicle, //236 SPELL_AURA_CONTROL_VEHICLE
290 &Aura::HandleModSpellDamagePercentFromAttackPower, //237 SPELL_AURA_MOD_SPELL_DAMAGE_OF_ATTACK_POWER implemented in Unit::SpellBaseDamageBonus
291 &Aura::HandleModSpellHealingPercentFromAttackPower, //238 SPELL_AURA_MOD_SPELL_HEALING_OF_ATTACK_POWER implemented in Unit::SpellBaseHealingBonus
292 &Aura::HandleAuraModScale, //239 SPELL_AURA_MOD_SCALE_2 only in Noggenfogger Elixir (16595) before 2.3.0 aura 61
293 &Aura::HandleAuraModExpertise, //240 SPELL_AURA_MOD_EXPERTISE
294 &Aura::HandleForceMoveForward, //241 Forces the player to move forward
295 &Aura::HandleUnused, //242 SPELL_AURA_MOD_SPELL_DAMAGE_FROM_HEALING
296 &Aura::HandleUnused, //243 used by two test spells
297 &Aura::HandleComprehendLanguage, //244 Comprehend language
298 &Aura::HandleUnused, //245 SPELL_AURA_MOD_DURATION_OF_MAGIC_EFFECTS
299 &Aura::HandleNoImmediateEffect, //246 SPELL_AURA_MOD_DURATION_OF_EFFECTS_BY_DISPEL
300 &Aura::HandleUnused, //247 unused
301 &Aura::HandleNoImmediateEffect, //248 SPELL_AURA_MOD_COMBAT_RESULT_CHANCE implemented in Unit::RollMeleeOutcomeAgainst
302 &Aura::HandleAuraConvertRune, //249 SPELL_AURA_CONVERT_RUNE
303 &Aura::HandleAuraModIncreaseHealth, //250 SPELL_AURA_MOD_INCREASE_HEALTH_2
304 &Aura::HandleNULL, //251 SPELL_AURA_MOD_ENEMY_DODGE
305 &Aura::HandleNULL, //252 haste all?
306 &Aura::HandleNULL, //253 SPELL_AURA_MOD_BLOCK_CRIT_CHANCE
307 &Aura::HandleNULL, //254 SPELL_AURA_MOD_DISARM_SHIELD disarm Shield
308 &Aura::HandleNULL, //255 SPELL_AURA_MOD_MECHANIC_DAMAGE_TAKEN_PERCENT
309 &Aura::HandleNoReagentUseAura, //256 SPELL_AURA_NO_REAGENT_USE Use SpellClassMask for spell select
310 &Aura::HandleNULL, //257 SPELL_AURA_MOD_TARGET_RESIST_BY_SPELL_CLASS Use SpellClassMask for spell select
311 &Aura::HandleNULL, //258 SPELL_AURA_MOD_SPELL_VISUAL
312 &Aura::HandleNULL, //259 corrupt healing over time spell
313 &Aura::HandleNULL, //260
314 &Aura::HandleNULL, //261 out of phase?
315 &Aura::HandleNULL, //262
316 &Aura::HandleNULL, //263 SPELL_AURA_ALLOW_ONLY_ABILITY player can use only abilites set in SpellClassMask
317 &Aura::HandleNULL, //264 unused
318 &Aura::HandleNULL, //265 unused
319 &Aura::HandleNULL, //266 unused
320 &Aura::HandleNULL, //267 some immunity?
321 &Aura::HandleAuraModAttackPowerOfStatPercent, //268 SPELL_AURA_MOD_ATTACK_POWER_OF_STAT_PERCENT
322 &Aura::HandleNULL, //269 ignore DR effects?
323 &Aura::HandleNULL, //270
324 &Aura::HandleNULL, //271 increase damage done?
325 &Aura::HandleNULL, //272 reduce spell cast time?
326 &Aura::HandleNULL, //273
327 &Aura::HandleNULL, //274 proc free shot?
328 &Aura::HandleNoImmediateEffect, //275 SPELL_AURA_MOD_IGNORE_SHAPESHIFT Use SpellClassMask for spell select
329 &Aura::HandleNULL, //276 mod damage % mechanic?
330 &Aura::HandleNoImmediateEffect, //277 SPELL_AURA_MOD_MAX_AFFECTED_TARGETS Use SpellClassMask for spell select
331 &Aura::HandleNULL, //278 SPELL_AURA_MOD_DISARM_RANGED disarm ranged weapon
332 &Aura::HandleNULL, //279
333 &Aura::HandleNULL, //280 SPELL_AURA_MOD_TARGET_ARMOR_PCT
334 &Aura::HandleNULL, //281 SPELL_AURA_MOD_HONOR_GAIN
335 &Aura::HandleAuraIncreaseBaseHealthPercent, //282 SPELL_AURA_INCREASE_BASE_HEALTH_PERCENT
336 &Aura::HandleNULL //283 SPD/heal from AP?
339 Aura::Aura(SpellEntry const* spellproto, uint32 eff, int32 *currentBasePoints, Unit *target, Unit *caster, Item* castItem) :
340 m_procCharges(0), m_spellmod(NULL), m_effIndex(eff), m_caster_guid(0), m_target(target),
341 m_timeCla(1000), m_castItemGuid(castItem?castItem->GetGUID():0), m_auraSlot(MAX_AURAS),
342 m_positive(false), m_permanent(false), m_isPeriodic(false), m_isTrigger(false), m_isAreaAura(false),
343 m_isPersistent(false), m_updated(false), m_removeMode(AURA_REMOVE_BY_DEFAULT), m_isRemovedOnShapeLost(true), m_in_use(false),
344 m_periodicTimer(0), m_PeriodicEventId(0), m_AuraDRGroup(DIMINISHING_NONE)
346 assert(target);
348 assert(spellproto && spellproto == sSpellStore.LookupEntry( spellproto->Id ) && "`info` must be pointer to sSpellStore element");
350 m_spellProto = spellproto;
352 m_currentBasePoints = currentBasePoints ? *currentBasePoints : m_spellProto->EffectBasePoints[eff];
354 m_isPassive = IsPassiveSpell(GetId());
355 m_positive = IsPositiveEffect(GetId(), m_effIndex);
357 m_applyTime = time(NULL);
359 int32 damage;
360 if(!caster)
362 m_caster_guid = target->GetGUID();
363 damage = m_currentBasePoints+1; // stored value-1
364 m_maxduration = target->CalculateSpellDuration(m_spellProto, m_effIndex, target);
366 else
368 m_caster_guid = caster->GetGUID();
370 damage = caster->CalculateSpellDamage(m_spellProto,m_effIndex,m_currentBasePoints,target);
371 m_maxduration = caster->CalculateSpellDuration(m_spellProto, m_effIndex, target);
373 if (!damage && castItem && castItem->GetItemSuffixFactor())
375 ItemRandomSuffixEntry const *item_rand_suffix = sItemRandomSuffixStore.LookupEntry(abs(castItem->GetItemRandomPropertyId()));
376 if(item_rand_suffix)
378 for (int k=0; k<3; k++)
380 SpellItemEnchantmentEntry const *pEnchant = sSpellItemEnchantmentStore.LookupEntry(item_rand_suffix->enchant_id[k]);
381 if(pEnchant)
383 for (int t=0; t<3; t++)
384 if(pEnchant->spellid[t] == m_spellProto->Id)
386 damage = uint32((item_rand_suffix->prefix[k]*castItem->GetItemSuffixFactor()) / 10000 );
387 break;
391 if(damage)
392 break;
398 if(m_maxduration == -1 || m_isPassive && m_spellProto->DurationIndex == 0)
399 m_permanent = true;
401 Player* modOwner = caster ? caster->GetSpellModOwner() : NULL;
403 if(!m_permanent && modOwner)
404 modOwner->ApplySpellMod(GetId(), SPELLMOD_DURATION, m_maxduration);
406 m_duration = m_maxduration;
408 if(modOwner)
409 modOwner->ApplySpellMod(GetId(), SPELLMOD_ACTIVATION_TIME, m_periodicTimer);
411 sLog.outDebug("Aura: construct Spellid : %u, Aura : %u Duration : %d Target : %d Damage : %d", m_spellProto->Id, m_spellProto->EffectApplyAuraName[eff], m_maxduration, m_spellProto->EffectImplicitTargetA[eff],damage);
413 m_effIndex = eff;
414 SetModifier(AuraType(m_spellProto->EffectApplyAuraName[eff]), damage, m_spellProto->EffectAmplitude[eff], m_spellProto->EffectMiscValue[eff]);
416 m_isDeathPersist = IsDeathPersistentSpell(m_spellProto);
418 if(m_spellProto->procCharges)
420 m_procCharges = m_spellProto->procCharges;
422 if(modOwner)
423 modOwner->ApplySpellMod(GetId(), SPELLMOD_CHARGES, m_procCharges);
425 else
426 m_procCharges = -1;
428 m_isRemovedOnShapeLost = (m_caster_guid==m_target->GetGUID() && m_spellProto->Stances &&
429 !(m_spellProto->AttributesEx2 & 0x80000) && !(m_spellProto->Attributes & 0x10000));
432 Aura::~Aura()
436 AreaAura::AreaAura(SpellEntry const* spellproto, uint32 eff, int32 *currentBasePoints, Unit *target,
437 Unit *caster, Item* castItem) : Aura(spellproto, eff, currentBasePoints, target, caster, castItem)
439 m_isAreaAura = true;
441 // caster==NULL in constructor args if target==caster in fact
442 Unit* caster_ptr = caster ? caster : target;
444 m_radius = GetSpellRadius(sSpellRadiusStore.LookupEntry(GetSpellProto()->EffectRadiusIndex[m_effIndex]));
445 if(Player* modOwner = caster_ptr->GetSpellModOwner())
446 modOwner->ApplySpellMod(GetId(), SPELLMOD_RADIUS, m_radius);
448 switch(spellproto->Effect[eff])
450 case SPELL_EFFECT_APPLY_AREA_AURA_PARTY:
451 m_areaAuraType = AREA_AURA_PARTY;
452 if(target->GetTypeId() == TYPEID_UNIT && ((Creature*)target)->isTotem())
453 m_modifier.m_auraname = SPELL_AURA_NONE;
454 break;
455 case SPELL_EFFECT_APPLY_AREA_AURA_RAID:
456 m_areaAuraType = AREA_AURA_RAID;
457 if(target->GetTypeId() == TYPEID_UNIT && ((Creature*)target)->isTotem())
458 m_modifier.m_auraname = SPELL_AURA_NONE;
459 break;
460 case SPELL_EFFECT_APPLY_AREA_AURA_FRIEND:
461 m_areaAuraType = AREA_AURA_FRIEND;
462 break;
463 case SPELL_EFFECT_APPLY_AREA_AURA_ENEMY:
464 m_areaAuraType = AREA_AURA_ENEMY;
465 if(target == caster_ptr)
466 m_modifier.m_auraname = SPELL_AURA_NONE; // Do not do any effect on self
467 break;
468 case SPELL_EFFECT_APPLY_AREA_AURA_PET:
469 m_areaAuraType = AREA_AURA_PET;
470 break;
471 case SPELL_EFFECT_APPLY_AREA_AURA_OWNER:
472 m_areaAuraType = AREA_AURA_OWNER;
473 if(target == caster_ptr)
474 m_modifier.m_auraname = SPELL_AURA_NONE;
475 break;
476 default:
477 sLog.outError("Wrong spell effect in AreaAura constructor");
478 ASSERT(false);
479 break;
483 AreaAura::~AreaAura()
487 PersistentAreaAura::PersistentAreaAura(SpellEntry const* spellproto, uint32 eff, int32 *currentBasePoints, Unit *target,
488 Unit *caster, Item* castItem) : Aura(spellproto, eff, currentBasePoints, target, caster, castItem)
490 m_isPersistent = true;
493 PersistentAreaAura::~PersistentAreaAura()
497 SingleEnemyTargetAura::SingleEnemyTargetAura(SpellEntry const* spellproto, uint32 eff, int32 *currentBasePoints, Unit *target,
498 Unit *caster, Item* castItem) : Aura(spellproto, eff, currentBasePoints, target, caster, castItem)
500 if (caster)
501 m_casters_target_guid = caster->GetTypeId()==TYPEID_PLAYER ? ((Player*)caster)->GetSelection() : caster->GetUInt64Value(UNIT_FIELD_TARGET);
502 else
503 m_casters_target_guid = 0;
506 SingleEnemyTargetAura::~SingleEnemyTargetAura()
510 Unit* SingleEnemyTargetAura::GetTriggerTarget() const
512 return ObjectAccessor::GetUnit(*m_target, m_casters_target_guid);
515 Aura* CreateAura(SpellEntry const* spellproto, uint32 eff, int32 *currentBasePoints, Unit *target, Unit *caster, Item* castItem)
517 if (IsAreaAuraEffect(spellproto->Effect[eff]))
518 return new AreaAura(spellproto, eff, currentBasePoints, target, caster, castItem);
520 uint32 triggeredSpellId = spellproto->EffectTriggerSpell[eff];
522 if(SpellEntry const* triggeredSpellInfo = sSpellStore.LookupEntry(triggeredSpellId))
523 for (int i = 0; i < 3; ++i)
524 if (triggeredSpellInfo->EffectImplicitTargetA[i] == TARGET_SINGLE_ENEMY)
525 return new SingleEnemyTargetAura(spellproto, eff, currentBasePoints, target, caster, castItem);
527 return new Aura(spellproto, eff, currentBasePoints, target, caster, castItem);
530 Unit* Aura::GetCaster() const
532 if(m_caster_guid==m_target->GetGUID())
533 return m_target;
535 //return ObjectAccessor::GetUnit(*m_target,m_caster_guid);
536 //must return caster even if it's in another grid/map
537 Unit *unit = ObjectAccessor::GetObjectInWorld(m_caster_guid, (Unit*)NULL);
538 return unit && unit->IsInWorld() ? unit : NULL;
541 void Aura::SetModifier(AuraType t, int32 a, uint32 pt, int32 miscValue)
543 m_modifier.m_auraname = t;
544 m_modifier.m_amount = a;
545 m_modifier.m_miscvalue = miscValue;
546 m_modifier.periodictime = pt;
549 void Aura::Update(uint32 diff)
551 if (m_duration > 0)
553 m_duration -= diff;
554 if (m_duration < 0)
555 m_duration = 0;
556 m_timeCla -= diff;
558 // GetEffIndex()==0 prevent double/triple apply manaPerSecond/manaPerSecondPerLevel to same spell with many auras
559 // all spells with manaPerSecond/manaPerSecondPerLevel have aura in effect 0
560 if(GetEffIndex()==0 && m_timeCla <= 0)
562 if(Unit* caster = GetCaster())
564 Powers powertype = Powers(m_spellProto->powerType);
565 int32 manaPerSecond = m_spellProto->manaPerSecond + m_spellProto->manaPerSecondPerLevel * caster->getLevel();
566 m_timeCla = 1000;
567 if (manaPerSecond)
569 if(powertype==POWER_HEALTH)
570 caster->ModifyHealth(-manaPerSecond);
571 else
572 caster->ModifyPower(powertype,-manaPerSecond);
578 // Channeled aura required check distance from caster
579 if(IsChanneledSpell(m_spellProto) && m_caster_guid != m_target->GetGUID())
581 Unit* caster = GetCaster();
582 if(!caster)
584 m_target->RemoveAura(GetId(),GetEffIndex());
585 return;
588 // Get spell range
589 float radius;
590 SpellModOp mod;
591 if (m_spellProto->EffectRadiusIndex[GetEffIndex()])
593 radius = GetSpellRadius(sSpellRadiusStore.LookupEntry(m_spellProto->EffectRadiusIndex[GetEffIndex()]));
594 mod = SPELLMOD_RADIUS;
596 else
598 radius = GetSpellMaxRange(sSpellRangeStore.LookupEntry(m_spellProto->rangeIndex));
599 mod = SPELLMOD_RANGE;
602 if(Player* modOwner = caster->GetSpellModOwner())
603 modOwner->ApplySpellMod(GetId(), mod, radius,NULL);
605 if(!caster->IsWithinDistInMap(m_target,radius))
607 m_target->RemoveAura(GetId(),GetEffIndex());
608 return;
612 if(m_isPeriodic && (m_duration >= 0 || m_isPassive || m_permanent))
614 m_periodicTimer -= diff;
615 if(m_periodicTimer <= 0) // tick also at m_periodicTimer==0 to prevent lost last tick in case max m_duration == (max m_periodicTimer)*N
617 if( m_modifier.m_auraname == SPELL_AURA_MOD_REGEN ||
618 m_modifier.m_auraname == SPELL_AURA_MOD_POWER_REGEN ||
619 // Cannibalize, eating items and other spells
620 m_modifier.m_auraname == SPELL_AURA_OBS_MOD_HEALTH ||
621 // Eating items and other spells
622 m_modifier.m_auraname == SPELL_AURA_OBS_MOD_MANA )
624 ApplyModifier(true);
625 return;
627 // update before applying (aura can be removed in TriggerSpell or PeriodicTick calls)
628 m_periodicTimer += m_modifier.periodictime;
630 if(m_isTrigger)
631 TriggerSpell();
632 else
633 PeriodicTick();
638 void AreaAura::Update(uint32 diff)
640 // update for the caster of the aura
641 if(m_caster_guid == m_target->GetGUID())
643 Unit* caster = m_target;
645 if( !caster->hasUnitState(UNIT_STAT_ISOLATED) )
647 Unit* owner = caster->GetCharmerOrOwner();
648 if (!owner)
649 owner = caster;
650 std::list<Unit *> targets;
652 switch(m_areaAuraType)
654 case AREA_AURA_PARTY:
656 Group *pGroup = NULL;
658 if (owner->GetTypeId() == TYPEID_PLAYER)
659 pGroup = ((Player*)owner)->GetGroup();
661 if( pGroup)
663 uint8 subgroup = ((Player*)owner)->GetSubGroup();
664 for(GroupReference *itr = pGroup->GetFirstMember(); itr != NULL; itr = itr->next())
666 Player* Target = itr->getSource();
667 if(Target && Target->isAlive() && Target->GetSubGroup()==subgroup && caster->IsFriendlyTo(Target))
669 if(caster->IsWithinDistInMap(Target, m_radius))
670 targets.push_back(Target);
671 Pet *pet = Target->GetPet();
672 if(pet && pet->isAlive() && caster->IsWithinDistInMap(pet, m_radius))
673 targets.push_back(pet);
677 else
679 // add owner
680 if( owner != caster && caster->IsWithinDistInMap(owner, m_radius) )
681 targets.push_back(owner);
682 // add caster's pet
683 Unit* pet = caster->GetPet();
684 if( pet && caster->IsWithinDistInMap(pet, m_radius))
685 targets.push_back(pet);
687 break;
689 case AREA_AURA_RAID:
691 Group *pGroup = NULL;
693 if (owner->GetTypeId() == TYPEID_PLAYER)
694 pGroup = ((Player*)owner)->GetGroup();
696 if( pGroup)
698 uint8 subgroup = ((Player*)owner)->GetSubGroup();
699 for(GroupReference *itr = pGroup->GetFirstMember(); itr != NULL; itr = itr->next())
701 Player* Target = itr->getSource();
702 if(Target && Target->isAlive() && caster->IsFriendlyTo(Target))
704 if(caster->IsWithinDistInMap(Target, m_radius))
705 targets.push_back(Target);
706 Pet *pet = Target->GetPet();
707 if(pet && pet->isAlive() && caster->IsWithinDistInMap(pet, m_radius))
708 targets.push_back(pet);
712 else
714 // add owner
715 if( owner != caster && caster->IsWithinDistInMap(owner, m_radius) )
716 targets.push_back(owner);
717 // add caster's pet
718 Unit* pet = caster->GetPet();
719 if( pet && caster->IsWithinDistInMap(pet, m_radius))
720 targets.push_back(pet);
722 break;
724 case AREA_AURA_FRIEND:
726 CellPair p(MaNGOS::ComputeCellPair(caster->GetPositionX(), caster->GetPositionY()));
727 Cell cell(p);
728 cell.data.Part.reserved = ALL_DISTRICT;
729 cell.SetNoCreate();
731 MaNGOS::AnyFriendlyUnitInObjectRangeCheck u_check(caster, owner, m_radius);
732 MaNGOS::UnitListSearcher<MaNGOS::AnyFriendlyUnitInObjectRangeCheck> searcher(targets, u_check);
733 TypeContainerVisitor<MaNGOS::UnitListSearcher<MaNGOS::AnyFriendlyUnitInObjectRangeCheck>, WorldTypeMapContainer > world_unit_searcher(searcher);
734 TypeContainerVisitor<MaNGOS::UnitListSearcher<MaNGOS::AnyFriendlyUnitInObjectRangeCheck>, GridTypeMapContainer > grid_unit_searcher(searcher);
735 CellLock<GridReadGuard> cell_lock(cell, p);
736 cell_lock->Visit(cell_lock, world_unit_searcher, *caster->GetMap());
737 cell_lock->Visit(cell_lock, grid_unit_searcher, *caster->GetMap());
738 break;
740 case AREA_AURA_ENEMY:
742 CellPair p(MaNGOS::ComputeCellPair(caster->GetPositionX(), caster->GetPositionY()));
743 Cell cell(p);
744 cell.data.Part.reserved = ALL_DISTRICT;
745 cell.SetNoCreate();
747 MaNGOS::AnyAoETargetUnitInObjectRangeCheck u_check(caster, owner, m_radius); // No GetCharmer in searcher
748 MaNGOS::UnitListSearcher<MaNGOS::AnyAoETargetUnitInObjectRangeCheck> searcher(targets, u_check);
749 TypeContainerVisitor<MaNGOS::UnitListSearcher<MaNGOS::AnyAoETargetUnitInObjectRangeCheck>, WorldTypeMapContainer > world_unit_searcher(searcher);
750 TypeContainerVisitor<MaNGOS::UnitListSearcher<MaNGOS::AnyAoETargetUnitInObjectRangeCheck>, GridTypeMapContainer > grid_unit_searcher(searcher);
751 CellLock<GridReadGuard> cell_lock(cell, p);
752 cell_lock->Visit(cell_lock, world_unit_searcher, *caster->GetMap());
753 cell_lock->Visit(cell_lock, grid_unit_searcher, *caster->GetMap());
754 break;
756 case AREA_AURA_OWNER:
757 case AREA_AURA_PET:
759 if(owner != caster)
760 targets.push_back(owner);
761 break;
765 for(std::list<Unit *>::iterator tIter = targets.begin(); tIter != targets.end(); tIter++)
767 if((*tIter)->HasAura(GetId(), m_effIndex))
768 continue;
770 if(SpellEntry const *actualSpellInfo = spellmgr.SelectAuraRankForPlayerLevel(GetSpellProto(), (*tIter)->getLevel()))
772 int32 actualBasePoints = m_currentBasePoints;
773 // recalculate basepoints for lower rank (all AreaAura spell not use custom basepoints?)
774 if(actualSpellInfo != GetSpellProto())
775 actualBasePoints = actualSpellInfo->EffectBasePoints[m_effIndex];
776 AreaAura *aur = new AreaAura(actualSpellInfo, m_effIndex, &actualBasePoints, (*tIter), caster, NULL);
777 (*tIter)->AddAura(aur);
781 Aura::Update(diff);
783 else // aura at non-caster
785 Unit * tmp_target = m_target;
786 Unit* caster = GetCaster();
787 uint32 tmp_spellId = GetId(), tmp_effIndex = m_effIndex;
789 // WARNING: the aura may get deleted during the update
790 // DO NOT access its members after update!
791 Aura::Update(diff);
793 // remove aura if out-of-range from caster (after teleport for example)
794 // or caster is isolated or caster no longer has the aura
795 // or caster is (no longer) friendly
796 bool needFriendly = (m_areaAuraType == AREA_AURA_ENEMY ? false : true);
797 if( !caster || caster->hasUnitState(UNIT_STAT_ISOLATED) ||
798 !caster->IsWithinDistInMap(tmp_target, m_radius) ||
799 !caster->HasAura(tmp_spellId, tmp_effIndex) ||
800 caster->IsFriendlyTo(tmp_target) != needFriendly
803 tmp_target->RemoveAura(tmp_spellId, tmp_effIndex);
805 else if( m_areaAuraType == AREA_AURA_PARTY) // check if in same sub group
807 // not check group if target == owner or target == pet
808 if (caster->GetCharmerOrOwnerGUID() != tmp_target->GetGUID() && caster->GetGUID() != tmp_target->GetCharmerOrOwnerGUID())
810 Player* check = caster->GetCharmerOrOwnerPlayerOrPlayerItself();
812 Group *pGroup = check ? check->GetGroup() : NULL;
813 if( pGroup )
815 Player* checkTarget = tmp_target->GetCharmerOrOwnerPlayerOrPlayerItself();
816 if(!checkTarget || !pGroup->SameSubGroup(check, checkTarget))
817 tmp_target->RemoveAura(tmp_spellId, tmp_effIndex);
819 else
820 tmp_target->RemoveAura(tmp_spellId, tmp_effIndex);
823 else if( m_areaAuraType == AREA_AURA_RAID) // TODO: fix me!
825 // not check group if target == owner or target == pet
826 if (caster->GetCharmerOrOwnerGUID() != tmp_target->GetGUID() && caster->GetGUID() != tmp_target->GetCharmerOrOwnerGUID())
828 Player* check = caster->GetCharmerOrOwnerPlayerOrPlayerItself();
830 Group *pGroup = check ? check->GetGroup() : NULL;
831 if( pGroup )
833 Player* checkTarget = tmp_target->GetCharmerOrOwnerPlayerOrPlayerItself();
834 if(!checkTarget)
835 tmp_target->RemoveAura(tmp_spellId, tmp_effIndex);
837 else
838 tmp_target->RemoveAura(tmp_spellId, tmp_effIndex);
841 else if( m_areaAuraType == AREA_AURA_PET || m_areaAuraType == AREA_AURA_OWNER )
843 if( tmp_target->GetGUID() != caster->GetCharmerOrOwnerGUID() )
844 tmp_target->RemoveAura(tmp_spellId, tmp_effIndex);
849 void PersistentAreaAura::Update(uint32 diff)
851 bool remove = false;
853 // remove the aura if its caster or the dynamic object causing it was removed
854 // or if the target moves too far from the dynamic object
855 Unit *caster = GetCaster();
856 if (caster)
858 DynamicObject *dynObj = caster->GetDynObject(GetId(), GetEffIndex());
859 if (dynObj)
861 if (!m_target->IsWithinDistInMap(dynObj, dynObj->GetRadius()))
862 remove = true;
864 else
865 remove = true;
867 else
868 remove = true;
870 Unit *tmp_target = m_target;
871 uint32 tmp_id = GetId(), tmp_index = GetEffIndex();
873 // WARNING: the aura may get deleted during the update
874 // DO NOT access its members after update!
875 Aura::Update(diff);
877 if(remove)
878 tmp_target->RemoveAura(tmp_id, tmp_index);
881 void Aura::ApplyModifier(bool apply, bool Real)
883 AuraType aura = m_modifier.m_auraname;
885 m_in_use = true;
886 if(aura<TOTAL_AURAS)
887 (*this.*AuraHandler [aura])(apply,Real);
888 m_in_use = false;
891 void Aura::_AddAura()
893 if (!GetId())
894 return;
895 if(!m_target)
896 return;
898 // we can found aura in NULL_AURA_SLOT and then need store state instead check slot != NULL_AURA_SLOT
899 bool samespell = false;
900 bool secondaura = false;
901 uint8 slot = NULL_AURA_SLOT;
903 for(uint8 i = 0; i < 3; i++)
905 Unit::spellEffectPair spair = Unit::spellEffectPair(GetId(), i);
906 for(Unit::AuraMap::const_iterator itr = m_target->GetAuras().lower_bound(spair); itr != m_target->GetAuras().upper_bound(spair); ++itr)
908 // allow use single slot only by auras from same caster
909 if(itr->second->GetCasterGUID()==GetCasterGUID())
911 samespell = true;
912 if (m_effIndex > itr->second->GetEffIndex())
913 secondaura = true;
914 slot = itr->second->GetAuraSlot();
915 break;
919 if(samespell)
920 break;
923 // not call total regen auras at adding
924 switch (m_modifier.m_auraname)
926 case SPELL_AURA_OBS_MOD_HEALTH:
927 case SPELL_AURA_OBS_MOD_MANA:
928 m_periodicTimer = m_modifier.periodictime;
929 break;
930 case SPELL_AURA_MOD_REGEN:
931 case SPELL_AURA_MOD_POWER_REGEN:
932 case SPELL_AURA_MOD_MANA_REGEN_FROM_STAT:
933 m_periodicTimer = 5000;
934 break;
937 // register aura
938 if (getDiminishGroup() != DIMINISHING_NONE )
939 m_target->ApplyDiminishingAura(getDiminishGroup(),true);
941 Unit* caster = GetCaster();
943 // passive auras (except totem auras) do not get placed in the slots
944 // area auras with SPELL_AURA_NONE are not shown on target
945 if((!m_isPassive || (caster && caster->GetTypeId() == TYPEID_UNIT && ((Creature*)caster)->isTotem())) &&
946 (m_spellProto->Effect[GetEffIndex()] != SPELL_EFFECT_APPLY_AREA_AURA_ENEMY || m_target != caster))
948 if(!samespell) // new slot need
950 if(m_target->GetVisibleAurasCount() < MAX_AURAS)
952 Unit::VisibleAuraMap const *visibleAuras = m_target->GetVisibleAuras();
953 for(uint8 i = 0; i < MAX_AURAS; ++i)
955 Unit::VisibleAuraMap::const_iterator itr = visibleAuras->find(i);
956 if(itr == visibleAuras->end())
958 slot = i;
959 break;
964 SetAuraSlot( slot );
966 // Not update fields for not first spell's aura, all data already in fields
967 if(!secondaura)
969 if(slot < MAX_AURAS) // slot found
971 SetAura(false);
972 SetAuraFlags((1 << GetEffIndex()) | AFLAG_NOT_CASTER | ((GetAuraMaxDuration() > 0) ? AFLAG_DURATION : AFLAG_NONE) | (IsPositive() ? AFLAG_POSITIVE : AFLAG_NEGATIVE));
973 SetAuraLevel(caster ? caster->getLevel() : sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL));
974 UpdateAuraCharges();
975 SendAuraUpdate(false);
977 // update for out of range group members
978 m_target->UpdateAuraForGroup(slot);
982 else // use found slot
984 SetAuraSlot( slot );
985 // Not recalculate stack count for second aura of the same spell
986 if (!secondaura)
987 UpdateSlotCounterAndDuration(true);
990 // Update Seals information
991 if( IsSealSpell(GetSpellProto()) )
992 m_target->ModifyAuraState(AURA_STATE_JUDGEMENT, true);
994 // Conflagrate aura state
995 if (GetSpellProto()->SpellFamilyName == SPELLFAMILY_WARLOCK && (GetSpellProto()->SpellFamilyFlags & 4))
996 m_target->ModifyAuraState(AURA_STATE_IMMOLATE, true);
998 if(GetSpellProto()->SpellFamilyName == SPELLFAMILY_DRUID
999 && (GetSpellProto()->SpellFamilyFlags == 0x40 || GetSpellProto()->SpellFamilyFlags == 0x10))
1001 m_target->ModifyAuraState(AURA_STATE_SWIFTMEND, true);
1006 void Aura::_RemoveAura()
1008 // Remove all triggered by aura spells vs unlimited duration
1009 // except same aura replace case
1010 if(m_removeMode!=AURA_REMOVE_BY_STACK)
1011 CleanupTriggeredSpells();
1013 Unit* caster = GetCaster();
1015 if(caster && IsPersistent())
1017 DynamicObject *dynObj = caster->GetDynObject(GetId(), GetEffIndex());
1018 if (dynObj)
1019 dynObj->RemoveAffected(m_target);
1022 // unregister aura
1023 if (getDiminishGroup() != DIMINISHING_NONE )
1024 m_target->ApplyDiminishingAura(getDiminishGroup(),false);
1026 //passive auras do not get put in slots
1027 // Note: but totem can be not accessible for aura target in time remove (to far for find in grid)
1028 //if(m_isPassive && !(caster && caster->GetTypeId() == TYPEID_UNIT && ((Creature*)caster)->isTotem()))
1029 // return;
1031 uint8 slot = GetAuraSlot();
1033 if(slot >= MAX_AURAS) // slot not set
1034 return;
1036 if(m_target->GetVisibleAura(slot) == 0)
1037 return;
1039 bool samespell = false;
1040 bool sameaura = false;
1042 // find other aura in same slot (current already removed from list)
1043 for(uint8 i = 0; i < 3; i++)
1045 Unit::spellEffectPair spair = Unit::spellEffectPair(GetId(), i);
1046 for(Unit::AuraMap::const_iterator itr = m_target->GetAuras().lower_bound(spair); itr != m_target->GetAuras().upper_bound(spair); ++itr)
1048 if(itr->second->GetAuraSlot()==slot)
1050 samespell = true;
1052 if(GetEffIndex()==i)
1053 sameaura = true;
1055 break;
1058 if(samespell)
1059 break;
1062 // only remove icon when the last aura of the spell is removed (current aura already removed from list)
1063 if (!samespell)
1065 SetAura(true);
1066 SetAuraFlags(AFLAG_NONE);
1067 SetAuraLevel(0);
1068 SetAuraCharges(0);
1069 SendAuraUpdate(true);
1071 // update for out of range group members
1072 m_target->UpdateAuraForGroup(slot);
1074 if( IsSealSpell(GetSpellProto()) )
1075 m_target->ModifyAuraState(AURA_STATE_JUDGEMENT,false);
1077 // Conflagrate aura state
1078 if (GetSpellProto()->SpellFamilyName == SPELLFAMILY_WARLOCK && (GetSpellProto()->SpellFamilyFlags & 4))
1079 m_target->ModifyAuraState(AURA_STATE_IMMOLATE, false);
1081 // Swiftmend aura state
1082 if(GetSpellProto()->SpellFamilyName == SPELLFAMILY_DRUID
1083 && (GetSpellProto()->SpellFamilyFlags == 0x40 || GetSpellProto()->SpellFamilyFlags == 0x10))
1085 bool found = false;
1086 Unit::AuraList const& RejorRegr = m_target->GetAurasByType(SPELL_AURA_PERIODIC_HEAL);
1087 for(Unit::AuraList::const_iterator i = RejorRegr.begin(); i != RejorRegr.end(); ++i)
1089 if((*i)->GetSpellProto()->SpellFamilyName == SPELLFAMILY_DRUID
1090 && ((*i)->GetSpellProto()->SpellFamilyFlags == 0x40 || (*i)->GetSpellProto()->SpellFamilyFlags == 0x10) )
1092 found = true;
1093 break;
1096 if(!found)
1097 m_target->ModifyAuraState(AURA_STATE_SWIFTMEND, false);
1100 // reset cooldown state for spells
1101 if(caster && caster->GetTypeId() == TYPEID_PLAYER)
1103 if ( GetSpellProto()->Attributes & SPELL_ATTR_DISABLED_WHILE_ACTIVE )
1104 ((Player*)caster)->SendCooldownEvent(GetSpellProto());
1107 else if(sameaura) // decrease count for spell, only for same aura effect, or this spell auras in remove process.
1108 UpdateSlotCounterAndDuration(false);
1111 void Aura::SendAuraUpdate(bool remove)
1113 WorldPacket data(SMSG_AURA_UPDATE);
1114 data.append(m_target->GetPackGUID());
1115 data << uint8(GetAuraSlot());
1116 data << uint32(remove ? 0 : GetId());
1118 if(remove)
1120 m_target->SendMessageToSet(&data, true);
1121 return;
1124 uint8 auraFlags = GetAuraFlags();
1125 data << uint8(auraFlags);
1126 data << uint8(GetAuraLevel());
1127 data << uint8(m_procCharges >= 0 ? m_procCharges : 0);
1129 if(!(auraFlags & AFLAG_NOT_CASTER))
1131 data << uint8(0); // pguid
1134 if(auraFlags & AFLAG_DURATION)
1136 data << uint32(GetAuraMaxDuration());
1137 data << uint32(GetAuraDuration());
1140 m_target->SendMessageToSet(&data, true);
1143 void Aura::UpdateSlotCounterAndDuration(bool add)
1145 uint8 slot = GetAuraSlot();
1146 if(slot >= MAX_AURAS)
1147 return;
1149 // calculate amount of similar auras by same effect index (similar different spells)
1150 int8 count = 0;
1152 // calculate auras and update durations in case aura adding
1153 Unit::AuraList const& aura_list = m_target->GetAurasByType(GetModifier()->m_auraname);
1154 for(Unit::AuraList::const_iterator i = aura_list.begin();i != aura_list.end(); ++i)
1156 if( (*i)->GetId()==GetId() && (*i)->GetEffIndex()==m_effIndex &&
1157 (*i)->GetCasterGUID()==GetCasterGUID() )
1159 ++count;
1161 if(add)
1162 (*i)->SetAuraDuration(GetAuraDuration());
1166 // at aura add aura not added yet, at aura remove aura already removed
1167 // in field stored (count-1)
1168 if(!add)
1169 --count;
1171 SetAuraCharges(count);
1172 SendAuraUpdate(false);
1175 bool Aura::isAffectedOnSpell(SpellEntry const *spell) const
1177 // Check family name
1178 if (spell->SpellFamilyName != m_spellProto->SpellFamilyName)
1179 return false;
1180 // Check EffectClassMask
1181 uint32 const *ptr = getAuraSpellClassMask();
1182 if (((uint64*)ptr)[0] & spell->SpellFamilyFlags)
1183 return true;
1184 if (ptr[2] & spell->SpellFamilyFlags2)
1185 return true;
1186 return false;
1189 /*********************************************************/
1190 /*** BASIC AURA FUNCTION ***/
1191 /*********************************************************/
1192 void Aura::HandleAddModifier(bool apply, bool Real)
1194 if(m_target->GetTypeId() != TYPEID_PLAYER || !Real)
1195 return;
1197 if(m_modifier.m_miscvalue >= MAX_SPELLMOD)
1198 return;
1200 if (apply)
1202 // Add custom charges for some mod aura
1203 switch (m_spellProto->Id)
1205 case 17941: // Shadow Trance
1206 case 22008: // Netherwind Focus
1207 case 31834: // Light's Grace
1208 case 34754: // Clearcasting
1209 case 34936: // Backlash
1210 case 48108: // Hot Streak
1211 m_procCharges = 1;
1212 break;
1215 SpellModifier *mod = new SpellModifier;
1216 mod->op = SpellModOp(m_modifier.m_miscvalue);
1217 mod->value = m_modifier.m_amount;
1218 mod->type = SpellModType(m_modifier.m_auraname); // SpellModType value == spell aura types
1219 mod->spellId = GetId();
1221 uint32 const *ptr;
1222 SpellAffectEntry const *spellAffect = spellmgr.GetSpellAffect(GetId(), m_effIndex);
1223 if (spellAffect)
1224 ptr = &spellAffect->SpellClassMask[0];
1225 else
1227 switch (m_effIndex)
1229 case 0: ptr = &m_spellProto->EffectSpellClassMaskA[0]; break;
1230 case 1: ptr = &m_spellProto->EffectSpellClassMaskB[0]; break;
1231 case 2: ptr = &m_spellProto->EffectSpellClassMaskC[0]; break;
1232 default:
1233 return;
1237 mod->mask = (uint64)ptr[0] | (uint64)ptr[1]<<32;
1238 mod->mask2= (uint64)ptr[2];
1240 if (m_procCharges > 0)
1241 mod->charges = m_procCharges;
1242 else
1243 mod->charges = 0;
1245 m_spellmod = mod;
1248 uint64 spellFamilyMask = m_spellmod->mask;
1250 ((Player*)m_target)->AddSpellMod(m_spellmod, apply);
1252 // reapply some passive spells after add/remove related spellmods
1253 if(m_spellProto->SpellFamilyName==SPELLFAMILY_WARRIOR && (spellFamilyMask & 0x0000100000000000LL))
1255 m_target->RemoveAurasDueToSpell(45471);
1257 if(apply)
1258 m_target->CastSpell(m_target,45471,true);
1261 void Aura::HandleAddTargetTrigger(bool apply, bool Real)
1263 // Use SpellModifier structure for check
1264 // used only fields:
1265 // spellId, mask, mask2
1266 if (apply)
1268 SpellModifier *mod = new SpellModifier;
1269 mod->spellId = GetId();
1271 uint32 const *ptr;
1272 SpellAffectEntry const *spellAffect = spellmgr.GetSpellAffect(GetId(), m_effIndex);
1273 if (spellAffect)
1274 ptr = &spellAffect->SpellClassMask[0];
1275 else
1277 switch (m_effIndex)
1279 case 0: ptr = &m_spellProto->EffectSpellClassMaskA[0]; break;
1280 case 1: ptr = &m_spellProto->EffectSpellClassMaskB[0]; break;
1281 case 2: ptr = &m_spellProto->EffectSpellClassMaskC[0]; break;
1282 default:
1283 return;
1287 mod->mask = (uint64)ptr[0] | (uint64)ptr[1]<<32;
1288 mod->mask2= (uint64)ptr[2];
1289 m_spellmod = mod;
1291 else
1293 delete m_spellmod;
1294 m_spellmod = NULL;
1297 void Aura::TriggerSpell()
1299 Unit* caster = GetCaster();
1300 Unit* target = GetTriggerTarget();
1302 if(!caster || !target)
1303 return;
1305 // generic casting code with custom spells and target/caster customs
1306 uint32 trigger_spell_id = GetSpellProto()->EffectTriggerSpell[m_effIndex];
1308 uint64 originalCasterGUID = GetCasterGUID();
1310 SpellEntry const *triggeredSpellInfo = sSpellStore.LookupEntry(trigger_spell_id);
1311 SpellEntry const *auraSpellInfo = GetSpellProto();
1312 uint32 auraId = auraSpellInfo->Id;
1314 // specific code for cases with no trigger spell provided in field
1315 if (triggeredSpellInfo == NULL)
1317 switch(auraSpellInfo->SpellFamilyName)
1319 case SPELLFAMILY_GENERIC:
1321 switch(auraId)
1323 // Firestone Passive (1-5 ranks)
1324 case 758:
1325 case 17945:
1326 case 17947:
1327 case 17949:
1328 case 27252:
1330 if (caster->GetTypeId()!=TYPEID_PLAYER)
1331 return;
1332 Item* item = ((Player*)caster)->GetWeaponForAttack(BASE_ATTACK);
1333 if (!item)
1334 return;
1335 uint32 enchant_id = 0;
1336 switch (GetId())
1338 case 758: enchant_id = 1803; break; // Rank 1
1339 case 17945: enchant_id = 1823; break; // Rank 2
1340 case 17947: enchant_id = 1824; break; // Rank 3
1341 case 17949: enchant_id = 1825; break; // Rank 4
1342 case 27252: enchant_id = 2645; break; // Rank 5
1343 default:
1344 return;
1346 // remove old enchanting before applying new
1347 ((Player*)caster)->ApplyEnchantment(item,TEMP_ENCHANTMENT_SLOT,false);
1348 item->SetEnchantment(TEMP_ENCHANTMENT_SLOT, enchant_id, m_modifier.periodictime+1000, 0);
1349 // add new enchanting
1350 ((Player*)caster)->ApplyEnchantment(item,TEMP_ENCHANTMENT_SLOT,true);
1351 return;
1353 // // Periodic Mana Burn
1354 // case 812: break;
1355 // // Polymorphic Ray
1356 // case 6965: break;
1357 // // Fire Nova (1-7 ranks)
1358 // case 8350:
1359 // case 8508:
1360 // case 8509:
1361 // case 11312:
1362 // case 11313:
1363 // case 25540:
1364 // case 25544:
1365 // break;
1366 // Thaumaturgy Channel
1367 case 9712: trigger_spell_id = 21029; break;
1368 // // Egan's Blaster
1369 // case 17368: break;
1370 // // Haunted
1371 // case 18347: break;
1372 // // Ranshalla Waiting
1373 // case 18953: break;
1374 // // Inferno
1375 // case 19695: break;
1376 // // Frostwolf Muzzle DND
1377 // case 21794: break;
1378 // // Alterac Ram Collar DND
1379 // case 21866: break;
1380 // // Celebras Waiting
1381 // case 21916: break;
1382 // Brood Affliction: Bronze
1383 case 23170:
1385 m_target->CastSpell(m_target, 23171, true, 0, this);
1386 return;
1388 // // Mark of Frost
1389 // case 23184: break;
1390 // Restoration
1391 case 23493:
1393 int32 heal = caster->GetMaxHealth() / 10;
1394 caster->ModifyHealth( heal );
1395 caster->SendHealSpellLog(caster, 23493, heal);
1397 int32 mana = caster->GetMaxPower(POWER_MANA);
1398 if (mana)
1400 mana /= 10;
1401 caster->ModifyPower( POWER_MANA, mana );
1402 caster->SendEnergizeSpellLog(caster, 23493, mana, POWER_MANA);
1404 break;
1406 // // Stoneclaw Totem Passive TEST
1407 // case 23792: break;
1408 // // Axe Flurry
1409 // case 24018: break;
1410 // // Mark of Arlokk
1411 // case 24210: break;
1412 // // Restoration
1413 // case 24379: break;
1414 // // Happy Pet
1415 // case 24716: break;
1416 // // Dream Fog
1417 // case 24780: break;
1418 // // Cannon Prep
1419 // case 24832: break;
1420 // // Shadow Bolt Whirl
1421 // case 24834: break;
1422 // // Stink Trap
1423 // case 24918: break;
1424 // // Mark of Nature
1425 // case 25041: break;
1426 // // Agro Drones
1427 // case 25152: break;
1428 // // Consume
1429 // case 25371: break;
1430 // // Pain Spike
1431 // case 25572: break;
1432 // // Rotate 360
1433 // case 26009: break;
1434 // // Rotate -360
1435 // case 26136: break;
1436 // // Consume
1437 // case 26196: break;
1438 // // Berserk
1439 // case 26615: break;
1440 // // Defile
1441 // case 27177: break;
1442 // // Teleport: IF/UC
1443 // case 27601: break;
1444 // // Five Fat Finger Exploding Heart Technique
1445 // case 27673: break;
1446 // // Nitrous Boost
1447 // case 27746: break;
1448 // // Steam Tank Passive
1449 // case 27747: break;
1450 // // Frost Blast
1451 // case 27808: break;
1452 // // Detonate Mana
1453 // case 27819: break;
1454 // // Controller Timer
1455 // case 28095: break;
1456 // // Stalagg Chain
1457 // case 28096: break;
1458 // // Stalagg Tesla Passive
1459 // case 28097: break;
1460 // // Feugen Tesla Passive
1461 // case 28109: break;
1462 // // Feugen Chain
1463 // case 28111: break;
1464 // // Mark of Didier
1465 // case 28114: break;
1466 // // Communique Timer, camp
1467 // case 28346: break;
1468 // // Icebolt
1469 // case 28522: break;
1470 // // Silithyst
1471 // case 29519: break;
1472 // // Inoculate Nestlewood Owlkin
1473 case 29528: trigger_spell_id = 28713; break;
1474 // // Overload
1475 // case 29768: break;
1476 // // Return Fire
1477 // case 29788: break;
1478 // // Return Fire
1479 // case 29793: break;
1480 // // Return Fire
1481 // case 29794: break;
1482 // // Guardian of Icecrown Passive
1483 // case 29897: break;
1484 // Feed Captured Animal
1485 case 29917: trigger_spell_id = 29916; break;
1486 // // Flame Wreath
1487 // case 29946: break;
1488 // // Flame Wreath
1489 // case 29947: break;
1490 // // Mind Exhaustion Passive
1491 // case 30025: break;
1492 // // Nether Beam - Serenity
1493 // case 30401: break;
1494 // Extract Gas
1495 case 30427:
1497 // move loot to player inventory and despawn target
1498 if(caster->GetTypeId() ==TYPEID_PLAYER &&
1499 target->GetTypeId() == TYPEID_UNIT &&
1500 ((Creature*)target)->GetCreatureInfo()->type == CREATURE_TYPE_GAS_CLOUD)
1502 Player* player = (Player*)caster;
1503 Creature* creature = (Creature*)target;
1504 // missing lootid has been reported on startup - just return
1505 if (!creature->GetCreatureInfo()->SkinLootId)
1507 return;
1509 Loot *loot = &creature->loot;
1510 loot->clear();
1511 loot->FillLoot(creature->GetCreatureInfo()->SkinLootId, LootTemplates_Skinning, NULL);
1512 for(uint8 i=0;i<loot->items.size();i++)
1514 LootItem *item = loot->LootItemInSlot(i,player);
1515 ItemPosCountVec dest;
1516 uint8 msg = player->CanStoreNewItem( NULL_BAG, NULL_SLOT, dest, item->itemid, item->count );
1517 if ( msg == EQUIP_ERR_OK )
1519 Item * newitem = player->StoreNewItem( dest, item->itemid, true, item->randomPropertyId);
1521 player->SendNewItem(newitem, uint32(item->count), false, false, true);
1523 else
1524 player->SendEquipError( msg, NULL, NULL );
1526 creature->setDeathState(JUST_DIED);
1527 creature->RemoveCorpse();
1528 creature->SetHealth(0); // just for nice GM-mode view
1530 return;
1531 break;
1533 // Quake
1534 case 30576: trigger_spell_id = 30571; break;
1535 // // Burning Maul
1536 // case 30598: break;
1537 // // Regeneration
1538 // case 30799:
1539 // case 30800:
1540 // case 30801:
1541 // break;
1542 // // Despawn Self - Smoke cloud
1543 // case 31269: break;
1544 // // Time Rift Periodic
1545 // case 31320: break;
1546 // // Corrupt Medivh
1547 // case 31326: break;
1548 // Doom
1549 case 31347:
1551 m_target->CastSpell(m_target,31350,true);
1552 m_target->DealDamage(m_target, m_target->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
1553 return;
1555 // Spellcloth
1556 case 31373:
1558 // Summon Elemental after create item
1559 caster->SummonCreature(17870, 0, 0, 0, caster->GetOrientation(), TEMPSUMMON_DEAD_DESPAWN, 0);
1560 return;
1562 // // Bloodmyst Tesla
1563 // case 31611: break;
1564 // // Doomfire
1565 // case 31944: break;
1566 // // Teleport Test
1567 // case 32236: break;
1568 // // Earthquake
1569 // case 32686: break;
1570 // // Possess
1571 // case 33401: break;
1572 // // Draw Shadows
1573 // case 33563: break;
1574 // // Murmur's Touch
1575 // case 33711: break;
1576 // Flame Quills
1577 case 34229:
1579 // cast 24 spells 34269-34289, 34314-34316
1580 for(uint32 spell_id = 34269; spell_id != 34290; ++spell_id)
1581 caster->CastSpell(m_target,spell_id,true);
1582 for(uint32 spell_id = 34314; spell_id != 34317; ++spell_id)
1583 caster->CastSpell(m_target,spell_id,true);
1584 return;
1586 // // Gravity Lapse
1587 // case 34480: break;
1588 // // Tornado
1589 // case 34683: break;
1590 // // Frostbite Rotate
1591 // case 34748: break;
1592 // // Arcane Flurry
1593 // case 34821: break;
1594 // // Interrupt Shutdown
1595 // case 35016: break;
1596 // // Interrupt Shutdown
1597 // case 35176: break;
1598 // // Inferno
1599 // case 35268: break;
1600 // // Salaadin's Tesla
1601 // case 35515: break;
1602 // // Ethereal Channel (Red)
1603 // case 35518: break;
1604 // // Nether Vapor
1605 // case 35879: break;
1606 // // Dark Portal Storm
1607 // case 36018: break;
1608 // // Burning Maul
1609 // case 36056: break;
1610 // // Living Grove Defender Lifespan
1611 // case 36061: break;
1612 // // Professor Dabiri Talks
1613 // case 36064: break;
1614 // // Kael Gaining Power
1615 // case 36091: break;
1616 // // They Must Burn Bomb Aura
1617 // case 36344: break;
1618 // // They Must Burn Bomb Aura (self)
1619 // case 36350: break;
1620 // // Stolen Ravenous Ravager Egg
1621 // case 36401: break;
1622 // // Activated Cannon
1623 // case 36410: break;
1624 // // Stolen Ravenous Ravager Egg
1625 // case 36418: break;
1626 // // Enchanted Weapons
1627 // case 36510: break;
1628 // // Cursed Scarab Periodic
1629 // case 36556: break;
1630 // // Cursed Scarab Despawn Periodic
1631 // case 36561: break;
1632 // // Vision Guide
1633 // case 36573: break;
1634 // // Cannon Charging (platform)
1635 // case 36785: break;
1636 // // Cannon Charging (self)
1637 // case 36860: break;
1638 // Remote Toy
1639 case 37027: trigger_spell_id = 37029; break;
1640 // // Mark of Death
1641 // case 37125: break;
1642 // // Arcane Flurry
1643 // case 37268: break;
1644 // // Spout
1645 // case 37429: break;
1646 // // Spout
1647 // case 37430: break;
1648 // // Karazhan - Chess NPC AI, Snapshot timer
1649 // case 37440: break;
1650 // // Karazhan - Chess NPC AI, action timer
1651 // case 37504: break;
1652 // // Karazhan - Chess: Is Square OCCUPIED aura (DND)
1653 // case 39400: break;
1654 // // Banish
1655 // case 37546: break;
1656 // // Shriveling Gaze
1657 // case 37589: break;
1658 // // Fake Aggro Radius (2 yd)
1659 // case 37815: break;
1660 // // Corrupt Medivh
1661 // case 37853: break;
1662 // Eye of Grillok
1663 case 38495:
1665 m_target->CastSpell(m_target, 38530, true);
1666 return;
1668 // Absorb Eye of Grillok (Zezzak's Shard)
1669 case 38554:
1671 if(m_target->GetTypeId() != TYPEID_UNIT)
1672 return;
1674 caster->CastSpell(caster, 38495, true);
1676 Creature* creatureTarget = (Creature*)m_target;
1678 creatureTarget->setDeathState(JUST_DIED);
1679 creatureTarget->RemoveCorpse();
1680 creatureTarget->SetHealth(0); // just for nice GM-mode view
1681 return;
1683 // // Magic Sucker Device timer
1684 // case 38672: break;
1685 // // Tomb Guarding Charging
1686 // case 38751: break;
1687 // // Murmur's Touch
1688 // case 38794: break;
1689 // // Activate Nether-wraith Beacon (31742 Nether-wraith Beacon item)
1690 // case 39105: break;
1691 // // Drain World Tree Visual
1692 // case 39140: break;
1693 // // Quest - Dustin's Undead Dragon Visual aura
1694 // case 39259: break;
1695 // // Hellfire - The Exorcism, Jules releases darkness, aura
1696 // case 39306: break;
1697 // // Inferno
1698 // case 39346: break;
1699 // // Enchanted Weapons
1700 // case 39489: break;
1701 // // Shadow Bolt Whirl
1702 // case 39630: break;
1703 // // Shadow Bolt Whirl
1704 // case 39634: break;
1705 // // Shadow Inferno
1706 // case 39645: break;
1707 // Tear of Azzinoth Summon Channel - it's not really supposed to do anything,and this only prevents the console spam
1708 case 39857: trigger_spell_id = 39856; break;
1709 // // Soulgrinder Ritual Visual (Smashed)
1710 // case 39974: break;
1711 // // Simon Game Pre-game timer
1712 // case 40041: break;
1713 // // Knockdown Fel Cannon: The Aggro Check Aura
1714 // case 40113: break;
1715 // // Spirit Lance
1716 // case 40157: break;
1717 // // Demon Transform 2
1718 // case 40398: break;
1719 // // Demon Transform 1
1720 // case 40511: break;
1721 // // Ancient Flames
1722 // case 40657: break;
1723 // // Ethereal Ring Cannon: Cannon Aura
1724 // case 40734: break;
1725 // // Cage Trap
1726 // case 40760: break;
1727 // // Random Periodic
1728 // case 40867: break;
1729 // // Prismatic Shield
1730 // case 40879: break;
1731 // // Aura of Desire
1732 // case 41350: break;
1733 // // Dementia
1734 // case 41404: break;
1735 // // Chaos Form
1736 // case 41629: break;
1737 // // Alert Drums
1738 // case 42177: break;
1739 // // Spout
1740 // case 42581: break;
1741 // // Spout
1742 // case 42582: break;
1743 // // Return to the Spirit Realm
1744 // case 44035: break;
1745 // // Curse of Boundless Agony
1746 // case 45050: break;
1747 // // Earthquake
1748 // case 46240: break;
1749 // Personalized Weather
1750 case 46736: trigger_spell_id = 46737; break;
1751 // // Stay Submerged
1752 // case 46981: break;
1753 // // Dragonblight Ram
1754 // case 47015: break;
1755 // // Party G.R.E.N.A.D.E.
1756 // case 51510: break;
1757 default:
1758 break;
1760 break;
1762 case SPELLFAMILY_MAGE:
1764 switch(auraId)
1766 // Invisibility
1767 case 66:
1769 if(!m_duration)
1770 m_target->CastSpell(m_target, 32612, true, NULL, this);
1771 return;
1773 default:
1774 break;
1776 break;
1778 // case SPELLFAMILY_WARRIOR:
1779 // {
1780 // switch(auraId)
1781 // {
1782 // // Wild Magic
1783 // case 23410: break;
1784 // // Corrupted Totems
1785 // case 23425: break;
1786 // default:
1787 // break;
1788 // }
1789 // break;
1790 // }
1791 // case SPELLFAMILY_PRIEST:
1792 // {
1793 // switch(auraId)
1794 // {
1795 // // Blue Beam
1796 // case 32930: break;
1797 // // Fury of the Dreghood Elders
1798 // case 35460: break;
1799 // default:
1800 // break;
1801 // }
1802 // break;
1803 // }
1804 case SPELLFAMILY_DRUID:
1806 switch(auraId)
1808 // Cat Form
1809 // trigger_spell_id not set and unknown effect triggered in this case, ignoring for while
1810 case 768:
1811 return;
1812 // Frenzied Regeneration
1813 case 22842:
1814 case 22895:
1815 case 22896:
1816 case 26999:
1818 int32 LifePerRage = GetModifier()->m_amount;
1820 int32 lRage = m_target->GetPower(POWER_RAGE);
1821 if(lRage > 100) // rage stored as rage*10
1822 lRage = 100;
1823 m_target->ModifyPower(POWER_RAGE, -lRage);
1824 int32 FRTriggerBasePoints = int32(lRage*LifePerRage/10);
1825 m_target->CastCustomSpell(m_target,22845,&FRTriggerBasePoints,NULL,NULL,true,NULL,this);
1826 return;
1828 default:
1829 break;
1831 break;
1834 // case SPELLFAMILY_HUNTER:
1835 // {
1836 // switch(auraId)
1837 // {
1838 // //Frost Trap Aura
1839 // case 13810:
1840 // return;
1841 // //Rizzle's Frost Trap
1842 // case 39900:
1843 // return;
1844 // // Tame spells
1845 // case 19597: // Tame Ice Claw Bear
1846 // case 19676: // Tame Snow Leopard
1847 // case 19677: // Tame Large Crag Boar
1848 // case 19678: // Tame Adult Plainstrider
1849 // case 19679: // Tame Prairie Stalker
1850 // case 19680: // Tame Swoop
1851 // case 19681: // Tame Dire Mottled Boar
1852 // case 19682: // Tame Surf Crawler
1853 // case 19683: // Tame Armored Scorpid
1854 // case 19684: // Tame Webwood Lurker
1855 // case 19685: // Tame Nightsaber Stalker
1856 // case 19686: // Tame Strigid Screecher
1857 // case 30100: // Tame Crazed Dragonhawk
1858 // case 30103: // Tame Elder Springpaw
1859 // case 30104: // Tame Mistbat
1860 // case 30647: // Tame Barbed Crawler
1861 // case 30648: // Tame Greater Timberstrider
1862 // case 30652: // Tame Nightstalker
1863 // return;
1864 // default:
1865 // break;
1866 // }
1867 // break;
1868 // }
1869 case SPELLFAMILY_SHAMAN:
1871 switch(auraId)
1873 // Lightning Shield (The Earthshatterer set trigger after cast Lighting Shield)
1874 case 28820:
1876 // Need remove self if Lightning Shield not active
1877 Unit::AuraMap const& auras = target->GetAuras();
1878 for(Unit::AuraMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
1880 SpellEntry const* spell = itr->second->GetSpellProto();
1881 if( spell->SpellFamilyName == SPELLFAMILY_SHAMAN &&
1882 spell->SpellFamilyFlags & 0x0000000000000400L)
1883 return;
1885 target->RemoveAurasDueToSpell(28820);
1886 return;
1888 // Totemic Mastery (Skyshatter Regalia (Shaman Tier 6) - bonus)
1889 case 38443:
1891 bool all = true;
1892 for(int i = 0; i < MAX_TOTEM; ++i)
1894 if(!caster->m_TotemSlot[i])
1896 all = false;
1897 break;
1901 if(all)
1902 caster->CastSpell(caster,38437,true);
1903 else
1904 caster->RemoveAurasDueToSpell(38437);
1905 return;
1907 default:
1908 break;
1910 break;
1912 default:
1913 break;
1915 // Reget trigger spell proto
1916 triggeredSpellInfo = sSpellStore.LookupEntry(trigger_spell_id);
1917 if(triggeredSpellInfo == NULL)
1919 sLog.outError("Aura::TriggerSpell: Spell %u have 0 in EffectTriggered[%d], not handled custom case?",GetId(),GetEffIndex());
1920 return;
1923 else
1925 // Spell exist but require custom code
1926 switch(auraId)
1928 // Curse of Idiocy
1929 case 1010:
1931 // TODO: spell casted by result in correct way mostly
1932 // BUT:
1933 // 1) target show casting at each triggered cast: target don't must show casting animation for any triggered spell
1934 // but must show affect apply like item casting
1935 // 2) maybe aura must be replace by new with accumulative stat mods instead stacking
1937 // prevent cast by triggered auras
1938 if(m_caster_guid == m_target->GetGUID())
1939 return;
1941 // stop triggering after each affected stats lost > 90
1942 int32 intelectLoss = 0;
1943 int32 spiritLoss = 0;
1945 Unit::AuraList const& mModStat = m_target->GetAurasByType(SPELL_AURA_MOD_STAT);
1946 for(Unit::AuraList::const_iterator i = mModStat.begin(); i != mModStat.end(); ++i)
1948 if ((*i)->GetId() == 1010)
1950 switch((*i)->GetModifier()->m_miscvalue)
1952 case STAT_INTELLECT: intelectLoss += (*i)->GetModifier()->m_amount; break;
1953 case STAT_SPIRIT: spiritLoss += (*i)->GetModifier()->m_amount; break;
1954 default: break;
1959 if(intelectLoss <= -90 && spiritLoss <= -90)
1960 return;
1962 caster = target;
1963 originalCasterGUID = 0;
1964 break;
1966 // Mana Tide
1967 case 16191:
1969 caster->CastCustomSpell(target, trigger_spell_id, &m_modifier.m_amount, NULL, NULL, true, NULL, this, originalCasterGUID);
1970 return;
1974 // All ok cast by default case
1975 Spell *spell = new Spell(caster, triggeredSpellInfo, true, originalCasterGUID );
1977 SpellCastTargets targets;
1978 targets.setUnitTarget( target );
1980 // if spell create dynamic object extract area from it
1981 if(DynamicObject* dynObj = caster->GetDynObject(GetId()))
1982 targets.setDestination(dynObj->GetPositionX(),dynObj->GetPositionY(),dynObj->GetPositionZ());
1984 spell->prepare(&targets, this);
1987 /*********************************************************/
1988 /*** AURA EFFECTS ***/
1989 /*********************************************************/
1991 void Aura::HandleAuraDummy(bool apply, bool Real)
1993 // spells required only Real aura add/remove
1994 if(!Real)
1995 return;
1997 Unit* caster = GetCaster();
1999 // AT APPLY
2000 if(apply)
2002 switch(GetId())
2004 case 1515: // Tame beast
2005 // FIX_ME: this is 2.0.12 threat effect replaced in 2.1.x by dummy aura, must be checked for correctness
2006 if( caster && m_target->CanHaveThreatList())
2007 m_target->AddThreat(caster, 10.0f);
2008 return;
2009 case 13139: // net-o-matic
2010 // root to self part of (root_target->charge->root_self sequence
2011 if(caster)
2012 caster->CastSpell(caster,13138,true,NULL,this);
2013 return;
2014 case 39850: // Rocket Blast
2015 if(roll_chance_i(20)) // backfire stun
2016 m_target->CastSpell(m_target, 51581, true, NULL, this);
2017 return;
2018 case 43873: // Headless Horseman Laugh
2019 if(caster->GetTypeId() == TYPEID_PLAYER)
2020 ((Player*)caster)->PlaySound(11965, false);
2021 return;
2022 case 46354: // Blood Elf Illusion
2023 if(caster)
2025 switch(caster->getGender())
2027 case GENDER_FEMALE:
2028 caster->CastSpell(m_target,46356,true,NULL,this);
2029 break;
2030 case GENDER_MALE:
2031 caster->CastSpell(m_target,46355,true,NULL,this);
2032 break;
2033 default:
2034 break;
2037 return;
2038 case 46699: // Requires No Ammo
2039 if(m_target->GetTypeId()==TYPEID_PLAYER)
2040 ((Player*)m_target)->RemoveAmmo(); // not use ammo and not allow use
2041 return;
2044 // Earth Shield
2045 if ( caster && GetSpellProto()->SpellFamilyName == SPELLFAMILY_SHAMAN && (GetSpellProto()->SpellFamilyFlags & 0x40000000000LL))
2047 // prevent double apply bonuses
2048 if(m_target->GetTypeId()!=TYPEID_PLAYER || !((Player*)m_target)->GetSession()->PlayerLoading())
2049 m_modifier.m_amount = caster->SpellHealingBonus(GetSpellProto(), m_modifier.m_amount, SPELL_DIRECT_DAMAGE, m_target);
2050 return;
2053 // AT REMOVE
2054 else
2056 if( m_target->GetTypeId() == TYPEID_PLAYER &&
2057 ( GetSpellProto()->Effect[0]==72 || GetSpellProto()->Effect[0]==6 &&
2058 ( GetSpellProto()->EffectApplyAuraName[0]==1 || GetSpellProto()->EffectApplyAuraName[0]==128 ) ) )
2060 // spells with SpellEffect=72 and aura=4: 6196, 6197, 21171, 21425
2061 ((Player*)m_target)->SetFarSight(NULL);
2062 WorldPacket data(SMSG_CLEAR_FAR_SIGHT_IMMEDIATE, 0);
2063 ((Player*)m_target)->GetSession()->SendPacket(&data);
2064 return;
2067 if( (IsQuestTameSpell(GetId())) && caster && caster->isAlive() && m_target->isAlive())
2069 uint32 finalSpelId = 0;
2070 switch(GetId())
2072 case 19548: finalSpelId = 19597; break;
2073 case 19674: finalSpelId = 19677; break;
2074 case 19687: finalSpelId = 19676; break;
2075 case 19688: finalSpelId = 19678; break;
2076 case 19689: finalSpelId = 19679; break;
2077 case 19692: finalSpelId = 19680; break;
2078 case 19693: finalSpelId = 19684; break;
2079 case 19694: finalSpelId = 19681; break;
2080 case 19696: finalSpelId = 19682; break;
2081 case 19697: finalSpelId = 19683; break;
2082 case 19699: finalSpelId = 19685; break;
2083 case 19700: finalSpelId = 19686; break;
2084 case 30646: finalSpelId = 30647; break;
2085 case 30653: finalSpelId = 30648; break;
2086 case 30654: finalSpelId = 30652; break;
2087 case 30099: finalSpelId = 30100; break;
2088 case 30102: finalSpelId = 30103; break;
2089 case 30105: finalSpelId = 30104; break;
2092 if(finalSpelId)
2093 caster->CastSpell(m_target,finalSpelId,true,NULL,this);
2094 return;
2097 // Waiting to Resurrect
2098 if(GetId()==2584)
2100 // Waiting to resurrect spell cancel, we must remove player from resurrect queue
2101 if(m_target->GetTypeId() == TYPEID_PLAYER)
2102 if(BattleGround *bg = ((Player*)m_target)->GetBattleGround())
2103 bg->RemovePlayerFromResurrectQueue(m_target->GetGUID());
2104 return;
2107 // Dark Fiend
2108 if(GetId()==45934)
2110 // Kill target if dispelled
2111 if (m_removeMode==AURA_REMOVE_BY_DISPEL)
2112 m_target->DealDamage(m_target, m_target->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
2113 return;
2116 // Burning Winds
2117 if(GetId()==46308) // casted only at creatures at spawn
2119 m_target->CastSpell(m_target,47287,true,NULL,this);
2120 return;
2124 // AT APPLY & REMOVE
2126 switch(m_spellProto->SpellFamilyName)
2128 case SPELLFAMILY_GENERIC:
2130 // Unstable Power
2131 if( GetId()==24658 )
2133 uint32 spellId = 24659;
2134 if (apply)
2136 const SpellEntry *spell = sSpellStore.LookupEntry(spellId);
2137 if (!spell)
2138 return;
2139 for (int i=0; i < spell->StackAmount; ++i)
2140 caster->CastSpell(m_target, spell->Id, true, NULL, NULL, GetCasterGUID());
2141 return;
2143 m_target->RemoveAurasDueToSpell(spellId);
2144 return;
2146 // Restless Strength
2147 if( GetId()==24661 )
2149 uint32 spellId = 24662;
2150 if (apply)
2152 const SpellEntry *spell = sSpellStore.LookupEntry(spellId);
2153 if (!spell)
2154 return;
2155 for (int i=0; i < spell->StackAmount; ++i)
2156 caster->CastSpell(m_target, spell->Id, true, NULL, NULL, GetCasterGUID());
2157 return;
2159 m_target->RemoveAurasDueToSpell(spellId);
2160 return;
2162 // Victorious
2163 if(GetId()==32216 && m_target->getClass()==CLASS_WARRIOR)
2165 m_target->ModifyAuraState(AURA_STATE_WARRIOR_VICTORY_RUSH, apply);
2166 return;
2168 //Summon Fire Elemental
2169 if (GetId() == 40133 && caster)
2171 Unit *owner = caster->GetOwner();
2172 if (owner && owner->GetTypeId() == TYPEID_PLAYER)
2174 if(apply)
2175 owner->CastSpell(owner,8985,true);
2176 else
2177 ((Player*)owner)->RemovePet(NULL, PET_SAVE_NOT_IN_SLOT, true);
2179 return;
2182 //Summon Earth Elemental
2183 if (GetId() == 40132 && caster)
2185 Unit *owner = caster->GetOwner();
2186 if (owner && owner->GetTypeId() == TYPEID_PLAYER)
2188 if(apply)
2189 owner->CastSpell(owner,19704,true);
2190 else
2191 ((Player*)owner)->RemovePet(NULL, PET_SAVE_NOT_IN_SLOT, true);
2193 return;
2195 break;
2197 case SPELLFAMILY_MAGE:
2199 // Hypothermia
2200 if( GetId()==41425 )
2202 m_target->ModifyAuraState(AURA_STATE_HYPOTHERMIA,apply);
2203 return;
2205 break;
2207 case SPELLFAMILY_DRUID:
2209 // Lifebloom
2210 if ( GetSpellProto()->SpellFamilyFlags & 0x1000000000LL )
2212 if ( apply )
2214 if ( caster )
2215 // prevent double apply bonuses
2216 if(m_target->GetTypeId()!=TYPEID_PLAYER || !((Player*)m_target)->GetSession()->PlayerLoading())
2217 m_modifier.m_amount = caster->SpellHealingBonus(GetSpellProto(), m_modifier.m_amount, SPELL_DIRECT_DAMAGE, m_target);
2219 else
2221 // Final heal only on dispelled or duration end
2222 if ( !(GetAuraDuration() <= 0 || m_removeMode==AURA_REMOVE_BY_DISPEL) )
2223 return;
2225 // have a look if there is still some other Lifebloom dummy aura
2226 Unit::AuraList auras = m_target->GetAurasByType(SPELL_AURA_DUMMY);
2227 for(Unit::AuraList::iterator itr = auras.begin(); itr!=auras.end(); ++itr)
2228 if((*itr)->GetSpellProto()->SpellFamilyName == SPELLFAMILY_DRUID &&
2229 (*itr)->GetSpellProto()->SpellFamilyFlags & 0x1000000000LL)
2230 return;
2232 // final heal
2233 if(m_target->IsInWorld())
2234 m_target->CastCustomSpell(m_target,33778,&m_modifier.m_amount,NULL,NULL,true,NULL,this,GetCasterGUID());
2236 return;
2239 // Predatory Strikes
2240 if(m_target->GetTypeId()==TYPEID_PLAYER && GetSpellProto()->SpellIconID == 1563)
2242 ((Player*)m_target)->UpdateAttackPowerAndDamage();
2243 return;
2245 // Idol of the Emerald Queen
2246 if ( GetId() == 34246 && m_target->GetTypeId()==TYPEID_PLAYER )
2248 if(apply)
2250 SpellModifier *mod = new SpellModifier;
2251 mod->op = SPELLMOD_DOT;
2252 mod->value = m_modifier.m_amount/7;
2253 mod->type = SPELLMOD_FLAT;
2254 mod->spellId = GetId();
2255 mod->mask = 0x001000000000LL;
2256 mod->mask2= 0LL;
2258 m_spellmod = mod;
2261 ((Player*)m_target)->AddSpellMod(m_spellmod, apply);
2262 return;
2264 break;
2266 case SPELLFAMILY_HUNTER:
2268 // Improved Aspect of the Viper
2269 if( GetId()==38390 && m_target->GetTypeId()==TYPEID_PLAYER )
2271 if(apply)
2273 // + effect value for Aspect of the Viper
2274 SpellModifier *mod = new SpellModifier;
2275 mod->op = SPELLMOD_EFFECT1;
2276 mod->value = m_modifier.m_amount;
2277 mod->type = SPELLMOD_FLAT;
2278 mod->spellId = GetId();
2279 mod->mask = 0x4000000000000LL;
2280 mod->mask2= 0LL;
2282 m_spellmod = mod;
2285 ((Player*)m_target)->AddSpellMod(m_spellmod, apply);
2286 return;
2288 break;
2290 case SPELLFAMILY_SHAMAN:
2292 // Improved Weapon Totems
2293 if( GetSpellProto()->SpellIconID == 57 && m_target->GetTypeId()==TYPEID_PLAYER )
2295 if(apply)
2297 SpellModifier *mod = new SpellModifier;
2298 mod->op = SPELLMOD_EFFECT1;
2299 mod->value = m_modifier.m_amount;
2300 mod->type = SPELLMOD_PCT;
2301 mod->spellId = GetId();
2302 switch (m_effIndex)
2304 case 0:
2305 mod->mask = 0x00200000000LL; // Windfury Totem
2306 mod->mask2= 0LL;
2307 break;
2308 case 1:
2309 mod->mask = 0x00400000000LL; // Flametongue Totem
2310 mod->mask2= 0LL;
2311 break;
2314 m_spellmod = mod;
2317 ((Player*)m_target)->AddSpellMod(m_spellmod, apply);
2318 return;
2320 break;
2324 // pet auras
2325 if(PetAura const* petSpell = spellmgr.GetPetAura(GetId()))
2327 if(apply)
2328 m_target->AddPetAura(petSpell);
2329 else
2330 m_target->RemovePetAura(petSpell);
2331 return;
2335 void Aura::HandleAuraPeriodicDummy(bool apply, bool Real)
2337 // spells required only Real aura add/remove
2338 if(!Real)
2339 return;
2341 Unit* caster = GetCaster();
2343 SpellEntry const*spell = GetSpellProto();
2344 switch( spell->SpellFamilyName)
2346 case SPELLFAMILY_ROGUE:
2348 // Master of Subtlety
2349 if (spell->Id==31666 && !apply && Real)
2351 m_target->RemoveAurasDueToSpell(31665);
2352 break;
2354 break;
2356 case SPELLFAMILY_HUNTER:
2358 // Aspect of the Viper
2359 if (spell->SpellFamilyFlags&0x0004000000000000LL)
2361 // Update regen on remove
2362 if (!apply && m_target->GetTypeId() == TYPEID_PLAYER)
2363 ((Player*)m_target)->UpdateManaRegen();
2364 break;
2366 // Explosive Shot
2367 if (spell->SpellFamilyFlags & 0x8000000000000000LL)
2369 if (apply && caster)
2371 int32 damage = m_modifier.m_amount + caster->GetTotalAttackPowerValue(RANGED_ATTACK) * 8 / 100;
2372 caster->CastCustomSpell(m_target, 53352, &damage, 0, 0, true, 0, this);
2374 break;
2376 break;
2380 m_isPeriodic = apply;
2383 void Aura::HandleAuraMounted(bool apply, bool Real)
2385 // only at real add/remove aura
2386 if(!Real)
2387 return;
2389 if(apply)
2391 CreatureInfo const* ci = objmgr.GetCreatureTemplate(m_modifier.m_miscvalue);
2392 if(!ci)
2394 sLog.outErrorDb("AuraMounted: `creature_template`='%u' not found in database (only need it modelid)", m_modifier.m_miscvalue);
2395 return;
2398 uint32 team = 0;
2399 if (m_target->GetTypeId()==TYPEID_PLAYER)
2400 team = ((Player*)m_target)->GetTeam();
2402 uint32 display_id = objmgr.ChooseDisplayId(team,ci);
2403 CreatureModelInfo const *minfo = objmgr.GetCreatureModelRandomGender(display_id);
2404 if (minfo)
2405 display_id = minfo->modelid;
2407 m_target->Mount(display_id);
2409 else
2411 m_target->Unmount();
2415 void Aura::HandleAuraWaterWalk(bool apply, bool Real)
2417 // only at real add/remove aura
2418 if(!Real)
2419 return;
2421 WorldPacket data;
2422 if(apply)
2423 data.Initialize(SMSG_MOVE_WATER_WALK, 8+4);
2424 else
2425 data.Initialize(SMSG_MOVE_LAND_WALK, 8+4);
2426 data.append(m_target->GetPackGUID());
2427 data << uint32(0);
2428 m_target->SendMessageToSet(&data,true);
2431 void Aura::HandleAuraFeatherFall(bool apply, bool Real)
2433 // only at real add/remove aura
2434 if(!Real)
2435 return;
2437 WorldPacket data;
2438 if(apply)
2439 data.Initialize(SMSG_MOVE_FEATHER_FALL, 8+4);
2440 else
2441 data.Initialize(SMSG_MOVE_NORMAL_FALL, 8+4);
2442 data.append(m_target->GetPackGUID());
2443 data << (uint32)0;
2444 m_target->SendMessageToSet(&data,true);
2447 void Aura::HandleAuraHover(bool apply, bool Real)
2449 // only at real add/remove aura
2450 if(!Real)
2451 return;
2453 WorldPacket data;
2454 if(apply)
2455 data.Initialize(SMSG_MOVE_SET_HOVER, 8+4);
2456 else
2457 data.Initialize(SMSG_MOVE_UNSET_HOVER, 8+4);
2458 data.append(m_target->GetPackGUID());
2459 data << uint32(0);
2460 m_target->SendMessageToSet(&data,true);
2463 void Aura::HandleWaterBreathing(bool apply, bool Real)
2465 if(apply)
2466 m_target->waterbreath = true;
2467 else if(m_target->GetAurasByType(SPELL_AURA_WATER_BREATHING).empty())
2469 m_target->waterbreath = false;
2471 // update for enable timer in case not moving target
2472 if(m_target->GetTypeId()==TYPEID_PLAYER && m_target->IsInWorld())
2474 ((Player*)m_target)->UpdateUnderwaterState(m_target->GetMap(),m_target->GetPositionX(),m_target->GetPositionY(),m_target->GetPositionZ());
2475 ((Player*)m_target)->HandleDrowning();
2480 void Aura::HandleAuraModShapeshift(bool apply, bool Real)
2482 if(!Real)
2483 return;
2485 uint32 modelid = 0;
2486 Powers PowerType = POWER_MANA;
2487 ShapeshiftForm form = ShapeshiftForm(m_modifier.m_miscvalue);
2488 switch(form)
2490 case FORM_CAT:
2491 if(Player::TeamForRace(m_target->getRace())==ALLIANCE)
2492 modelid = 892;
2493 else
2494 modelid = 8571;
2495 PowerType = POWER_ENERGY;
2496 break;
2497 case FORM_TRAVEL:
2498 modelid = 632;
2499 break;
2500 case FORM_AQUA:
2501 if(Player::TeamForRace(m_target->getRace())==ALLIANCE)
2502 modelid = 2428;
2503 else
2504 modelid = 2428;
2505 break;
2506 case FORM_BEAR:
2507 if(Player::TeamForRace(m_target->getRace())==ALLIANCE)
2508 modelid = 2281;
2509 else
2510 modelid = 2289;
2511 PowerType = POWER_RAGE;
2512 break;
2513 case FORM_GHOUL:
2514 if(Player::TeamForRace(m_target->getRace())==ALLIANCE)
2515 modelid = 10045;
2516 break;
2517 case FORM_DIREBEAR:
2518 if(Player::TeamForRace(m_target->getRace())==ALLIANCE)
2519 modelid = 2281;
2520 else
2521 modelid = 2289;
2522 PowerType = POWER_RAGE;
2523 break;
2524 case FORM_CREATUREBEAR:
2525 modelid = 902;
2526 break;
2527 case FORM_GHOSTWOLF:
2528 modelid = 4613;
2529 break;
2530 case FORM_FLIGHT:
2531 if(Player::TeamForRace(m_target->getRace())==ALLIANCE)
2532 modelid = 20857;
2533 else
2534 modelid = 20872;
2535 break;
2536 case FORM_MOONKIN:
2537 if(Player::TeamForRace(m_target->getRace())==ALLIANCE)
2538 modelid = 15374;
2539 else
2540 modelid = 15375;
2541 break;
2542 case FORM_FLIGHT_EPIC:
2543 if(Player::TeamForRace(m_target->getRace())==ALLIANCE)
2544 modelid = 21243;
2545 else
2546 modelid = 21244;
2547 break;
2548 case FORM_METAMORPHOSIS:
2549 modelid = 25277;
2550 break;
2551 case FORM_AMBIENT:
2552 case FORM_SHADOW:
2553 case FORM_STEALTH:
2554 break;
2555 case FORM_TREE:
2556 modelid = 864;
2557 break;
2558 case FORM_BATTLESTANCE:
2559 case FORM_BERSERKERSTANCE:
2560 case FORM_DEFENSIVESTANCE:
2561 PowerType = POWER_RAGE;
2562 break;
2563 case FORM_SPIRITOFREDEMPTION:
2564 modelid = 16031;
2565 break;
2566 default:
2567 sLog.outError("Auras: Unknown Shapeshift Type: %u", m_modifier.m_miscvalue);
2570 // remove polymorph before changing display id to keep new display id
2571 switch ( form )
2573 case FORM_CAT:
2574 case FORM_TREE:
2575 case FORM_TRAVEL:
2576 case FORM_AQUA:
2577 case FORM_BEAR:
2578 case FORM_DIREBEAR:
2579 case FORM_FLIGHT_EPIC:
2580 case FORM_FLIGHT:
2581 case FORM_MOONKIN:
2582 // remove movement affects
2583 m_target->RemoveSpellsCausingAura(SPELL_AURA_MOD_ROOT);
2584 m_target->RemoveSpellsCausingAura(SPELL_AURA_MOD_DECREASE_SPEED);
2586 // and polymorphic affects
2587 if(m_target->IsPolymorphed())
2588 m_target->RemoveAurasDueToSpell(m_target->getTransForm());
2589 break;
2590 default:
2591 break;
2594 if(apply)
2596 // remove other shapeshift before applying a new one
2597 if(m_target->m_ShapeShiftFormSpellId)
2598 m_target->RemoveAurasDueToSpell(m_target->m_ShapeShiftFormSpellId,this);
2600 m_target->SetByteValue(UNIT_FIELD_BYTES_2, 3, form);
2602 if(modelid > 0)
2603 m_target->SetDisplayId(modelid);
2605 if(PowerType != POWER_MANA)
2607 // reset power to default values only at power change
2608 if(m_target->getPowerType()!=PowerType)
2609 m_target->setPowerType(PowerType);
2611 switch(form)
2613 case FORM_CAT:
2614 case FORM_BEAR:
2615 case FORM_DIREBEAR:
2617 // get furor proc chance
2618 uint32 FurorChance = 0;
2619 Unit::AuraList const& mDummy = m_target->GetAurasByType(SPELL_AURA_DUMMY);
2620 for(Unit::AuraList::const_iterator i = mDummy.begin(); i != mDummy.end(); ++i)
2622 if ((*i)->GetSpellProto()->SpellIconID == 238)
2624 FurorChance = (*i)->GetModifier()->m_amount;
2625 break;
2629 if (m_modifier.m_miscvalue == FORM_CAT)
2631 m_target->SetPower(POWER_ENERGY,0);
2632 if(urand(1,100) <= FurorChance)
2633 m_target->CastSpell(m_target,17099,true,NULL,this);
2635 else
2637 m_target->SetPower(POWER_RAGE,0);
2638 if(urand(1,100) <= FurorChance)
2639 m_target->CastSpell(m_target,17057,true,NULL,this);
2641 break;
2643 case FORM_BATTLESTANCE:
2644 case FORM_DEFENSIVESTANCE:
2645 case FORM_BERSERKERSTANCE:
2647 uint32 Rage_val = 0;
2648 // Stance mastery + Tactical mastery (both passive, and last have aura only in defense stance, but need apply at any stance switch)
2649 if(m_target->GetTypeId() == TYPEID_PLAYER)
2651 PlayerSpellMap const& sp_list = ((Player *)m_target)->GetSpellMap();
2652 for (PlayerSpellMap::const_iterator itr = sp_list.begin(); itr != sp_list.end(); ++itr)
2654 if(itr->second->state == PLAYERSPELL_REMOVED) continue;
2655 SpellEntry const *spellInfo = sSpellStore.LookupEntry(itr->first);
2656 if (spellInfo && spellInfo->SpellFamilyName == SPELLFAMILY_WARRIOR && spellInfo->SpellIconID == 139)
2657 Rage_val += m_target->CalculateSpellDamage(spellInfo,0,spellInfo->EffectBasePoints[0],m_target) * 10;
2661 if (m_target->GetPower(POWER_RAGE) > Rage_val)
2662 m_target->SetPower(POWER_RAGE,Rage_val);
2663 break;
2665 default:
2666 break;
2670 m_target->m_ShapeShiftFormSpellId = GetId();
2671 m_target->m_form = form;
2673 else
2675 if(modelid > 0)
2676 m_target->SetDisplayId(m_target->GetNativeDisplayId());
2677 m_target->SetByteValue(UNIT_FIELD_BYTES_2, 3, FORM_NONE);
2678 if(m_target->getClass() == CLASS_DRUID)
2679 m_target->setPowerType(POWER_MANA);
2680 m_target->m_ShapeShiftFormSpellId = 0;
2681 m_target->m_form = FORM_NONE;
2683 switch(form)
2685 // Nordrassil Harness - bonus
2686 case FORM_BEAR:
2687 case FORM_DIREBEAR:
2688 case FORM_CAT:
2690 if(Aura* dummy = m_target->GetDummyAura(37315) )
2691 m_target->CastSpell(m_target,37316,true,NULL,dummy);
2692 break;
2694 // Nordrassil Regalia - bonus
2695 case FORM_MOONKIN:
2697 if(Aura* dummy = m_target->GetDummyAura(37324) )
2698 m_target->CastSpell(m_target,37325,true,NULL,dummy);
2699 break;
2704 // adding/removing linked auras
2705 // add/remove the shapeshift aura's boosts
2706 HandleShapeshiftBoosts(apply);
2708 if(m_target->GetTypeId()==TYPEID_PLAYER)
2709 ((Player*)m_target)->InitDataForForm();
2712 void Aura::HandleAuraTransform(bool apply, bool Real)
2714 if (apply)
2716 // special case (spell specific functionality)
2717 if(m_modifier.m_miscvalue==0)
2719 // player applied only
2720 if(m_target->GetTypeId()!=TYPEID_PLAYER)
2721 return;
2723 switch(GetId())
2725 // Orb of Deception
2726 case 16739:
2728 uint32 orb_model = m_target->GetNativeDisplayId();
2729 switch(orb_model)
2731 // Troll Female
2732 case 1479: m_target->SetDisplayId(10134); break;
2733 // Troll Male
2734 case 1478: m_target->SetDisplayId(10135); break;
2735 // Tauren Male
2736 case 59: m_target->SetDisplayId(10136); break;
2737 // Human Male
2738 case 49: m_target->SetDisplayId(10137); break;
2739 // Human Female
2740 case 50: m_target->SetDisplayId(10138); break;
2741 // Orc Male
2742 case 51: m_target->SetDisplayId(10139); break;
2743 // Orc Female
2744 case 52: m_target->SetDisplayId(10140); break;
2745 // Dwarf Male
2746 case 53: m_target->SetDisplayId(10141); break;
2747 // Dwarf Female
2748 case 54: m_target->SetDisplayId(10142); break;
2749 // NightElf Male
2750 case 55: m_target->SetDisplayId(10143); break;
2751 // NightElf Female
2752 case 56: m_target->SetDisplayId(10144); break;
2753 // Undead Female
2754 case 58: m_target->SetDisplayId(10145); break;
2755 // Undead Male
2756 case 57: m_target->SetDisplayId(10146); break;
2757 // Tauren Female
2758 case 60: m_target->SetDisplayId(10147); break;
2759 // Gnome Male
2760 case 1563: m_target->SetDisplayId(10148); break;
2761 // Gnome Female
2762 case 1564: m_target->SetDisplayId(10149); break;
2763 // BloodElf Female
2764 case 15475: m_target->SetDisplayId(17830); break;
2765 // BloodElf Male
2766 case 15476: m_target->SetDisplayId(17829); break;
2767 // Dranei Female
2768 case 16126: m_target->SetDisplayId(17828); break;
2769 // Dranei Male
2770 case 16125: m_target->SetDisplayId(17827); break;
2771 default: break;
2773 break;
2775 // Murloc costume
2776 case 42365: m_target->SetDisplayId(21723); break;
2777 default: break;
2780 else
2782 CreatureInfo const * ci = objmgr.GetCreatureTemplate(m_modifier.m_miscvalue);
2783 if(!ci)
2785 //pig pink ^_^
2786 m_target->SetDisplayId(16358);
2787 sLog.outError("Auras: unknown creature id = %d (only need its modelid) Form Spell Aura Transform in Spell ID = %d", m_modifier.m_miscvalue, GetId());
2789 else
2791 // Will use the default model here
2792 m_target->SetDisplayId(ci->DisplayID_A);
2794 // Dragonmaw Illusion (set mount model also)
2795 if(GetId()==42016 && m_target->GetMountID() && !m_target->GetAurasByType(SPELL_AURA_MOD_INCREASE_FLIGHT_SPEED).empty())
2796 m_target->SetUInt32Value(UNIT_FIELD_MOUNTDISPLAYID,16314);
2798 m_target->setTransForm(GetId());
2801 // polymorph case
2802 if( Real && m_target->GetTypeId() == TYPEID_PLAYER && m_target->IsPolymorphed())
2804 // for players, start regeneration after 1s (in polymorph fast regeneration case)
2805 // only if caster is Player (after patch 2.4.2)
2806 if(IS_PLAYER_GUID(GetCasterGUID()) )
2807 ((Player*)m_target)->setRegenTimer(1000);
2809 //dismount polymorphed target (after patch 2.4.2)
2810 if (m_target->IsMounted())
2811 m_target->RemoveSpellsCausingAura(SPELL_AURA_MOUNTED);
2814 else
2816 Unit::AuraList const& otherTransforms = m_target->GetAurasByType(SPELL_AURA_TRANSFORM);
2817 if(otherTransforms.empty())
2819 m_target->SetDisplayId(m_target->GetNativeDisplayId());
2820 m_target->setTransForm(0);
2822 else
2824 // look for other transform auras
2825 Aura* handledAura = *otherTransforms.begin();
2826 for(Unit::AuraList::const_iterator i = otherTransforms.begin();i != otherTransforms.end(); ++i)
2828 // negative auras are preferred
2829 if(!IsPositiveSpell((*i)->GetSpellProto()->Id))
2831 handledAura = *i;
2832 break;
2835 handledAura->ApplyModifier(true);
2838 // Dragonmaw Illusion (restore mount model)
2839 if(GetId()==42016 && m_target->GetMountID()==16314)
2841 if(!m_target->GetAurasByType(SPELL_AURA_MOUNTED).empty())
2843 uint32 cr_id = m_target->GetAurasByType(SPELL_AURA_MOUNTED).front()->GetModifier()->m_miscvalue;
2844 if(CreatureInfo const* ci = objmgr.GetCreatureTemplate(cr_id))
2846 uint32 team = 0;
2847 if (m_target->GetTypeId()==TYPEID_PLAYER)
2848 team = ((Player*)m_target)->GetTeam();
2850 uint32 display_id = objmgr.ChooseDisplayId(team,ci);
2851 CreatureModelInfo const *minfo = objmgr.GetCreatureModelRandomGender(display_id);
2852 if (minfo)
2853 display_id = minfo->modelid;
2855 m_target->SetUInt32Value(UNIT_FIELD_MOUNTDISPLAYID,display_id);
2862 void Aura::HandleForceReaction(bool apply, bool Real)
2864 if(m_target->GetTypeId() != TYPEID_PLAYER)
2865 return;
2867 if(!Real)
2868 return;
2870 Player* player = (Player*)m_target;
2872 uint32 faction_id = m_modifier.m_miscvalue;
2873 uint32 faction_rank = m_modifier.m_amount;
2875 if(apply)
2876 player->m_forcedReactions[faction_id] = ReputationRank(faction_rank);
2877 else
2878 player->m_forcedReactions.erase(faction_id);
2880 WorldPacket data;
2881 data.Initialize(SMSG_SET_FORCED_REACTIONS, 4+player->m_forcedReactions.size()*(4+4));
2882 data << uint32(player->m_forcedReactions.size());
2883 for(ForcedReactions::const_iterator itr = player->m_forcedReactions.begin(); itr != player->m_forcedReactions.end(); ++itr)
2885 data << uint32(itr->first); // faction_id (Faction.dbc)
2886 data << uint32(itr->second); // reputation rank
2888 player->SendDirectMessage(&data);
2891 void Aura::HandleAuraModSkill(bool apply, bool Real)
2893 if(m_target->GetTypeId() != TYPEID_PLAYER)
2894 return;
2896 uint32 prot=GetSpellProto()->EffectMiscValue[m_effIndex];
2897 int32 points = GetModifier()->m_amount;
2899 ((Player*)m_target)->ModifySkillBonus(prot,(apply ? points: -points),m_modifier.m_auraname==SPELL_AURA_MOD_SKILL_TALENT);
2900 if(prot == SKILL_DEFENSE)
2901 ((Player*)m_target)->UpdateDefenseBonusesMod();
2904 void Aura::HandleChannelDeathItem(bool apply, bool Real)
2906 if(Real && !apply)
2908 Unit* caster = GetCaster();
2909 Unit* victim = GetTarget();
2910 if(!caster || caster->GetTypeId() != TYPEID_PLAYER || !victim || m_removeMode!=AURA_REMOVE_BY_DEATH)
2911 return;
2913 SpellEntry const *spellInfo = GetSpellProto();
2914 if(spellInfo->EffectItemType[m_effIndex] == 0)
2915 return;
2917 // Soul Shard only from non-grey units
2918 if( spellInfo->EffectItemType[m_effIndex] == 6265 &&
2919 (victim->getLevel() <= MaNGOS::XP::GetGrayLevel(caster->getLevel()) ||
2920 victim->GetTypeId()==TYPEID_UNIT && !((Player*)caster)->isAllowedToLoot((Creature*)victim)) )
2921 return;
2922 ItemPosCountVec dest;
2923 uint8 msg = ((Player*)caster)->CanStoreNewItem( NULL_BAG, NULL_SLOT, dest, spellInfo->EffectItemType[m_effIndex], 1 );
2924 if( msg != EQUIP_ERR_OK )
2926 ((Player*)caster)->SendEquipError( msg, NULL, NULL );
2927 return;
2930 Item* newitem = ((Player*)caster)->StoreNewItem(dest, spellInfo->EffectItemType[m_effIndex], true);
2931 ((Player*)caster)->SendNewItem(newitem, 1, true, false);
2935 void Aura::HandleBindSight(bool apply, bool Real)
2937 Unit* caster = GetCaster();
2938 if(!caster || caster->GetTypeId() != TYPEID_PLAYER)
2939 return;
2941 ((Player*)caster)->SetFarSight(apply ? m_target->GetGUID() : NULL);
2944 void Aura::HandleFarSight(bool apply, bool Real)
2946 Unit* caster = GetCaster();
2947 if(!caster || caster->GetTypeId() != TYPEID_PLAYER)
2948 return;
2950 ((Player*)caster)->SetFarSight(apply ? m_target->GetGUID() : NULL);
2953 void Aura::HandleAuraTrackCreatures(bool apply, bool Real)
2955 if(m_target->GetTypeId()!=TYPEID_PLAYER)
2956 return;
2958 if(apply)
2959 m_target->RemoveNoStackAurasDueToAura(this);
2960 m_target->SetUInt32Value(PLAYER_TRACK_CREATURES, apply ? ((uint32)1)<<(m_modifier.m_miscvalue-1) : 0 );
2963 void Aura::HandleAuraTrackResources(bool apply, bool Real)
2965 if(m_target->GetTypeId()!=TYPEID_PLAYER)
2966 return;
2968 if(apply)
2969 m_target->RemoveNoStackAurasDueToAura(this);
2970 m_target->SetUInt32Value(PLAYER_TRACK_RESOURCES, apply ? ((uint32)1)<<(m_modifier.m_miscvalue-1): 0 );
2973 void Aura::HandleAuraTrackStealthed(bool apply, bool Real)
2975 if(m_target->GetTypeId()!=TYPEID_PLAYER)
2976 return;
2978 if(apply)
2979 m_target->RemoveNoStackAurasDueToAura(this);
2981 m_target->ApplyModFlag(PLAYER_FIELD_BYTES,PLAYER_FIELD_BYTE_TRACK_STEALTHED,apply);
2984 void Aura::HandleAuraModScale(bool apply, bool Real)
2986 m_target->ApplyPercentModFloatValue(OBJECT_FIELD_SCALE_X,m_modifier.m_amount,apply);
2989 void Aura::HandleModPossess(bool apply, bool Real)
2991 if(!Real)
2992 return;
2994 if(m_target->getLevel() > m_modifier.m_amount)
2995 return;
2997 // not possess yourself
2998 if(GetCasterGUID() == m_target->GetGUID())
2999 return;
3001 Unit* caster = GetCaster();
3002 if(!caster)
3003 return;
3005 if( apply )
3007 m_target->SetCharmerGUID(GetCasterGUID());
3008 m_target->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE,caster->getFaction());
3009 caster->SetCharm(m_target);
3011 m_target->CombatStop();
3012 m_target->DeleteThreatList();
3013 if(m_target->GetTypeId() == TYPEID_UNIT)
3015 m_target->StopMoving();
3016 m_target->GetMotionMaster()->Clear();
3017 m_target->GetMotionMaster()->MoveIdle();
3018 CharmInfo *charmInfo = ((Creature*)m_target)->InitCharmInfo(m_target);
3019 charmInfo->InitPossessCreateSpells();
3022 if(caster->GetTypeId() == TYPEID_PLAYER)
3024 ((Player*)caster)->PossessSpellInitialize();
3027 else
3029 m_target->SetCharmerGUID(0);
3031 if(m_target->GetTypeId() == TYPEID_PLAYER)
3032 ((Player*)m_target)->setFactionForRace(m_target->getRace());
3033 else if(m_target->GetTypeId() == TYPEID_UNIT)
3035 CreatureInfo const *cinfo = ((Creature*)m_target)->GetCreatureInfo();
3036 m_target->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE,cinfo->faction_A);
3039 caster->SetCharm(0);
3041 if(caster->GetTypeId() == TYPEID_PLAYER)
3043 WorldPacket data(SMSG_PET_SPELLS, 8);
3044 data << uint64(0);
3045 data << uint32(0);
3046 ((Player*)caster)->GetSession()->SendPacket(&data);
3048 if(m_target->GetTypeId() == TYPEID_UNIT)
3050 ((Creature*)m_target)->AIM_Initialize();
3052 if (((Creature*)m_target)->AI())
3053 ((Creature*)m_target)->AI()->AttackStart(caster);
3056 if(caster->GetTypeId() == TYPEID_PLAYER)
3057 ((Player*)caster)->SetFarSight(apply ? m_target->GetGUID() : NULL);
3060 void Aura::HandleModPossessPet(bool apply, bool Real)
3062 if(!Real)
3063 return;
3065 Unit* caster = GetCaster();
3066 if(!caster || caster->GetTypeId() != TYPEID_PLAYER)
3067 return;
3069 Pet *pet = caster->GetPet();
3070 if(!pet || pet != m_target)
3071 return;
3073 if(apply)
3074 pet->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNKNOWN5);
3075 else
3076 pet->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNKNOWN5);
3078 ((Player*)caster)->SetFarSight(apply ? pet->GetGUID() : NULL);
3079 ((Player*)caster)->SetCharm(apply ? pet : NULL);
3080 ((Player*)caster)->SetClientControl(pet, apply ? 1 : 0);
3082 if(apply)
3084 pet->StopMoving();
3085 pet->GetMotionMaster()->Clear();
3086 pet->GetMotionMaster()->MoveIdle();
3088 else
3090 pet->AttackStop();
3091 pet->GetMotionMaster()->MoveFollow(caster, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE);
3092 pet->SetUnitMovementFlags(MOVEMENTFLAG_NONE);
3096 void Aura::HandleModCharm(bool apply, bool Real)
3098 if(!Real)
3099 return;
3101 // not charm yourself
3102 if(GetCasterGUID() == m_target->GetGUID())
3103 return;
3105 Unit* caster = GetCaster();
3106 if(!caster)
3107 return;
3109 if(int32(m_target->getLevel()) <= m_modifier.m_amount)
3111 if( apply )
3113 m_target->SetCharmerGUID(GetCasterGUID());
3114 m_target->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE,caster->getFaction());
3115 m_target->CastStop(m_target==caster ? GetId() : 0);
3116 caster->SetCharm(m_target);
3118 m_target->CombatStop();
3119 m_target->DeleteThreatList();
3121 if(m_target->GetTypeId() == TYPEID_UNIT)
3123 ((Creature*)m_target)->AIM_Initialize();
3124 CharmInfo *charmInfo = ((Creature*)m_target)->InitCharmInfo(m_target);
3125 charmInfo->InitCharmCreateSpells();
3126 charmInfo->SetReactState( REACT_DEFENSIVE );
3128 if(caster->GetTypeId() == TYPEID_PLAYER && caster->getClass() == CLASS_WARLOCK)
3130 CreatureInfo const *cinfo = ((Creature*)m_target)->GetCreatureInfo();
3131 if(cinfo && cinfo->type == CREATURE_TYPE_DEMON)
3133 //to prevent client crash
3134 m_target->SetFlag(UNIT_FIELD_BYTES_0, 2048);
3135 //just to enable stat window
3136 charmInfo->SetPetNumber(objmgr.GeneratePetNumber(), true);
3137 //if charmed two demons the same session, the 2nd gets the 1st one's name
3138 m_target->SetUInt32Value(UNIT_FIELD_PET_NAME_TIMESTAMP, time(NULL));
3143 if(caster->GetTypeId() == TYPEID_PLAYER)
3145 ((Player*)caster)->CharmSpellInitialize();
3148 else
3150 m_target->SetCharmerGUID(0);
3152 if(m_target->GetTypeId() == TYPEID_PLAYER)
3153 ((Player*)m_target)->setFactionForRace(m_target->getRace());
3154 else
3156 CreatureInfo const *cinfo = ((Creature*)m_target)->GetCreatureInfo();
3158 // restore faction
3159 if(((Creature*)m_target)->isPet())
3161 if(Unit* owner = m_target->GetOwner())
3162 m_target->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE,owner->getFaction());
3163 else if(cinfo)
3164 m_target->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE,cinfo->faction_A);
3166 else if(cinfo) // normal creature
3167 m_target->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE,cinfo->faction_A);
3169 // restore UNIT_FIELD_BYTES_0
3170 if(cinfo && caster->GetTypeId() == TYPEID_PLAYER && caster->getClass() == CLASS_WARLOCK && cinfo->type == CREATURE_TYPE_DEMON)
3172 CreatureDataAddon const *cainfo = ((Creature*)m_target)->GetCreatureAddon();
3173 if(cainfo && cainfo->bytes0 != 0)
3174 m_target->SetUInt32Value(UNIT_FIELD_BYTES_0, cainfo->bytes0);
3175 else
3176 m_target->RemoveFlag(UNIT_FIELD_BYTES_0, 2048);
3178 if(m_target->GetCharmInfo())
3179 m_target->GetCharmInfo()->SetPetNumber(0, true);
3180 else
3181 sLog.outError("Aura::HandleModCharm: target="I64FMTD" with typeid=%d has a charm aura but no charm info!", m_target->GetGUID(), m_target->GetTypeId());
3185 caster->SetCharm(0);
3187 if(caster->GetTypeId() == TYPEID_PLAYER)
3189 WorldPacket data(SMSG_PET_SPELLS, 8);
3190 data << uint64(0);
3191 data << uint32(0);
3192 ((Player*)caster)->GetSession()->SendPacket(&data);
3194 if(m_target->GetTypeId() == TYPEID_UNIT)
3196 ((Creature*)m_target)->AIM_Initialize();
3197 if (((Creature*)m_target)->AI())
3198 ((Creature*)m_target)->AI()->AttackStart(caster);
3204 void Aura::HandleModConfuse(bool apply, bool Real)
3206 if(!Real)
3207 return;
3209 m_target->SetConfused(apply, GetCasterGUID(), GetId());
3212 void Aura::HandleModFear(bool apply, bool Real)
3214 if (!Real)
3215 return;
3217 m_target->SetFeared(apply, GetCasterGUID(), GetId());
3220 void Aura::HandleFeignDeath(bool apply, bool Real)
3222 if(!Real)
3223 return;
3225 if(m_target->GetTypeId() != TYPEID_PLAYER)
3226 return;
3228 if( apply )
3231 WorldPacket data(SMSG_FEIGN_DEATH_RESISTED, 9);
3232 data<<m_target->GetGUID();
3233 data<<uint8(0);
3234 m_target->SendMessageToSet(&data,true);
3236 // blizz like 2.0.x
3237 m_target->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNKNOWN6);
3238 // blizz like 2.0.x
3239 m_target->SetFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_FEIGN_DEATH);
3240 // blizz like 2.0.x
3241 m_target->SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_DEAD);
3243 m_target->addUnitState(UNIT_STAT_DIED);
3244 m_target->CombatStop();
3246 // prevent interrupt message
3247 if(m_caster_guid==m_target->GetGUID() && m_target->m_currentSpells[CURRENT_GENERIC_SPELL])
3248 m_target->m_currentSpells[CURRENT_GENERIC_SPELL]->finish();
3249 m_target->InterruptNonMeleeSpells(true);
3250 m_target->getHostilRefManager().deleteReferences();
3252 else
3255 WorldPacket data(SMSG_FEIGN_DEATH_RESISTED, 9);
3256 data<<m_target->GetGUID();
3257 data<<uint8(1);
3258 m_target->SendMessageToSet(&data,true);
3260 // blizz like 2.0.x
3261 m_target->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNKNOWN6);
3262 // blizz like 2.0.x
3263 m_target->RemoveFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_FEIGN_DEATH);
3264 // blizz like 2.0.x
3265 m_target->RemoveFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_DEAD);
3267 m_target->clearUnitState(UNIT_STAT_DIED);
3271 void Aura::HandleAuraModDisarm(bool apply, bool Real)
3273 if(!Real)
3274 return;
3276 if(!apply && m_target->HasAuraType(SPELL_AURA_MOD_DISARM))
3277 return;
3279 // not sure for it's correctness
3280 if(apply)
3281 m_target->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISARMED);
3282 else
3283 m_target->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISARMED);
3285 // only at real add/remove aura
3286 if (m_target->GetTypeId() != TYPEID_PLAYER)
3287 return;
3289 // main-hand attack speed already set to special value for feral form already and don't must change and reset at remove.
3290 if (((Player *)m_target)->IsInFeralForm())
3291 return;
3293 if (apply)
3294 m_target->SetAttackTime(BASE_ATTACK,BASE_ATTACK_TIME);
3295 else
3296 ((Player *)m_target)->SetRegularAttackTime();
3298 m_target->UpdateDamagePhysical(BASE_ATTACK);
3301 void Aura::HandleAuraModStun(bool apply, bool Real)
3303 if(!Real)
3304 return;
3306 if (apply)
3308 m_target->addUnitState(UNIT_STAT_STUNNED);
3309 m_target->SetUInt64Value(UNIT_FIELD_TARGET, 0);
3311 m_target->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED);
3312 m_target->CastStop(m_target->GetGUID() == GetCasterGUID() ? GetId() : 0);
3314 // Creature specific
3315 if(m_target->GetTypeId() != TYPEID_PLAYER)
3316 ((Creature*)m_target)->StopMoving();
3317 else
3318 m_target->SetUnitMovementFlags(0); //Clear movement flags
3320 WorldPacket data(SMSG_FORCE_MOVE_ROOT, 8);
3322 data.append(m_target->GetPackGUID());
3323 data << uint32(0);
3324 m_target->SendMessageToSet(&data,true);
3326 else
3328 // Real remove called after current aura remove from lists, check if other similar auras active
3329 if(m_target->HasAuraType(SPELL_AURA_MOD_STUN))
3330 return;
3332 m_target->clearUnitState(UNIT_STAT_STUNNED);
3333 m_target->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED);
3335 if(!m_target->hasUnitState(UNIT_STAT_ROOT)) // prevent allow move if have also root effect
3337 if(m_target->getVictim() && m_target->isAlive())
3338 m_target->SetUInt64Value(UNIT_FIELD_TARGET,m_target->getVictim()->GetGUID() );
3340 WorldPacket data(SMSG_FORCE_MOVE_UNROOT, 8+4);
3341 data.append(m_target->GetPackGUID());
3342 data << uint32(0);
3343 m_target->SendMessageToSet(&data,true);
3346 // Wyvern Sting
3347 if (GetSpellProto()->SpellFamilyName == SPELLFAMILY_HUNTER && GetSpellProto()->SpellIconID == 1721)
3349 Unit* caster = GetCaster();
3350 if( !caster || caster->GetTypeId()!=TYPEID_PLAYER )
3351 return;
3353 uint32 spell_id = 0;
3355 switch(GetId())
3357 case 19386: spell_id = 24131; break;
3358 case 24132: spell_id = 24134; break;
3359 case 24133: spell_id = 24135; break;
3360 case 27068: spell_id = 27069; break;
3361 default:
3362 sLog.outError("Spell selection called for unexpected original spell %u, new spell for this spell family?",GetId());
3363 return;
3366 SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell_id);
3368 if(!spellInfo)
3369 return;
3371 caster->CastSpell(m_target,spellInfo,true,NULL,this);
3372 return;
3377 void Aura::HandleModStealth(bool apply, bool Real)
3379 if(apply)
3381 // drop flag at stealth in bg
3382 if(Real && m_target->GetTypeId()==TYPEID_PLAYER && ((Player*)m_target)->InBattleGround())
3383 if(BattleGround *bg = ((Player*)m_target)->GetBattleGround())
3384 bg->EventPlayerDroppedFlag((Player*)m_target);
3386 // only at real aura add
3387 if(Real)
3389 m_target->SetByteValue(UNIT_FIELD_BYTES_1, 2, 0x02);
3390 if(m_target->GetTypeId()==TYPEID_PLAYER)
3391 m_target->SetFlag(PLAYER_FIELD_BYTES2, 0x2000);
3393 // apply only if not in GM invisibility (and overwrite invisibility state)
3394 if(m_target->GetVisibility()!=VISIBILITY_OFF)
3396 m_target->SetVisibility(VISIBILITY_GROUP_NO_DETECT);
3397 m_target->SetVisibility(VISIBILITY_GROUP_STEALTH);
3400 // for RACE_NIGHTELF stealth
3401 if(m_target->GetTypeId()==TYPEID_PLAYER && GetId()==20580)
3402 m_target->CastSpell(m_target, 21009, true, NULL, this);
3405 else
3407 // only at real aura remove
3408 if(Real)
3410 // for RACE_NIGHTELF stealth
3411 if(m_target->GetTypeId()==TYPEID_PLAYER && GetId()==20580)
3412 m_target->RemoveAurasDueToSpell(21009);
3414 // if last SPELL_AURA_MOD_STEALTH and no GM invisibility
3415 if(!m_target->HasAuraType(SPELL_AURA_MOD_STEALTH) && m_target->GetVisibility()!=VISIBILITY_OFF)
3417 m_target->SetByteValue(UNIT_FIELD_BYTES_1, 2, 0x00);
3418 if(m_target->GetTypeId()==TYPEID_PLAYER)
3419 m_target->RemoveFlag(PLAYER_FIELD_BYTES2, 0x2000);
3421 // restore invisibility if any
3422 if(m_target->HasAuraType(SPELL_AURA_MOD_INVISIBILITY))
3424 m_target->SetVisibility(VISIBILITY_GROUP_NO_DETECT);
3425 m_target->SetVisibility(VISIBILITY_GROUP_INVISIBILITY);
3427 else
3428 m_target->SetVisibility(VISIBILITY_ON);
3433 // Master of Subtlety
3434 Unit::AuraList const& mDummyAuras = m_target->GetAurasByType(SPELL_AURA_DUMMY);
3435 for(Unit::AuraList::const_iterator i = mDummyAuras.begin();i != mDummyAuras.end(); ++i)
3437 if ((*i)->GetSpellProto()->SpellIconID == 2114)
3439 if (apply)
3441 int32 bp = (*i)->GetModifier()->m_amount;
3442 m_target->CastCustomSpell(m_target,31665,&bp,NULL,NULL,true);
3444 else
3445 m_target->CastSpell(m_target,31666,true);
3446 break;
3451 void Aura::HandleInvisibility(bool apply, bool Real)
3453 if(apply)
3455 m_target->m_invisibilityMask |= (1 << m_modifier.m_miscvalue);
3457 if(Real && m_target->GetTypeId()==TYPEID_PLAYER)
3459 // apply glow vision
3460 m_target->SetFlag(PLAYER_FIELD_BYTES2,PLAYER_FIELD_BYTE2_INVISIBILITY_GLOW);
3462 // drop flag at invisible in bg
3463 if(((Player*)m_target)->InBattleGround())
3464 if(BattleGround *bg = ((Player*)m_target)->GetBattleGround())
3465 bg->EventPlayerDroppedFlag((Player*)m_target);
3468 // apply only if not in GM invisibility and not stealth
3469 if(m_target->GetVisibility()==VISIBILITY_ON)
3471 // Aura not added yet but visibility code expect temporary add aura
3472 m_target->SetVisibility(VISIBILITY_GROUP_NO_DETECT);
3473 m_target->SetVisibility(VISIBILITY_GROUP_INVISIBILITY);
3476 else
3478 // recalculate value at modifier remove (current aura already removed)
3479 m_target->m_invisibilityMask = 0;
3480 Unit::AuraList const& auras = m_target->GetAurasByType(SPELL_AURA_MOD_INVISIBILITY);
3481 for(Unit::AuraList::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
3482 m_target->m_invisibilityMask |= (1 << m_modifier.m_miscvalue);
3484 // only at real aura remove and if not have different invisibility auras.
3485 if(Real && m_target->m_invisibilityMask==0)
3487 // remove glow vision
3488 if(m_target->GetTypeId() == TYPEID_PLAYER)
3489 m_target->RemoveFlag(PLAYER_FIELD_BYTES2,PLAYER_FIELD_BYTE2_INVISIBILITY_GLOW);
3491 // apply only if not in GM invisibility & not stealthed while invisible
3492 if(m_target->GetVisibility()!=VISIBILITY_OFF)
3494 // if have stealth aura then already have stealth visibility
3495 if(!m_target->HasAuraType(SPELL_AURA_MOD_STEALTH))
3496 m_target->SetVisibility(VISIBILITY_ON);
3502 void Aura::HandleInvisibilityDetect(bool apply, bool Real)
3504 if(apply)
3506 m_target->m_detectInvisibilityMask |= (1 << m_modifier.m_miscvalue);
3508 else
3510 // recalculate value at modifier remove (current aura already removed)
3511 m_target->m_detectInvisibilityMask = 0;
3512 Unit::AuraList const& auras = m_target->GetAurasByType(SPELL_AURA_MOD_INVISIBILITY_DETECTION);
3513 for(Unit::AuraList::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
3514 m_target->m_detectInvisibilityMask |= (1 << m_modifier.m_miscvalue);
3516 if(Real && m_target->GetTypeId()==TYPEID_PLAYER)
3517 ObjectAccessor::UpdateVisibilityForPlayer((Player*)m_target);
3520 void Aura::HandleAuraModRoot(bool apply, bool Real)
3522 // only at real add/remove aura
3523 if(!Real)
3524 return;
3526 uint32 apply_stat = UNIT_STAT_ROOT;
3527 if (apply)
3529 m_target->addUnitState(UNIT_STAT_ROOT);
3530 m_target->SetUInt64Value (UNIT_FIELD_TARGET, 0);
3531 // probably wrong
3532 m_target->SetFlag(UNIT_FIELD_FLAGS,(apply_stat<<16));
3534 //Save last orientation
3535 if( m_target->getVictim() )
3536 m_target->SetOrientation(m_target->GetAngle(m_target->getVictim()));
3538 if(m_target->GetTypeId() == TYPEID_PLAYER)
3540 WorldPacket data(SMSG_FORCE_MOVE_ROOT, 10);
3541 data.append(m_target->GetPackGUID());
3542 data << (uint32)2;
3543 m_target->SendMessageToSet(&data,true);
3545 //Clear unit movement flags
3546 m_target->SetUnitMovementFlags(0);
3548 else
3549 ((Creature *)m_target)->StopMoving();
3551 else
3553 // Real remove called after current aura remove from lists, check if other similar auras active
3554 if(m_target->HasAuraType(SPELL_AURA_MOD_ROOT))
3555 return;
3557 m_target->clearUnitState(UNIT_STAT_ROOT);
3558 // probably wrong
3559 m_target->RemoveFlag(UNIT_FIELD_FLAGS,(apply_stat<<16));
3561 if(!m_target->hasUnitState(UNIT_STAT_STUNNED)) // prevent allow move if have also stun effect
3563 if(m_target->getVictim() && m_target->isAlive())
3564 m_target->SetUInt64Value (UNIT_FIELD_TARGET,m_target->getVictim()->GetGUID() );
3566 if(m_target->GetTypeId() == TYPEID_PLAYER)
3568 WorldPacket data(SMSG_FORCE_MOVE_UNROOT, 10);
3569 data.append(m_target->GetPackGUID());
3570 data << (uint32)2;
3571 m_target->SendMessageToSet(&data,true);
3577 void Aura::HandleAuraModSilence(bool apply, bool Real)
3579 // only at real add/remove aura
3580 if(!Real)
3581 return;
3583 if(apply)
3585 m_target->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SILENCED);
3586 // Stop cast only spells vs PreventionType == SPELL_PREVENTION_TYPE_SILENCE
3587 for (uint32 i = CURRENT_MELEE_SPELL; i < CURRENT_MAX_SPELL;i++)
3589 Spell* currentSpell = m_target->m_currentSpells[i];
3590 if (currentSpell && currentSpell->m_spellInfo->PreventionType == SPELL_PREVENTION_TYPE_SILENCE)
3592 uint32 state = currentSpell->getState();
3593 // Stop spells on prepare or casting state
3594 if ( state == SPELL_STATE_PREPARING || state == SPELL_STATE_CASTING )
3596 currentSpell->cancel();
3597 currentSpell->SetReferencedFromCurrent(false);
3598 m_target->m_currentSpells[i] = NULL;
3603 switch (GetId())
3605 // Arcane Torrent (Energy)
3606 case 25046:
3608 Unit * caster = GetCaster();
3609 if (!caster)
3610 return;
3612 // Search Mana Tap auras on caster
3613 int32 energy = 0;
3614 Unit::AuraList const& m_dummyAuras = caster->GetAurasByType(SPELL_AURA_DUMMY);
3615 for(Unit::AuraList::const_iterator i = m_dummyAuras.begin(); i != m_dummyAuras.end(); ++i)
3616 if ((*i)->GetId() == 28734)
3617 ++energy;
3618 if (energy)
3620 energy *= 10;
3621 caster->CastCustomSpell(caster, 25048, &energy, NULL, NULL, true);
3622 caster->RemoveAurasDueToSpell(28734);
3627 else
3629 // Real remove called after current aura remove from lists, check if other similar auras active
3630 if(m_target->HasAuraType(SPELL_AURA_MOD_SILENCE))
3631 return;
3633 m_target->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SILENCED);
3637 void Aura::HandleModThreat(bool apply, bool Real)
3639 // only at real add/remove aura
3640 if(!Real)
3641 return;
3643 if(!m_target->isAlive())
3644 return;
3646 Unit* caster = GetCaster();
3648 if(!caster || !caster->isAlive())
3649 return;
3651 int level_diff = 0;
3652 int multiplier = 0;
3653 switch (GetId())
3655 // Arcane Shroud
3656 case 26400:
3657 level_diff = m_target->getLevel() - 60;
3658 multiplier = 2;
3659 break;
3660 // The Eye of Diminution
3661 case 28862:
3662 level_diff = m_target->getLevel() - 60;
3663 multiplier = 1;
3664 break;
3666 if (level_diff > 0)
3667 m_modifier.m_amount += multiplier * level_diff;
3669 for(int8 x=0;x < MAX_SPELL_SCHOOL;x++)
3671 if(m_modifier.m_miscvalue & int32(1<<x))
3673 if(m_target->GetTypeId() == TYPEID_PLAYER)
3674 ApplyPercentModFloatVar(m_target->m_threatModifier[x], m_positive ? m_modifier.m_amount : -m_modifier.m_amount, apply);
3679 void Aura::HandleAuraModTotalThreat(bool apply, bool Real)
3681 // only at real add/remove aura
3682 if(!Real)
3683 return;
3685 if(!m_target->isAlive() || m_target->GetTypeId()!= TYPEID_PLAYER)
3686 return;
3688 Unit* caster = GetCaster();
3690 if(!caster || !caster->isAlive())
3691 return;
3693 float threatMod = 0.0f;
3694 if(apply)
3695 threatMod = float(m_modifier.m_amount);
3696 else
3697 threatMod = float(-m_modifier.m_amount);
3699 m_target->getHostilRefManager().threatAssist(caster, threatMod);
3702 void Aura::HandleModTaunt(bool apply, bool Real)
3704 // only at real add/remove aura
3705 if(!Real)
3706 return;
3708 if(!m_target->isAlive() || !m_target->CanHaveThreatList())
3709 return;
3711 Unit* caster = GetCaster();
3713 if(!caster || !caster->isAlive() || caster->GetTypeId() != TYPEID_PLAYER)
3714 return;
3716 if(apply)
3717 m_target->TauntApply(caster);
3718 else
3720 // When taunt aura fades out, mob will switch to previous target if current has less than 1.1 * secondthreat
3721 m_target->TauntFadeOut(caster);
3725 /*********************************************************/
3726 /*** MODIFY SPEED ***/
3727 /*********************************************************/
3728 void Aura::HandleAuraModIncreaseSpeed(bool /*apply*/, bool Real)
3730 // all applied/removed only at real aura add/remove
3731 if(!Real)
3732 return;
3734 m_target->UpdateSpeed(MOVE_RUN, true);
3737 void Aura::HandleAuraModIncreaseMountedSpeed(bool /*apply*/, bool Real)
3739 // all applied/removed only at real aura add/remove
3740 if(!Real)
3741 return;
3743 m_target->UpdateSpeed(MOVE_RUN, true);
3746 void Aura::HandleAuraModIncreaseFlightSpeed(bool apply, bool Real)
3748 // all applied/removed only at real aura add/remove
3749 if(!Real)
3750 return;
3752 // Enable Fly mode for flying mounts
3753 if (m_modifier.m_auraname == SPELL_AURA_MOD_INCREASE_FLIGHT_SPEED)
3755 WorldPacket data;
3756 if(apply)
3757 data.Initialize(SMSG_MOVE_SET_CAN_FLY, 12);
3758 else
3759 data.Initialize(SMSG_MOVE_UNSET_CAN_FLY, 12);
3760 data.append(m_target->GetPackGUID());
3761 data << uint32(0); // unknown
3762 m_target->SendMessageToSet(&data, true);
3764 //Players on flying mounts must be immune to polymorph
3765 if (m_target->GetTypeId()==TYPEID_PLAYER)
3766 m_target->ApplySpellImmune(GetId(),IMMUNITY_MECHANIC,MECHANIC_POLYMORPH,apply);
3768 // Dragonmaw Illusion (overwrite mount model, mounted aura already applied)
3769 if( apply && m_target->HasAura(42016,0) && m_target->GetMountID())
3770 m_target->SetUInt32Value(UNIT_FIELD_MOUNTDISPLAYID,16314);
3773 m_target->UpdateSpeed(MOVE_FLIGHT, true);
3776 void Aura::HandleAuraModIncreaseSwimSpeed(bool /*apply*/, bool Real)
3778 // all applied/removed only at real aura add/remove
3779 if(!Real)
3780 return;
3782 m_target->UpdateSpeed(MOVE_SWIM, true);
3785 void Aura::HandleAuraModDecreaseSpeed(bool /*apply*/, bool Real)
3787 // all applied/removed only at real aura add/remove
3788 if(!Real)
3789 return;
3791 m_target->UpdateSpeed(MOVE_RUN, true);
3792 m_target->UpdateSpeed(MOVE_SWIM, true);
3793 m_target->UpdateSpeed(MOVE_FLIGHT, true);
3796 void Aura::HandleAuraModUseNormalSpeed(bool /*apply*/, bool Real)
3798 // all applied/removed only at real aura add/remove
3799 if(!Real)
3800 return;
3802 m_target->UpdateSpeed(MOVE_RUN, true);
3803 m_target->UpdateSpeed(MOVE_SWIM, true);
3804 m_target->UpdateSpeed(MOVE_FLIGHT, true);
3807 /*********************************************************/
3808 /*** IMMUNITY ***/
3809 /*********************************************************/
3811 void Aura::HandleModMechanicImmunity(bool apply, bool Real)
3813 uint32 mechanic = 1 << m_modifier.m_miscvalue;
3815 //immune movement impairment and loss of control
3816 if(GetId()==42292)
3817 mechanic=IMMUNE_TO_MOVEMENT_IMPAIRMENT_AND_LOSS_CONTROL_MASK;
3819 if(apply && GetSpellProto()->AttributesEx & SPELL_ATTR_EX_DISPEL_AURAS_ON_IMMUNITY)
3821 Unit::AuraMap& Auras = m_target->GetAuras();
3822 for(Unit::AuraMap::iterator iter = Auras.begin(), next; iter != Auras.end(); iter = next)
3824 next = iter;
3825 ++next;
3826 SpellEntry const *spell = iter->second->GetSpellProto();
3827 if (!( spell->Attributes & SPELL_ATTR_UNAFFECTED_BY_INVULNERABILITY) // spells unaffected by invulnerability
3828 && !iter->second->IsPositive() // only remove negative spells
3829 && spell->Id != GetId())
3831 //check for mechanic mask
3832 if(GetSpellMechanicMask(spell, iter->second->GetEffIndex()) & mechanic)
3834 m_target->RemoveAurasDueToSpell(spell->Id);
3835 if(Auras.empty())
3836 break;
3837 else
3838 next = Auras.begin();
3844 m_target->ApplySpellImmune(GetId(),IMMUNITY_MECHANIC,m_modifier.m_miscvalue,apply);
3846 // special cases
3847 switch(m_modifier.m_miscvalue)
3849 case MECHANIC_INVULNERABILITY:
3850 m_target->ModifyAuraState(AURA_STATE_FORBEARANCE,apply);
3851 break;
3852 case MECHANIC_SHIELD:
3853 m_target->ModifyAuraState(AURA_STATE_WEAKENED_SOUL,apply);
3854 break;
3857 // Bestial Wrath
3858 if ( GetSpellProto()->SpellFamilyName == SPELLFAMILY_HUNTER && GetSpellProto()->SpellIconID == 1680)
3860 // The Beast Within cast on owner if talent present
3861 if ( Unit* owner = m_target->GetOwner() )
3863 // Search talent
3864 Unit::AuraList const& m_dummyAuras = owner->GetAurasByType(SPELL_AURA_DUMMY);
3865 for(Unit::AuraList::const_iterator i = m_dummyAuras.begin(); i != m_dummyAuras.end(); ++i)
3867 if ( (*i)->GetSpellProto()->SpellIconID == 2229 )
3869 if (apply)
3870 owner->CastSpell(owner, 34471, true, 0, this);
3871 else
3872 owner->RemoveAurasDueToSpell(34471);
3873 break;
3879 // The Beast Within and Bestial Wrath - immunity
3880 if(GetId() == 19574 || GetId() == 34471)
3882 if(apply)
3884 m_target->CastSpell(m_target,24395,true);
3885 m_target->CastSpell(m_target,24396,true);
3886 m_target->CastSpell(m_target,24397,true);
3887 m_target->CastSpell(m_target,26592,true);
3889 else
3891 m_target->RemoveAurasDueToSpell(24395);
3892 m_target->RemoveAurasDueToSpell(24396);
3893 m_target->RemoveAurasDueToSpell(24397);
3894 m_target->RemoveAurasDueToSpell(26592);
3899 void Aura::HandleAuraModEffectImmunity(bool apply, bool Real)
3901 if(!apply)
3903 if(m_target->GetTypeId() == TYPEID_PLAYER)
3905 if(((Player*)m_target)->InBattleGround())
3907 BattleGround *bg = ((Player*)m_target)->GetBattleGround();
3908 if(bg)
3910 switch(bg->GetTypeID())
3912 case BATTLEGROUND_AV:
3914 break;
3916 case BATTLEGROUND_WS:
3918 // Warsong Flag, horde // Silverwing Flag, alliance
3919 if(GetId() == 23333 || GetId() == 23335)
3920 bg->EventPlayerDroppedFlag(((Player*)m_target));
3921 break;
3923 case BATTLEGROUND_AB:
3925 break;
3927 case BATTLEGROUND_EY:
3929 if(GetId() == 34976)
3930 bg->EventPlayerDroppedFlag(((Player*)m_target));
3931 break;
3939 m_target->ApplySpellImmune(GetId(),IMMUNITY_EFFECT,m_modifier.m_miscvalue,apply);
3942 void Aura::HandleAuraModStateImmunity(bool apply, bool Real)
3944 if(apply && Real && GetSpellProto()->AttributesEx & SPELL_ATTR_EX_DISPEL_AURAS_ON_IMMUNITY)
3946 Unit::AuraList const& auraList = m_target->GetAurasByType(AuraType(m_modifier.m_miscvalue));
3947 for(Unit::AuraList::const_iterator itr = auraList.begin(); itr != auraList.end();)
3949 if (auraList.front() != this) // skip itself aura (it already added)
3951 m_target->RemoveAurasDueToSpell(auraList.front()->GetId());
3952 itr = auraList.begin();
3954 else
3955 ++itr;
3959 m_target->ApplySpellImmune(GetId(),IMMUNITY_STATE,m_modifier.m_miscvalue,apply);
3962 void Aura::HandleAuraModSchoolImmunity(bool apply, bool Real)
3964 m_target->ApplySpellImmune(GetId(),IMMUNITY_SCHOOL,m_modifier.m_miscvalue,apply);
3966 if(Real && apply && GetSpellProto()->AttributesEx & SPELL_ATTR_EX_DISPEL_AURAS_ON_IMMUNITY)
3968 if(IsPositiveSpell(GetId())) //Only positive immunity removes auras
3970 uint32 school_mask = m_modifier.m_miscvalue;
3971 Unit::AuraMap& Auras = m_target->GetAuras();
3972 for(Unit::AuraMap::iterator iter = Auras.begin(), next; iter != Auras.end(); iter = next)
3974 next = iter;
3975 ++next;
3976 SpellEntry const *spell = iter->second->GetSpellProto();
3977 if((GetSpellSchoolMask(spell) & school_mask)//Check for school mask
3978 && !( spell->Attributes & SPELL_ATTR_UNAFFECTED_BY_INVULNERABILITY) //Spells unaffected by invulnerability
3979 && !iter->second->IsPositive() //Don't remove positive spells
3980 && spell->Id != GetId() ) //Don't remove self
3982 m_target->RemoveAurasDueToSpell(spell->Id);
3983 if(Auras.empty())
3984 break;
3985 else
3986 next = Auras.begin();
3991 if( Real && GetSpellProto()->Mechanic == MECHANIC_BANISH )
3993 if( apply )
3994 m_target->addUnitState(UNIT_STAT_ISOLATED);
3995 else
3996 m_target->clearUnitState(UNIT_STAT_ISOLATED);
4000 void Aura::HandleAuraModDmgImmunity(bool apply, bool Real)
4002 m_target->ApplySpellImmune(GetId(),IMMUNITY_DAMAGE,m_modifier.m_miscvalue,apply);
4005 void Aura::HandleAuraModDispelImmunity(bool apply, bool Real)
4007 // all applied/removed only at real aura add/remove
4008 if(!Real)
4009 return;
4011 m_target->ApplySpellDispelImmunity(m_spellProto, DispelType(m_modifier.m_miscvalue), apply);
4014 void Aura::HandleAuraProcTriggerSpell(bool apply, bool Real)
4016 if(!Real)
4017 return;
4019 if(apply)
4021 // some spell have charges by functionality not have its in spell data
4022 switch (GetId())
4024 case 28200: // Ascendance (Talisman of Ascendance trinket)
4025 m_procCharges = 6;
4026 UpdateAuraCharges();
4027 break;
4028 default: break;
4033 void Aura::HandleAuraModStalked(bool apply, bool Real)
4035 // used by spells: Hunter's Mark, Mind Vision, Syndicate Tracker (MURP) DND
4036 if(apply)
4037 m_target->SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_TRACK_UNIT);
4038 else
4039 m_target->RemoveFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_TRACK_UNIT);
4042 /*********************************************************/
4043 /*** PERIODIC ***/
4044 /*********************************************************/
4046 void Aura::HandlePeriodicTriggerSpell(bool apply, bool Real)
4048 if (m_periodicTimer <= 0)
4049 m_periodicTimer += m_modifier.periodictime;
4051 m_isPeriodic = apply;
4052 m_isTrigger = apply;
4054 // Curse of the Plaguebringer
4055 if (!apply && m_spellProto->Id == 29213 && m_removeMode!=AURA_REMOVE_BY_DISPEL)
4057 // Cast Wrath of the Plaguebringer if not dispelled
4058 m_target->CastSpell(m_target, 29214, true, 0, this);
4062 void Aura::HandlePeriodicEnergize(bool apply, bool Real)
4064 if (m_periodicTimer <= 0)
4065 m_periodicTimer += m_modifier.periodictime;
4067 m_isPeriodic = apply;
4070 void Aura::HandlePeriodicHeal(bool apply, bool Real)
4072 if (m_periodicTimer <= 0)
4073 m_periodicTimer += m_modifier.periodictime;
4075 m_isPeriodic = apply;
4077 // only at real apply
4078 if (Real && apply && GetSpellProto()->Mechanic == MECHANIC_BANDAGE)
4080 // provided m_target as original caster to prevent apply aura caster selection for this negative buff
4081 m_target->CastSpell(m_target,11196,true,NULL,this,m_target->GetGUID());
4084 // For prevent double apply bonuses
4085 bool loading = (m_target->GetTypeId() == TYPEID_PLAYER && ((Player*)m_target)->GetSession()->PlayerLoading());
4087 if(!loading && apply)
4089 switch (m_spellProto->SpellFamilyName)
4091 case SPELLFAMILY_DRUID:
4093 // Rejuvenation
4094 if(m_spellProto->SpellFamilyFlags & 0x0000000000000010LL)
4096 if(Unit* caster = GetCaster())
4098 Unit::AuraList const& classScripts = caster->GetAurasByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS);
4099 for(Unit::AuraList::const_iterator k = classScripts.begin(); k != classScripts.end(); ++k)
4101 int32 tickcount = GetSpellDuration(m_spellProto) / m_spellProto->EffectAmplitude[m_effIndex];
4102 switch((*k)->GetModifier()->m_miscvalue)
4104 case 4953: // Increased Rejuvenation Healing - Harold's Rejuvenating Broach Aura
4105 case 4415: // Increased Rejuvenation Healing - Idol of Rejuvenation Aura
4107 m_modifier.m_amount += (*k)->GetModifier()->m_amount / tickcount;
4108 break;
4119 void Aura::HandlePeriodicDamage(bool apply, bool Real)
4121 // spells required only Real aura add/remove
4122 if(!Real)
4123 return;
4125 if (m_periodicTimer <= 0)
4126 m_periodicTimer += m_modifier.periodictime;
4128 m_isPeriodic = apply;
4130 // For prevent double apply bonuses
4131 bool loading = (m_target->GetTypeId() == TYPEID_PLAYER && ((Player*)m_target)->GetSession()->PlayerLoading());
4133 Unit *caster = GetCaster();
4135 switch (m_spellProto->SpellFamilyName)
4137 case SPELLFAMILY_GENERIC:
4139 // Pounce Bleed
4140 if ( m_spellProto->SpellIconID == 147 && m_spellProto->SpellVisual == 0 )
4142 // $AP*0.18/6 bonus per tick
4143 if (apply && !loading && caster)
4144 m_modifier.m_amount += int32(caster->GetTotalAttackPowerValue(BASE_ATTACK) * 3 / 100);
4145 return;
4147 break;
4149 case SPELLFAMILY_WARRIOR:
4151 // Rend
4152 if (m_spellProto->SpellFamilyFlags & 0x0000000000000020LL)
4154 // 0.00743*(($MWB+$mwb)/2+$AP/14*$MWS) bonus per tick
4155 if (apply && !loading && caster)
4157 float ap = caster->GetTotalAttackPowerValue(BASE_ATTACK);
4158 int32 mws = caster->GetAttackTime(BASE_ATTACK);
4159 float mwb_min = caster->GetWeaponDamageRange(BASE_ATTACK,MINDAMAGE);
4160 float mwb_max = caster->GetWeaponDamageRange(BASE_ATTACK,MAXDAMAGE);
4161 // WARNING! in 3.0 multiplier 0.00743f change to 0.6
4162 m_modifier.m_amount+=int32(((mwb_min+mwb_max)/2+ap*mws/14000)*0.00743f);
4164 return;
4166 break;
4168 case SPELLFAMILY_DRUID:
4170 // Rake
4171 if (m_spellProto->SpellFamilyFlags & 0x0000000000001000LL)
4173 // $AP*0.06/3 bonus per tick
4174 if (apply && !loading && caster)
4175 m_modifier.m_amount += int32(caster->GetTotalAttackPowerValue(BASE_ATTACK) * 2 / 100);
4176 return;
4178 // Lacerate
4179 if (m_spellProto->SpellFamilyFlags & 0x000000010000000000LL)
4181 // $AP*0.05/5 bonus per tick
4182 if (apply && !loading && caster)
4183 m_modifier.m_amount += int32(caster->GetTotalAttackPowerValue(BASE_ATTACK) / 100);
4184 return;
4186 // Rip
4187 if (m_spellProto->SpellFamilyFlags & 0x000000000000800000LL)
4189 // $AP * min(0.06*$cp, 0.24)/6 [Yes, there is no difference, whether 4 or 5 CPs are being used]
4190 if (apply && !loading && caster && caster->GetTypeId() == TYPEID_PLAYER)
4192 uint8 cp = ((Player*)caster)->GetComboPoints();
4194 // Idol of Feral Shadows. Cant be handled as SpellMod in SpellAura:Dummy due its dependency from CPs
4195 Unit::AuraList const& dummyAuras = caster->GetAurasByType(SPELL_AURA_DUMMY);
4196 for(Unit::AuraList::const_iterator itr = dummyAuras.begin(); itr != dummyAuras.end(); ++itr)
4198 if((*itr)->GetId()==34241)
4200 m_modifier.m_amount += cp * (*itr)->GetModifier()->m_amount;
4201 break;
4205 if (cp > 4) cp = 4;
4206 m_modifier.m_amount += int32(caster->GetTotalAttackPowerValue(BASE_ATTACK) * cp / 100);
4208 return;
4210 break;
4212 case SPELLFAMILY_ROGUE:
4214 // Deadly poison aura state
4215 if((m_spellProto->SpellFamilyFlags & 0x10000) && m_spellProto->SpellVisual[0]==5100)
4217 if(apply)
4218 m_target->ModifyAuraState(AURA_STATE_DEADLY_POISON,true);
4219 else
4221 // current aura already removed, search present of another
4222 bool found = false;
4223 Unit::AuraList const& auras = m_target->GetAurasByType(SPELL_AURA_PERIODIC_DAMAGE);
4224 for(Unit::AuraList::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
4226 SpellEntry const* itr_spell = (*itr)->GetSpellProto();
4227 if(itr_spell && itr_spell->SpellFamilyName==SPELLFAMILY_ROGUE && (itr_spell->SpellFamilyFlags & 0x10000) && itr_spell->SpellVisual[0]==5100)
4229 found = true;
4230 break;
4233 // this has been last deadly poison aura
4234 if(!found)
4235 m_target->ModifyAuraState(AURA_STATE_DEADLY_POISON,false);
4237 return;
4239 // Rupture
4240 if (m_spellProto->SpellFamilyFlags & 0x000000000000100000LL)
4242 // Dmg/tick = $AP*min(0.01*$cp, 0.03) [Like Rip: only the first three CP increase the contribution from AP]
4243 if (apply && !loading && caster && caster->GetTypeId() == TYPEID_PLAYER)
4245 uint8 cp = ((Player*)caster)->GetComboPoints();
4246 if (cp > 3) cp = 3;
4247 m_modifier.m_amount += int32(caster->GetTotalAttackPowerValue(BASE_ATTACK) * cp / 100);
4249 return;
4251 // Garrote
4252 if (m_spellProto->SpellFamilyFlags & 0x000000000000000100LL)
4254 // $AP*0.18/6 bonus per tick
4255 if (apply && !loading && caster)
4256 m_modifier.m_amount += int32(caster->GetTotalAttackPowerValue(BASE_ATTACK) * 3 / 100);
4257 return;
4259 break;
4261 case SPELLFAMILY_HUNTER:
4263 // Serpent Sting
4264 if (m_spellProto->SpellFamilyFlags & 0x0000000000004000LL)
4266 // $RAP*0.1/5 bonus per tick
4267 if (apply && !loading && caster)
4268 m_modifier.m_amount += int32(caster->GetTotalAttackPowerValue(RANGED_ATTACK) * 10 / 500);
4269 return;
4271 // Immolation Trap
4272 if (m_spellProto->SpellFamilyFlags & 0x0000000000000004LL && m_spellProto->SpellIconID == 678)
4274 // $RAP*0.1/5 bonus per tick
4275 if (apply && !loading && caster)
4276 m_modifier.m_amount += int32(caster->GetTotalAttackPowerValue(RANGED_ATTACK) * 10 / 500);
4277 return;
4279 break;
4281 case SPELLFAMILY_PALADIN:
4283 // Consecration
4284 if (m_spellProto->SpellFamilyFlags & 0x0000000000000020LL)
4286 if (apply && !loading)
4288 if(Unit* caster = GetCaster())
4290 Unit::AuraList const& classScripts = caster->GetAurasByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS);
4291 for(Unit::AuraList::const_iterator k = classScripts.begin(); k != classScripts.end(); ++k)
4293 int32 tickcount = GetSpellDuration(m_spellProto) / m_spellProto->EffectAmplitude[m_effIndex];
4294 switch((*k)->GetModifier()->m_miscvalue)
4296 case 5147: // Improved Consecration - Libram of the Eternal Rest
4298 m_modifier.m_amount += (*k)->GetModifier()->m_amount / tickcount;
4299 break;
4305 return;
4307 break;
4309 default:
4310 break;
4314 void Aura::HandlePeriodicDamagePCT(bool apply, bool Real)
4316 if (m_periodicTimer <= 0)
4317 m_periodicTimer += m_modifier.periodictime;
4319 m_isPeriodic = apply;
4322 void Aura::HandlePeriodicLeech(bool apply, bool Real)
4324 if (m_periodicTimer <= 0)
4325 m_periodicTimer += m_modifier.periodictime;
4327 m_isPeriodic = apply;
4330 void Aura::HandlePeriodicManaLeech(bool apply, bool Real)
4332 if (m_periodicTimer <= 0)
4333 m_periodicTimer += m_modifier.periodictime;
4335 m_isPeriodic = apply;
4338 /*********************************************************/
4339 /*** MODIFY STATS ***/
4340 /*********************************************************/
4342 /********************************/
4343 /*** RESISTANCE ***/
4344 /********************************/
4346 void Aura::HandleAuraModResistanceExclusive(bool apply, bool Real)
4348 for(int8 x = SPELL_SCHOOL_NORMAL; x < MAX_SPELL_SCHOOL;x++)
4350 if(m_modifier.m_miscvalue & int32(1<<x))
4352 m_target->HandleStatModifier(UnitMods(UNIT_MOD_RESISTANCE_START + x), BASE_VALUE, float(m_modifier.m_amount), apply);
4353 if(m_target->GetTypeId() == TYPEID_PLAYER)
4354 m_target->ApplyResistanceBuffModsMod(SpellSchools(x),m_positive,m_modifier.m_amount, apply);
4359 void Aura::HandleAuraModResistance(bool apply, bool Real)
4361 for(int8 x = SPELL_SCHOOL_NORMAL; x < MAX_SPELL_SCHOOL;x++)
4363 if(m_modifier.m_miscvalue & int32(1<<x))
4365 m_target->HandleStatModifier(UnitMods(UNIT_MOD_RESISTANCE_START + x), TOTAL_VALUE, float(m_modifier.m_amount), apply);
4366 if(m_target->GetTypeId() == TYPEID_PLAYER || ((Creature*)m_target)->isPet())
4367 m_target->ApplyResistanceBuffModsMod(SpellSchools(x),m_positive,m_modifier.m_amount, apply);
4371 // Faerie Fire (druid versions)
4372 if( m_spellProto->SpellIconID == 109 &&
4373 m_spellProto->SpellFamilyName == SPELLFAMILY_DRUID &&
4374 m_spellProto->SpellFamilyFlags & 0x0000000000000400LL )
4376 m_target->ModifyAuraState(AURA_STATE_FAERIE_FIRE,apply);
4380 void Aura::HandleAuraModBaseResistancePCT(bool apply, bool Real)
4382 // only players have base stats
4383 if(m_target->GetTypeId() != TYPEID_PLAYER)
4385 //pets only have base armor
4386 if(((Creature*)m_target)->isPet() && (m_modifier.m_miscvalue & SPELL_SCHOOL_MASK_NORMAL))
4387 m_target->HandleStatModifier(UNIT_MOD_ARMOR, BASE_PCT, float(m_modifier.m_amount), apply);
4389 else
4391 for(int8 x = SPELL_SCHOOL_NORMAL; x < MAX_SPELL_SCHOOL;x++)
4393 if(m_modifier.m_miscvalue & int32(1<<x))
4394 m_target->HandleStatModifier(UnitMods(UNIT_MOD_RESISTANCE_START + x), BASE_PCT, float(m_modifier.m_amount), apply);
4399 void Aura::HandleModResistancePercent(bool apply, bool Real)
4401 for(int8 i = SPELL_SCHOOL_NORMAL; i < MAX_SPELL_SCHOOL; i++)
4403 if(m_modifier.m_miscvalue & int32(1<<i))
4405 m_target->HandleStatModifier(UnitMods(UNIT_MOD_RESISTANCE_START + i), TOTAL_PCT, float(m_modifier.m_amount), apply);
4406 if(m_target->GetTypeId() == TYPEID_PLAYER || ((Creature*)m_target)->isPet())
4408 m_target->ApplyResistanceBuffModsPercentMod(SpellSchools(i),true,m_modifier.m_amount, apply);
4409 m_target->ApplyResistanceBuffModsPercentMod(SpellSchools(i),false,m_modifier.m_amount, apply);
4415 void Aura::HandleModBaseResistance(bool apply, bool Real)
4417 // only players have base stats
4418 if(m_target->GetTypeId() != TYPEID_PLAYER)
4420 //only pets have base stats
4421 if(((Creature*)m_target)->isPet() && (m_modifier.m_miscvalue & SPELL_SCHOOL_MASK_NORMAL))
4422 m_target->HandleStatModifier(UNIT_MOD_ARMOR, TOTAL_VALUE, float(m_modifier.m_amount), apply);
4424 else
4426 for(int i = SPELL_SCHOOL_NORMAL; i < MAX_SPELL_SCHOOL; i++)
4427 if(m_modifier.m_miscvalue & (1<<i))
4428 m_target->HandleStatModifier(UnitMods(UNIT_MOD_RESISTANCE_START + i), TOTAL_VALUE, float(m_modifier.m_amount), apply);
4432 /********************************/
4433 /*** STAT ***/
4434 /********************************/
4436 void Aura::HandleAuraModStat(bool apply, bool Real)
4438 if (m_modifier.m_miscvalue < -2 || m_modifier.m_miscvalue > 4)
4440 sLog.outError("WARNING: Spell %u effect %u have unsupported misc value (%i) for SPELL_AURA_MOD_STAT ",GetId(),GetEffIndex(),m_modifier.m_miscvalue);
4441 return;
4444 for(int32 i = STAT_STRENGTH; i < MAX_STATS; i++)
4446 // -1 or -2 is all stats ( misc < -2 checked in function beginning )
4447 if (m_modifier.m_miscvalue < 0 || m_modifier.m_miscvalue == i)
4449 //m_target->ApplyStatMod(Stats(i), m_modifier.m_amount,apply);
4450 m_target->HandleStatModifier(UnitMods(UNIT_MOD_STAT_START + i), TOTAL_VALUE, float(m_modifier.m_amount), apply);
4451 if(m_target->GetTypeId() == TYPEID_PLAYER || ((Creature*)m_target)->isPet())
4452 m_target->ApplyStatBuffMod(Stats(i),m_modifier.m_amount,apply);
4457 void Aura::HandleModPercentStat(bool apply, bool Real)
4459 if (m_modifier.m_miscvalue < -1 || m_modifier.m_miscvalue > 4)
4461 sLog.outError("WARNING: Misc Value for SPELL_AURA_MOD_PERCENT_STAT not valid");
4462 return;
4465 // only players have base stats
4466 if (m_target->GetTypeId() != TYPEID_PLAYER)
4467 return;
4469 for (int32 i = STAT_STRENGTH; i < MAX_STATS; ++i)
4471 if(m_modifier.m_miscvalue == i || m_modifier.m_miscvalue == -1)
4472 m_target->HandleStatModifier(UnitMods(UNIT_MOD_STAT_START + i), BASE_PCT, float(m_modifier.m_amount), apply);
4476 void Aura::HandleModSpellDamagePercentFromStat(bool /*apply*/, bool Real)
4478 if(m_target->GetTypeId() != TYPEID_PLAYER)
4479 return;
4481 // Magic damage modifiers implemented in Unit::SpellDamageBonus
4482 // This information for client side use only
4483 // Recalculate bonus
4484 ((Player*)m_target)->UpdateSpellDamageAndHealingBonus();
4487 void Aura::HandleModSpellHealingPercentFromStat(bool /*apply*/, bool Real)
4489 if(m_target->GetTypeId() != TYPEID_PLAYER)
4490 return;
4492 // Recalculate bonus
4493 ((Player*)m_target)->UpdateSpellDamageAndHealingBonus();
4496 void Aura::HandleAuraModDispelResist(bool apply, bool Real)
4498 if(!Real || !apply)
4499 return;
4501 if(GetId()==33206)
4502 m_target->CastSpell(m_target,44416,true,NULL,this,GetCasterGUID());
4505 void Aura::HandleModSpellDamagePercentFromAttackPower(bool /*apply*/, bool Real)
4507 if(m_target->GetTypeId() != TYPEID_PLAYER)
4508 return;
4510 // Magic damage modifiers implemented in Unit::SpellDamageBonus
4511 // This information for client side use only
4512 // Recalculate bonus
4513 ((Player*)m_target)->UpdateSpellDamageAndHealingBonus();
4516 void Aura::HandleModSpellHealingPercentFromAttackPower(bool /*apply*/, bool Real)
4518 if(m_target->GetTypeId() != TYPEID_PLAYER)
4519 return;
4521 // Recalculate bonus
4522 ((Player*)m_target)->UpdateSpellDamageAndHealingBonus();
4525 void Aura::HandleModHealingDone(bool /*apply*/, bool Real)
4527 if(m_target->GetTypeId() != TYPEID_PLAYER)
4528 return;
4529 // implemented in Unit::SpellHealingBonus
4530 // this information is for client side only
4531 ((Player*)m_target)->UpdateSpellDamageAndHealingBonus();
4534 void Aura::HandleModTotalPercentStat(bool apply, bool Real)
4536 if (m_modifier.m_miscvalue < -1 || m_modifier.m_miscvalue > 4)
4538 sLog.outError("WARNING: Misc Value for SPELL_AURA_MOD_PERCENT_STAT not valid");
4539 return;
4542 //save current and max HP before applying aura
4543 uint32 curHPValue = m_target->GetHealth();
4544 uint32 maxHPValue = m_target->GetMaxHealth();
4546 for (int32 i = STAT_STRENGTH; i < MAX_STATS; i++)
4548 if(m_modifier.m_miscvalue == i || m_modifier.m_miscvalue == -1)
4550 m_target->HandleStatModifier(UnitMods(UNIT_MOD_STAT_START + i), TOTAL_PCT, float(m_modifier.m_amount), apply);
4551 if(m_target->GetTypeId() == TYPEID_PLAYER || ((Creature*)m_target)->isPet())
4552 m_target->ApplyStatPercentBuffMod(Stats(i), m_modifier.m_amount, apply );
4556 //recalculate current HP/MP after applying aura modifications (only for spells with 0x10 flag)
4557 if ((m_modifier.m_miscvalue == STAT_STAMINA) && (maxHPValue > 0) && (m_spellProto->Attributes & 0x10))
4559 // newHP = (curHP / maxHP) * newMaxHP = (newMaxHP * curHP) / maxHP -> which is better because no int -> double -> int conversion is needed
4560 uint32 newHPValue = (m_target->GetMaxHealth() * curHPValue) / maxHPValue;
4561 m_target->SetHealth(newHPValue);
4565 void Aura::HandleAuraModResistenceOfStatPercent(bool /*apply*/, bool Real)
4567 if(m_target->GetTypeId() != TYPEID_PLAYER)
4568 return;
4570 if(m_modifier.m_miscvalue != SPELL_SCHOOL_MASK_NORMAL)
4572 // support required adding replace UpdateArmor by loop by UpdateResistence at intellect update
4573 // and include in UpdateResistence same code as in UpdateArmor for aura mod apply.
4574 sLog.outError("Aura SPELL_AURA_MOD_RESISTANCE_OF_STAT_PERCENT(182) need adding support for non-armor resistances!");
4575 return;
4578 // Recalculate Armor
4579 m_target->UpdateArmor();
4582 /********************************/
4583 /*** HEAL & ENERGIZE ***/
4584 /********************************/
4585 void Aura::HandleAuraModTotalHealthPercentRegen(bool apply, bool Real)
4588 Need additional checking for auras who reduce or increase healing, magic effect like Dumpen Magic,
4589 so this aura not fully working.
4591 if(apply)
4593 if(!m_target->isAlive())
4594 return;
4596 if((GetSpellProto()->AuraInterruptFlags & AURA_INTERRUPT_FLAG_NOT_SEATED) && !m_target->IsSitState())
4597 m_target->SetStandState(PLAYER_STATE_SIT);
4599 if(m_periodicTimer <= 0)
4601 m_periodicTimer += m_modifier.periodictime;
4603 if(m_target->GetHealth() < m_target->GetMaxHealth())
4605 // PeriodicTick can cast triggered spells with stats changes
4606 PeriodicTick();
4611 m_isPeriodic = apply;
4614 void Aura::HandleAuraModTotalManaPercentRegen(bool apply, bool Real)
4616 if((GetSpellProto()->AuraInterruptFlags & AURA_INTERRUPT_FLAG_NOT_SEATED) && apply && !m_target->IsSitState())
4617 m_target->SetStandState(PLAYER_STATE_SIT);
4618 if(apply)
4620 if(m_modifier.periodictime == 0)
4621 m_modifier.periodictime = 1000;
4622 if(m_periodicTimer <= 0 && m_target->getPowerType() == POWER_MANA)
4624 m_periodicTimer += m_modifier.periodictime;
4626 if(m_target->GetPower(POWER_MANA) < m_target->GetMaxPower(POWER_MANA))
4628 // PeriodicTick can cast triggered spells with stats changes
4629 PeriodicTick();
4634 m_isPeriodic = apply;
4637 void Aura::HandleModRegen(bool apply, bool Real) // eating
4639 if(apply)
4641 if(!m_target->isAlive())
4642 return;
4644 if ((GetSpellProto()->AuraInterruptFlags & AURA_INTERRUPT_FLAG_NOT_SEATED) && !m_target->IsSitState())
4645 m_target->SetStandState(PLAYER_STATE_SIT);
4647 if(m_periodicTimer <= 0)
4649 m_periodicTimer += 5000;
4650 int32 gain = m_target->ModifyHealth(m_modifier.m_amount);
4651 Unit *caster = GetCaster();
4652 if (caster)
4654 SpellEntry const *spellProto = GetSpellProto();
4655 if (spellProto)
4656 m_target->getHostilRefManager().threatAssist(caster, float(gain) * 0.5f, spellProto);
4661 m_isPeriodic = apply;
4664 void Aura::HandleModPowerRegen(bool apply, bool Real) // drinking
4666 if ((GetSpellProto()->AuraInterruptFlags & AURA_INTERRUPT_FLAG_NOT_SEATED) && apply && !m_target->IsSitState())
4667 m_target->SetStandState(PLAYER_STATE_SIT);
4669 if(apply && m_periodicTimer <= 0)
4671 m_periodicTimer += 2000;
4673 Powers pt = m_target->getPowerType();
4674 if(int32(pt) != m_modifier.m_miscvalue)
4675 return;
4677 if ( GetSpellProto()->AuraInterruptFlags & AURA_INTERRUPT_FLAG_NOT_SEATED )
4679 // eating anim
4680 m_target->HandleEmoteCommand(EMOTE_ONESHOT_EAT);
4682 else if( GetId() == 20577 )
4684 // cannibalize anim
4685 m_target->HandleEmoteCommand(398);
4688 // Warrior talent, gain 1 rage every 3 seconds while in combat
4689 if(pt == POWER_RAGE && m_target->isInCombat())
4691 m_target->ModifyPower(pt, m_modifier.m_amount*10/17);
4692 m_periodicTimer += 1000;
4695 m_isPeriodic = apply;
4696 if (Real && m_target->GetTypeId() == TYPEID_PLAYER && m_modifier.m_miscvalue == POWER_MANA)
4697 ((Player*)m_target)->UpdateManaRegen();
4700 void Aura::HandleModPowerRegenPCT(bool /*apply*/, bool Real)
4702 // spells required only Real aura add/remove
4703 if(!Real)
4704 return;
4706 if (m_target->GetTypeId() != TYPEID_PLAYER)
4707 return;
4709 // Update manaregen value
4710 if (m_modifier.m_miscvalue == POWER_MANA)
4711 ((Player*)m_target)->UpdateManaRegen();
4714 void Aura::HandleModManaRegen(bool /*apply*/, bool Real)
4716 // spells required only Real aura add/remove
4717 if(!Real)
4718 return;
4720 if (m_target->GetTypeId() != TYPEID_PLAYER)
4721 return;
4723 //Note: an increase in regen does NOT cause threat.
4724 ((Player*)m_target)->UpdateManaRegen();
4727 void Aura::HandleComprehendLanguage(bool apply, bool Real)
4729 if(apply)
4730 m_target->SetFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_COMPREHEND_LANG);
4731 else
4732 m_target->RemoveFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_COMPREHEND_LANG);
4735 void Aura::HandleAuraModIncreaseHealth(bool apply, bool Real)
4737 // Special case with temporary increase max/current health
4738 switch(GetId())
4740 case 12976: // Warrior Last Stand triggered spell
4741 case 28726: // Nightmare Seed ( Nightmare Seed )
4742 case 34511: // Valor (Bulwark of Kings, Bulwark of the Ancient Kings)
4743 case 44055: // Tremendous Fortitude (Battlemaster's Alacrity)
4745 if(Real)
4747 if(apply)
4749 m_target->HandleStatModifier(UNIT_MOD_HEALTH, TOTAL_VALUE, float(m_modifier.m_amount), apply);
4750 m_target->ModifyHealth(m_modifier.m_amount);
4752 else
4754 if (int32(m_target->GetHealth()) > m_modifier.m_amount)
4755 m_target->ModifyHealth(-m_modifier.m_amount);
4756 else
4757 m_target->SetHealth(1);
4758 m_target->HandleStatModifier(UNIT_MOD_HEALTH, TOTAL_VALUE, float(m_modifier.m_amount), apply);
4761 return;
4765 // generic case
4766 m_target->HandleStatModifier(UNIT_MOD_HEALTH, TOTAL_VALUE, float(m_modifier.m_amount), apply);
4769 void Aura::HandleAuraModIncreaseMaxHealth(bool apply, bool Real)
4771 uint32 oldhealth = m_target->GetHealth();
4772 double healthPercentage = (double)oldhealth / (double)m_target->GetMaxHealth();
4774 m_target->HandleStatModifier(UNIT_MOD_HEALTH, TOTAL_VALUE, float(m_modifier.m_amount), apply);
4776 // refresh percentage
4777 if(oldhealth > 0)
4779 uint32 newhealth = uint32(ceil((double)m_target->GetMaxHealth() * healthPercentage));
4780 if(newhealth==0)
4781 newhealth = 1;
4783 m_target->SetHealth(newhealth);
4787 void Aura::HandleAuraModIncreaseEnergy(bool apply, bool Real)
4789 Powers powerType = m_target->getPowerType();
4790 if(int32(powerType) != m_modifier.m_miscvalue)
4791 return;
4793 UnitMods unitMod = UnitMods(UNIT_MOD_POWER_START + powerType);
4795 m_target->HandleStatModifier(unitMod, TOTAL_VALUE, float(m_modifier.m_amount), apply);
4798 void Aura::HandleAuraModIncreaseEnergyPercent(bool apply, bool /*Real*/)
4800 Powers powerType = m_target->getPowerType();
4801 if(int32(powerType) != m_modifier.m_miscvalue)
4802 return;
4804 UnitMods unitMod = UnitMods(UNIT_MOD_POWER_START + powerType);
4806 m_target->HandleStatModifier(unitMod, TOTAL_PCT, float(m_modifier.m_amount), apply);
4809 void Aura::HandleAuraModIncreaseHealthPercent(bool apply, bool /*Real*/)
4811 m_target->HandleStatModifier(UNIT_MOD_HEALTH, TOTAL_PCT, float(m_modifier.m_amount), apply);
4814 void Aura::HandleAuraIncreaseBaseHealthPercent(bool apply, bool /*Real*/)
4816 m_target->HandleStatModifier(UNIT_MOD_HEALTH, BASE_PCT, float(m_modifier.m_amount), apply);
4819 /********************************/
4820 /*** FIGHT ***/
4821 /********************************/
4823 void Aura::HandleAuraModParryPercent(bool /*apply*/, bool Real)
4825 if(m_target->GetTypeId()!=TYPEID_PLAYER)
4826 return;
4828 ((Player*)m_target)->UpdateParryPercentage();
4831 void Aura::HandleAuraModDodgePercent(bool /*apply*/, bool Real)
4833 if(m_target->GetTypeId()!=TYPEID_PLAYER)
4834 return;
4836 ((Player*)m_target)->UpdateDodgePercentage();
4837 //sLog.outError("BONUS DODGE CHANCE: + %f", float(m_modifier.m_amount));
4840 void Aura::HandleAuraModBlockPercent(bool /*apply*/, bool Real)
4842 if(m_target->GetTypeId()!=TYPEID_PLAYER)
4843 return;
4845 ((Player*)m_target)->UpdateBlockPercentage();
4846 //sLog.outError("BONUS BLOCK CHANCE: + %f", float(m_modifier.m_amount));
4849 void Aura::HandleAuraModRegenInterrupt(bool /*apply*/, bool Real)
4851 // spells required only Real aura add/remove
4852 if(!Real)
4853 return;
4855 if(m_target->GetTypeId()!=TYPEID_PLAYER)
4856 return;
4858 ((Player*)m_target)->UpdateManaRegen();
4861 void Aura::HandleAuraModCritPercent(bool apply, bool Real)
4863 if(m_target->GetTypeId()!=TYPEID_PLAYER)
4864 return;
4866 // apply item specific bonuses for already equipped weapon
4867 if(Real)
4869 for(int i = 0; i < MAX_ATTACK; ++i)
4870 if(Item* pItem = ((Player*)m_target)->GetWeaponForAttack(WeaponAttackType(i)))
4871 ((Player*)m_target)->_ApplyWeaponDependentAuraCritMod(pItem,WeaponAttackType(i),this,apply);
4874 // mods must be applied base at equipped weapon class and subclass comparison
4875 // with spell->EquippedItemClass and EquippedItemSubClassMask and EquippedItemInventoryTypeMask
4876 // m_modifier.m_miscvalue comparison with item generated damage types
4878 if (GetSpellProto()->EquippedItemClass == -1)
4880 ((Player*)m_target)->HandleBaseModValue(CRIT_PERCENTAGE, FLAT_MOD, float (m_modifier.m_amount), apply);
4881 ((Player*)m_target)->HandleBaseModValue(OFFHAND_CRIT_PERCENTAGE, FLAT_MOD, float (m_modifier.m_amount), apply);
4882 ((Player*)m_target)->HandleBaseModValue(RANGED_CRIT_PERCENTAGE, FLAT_MOD, float (m_modifier.m_amount), apply);
4884 else
4886 // done in Player::_ApplyWeaponDependentAuraMods
4890 void Aura::HandleModHitChance(bool apply, bool Real)
4892 if(m_target->GetTypeId() == TYPEID_PLAYER)
4894 ((Player*)m_target)->UpdateMeleeHitChances();
4895 ((Player*)m_target)->UpdateRangedHitChances();
4897 else
4899 m_target->m_modMeleeHitChance += apply ? m_modifier.m_amount : (-m_modifier.m_amount);
4900 m_target->m_modRangedHitChance += apply ? m_modifier.m_amount : (-m_modifier.m_amount);
4904 void Aura::HandleModSpellHitChance(bool apply, bool Real)
4906 if(m_target->GetTypeId() == TYPEID_PLAYER)
4908 ((Player*)m_target)->UpdateSpellHitChances();
4910 else
4912 m_target->m_modSpellHitChance += apply ? m_modifier.m_amount: (-m_modifier.m_amount);
4916 void Aura::HandleModSpellCritChance(bool apply, bool Real)
4918 // spells required only Real aura add/remove
4919 if(!Real)
4920 return;
4922 if(m_target->GetTypeId() == TYPEID_PLAYER)
4924 ((Player*)m_target)->UpdateAllSpellCritChances();
4926 else
4928 m_target->m_baseSpellCritChance += apply ? m_modifier.m_amount:(-m_modifier.m_amount);
4932 void Aura::HandleModSpellCritChanceShool(bool /*apply*/, bool Real)
4934 // spells required only Real aura add/remove
4935 if(!Real)
4936 return;
4938 if(m_target->GetTypeId() != TYPEID_PLAYER)
4939 return;
4941 for(int school = SPELL_SCHOOL_NORMAL; school < MAX_SPELL_SCHOOL; ++school)
4942 if (m_modifier.m_miscvalue & (1<<school))
4943 ((Player*)m_target)->UpdateSpellCritChance(school);
4946 /********************************/
4947 /*** ATTACK SPEED ***/
4948 /********************************/
4950 void Aura::HandleModCastingSpeed(bool apply, bool Real)
4952 m_target->ApplyCastTimePercentMod(m_modifier.m_amount,apply);
4955 void Aura::HandleModMeleeRangedSpeedPct(bool apply, bool Real)
4957 m_target->ApplyAttackTimePercentMod(BASE_ATTACK,m_modifier.m_amount,apply);
4958 m_target->ApplyAttackTimePercentMod(OFF_ATTACK,m_modifier.m_amount,apply);
4959 m_target->ApplyAttackTimePercentMod(RANGED_ATTACK, m_modifier.m_amount, apply);
4962 void Aura::HandleModCombatSpeedPct(bool apply, bool Real)
4964 m_target->ApplyCastTimePercentMod(m_modifier.m_amount,apply);
4965 m_target->ApplyAttackTimePercentMod(BASE_ATTACK,m_modifier.m_amount,apply);
4966 m_target->ApplyAttackTimePercentMod(OFF_ATTACK,m_modifier.m_amount,apply);
4967 m_target->ApplyAttackTimePercentMod(RANGED_ATTACK, m_modifier.m_amount, apply);
4970 void Aura::HandleModAttackSpeed(bool apply, bool Real)
4972 if(!m_target->isAlive() )
4973 return;
4975 m_target->ApplyAttackTimePercentMod(BASE_ATTACK,m_modifier.m_amount,apply);
4978 void Aura::HandleHaste(bool apply, bool Real)
4980 m_target->ApplyAttackTimePercentMod(BASE_ATTACK, m_modifier.m_amount,apply);
4981 m_target->ApplyAttackTimePercentMod(OFF_ATTACK, m_modifier.m_amount,apply);
4982 m_target->ApplyAttackTimePercentMod(RANGED_ATTACK,m_modifier.m_amount,apply);
4985 void Aura::HandleAuraModRangedHaste(bool apply, bool Real)
4987 m_target->ApplyAttackTimePercentMod(RANGED_ATTACK, m_modifier.m_amount, apply);
4990 void Aura::HandleRangedAmmoHaste(bool apply, bool Real)
4992 if(m_target->GetTypeId() != TYPEID_PLAYER)
4993 return;
4994 m_target->ApplyAttackTimePercentMod(RANGED_ATTACK,m_modifier.m_amount, apply);
4997 /********************************/
4998 /*** ATTACK POWER ***/
4999 /********************************/
5001 void Aura::HandleAuraModAttackPower(bool apply, bool Real)
5003 m_target->HandleStatModifier(UNIT_MOD_ATTACK_POWER, TOTAL_VALUE, float(m_modifier.m_amount), apply);
5006 void Aura::HandleAuraModRangedAttackPower(bool apply, bool Real)
5008 if((m_target->getClassMask() & CLASSMASK_WAND_USERS)!=0)
5009 return;
5011 m_target->HandleStatModifier(UNIT_MOD_ATTACK_POWER_RANGED, TOTAL_VALUE, float(m_modifier.m_amount), apply);
5014 void Aura::HandleAuraModAttackPowerPercent(bool apply, bool Real)
5016 //UNIT_FIELD_ATTACK_POWER_MULTIPLIER = multiplier - 1
5017 m_target->HandleStatModifier(UNIT_MOD_ATTACK_POWER, TOTAL_PCT, float(m_modifier.m_amount), apply);
5020 void Aura::HandleAuraModRangedAttackPowerPercent(bool apply, bool Real)
5022 if((m_target->getClassMask() & CLASSMASK_WAND_USERS)!=0)
5023 return;
5025 //UNIT_FIELD_RANGED_ATTACK_POWER_MULTIPLIER = multiplier - 1
5026 m_target->HandleStatModifier(UNIT_MOD_ATTACK_POWER_RANGED, TOTAL_PCT, float(m_modifier.m_amount), apply);
5029 void Aura::HandleAuraModRangedAttackPowerOfStatPercent(bool apply, bool Real)
5031 // spells required only Real aura add/remove
5032 if(!Real)
5033 return;
5035 if(m_target->GetTypeId() == TYPEID_PLAYER && (m_target->getClassMask() & CLASSMASK_WAND_USERS)!=0)
5036 return;
5038 // Recalculate bonus
5039 ((Player*)m_target)->UpdateAttackPowerAndDamage(true);
5042 void Aura::HandleAuraModAttackPowerOfStatPercent(bool apply, bool Real)
5044 // spells required only Real aura add/remove
5045 if(!Real)
5046 return;
5048 if(m_target->GetTypeId() == TYPEID_PLAYER && (m_target->getClassMask() & CLASSMASK_WAND_USERS)!=0)
5049 return;
5051 // Recalculate bonus
5052 ((Player*)m_target)->UpdateAttackPowerAndDamage(false);
5055 /********************************/
5056 /*** DAMAGE BONUS ***/
5057 /********************************/
5058 void Aura::HandleModDamageDone(bool apply, bool Real)
5060 // apply item specific bonuses for already equipped weapon
5061 if(Real && m_target->GetTypeId()==TYPEID_PLAYER)
5063 for(int i = 0; i < MAX_ATTACK; ++i)
5064 if(Item* pItem = ((Player*)m_target)->GetWeaponForAttack(WeaponAttackType(i)))
5065 ((Player*)m_target)->_ApplyWeaponDependentAuraDamageMod(pItem,WeaponAttackType(i),this,apply);
5068 // m_modifier.m_miscvalue is bitmask of spell schools
5069 // 1 ( 0-bit ) - normal school damage (SPELL_SCHOOL_MASK_NORMAL)
5070 // 126 - full bitmask all magic damages (SPELL_SCHOOL_MASK_MAGIC) including wands
5071 // 127 - full bitmask any damages
5073 // mods must be applied base at equipped weapon class and subclass comparison
5074 // with spell->EquippedItemClass and EquippedItemSubClassMask and EquippedItemInventoryTypeMask
5075 // m_modifier.m_miscvalue comparison with item generated damage types
5077 if((m_modifier.m_miscvalue & SPELL_SCHOOL_MASK_NORMAL) != 0)
5079 // apply generic physical damage bonuses including wand case
5080 if (GetSpellProto()->EquippedItemClass == -1 || m_target->GetTypeId() != TYPEID_PLAYER)
5082 m_target->HandleStatModifier(UNIT_MOD_DAMAGE_MAINHAND, TOTAL_VALUE, float(m_modifier.m_amount), apply);
5083 m_target->HandleStatModifier(UNIT_MOD_DAMAGE_OFFHAND, TOTAL_VALUE, float(m_modifier.m_amount), apply);
5084 m_target->HandleStatModifier(UNIT_MOD_DAMAGE_RANGED, TOTAL_VALUE, float(m_modifier.m_amount), apply);
5086 else
5088 // done in Player::_ApplyWeaponDependentAuraMods
5091 if(m_target->GetTypeId() == TYPEID_PLAYER)
5093 if(m_positive)
5094 m_target->ApplyModUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_POS,m_modifier.m_amount,apply);
5095 else
5096 m_target->ApplyModUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_NEG,m_modifier.m_amount,apply);
5100 // Skip non magic case for speedup
5101 if((m_modifier.m_miscvalue & SPELL_SCHOOL_MASK_MAGIC) == 0)
5102 return;
5104 if( GetSpellProto()->EquippedItemClass != -1 || GetSpellProto()->EquippedItemInventoryTypeMask != 0 )
5106 // wand magic case (skip generic to all item spell bonuses)
5107 // done in Player::_ApplyWeaponDependentAuraMods
5109 // Skip item specific requirements for not wand magic damage
5110 return;
5113 // Magic damage modifiers implemented in Unit::SpellDamageBonus
5114 // This information for client side use only
5115 if(m_target->GetTypeId() == TYPEID_PLAYER)
5117 if(m_positive)
5119 for(int i = SPELL_SCHOOL_HOLY; i < MAX_SPELL_SCHOOL; i++)
5121 if((m_modifier.m_miscvalue & (1<<i)) != 0)
5122 m_target->ApplyModUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_POS+i,m_modifier.m_amount,apply);
5125 else
5127 for(int i = SPELL_SCHOOL_HOLY; i < MAX_SPELL_SCHOOL; i++)
5129 if((m_modifier.m_miscvalue & (1<<i)) != 0)
5130 m_target->ApplyModUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_NEG+i,m_modifier.m_amount,apply);
5133 Pet* pet = m_target->GetPet();
5134 if(pet)
5135 pet->UpdateAttackPowerAndDamage();
5139 void Aura::HandleModDamagePercentDone(bool apply, bool Real)
5141 sLog.outDebug("AURA MOD DAMAGE type:%u negative:%u", m_modifier.m_miscvalue, m_positive ? 0 : 1);
5143 // apply item specific bonuses for already equipped weapon
5144 if(Real && m_target->GetTypeId()==TYPEID_PLAYER)
5146 for(int i = 0; i < MAX_ATTACK; ++i)
5147 if(Item* pItem = ((Player*)m_target)->GetWeaponForAttack(WeaponAttackType(i)))
5148 ((Player*)m_target)->_ApplyWeaponDependentAuraDamageMod(pItem,WeaponAttackType(i),this,apply);
5151 // m_modifier.m_miscvalue is bitmask of spell schools
5152 // 1 ( 0-bit ) - normal school damage (SPELL_SCHOOL_MASK_NORMAL)
5153 // 126 - full bitmask all magic damages (SPELL_SCHOOL_MASK_MAGIC) including wand
5154 // 127 - full bitmask any damages
5156 // mods must be applied base at equipped weapon class and subclass comparison
5157 // with spell->EquippedItemClass and EquippedItemSubClassMask and EquippedItemInventoryTypeMask
5158 // m_modifier.m_miscvalue comparison with item generated damage types
5160 if((m_modifier.m_miscvalue & SPELL_SCHOOL_MASK_NORMAL) != 0)
5162 // apply generic physical damage bonuses including wand case
5163 if (GetSpellProto()->EquippedItemClass == -1 || m_target->GetTypeId() != TYPEID_PLAYER)
5165 m_target->HandleStatModifier(UNIT_MOD_DAMAGE_MAINHAND, TOTAL_PCT, float(m_modifier.m_amount), apply);
5166 m_target->HandleStatModifier(UNIT_MOD_DAMAGE_OFFHAND, TOTAL_PCT, float(m_modifier.m_amount), apply);
5167 m_target->HandleStatModifier(UNIT_MOD_DAMAGE_RANGED, TOTAL_PCT, float(m_modifier.m_amount), apply);
5169 else
5171 // done in Player::_ApplyWeaponDependentAuraMods
5173 // For show in client
5174 if(m_target->GetTypeId() == TYPEID_PLAYER)
5175 m_target->ApplyModSignedFloatValue(PLAYER_FIELD_MOD_DAMAGE_DONE_PCT,m_modifier.m_amount/100.0f,apply);
5178 // Skip non magic case for speedup
5179 if((m_modifier.m_miscvalue & SPELL_SCHOOL_MASK_MAGIC) == 0)
5180 return;
5182 if( GetSpellProto()->EquippedItemClass != -1 || GetSpellProto()->EquippedItemInventoryTypeMask != 0 )
5184 // wand magic case (skip generic to all item spell bonuses)
5185 // done in Player::_ApplyWeaponDependentAuraMods
5187 // Skip item specific requirements for not wand magic damage
5188 return;
5191 // Magic damage percent modifiers implemented in Unit::SpellDamageBonus
5192 // Send info to client
5193 if(m_target->GetTypeId() == TYPEID_PLAYER)
5194 for(int i = SPELL_SCHOOL_HOLY; i < MAX_SPELL_SCHOOL; ++i)
5195 m_target->ApplyModSignedFloatValue(PLAYER_FIELD_MOD_DAMAGE_DONE_PCT+i,m_modifier.m_amount/100.0f,apply);
5198 void Aura::HandleModOffhandDamagePercent(bool apply, bool Real)
5200 // spells required only Real aura add/remove
5201 if(!Real)
5202 return;
5204 sLog.outDebug("AURA MOD OFFHAND DAMAGE");
5206 m_target->HandleStatModifier(UNIT_MOD_DAMAGE_OFFHAND, TOTAL_PCT, float(m_modifier.m_amount), apply);
5209 /********************************/
5210 /*** POWER COST ***/
5211 /********************************/
5213 void Aura::HandleModPowerCostPCT(bool apply, bool Real)
5215 // spells required only Real aura add/remove
5216 if(!Real)
5217 return;
5219 float amount = m_modifier.m_amount/100.0f;
5220 for(int i = 0; i < MAX_SPELL_SCHOOL; ++i)
5221 if(m_modifier.m_miscvalue & (1<<i))
5222 m_target->ApplyModSignedFloatValue(UNIT_FIELD_POWER_COST_MULTIPLIER+i,amount,apply);
5225 void Aura::HandleModPowerCost(bool apply, bool Real)
5227 // spells required only Real aura add/remove
5228 if(!Real)
5229 return;
5231 for(int i = 0; i < MAX_SPELL_SCHOOL; ++i)
5232 if(m_modifier.m_miscvalue & (1<<i))
5233 m_target->ApplyModInt32Value(UNIT_FIELD_POWER_COST_MODIFIER+i,m_modifier.m_amount,apply);
5236 void Aura::HandleNoReagentUseAura(bool Apply, bool Real)
5238 // spells required only Real aura add/remove
5239 if(!Real)
5240 return;
5241 if(m_target->GetTypeId() != TYPEID_PLAYER)
5242 return;
5243 uint32 mask[3] = {0, 0, 0};
5244 Unit::AuraList const& noReagent = m_target->GetAurasByType(SPELL_AURA_NO_REAGENT_USE);
5245 for(Unit::AuraList::const_iterator i = noReagent.begin(); i != noReagent.end(); ++i)
5247 uint32 const *ptr = (*i)->getAuraSpellClassMask();
5248 mask[0]|=ptr[0];
5249 mask[1]|=ptr[1];
5250 mask[2]|=ptr[2];
5253 m_target->SetUInt32Value(PLAYER_NO_REAGENT_COST_1 , mask[0]);
5254 m_target->SetUInt32Value(PLAYER_NO_REAGENT_COST_1+1, mask[1]);
5255 m_target->SetUInt32Value(PLAYER_NO_REAGENT_COST_1+2, mask[2]);
5258 /*********************************************************/
5259 /*** OTHERS ***/
5260 /*********************************************************/
5262 void Aura::HandleShapeshiftBoosts(bool apply)
5264 uint32 spellId = 0;
5265 uint32 spellId2 = 0;
5266 uint32 HotWSpellId = 0;
5268 switch(GetModifier()->m_miscvalue)
5270 case FORM_CAT:
5271 spellId = 3025;
5272 HotWSpellId = 24900;
5273 break;
5274 case FORM_TREE:
5275 spellId = 5420;
5276 break;
5277 case FORM_TRAVEL:
5278 spellId = 5419;
5279 break;
5280 case FORM_AQUA:
5281 spellId = 5421;
5282 break;
5283 case FORM_BEAR:
5284 spellId = 1178;
5285 spellId2 = 21178;
5286 HotWSpellId = 24899;
5287 break;
5288 case FORM_DIREBEAR:
5289 spellId = 9635;
5290 spellId2 = 21178;
5291 HotWSpellId = 24899;
5292 break;
5293 case FORM_BATTLESTANCE:
5294 spellId = 21156;
5295 break;
5296 case FORM_DEFENSIVESTANCE:
5297 spellId = 7376;
5298 break;
5299 case FORM_BERSERKERSTANCE:
5300 spellId = 7381;
5301 break;
5302 case FORM_MOONKIN:
5303 spellId = 24905;
5304 // aura from effect trigger spell
5305 spellId2 = 24907;
5306 break;
5307 case FORM_FLIGHT:
5308 spellId = 33948;
5309 break;
5310 case FORM_FLIGHT_EPIC:
5311 spellId = 40122;
5312 spellId2 = 40121;
5313 break;
5314 case FORM_METAMORPHOSIS:
5315 spellId = 54817;
5316 spellId2 = 54879;
5317 break;
5318 case FORM_SPIRITOFREDEMPTION:
5319 spellId = 27792;
5320 spellId2 = 27795; // must be second, this important at aura remove to prevent to early iterator invalidation.
5321 break;
5322 case FORM_GHOSTWOLF:
5323 case FORM_AMBIENT:
5324 case FORM_GHOUL:
5325 case FORM_SHADOW:
5326 case FORM_STEALTH:
5327 case FORM_CREATURECAT:
5328 case FORM_CREATUREBEAR:
5329 spellId = 0;
5330 break;
5333 uint32 form = GetModifier()->m_miscvalue-1;
5335 if(apply)
5337 if (spellId) m_target->CastSpell(m_target, spellId, true, NULL, this );
5338 if (spellId2) m_target->CastSpell(m_target, spellId2, true, NULL, this);
5340 if(m_target->GetTypeId() == TYPEID_PLAYER)
5342 const PlayerSpellMap& sp_list = ((Player *)m_target)->GetSpellMap();
5343 for (PlayerSpellMap::const_iterator itr = sp_list.begin(); itr != sp_list.end(); ++itr)
5345 if(itr->second->state == PLAYERSPELL_REMOVED) continue;
5346 if(itr->first==spellId || itr->first==spellId2) continue;
5347 SpellEntry const *spellInfo = sSpellStore.LookupEntry(itr->first);
5348 if (!spellInfo || !(spellInfo->Attributes & ((1<<6) | (1<<7)))) continue;
5349 if (spellInfo->Stances & (1<<form))
5350 m_target->CastSpell(m_target, itr->first, true, NULL, this);
5352 //LotP
5353 if (((Player*)m_target)->HasSpell(17007))
5355 SpellEntry const *spellInfo = sSpellStore.LookupEntry(24932);
5356 if (spellInfo && spellInfo->Stances & (1<<form))
5357 m_target->CastSpell(m_target, 24932, true, NULL, this);
5359 // HotW
5360 if (HotWSpellId)
5362 Unit::AuraList const& mModTotalStatPct = m_target->GetAurasByType(SPELL_AURA_MOD_TOTAL_STAT_PERCENTAGE);
5363 for(Unit::AuraList::const_iterator i = mModTotalStatPct.begin(); i != mModTotalStatPct.end(); ++i)
5365 if ((*i)->GetSpellProto()->SpellIconID == 240 && (*i)->GetModifier()->m_miscvalue == 3)
5367 int32 HotWMod = (*i)->GetModifier()->m_amount;
5368 if(GetModifier()->m_miscvalue == FORM_CAT)
5369 HotWMod /= 2;
5371 m_target->CastCustomSpell(m_target, HotWSpellId, &HotWMod, NULL, NULL, true, NULL, this);
5372 break;
5378 else
5380 m_target->RemoveAurasDueToSpell(spellId);
5381 m_target->RemoveAurasDueToSpell(spellId2);
5383 Unit::AuraMap& tAuras = m_target->GetAuras();
5384 for (Unit::AuraMap::iterator itr = tAuras.begin(); itr != tAuras.end();)
5386 if (itr->second->IsRemovedOnShapeLost())
5388 m_target->RemoveAurasDueToSpell(itr->second->GetId());
5389 itr = tAuras.begin();
5391 else
5393 ++itr;
5398 /*double healthPercentage = (double)m_target->GetHealth() / (double)m_target->GetMaxHealth();
5399 m_target->SetHealth(uint32(ceil((double)m_target->GetMaxHealth() * healthPercentage)));*/
5402 void Aura::HandleAuraEmpathy(bool apply, bool Real)
5404 if(m_target->GetTypeId() != TYPEID_UNIT)
5405 return;
5407 CreatureInfo const * ci = objmgr.GetCreatureTemplate(m_target->GetEntry());
5408 if(ci && ci->type == CREATURE_TYPE_BEAST)
5409 m_target->ApplyModUInt32Value(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_SPECIALINFO, apply);
5412 void Aura::HandleAuraUntrackable(bool apply, bool Real)
5414 if(apply)
5415 m_target->SetFlag(UNIT_FIELD_BYTES_1, PLAYER_STATE_FLAG_UNTRACKABLE);
5416 else
5417 m_target->RemoveFlag(UNIT_FIELD_BYTES_1, PLAYER_STATE_FLAG_UNTRACKABLE);
5420 void Aura::HandleAuraModPacify(bool apply, bool Real)
5422 if(m_target->GetTypeId() != TYPEID_PLAYER)
5423 return;
5425 if(apply)
5426 m_target->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PACIFIED);
5427 else
5428 m_target->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PACIFIED);
5431 void Aura::HandleAuraModPacifyAndSilence(bool apply, bool Real)
5433 HandleAuraModPacify(apply,Real);
5434 HandleAuraModSilence(apply,Real);
5437 void Aura::HandleAuraGhost(bool apply, bool Real)
5439 if(m_target->GetTypeId() != TYPEID_PLAYER)
5440 return;
5442 if(apply)
5444 m_target->SetFlag(PLAYER_FLAGS, PLAYER_FLAGS_GHOST);
5446 else
5448 m_target->RemoveFlag(PLAYER_FLAGS, PLAYER_FLAGS_GHOST);
5452 void Aura::HandleAuraAllowFlight(bool apply, bool Real)
5454 // all applied/removed only at real aura add/remove
5455 if(!Real)
5456 return;
5458 // allow fly
5459 WorldPacket data;
5460 if(apply)
5461 data.Initialize(SMSG_MOVE_SET_CAN_FLY, 12);
5462 else
5463 data.Initialize(SMSG_MOVE_UNSET_CAN_FLY, 12);
5464 data.append(m_target->GetPackGUID());
5465 data << uint32(0); // unk
5466 m_target->SendMessageToSet(&data, true);
5469 void Aura::HandleModRating(bool apply, bool Real)
5471 // spells required only Real aura add/remove
5472 if(!Real)
5473 return;
5475 if(m_target->GetTypeId() != TYPEID_PLAYER)
5476 return;
5478 for (uint32 rating = 0; rating < MAX_COMBAT_RATING; ++rating)
5479 if (m_modifier.m_miscvalue & (1 << rating))
5480 ((Player*)m_target)->ApplyRatingMod(CombatRating(rating), m_modifier.m_amount, apply);
5483 void Aura::HandleModRatingFromStat(bool apply, bool Real)
5485 // spells required only Real aura add/remove
5486 if(!Real)
5487 return;
5489 if(m_target->GetTypeId() != TYPEID_PLAYER)
5490 return;
5491 // Just recalculate ratings
5492 for (uint32 rating = 0; rating < MAX_COMBAT_RATING; ++rating)
5493 if (m_modifier.m_miscvalue & (1 << rating))
5494 ((Player*)m_target)->ApplyRatingMod(CombatRating(rating), 0, apply);
5497 void Aura::HandleForceMoveForward(bool apply, bool Real)
5499 if(!Real || m_target->GetTypeId() != TYPEID_PLAYER)
5500 return;
5501 if(apply)
5502 m_target->SetFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_FORCE_MOVE);
5503 else
5504 m_target->RemoveFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_FORCE_MOVE);
5507 void Aura::HandleAuraModExpertise(bool /*apply*/, bool Real)
5509 if(m_target->GetTypeId() != TYPEID_PLAYER)
5510 return;
5512 ((Player*)m_target)->UpdateExpertise(BASE_ATTACK);
5513 ((Player*)m_target)->UpdateExpertise(OFF_ATTACK);
5516 void Aura::HandleModTargetResistance(bool apply, bool Real)
5518 // spells required only Real aura add/remove
5519 if(!Real)
5520 return;
5521 // applied to damage as HandleNoImmediateEffect in Unit::CalcAbsorbResist and Unit::CalcArmorReducedDamage
5523 // show armor penetration
5524 if (m_target->GetTypeId() == TYPEID_PLAYER && (m_modifier.m_miscvalue & SPELL_SCHOOL_MASK_NORMAL))
5525 m_target->ApplyModInt32Value(PLAYER_FIELD_MOD_TARGET_PHYSICAL_RESISTANCE,m_modifier.m_amount, apply);
5527 // show as spell penetration only full spell penetration bonuses (all resistances except armor and holy
5528 if (m_target->GetTypeId() == TYPEID_PLAYER && (m_modifier.m_miscvalue & SPELL_SCHOOL_MASK_SPELL)==SPELL_SCHOOL_MASK_SPELL)
5529 m_target->ApplyModInt32Value(PLAYER_FIELD_MOD_TARGET_RESISTANCE,m_modifier.m_amount, apply);
5532 void Aura::HandleShieldBlockValue(bool apply, bool Real)
5534 BaseModType modType = FLAT_MOD;
5535 if(m_modifier.m_auraname == SPELL_AURA_MOD_SHIELD_BLOCKVALUE_PCT)
5536 modType = PCT_MOD;
5538 if(m_target->GetTypeId() == TYPEID_PLAYER)
5539 ((Player*)m_target)->HandleBaseModValue(SHIELD_BLOCK_VALUE, modType, float(m_modifier.m_amount), apply);
5542 void Aura::HandleAuraRetainComboPoints(bool apply, bool Real)
5544 // spells required only Real aura add/remove
5545 if(!Real)
5546 return;
5548 if(m_target->GetTypeId() != TYPEID_PLAYER)
5549 return;
5551 Player *target = (Player*)m_target;
5553 // combo points was added in SPELL_EFFECT_ADD_COMBO_POINTS handler
5554 // remove only if aura expire by time (in case combo points amount change aura removed without combo points lost)
5555 if( !apply && m_duration==0 && target->GetComboTarget())
5556 if(Unit* unit = ObjectAccessor::GetUnit(*m_target,target->GetComboTarget()))
5557 target->AddComboPoints(unit, -m_modifier.m_amount);
5560 void Aura::HandleModUnattackable( bool Apply, bool Real )
5562 if(Real && Apply)
5563 m_target->CombatStop();
5565 m_target->ApplyModFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE,Apply);
5568 void Aura::HandleSpiritOfRedemption( bool apply, bool Real )
5570 // spells required only Real aura add/remove
5571 if(!Real)
5572 return;
5574 // prepare spirit state
5575 if(apply)
5577 if(m_target->GetTypeId()==TYPEID_PLAYER)
5579 // disable breath/etc timers
5580 ((Player*)m_target)->StopMirrorTimers();
5582 // set stand state (expected in this form)
5583 if(!m_target->IsStandState())
5584 m_target->SetStandState(PLAYER_STATE_NONE);
5587 m_target->SetHealth(1);
5589 // die at aura end
5590 else
5591 m_target->DealDamage(m_target, m_target->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, GetSpellProto(), false);
5594 void Aura::CleanupTriggeredSpells()
5596 uint32 tSpellId = m_spellProto->EffectTriggerSpell[GetEffIndex()];
5597 if(!tSpellId)
5598 return;
5600 SpellEntry const* tProto = sSpellStore.LookupEntry(tSpellId);
5601 if(!tProto)
5602 return;
5604 if(GetSpellDuration(tProto) != -1)
5605 return;
5607 // needed for spell 43680, maybe others
5608 // TODO: is there a spell flag, which can solve this in a more sophisticated way?
5609 if(m_spellProto->EffectApplyAuraName[GetEffIndex()] == SPELL_AURA_PERIODIC_TRIGGER_SPELL &&
5610 GetSpellDuration(m_spellProto) == m_spellProto->EffectAmplitude[GetEffIndex()])
5611 return;
5612 m_target->RemoveAurasDueToSpell(tSpellId);
5615 void Aura::HandleAuraPowerBurn(bool apply, bool Real)
5617 if (m_periodicTimer <= 0)
5618 m_periodicTimer += m_modifier.periodictime;
5620 m_isPeriodic = apply;
5623 void Aura::HandleSchoolAbsorb(bool apply, bool Real)
5625 if(!Real)
5626 return;
5628 // prevent double apply bonuses
5629 if(apply && (m_target->GetTypeId()!=TYPEID_PLAYER || !((Player*)m_target)->GetSession()->PlayerLoading()))
5631 if(Unit* caster = GetCaster())
5633 float DoneActualBenefit = 0.0f;
5634 switch(m_spellProto->SpellFamilyName)
5636 case SPELLFAMILY_PRIEST:
5637 if(m_spellProto->SpellFamilyFlags == 0x1) //PW:S
5639 //+30% from +healing bonus
5640 DoneActualBenefit = caster->SpellBaseHealingBonus(GetSpellSchoolMask(m_spellProto)) * 0.3f;
5641 break;
5643 break;
5644 case SPELLFAMILY_MAGE:
5645 if(m_spellProto->SpellFamilyFlags == 0x80100 || m_spellProto->SpellFamilyFlags == 0x8 || m_spellProto->SpellFamilyFlags == 0x100000000LL)
5647 //frost ward, fire ward, ice barrier
5648 //+10% from +spd bonus
5649 DoneActualBenefit = caster->SpellBaseDamageBonus(GetSpellSchoolMask(m_spellProto)) * 0.1f;
5650 break;
5652 break;
5653 case SPELLFAMILY_WARLOCK:
5654 if(m_spellProto->SpellFamilyFlags == 0x00)
5656 //shadow ward
5657 //+10% from +spd bonus
5658 DoneActualBenefit = caster->SpellBaseDamageBonus(GetSpellSchoolMask(m_spellProto)) * 0.1f;
5659 break;
5661 break;
5662 default:
5663 break;
5666 DoneActualBenefit *= caster->CalculateLevelPenalty(GetSpellProto());
5668 m_modifier.m_amount += (int32)DoneActualBenefit;
5673 void Aura::PeriodicTick()
5675 if(!m_target->isAlive())
5676 return;
5678 switch(m_modifier.m_auraname)
5680 case SPELL_AURA_PERIODIC_DAMAGE:
5681 case SPELL_AURA_PERIODIC_DAMAGE_PERCENT:
5683 Unit *pCaster = GetCaster();
5684 if(!pCaster)
5685 return;
5687 if( GetSpellProto()->Effect[GetEffIndex()]==SPELL_EFFECT_PERSISTENT_AREA_AURA &&
5688 pCaster->SpellHitResult(m_target,GetSpellProto(),false)!=SPELL_MISS_NONE)
5689 return;
5691 // Check for immune (not use charges)
5692 if(m_target->IsImmunedToDamage(GetSpellSchoolMask(GetSpellProto())))
5693 return;
5695 // some auras remove at specific health level or more
5696 if(m_modifier.m_auraname==SPELL_AURA_PERIODIC_DAMAGE)
5698 switch(GetId())
5700 case 43093: case 31956: case 38801:
5701 case 35321: case 38363: case 39215:
5702 if(m_target->GetHealth() == m_target->GetMaxHealth() )
5704 m_target->RemoveAurasDueToSpell(GetId());
5705 return;
5707 break;
5708 case 38772:
5710 uint32 percent =
5711 GetEffIndex() < 2 && GetSpellProto()->Effect[GetEffIndex()]==SPELL_EFFECT_DUMMY ?
5712 pCaster->CalculateSpellDamage(GetSpellProto(),GetEffIndex()+1,GetSpellProto()->EffectBasePoints[GetEffIndex()+1],m_target) :
5713 100;
5714 if(m_target->GetHealth()*100 >= m_target->GetMaxHealth()*percent )
5716 m_target->RemoveAurasDueToSpell(GetId());
5717 return;
5719 break;
5721 default:
5722 break;
5726 uint32 absorb=0;
5727 uint32 resist=0;
5728 CleanDamage cleanDamage = CleanDamage(0, BASE_ATTACK, MELEE_HIT_NORMAL );
5730 // ignore non positive values (can be result apply spellmods to aura damage
5731 uint32 amount = m_modifier.m_amount > 0 ? m_modifier.m_amount : 0;
5733 uint32 pdamage;
5735 if(m_modifier.m_auraname == SPELL_AURA_PERIODIC_DAMAGE)
5737 pdamage = amount;
5739 // Calculate armor mitigation if it is a physical spell
5740 // But not for bleed mechanic spells
5741 if ( GetSpellSchoolMask(GetSpellProto()) & SPELL_SCHOOL_MASK_NORMAL &&
5742 GetEffectMechanic(GetSpellProto(), m_effIndex) != MECHANIC_BLEED)
5744 uint32 pdamageReductedArmor = pCaster->CalcArmorReducedDamage(m_target, pdamage);
5745 cleanDamage.damage += pdamage - pdamageReductedArmor;
5746 pdamage = pdamageReductedArmor;
5749 pdamage = pCaster->SpellDamageBonus(m_target,GetSpellProto(),pdamage,DOT);
5751 // Curse of Agony damage-per-tick calculation
5752 if (GetSpellProto()->SpellFamilyName==SPELLFAMILY_WARLOCK && (GetSpellProto()->SpellFamilyFlags & 0x0000000000000400LL) && GetSpellProto()->SpellIconID==544)
5754 // 1..4 ticks, 1/2 from normal tick damage
5755 if (m_duration>=((m_maxduration-m_modifier.periodictime)*2/3))
5756 pdamage = pdamage/2;
5757 // 9..12 ticks, 3/2 from normal tick damage
5758 else if(m_duration<((m_maxduration-m_modifier.periodictime)/3))
5759 pdamage += (pdamage+1)/2; // +1 prevent 0.5 damage possible lost at 1..4 ticks
5760 // 5..8 ticks have normal tick damage
5763 else
5764 pdamage = uint32(m_target->GetMaxHealth()*amount/100);
5766 //As of 2.2 resilience reduces damage from DoT ticks as much as the chance to not be critically hit
5767 // Reduce dot damage from resilience for players
5768 if (m_target->GetTypeId()==TYPEID_PLAYER)
5769 pdamage-=((Player*)m_target)->GetDotDamageReduction(pdamage);
5771 pCaster->CalcAbsorbResist(m_target, GetSpellSchoolMask(GetSpellProto()), DOT, pdamage, &absorb, &resist);
5773 sLog.outDetail("PeriodicTick: %u (TypeId: %u) attacked %u (TypeId: %u) for %u dmg inflicted by %u abs is %u",
5774 GUID_LOPART(GetCasterGUID()), GuidHigh2TypeId(GUID_HIPART(GetCasterGUID())), m_target->GetGUIDLow(), m_target->GetTypeId(), pdamage, GetId(),absorb);
5776 WorldPacket data(SMSG_PERIODICAURALOG, (21+16));// we guess size
5777 data.append(m_target->GetPackGUID());
5778 data.appendPackGUID(GetCasterGUID());
5779 data << uint32(GetId());
5780 data << uint32(1);
5781 data << uint32(m_modifier.m_auraname);
5782 data << (uint32)pdamage;
5783 data << uint32(0); // overkill
5784 data << (uint32)GetSpellSchoolMask(GetSpellProto()); // will be mask in 2.4.x
5785 data << (uint32)absorb;
5786 data << (uint32)resist;
5787 m_target->SendMessageToSet(&data,true);
5789 Unit* target = m_target; // aura can be deleted in DealDamage
5790 SpellEntry const* spellProto = GetSpellProto();
5792 // Set trigger flag
5793 uint32 procAttacker = PROC_FLAG_ON_DO_PERIODIC;// | PROC_FLAG_SUCCESSFUL_HARMFUL_SPELL_HIT;
5794 uint32 procVictim = PROC_FLAG_ON_TAKE_PERIODIC;// | PROC_FLAG_TAKEN_HARMFUL_SPELL_HIT;
5795 pdamage = (pdamage <= absorb+resist) ? 0 : (pdamage-absorb-resist);
5796 if (pdamage)
5797 procVictim|=PROC_FLAG_TAKEN_ANY_DAMAGE;
5798 pCaster->ProcDamageAndSpell(target, procAttacker, procVictim, PROC_EX_NORMAL_HIT, pdamage, BASE_ATTACK, spellProto);
5800 pCaster->DealDamage(target, pdamage, &cleanDamage, DOT, GetSpellSchoolMask(spellProto), spellProto, true);
5801 break;
5803 case SPELL_AURA_PERIODIC_LEECH:
5805 Unit *pCaster = GetCaster();
5806 if(!pCaster)
5807 return;
5809 if(!pCaster->isAlive())
5810 return;
5812 if( GetSpellProto()->Effect[GetEffIndex()]==SPELL_EFFECT_PERSISTENT_AREA_AURA &&
5813 pCaster->SpellHitResult(m_target,GetSpellProto(),false)!=SPELL_MISS_NONE)
5814 return;
5816 // Check for immune (not use charges)
5817 if(m_target->IsImmunedToDamage(GetSpellSchoolMask(GetSpellProto())))
5818 return;
5820 uint32 absorb=0;
5821 uint32 resist=0;
5822 CleanDamage cleanDamage = CleanDamage(0, BASE_ATTACK, MELEE_HIT_NORMAL );
5824 uint32 pdamage = m_modifier.m_amount > 0 ? m_modifier.m_amount : 0;
5826 //Calculate armor mitigation if it is a physical spell
5827 if (GetSpellSchoolMask(GetSpellProto()) & SPELL_SCHOOL_MASK_NORMAL)
5829 uint32 pdamageReductedArmor = pCaster->CalcArmorReducedDamage(m_target, pdamage);
5830 cleanDamage.damage += pdamage - pdamageReductedArmor;
5831 pdamage = pdamageReductedArmor;
5834 pdamage = pCaster->SpellDamageBonus(m_target,GetSpellProto(),pdamage,DOT);
5836 // talent Soul Siphon add bonus to Drain Life spells
5837 if( GetSpellProto()->SpellFamilyName == SPELLFAMILY_WARLOCK && (GetSpellProto()->SpellFamilyFlags & 0x8) )
5839 // find talent max bonus percentage
5840 Unit::AuraList const& mClassScriptAuras = pCaster->GetAurasByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS);
5841 for(Unit::AuraList::const_iterator i = mClassScriptAuras.begin(); i != mClassScriptAuras.end(); ++i)
5843 if ((*i)->GetModifier()->m_miscvalue == 4992 || (*i)->GetModifier()->m_miscvalue == 4993)
5845 if((*i)->GetEffIndex()!=1)
5847 sLog.outError("Expected spell %u structure change, need code update",(*i)->GetId());
5848 break;
5851 // effect 1 m_amount
5852 int32 maxPercent = (*i)->GetModifier()->m_amount;
5853 // effect 0 m_amount
5854 int32 stepPercent = pCaster->CalculateSpellDamage((*i)->GetSpellProto(),0,(*i)->GetSpellProto()->EffectBasePoints[0],pCaster);
5856 // count affliction effects and calc additional damage in percentage
5857 int32 modPercent = 0;
5858 Unit::AuraMap const& victimAuras = m_target->GetAuras();
5859 for (Unit::AuraMap::const_iterator itr = victimAuras.begin(); itr != victimAuras.end(); ++itr)
5861 Aura* aura = itr->second;
5862 if (aura->IsPositive())continue;
5863 SpellEntry const* m_spell = aura->GetSpellProto();
5864 if (m_spell->SpellFamilyName != SPELLFAMILY_WARLOCK)
5865 continue;
5867 SkillLineAbilityMap::const_iterator lower = spellmgr.GetBeginSkillLineAbilityMap(m_spell->Id);
5868 SkillLineAbilityMap::const_iterator upper = spellmgr.GetEndSkillLineAbilityMap(m_spell->Id);
5870 for(SkillLineAbilityMap::const_iterator _spell_idx = lower; _spell_idx != upper; ++_spell_idx)
5872 if(_spell_idx->second->skillId == SKILL_AFFLICTION)
5874 modPercent += stepPercent;
5875 if (modPercent >= maxPercent)
5877 modPercent = maxPercent;
5878 break;
5883 pdamage += (pdamage*modPercent/100);
5884 break;
5889 //As of 2.2 resilience reduces damage from DoT ticks as much as the chance to not be critically hit
5890 // Reduce dot damage from resilience for players
5891 if (m_target->GetTypeId()==TYPEID_PLAYER)
5892 pdamage-=((Player*)m_target)->GetDotDamageReduction(pdamage);
5894 pCaster->CalcAbsorbResist(m_target, GetSpellSchoolMask(GetSpellProto()), DOT, pdamage, &absorb, &resist);
5896 if(m_target->GetHealth() < pdamage)
5897 pdamage = uint32(m_target->GetHealth());
5899 sLog.outDetail("PeriodicTick: %u (TypeId: %u) health leech of %u (TypeId: %u) for %u dmg inflicted by %u abs is %u",
5900 GUID_LOPART(GetCasterGUID()), GuidHigh2TypeId(GUID_HIPART(GetCasterGUID())), m_target->GetGUIDLow(), m_target->GetTypeId(), pdamage, GetId(),absorb);
5902 pCaster->SendSpellNonMeleeDamageLog(m_target, GetId(), pdamage, GetSpellSchoolMask(GetSpellProto()), absorb, resist, false, 0);
5905 Unit* target = m_target; // aura can be deleted in DealDamage
5906 SpellEntry const* spellProto = GetSpellProto();
5907 float multiplier = spellProto->EffectMultipleValue[GetEffIndex()] > 0 ? spellProto->EffectMultipleValue[GetEffIndex()] : 1;
5909 // Set trigger flag
5910 uint32 procAttacker = PROC_FLAG_ON_DO_PERIODIC;// | PROC_FLAG_SUCCESSFUL_HARMFUL_SPELL_HIT;
5911 uint32 procVictim = PROC_FLAG_ON_TAKE_PERIODIC;// | PROC_FLAG_TAKEN_HARMFUL_SPELL_HIT;
5912 pdamage = (pdamage <= absorb+resist) ? 0 : (pdamage-absorb-resist);
5913 if (pdamage)
5914 procVictim|=PROC_FLAG_TAKEN_ANY_DAMAGE;
5915 pCaster->ProcDamageAndSpell(target, procAttacker, procVictim, PROC_EX_NORMAL_HIT, pdamage, BASE_ATTACK, spellProto);
5916 int32 new_damage = pCaster->DealDamage(target, pdamage, &cleanDamage, DOT, GetSpellSchoolMask(spellProto), spellProto, false);
5918 if (!target->isAlive() && pCaster->IsNonMeleeSpellCasted(false))
5920 for (uint32 i = CURRENT_FIRST_NON_MELEE_SPELL; i < CURRENT_MAX_SPELL; i++)
5922 if (pCaster->m_currentSpells[i] && pCaster->m_currentSpells[i]->m_spellInfo->Id == spellProto->Id)
5923 pCaster->m_currentSpells[i]->cancel();
5928 if(Player *modOwner = pCaster->GetSpellModOwner())
5929 modOwner->ApplySpellMod(spellProto->Id, SPELLMOD_MULTIPLE_VALUE, multiplier);
5931 uint32 heal = pCaster->SpellHealingBonus(spellProto, uint32(new_damage * multiplier), DOT, pCaster);
5933 int32 gain = pCaster->ModifyHealth(heal);
5934 pCaster->getHostilRefManager().threatAssist(pCaster, gain * 0.5f, spellProto);
5936 pCaster->SendHealSpellLog(pCaster, spellProto->Id, heal);
5937 break;
5939 case SPELL_AURA_PERIODIC_HEAL:
5940 case SPELL_AURA_OBS_MOD_HEALTH:
5942 Unit *pCaster = GetCaster();
5943 if(!pCaster)
5944 return;
5946 // heal for caster damage (must be alive)
5947 if(m_target != pCaster && GetSpellProto()->SpellVisual[0]==163 && !pCaster->isAlive())
5948 return;
5950 // ignore non positive values (can be result apply spellmods to aura damage
5951 uint32 amount = m_modifier.m_amount > 0 ? m_modifier.m_amount : 0;
5953 uint32 pdamage;
5955 if(m_modifier.m_auraname==SPELL_AURA_OBS_MOD_HEALTH)
5956 pdamage = uint32(m_target->GetMaxHealth() * amount/100);
5957 else
5958 pdamage = amount;
5960 pdamage = pCaster->SpellHealingBonus(GetSpellProto(), pdamage, DOT, m_target);
5962 sLog.outDetail("PeriodicTick: %u (TypeId: %u) heal of %u (TypeId: %u) for %u health inflicted by %u",
5963 GUID_LOPART(GetCasterGUID()), GuidHigh2TypeId(GUID_HIPART(GetCasterGUID())), m_target->GetGUIDLow(), m_target->GetTypeId(), pdamage, GetId());
5965 WorldPacket data(SMSG_PERIODICAURALOG, (21+16));// we guess size
5966 data.append(m_target->GetPackGUID());
5967 data.appendPackGUID(GetCasterGUID());
5968 data << uint32(GetId());
5969 data << uint32(1);
5970 data << uint32(m_modifier.m_auraname);
5971 data << (uint32)pdamage;
5972 data << uint32(0); // wotlk
5973 m_target->SendMessageToSet(&data,true);
5975 int32 gain = m_target->ModifyHealth(pdamage);
5977 // add HoTs to amount healed in bgs
5978 if( pCaster->GetTypeId() == TYPEID_PLAYER )
5979 if( BattleGround *bg = ((Player*)pCaster)->GetBattleGround() )
5980 bg->UpdatePlayerScore(((Player*)pCaster), SCORE_HEALING_DONE, gain);
5982 //Do check before because m_modifier.auraName can be invalidate by DealDamage.
5983 bool procSpell = (m_modifier.m_auraname == SPELL_AURA_PERIODIC_HEAL && m_target != pCaster);
5985 m_target->getHostilRefManager().threatAssist(pCaster, float(gain) * 0.5f, GetSpellProto());
5987 Unit* target = m_target; // aura can be deleted in DealDamage
5988 SpellEntry const* spellProto = GetSpellProto();
5989 bool haveCastItem = GetCastItemGUID()!=0;
5991 // heal for caster damage
5992 if(m_target!=pCaster && spellProto->SpellVisual[0]==163)
5994 uint32 dmg = spellProto->manaPerSecond;
5995 if(pCaster->GetHealth() <= dmg && pCaster->GetTypeId()==TYPEID_PLAYER)
5997 pCaster->RemoveAurasDueToSpell(GetId());
5999 // finish current generic/channeling spells, don't affect autorepeat
6000 if(pCaster->m_currentSpells[CURRENT_GENERIC_SPELL])
6002 pCaster->m_currentSpells[CURRENT_GENERIC_SPELL]->finish();
6004 if(pCaster->m_currentSpells[CURRENT_CHANNELED_SPELL])
6006 pCaster->m_currentSpells[CURRENT_CHANNELED_SPELL]->SendChannelUpdate(0);
6007 pCaster->m_currentSpells[CURRENT_CHANNELED_SPELL]->finish();
6010 else
6012 pCaster->SendSpellNonMeleeDamageLog(pCaster, GetId(), gain, GetSpellSchoolMask(GetSpellProto()), 0, 0, false, 0, false);
6014 CleanDamage cleanDamage = CleanDamage(0, BASE_ATTACK, MELEE_HIT_NORMAL );
6015 pCaster->DealDamage(pCaster, gain, &cleanDamage, NODAMAGE, GetSpellSchoolMask(GetSpellProto()), GetSpellProto(), true);
6019 uint32 procAttacker = PROC_FLAG_ON_DO_PERIODIC;// | PROC_FLAG_SUCCESSFUL_HEAL;
6020 uint32 procVictim = 0;//ROC_FLAG_ON_TAKE_PERIODIC | PROC_FLAG_TAKEN_HEAL;
6021 // ignore item heals
6022 // if(procSpell && !haveCastItem)
6023 // pCaster->ProcDamageAndSpell(target, procAttacker, procVictim, PROC_EX_NORMAL_HIT, pdamage, BASE_ATTACK, spellProto);
6024 break;
6026 case SPELL_AURA_PERIODIC_MANA_LEECH:
6028 Unit *pCaster = GetCaster();
6029 if(!pCaster)
6030 return;
6032 if(!pCaster->isAlive())
6033 return;
6035 if( GetSpellProto()->Effect[GetEffIndex()]==SPELL_EFFECT_PERSISTENT_AREA_AURA &&
6036 pCaster->SpellHitResult(m_target,GetSpellProto(),false)!=SPELL_MISS_NONE)
6037 return;
6039 // Check for immune (not use charges)
6040 if(m_target->IsImmunedToDamage(GetSpellSchoolMask(GetSpellProto())))
6041 return;
6043 // ignore non positive values (can be result apply spellmods to aura damage
6044 uint32 pdamage = m_modifier.m_amount > 0 ? m_modifier.m_amount : 0;
6046 sLog.outDetail("PeriodicTick: %u (TypeId: %u) power leech of %u (TypeId: %u) for %u dmg inflicted by %u",
6047 GUID_LOPART(GetCasterGUID()), GuidHigh2TypeId(GUID_HIPART(GetCasterGUID())), m_target->GetGUIDLow(), m_target->GetTypeId(), pdamage, GetId());
6049 if(m_modifier.m_miscvalue < 0 || m_modifier.m_miscvalue > 4)
6050 break;
6052 Powers power = Powers(m_modifier.m_miscvalue);
6054 // power type might have changed between aura applying and tick (druid's shapeshift)
6055 if(m_target->getPowerType() != power)
6056 break;
6058 int32 drain_amount = m_target->GetPower(power) > pdamage ? pdamage : m_target->GetPower(power);
6060 // resilience reduce mana draining effect at spell crit damage reduction (added in 2.4)
6061 if (power == POWER_MANA && m_target->GetTypeId() == TYPEID_PLAYER)
6062 drain_amount -= ((Player*)m_target)->GetSpellCritDamageReduction(drain_amount);
6064 m_target->ModifyPower(power, -drain_amount);
6066 float gain_multiplier = 0;
6068 if(pCaster->GetMaxPower(power) > 0)
6070 gain_multiplier = GetSpellProto()->EffectMultipleValue[GetEffIndex()];
6072 if(Player *modOwner = pCaster->GetSpellModOwner())
6073 modOwner->ApplySpellMod(GetId(), SPELLMOD_MULTIPLE_VALUE, gain_multiplier);
6076 WorldPacket data(SMSG_PERIODICAURALOG, (21+16));// we guess size
6077 data.append(m_target->GetPackGUID());
6078 data.appendPackGUID(GetCasterGUID());
6079 data << uint32(GetId());
6080 data << uint32(1);
6081 data << uint32(m_modifier.m_auraname);
6082 data << (uint32)power; // power type
6083 data << (uint32)drain_amount;
6084 data << (float)gain_multiplier;
6085 m_target->SendMessageToSet(&data,true);
6087 int32 gain_amount = int32(drain_amount*gain_multiplier);
6089 if(gain_amount)
6091 int32 gain = pCaster->ModifyPower(power,gain_amount);
6092 m_target->AddThreat(pCaster, float(gain) * 0.5f, GetSpellSchoolMask(GetSpellProto()), GetSpellProto());
6094 break;
6096 case SPELL_AURA_PERIODIC_ENERGIZE:
6098 // ignore non positive values (can be result apply spellmods to aura damage
6099 uint32 pdamage = m_modifier.m_amount > 0 ? m_modifier.m_amount : 0;
6101 sLog.outDetail("PeriodicTick: %u (TypeId: %u) energize %u (TypeId: %u) for %u dmg inflicted by %u",
6102 GUID_LOPART(GetCasterGUID()), GuidHigh2TypeId(GUID_HIPART(GetCasterGUID())), m_target->GetGUIDLow(), m_target->GetTypeId(), pdamage, GetId());
6104 if(m_modifier.m_miscvalue < 0 || m_modifier.m_miscvalue > 4)
6105 break;
6107 Powers power = Powers(m_modifier.m_miscvalue);
6109 if(m_target->GetMaxPower(power) == 0)
6110 break;
6112 WorldPacket data(SMSG_PERIODICAURALOG, (21+16));// we guess size
6113 data.append(m_target->GetPackGUID());
6114 data.appendPackGUID(GetCasterGUID());
6115 data << uint32(GetId());
6116 data << uint32(1);
6117 data << uint32(m_modifier.m_auraname);
6118 data << (uint32)power; // power type
6119 data << (uint32)pdamage;
6120 m_target->SendMessageToSet(&data,true);
6122 int32 gain = m_target->ModifyPower(power,pdamage);
6124 if(Unit* pCaster = GetCaster())
6125 m_target->getHostilRefManager().threatAssist(pCaster, float(gain) * 0.5f, GetSpellProto());
6126 break;
6128 case SPELL_AURA_OBS_MOD_MANA:
6130 // ignore non positive values (can be result apply spellmods to aura damage
6131 uint32 amount = m_modifier.m_amount > 0 ? m_modifier.m_amount : 0;
6133 uint32 pdamage = uint32(m_target->GetMaxPower(POWER_MANA) * amount/100);
6135 sLog.outDetail("PeriodicTick: %u (TypeId: %u) energize %u (TypeId: %u) for %u mana inflicted by %u",
6136 GUID_LOPART(GetCasterGUID()), GuidHigh2TypeId(GUID_HIPART(GetCasterGUID())), m_target->GetGUIDLow(), m_target->GetTypeId(), pdamage, GetId());
6138 if(m_target->GetMaxPower(POWER_MANA) == 0)
6139 break;
6141 WorldPacket data(SMSG_PERIODICAURALOG, (21+16));// we guess size
6142 data.append(m_target->GetPackGUID());
6143 data.appendPackGUID(GetCasterGUID());
6144 data << uint32(GetId());
6145 data << uint32(1);
6146 data << uint32(m_modifier.m_auraname);
6147 data << (uint32)0; // ?
6148 data << (uint32)pdamage;
6149 m_target->SendMessageToSet(&data,true);
6151 int32 gain = m_target->ModifyPower(POWER_MANA, pdamage);
6153 if(Unit* pCaster = GetCaster())
6154 m_target->getHostilRefManager().threatAssist(pCaster, float(gain) * 0.5f, GetSpellProto());
6155 break;
6157 case SPELL_AURA_POWER_BURN_MANA:
6159 Unit *pCaster = GetCaster();
6160 if(!pCaster)
6161 return;
6163 // Check for immune (not use charges)
6164 if(m_target->IsImmunedToDamage(GetSpellSchoolMask(GetSpellProto())))
6165 return;
6167 int32 pdamage = m_modifier.m_amount > 0 ? m_modifier.m_amount : 0;
6169 Powers powerType = Powers(m_modifier.m_miscvalue);
6171 if(!m_target->isAlive() || m_target->getPowerType() != powerType)
6172 return;
6174 // resilience reduce mana draining effect at spell crit damage reduction (added in 2.4)
6175 if (powerType == POWER_MANA && m_target->GetTypeId() == TYPEID_PLAYER)
6176 pdamage -= ((Player*)m_target)->GetSpellCritDamageReduction(pdamage);
6178 uint32 gain = uint32(-m_target->ModifyPower(powerType, -pdamage));
6180 gain = uint32(gain * GetSpellProto()->EffectMultipleValue[GetEffIndex()]);
6182 SpellEntry const* spellProto = GetSpellProto();
6183 //maybe has to be sent different to client, but not by SMSG_PERIODICAURALOG
6184 SpellNonMeleeDamage damageInfo(pCaster, m_target, spellProto->Id, spellProto->SchoolMask);
6185 pCaster->CalculateSpellDamage(&damageInfo, gain, spellProto);
6186 pCaster->SendSpellNonMeleeDamageLog(&damageInfo);
6188 // Set trigger flag
6189 uint32 procAttacker = PROC_FLAG_ON_DO_PERIODIC;// | PROC_FLAG_SUCCESSFUL_HARMFUL_SPELL_HIT;
6190 uint32 procVictim = PROC_FLAG_ON_TAKE_PERIODIC;// | PROC_FLAG_TAKEN_HARMFUL_SPELL_HIT;
6191 uint32 procEx = createProcExtendMask(&damageInfo, SPELL_MISS_NONE);
6192 if (damageInfo.damage)
6193 procVictim|=PROC_FLAG_TAKEN_ANY_DAMAGE;
6195 pCaster->ProcDamageAndSpell(damageInfo.target, procAttacker, procVictim, procEx, damageInfo.damage, BASE_ATTACK, spellProto);
6197 pCaster->DealSpellDamage(&damageInfo, true);
6198 break;
6200 // Here tick dummy auras
6201 case SPELL_AURA_PERIODIC_DUMMY:
6203 PeriodicDummyTick();
6204 break;
6206 default:
6207 break;
6211 void Aura::PeriodicDummyTick()
6213 Unit *caster = GetCaster();
6214 SpellEntry const* spell = GetSpellProto();
6215 switch (spell->SpellFamilyName)
6217 case SPELLFAMILY_GENERIC:
6218 switch (spell->Id)
6220 // Drink
6221 case 430:
6222 case 431:
6223 case 432:
6224 case 1133:
6225 case 1135:
6226 case 1137:
6227 case 10250:
6228 case 22734:
6229 case 27089:
6230 case 34291:
6231 case 43706:
6232 case 46755:
6233 case 49472: // Drink Coffee
6234 case 61830:
6236 if (m_target->GetTypeId() != TYPEID_PLAYER)
6237 return;
6238 // Search SPELL_AURA_MOD_POWER_REGEN aura for this spell and add bonus
6239 Unit::AuraList const& aura = m_target->GetAurasByType(SPELL_AURA_MOD_POWER_REGEN);
6240 for(Unit::AuraList::const_iterator i = aura.begin(); i != aura.end(); ++i)
6242 if ((*i)->GetId() == GetId())
6244 // Get tick number
6245 int32 tick = (m_maxduration - m_duration) / m_modifier.periodictime;
6246 // Default case (not on arenas)
6247 if (tick == 0)
6249 (*i)->GetModifier()->m_amount = m_modifier.m_amount;
6250 ((Player*)m_target)->UpdateManaRegen();
6251 // Disable continue
6252 m_isPeriodic = false;
6254 return;
6255 //**********************************************
6256 // Code commended since arena patch not added
6257 // This feature uses only in arenas
6258 //**********************************************
6259 // Here need increase mana regen per tick (6 second rule)
6260 // on 0 tick - 0 (handled in 2 second)
6261 // on 1 tick - 166% (handled in 4 second)
6262 // on 2 tick - 133% (handled in 6 second)
6263 // Not need update after 3 tick
6265 if (tick > 3)
6266 return;
6267 // Apply bonus for 0 - 3 tick
6268 switch (tick)
6270 case 0: // 0%
6271 (*i)->GetModifier()->m_amount = m_modifier.m_amount = 0;
6272 break;
6273 case 1: // 166%
6274 (*i)->GetModifier()->m_amount = m_modifier.m_amount * 5 / 3;
6275 break;
6276 case 2: // 133%
6277 (*i)->GetModifier()->m_amount = m_modifier.m_amount * 4 / 3;
6278 break;
6279 default: // 100% - normal regen
6280 (*i)->GetModifier()->m_amount = m_modifier.m_amount;
6281 break;
6283 ((Player*)m_target)->UpdateManaRegen();
6284 return;*/
6287 return;
6289 // Forsaken Skills
6290 case 7054:
6292 // Possibly need cast one of them (but
6293 // 7038 Forsaken Skill: Swords
6294 // 7039 Forsaken Skill: Axes
6295 // 7040 Forsaken Skill: Daggers
6296 // 7041 Forsaken Skill: Maces
6297 // 7042 Forsaken Skill: Staves
6298 // 7043 Forsaken Skill: Bows
6299 // 7044 Forsaken Skill: Guns
6300 // 7045 Forsaken Skill: 2H Axes
6301 // 7046 Forsaken Skill: 2H Maces
6302 // 7047 Forsaken Skill: 2H Swords
6303 // 7048 Forsaken Skill: Defense
6304 // 7049 Forsaken Skill: Fire
6305 // 7050 Forsaken Skill: Frost
6306 // 7051 Forsaken Skill: Holy
6307 // 7053 Forsaken Skill: Shadow
6308 return;
6310 // // Panda
6311 // case 19230: break;
6312 // // Gossip NPC Periodic - Talk
6313 // case 33208: break;
6314 // // Gossip NPC Periodic - Despawn
6315 // case 33209: break;
6317 // TODO: now its not periodic dummy - need move out from here
6318 // Aspect of the Viper
6319 case 34074:
6321 if (m_target->GetTypeId() != TYPEID_PLAYER)
6322 return;
6323 // Should be manauser
6324 if (m_target->getPowerType()!=POWER_MANA)
6325 return;
6326 if (!caster)
6327 return;
6328 // Regen amount is max (100% from spell) on 21% or less mana and min on 92.5% or greater mana (20% from spell)
6329 int mana = m_target->GetPower(POWER_MANA);
6330 int max_mana = m_target->GetMaxPower(POWER_MANA);
6331 int32 base_regen = caster->CalculateSpellDamage(m_spellProto, m_effIndex, m_currentBasePoints, m_target);
6332 float regen_pct = 1.20f - 1.1f * mana / max_mana;
6333 if (regen_pct > 1.0f) regen_pct = 1.0f;
6334 else if (regen_pct < 0.2f) regen_pct = 0.2f;
6335 m_modifier.m_amount = int32 (base_regen * regen_pct);
6336 ((Player*)m_target)->UpdateManaRegen();
6337 return;
6339 // // Steal Weapon
6340 // case 36207: break;
6341 // // Simon Game START timer, (DND)
6342 // case 39993: break;
6343 // // Knockdown Fel Cannon: break; The Aggro Burst
6344 // case 40119: break;
6345 // // Old Mount Spell
6346 // case 40154: break;
6347 // // Magnetic Pull
6348 // case 40581: break;
6349 // // Ethereal Ring: break; The Bolt Burst
6350 // case 40801: break;
6351 // // Crystal Prison
6352 // case 40846: break;
6353 // // Copy Weapon
6354 // case 41054: break;
6355 // // Dementia
6356 // case 41404: break;
6357 // // Ethereal Ring Visual, Lightning Aura
6358 // case 41477: break;
6359 // // Ethereal Ring Visual, Lightning Aura (Fork)
6360 // case 41525: break;
6361 // // Ethereal Ring Visual, Lightning Jumper Aura
6362 // case 41567: break;
6363 // // No Man's Land
6364 // case 41955: break;
6365 // // Headless Horseman - Fire
6366 // case 42074: break;
6367 // // Headless Horseman - Visual - Large Fire
6368 // case 42075: break;
6369 // // Headless Horseman - Start Fire, Periodic Aura
6370 // case 42140: break;
6371 // // Ram Speed Boost
6372 // case 42152: break;
6373 // // Headless Horseman - Fires Out Victory Aura
6374 // case 42235: break;
6375 // // Pumpkin Life Cycle
6376 // case 42280: break;
6377 // // Brewfest Request Chick Chuck Mug Aura
6378 // case 42537: break;
6379 // // Squashling
6380 // case 42596: break;
6381 // // Headless Horseman Climax, Head: Periodic
6382 // case 42603: break;
6383 // // Fire Bomb
6384 // case 42621: break;
6385 // // Headless Horseman - Conflagrate, Periodic Aura
6386 // case 42637: break;
6387 // // Headless Horseman - Create Pumpkin Treats Aura
6388 // case 42774: break;
6389 // // Headless Horseman Climax - Summoning Rhyme Aura
6390 // case 42879: break;
6391 // // Tricky Treat
6392 // case 42919: break;
6393 // // Giddyup!
6394 // case 42924: break;
6395 // // Ram - Trot
6396 // case 42992: break;
6397 // // Ram - Canter
6398 // case 42993: break;
6399 // // Ram - Gallop
6400 // case 42994: break;
6401 // // Ram Level - Neutral
6402 // case 43310: break;
6403 // // Headless Horseman - Maniacal Laugh, Maniacal, Delayed 17
6404 // case 43884: break;
6405 // // Wretched!
6406 // case 43963: break;
6407 // // Headless Horseman - Maniacal Laugh, Maniacal, other, Delayed 17
6408 // case 44000: break;
6409 // // Energy Feedback
6410 // case 44328: break;
6411 // // Romantic Picnic
6412 // case 45102: break;
6413 // // Romantic Picnic
6414 // case 45123: break;
6415 // // Looking for Love
6416 // case 45124: break;
6417 // // Kite - Lightning Strike Kite Aura
6418 // case 45197: break;
6419 // // Rocket Chicken
6420 // case 45202: break;
6421 // // Copy Offhand Weapon
6422 // case 45205: break;
6423 // // Upper Deck - Kite - Lightning Periodic Aura
6424 // case 45207: break;
6425 // // Kite -Sky Lightning Strike Kite Aura
6426 // case 45251: break;
6427 // // Ribbon Pole Dancer Check Aura
6428 // case 45390: break;
6429 // // Holiday - Midsummer, Ribbon Pole Periodic Visual
6430 // case 45406: break;
6431 // // Parachute
6432 // case 45472: break;
6433 // // Alliance Flag, Extra Damage Debuff
6434 // case 45898: break;
6435 // // Horde Flag, Extra Damage Debuff
6436 // case 45899: break;
6437 // // Ahune - Summoning Rhyme Aura
6438 // case 45926: break;
6439 // // Ahune - Slippery Floor
6440 // case 45945: break;
6441 // // Ahune's Shield
6442 // case 45954: break;
6443 // // Nether Vapor Lightning
6444 // case 45960: break;
6445 // // Darkness
6446 // case 45996: break;
6447 // // Summon Blood Elves Periodic
6448 // case 46041: break;
6449 // // Transform Visual Missile Periodic
6450 // case 46205: break;
6451 // // Find Opening Beam End
6452 // case 46333: break;
6453 // // Ice Spear Control Aura
6454 // case 46371: break;
6455 // // Hailstone Chill
6456 // case 46458: break;
6457 // // Hailstone Chill, Internal
6458 // case 46465: break;
6459 // // Chill, Internal Shifter
6460 // case 46549: break;
6461 // // Summon Ice Spear Knockback Delayer
6462 // case 46878: break;
6463 // // Burninate Effect
6464 // case 47214: break;
6465 // // Fizzcrank Practice Parachute
6466 // case 47228: break;
6467 // // Send Mug Control Aura
6468 // case 47369: break;
6469 // // Direbrew's Disarm (precast)
6470 // case 47407: break;
6471 // // Mole Machine Port Schedule
6472 // case 47489: break;
6473 // case 47941: break; // Crystal Spike
6474 // case 48200: break; // Healer Aura
6475 // case 48630: break; // Summon Gauntlet Mobs Periodic
6476 // case 49313: break; // Proximity Mine Area Aura
6477 // // Mole Machine Portal Schedule
6478 // case 49466: break;
6479 // case 49555: break; // Corpse Explode
6480 // case 49592: break; // Temporal Rift
6481 // case 49957: break; // Cutting Laser
6482 // case 50085: break; // Slow Fall
6483 // // Listening to Music
6484 // case 50493: break;
6485 // // Love Rocket Barrage
6486 // case 50530: break;
6487 // Exist more after, need add later
6488 default:
6489 break;
6491 break;
6492 case SPELLFAMILY_MAGE:
6494 // Mirror Image
6495 // if (spell->Id == 55342)
6496 // return;
6497 break;
6499 case SPELLFAMILY_WARRIOR:
6501 // Armored to the Teeth
6502 if (spell->SpellIconID == 3516)
6504 // Increases your attack power by $s1 for every $s2 armor value you have.
6505 // Calculate AP bonus (from 1 efect of this spell)
6506 int32 apBonus = m_modifier.m_amount * m_target->GetArmor() / m_target->CalculateSpellDamage(spell, 1, spell->EffectBasePoints[1], m_target);
6507 m_target->CastCustomSpell(m_target, 61217, &apBonus, &apBonus, 0, true, 0, this);
6508 return;
6510 break;
6512 case SPELLFAMILY_DRUID:
6514 switch (spell->Id)
6516 // Frenzied Regeneration
6517 case 22842:
6519 // Converts up to 10 rage per second into health for $d. Each point of rage is converted into ${$m2/10}.1% of max health.
6520 // Should be manauser
6521 if (m_target->getPowerType()!=POWER_RAGE)
6522 return;
6523 uint32 rage = m_target->GetPower(POWER_RAGE);
6524 // Nothing todo
6525 if (rage == 0)
6526 return;
6527 int32 mod = (rage < 100) ? rage : 100;
6528 int32 points = m_target->CalculateSpellDamage(spell, 1, spell->EffectBasePoints[1], m_target);
6529 int32 regen = m_target->GetMaxHealth() * (mod * points / 10) / 1000;
6530 m_target->CastCustomSpell(m_target, 22845, &regen, 0, 0, true, 0, this);
6531 m_target->SetPower(POWER_RAGE, rage-mod);
6532 return;
6534 // Force of Nature
6535 case 33831:
6536 return;
6537 default:
6538 break;
6540 break;
6542 case SPELLFAMILY_ROGUE:
6544 // switch (spell->Id)
6545 // {
6546 // Master of Subtlety
6547 // case 31666: break;
6548 // Killing Spree
6549 // case 51690: break;
6550 // Overkill
6551 // case 58428: break;
6552 // default:
6553 // break;
6554 // }
6555 break;
6557 case SPELLFAMILY_HUNTER:
6559 // Explosive Shot
6560 if (spell->SpellFamilyFlags & 0x8000000000000000LL)
6562 if (!caster)
6563 return;
6564 // Skip 0 tick
6565 if (m_duration < m_modifier.periodictime)
6566 return;
6567 int32 damage = caster->CalculateSpellDamage(spell, GetEffIndex(), GetBasePoints(), m_target);
6568 damage+=caster->GetTotalAttackPowerValue(RANGED_ATTACK) * 8 / 100;
6569 damage/=4;
6570 caster->CastCustomSpell(m_target, 56298, &damage, 0, 0, true, 0, this);
6571 return;
6573 switch (spell->Id)
6575 // Harpooner's Mark
6576 // case 40084:
6577 // return;
6578 // Feeding Frenzy Rank 1
6579 case 53511:
6580 if ( m_target->GetHealth() * 100 < m_target->GetMaxHealth() * 35 )
6581 m_target->CastSpell(m_target, 60096, true, 0, this);
6582 return;
6583 // Feeding Frenzy Rank 2
6584 case 53512:
6585 if ( m_target->GetHealth() * 100 < m_target->GetMaxHealth() * 35 )
6586 m_target->CastSpell(m_target, 60097, true, 0, this);
6587 return;
6588 default:
6589 break;
6591 break;
6593 case SPELLFAMILY_SHAMAN:
6595 // Astral Shift
6596 // if (spell->Id == 52179)
6597 // return;
6598 break;
6600 case SPELLFAMILY_DEATHKNIGHT:
6602 // Death and Decay
6603 // if (spell->SpellFamilyFlags & 0x0000000000000020LL)
6604 // return;
6605 // Raise Dead
6606 // if (spell->SpellFamilyFlags & 0x0000000000001000LL)
6607 // return;
6608 // Chains of Ice
6609 if (spell->SpellFamilyFlags & 0x0000400000000000LL)
6611 // Get 0 effect aura
6612 Aura *slow = m_target->GetAura(GetId(), 0);
6613 if (slow)
6615 slow->ApplyModifier(false, true);
6616 Modifier *mod = slow->GetModifier();
6617 mod->m_amount+= m_modifier.m_amount;
6618 if (mod->m_amount > 0) mod->m_amount = 0;
6619 slow->ApplyModifier(true, true);
6621 return;
6623 // Summon Gargoyle
6624 // if (spell->SpellFamilyFlags & 0x0000008000000000LL)
6625 // return;
6626 // Death Rune Mastery
6627 // if (spell->SpellFamilyFlags & 0x0000000000004000LL)
6628 // return;
6629 // Bladed Armor
6630 if (spell->SpellIconID == 2653)
6632 // Increases your attack power by $s1 for every $s2 armor value you have.
6633 // Calculate AP bonus (from 1 efect of this spell)
6634 int32 apBonus = m_modifier.m_amount * m_target->GetArmor() / m_target->CalculateSpellDamage(spell, 1, spell->EffectBasePoints[1], m_target);
6635 m_target->CastCustomSpell(m_target, 61217, &apBonus, &apBonus, 0, true, 0, this);
6636 return;
6638 // Reaping
6639 // if (spell->SpellIconID == 22)
6640 // return;
6641 // Blood of the North
6642 // if (spell->SpellIconID == 30412)
6643 // return;
6644 break;
6646 default:
6647 break;
6651 void Aura::HandlePreventFleeing(bool apply, bool Real)
6653 if(!Real)
6654 return;
6656 Unit::AuraList const& fearAuras = m_target->GetAurasByType(SPELL_AURA_MOD_FEAR);
6657 if( !fearAuras.empty() )
6659 if (apply)
6660 m_target->SetFeared(false, fearAuras.front()->GetCasterGUID());
6661 else
6662 m_target->SetFeared(true);
6666 void Aura::HandleManaShield(bool apply, bool Real)
6668 if(!Real)
6669 return;
6671 // prevent double apply bonuses
6672 if(apply && (m_target->GetTypeId()!=TYPEID_PLAYER || !((Player*)m_target)->GetSession()->PlayerLoading()))
6674 if(Unit* caster = GetCaster())
6676 float DoneActualBenefit = 0.0f;
6677 switch(m_spellProto->SpellFamilyName)
6679 case SPELLFAMILY_MAGE:
6680 if(m_spellProto->SpellFamilyFlags & 0x8000)
6682 // Mana Shield
6683 // +50% from +spd bonus
6684 DoneActualBenefit = caster->SpellBaseDamageBonus(GetSpellSchoolMask(m_spellProto)) * 0.5f;
6685 break;
6687 break;
6688 default:
6689 break;
6692 DoneActualBenefit *= caster->CalculateLevelPenalty(GetSpellProto());
6694 m_modifier.m_amount += (int32)DoneActualBenefit;
6699 void Aura::HandleArenaPreparation(bool apply, bool Real)
6701 if(!Real)
6702 return;
6704 if(apply)
6705 m_target->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PREPARATION);
6706 else
6707 m_target->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PREPARATION);
6710 void Aura::HandleAuraControlVehicle(bool apply, bool Real)
6712 if(!Real)
6713 return;
6715 if(m_target->GetTypeId() != TYPEID_PLAYER)
6716 return;
6718 if(Pet *pet = m_target->GetPet())
6719 pet->Remove(PET_SAVE_AS_CURRENT);
6721 WorldPacket data(SMSG_ON_CANCEL_EXPECTED_RIDE_VEHICLE_AURA, 0);
6722 ((Player*)m_target)->GetSession()->SendPacket(&data);
6725 void Aura::HandleAuraConvertRune(bool apply, bool Real)
6727 if(!Real)
6728 return;
6730 if(m_target->GetTypeId() != TYPEID_PLAYER)
6731 return;
6733 Player *plr = (Player*)m_target;
6735 if(plr->getClass() != CLASS_DEATH_KNIGHT)
6736 return;
6738 // how to determine what rune need to be converted?
6739 for(uint32 i = 0; i < MAX_RUNES; ++i)
6741 if(apply)
6743 if(!plr->GetRuneCooldown(i))
6745 plr->ConvertRune(i, GetSpellProto()->EffectMiscValueB[m_effIndex]);
6746 break;
6749 else
6751 if(plr->GetCurrentRune(i) == GetSpellProto()->EffectMiscValueB[m_effIndex])
6753 plr->ConvertRune(i, plr->GetBaseRune(i));
6754 break;