[3154] - Applied MaNGOS coding style (see trunk/bcpp.cfg).
[mangos-git.git] / src / game / SpellAuras.cpp
blob4bb91e912232b0cc692361294668ba4ea2d03a1a
1 /*
2 * Copyright (C) 2005,2006,2007 MaNGOS <http://www.mangosproject.org/>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 #include "Common.h"
20 #include "Database/DatabaseEnv.h"
21 #include "WorldPacket.h"
22 #include "WorldSession.h"
23 #include "Opcodes.h"
24 #include "Log.h"
25 #include "UpdateMask.h"
26 #include "World.h"
27 #include "ObjectMgr.h"
28 #include "Player.h"
29 #include "Unit.h"
30 #include "Spell.h"
31 #include "SpellAuras.h"
32 #include "EventSystem.h"
33 #include "DynamicObject.h"
34 #include "Group.h"
35 #include "UpdateData.h"
36 #include "MapManager.h"
37 #include "ObjectAccessor.h"
38 #include "RedZoneDistrict.h"
39 #include "CellImpl.h"
40 #include "Policies/SingletonImp.h"
41 #include "Totem.h"
42 #include "Creature.h"
43 #include "ConfusedMovementGenerator.h"
44 #include "Formulas.h"
46 pAuraHandler AuraHandler[TOTAL_AURAS]=
48 &Aura::HandleNULL, //SPELL_AURA_NONE
49 &Aura::HandleBindSight, //SPELL_AURA_BIND_SIGHT
50 &Aura::HandleModPossess, //SPELL_AURA_MOD_POSSESS = 2,
51 &Aura::HandlePeriodicDamage, //SPELL_AURA_PERIODIC_DAMAGE = 3,
52 &Aura::HandleAuraDummy, //SPELL_AURA_DUMMY //missing 4
53 &Aura::HandleModConfuse, //SPELL_AURA_MOD_CONFUSE = 5,
54 &Aura::HandleModCharm, //SPELL_AURA_MOD_CHARM = 6,
55 &Aura::HandleModFear, //SPELL_AURA_MOD_FEAR = 7,
56 &Aura::HandlePeriodicHeal, //SPELL_AURA_PERIODIC_HEAL = 8,
57 &Aura::HandleModAttackSpeed, //SPELL_AURA_MOD_ATTACKSPEED = 9,
58 &Aura::HandleModThreat, //SPELL_AURA_MOD_THREAT = 10,
59 &Aura::HandleModTaunt, //SPELL_AURA_MOD_TAUNT = 11,
60 &Aura::HandleAuraModStun, //SPELL_AURA_MOD_STUN = 12,
61 &Aura::HandleModDamageDone, //SPELL_AURA_MOD_DAMAGE_DONE = 13,
62 &Aura::HandleModDamageTaken, //SPELL_AURA_MOD_DAMAGE_TAKEN = 14,
63 &Aura::HandleAuraDamageShield, //SPELL_AURA_DAMAGE_SHIELD = 15,
64 &Aura::HandleModStealth, //SPELL_AURA_MOD_STEALTH = 16,
65 &Aura::HandleModDetect, //SPELL_AURA_MOD_DETECT = 17,
66 &Aura::HandleInvisibility, //SPELL_AURA_MOD_INVISIBILITY = 18,
67 &Aura::HandleInvisibilityDetect, //SPELL_AURA_MOD_INVISIBILITY_DETECTION = 19,
68 &Aura::HandleAuraModTotalHealthPercentRegen, //SPELL_AURA_OBS_MOD_HEALTH = 20
69 &Aura::HandleAuraModTotalManaPercentRegen, //SPELL_AURA_OBS_MOD_MANA = 21
70 &Aura::HandleAuraModResistance, //SPELL_AURA_MOD_RESISTANCE = 22,
71 &Aura::HandlePeriodicTriggerSpell, //SPELL_AURA_PERIODIC_TRIGGER_SPELL = 23,
72 &Aura::HandlePeriodicEnergize, //SPELL_AURA_PERIODIC_ENERGIZE = 24,
73 &Aura::HandleNULL, //SPELL_AURA_MOD_PACIFY = 25,
74 &Aura::HandleAuraModRoot, //SPELL_AURA_MOD_ROOT = 26,
75 &Aura::HandleAuraModSilence, //SPELL_AURA_MOD_SILENCE = 27,
76 &Aura::HandleReflectSpells, //SPELL_AURA_REFLECT_SPELLS = 28,
77 &Aura::HandleAuraModStat, //SPELL_AURA_MOD_STAT = 29,
78 &Aura::HandleAuraModSkill, //SPELL_AURA_MOD_SKILL = 30,
79 &Aura::HandleAuraModIncreaseSpeed, //SPELL_AURA_MOD_INCREASE_SPEED = 31,
80 &Aura::HandleAuraModIncreaseMountedSpeed, //SPELL_AURA_MOD_INCREASE_MOUNTED_SPEED = 32,
81 &Aura::HandleAuraModDecreaseSpeed, //SPELL_AURA_MOD_DECREASE_SPEED = 33,
82 &Aura::HandleAuraModIncreaseHealth, //SPELL_AURA_MOD_INCREASE_HEALTH = 34,
83 &Aura::HandleAuraModIncreaseEnergy, //SPELL_AURA_MOD_INCREASE_ENERGY = 35,
84 &Aura::HandleAuraModShapeshift, //SPELL_AURA_MOD_SHAPESHIFT = 36,
85 &Aura::HandleAuraModEffectImmunity, //SPELL_AURA_EFFECT_IMMUNITY = 37,
86 &Aura::HandleAuraModStateImmunity, //SPELL_AURA_STATE_IMMUNITY = 38,
87 &Aura::HandleAuraModSchoolImmunity, //SPELL_AURA_SCHOOL_IMMUNITY = 39,
88 &Aura::HandleAuraModDmgImmunity, //SPELL_AURA_DAMAGE_IMMUNITY = 40,
89 &Aura::HandleAuraModDispelImmunity, //SPELL_AURA_DISPEL_IMMUNITY = 41,
90 &Aura::HandleAuraProcTriggerSpell, //SPELL_AURA_PROC_TRIGGER_SPELL = 42,
91 &Aura::HandleAuraProcTriggerDamage, //SPELL_AURA_PROC_TRIGGER_DAMAGE = 43,
92 &Aura::HandleAuraTrackCreatures, //SPELL_AURA_TRACK_CREATURES = 44,
93 &Aura::HandleAuraTrackResources, //SPELL_AURA_TRACK_RESOURCES = 45,
94 &Aura::HandleNULL, //SPELL_AURA_MOD_PARRY_SKILL = 46, obsolete?
95 &Aura::HandleAuraModParryPercent, //SPELL_AURA_MOD_PARRY_PERCENT = 47,
96 &Aura::HandleNULL, //SPELL_AURA_MOD_DODGE_SKILL = 48, obsolete?
97 &Aura::HandleAuraModDodgePercent, //SPELL_AURA_MOD_DODGE_PERCENT = 49,
98 &Aura::HandleNULL, //SPELL_AURA_MOD_BLOCK_SKILL = 50, obsolete?
99 &Aura::HandleAuraModBlockPercent, //SPELL_AURA_MOD_BLOCK_PERCENT = 51,
100 &Aura::HandleAuraModCritPercent, //SPELL_AURA_MOD_CRIT_PERCENT = 52,
101 &Aura::HandlePeriodicLeech, //SPELL_AURA_PERIODIC_LEECH = 53,
102 &Aura::HandleModHitChance, //SPELL_AURA_MOD_HIT_CHANCE = 54,
103 &Aura::HandleModSpellHitChance, //SPELL_AURA_MOD_SPELL_HIT_CHANCE = 55,
104 &Aura::HandleAuraTransform, //SPELL_AURA_TRANSFORM = 56,
105 &Aura::HandleModSpellCritChance, //SPELL_AURA_MOD_SPELL_CRIT_CHANCE = 57,
106 &Aura::HandleAuraModIncreaseSwimSpeed, //SPELL_AURA_MOD_INCREASE_SWIM_SPEED = 58,
107 &Aura::HandleModDamageDoneCreature, //SPELL_AURA_MOD_DAMAGE_DONE_CREATURE = 59,
108 &Aura::HandleNULL, //SPELL_AURA_MOD_PACIFY_SILENCE = 60,
109 &Aura::HandleAuraModScale, //SPELL_AURA_MOD_SCALE = 61,
110 &Aura::HandleNULL, //SPELL_AURA_PERIODIC_HEALTH_FUNNEL = 62,
111 &Aura::HandleNULL, //SPELL_AURA_PERIODIC_MANA_FUNNEL = 63,
112 &Aura::HandlePeriodicManaLeech, //SPELL_AURA_PERIODIC_MANA_LEECH = 64,
113 &Aura::HandleModCastingSpeed, //SPELL_AURA_MOD_CASTING_SPEED = 65,
114 &Aura::HandleFeignDeath, //SPELL_AURA_FEIGN_DEATH = 66,
115 &Aura::HandleNULL, //SPELL_AURA_MOD_DISARM = 67,
116 &Aura::HandleNULL, //SPELL_AURA_MOD_STALKED = 68,
117 &Aura::HandleAuraSchoolAbsorb, //SPELL_AURA_SCHOOL_ABSORB = 69,
118 &Aura::HandleNULL, //SPELL_AURA_EXTRA_ATTACKS = 70,// Useless
119 &Aura::HandleModSpellCritChanceShool, //SPELL_AURA_MOD_SPELL_CRIT_CHANCE_SCHOOL = 71,
120 &Aura::HandleModPowerCost, //SPELL_AURA_MOD_POWER_COST = 72,
121 &Aura::HandleModPowerCostSchool, //SPELL_AURA_MOD_POWER_COST_SCHOOL = 73,
122 &Aura::HandleReflectSpellsSchool, //SPELL_AURA_REFLECT_SPELLS_SCHOOL = 74,
123 &Aura::HandleNULL, //SPELL_AURA_MOD_LANGUAGE = 75,
124 &Aura::HandleFarSight, //SPELL_AURA_FAR_SIGHT = 76,
125 &Aura::HandleModMechanicImmunity, //SPELL_AURA_MECHANIC_IMMUNITY = 77,
126 &Aura::HandleAuraMounted, //SPELL_AURA_MOUNTED = 78,
127 &Aura::HandleModDamagePercentDone, //SPELL_AURA_MOD_DAMAGE_PERCENT_DONE = 79,
128 &Aura::HandleModPercentStat, //SPELL_AURA_MOD_PERCENT_STAT = 80,
129 &Aura::HandleNULL, //SPELL_AURA_SPLIT_DAMAGE = 81,
130 &Aura::HandleWaterBreathing, //SPELL_AURA_WATER_BREATHING = 82,
131 &Aura::HandleModBaseResistance, //SPELL_AURA_MOD_BASE_RESISTANCE = 83,
132 &Aura::HandleModRegen, //SPELL_AURA_MOD_REGEN = 84,
133 &Aura::HandleModPowerRegen, //SPELL_AURA_MOD_POWER_REGEN = 85,
134 &Aura::HandleChannelDeathItem, //SPELL_AURA_CHANNEL_DEATH_ITEM = 86,
135 &Aura::HandleModDamagePCTTaken, //SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN = 87,
136 &Aura::HandleModPCTRegen, //SPELL_AURA_MOD_HEALTH_REGEN_PERCENT = 88,
137 &Aura::HandlePeriodicDamagePCT, //SPELL_AURA_PERIODIC_DAMAGE_PERCENT = 89,
138 &Aura::HandleNULL, //SPELL_AURA_MOD_RESIST_CHANCE = 90,// Useless
139 &Aura::HandleModDetectRange, //SPELL_AURA_MOD_DETECT_RANGE = 91,
140 &Aura::HandleNULL, //SPELL_AURA_PREVENTS_FLEEING = 92,
141 &Aura::HandleNULL, //SPELL_AURA_MOD_UNATTACKABLE = 93,
142 &Aura::HandleNULL, //SPELL_AURA_INTERRUPT_REGEN = 94,
143 &Aura::HandleNULL, //SPELL_AURA_GHOST = 95,
144 &Aura::HandleNULL, //SPELL_AURA_SPELL_MAGNET = 96,
145 &Aura::HandleAuraManaShield, //SPELL_AURA_MANA_SHIELD = 97,
146 &Aura::HandleAuraModSkill, //SPELL_AURA_MOD_SKILL_TALENT = 98,
147 &Aura::HandleAuraModAttackPower, //SPELL_AURA_MOD_ATTACK_POWER = 99,
148 &Aura::HandleNULL, //SPELL_AURA_AURAS_VISIBLE = 100,
149 &Aura::HandleModResistancePercent, //SPELL_AURA_MOD_RESISTANCE_PCT = 101,
150 &Aura::HandleModCreatureAttackPower, //SPELL_AURA_MOD_CREATURE_ATTACK_POWER = 102,
151 &Aura::HandleNULL, //SPELL_AURA_MOD_TOTAL_THREAT = 103,
152 &Aura::HandleAuraWaterWalk, //SPELL_AURA_WATER_WALK = 104,
153 &Aura::HandleAuraFeatherFall, //SPELL_AURA_FEATHER_FALL = 105,
154 &Aura::HandleAuraHover, //SPELL_AURA_HOVER = 106,
155 &Aura::HandleAddModifier, //SPELL_AURA_ADD_FLAT_MODIFIER = 107,
156 &Aura::HandleAddModifier, //SPELL_AURA_ADD_PCT_MODIFIER = 108,
157 &Aura::HandleNULL, //SPELL_AURA_ADD_TARGET_TRIGGER = 109,
158 &Aura::HandleNULL, //SPELL_AURA_MOD_POWER_REGEN_PERCENT = 110,
159 &Aura::HandleNULL, //SPELL_AURA_ADD_CASTER_HIT_TRIGGER = 111,
160 &Aura::HandleNULL, //SPELL_AURA_OVERRIDE_CLASS_SCRIPTS = 112,
161 &Aura::HandleNULL, //SPELL_AURA_MOD_RANGED_DAMAGE_TAKEN = 113,
162 &Aura::HandleNULL, //SPELL_AURA_MOD_RANGED_DAMAGE_TAKEN_PCT = 114,
163 &Aura::HandleNULL, //SPELL_AURA_MOD_HEALING = 115,
164 &Aura::HandleNULL, //SPELL_AURA_IGNORE_REGEN_INTERRUPT = 116,
165 &Aura::HandleNULL, //SPELL_AURA_MOD_MECHANIC_RESISTANCE = 117,
166 &Aura::HandleNULL, //SPELL_AURA_MOD_HEALING_PCT = 118,
167 &Aura::HandleNULL, //SPELL_AURA_SHARE_PET_TRACKING = 119,
168 &Aura::HandleNULL, //SPELL_AURA_UNTRACKABLE = 120,
169 &Aura::HandleAuraEmpathy, //SPELL_AURA_EMPATHY = 121,
170 &Aura::HandleNULL, //SPELL_AURA_MOD_OFFHAND_DAMAGE_PCT = 122,
171 &Aura::HandleNULL, //SPELL_AURA_MOD_POWER_COST_PCT = 123,
172 &Aura::HandleAuraModRangedAttackPower, //SPELL_AURA_MOD_RANGED_ATTACK_POWER = 124,
173 &Aura::HandleNULL, //SPELL_AURA_MOD_MELEE_DAMAGE_TAKEN = 125,
174 &Aura::HandleNULL, //SPELL_AURA_MOD_MELEE_DAMAGE_TAKEN_PCT = 126,
175 &Aura::HandleNULL, //SPELL_AURA_RANGED_ATTACK_POWER_ATTACKER_BONUS = 127,
176 &Aura::HandleModPossessPet, //SPELL_AURA_MOD_POSSESS_PET = 128,
177 &Aura::HandleAuraModIncreaseSpeedAlways, //SPELL_AURA_MOD_INCREASE_SPEED_ALWAYS = 129,
178 &Aura::HandleNULL, //SPELL_AURA_MOD_MOUNTED_SPEED_ALWAYS = 130,
179 &Aura::HandleNULL, //SPELL_AURA_MOD_CREATURE_RANGED_ATTACK_POWER = 131,
180 &Aura::HandleAuraModIncreaseEnergyPercent, //SPELL_AURA_MOD_INCREASE_ENERGY_PERCENT = 132,
181 &Aura::HandleAuraModIncreaseHealthPercent, //SPELL_AURA_MOD_INCREASE_HEALTH_PERCENT = 133,
182 &Aura::HandleNULL, //SPELL_AURA_MOD_MANA_REGEN_INTERRUPT = 134,
183 &Aura::HandleNULL, //SPELL_AURA_MOD_HEALING_DONE = 135,
184 &Aura::HandleNULL, //SPELL_AURA_MOD_HEALING_DONE_PERCENT = 136,
185 &Aura::HandleModTotalPercentStat, //SPELL_AURA_MOD_TOTAL_STAT_PERCENTAGE = 137,
186 &Aura::HandleHaste, //SPELL_AURA_MOD_HASTE = 138,
187 &Aura::HandleForceReaction, //SPELL_AURA_FORCE_REACTION = 139,
188 &Aura::HandleAuraModRangedHaste, //SPELL_AURA_MOD_RANGED_HASTE = 140,
189 &Aura::HandleRangedAmmoHaste, //SPELL_AURA_MOD_RANGED_AMMO_HASTE = 141,
190 &Aura::HandleAuraModBaseResistancePCT, //SPELL_AURA_MOD_BASE_RESISTANCE_PCT = 142,
191 &Aura::HandleAuraModResistanceExclusive, //SPELL_AURA_MOD_RESISTANCE_EXCLUSIVE = 143,
192 &Aura::HandleAuraSafeFall, //SPELL_AURA_SAFE_FALL = 144,
193 &Aura::HandleNULL, //SPELL_AURA_CHARISMA = 145,
194 &Aura::HandleNULL, //SPELL_AURA_PERSUADED = 146,
195 &Aura::HandleNULL, //SPELL_AURA_ADD_CREATURE_IMMUNITY = 147,
196 &Aura::HandleNULL, //SPELL_AURA_RETAIN_COMBO_POINTS = 148,
197 &Aura::HandleNULL, //SPELL_AURA_RESIST_PUSHBACK = 149 ,// Resist Pushback
198 &Aura::HandleModShieldBlock, //SPELL_AURA_MOD_SHIELD_BLOCK_PCT = 150 ,// Mod Shield Block %
199 &Aura::HandleAuraTrackStealthed, //SPELL_AURA_TRACK_STEALTHED = 151 ,// Track Stealthed
200 &Aura::HandleNULL, //SPELL_AURA_MOD_DETECTED_RANGE = 152 ,// Mod Detected Range
201 &Aura::HandleNULL, //SPELL_AURA_SPLIT_DAMAGE_FLAT = 153 ,// Split Damage Flat
202 &Aura::HandleNULL, //SPELL_AURA_MOD_STEALTH_LEVEL = 154 ,// Stealth Level Modifier
203 &Aura::HandleNULL, //SPELL_AURA_MOD_WATER_BREATHING = 155 ,// Mod Water Breathing
204 &Aura::HandleModReputationGain, //SPELL_AURA_MOD_REPUTATION_GAIN = 156 ,// Mod Reputation Gain
205 &Aura::HandleNULL, //SPELL_AURA_PET_DAMAGE_MULTI = 157 ,// Mod Pet Damage
206 &Aura::HandleNULL, //SPELL_AURA_MOD_SHIELD_BLOCK = 158 ,//
207 &Aura::HandleNULL, //SPELL_AURA_NO_PVP_CREDIT = 159 ,//
208 &Aura::HandleNULL, //SPELL_AURA_MOD_AOE_AVOIDANCE = 160 ,//
209 &Aura::HandleNULL, //SPELL_AURA_MOD_HEALTH_REGEN_IN_COMBAT = 161 ,//
210 &Aura::HandleNULL //SPELL_AURA_POWER_BURN_MANA = 162 ,//
213 Aura::Aura(SpellEntry const* spellproto, uint32 eff, Unit *target, Unit *caster, Item* castItem) :
214 m_spellId(spellproto->Id), m_effIndex(eff), m_caster_guid(0), m_target(target),
215 m_timeCla(1000), m_castItem(castItem), m_auraSlot(0),m_positive(false), m_permanent(false),
216 m_isPeriodic(false), m_isTrigger(false), m_periodicTimer(0), m_PeriodicEventId(0),
217 m_procCharges(0), m_absorbDmg(0), m_isPersistent(false), m_removeOnDeath(false),
218 m_isAreaAura(false)
220 assert(target);
222 // make own copy of custom `spellproto` (`spellproto` will be deleted at spell cast finished)
223 // copy custom SpellEntry in m_spellProto will be delete at Aura delete
224 if(spellproto != sSpellStore.LookupEntry( spellproto->Id ))
226 SpellEntry* sInfo = new SpellEntry;
227 *sInfo = *spellproto;
228 m_spellProto = sInfo;
230 else
231 m_spellProto = spellproto;
233 m_duration = GetDuration(spellproto);
234 int32 maxduration = GetMaxDuration(spellproto);
235 if(m_duration == -1)
236 m_permanent = true;
237 if( m_duration != maxduration )
239 uint8 comboPoints=0;
240 if(caster->GetTypeId() == TYPEID_PLAYER)
242 comboPoints = (uint8)((caster->GetUInt32Value(PLAYER_FIELD_BYTES) & 0xFF00) >> 8);
243 caster->SetUInt32Value(PLAYER_FIELD_BYTES,((caster->GetUInt32Value(PLAYER_FIELD_BYTES) & ~(0xFF << 8)) | (0x00 << 8)));
245 comboPoints = comboPoints < 5 ? comboPoints : 5;
246 m_duration += int32((maxduration - m_duration) * comboPoints / 5);
248 m_isPassive = IsPassiveSpell(m_spellId);
249 m_positive = IsPositiveEffect(m_spellId, m_effIndex);
250 m_applyTime = time(NULL);
252 sLog.outDebug("Aura: construct Spellid : %u, Aura : %u Duration : %d Target : %d.", spellproto->Id, spellproto->EffectApplyAuraName[eff], m_duration, spellproto->EffectImplicitTargetA[eff]);
254 uint32 type = 0;
255 if(!m_positive)
256 type = 1;
257 int32 damage;
258 if(!caster)
260 m_caster_guid = target->GetGUID();
261 damage = spellproto->EffectBasePoints[eff]+1; // stored value-1
263 else
265 m_caster_guid = caster->GetGUID();
266 damage = CalculateDamage();
269 m_effIndex = eff;
270 SetModifier(spellproto->EffectApplyAuraName[eff], damage, spellproto->EffectAmplitude[eff], spellproto->EffectMiscValue[eff], type);
273 Aura::~Aura()
275 // free custom m_spellProto
276 if(m_spellProto != sSpellStore.LookupEntry(m_spellProto->Id))
277 delete m_spellProto;
280 AreaAura::AreaAura(SpellEntry const* spellproto, uint32 eff, Unit *target,
281 Unit *caster, Item* castItem) : Aura(spellproto, eff, target, caster, castItem)
283 m_isAreaAura = true;
286 AreaAura::~AreaAura()
290 PersistentAreaAura::PersistentAreaAura(SpellEntry const* spellproto, uint32 eff, Unit *target,
291 Unit *caster, Item* castItem) : Aura(spellproto, eff, target, caster, castItem)
293 m_isPersistent = true;
296 PersistentAreaAura::~PersistentAreaAura()
300 Unit* Aura::GetCaster() const
302 if(m_caster_guid==m_target->GetGUID())
303 return m_target;
305 return ObjectAccessor::Instance().GetUnit(*m_target,m_caster_guid);
308 int32 Aura::CalculateDamage()
310 SpellEntry const* spellproto = GetSpellProto();
311 int32 value = 0;
312 uint32 level = 0;
313 if(!m_target)
314 return 0;
315 Unit* caster = GetCaster();
316 if(!caster)
317 caster = m_target;
318 /*level= caster->getLevel();
319 if( level > spellproto->maxLevel && spellproto->maxLevel > 0)
320 level = spellproto->maxLevel;*/
322 float basePointsPerLevel = spellproto->EffectRealPointsPerLevel[m_effIndex];
323 float randomPointsPerLevel = spellproto->EffectDicePerLevel[m_effIndex];
324 int32 basePoints = int32(spellproto->EffectBasePoints[m_effIndex] + level * basePointsPerLevel);
325 int32 randomPoints = int32(spellproto->EffectDieSides[m_effIndex] + level * randomPointsPerLevel);
326 float comboDamage = spellproto->EffectPointsPerComboPoint[m_effIndex];
327 uint8 comboPoints=0;
328 if(caster->GetTypeId() == TYPEID_PLAYER)
329 comboPoints = (uint8)((caster->GetUInt32Value(PLAYER_FIELD_BYTES) & 0xFF00) >> 8);
331 value += spellproto->EffectBaseDice[m_effIndex];
332 if(randomPoints <= 1)
333 value = basePoints+1;
334 else
335 value = basePoints+rand()%randomPoints;
337 if(comboDamage > 0)
339 value += (int32)(comboDamage * comboPoints);
340 if(caster->GetTypeId() == TYPEID_PLAYER)
341 caster->SetUInt32Value(PLAYER_FIELD_BYTES,((caster->GetUInt32Value(PLAYER_FIELD_BYTES) & ~(0xFF << 8)) | (0x00 << 8)));
344 return value;
347 void Aura::SetModifier(uint8 t, int32 a, uint32 pt, int32 miscValue, uint32 miscValue2)
349 m_modifier.m_auraname = t;
350 m_modifier.m_amount = a;
351 m_modifier.m_miscvalue = miscValue;
352 m_modifier.m_miscvalue2 = miscValue2;
353 m_modifier.periodictime = pt;
355 Unit* caster = GetCaster();
356 if (caster && caster->GetTypeId() == TYPEID_PLAYER)
357 ((Player *)caster)->ApplySpellMod(m_spellId,SPELLMOD_ALL_EFFECTS, m_modifier.m_amount);
360 void Aura::Update(uint32 diff)
362 if (m_duration > 0)
364 m_duration -= diff;
365 if (m_duration < 0)
366 m_duration = 0;
367 m_timeCla -= diff;
369 Unit* caster = GetCaster();
370 if(caster && m_timeCla <= 0)
372 Powers powertype = caster->getPowerType();
373 int32 manaPerSecond = GetSpellProto()->manaPerSecond;
374 int32 manaPerSecondPerLevel = uint32(GetSpellProto()->manaPerSecondPerLevel*caster->getLevel());
375 m_timeCla = 1000;
376 caster->ModifyPower(powertype,-manaPerSecond);
377 caster->ModifyPower(powertype,-manaPerSecondPerLevel);
379 if(caster && m_target->isAlive() && m_target->HasFlag(UNIT_FIELD_FLAGS,(UNIT_STAT_FLEEING<<16)))
381 float x,y,z,angle,speed,pos_x,pos_y,pos_z;
382 angle = m_target->GetAngle( caster->GetPositionX(), caster->GetPositionY() );
383 // If the m_target is player,and if the speed is too slow,change it :P
384 speed = m_target->GetSpeed(MOVE_RUN);
385 pos_x = m_target->GetPositionX();
386 pos_y = m_target->GetPositionY();
387 uint32 mapid = m_target->GetMapId();
388 pos_z = MapManager::Instance().GetMap(mapid)->GetHeight(pos_x,pos_y);
389 // Control the max Distance; 20 for temp.
390 if(m_target->IsWithinDist(caster, 20))
392 if( m_target->GetPositionX() < caster->GetPositionX() || m_target->GetPositionY() > caster->GetPositionY() )
393 x = m_target->GetPositionX() + speed*diff * sin(angle)/1000;
394 else
395 x = m_target->GetPositionX() - speed*diff * sin(angle)/1000;
396 y = m_target->GetPositionY() - speed*diff * cos(angle)/1000;
397 mapid = m_target->GetMapId();
398 z = MapManager::Instance().GetMap(mapid)->GetHeight(x,y);
399 // Control the target to not climb or drop when dz > |x|,x = 1.3 for temp.
400 // fixed me if it needs checking when the position will be in water?
401 if(z<=pos_z+1.3 && z>=pos_z-1.3)
403 m_target->SendMonsterMove(x,y,z,false,true,diff);
404 if(m_target->GetTypeId() != TYPEID_PLAYER)
405 m_target->Relocate(x,y,z,m_target->GetOrientation());
411 if(m_isPeriodic && (m_duration >= 0 || m_isPassive))
413 m_periodicTimer -= diff;
414 if(m_periodicTimer < 0)
416 if( m_modifier.m_auraname == SPELL_AURA_MOD_REGEN ||
417 m_modifier.m_auraname == SPELL_AURA_MOD_POWER_REGEN ||
418 // Cannibalize, eating items and other spells
419 m_modifier.m_auraname == SPELL_AURA_OBS_MOD_HEALTH ||
420 // Eating items and other spells
421 m_modifier.m_auraname == SPELL_AURA_OBS_MOD_MANA )
423 ApplyModifier(true);
424 return;
426 // update before applying (aura can be removed in TriggerSpell or PeriodicAuraLog calls)
427 m_periodicTimer += m_modifier.periodictime;
429 if(m_isTrigger)
431 TriggerSpell();
433 else
435 if(Unit* caster = GetCaster())
436 caster->PeriodicAuraLog(m_target, GetSpellProto(), &m_modifier);
437 else
438 m_target->PeriodicAuraLog(m_target, GetSpellProto(), &m_modifier);
444 void AreaAura::Update(uint32 diff)
446 // update for the caster of the aura
447 if(m_caster_guid == m_target->GetGUID())
449 Unit* caster = m_target;
451 Group *pGroup = NULL;
452 if (caster->GetTypeId() == TYPEID_PLAYER)
453 pGroup = ((Player*)caster)->groupInfo.group;
454 else if(((Creature*)caster)->isTotem())
456 Unit *owner = ((Totem*)caster)->GetOwner();
457 if (owner && owner->GetTypeId() == TYPEID_PLAYER)
458 pGroup = ((Player*)owner)->groupInfo.group;
461 float radius = GetRadius(sSpellRadiusStore.LookupEntry(GetSpellProto()->EffectRadiusIndex[m_effIndex]));
462 if(pGroup)
464 for(uint32 p=0;p<pGroup->GetMembersCount();p++)
466 Unit* Target = objmgr.GetPlayer(pGroup->GetMemberGUID(p));
468 if (caster->GetTypeId() == TYPEID_PLAYER)
470 if(!Target || Target->GetGUID() == m_caster_guid || !Target->isAlive() || !pGroup->SameSubGroup(m_caster_guid, Target->GetGUID()))
471 continue;
473 else if(((Creature*)caster)->isTotem())
475 Unit *owner = ((Totem*)caster)->GetOwner();
476 if(!Target || !Target->isAlive() || !pGroup->SameSubGroup(owner->GetGUID(), Target->GetGUID()))
477 continue;
480 Aura *t_aura = Target->GetAura(m_spellId, m_effIndex);
482 if(caster->IsWithinDist(Target, radius) )
484 // apply aura to players in range that dont have it yet
485 if (!t_aura)
487 AreaAura *aur = new AreaAura(GetSpellProto(), m_effIndex, Target, caster);
488 Target->AddAura(aur);
491 else
493 // remove auras of the same caster from out of range players
494 if (t_aura)
495 if (t_aura->GetCasterGUID() == m_caster_guid)
496 Target->RemoveAura(m_spellId, m_effIndex);
500 else if (caster->GetTypeId() != TYPEID_PLAYER && ((Creature*)caster)->isTotem())
502 // add / remove auras from the totem's owner
503 Unit *owner = ((Totem*)caster)->GetOwner();
504 if (owner)
506 Aura *o_aura = owner->GetAura(m_spellId, m_effIndex);
507 if(caster->IsWithinDist(owner, radius))
509 if (!o_aura)
511 AreaAura *aur = new AreaAura(GetSpellProto(), m_effIndex, owner, caster);
512 owner->AddAura(aur);
515 else
517 if (o_aura)
518 if (o_aura->GetCasterGUID() == m_caster_guid)
519 owner->RemoveAura(m_spellId, m_effIndex);
525 Aura::Update(diff);
528 void PersistentAreaAura::Update(uint32 diff)
530 bool remove = false;
532 // remove the aura if its caster or the dynamic object causing it was removed
533 // or if the target moves too far from the dynamic object
534 Unit *caster = GetCaster();
535 if (caster)
537 DynamicObject *dynObj = caster->GetDynObject(GetId(), GetEffIndex());
538 if (dynObj)
540 if (!m_target->IsWithinDist(dynObj, dynObj->GetRadius()))
541 remove = true;
543 else
544 remove = true;
546 else
547 remove = true;
549 Aura::Update(diff);
551 if(remove)
552 m_target->RemoveAura(GetId(), GetEffIndex());
555 void Aura::ApplyModifier(bool apply, bool Real)
557 uint8 aura = 0;
558 aura = m_modifier.m_auraname;
560 if(aura<TOTAL_AURAS)
561 (*this.*AuraHandler [aura])(apply,Real);
564 void Aura::UpdateAuraDuration()
566 if(m_target->GetTypeId() != TYPEID_PLAYER)
567 return;
568 if(m_isPassive)
569 return;
571 WorldPacket data(SMSG_UPDATE_AURA_DURATION, 5);
572 data << (uint8)m_auraSlot << (uint32)m_duration;
573 //((Player*)m_target)->SendMessageToSet(&data, true); //GetSession()->SendPacket(&data);
574 ((Player*)m_target)->SendDirectMessage(&data);
577 void Aura::_AddAura()
579 if (!m_spellId)
580 return;
581 if(!m_target)
582 return;
584 bool samespell = false;
585 uint8 slot = 0xFF, i;
586 Aura* aura = NULL;
588 for(i = 0; i < 3; i++)
590 aura = m_target->GetAura(m_spellId, i);
591 if(aura)
593 //if (i != m_effIndex)
595 samespell = true;
596 slot = aura->GetAuraSlot();
601 // not call total regen auras at adding
602 if( m_modifier.m_auraname==SPELL_AURA_OBS_MOD_HEALTH || m_modifier.m_auraname==SPELL_AURA_OBS_MOD_MANA )
603 m_periodicTimer = m_modifier.periodictime;
604 else
605 if( m_modifier.m_auraname==SPELL_AURA_MOD_REGEN || m_modifier.m_auraname==SPELL_AURA_MOD_POWER_REGEN )
606 m_periodicTimer = 5000;
608 m_target->ApplyStats(false);
609 ApplyModifier(true,true);
610 m_target->ApplyStats(true);
612 sLog.outDebug("Aura %u now is in use", m_modifier.m_auraname);
614 Unit* caster = GetCaster();
616 // passive auras (except totem auras) do not get placed in the slots
617 if(!m_isPassive || (caster && caster->GetTypeId() == TYPEID_UNIT && ((Creature*)caster)->isTotem()))
619 if(!samespell)
621 if (IsPositive())
623 for (i = 0; i < MAX_POSITIVE_AURAS; i++)
625 if (m_target->GetUInt32Value((uint16)(UNIT_FIELD_AURA + i)) == 0)
627 slot = i;
628 break;
632 else
634 for (i = MAX_POSITIVE_AURAS; i < MAX_AURAS; i++)
636 if (m_target->GetUInt32Value((uint16)(UNIT_FIELD_AURA + i)) == 0)
638 slot = i;
639 break;
644 m_target->SetUInt32Value((uint16)(UNIT_FIELD_AURA + slot), GetId());
646 uint8 flagslot = slot >> 3;
647 uint32 value = m_target->GetUInt32Value((uint16)(UNIT_FIELD_AURAFLAGS + flagslot));
649 uint8 value1 = (slot & 7) << 2;
650 value |= ((uint32)AFLAG_SET << value1);
652 m_target->SetUInt32Value((uint16)(UNIT_FIELD_AURAFLAGS + flagslot), value);
654 else
656 /* TODO: increase count */
659 if(GetSpellProto()->SpellVisual == 5622)
660 m_target->SetFlag(UNIT_FIELD_AURASTATE, uint32(1<<(AURA_STATE_JUDGEMENT-1)));
661 SetAuraSlot( slot );
662 if( m_target->GetTypeId() == TYPEID_PLAYER )
663 UpdateAuraDuration();
668 void Aura::_RemoveAura()
670 m_target->ApplyStats(false);
671 sLog.outDebug("Aura %u now is remove", m_modifier.m_auraname);
672 ApplyModifier(false,true);
673 m_target->ApplyStats(true);
675 Unit* caster = GetCaster();
677 if(caster && IsPersistent())
679 DynamicObject *dynObj = caster->GetDynObject(GetId(), GetEffIndex());
680 if (dynObj)
681 dynObj->RemoveAffected(m_target);
683 //passive auras do not get put in slots
684 if(m_isPassive && !(caster && caster->GetTypeId() == TYPEID_UNIT && ((Creature*)caster)->isTotem()))
685 return;
687 uint8 slot = GetAuraSlot();
689 // Aura added always to m_target
690 //Aura* aura = m_target->GetAura(m_spellId, m_effIndex);
691 //if(!aura)
692 // return;
694 if(m_target->GetUInt32Value((uint16)(UNIT_FIELD_AURA + slot)) == 0)
695 return;
697 // count all auras from each effect of the spell
698 Unit::AuraMap& t_Auras = m_target->GetAuras();
699 uint8 count[3], totalcount = 0;
700 for(uint8 i = 0; i < 3; i++)
702 count[i] = t_Auras.count(Unit::spellEffectPair(m_spellId, i));
703 totalcount += count[i];
707 count[m_effIndex]--;
708 // all counts should be the same after the last effect of a spell was taken out
709 for(uint8 i = 0; i < 3; i++)
710 if (count[i] > count[m_effIndex])
711 break;
712 if (i == 3)
713 TODO: decrease count for spell
716 // only remove icon when the last aura of the spell is removed (current aura already removed from list)
717 if (totalcount > 0)
718 return;
720 m_target->SetUInt32Value((uint16)(UNIT_FIELD_AURA + slot), 0);
722 uint8 flagslot = slot >> 3;
724 uint32 value = m_target->GetUInt32Value((uint16)(UNIT_FIELD_AURAFLAGS + flagslot));
726 uint8 aurapos = (slot & 7) << 2;
727 uint32 value1 = ~( AFLAG_SET << aurapos );
728 value &= value1;
730 m_target->SetUInt32Value((uint16)(UNIT_FIELD_AURAFLAGS + flagslot), value);
731 if(GetSpellProto()->SpellVisual == 5622)
732 m_target->RemoveFlag(UNIT_FIELD_AURASTATE, uint32(1<<(AURA_STATE_JUDGEMENT-1)));
735 /*********************************************************/
736 /*** BASIC AURA FUNCTION ***/
737 /*********************************************************/
739 void Aura::HandleNULL(bool apply, bool Real)
743 void Aura::HandleAddModifier(bool apply, bool Real)
745 if(m_target->GetTypeId() != TYPEID_PLAYER)
746 return;
748 Player *p_target = (Player *)m_target;
750 SpellEntry const *spellInfo = GetSpellProto();
751 if(!spellInfo) return;
753 uint8 op = spellInfo->EffectMiscValue[m_effIndex];
754 int32 value = spellInfo->EffectBasePoints[m_effIndex]+1;
755 uint8 type = spellInfo->EffectApplyAuraName[m_effIndex];
756 uint32 mask = spellInfo->EffectItemType[m_effIndex];
757 if (!op) return;
758 SpellModList *p_mods = p_target->getSpellModList(op);
759 if (!p_mods) return;
761 if (apply)
763 SpellModifier *mod = new SpellModifier;
764 mod->op = op;
765 mod->value = value;
766 mod->type = type;
767 mod->mask = mask;
768 mod->spellId = m_spellId;
769 mod->charges = spellInfo->procCharges;
770 p_mods->push_back(mod);
771 m_spellmod = mod;
773 uint16 send_val=0, send_mark=0;
774 int16 tmpval=spellInfo->EffectBasePoints[m_effIndex];
775 uint32 shiftdata=0x01, Opcode=SMSG_SET_FLAT_SPELL_MODIFIER;
777 if(tmpval != 0)
779 if(tmpval > 0)
781 send_val = tmpval+1;
782 send_mark = 0x0;
784 else
786 send_val = 0xFFFF + (tmpval+2);
787 send_mark = 0xFFFF;
791 if (mod->type == SPELLMOD_FLAT) Opcode = SMSG_SET_FLAT_SPELL_MODIFIER;
792 else if (mod->type == SPELLMOD_PCT) Opcode = SMSG_SET_PCT_SPELL_MODIFIER;
794 for(int eff=0;eff<32;eff++)
796 if ( mask & shiftdata )
798 WorldPacket data(Opcode, (1+1+2+2));
799 data << uint8(eff);
800 data << uint8(mod->op);
801 data << uint16(send_val);
802 data << uint16(send_mark);
803 p_target->SendDirectMessage(&data);
805 shiftdata=shiftdata<<1;
808 else
810 SpellModList *p_mods = p_target->getSpellModList(spellInfo->EffectMiscValue[m_effIndex]);
811 p_mods->remove(this->m_spellmod);
815 void Aura::TriggerSpell()
817 SpellEntry const *spellInfo = sSpellStore.LookupEntry( GetSpellProto()->EffectTriggerSpell[m_effIndex] );
819 if(!spellInfo)
821 sLog.outError("Auras: unknown TriggerSpell:%i From spell: %i", GetSpellProto()->EffectTriggerSpell[m_effIndex],GetSpellProto()->Id);
822 return;
824 if(GetSpellProto()->Id == 1515)
825 spellInfo = sSpellStore.LookupEntry( 13481 );
827 Unit* caster = GetCaster();
829 Spell spell(caster, spellInfo, true, this);
830 Unit* target = m_target;
831 if(!target && caster && caster->GetTypeId() == TYPEID_PLAYER)
833 target = ObjectAccessor::Instance().GetUnit(*caster, ((Player*)caster)->GetSelection());
835 if(!target)
836 return;
837 SpellCastTargets targets;
838 targets.setUnitTarget(target);
839 spell.prepare(&targets);
842 /*********************************************************/
843 /*** AURA EFFECTS ***/
844 /*********************************************************/
846 void Aura::HandleAuraDummy(bool apply, bool Real)
848 Unit* caster = GetCaster();
850 // currently all dummy auras applyed/un-applied only at real add/remove
851 if(!Real)
852 return;
854 if(apply && !m_procCharges)
856 m_procCharges = GetSpellProto()->procCharges;
857 if (!m_procCharges)
858 m_procCharges = -1;
861 if(GetSpellProto()->SpellVisual == 5622 && caster && caster->GetTypeId() == TYPEID_PLAYER)
863 if(GetSpellProto()->SpellIconID == 25 && GetEffIndex() == 0)
865 Unit::AuraList& tAuraProcTriggerDamage = m_target->GetAurasByType(SPELL_AURA_PROC_TRIGGER_DAMAGE);
866 if(apply)
867 tAuraProcTriggerDamage.push_back(this);
868 else
869 tAuraProcTriggerDamage.remove(this);
873 if(GetSpellProto()->SpellVisual == 7395 && GetSpellProto()->SpellIconID == 278 && caster->GetTypeId() == TYPEID_PLAYER)
875 Unit::AuraList& tAuraProcTriggerDamage = m_target->GetAurasByType(SPELL_AURA_PROC_TRIGGER_DAMAGE);
876 if(apply)
877 tAuraProcTriggerDamage.push_back(this);
878 else
879 tAuraProcTriggerDamage.remove(this);
882 // only at real add/remove
883 if(GetSpellProto()->SpellVisual == 99 && GetSpellProto()->SpellIconID == 92 &&
884 caster && caster->GetTypeId() == TYPEID_PLAYER && m_target && m_target->GetTypeId() == TYPEID_PLAYER)
886 Player * player = (Player*)m_target;
887 if(apply)
889 uint32 spellid = 0;
890 switch(GetId())
892 case 20707:spellid = 3026;break;
893 case 20762:spellid = 20758;break;
894 case 20763:spellid = 20759;break;
895 case 20764:spellid = 20760;break;
896 case 20765:spellid = 20761;break;
897 default:break;
899 if(!spellid)
900 return;
901 player->SetSoulStoneSpell(spellid);
903 else
904 player->SetSoulStoneSpell(0);
907 if(!apply)
909 if( IsQuestTameSpell(GetId()) && caster && caster->isAlive() && m_target && m_target->isAlive())
911 uint32 finalSpelId = 0;
912 switch(GetId())
914 case 19548: finalSpelId = 19597; break;
915 case 19674: finalSpelId = 19677; break;
916 case 19687: finalSpelId = 19676; break;
917 case 19688: finalSpelId = 19678; break;
918 case 19689: finalSpelId = 19679; break;
919 case 19692: finalSpelId = 19680; break;
920 case 19693: finalSpelId = 19684; break;
921 case 19694: finalSpelId = 19681; break;
922 case 19696: finalSpelId = 19682; break;
923 case 19697: finalSpelId = 19683; break;
924 case 19699: finalSpelId = 19685; break;
925 case 19700: finalSpelId = 19686; break;
928 if(finalSpelId)
930 SpellEntry const *spell_proto = sSpellStore.LookupEntry(finalSpelId);
931 if(!spell_proto)
932 return;
934 Spell spell(caster, spell_proto, true, 0);
935 SpellCastTargets targets;
936 targets.setUnitTarget(m_target);
937 // prevent double stat apply for triggered auras
938 m_target->ApplyStats(true);
939 spell.prepare(&targets);
940 m_target->ApplyStats(false);
946 void Aura::HandleAuraMounted(bool apply, bool Real)
948 if(apply)
950 CreatureInfo const* ci = objmgr.GetCreatureTemplate(m_modifier.m_miscvalue);
951 if(!ci)return;
952 uint32 displayId = ci->randomDisplayID();
953 if(displayId != 0)
954 m_target->Mount(displayId);
955 }else
957 m_target->Unmount();
961 void Aura::HandleAuraWaterWalk(bool apply, bool Real)
963 // only at real add/remove aura
964 if(!Real)
965 return;
967 WorldPacket data;
968 if(apply)
969 data.Initialize(SMSG_MOVE_WATER_WALK, 8);
970 else
971 data.Initialize(SMSG_MOVE_LAND_WALK, 8);
972 data.append(m_target->GetPackGUID());
973 m_target->SendMessageToSet(&data,true);
976 void Aura::HandleAuraFeatherFall(bool apply, bool Real)
978 // only at real add/remove aura
979 if(!Real)
980 return;
982 WorldPacket data;
983 if(apply)
984 data.Initialize(SMSG_MOVE_FEATHER_FALL, 8);
985 else
986 data.Initialize(SMSG_MOVE_NORMAL_FALL, 8);
987 data.append(m_target->GetPackGUID());
988 m_target->SendMessageToSet(&data,true);
991 void Aura::HandleAuraHover(bool apply, bool Real)
993 // only at real add/remove aura
994 if(!Real)
995 return;
997 WorldPacket data;
998 if(apply)
999 data.Initialize(SMSG_MOVE_SET_HOVER, 8);
1000 else
1001 data.Initialize(SMSG_MOVE_UNSET_HOVER, 8);
1002 data.append(m_target->GetPackGUID());
1003 m_target->SendMessageToSet(&data,true);
1006 void Aura::HandleWaterBreathing(bool apply, bool Real)
1008 m_target->waterbreath = apply;
1011 void Aura::HandleAuraModShapeshift(bool apply, bool Real)
1013 if(!m_target)
1014 return;
1015 if(!Real)
1016 return;
1018 Player* player = m_target->GetTypeId()==TYPEID_PLAYER ? ((Player*)m_target) : NULL;
1020 // remove for old form
1021 if(player)
1023 player->_ApplyStatsMods();
1024 player->_RemoveAllItemMods();
1025 player->_RemoveAllAuraMods();
1026 player->_RemoveStatsMods();
1029 Unit *unit_target = m_target;
1030 uint32 modelid = 0;
1031 Powers PowerType = POWER_MANA;
1032 uint32 new_bytes_1 = m_modifier.m_miscvalue;
1033 switch(m_modifier.m_miscvalue)
1035 case FORM_CAT:
1036 if(unit_target->getRace() == RACE_NIGHTELF)
1037 modelid = 892;
1038 else if(unit_target->getRace() == RACE_TAUREN)
1039 modelid = 8571;
1040 PowerType = POWER_ENERGY;
1041 break;
1042 case FORM_TRAVEL:
1043 modelid = 632;
1044 break;
1045 case FORM_AQUA:
1046 if(unit_target->getRace() == RACE_NIGHTELF)
1047 modelid = 2428;
1048 else if(unit_target->getRace() == RACE_TAUREN)
1049 modelid = 2428;
1050 break;
1051 case FORM_BEAR:
1052 if(unit_target->getRace() == RACE_NIGHTELF)
1053 modelid = 2281;
1054 else if(unit_target->getRace() == RACE_TAUREN)
1055 modelid = 2289;
1056 PowerType = POWER_RAGE;
1057 break;
1058 case FORM_GHOUL:
1059 if(unit_target->getRace() == RACE_NIGHTELF)
1060 modelid = 10045;
1061 break;
1062 case FORM_DIREBEAR:
1063 if(unit_target->getRace() == RACE_NIGHTELF)
1064 modelid = 2281;
1065 else if(unit_target->getRace() == RACE_TAUREN)
1066 modelid = 2289;
1067 PowerType = POWER_RAGE;
1068 break;
1069 case FORM_CREATUREBEAR:
1070 modelid = 902;
1071 break;
1072 case FORM_GHOSTWOLF:
1073 modelid = 4613;
1074 break;
1075 case FORM_MOONKIN:
1076 if(unit_target->getRace() == RACE_NIGHTELF)
1077 modelid = 15374;
1078 else if(unit_target->getRace() == RACE_TAUREN)
1079 modelid = 15375;
1080 break;
1081 case FORM_AMBIENT:
1082 case FORM_BATTLESTANCE:
1083 case FORM_BERSERKERSTANCE:
1084 case FORM_DEFENSIVESTANCE:
1085 case FORM_SHADOW:
1086 case FORM_STEALTH:
1087 case FORM_TREE:
1088 break;
1089 default:
1090 sLog.outError("Auras: Unknown Shapeshift Type: %u", m_modifier.m_miscvalue);
1093 if(apply)
1095 unit_target->SetFlag(UNIT_FIELD_BYTES_1, (new_bytes_1<<16) );
1096 if(modelid > 0)
1098 unit_target->SetUInt32Value(UNIT_FIELD_DISPLAYID,modelid);
1101 if(PowerType != POWER_MANA)
1103 unit_target->setPowerType(PowerType);
1105 // energy in cat start with 0.
1106 //TODO: implement SPELL_AURA_ADD_TARGET_TRIGGER that used for receiving with some chance non-0 energy at transformation
1107 if(m_modifier.m_miscvalue == FORM_CAT)
1108 unit_target->SetPower(POWER_ENERGY,0);
1111 unit_target->m_ShapeShiftForm = m_spellId;
1112 unit_target->m_form = m_modifier.m_miscvalue;
1113 if(unit_target->m_form == FORM_DIREBEAR)
1114 if (m_target->getRace() == RACE_TAUREN)
1116 m_target->SetFloatValue(OBJECT_FIELD_SCALE_X,1.35f);
1118 else
1119 m_target->SetFloatValue(OBJECT_FIELD_SCALE_X,1.0f);
1121 else
1123 if (m_target->getRace() == RACE_TAUREN)
1124 unit_target->SetFloatValue(OBJECT_FIELD_SCALE_X,1.35f);
1125 else
1126 unit_target->SetFloatValue(OBJECT_FIELD_SCALE_X,1.0f);
1127 unit_target->SetUInt32Value(UNIT_FIELD_DISPLAYID,unit_target->GetUInt32Value(UNIT_FIELD_NATIVEDISPLAYID));
1128 unit_target->RemoveFlag(UNIT_FIELD_BYTES_1, (new_bytes_1<<16) );
1129 if(unit_target->getClass() == CLASS_DRUID)
1130 unit_target->setPowerType(POWER_MANA);
1131 unit_target->m_ShapeShiftForm = 0;
1132 unit_target->m_form = 0;
1135 if(player)
1136 player->InitDataForForm();
1138 // apply for new form
1139 if(player)
1141 player->_ApplyStatsMods();
1142 player->_ApplyAllAuraMods();
1143 player->_ApplyAllItemMods();
1144 player->_RemoveStatsMods();
1148 void Aura::HandleAuraTransform(bool apply, bool Real)
1150 if(!m_target)
1151 return;
1153 if (apply)
1155 // special case
1156 if(m_modifier.m_miscvalue==0)
1158 if(m_target->GetTypeId()!=TYPEID_PLAYER)
1159 return;
1161 uint32 orb_model = m_target->GetUInt32Value(UNIT_FIELD_NATIVEDISPLAYID);
1162 switch(orb_model)
1164 // Troll Female
1165 case 1479: m_target->SetUInt32Value(UNIT_FIELD_DISPLAYID, 10134); break;
1166 // Troll Male
1167 case 1478: m_target->SetUInt32Value(UNIT_FIELD_DISPLAYID, 10135); break;
1168 // Tauren Male
1169 case 59: m_target->SetUInt32Value(UNIT_FIELD_DISPLAYID, 10136); break;
1170 // Human Male
1171 case 49: m_target->SetUInt32Value(UNIT_FIELD_DISPLAYID, 10137); break;
1172 // Human Female
1173 case 50: m_target->SetUInt32Value(UNIT_FIELD_DISPLAYID, 10138); break;
1174 // Orc Male
1175 case 51: m_target->SetUInt32Value(UNIT_FIELD_DISPLAYID, 10139); break;
1176 // Orc Female
1177 case 52: m_target->SetUInt32Value(UNIT_FIELD_DISPLAYID, 10140); break;
1178 // Dwarf Male
1179 case 53: m_target->SetUInt32Value(UNIT_FIELD_DISPLAYID, 10141); break;
1180 // Dwarf Female
1181 case 54: m_target->SetUInt32Value(UNIT_FIELD_DISPLAYID, 10142); break;
1182 // NightElf Male
1183 case 55: m_target->SetUInt32Value(UNIT_FIELD_DISPLAYID, 10143); break;
1184 // NightElf Female
1185 case 56: m_target->SetUInt32Value(UNIT_FIELD_DISPLAYID, 10144); break;
1186 // Undead Female
1187 case 58: m_target->SetUInt32Value(UNIT_FIELD_DISPLAYID, 10145); break;
1188 // Undead Male
1189 case 57: m_target->SetUInt32Value(UNIT_FIELD_DISPLAYID, 10146); break;
1190 // Tauren Female
1191 case 60: m_target->SetUInt32Value(UNIT_FIELD_DISPLAYID, 10147); break;
1192 // Gnome Male
1193 case 1563: m_target->SetUInt32Value(UNIT_FIELD_DISPLAYID, 10148); break;
1194 // Gnome Female
1195 case 1564: m_target->SetUInt32Value(UNIT_FIELD_DISPLAYID, 10149); break;
1196 default: break;
1199 else
1201 CreatureInfo const * ci = objmgr.GetCreatureTemplate(m_modifier.m_miscvalue);
1202 if(!ci)
1204 //pig pink ^_^
1205 m_target->SetUInt32Value (UNIT_FIELD_DISPLAYID, 16358);
1206 sLog.outError("Auras: unknown creature id = %d (only need its modelid) Form Spell Aura Transform in Spell ID = %d", m_modifier.m_miscvalue, GetSpellProto()->Id);
1208 else
1210 m_target->SetUInt32Value (UNIT_FIELD_DISPLAYID, ci->randomDisplayID());
1212 m_target->setTransForm(GetSpellProto()->Id);
1215 else
1217 m_target->SetUInt32Value (UNIT_FIELD_DISPLAYID, m_target->GetUInt32Value(UNIT_FIELD_NATIVEDISPLAYID));
1218 m_target->setTransForm(0);
1221 Unit* caster = GetCaster();
1223 if(caster && caster->GetTypeId() == TYPEID_PLAYER)
1224 m_target->SendUpdateToPlayer((Player*)caster);
1227 void Aura::HandleForceReaction(bool Apply, bool Real)
1229 if(m_target->GetTypeId() != TYPEID_PLAYER)
1230 return;
1232 if(Apply)
1234 uint32 faction_id = m_modifier.m_miscvalue;
1236 FactionTemplateEntry const *factionTemplateEntry = NULL;
1238 for(uint32 i = 0; i < sFactionTemplateStore.GetNumRows(); ++i)
1240 factionTemplateEntry = sFactionTemplateStore.LookupEntry(i);
1241 if(!factionTemplateEntry)
1242 continue;
1244 if(factionTemplateEntry->faction == faction_id)
1245 break;
1248 if(!factionTemplateEntry)
1249 return;
1251 m_target->setFaction(factionTemplateEntry->ID);
1253 else
1254 ((Player*)m_target)->setFactionForRace(((Player*)m_target)->getRace());
1257 void Aura::HandleAuraModSkill(bool apply, bool Real)
1259 if(m_target->GetTypeId() != TYPEID_PLAYER)
1260 return;
1262 uint32 prot=GetSpellProto()->EffectMiscValue[m_effIndex];
1263 int32 points = GetSpellProto()->EffectBasePoints[m_effIndex]+1;
1265 ((Player*)m_target)->ModifySkillBonus(prot,(apply ? points: -points));
1266 if(prot == SKILL_DEFENSE)
1267 ((Player*)m_target)->ApplyDefenseBonusesMod(points, apply);
1270 void Aura::HandleChannelDeathItem(bool apply, bool Real)
1272 if(!apply)
1274 Unit* caster = GetCaster();
1275 Unit* victim = GetTarget();
1276 if(!caster || caster->GetTypeId() != TYPEID_PLAYER || !victim || !m_removeOnDeath)
1277 return;
1279 SpellEntry const *spellInfo = GetSpellProto();
1280 if(spellInfo->EffectItemType[m_effIndex] == 0)
1281 return;
1283 // Soul Shard only from non-grey units
1284 if( victim->getLevel() <= MaNGOS::XP::GetGrayLevel(caster->getLevel()) && spellInfo->EffectItemType[m_effIndex] == 6265)
1285 return;
1287 uint16 dest;
1288 uint8 msg = ((Player*)caster)->CanStoreNewItem( NULL_BAG, NULL_SLOT, dest, spellInfo->EffectItemType[m_effIndex], 1, false);
1289 if( msg == EQUIP_ERR_OK )
1290 ((Player*)caster)->StoreNewItem(dest, spellInfo->EffectItemType[m_effIndex], 1, true);
1291 else
1292 ((Player*)caster)->SendEquipError( msg, NULL, NULL );
1296 void Aura::HandleAuraSafeFall(bool apply, bool Real)
1298 // only at real add/remove aura
1299 if(!Real)
1300 return;
1302 WorldPacket data;
1303 if(apply)
1304 data.Initialize(SMSG_MOVE_FEATHER_FALL, 8);
1305 else
1306 data.Initialize(SMSG_MOVE_NORMAL_FALL, 8);
1307 data.append(m_target->GetPackGUID());
1308 m_target->SendMessageToSet(&data,true);
1311 void Aura::HandleBindSight(bool apply, bool Real)
1313 if(!m_target)
1314 return;
1316 if(GetCaster()->GetTypeId() != TYPEID_PLAYER)
1317 return;
1319 GetCaster()->SetUInt64Value(PLAYER_FARSIGHT,apply ? m_target->GetGUID() : 0);
1322 void Aura::HandleFarSight(bool apply, bool Real)
1324 if(!m_target)
1325 return;
1327 if(GetCaster()->GetTypeId() != TYPEID_PLAYER)
1328 return;
1330 GetCaster()->SetUInt64Value(PLAYER_FARSIGHT,apply ? m_modifier.m_miscvalue : 0);
1333 void Aura::HandleAuraTrackCreatures(bool apply, bool Real)
1335 if(m_target->GetTypeId()!=TYPEID_PLAYER)
1336 return;
1338 if(apply)
1339 m_target->RemoveNoStackAurasDueToAura(this);
1340 m_target->SetUInt32Value(PLAYER_TRACK_CREATURES, apply ? ((uint32)1)<<(m_modifier.m_miscvalue-1) : 0 );
1343 void Aura::HandleAuraTrackResources(bool apply, bool Real)
1345 if(m_target->GetTypeId()!=TYPEID_PLAYER)
1346 return;
1348 if(apply)
1349 m_target->RemoveNoStackAurasDueToAura(this);
1350 m_target->SetUInt32Value(PLAYER_TRACK_RESOURCES, apply ? ((uint32)1)<<(m_modifier.m_miscvalue-1): 0 );
1353 void Aura::HandleAuraTrackStealthed(bool apply, bool Real)
1355 if(m_target->GetTypeId()!=TYPEID_PLAYER)
1356 return;
1358 if(apply)
1359 m_target->RemoveNoStackAurasDueToAura(this);
1361 //TODO: add stealthed tracking effect
1364 void Aura::HandleAuraModScale(bool apply, bool Real)
1366 m_target->ApplyPercentModFloatValue(OBJECT_FIELD_SCALE_X,m_modifier.m_amount,apply);
1369 void Aura::HandleModPossess(bool apply, bool Real)
1371 if(!m_target)
1372 return;
1373 if(!Real)
1374 return;
1376 if(m_target->GetTypeId() == TYPEID_UNIT)
1378 CreatureInfo const *cinfo = ((Creature*)m_target)->GetCreatureInfo();
1379 if(cinfo->type != CREATURE_TYPE_HUMANOID)
1380 return;
1383 Unit* caster = GetCaster();
1384 if(!caster)
1385 return;
1387 if(int32(m_target->getLevel()) <= m_modifier.m_amount)
1389 if( apply )
1391 m_target->SetUInt64Value(UNIT_FIELD_CHARMEDBY,caster->GetGUID());
1392 m_target->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE,caster->getFaction());
1393 caster->SetCharm((Creature*)m_target);
1394 if(caster->GetTypeId() == TYPEID_PLAYER)
1396 ((Player*)caster)->PetSpellInitialize();
1398 if(caster->getVictim()==m_target)
1399 caster->AttackStop();
1400 m_target->CombatStop();
1402 else
1404 m_target->SetUInt64Value(UNIT_FIELD_CHARMEDBY,0);
1406 if(m_target->GetTypeId() == TYPEID_PLAYER)
1408 ((Player*)m_target)->setFactionForRace(m_target->getRace());
1410 else if(m_target->GetTypeId() == TYPEID_UNIT)
1412 CreatureInfo const *cinfo = ((Creature*)m_target)->GetCreatureInfo();
1413 m_target->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE,cinfo->faction);
1416 caster->SetCharm(0);
1418 if(caster->GetTypeId() == TYPEID_PLAYER)
1420 WorldPacket data(SMSG_PET_SPELLS, 8);
1421 data << uint64(0);
1422 ((Player*)caster)->GetSession()->SendPacket(&data);
1424 if(m_target->GetTypeId() == TYPEID_UNIT)
1426 ((Creature*)m_target)->AIM_Initialize();
1427 ((Creature*)m_target)->Attack(caster);
1430 if(caster->GetTypeId() == TYPEID_PLAYER)
1431 GetCaster()->SetUInt64Value(PLAYER_FARSIGHT,apply ? m_target->GetGUID() : 0);
1435 void Aura::HandleModPossessPet(bool apply, bool Real)
1437 if(!m_target)
1438 return;
1439 if(!Real)
1440 return;
1442 Unit* caster = GetCaster();
1443 if(!caster || caster->GetTypeId() != TYPEID_PLAYER)
1444 return;
1445 if(GetCaster()->GetPet() != m_target)
1446 return;
1448 if(caster->GetTypeId() == TYPEID_PLAYER)
1449 GetCaster()->SetUInt64Value(PLAYER_FARSIGHT,apply ? m_target->GetGUID() : 0);
1452 void Aura::HandleModCharm(bool apply, bool Real)
1454 if(!m_target)
1455 return;
1456 if(!Real)
1457 return;
1459 Unit* caster = GetCaster();
1460 if(!caster)
1461 return;
1463 if(int32(m_target->getLevel()) <= m_modifier.m_amount)
1465 if( apply )
1467 m_target->SetUInt64Value(UNIT_FIELD_CHARMEDBY,caster->GetGUID());
1468 m_target->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE,caster->getFaction());
1469 caster->SetCharm((Creature*)m_target);
1471 if(caster->getVictim()==m_target)
1472 caster->AttackStop();
1473 m_target->CombatStop();
1475 if(caster->GetTypeId() == TYPEID_PLAYER)
1477 ((Player*)caster)->PetSpellInitialize();
1480 else
1482 m_target->SetUInt64Value(UNIT_FIELD_CHARMEDBY,0);
1484 if(m_target->GetTypeId() == TYPEID_PLAYER)
1486 ((Player*)m_target)->setFactionForRace(m_target->getRace());
1488 else if(m_target->GetTypeId() == TYPEID_UNIT)
1490 CreatureInfo const *cinfo = ((Creature*)m_target)->GetCreatureInfo();
1491 m_target->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE,cinfo->faction);
1494 caster->SetCharm(0);
1496 if(caster->GetTypeId() == TYPEID_PLAYER)
1498 WorldPacket data(SMSG_PET_SPELLS, 8);
1499 data << uint64(0);
1500 ((Player*)caster)->GetSession()->SendPacket(&data);
1502 if(m_target->GetTypeId() == TYPEID_UNIT)
1504 ((Creature*)m_target)->AIM_Initialize();
1505 ((Creature*)m_target)->Attack(caster);
1511 void Aura::HandleModConfuse(bool apply, bool Real)
1513 uint32 apply_stat = UNIT_STAT_CONFUSED;
1514 if( apply )
1516 m_target->addUnitState(UNIT_STAT_CONFUSED);
1517 m_target->SetFlag(UNIT_FIELD_FLAGS,(apply_stat<<16));
1519 // only at real add aura
1520 if(Real)
1522 if (m_target->GetTypeId() == TYPEID_UNIT)
1523 (*((Creature*)m_target))->Mutate(new ConfusedMovementGenerator(*((Creature*)m_target)));
1526 else
1528 m_target->clearUnitState(UNIT_STAT_CONFUSED);
1529 m_target->RemoveFlag(UNIT_FIELD_FLAGS,(apply_stat<<16));
1531 // only at real remove aura
1532 if(Real)
1534 if (m_target->GetTypeId() == TYPEID_UNIT)
1535 (*((Creature*)m_target))->MovementExpired();
1540 void Aura::HandleModFear(bool Apply, bool Real)
1542 uint32 apply_stat = UNIT_STAT_FLEEING;
1543 if( Apply )
1545 m_target->addUnitState(UNIT_STAT_FLEEING);
1546 // m_target->AttackStop();
1548 m_target->SetFlag(UNIT_FIELD_FLAGS,(apply_stat<<16));
1550 // only at real add aura
1551 if(Real)
1553 WorldPacket data(SMSG_DEATH_NOTIFY_OBSOLETE, 9);
1554 data<<m_target->GetGUID();
1555 data<<uint8(0);
1556 m_target->SendMessageToSet(&data,true);
1559 else
1561 m_target->clearUnitState(UNIT_STAT_FLEEING);
1562 m_target->RemoveFlag(UNIT_FIELD_FLAGS,(apply_stat<<16));
1564 // only at real remove aura
1565 if(Real)
1567 if(m_target->GetTypeId() != TYPEID_PLAYER)
1568 m_target->Attack(GetCaster());
1569 WorldPacket data(SMSG_DEATH_NOTIFY_OBSOLETE, 9);
1570 data<<m_target->GetGUID();
1571 data<<uint8(1);
1572 m_target->SendMessageToSet(&data,true);
1577 void Aura::HandleFeignDeath(bool Apply, bool Real)
1579 uint32 apply_stat = UNIT_STAT_DIED;
1580 if( Apply )
1582 //m_target->addUnitState(UNIT_STAT_DIED);
1583 // m_target->AttackStop();
1585 //m_target->SetFlag(UNIT_FIELD_FLAGS,(apply_stat<<16));
1587 // only at real add aura
1588 if(Real)
1591 WorldPacket data(SMSG_FEIGN_DEATH_RESISTED, 9);
1592 data<<m_target->GetGUID();
1593 data<<uint8(0);
1594 m_target->SendMessageToSet(&data,true);
1596 m_target->HandleEmoteCommand(EMOTE_STATE_DEAD);
1597 m_target->ClearInCombat();
1598 m_target->AttackStop();
1599 m_target->setDeathState(CORPSE);
1600 m_target->SetHealth(0);
1604 else
1606 m_target->SetHealth(m_target->GetMaxHealth()/2);
1607 m_target->setDeathState(ALIVE);
1608 //m_target->RemoveFlag(UNIT_FIELD_FLAGS,(apply_stat<<16));
1610 // only at real remove aura
1611 if(!Real)
1614 WorldPacket data(SMSG_FEIGN_DEATH_RESISTED, 9);
1615 data<<m_target->GetGUID();
1616 data<<uint8(1);
1617 m_target->SendMessageToSet(&data,true);
1624 void Aura::HandleAuraModStun(bool apply, bool Real)
1626 if (apply)
1628 m_target->addUnitState(UNIT_STAT_STUNDED);
1629 m_target->SetUInt64Value (UNIT_FIELD_TARGET, 0);
1630 m_target->SetFlag(UNIT_FIELD_FLAGS, 0x40000);
1632 // only at real add aura
1633 if(Real)
1635 if(m_target->GetTypeId() != TYPEID_PLAYER)
1636 ((Creature *)m_target)->StopMoving();
1638 WorldPacket data(SMSG_FORCE_MOVE_ROOT, 8);
1639 data.append(m_target->GetPackGUID());
1640 m_target->SendMessageToSet(&data,true);
1643 else
1645 m_target->clearUnitState(UNIT_STAT_STUNDED);
1646 m_target->RemoveFlag(UNIT_FIELD_FLAGS, 0x40000);
1647 Unit* caster = GetCaster();
1648 if(caster) // set creature facing on root effect
1650 m_target->SetUInt64Value (UNIT_FIELD_TARGET,caster->GetGUIDLow());
1653 // only at real remove aura
1654 if(Real)
1656 WorldPacket data(SMSG_FORCE_MOVE_UNROOT, 8);
1657 data.append(m_target->GetPackGUID());
1658 m_target->SendMessageToSet(&data,true);
1663 void Aura::HandleModStealth(bool apply, bool Real)
1665 if(apply)
1667 m_target->m_stealthvalue = CalculateDamage();
1668 m_target->SetFlag(UNIT_FIELD_BYTES_1, PLAYER_STATE_FLAG_STEALTH);
1670 // only at real aura add
1671 if(Real)
1673 m_target->SetVisibility(VISIBILITY_GROUP);
1674 if(m_target->GetTypeId() == TYPEID_PLAYER)
1675 m_target->SendUpdateToPlayer((Player*)m_target);
1678 else
1680 m_target->m_stealthvalue = 0;
1681 m_target->RemoveFlag(UNIT_FIELD_BYTES_1, PLAYER_STATE_FLAG_STEALTH);
1683 // only at real aura remove
1684 if(Real)
1686 SendCoolDownEvent();
1687 m_target->SetVisibility(VISIBILITY_ON);
1688 if(m_target->GetTypeId() == TYPEID_PLAYER)
1689 m_target->SendUpdateToPlayer((Player*)m_target);
1694 void Aura::HandleModDetect(bool apply, bool Real)
1696 if(apply)
1698 m_target->m_detectStealth = CalculateDamage();
1700 else
1702 m_target->m_detectStealth = 0;
1706 void Aura::HandleInvisibility(bool Apply, bool Real)
1708 if(Apply)
1710 m_target->m_stealthvalue = CalculateDamage();
1711 m_target->SetFlag(UNIT_FIELD_BYTES_1, PLAYER_STATE_FLAG_STEALTH );
1713 // only at real aura add
1714 if(Real)
1716 m_target->SetVisibility(VISIBILITY_GROUP);
1717 if(m_target->GetTypeId() == TYPEID_PLAYER)
1718 m_target->SendUpdateToPlayer((Player*)m_target);
1721 else
1723 m_target->m_stealthvalue = 0;
1724 m_target->RemoveFlag(UNIT_FIELD_BYTES_1, PLAYER_STATE_FLAG_STEALTH );
1726 // only at real aura remove
1727 if(Real)
1729 SendCoolDownEvent();
1730 m_target->SetVisibility(VISIBILITY_ON);
1731 if(m_target->GetTypeId() == TYPEID_PLAYER)
1732 m_target->SendUpdateToPlayer((Player*)m_target);
1737 void Aura::HandleInvisibilityDetect(bool Apply, bool Real)
1739 if(Apply)
1741 m_target->m_detectStealth = CalculateDamage();
1743 else
1745 m_target->m_detectStealth = 0;
1749 void Aura::HandleAuraModRoot(bool apply, bool Real)
1751 uint32 apply_stat = UNIT_STAT_ROOT;
1752 if (apply)
1754 m_target->addUnitState(UNIT_STAT_ROOT);
1755 m_target->SetUInt64Value (UNIT_FIELD_TARGET, 0);
1756 m_target->SetFlag(UNIT_FIELD_FLAGS,(apply_stat<<16));
1758 // only at real add aura
1759 if(Real)
1761 if(m_target->GetTypeId() == TYPEID_PLAYER)
1763 WorldPacket data(SMSG_FORCE_MOVE_ROOT, 10);
1764 data.append(m_target->GetPackGUID());
1765 data << (uint32)2;
1766 m_target->SendMessageToSet(&data,true);
1768 else
1769 ((Creature *)m_target)->StopMoving();
1772 else
1774 m_target->clearUnitState(UNIT_STAT_ROOT);
1775 m_target->RemoveFlag(UNIT_FIELD_FLAGS,(apply_stat<<16));
1776 Unit* caster = GetCaster();
1777 if(caster) // set creature facing on root effect
1779 m_target->SetUInt64Value (UNIT_FIELD_TARGET,caster->GetGUIDLow());
1782 // only at real remove aura
1783 if(Real)
1785 if(m_target->GetTypeId() == TYPEID_PLAYER)
1787 WorldPacket data(SMSG_FORCE_MOVE_UNROOT, 10);
1788 data.append(m_target->GetPackGUID());
1789 data << (uint32)2;
1790 m_target->SendMessageToSet(&data,true);
1796 void Aura::HandleAuraModSilence(bool apply, bool Real)
1798 apply ? m_target->m_silenced = true : m_target->m_silenced = false;
1801 void Aura::HandleModThreat(bool apply, bool Real)
1803 // only at real add/remove aura
1804 if(!Real)
1805 return;
1807 if(!m_target || !m_target->isAlive())
1808 return;
1810 Unit* caster = GetCaster();
1812 if(!caster || !caster->isAlive())
1813 return;
1815 if(m_modifier.m_miscvalue < SPELL_SCHOOL_NORMAL || m_modifier.m_miscvalue >= (1<<MAX_SPELL_SCHOOOL))
1817 sLog.outError("WARNING: Misc Value for SPELL_AURA_MOD_THREAT not valid");
1818 return;
1821 bool positive = m_modifier.m_miscvalue2 == 0;
1823 for(int8 x=0;x < MAX_SPELL_SCHOOOL;x++)
1825 if(m_modifier.m_miscvalue & int32(1<<x))
1827 if(m_target->GetTypeId() == TYPEID_PLAYER)
1828 ApplyPercentModFloatVar(m_target->m_threatModifier[x], positive ? m_modifier.m_amount : -m_modifier.m_amount, apply);
1833 void Aura::HandleModTaunt(bool apply, bool Real)
1835 // only at real add/remove aura
1836 if(!Real)
1837 return;
1839 if(!m_target || !m_target->isAlive() || !m_target->CanHaveThreatList())
1840 return;
1842 Unit* caster = GetCaster();
1844 if(!caster || !caster->isAlive() || caster->GetTypeId() != TYPEID_PLAYER)
1845 return;
1847 if(apply)
1849 if (m_target->getVictim() != caster)
1850 m_target->TauntApply(caster);
1852 else
1854 // When taunt aura fades out, mob will switch to previous target if current has less than 1.1 * secondthreat
1855 m_target->TauntFadeOut(caster);
1859 /*********************************************************/
1860 /*** MODIDY SPEED ***/
1861 /*********************************************************/
1863 void Aura::HandleAuraModIncreaseSpeedAlways(bool apply, bool Real)
1865 // all applied/removed only at real aura add/remove
1866 if(!Real)
1867 return;
1869 sLog.outDebug("HandleAuraModIncreaseSpeedAlways: Current Speed:%f \tmodify percent:%f", m_target->GetSpeed(MOVE_RUN),(float)m_modifier.m_amount);
1870 if(m_modifier.m_amount<=1)
1871 return;
1873 float rate = (100.0f + m_modifier.m_amount)/100.0f;
1875 m_target->ApplySpeedMod(MOVE_RUN, rate, false, apply );
1876 sLog.outDebug("ChangeSpeedTo:%f", m_target->GetSpeed(MOVE_RUN));
1879 void Aura::HandleAuraModIncreaseSpeed(bool apply, bool Real)
1881 // all applied/removed only at real aura add/remove
1882 if(!Real)
1883 return;
1885 sLog.outDebug("HandleAuraModIncreaseSpeed: Current Speed:%f \tmodify percent:%f", m_target->GetSpeed(MOVE_RUN),(float)m_modifier.m_amount);
1886 if(m_modifier.m_amount<=1)
1887 return;
1889 float rate = (100.0f + m_modifier.m_amount)/100.0f;
1891 m_target->ApplySpeedMod(MOVE_RUN, rate, true, apply );
1893 sLog.outDebug("ChangeSpeedTo:%f", m_target->GetSpeed(MOVE_RUN));
1896 void Aura::HandleAuraModIncreaseMountedSpeed(bool apply, bool Real)
1898 // all applied/removed only at real aura add/remove
1899 if(!Real)
1900 return;
1902 sLog.outDebug("HandleAuraModIncreaseMountedSpeed: Current Speed:%f \tmodify percent:%f", m_target->GetSpeed(MOVE_RUN),(float)m_modifier.m_amount);
1903 if(m_modifier.m_amount<=1)
1904 return;
1906 float rate = (100.0f + m_modifier.m_amount)/100.0f;
1908 m_target->ApplySpeedMod(MOVE_RUN, rate, true, apply );
1910 sLog.outDebug("ChangeSpeedTo:%f", m_target->GetSpeed(MOVE_RUN));
1913 void Aura::HandleAuraModDecreaseSpeed(bool apply, bool Real)
1915 // all applied/removed only at real aura add/remove
1916 if(!Real)
1917 return;
1919 sLog.outDebug("HandleAuraModDecreaseSpeed: Current Speed:%f \tmodify percent:%f", m_target->GetSpeed(MOVE_RUN),(float)m_modifier.m_amount);
1920 if(m_modifier.m_amount <= 0)
1921 { //for new spell dbc
1922 float rate = (100.0f + m_modifier.m_amount)/100.0f;
1924 m_target->ApplySpeedMod(MOVE_RUN, rate, true, apply );
1926 else
1927 { //for old spell dbc
1928 float rate = m_modifier.m_amount / 100.0f;
1930 m_target->ApplySpeedMod(MOVE_RUN, rate, true, apply );
1932 sLog.outDebug("ChangeSpeedTo:%f", m_target->GetSpeed(MOVE_RUN));
1935 void Aura::HandleAuraModIncreaseSwimSpeed(bool apply, bool Real)
1937 // all applied/removed only at real aura add/remove
1938 if(!Real)
1939 return;
1941 sLog.outDebug("HandleAuraModIncreaseSwimSpeed: Current Speed:%f \tmodify percent:%f", m_target->GetSpeed(MOVE_SWIM),(float)m_modifier.m_amount);
1942 if(m_modifier.m_amount<=1)
1943 return;
1945 float rate = (100.0f + m_modifier.m_amount)/100.0f;
1947 m_target->ApplySpeedMod(MOVE_SWIM, rate, true, apply );
1949 sLog.outDebug("ChangeSpeedTo:%f", m_target->GetSpeed(MOVE_SWIM));
1952 /*********************************************************/
1953 /*** IMMUNITY ***/
1954 /*********************************************************/
1956 void Aura::HandleModMechanicImmunity(bool apply, bool Real)
1958 m_target->ApplySpellImmune(GetId(),IMMUNITY_MECHANIC,m_modifier.m_miscvalue,apply);
1961 void Aura::HandleAuraModEffectImmunity(bool apply, bool Real)
1963 m_target->ApplySpellImmune(GetId(),IMMUNITY_EFFECT,m_modifier.m_miscvalue,apply);
1966 void Aura::HandleAuraModStateImmunity(bool apply, bool Real)
1968 m_target->ApplySpellImmune(GetId(),IMMUNITY_STATE,m_modifier.m_miscvalue,apply);
1971 void Aura::HandleAuraModSchoolImmunity(bool apply, bool Real)
1973 m_target->ApplySpellImmune(GetId(),IMMUNITY_SCHOOL,m_modifier.m_miscvalue,apply);
1976 void Aura::HandleAuraModDmgImmunity(bool apply, bool Real)
1978 m_target->ApplySpellImmune(GetId(),IMMUNITY_DAMAGE,m_modifier.m_miscvalue,apply);
1981 void Aura::HandleAuraModDispelImmunity(bool apply, bool Real)
1983 m_target->ApplySpellImmune(GetId(),IMMUNITY_DISPEL,m_modifier.m_miscvalue,apply);
1986 /*********************************************************/
1987 /*** MANA SHIELD ***/
1988 /*********************************************************/
1990 void Aura::HandleAuraDamageShield(bool apply, bool Real)
1992 /*if(apply)
1994 for(std::list<struct DamageShield>::iterator i = m_target->m_damageShields.begin();i != m_target->m_damageShields.end();i++)
1995 if(i->m_spellId == GetId() && i->m_caster_guid == m_caster_guid)
1997 m_target->m_damageShields.erase(i);
1998 break;
2000 DamageShield* ds = new DamageShield();
2001 ds->m_caster_guid = m_caster_guid;
2002 ds->m_damage = m_modifier.m_amount;
2003 ds->m_spellId = GetId();
2004 m_target->m_damageShields.push_back((*ds));
2006 else
2008 for(std::list<struct DamageShield>::iterator i = m_target->m_damageShields.begin();i != m_target->m_damageShields.end();i++)
2009 if(i->m_spellId == GetId() && i->m_caster_guid == m_caster_guid)
2011 m_target->m_damageShields.erase(i);
2012 break;
2017 void Aura::HandleAuraManaShield(bool apply, bool Real)
2019 if (apply && !m_absorbDmg)
2020 m_absorbDmg = m_modifier.m_amount;
2022 /*if(apply)
2025 for(std::list<struct DamageManaShield*>::iterator i = m_target->m_damageManaShield.begin();i != m_target->m_damageManaShield.end();i++)
2027 if(GetId() == (*i)->m_spellId)
2029 delete *i;
2030 m_target->m_damageManaShield.erase(i);
2034 DamageManaShield *dms = new DamageManaShield();
2036 dms->m_spellId = GetId();
2037 dms->m_modType = m_modifier.m_auraname;
2038 dms->m_totalAbsorb = m_modifier.m_amount;
2039 dms->m_currAbsorb = 0;
2040 dms->m_schoolType = m_modifier.m_miscvalue;
2041 m_target->m_damageManaShield.push_back(dms);
2043 else
2045 for(std::list<struct DamageManaShield*>::iterator i = m_target->m_damageManaShield.begin();i != m_target->m_damageManaShield.end();i++)
2047 if(GetId() == (*i)->m_spellId)
2049 delete *i;
2050 m_target->m_damageManaShield.erase(i);
2051 break;
2057 void Aura::HandleAuraSchoolAbsorb(bool apply, bool Real)
2059 if (apply && !m_absorbDmg)
2060 m_absorbDmg = m_modifier.m_amount;
2061 /*if(apply)
2064 for(std::list<struct DamageManaShield*>::iterator i = m_target->m_damageManaShield.begin();i != m_target->m_damageManaShield.end();i++)
2066 if(GetId() == (*i)->m_spellId)
2068 m_target->m_damageManaShield.erase(i);
2072 DamageManaShield *dms = new DamageManaShield();
2074 dms->m_spellId = GetId();
2075 dms->m_modType = m_modifier.m_auraname;
2076 dms->m_totalAbsorb = m_modifier.m_amount;
2077 dms->m_currAbsorb = 0;
2078 dms->m_schoolType = m_modifier.m_miscvalue;
2079 m_target->m_damageManaShield.push_back(dms);
2081 else
2083 for(std::list<struct DamageManaShield*>::iterator i = m_target->m_damageManaShield.begin();i != m_target->m_damageManaShield.end();i++)
2085 if(GetId() == (*i)->m_spellId)
2087 m_target->m_damageManaShield.erase(i);
2088 break;
2094 /*********************************************************/
2095 /*** REFLECT SPELLS ***/
2096 /*********************************************************/
2098 void Aura::HandleReflectSpells(bool apply, bool Real)
2100 // has no immediate effect when adding / removing
2103 void Aura::HandleReflectSpellsSchool(bool apply, bool Real)
2105 // has no immediate effect when adding / removing
2108 /*********************************************************/
2109 /*** PROC TRIGGER ***/
2110 /*********************************************************/
2112 void Aura::HandleAuraProcTriggerSpell(bool apply, bool Real)
2114 if(apply && !m_procCharges)
2116 m_procCharges = GetSpellProto()->procCharges;
2117 if (!m_procCharges)
2118 m_procCharges = -1;
2122 void Aura::HandleAuraProcTriggerDamage(bool apply, bool Real)
2124 if(apply && !m_procCharges)
2126 m_procCharges = GetSpellProto()->procCharges;
2127 if (!m_procCharges)
2128 m_procCharges = -1;
2132 /*********************************************************/
2133 /*** PERIODIC ***/
2134 /*********************************************************/
2136 void Aura::HandlePeriodicTriggerSpell(bool apply, bool Real)
2138 if (m_periodicTimer <= 0)
2139 m_periodicTimer += m_modifier.periodictime;
2141 m_isPeriodic = apply;
2142 m_isTrigger = apply;
2145 void Aura::HandlePeriodicEnergize(bool apply, bool Real)
2147 if (m_periodicTimer <= 0)
2148 m_periodicTimer += m_modifier.periodictime;
2150 m_isPeriodic = apply;
2153 void Aura::HandlePeriodicHeal(bool apply, bool Real)
2155 if (m_periodicTimer <= 0)
2156 m_periodicTimer += m_modifier.periodictime;
2158 m_isPeriodic = apply;
2161 void Aura::HandlePeriodicDamage(bool apply, bool Real)
2163 if (m_periodicTimer <= 0)
2164 m_periodicTimer += m_modifier.periodictime;
2166 m_isPeriodic = apply;
2169 void Aura::HandlePeriodicDamagePCT(bool apply, bool Real)
2171 if (m_periodicTimer <= 0)
2172 m_periodicTimer += m_modifier.periodictime;
2174 m_isPeriodic = apply;
2177 void Aura::HandleModDetectRange(bool apply, bool Real)
2179 // has no immediate effect when adding / removing
2182 void Aura::HandlePeriodicLeech(bool apply, bool Real)
2184 if (m_periodicTimer <= 0)
2185 m_periodicTimer += m_modifier.periodictime;
2187 m_isPeriodic = apply;
2190 void Aura::HandlePeriodicManaLeech(bool apply, bool Real)
2192 if (m_periodicTimer <= 0)
2193 m_periodicTimer += m_modifier.periodictime;
2195 m_isPeriodic = apply;
2198 /*********************************************************/
2199 /*** MODITY STATES ***/
2200 /*********************************************************/
2202 /********************************/
2203 /*** RESISTANCE ***/
2204 /********************************/
2206 void Aura::HandleAuraModResistanceExclusive(bool apply, bool Real)
2208 if(m_modifier.m_miscvalue < IMMUNE_SCHOOL_PHYSICAL || m_modifier.m_miscvalue > 127)
2210 sLog.outError("WARNING: Misc Value for SPELL_AURA_MOD_BASE_RESISTANCE_PCT not valid");
2211 return;
2214 bool positive = m_modifier.m_miscvalue2 == 0;
2216 for(int8 x=0;x < MAX_SPELL_SCHOOOL;x++)
2218 if(m_modifier.m_miscvalue & int32(1<<x))
2220 SpellSchools school = SpellSchools(SPELL_SCHOOL_NORMAL + x);
2222 m_target->ApplyResistanceMod(school,m_modifier.m_amount, apply);
2223 if(m_target->GetTypeId() == TYPEID_PLAYER)
2224 ((Player*)m_target)->ApplyResistanceBuffModsMod(school,positive,m_modifier.m_amount, apply);
2229 void Aura::HandleAuraModResistance(bool apply, bool Real)
2231 if(m_modifier.m_miscvalue < IMMUNE_SCHOOL_PHYSICAL || m_modifier.m_miscvalue > 127)
2233 sLog.outError("WARNING: Misc Value for SPELL_AURA_MOD_BASE_RESISTANCE_PCT not valid");
2234 return;
2237 bool positive = m_modifier.m_miscvalue2 == 0;
2239 for(int8 x=0;x < MAX_SPELL_SCHOOOL;x++)
2241 if(m_modifier.m_miscvalue & int32(1<<x))
2243 SpellSchools school = SpellSchools(SPELL_SCHOOL_NORMAL + x);
2245 m_target->ApplyResistanceMod(school,m_modifier.m_amount, apply);
2246 if(m_target->GetTypeId() == TYPEID_PLAYER)
2247 ((Player*)m_target)->ApplyResistanceBuffModsMod(school,positive,m_modifier.m_amount, apply);
2252 void Aura::HandleAuraModBaseResistancePCT(bool apply, bool Real)
2254 if(m_modifier.m_miscvalue < IMMUNE_SCHOOL_PHYSICAL || m_modifier.m_miscvalue > 127)
2256 sLog.outError("WARNING: Misc Value for SPELL_AURA_MOD_BASE_RESISTANCE_PCT not valid");
2257 return;
2260 // only players have base stats
2261 if(m_target->GetTypeId() != TYPEID_PLAYER)
2262 return;
2263 Player *p_target = (Player*)m_target;
2265 for(int8 x=0;x < MAX_SPELL_SCHOOOL;x++)
2267 if(m_modifier.m_miscvalue & int32(1<<x))
2269 SpellSchools school = SpellSchools(SPELL_SCHOOL_NORMAL + x);
2270 float curRes = p_target->GetResistance(school);
2271 float baseRes = curRes + p_target->GetResistanceBuffMods(school, false) - p_target->GetResistanceBuffMods(school, true);
2272 float baseRes_new = baseRes * (apply?(100.0f+m_modifier.m_amount)/100.0f : 100.0f / (100.0f+m_modifier.m_amount));
2273 p_target->SetResistance(school, curRes + baseRes_new - baseRes);
2278 void Aura::HandleModResistancePercent(bool apply, bool Real)
2280 for(int8 i = 0; i < MAX_SPELL_SCHOOOL; i++)
2282 if(m_modifier.m_miscvalue & int32(1<<i))
2284 m_target->ApplyResistancePercentMod(SpellSchools(i), m_modifier.m_amount, apply );
2285 if(m_target->GetTypeId() == TYPEID_PLAYER)
2287 ((Player*)m_target)->ApplyResistanceBuffModsPercentMod(SpellSchools(i),true,m_modifier.m_amount, apply);
2288 ((Player*)m_target)->ApplyResistanceBuffModsPercentMod(SpellSchools(i),false,m_modifier.m_amount, apply);
2294 void Aura::HandleModBaseResistance(bool apply, bool Real)
2296 // only players have base stats
2297 if(m_target->GetTypeId() != TYPEID_PLAYER)
2298 return;
2299 Player *p_target = (Player*)m_target;
2301 for(int i = 0; i < MAX_SPELL_SCHOOOL; i++)
2302 if(m_modifier.m_miscvalue & (1<<i))
2303 p_target->ApplyResistanceMod(SpellSchools(SPELL_SCHOOL_NORMAL + i),m_modifier.m_amount, apply);
2306 /********************************/
2307 /*** STAT ***/
2308 /********************************/
2310 void Aura::HandleAuraModStat(bool apply, bool Real)
2312 if (m_modifier.m_miscvalue < -1 || m_modifier.m_miscvalue > 4)
2314 sLog.outError("WARNING: Misc Value for SPELL_AURA_MOD_STAT not valid");
2315 return;
2318 for(int32 i = 0; i < 5; i++)
2320 if (m_modifier.m_miscvalue == -1 || m_modifier.m_miscvalue == i)
2322 m_target->ApplyStatMod(Stats(i), m_modifier.m_amount,apply);
2323 if(m_target->GetTypeId() == TYPEID_PLAYER)
2325 if (m_modifier.m_miscvalue2 == 0)
2326 ((Player*)m_target)->ApplyPosStatMod(Stats(i),m_modifier.m_amount,apply);
2327 else
2328 ((Player*)m_target)->ApplyNegStatMod(Stats(i),m_modifier.m_amount,apply);
2334 void Aura::HandleModPercentStat(bool apply, bool Real)
2336 if (m_modifier.m_miscvalue < -1 || m_modifier.m_miscvalue > 4)
2338 sLog.outError("WARNING: Misc Value for SPELL_AURA_MOD_PERCENT_STAT not valid");
2339 return;
2342 // only players have base stats
2343 if (m_target->GetTypeId() != TYPEID_PLAYER)
2344 return;
2345 Player *p_target = (Player*)m_target;
2347 for (int32 i = 0; i < 5; i++)
2349 if(m_modifier.m_miscvalue == i || m_modifier.m_miscvalue == -1)
2351 float curStat = p_target->GetStat(Stats(i));
2352 float baseStat = curStat + p_target->GetNegStat(Stats(i)) - p_target->GetPosStat(Stats(i));
2353 float baseStat_new = baseStat * (apply?(100.0f+m_modifier.m_amount)/100.0f : 100.0f / (100.0f+m_modifier.m_amount));
2354 p_target->SetStat(Stats(i), curStat + baseStat_new - baseStat);
2355 p_target->ApplyCreateStatPercentMod(Stats(i), m_modifier.m_amount, apply );
2360 void Aura::HandleModTotalPercentStat(bool apply, bool Real)
2362 if (m_modifier.m_miscvalue < -1 || m_modifier.m_miscvalue > 4)
2364 sLog.outError("WARNING: Misc Value for SPELL_AURA_MOD_PERCENT_STAT not valid");
2365 return;
2368 for (int32 i = 0; i < 5; i++)
2370 if(m_modifier.m_miscvalue == i || m_modifier.m_miscvalue == -1)
2372 m_target->ApplyStatPercentMod(Stats(i), m_modifier.m_amount, apply );
2373 if (m_target->GetTypeId() == TYPEID_PLAYER)
2375 ((Player*)m_target)->ApplyPosStatPercentMod(Stats(i), m_modifier.m_amount, apply );
2376 ((Player*)m_target)->ApplyNegStatPercentMod(Stats(i), m_modifier.m_amount, apply );
2377 ((Player*)m_target)->ApplyCreateStatPercentMod(Stats(i), m_modifier.m_amount, apply );
2383 /********************************/
2384 /*** HEAL & ENERGIZE ***/
2385 /********************************/
2386 void Aura::HandleAuraModTotalHealthPercentRegen(bool apply, bool Real)
2389 Need additional checking for auras who reduce or increase healing, magic effect like Dumpen Magic,
2390 so this aura not fully working.
2392 if ((GetSpellProto()->AuraInterruptFlags & (1 << 18)) != 0)
2394 m_target->ApplyModFlag(UNIT_FIELD_BYTES_1,PLAYER_STATE_SIT,apply);
2397 if(apply && m_periodicTimer <= 0)
2399 m_periodicTimer += m_modifier.periodictime;
2400 float modifier = GetSpellProto()->EffectBasePoints[m_effIndex]+1;
2401 m_modifier.m_amount = uint32(m_target->GetMaxHealth() * modifier/100);
2403 if(m_target->GetHealth() < m_target->GetMaxHealth())
2404 m_target->PeriodicAuraLog(m_target, GetSpellProto(), &m_modifier);
2407 m_isPeriodic = apply;
2410 void Aura::HandleAuraModTotalManaPercentRegen(bool apply, bool Real)
2412 if ((GetSpellProto()->AuraInterruptFlags & (1 << 18)) != 0)
2413 m_target->ApplyModFlag(UNIT_FIELD_BYTES_1,PLAYER_STATE_SIT,apply);
2415 if(apply && m_periodicTimer <= 0 && m_target->getPowerType() == POWER_MANA)
2417 m_periodicTimer += m_modifier.periodictime;
2418 if (m_modifier.m_amount)
2420 float modifier = GetSpellProto()->EffectBasePoints[m_effIndex]+1;
2421 // take percent (m_modifier.m_amount) max mana
2422 m_modifier.m_amount = uint32((m_target->GetMaxPower(POWER_MANA) * modifier)/100);
2425 if(m_target->GetPower(POWER_MANA) < m_target->GetMaxPower(POWER_MANA))
2426 m_target->PeriodicAuraLog(m_target, GetSpellProto(), &m_modifier);
2429 m_isPeriodic = apply;
2432 void Aura::HandleModRegen(bool apply, bool Real) // eating
2434 if ((GetSpellProto()->AuraInterruptFlags & (1 << 18)) != 0)
2435 m_target->ApplyModFlag(UNIT_FIELD_BYTES_1,PLAYER_STATE_SIT,apply);
2437 if(apply && m_periodicTimer <= 0)
2439 m_periodicTimer += 5000;
2440 int32 gain = m_target->ModifyHealth(m_modifier.m_amount);
2441 Unit *caster = GetCaster();
2442 if (caster)
2444 SpellEntry const *spellProto = GetSpellProto();
2445 if (spellProto)
2446 caster->ThreatAssist(m_target, float(gain) * 0.5f, spellProto->School, spellProto);
2450 m_isPeriodic = apply;
2453 void Aura::HandleModPowerRegen(bool apply, bool Real) // drinking
2455 if ((GetSpellProto()->AuraInterruptFlags & (1 << 18)) != 0)
2456 m_target->ApplyModFlag(UNIT_FIELD_BYTES_1,PLAYER_STATE_SIT,apply);
2458 if(apply && m_periodicTimer <= 0)
2460 m_periodicTimer += 5000;
2461 Powers pt = m_target->getPowerType();
2462 // Prevent rage regeneration in combat with rage loss slowdown warrior talant and 0<->1 switching range out combat.
2463 if( !(pt == POWER_RAGE && (m_target->isInCombat() || m_target->GetPower(POWER_RAGE) == 0)) )
2465 int32 gain = m_target->ModifyPower(pt, m_modifier.m_amount);
2466 Unit *caster = GetCaster();
2467 if (caster && pt == POWER_MANA)
2469 SpellEntry const *spellProto = GetSpellProto();
2470 if (spellProto)
2471 caster->ThreatAssist(m_target, float(gain) * 0.5f, spellProto->School, spellProto);
2476 m_isPeriodic = apply;
2479 void Aura::HandleAuraModIncreaseHealth(bool apply, bool Real)
2481 m_target->ApplyMaxHealthMod(m_modifier.m_amount,apply);
2484 void Aura::HandleAuraModIncreaseEnergy(bool apply, bool Real)
2486 Powers powerType = m_target->getPowerType();
2487 if(int32(powerType) != m_modifier.m_miscvalue)
2488 return;
2490 m_target->ApplyMaxPowerMod(powerType, m_modifier.m_amount,apply);
2493 void Aura::HandleAuraModIncreaseEnergyPercent(bool apply, bool Real)
2495 Powers powerType = m_target->getPowerType();
2496 if(int32(powerType) != m_modifier.m_miscvalue)
2497 return;
2499 m_target->ApplyMaxPowerPercentMod(powerType,m_modifier.m_amount,apply);
2500 sLog.outDetail("MaxPowerPercentMod %s %d",(apply ? "+" : "-"), m_modifier.m_amount);
2503 void Aura::HandleAuraModIncreaseHealthPercent(bool apply, bool Real)
2505 m_target->ApplyMaxHealthPercentMod(m_modifier.m_amount,apply);
2508 /********************************/
2509 /*** FIGHT ***/
2510 /********************************/
2512 void Aura::HandleAuraModParryPercent(bool apply, bool Real)
2514 if(m_target->GetTypeId()!=TYPEID_PLAYER)
2515 return;
2517 m_target->ApplyModFloatValue(PLAYER_PARRY_PERCENTAGE,m_modifier.m_amount,apply);
2520 void Aura::HandleAuraModDodgePercent(bool apply, bool Real)
2522 if(m_target->GetTypeId()!=TYPEID_PLAYER)
2523 return;
2525 m_target->ApplyModFloatValue(PLAYER_DODGE_PERCENTAGE,m_modifier.m_amount,apply);
2528 void Aura::HandleAuraModBlockPercent(bool apply, bool Real)
2530 if(m_target->GetTypeId()!=TYPEID_PLAYER)
2531 return;
2533 m_target->ApplyModFloatValue(PLAYER_BLOCK_PERCENTAGE,m_modifier.m_amount,apply);
2536 void Aura::HandleAuraModCritPercent(bool apply, bool Real)
2538 if(m_target->GetTypeId()!=TYPEID_PLAYER)
2539 return;
2541 m_target->ApplyModFloatValue(PLAYER_CRIT_PERCENTAGE,m_modifier.m_amount,apply);
2544 void Aura::HandleModShieldBlock(bool apply, bool Real)
2546 if(m_target->GetTypeId() != TYPEID_PLAYER)
2547 return;
2549 ((Player*)m_target)->ApplyBlockValueMod(m_modifier.m_amount,apply);
2552 void Aura::HandleModHitChance(bool Apply, bool Real)
2554 m_target->m_modHitChance = Apply?m_modifier.m_amount:0;
2557 void Aura::HandleModSpellHitChance(bool Apply, bool Real)
2559 m_target->m_modSpellHitChance = Apply?m_modifier.m_amount:0;
2562 void Aura::HandleModSpellCritChance(bool Apply, bool Real)
2564 m_target->m_baseSpellCritChance += Apply?m_modifier.m_amount:(-m_modifier.m_amount);
2567 void Aura::HandleModSpellCritChanceShool(bool apply, bool Real)
2569 // has no immediate effect when adding / removing
2572 /********************************/
2573 /*** ATTACK SPEED ***/
2574 /********************************/
2576 void Aura::HandleModCastingSpeed(bool apply, bool Real)
2578 m_target->m_modCastSpeedPct += apply ? m_modifier.m_amount : (-m_modifier.m_amount);
2581 void Aura::HandleModAttackSpeed(bool apply, bool Real)
2583 if(!m_target || !m_target->isAlive() )
2584 return;
2586 m_target->ApplyAttackTimePercentMod(BASE_ATTACK,m_modifier.m_amount,apply);
2589 void Aura::HandleHaste(bool apply, bool Real)
2592 if(m_modifier.m_amount >= 0)
2594 // v*(1+percent/100)
2595 m_target->ApplyAttackTimePercentMod(BASE_ATTACK, m_modifier.m_amount,apply);
2596 m_target->ApplyAttackTimePercentMod(OFF_ATTACK, m_modifier.m_amount,apply);
2598 if(m_target->GetTypeId()==TYPEID_PLAYER)
2599 ((Player*)m_target)->_ApplyAmmoBonuses(false);
2601 m_target->ApplyAttackTimePercentMod(RANGED_ATTACK,m_modifier.m_amount,apply);
2603 if(m_target->GetTypeId()==TYPEID_PLAYER)
2604 ((Player*)m_target)->_ApplyAmmoBonuses(true);
2606 else
2608 // v/(1+abs(percent)/100)
2609 m_target->ApplyAttackTimePercentMod(BASE_ATTACK, -m_modifier.m_amount,!apply);
2610 m_target->ApplyAttackTimePercentMod(OFF_ATTACK, -m_modifier.m_amount,!apply);
2612 if(m_target->GetTypeId()==TYPEID_PLAYER)
2613 ((Player*)m_target)->_ApplyAmmoBonuses(false);
2615 m_target->ApplyAttackTimePercentMod(RANGED_ATTACK,-m_modifier.m_amount,!apply);
2617 if(m_target->GetTypeId()==TYPEID_PLAYER)
2618 ((Player*)m_target)->_ApplyAmmoBonuses(true);
2622 void Aura::HandleAuraModRangedHaste(bool apply, bool Real)
2624 if(m_target->GetTypeId()==TYPEID_PLAYER)
2625 ((Player*)m_target)->_ApplyAmmoBonuses(false);
2627 if(m_modifier.m_amount >= 0)
2628 m_target->ApplyAttackTimePercentMod(RANGED_ATTACK, m_modifier.m_amount, apply);
2629 else
2630 m_target->ApplyAttackTimePercentMod(RANGED_ATTACK, -m_modifier.m_amount, !apply);
2632 if(m_target->GetTypeId()==TYPEID_PLAYER)
2633 ((Player*)m_target)->_ApplyAmmoBonuses(true);
2636 void Aura::HandleRangedAmmoHaste(bool apply, bool Real)
2638 if(m_target->GetTypeId() != TYPEID_PLAYER)
2639 return;
2640 ((Player*)m_target)->_ApplyAmmoBonuses(false);
2641 m_target->ApplyAttackTimePercentMod(RANGED_ATTACK,m_modifier.m_amount, apply);
2642 ((Player*)m_target)->_ApplyAmmoBonuses(true);
2645 /********************************/
2646 /*** ATTACK POWER ***/
2647 /********************************/
2649 void Aura::HandleAuraModAttackPower(bool apply, bool Real)
2651 m_target->ApplyModUInt32Value(UNIT_FIELD_ATTACK_POWER_MODS, m_modifier.m_amount, apply);
2654 void Aura::HandleAuraModRangedAttackPower(bool apply, bool Real)
2656 m_target->ApplyModUInt32Value(UNIT_FIELD_RANGED_ATTACK_POWER_MODS,m_modifier.m_amount,apply);
2659 /********************************/
2660 /*** DAMAGE BONUS ***/
2661 /********************************/
2663 void Aura::HandleModDamagePCTTaken(bool apply, bool Real)
2665 m_target->m_modDamagePCT = apply ? m_modifier.m_amount : 0;
2668 void Aura::HandleModPCTRegen(bool apply, bool Real)
2670 // has no immediate effect when adding / removing
2673 void Aura::HandleModCreatureAttackPower(bool apply, bool Real)
2675 // has no immediate effect when adding / removing
2678 void Aura::HandleModDamageDoneCreature(bool apply, bool Real)
2680 // has no immediate effect when adding / removing
2683 void Aura::HandleModDamageDone(bool apply, bool Real)
2685 // physical damage modifier is applied to damage fields
2686 if(m_modifier.m_miscvalue & (int32)(1<<SPELL_SCHOOL_NORMAL))
2688 m_target->ApplyModFloatValue(UNIT_FIELD_MINDAMAGE,m_modifier.m_amount,apply);
2689 m_target->ApplyModFloatValue(UNIT_FIELD_MAXDAMAGE,m_modifier.m_amount,apply);
2690 // TODO: add ranged support and maybe offhand ?
2691 // not completely sure how this should work
2692 if(m_target->GetTypeId() == TYPEID_PLAYER)
2694 if(m_modifier.m_miscvalue2)
2695 m_target->ApplyModFloatValue(PLAYER_FIELD_MOD_DAMAGE_DONE_NEG,m_modifier.m_amount,apply);
2696 else
2697 m_target->ApplyModFloatValue(PLAYER_FIELD_MOD_DAMAGE_DONE_POS,m_modifier.m_amount,apply);
2702 void Aura::HandleModDamageTaken(bool apply, bool Real)
2704 // has no immediate effect when adding / removing
2707 void Aura::HandleModDamagePercentDone(bool apply, bool Real)
2709 sLog.outDebug("AURA MOD DAMAGE type:%u type2:%u", m_modifier.m_miscvalue, m_modifier.m_miscvalue2);
2711 // FIX ME: This is wrong code.
2712 // It not work with 20218 18791 spells
2714 // m_modifier.m_miscvalue is bitmask of spell schools
2715 // 1 ( 0-bit ) - normal school damage
2716 // 126 - full bitmask all magic damages
2717 // 127 - full bitmask any damages
2719 // mods must be applied base at equiped weapon class and subclass comparison
2720 // with spell->EquippedItemClass and EquippedItemSubClassMask and EquippedItemInventoryTypeMask
2721 // m_modifier.m_miscvalue comparison with item generated damage types
2722 if (!m_target)
2723 return;
2725 if((m_modifier.m_miscvalue & 1) != 0)
2727 if (GetSpellProto()->EquippedItemClass == -1 || m_target->GetTypeId() != TYPEID_PLAYER)
2729 m_target->ApplyPercentModFloatValue(UNIT_FIELD_MINRANGEDDAMAGE, m_modifier.m_amount, apply );
2730 m_target->ApplyPercentModFloatValue(UNIT_FIELD_MAXRANGEDDAMAGE, m_modifier.m_amount, apply );
2731 m_target->ApplyPercentModFloatValue(UNIT_FIELD_MINOFFHANDDAMAGE, m_modifier.m_amount, apply );
2732 m_target->ApplyPercentModFloatValue(UNIT_FIELD_MAXOFFHANDDAMAGE, m_modifier.m_amount, apply );
2733 m_target->ApplyPercentModFloatValue(UNIT_FIELD_MINDAMAGE, m_modifier.m_amount, apply );
2734 m_target->ApplyPercentModFloatValue(UNIT_FIELD_MAXDAMAGE, m_modifier.m_amount, apply );
2736 else
2738 Item* pItem = ((Player*)m_target)->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_MAINHAND);
2739 if (pItem)
2741 if (pItem->IsFitToSpellRequirements(GetSpellProto()))
2743 m_target->ApplyPercentModFloatValue(UNIT_FIELD_MINDAMAGE, m_modifier.m_amount, apply );
2744 m_target->ApplyPercentModFloatValue(UNIT_FIELD_MAXDAMAGE, m_modifier.m_amount, apply );
2747 pItem = ((Player*)m_target)->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_OFFHAND);
2748 if (pItem)
2750 if (pItem->IsFitToSpellRequirements(GetSpellProto()))
2752 m_target->ApplyPercentModFloatValue(UNIT_FIELD_MINOFFHANDDAMAGE, m_modifier.m_amount, apply );
2753 m_target->ApplyPercentModFloatValue(UNIT_FIELD_MAXOFFHANDDAMAGE, m_modifier.m_amount, apply );
2756 pItem = ((Player*)m_target)->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_RANGED);
2757 if (pItem)
2759 if (pItem->IsFitToSpellRequirements(GetSpellProto()))
2761 m_target->ApplyPercentModFloatValue(UNIT_FIELD_MINRANGEDDAMAGE, m_modifier.m_amount, apply );
2762 m_target->ApplyPercentModFloatValue(UNIT_FIELD_MAXRANGEDDAMAGE, m_modifier.m_amount, apply );
2768 // Magic damage percent modifiers implemented in Unit::SpellDamageBonus
2771 /********************************/
2772 /*** POWER COST ***/
2773 /********************************/
2775 void Aura::HandleModPowerCost(bool apply, bool Real)
2777 m_target->ApplyModUInt32Value(UNIT_FIELD_POWER_COST_MODIFIER, m_modifier.m_amount, apply);
2780 void Aura::HandleModPowerCostSchool(bool apply, bool Real)
2782 // has no immediate effect when adding / removing
2785 /*********************************************************/
2786 /*** OTHERS ***/
2787 /*********************************************************/
2789 void Aura::HandleModReputationGain(bool apply, bool Real)
2791 // has no immediate effect when adding / removing
2794 void Aura::SendCoolDownEvent()
2796 Unit* caster = GetCaster();
2797 if(caster)
2799 WorldPacket data(SMSG_COOLDOWN_EVENT, (4+8+4));
2800 data << uint32(m_spellId) << m_caster_guid;
2801 data << uint32(0); //CoolDown Time ?
2802 caster->SendMessageToSet(&data,true);
2806 // FIX-ME!!
2807 void HandleTriggerSpellEvent(void *obj)
2809 Aura *Aur = ((Aura*)obj);
2810 if(!Aur)
2811 return;
2812 SpellEntry const *spellInfo = sSpellStore.LookupEntry(Aur->GetSpellProto()->EffectTriggerSpell[Aur->GetEffIndex()]);
2814 if(!spellInfo)
2816 sLog.outError("WORLD: unknown spell id %i\n", Aur->GetSpellProto()->EffectTriggerSpell[Aur->GetEffIndex()]);
2817 return;
2820 Spell spell(Aur->GetCaster(), spellInfo, true, Aur);
2821 SpellCastTargets targets;
2822 targets.setUnitTarget(Aur->GetTarget());
2823 //WorldPacket dump;
2824 //dump.Initialize(0);
2825 //dump << uint16(2) << GetUInt32Value(UNIT_FIELD_CHANNEL_OBJECT) << GetUInt32Value(UNIT_FIELD_CHANNEL_OBJECT+1);
2826 //targets.read(&dump,this);
2827 spell.prepare(&targets);
2829 /*else if(m_spellProto->EffectApplyAuraName[i] == 23)
2831 unitTarget->tmpAura->SetPeriodicTriggerSpell(m_spellProto->EffectTriggerSpell[i],m_spellProto->EffectAmplitude[i]);
2835 void HandleDOTEvent(void *obj)
2837 Aura *Aur = ((Aura*)obj);
2838 //Aur->GetCaster()->AddPeriodicAura(Aur);
2839 if(Unit* caster = Aur->GetCaster())
2840 caster->PeriodicAuraLog(Aur->GetTarget(), Aur->GetSpellProto(), Aur->GetModifier());
2843 void HandleHealEvent(void *obj)
2845 Aura *Aur = ((Aura*)obj);
2846 if(Unit* caster = Aur->GetCaster())
2847 Aur->GetTarget()->PeriodicAuraLog(caster, Aur->GetSpellProto(), Aur->GetModifier());
2850 void Aura::HandleShapeshiftBoosts(bool apply)
2852 if(!m_target)
2853 return;
2855 uint32 spellId = 0;
2856 uint32 spellId2 = 0;
2858 switch(GetModifier()->m_miscvalue)
2860 case FORM_CAT:
2861 spellId = 3025;
2862 break;
2863 case FORM_TREE:
2864 spellId = 3122;
2865 break;
2866 case FORM_TRAVEL:
2867 spellId = 5419;
2868 break;
2869 case FORM_AQUA:
2870 spellId = 5421;
2871 break;
2872 case FORM_BEAR:
2873 spellId = 1178;
2874 break;
2875 case FORM_DIREBEAR:
2876 spellId = 9635;
2877 break;
2878 case FORM_CREATUREBEAR:
2879 spellId = 2882;
2880 break;
2881 case FORM_BATTLESTANCE:
2882 spellId = 21156;
2883 break;
2884 case FORM_DEFENSIVESTANCE:
2885 spellId = 7376;
2886 break;
2887 case FORM_BERSERKERSTANCE:
2888 spellId = 7381;
2889 break;
2890 case FORM_MOONKIN:
2891 spellId = 24905;
2892 // aura from effect trigger spell
2893 spellId2 = 24907;
2894 break;
2895 case FORM_GHOSTWOLF:
2896 case FORM_AMBIENT:
2897 case FORM_GHOUL:
2898 case FORM_SHADOW:
2899 case FORM_STEALTH:
2900 spellId = 0;
2901 break;
2904 uint32 form = GetModifier()->m_miscvalue-1;
2906 if(apply)
2908 if(m_target->m_ShapeShiftForm)
2910 m_target->RemoveAurasDueToSpell(m_target->m_ShapeShiftForm);
2913 if (spellId) m_target->CastSpell(m_target, spellId, true);
2914 if (spellId2) m_target->CastSpell(m_target, spellId2, true);
2916 if(m_target->GetTypeId() == TYPEID_PLAYER)
2918 const PlayerSpellMap& sp_list = ((Player *)m_target)->GetSpellMap();
2919 for (PlayerSpellMap::const_iterator itr = sp_list.begin(); itr != sp_list.end(); ++itr)
2921 if(itr->second->state == PLAYERSPELL_REMOVED) continue;
2922 SpellEntry const *spellInfo = sSpellStore.LookupEntry(itr->first);
2923 if (!spellInfo || !IsPassiveSpell(itr->first)) continue;
2924 if (spellInfo->Stances & (1<<form))
2925 m_target->CastSpell(m_target, itr->first, true);
2929 else
2931 m_target->RemoveAurasDueToSpell(spellId);
2932 m_target->RemoveAurasDueToSpell(spellId2);
2934 Unit::AuraMap& tAuras = m_target->GetAuras();
2935 for (Unit::AuraMap::iterator itr = tAuras.begin(); itr != tAuras.end();)
2937 if ((*itr).second->GetSpellProto()->Stances & uint32(1<<form))
2938 m_target->RemoveAura(itr);
2939 else
2940 ++itr;
2944 double healthPercentage = (double)m_target->GetHealth() / (double)m_target->GetMaxHealth();
2945 m_target->SetHealth(uint32(ceil((double)m_target->GetMaxHealth() * healthPercentage)));
2948 void Aura::HandleAuraEmpathy(bool apply, bool Real)
2950 if(m_target->GetTypeId()!=TYPEID_UNIT)
2951 return;
2953 CreatureInfo const * ci = objmgr.GetCreatureTemplate(m_target->GetEntry());
2954 if(ci && ci->type == CREATURE_TYPE_BEAST)
2956 m_target->ApplyModUInt32Value(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_SPECIALINFO, apply);