[2390] Applied MaNGOS coding style (see trunk/bcpp.cfg).
[mangos-git.git] / src / game / SpellAuras.cpp
blobca63e7a1cfcccbe114155fb4826d20c41f62beb8
1 /*
2 * Copyright (C) 2005,2006 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"
45 pAuraHandler AuraHandler[TOTAL_AURAS]=
47 &Aura::HandleNULL, //SPELL_AURA_NONE
48 &Aura::HandleBindSight, //SPELL_AURA_BIND_SIGHT
49 &Aura::HandleModPossess, //SPELL_AURA_MOD_POSSESS = 2,
50 &Aura::HandlePeriodicDamage, //SPELL_AURA_PERIODIC_DAMAGE = 3,
51 &Aura::HandleAuraDummy, //SPELL_AURA_DUMMY //missing 4
52 &Aura::HandleModConfuse, //SPELL_AURA_MOD_CONFUSE = 5,
53 &Aura::HandleModCharm, //SPELL_AURA_MOD_CHARM = 6,
54 &Aura::HandleModFear, //SPELL_AURA_MOD_FEAR = 7,
55 &Aura::HandlePeriodicHeal, //SPELL_AURA_PERIODIC_HEAL = 8,
56 &Aura::HandleModAttackSpeed, //SPELL_AURA_MOD_ATTACKSPEED = 9,
57 &Aura::HandleModThreat, //SPELL_AURA_MOD_THREAT = 10,
58 &Aura::HandleNULL, //SPELL_AURA_MOD_TAUNT = 11,
59 &Aura::HandleAuraModStun, //SPELL_AURA_MOD_STUN = 12,
60 &Aura::HandleModDamageDone, //SPELL_AURA_MOD_DAMAGE_DONE = 13,
61 &Aura::HandleModDamageTaken, //SPELL_AURA_MOD_DAMAGE_TAKEN = 14,
62 &Aura::HandleAuraDamageShield, //SPELL_AURA_DAMAGE_SHIELD = 15,
63 &Aura::HandleModStealth, //SPELL_AURA_MOD_STEALTH = 16,
64 &Aura::HandleModDetect, //SPELL_AURA_MOD_DETECT = 17,
65 &Aura::HandleInvisibility, //SPELL_AURA_MOD_INVISIBILITY = 18,
66 &Aura::HandleInvisibilityDetect, //SPELL_AURA_MOD_INVISIBILITY_DETECTION = 19,
67 &Aura::HandleNULL, //missing 20,
68 &Aura::HandleNULL, //missing 21
69 &Aura::HandleAuraModResistance, //SPELL_AURA_MOD_RESISTANCE = 22,
70 &Aura::HandlePeriodicTriggerSpell, //SPELL_AURA_PERIODIC_TRIGGER_SPELL = 23,
71 &Aura::HandlePeriodicEnergize, //SPELL_AURA_PERIODIC_ENERGIZE = 24,
72 &Aura::HandleNULL, //SPELL_AURA_MOD_PACIFY = 25,
73 &Aura::HandleAuraModRoot, //SPELL_AURA_MOD_ROOT = 26,
74 &Aura::HandleAuraModSilence, //SPELL_AURA_MOD_SILENCE = 27,
75 &Aura::HandleReflectSpells, //SPELL_AURA_REFLECT_SPELLS = 28,
76 &Aura::HandleAuraModStat, //SPELL_AURA_MOD_STAT = 29,
77 &Aura::HandleAuraModSkill, //SPELL_AURA_MOD_SKILL = 30,
78 &Aura::HandleAuraModIncreaseSpeed, //SPELL_AURA_MOD_INCREASE_SPEED = 31,
79 &Aura::HandleAuraModIncreaseMountedSpeed, //SPELL_AURA_MOD_INCREASE_MOUNTED_SPEED = 32,
80 &Aura::HandleAuraModDecreaseSpeed, //SPELL_AURA_MOD_DECREASE_SPEED = 33,
81 &Aura::HandleAuraModIncreaseHealth, //SPELL_AURA_MOD_INCREASE_HEALTH = 34,
82 &Aura::HandleAuraModIncreaseEnergy, //SPELL_AURA_MOD_INCREASE_ENERGY = 35,
83 &Aura::HandleAuraModShapeshift, //SPELL_AURA_MOD_SHAPESHIFT = 36,
84 &Aura::HandleAuraModEffectImmunity, //SPELL_AURA_EFFECT_IMMUNITY = 37,
85 &Aura::HandleAuraModStateImmunity, //SPELL_AURA_STATE_IMMUNITY = 38,
86 &Aura::HandleAuraModSchoolImmunity, //SPELL_AURA_SCHOOL_IMMUNITY = 39,
87 &Aura::HandleAuraModDmgImmunity, //SPELL_AURA_DAMAGE_IMMUNITY = 40,
88 &Aura::HandleAuraModDispelImmunity, //SPELL_AURA_DISPEL_IMMUNITY = 41,
89 &Aura::HandleAuraProcTriggerSpell, //SPELL_AURA_PROC_TRIGGER_SPELL = 42,
90 &Aura::HandleAuraProcTriggerDamage, //SPELL_AURA_PROC_TRIGGER_DAMAGE = 43,
91 &Aura::HandleAuraTracCreatures, //SPELL_AURA_TRACK_CREATURES = 44,
92 &Aura::HandleAuraTracResources, //SPELL_AURA_TRACK_RESOURCES = 45,
93 &Aura::HandleNULL, //SPELL_AURA_MOD_PARRY_SKILL = 46, obsolete?
94 &Aura::HandleAuraModParryPercent, //SPELL_AURA_MOD_PARRY_PERCENT = 47,
95 &Aura::HandleNULL, //SPELL_AURA_MOD_DODGE_SKILL = 48, obsolete?
96 &Aura::HandleAuraModDodgePercent, //SPELL_AURA_MOD_DODGE_PERCENT = 49,
97 &Aura::HandleNULL, //SPELL_AURA_MOD_BLOCK_SKILL = 50, obsolete?
98 &Aura::HandleAuraModBlockPercent, //SPELL_AURA_MOD_BLOCK_PERCENT = 51,
99 &Aura::HandleAuraModCritPercent, //SPELL_AURA_MOD_CRIT_PERCENT = 52,
100 &Aura::HandlePeriodicLeech, //SPELL_AURA_PERIODIC_LEECH = 53,
101 &Aura::HandleModHitChance, //SPELL_AURA_MOD_HIT_CHANCE = 54,
102 &Aura::HandleModSpellHitChance, //SPELL_AURA_MOD_SPELL_HIT_CHANCE = 55,
103 &Aura::HandleAuraTransform, //SPELL_AURA_TRANSFORM = 56,
104 &Aura::HandleModSpellCritChance, //SPELL_AURA_MOD_SPELL_CRIT_CHANCE = 57,
105 &Aura::HandleAuraModIncreaseSwimSpeed, //SPELL_AURA_MOD_INCREASE_SWIM_SPEED = 58,
106 &Aura::HandleModDamageDoneCreature, //SPELL_AURA_MOD_DAMAGE_DONE_CREATURE = 59,
107 &Aura::HandleNULL, //SPELL_AURA_MOD_PACIFY_SILENCE = 60,
108 &Aura::HandleAuraModScale, //SPELL_AURA_MOD_SCALE = 61,
109 &Aura::HandleNULL, //SPELL_AURA_PERIODIC_HEALTH_FUNNEL = 62,
110 &Aura::HandleNULL, //SPELL_AURA_PERIODIC_MANA_FUNNEL = 63,
111 &Aura::HandlePeriodicManaLeech, //SPELL_AURA_PERIODIC_MANA_LEECH = 64,
112 &Aura::HandleModCastingSpeed, //SPELL_AURA_MOD_CASTING_SPEED = 65,
113 &Aura::HandleNULL, //SPELL_AURA_FEIGN_DEATH = 66,
114 &Aura::HandleNULL, //SPELL_AURA_MOD_DISARM = 67,
115 &Aura::HandleNULL, //SPELL_AURA_MOD_STALKED = 68,
116 &Aura::HandleAuraSchoolAbsorb, //SPELL_AURA_SCHOOL_ABSORB = 69,
117 &Aura::HandleNULL, //SPELL_AURA_EXTRA_ATTACKS = 70,// Useless
118 &Aura::HandleModSpellCritChanceShool, //SPELL_AURA_MOD_SPELL_CRIT_CHANCE_SCHOOL = 71,
119 &Aura::HandleModPowerCost, //SPELL_AURA_MOD_POWER_COST = 72,
120 &Aura::HandleModPowerCostSchool, //SPELL_AURA_MOD_POWER_COST_SCHOOL = 73,
121 &Aura::HandleReflectSpellsSchool, //SPELL_AURA_REFLECT_SPELLS_SCHOOL = 74,
122 &Aura::HandleNULL, //SPELL_AURA_MOD_LANGUAGE = 75,
123 &Aura::HandleFarSight, //SPELL_AURA_FAR_SIGHT = 76,
124 &Aura::HandleModMechanicImmunity, //SPELL_AURA_MECHANIC_IMMUNITY = 77,
125 &Aura::HandleAuraMounted, //SPELL_AURA_MOUNTED = 78,
126 &Aura::HandleModDamagePercentDone, //SPELL_AURA_MOD_DAMAGE_PERCENT_DONE = 79,
127 &Aura::HandleModPercentStat, //SPELL_AURA_MOD_PERCENT_STAT = 80,
128 &Aura::HandleNULL, //SPELL_AURA_SPLIT_DAMAGE = 81,
129 &Aura::HandleWaterBreathing, //SPELL_AURA_WATER_BREATHING = 82,
130 &Aura::HandleModBaseResistance, //SPELL_AURA_MOD_BASE_RESISTANCE = 83,
131 &Aura::HandleModRegen, //SPELL_AURA_MOD_REGEN = 84,
132 &Aura::HandleModPowerRegen, //SPELL_AURA_MOD_POWER_REGEN = 85,
133 &Aura::HandleChannelDeathItem, //SPELL_AURA_CHANNEL_DEATH_ITEM = 86,
134 &Aura::HandleModDamagePCTTaken, //SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN = 87,
135 &Aura::HandleModPCTRegen, //SPELL_AURA_MOD_HEALTH_REGEN_PERCENT = 88,
136 &Aura::HandlePeriodicDamagePCT, //SPELL_AURA_PERIODIC_DAMAGE_PERCENT = 89,
137 &Aura::HandleNULL, //SPELL_AURA_MOD_RESIST_CHANCE = 90,// Useless
138 &Aura::HandleNULL, //SPELL_AURA_MOD_DETECT_RANGE = 91,
139 &Aura::HandleNULL, //SPELL_AURA_PREVENTS_FLEEING = 92,
140 &Aura::HandleNULL, //SPELL_AURA_MOD_UNATTACKABLE = 93,
141 &Aura::HandleNULL, //SPELL_AURA_INTERRUPT_REGEN = 94,
142 &Aura::HandleNULL, //SPELL_AURA_GHOST = 95,
143 &Aura::HandleNULL, //SPELL_AURA_SPELL_MAGNET = 96,
144 &Aura::HandleAuraManaShield, //SPELL_AURA_MANA_SHIELD = 97,
145 &Aura::HandleAuraModSkill, //SPELL_AURA_MOD_SKILL_TALENT = 98,
146 &Aura::HandleAuraModAttackPower, //SPELL_AURA_MOD_ATTACK_POWER = 99,
147 &Aura::HandleNULL, //SPELL_AURA_AURAS_VISIBLE = 100,
148 &Aura::HandleModResistancePercent, //SPELL_AURA_MOD_RESISTANCE_PCT = 101,
149 &Aura::HandleModCreatureAttackPower, //SPELL_AURA_MOD_CREATURE_ATTACK_POWER = 102,
150 &Aura::HandleNULL, //SPELL_AURA_MOD_TOTAL_THREAT = 103,
151 &Aura::HandleAuraWaterWalk, //SPELL_AURA_WATER_WALK = 104,
152 &Aura::HandleAuraFeatherFall, //SPELL_AURA_FEATHER_FALL = 105,
153 &Aura::HandleNULL, //SPELL_AURA_HOVER = 106,
154 &Aura::HandleAddModifier, //SPELL_AURA_ADD_FLAT_MODIFIER = 107,
155 &Aura::HandleAddModifier, //SPELL_AURA_ADD_PCT_MODIFIER = 108,
156 &Aura::HandleNULL, //SPELL_AURA_ADD_TARGET_TRIGGER = 109,
157 &Aura::HandleNULL, //SPELL_AURA_MOD_POWER_REGEN_PERCENT = 110,
158 &Aura::HandleNULL, //SPELL_AURA_ADD_CASTER_HIT_TRIGGER = 111,
159 &Aura::HandleNULL, //SPELL_AURA_OVERRIDE_CLASS_SCRIPTS = 112,
160 &Aura::HandleNULL, //SPELL_AURA_MOD_RANGED_DAMAGE_TAKEN = 113,
161 &Aura::HandleNULL, //SPELL_AURA_MOD_RANGED_DAMAGE_TAKEN_PCT = 114,
162 &Aura::HandleNULL, //SPELL_AURA_MOD_HEALING = 115,
163 &Aura::HandleNULL, //SPELL_AURA_IGNORE_REGEN_INTERRUPT = 116,
164 &Aura::HandleNULL, //SPELL_AURA_MOD_MECHANIC_RESISTANCE = 117,
165 &Aura::HandleNULL, //SPELL_AURA_MOD_HEALING_PCT = 118,
166 &Aura::HandleNULL, //SPELL_AURA_SHARE_PET_TRACKING = 119,
167 &Aura::HandleNULL, //SPELL_AURA_UNTRACKABLE = 120,
168 &Aura::HandleNULL, //SPELL_AURA_EMPATHY = 121,
169 &Aura::HandleNULL, //SPELL_AURA_MOD_OFFHAND_DAMAGE_PCT = 122,
170 &Aura::HandleNULL, //SPELL_AURA_MOD_POWER_COST_PCT = 123,
171 &Aura::HandleAuraModRangedAttackPower, //SPELL_AURA_MOD_RANGED_ATTACK_POWER = 124,
172 &Aura::HandleNULL, //SPELL_AURA_MOD_MELEE_DAMAGE_TAKEN = 125,
173 &Aura::HandleNULL, //SPELL_AURA_MOD_MELEE_DAMAGE_TAKEN_PCT = 126,
174 &Aura::HandleNULL, //SPELL_AURA_RANGED_ATTACK_POWER_ATTACKER_BONUS = 127,
175 &Aura::HandleNULL, //SPELL_AURA_MOD_POSSESS_PET = 128,
176 &Aura::HandleAuraModIncreaseSpeedAlways, //SPELL_AURA_MOD_INCREASE_SPEED_ALWAYS = 129,
177 &Aura::HandleNULL, //SPELL_AURA_MOD_MOUNTED_SPEED_ALWAYS = 130,
178 &Aura::HandleNULL, //SPELL_AURA_MOD_CREATURE_RANGED_ATTACK_POWER = 131,
179 &Aura::HandleAuraModIncreaseEnergyPercent, //SPELL_AURA_MOD_INCREASE_ENERGY_PERCENT = 132,
180 &Aura::HandleAuraModIncreaseHealthPercent, //SPELL_AURA_MOD_INCREASE_HEALTH_PERCENT = 133,
181 &Aura::HandleNULL, //SPELL_AURA_MOD_MANA_REGEN_INTERRUPT = 134,
182 &Aura::HandleNULL, //SPELL_AURA_MOD_HEALING_DONE = 135,
183 &Aura::HandleNULL, //SPELL_AURA_MOD_HEALING_DONE_PERCENT = 136,
184 &Aura::HandleModTotalPercentStat, //SPELL_AURA_MOD_TOTAL_STAT_PERCENTAGE = 137,
185 &Aura::HandleHaste, //SPELL_AURA_MOD_HASTE = 138,
186 &Aura::HandleForceReaction, //SPELL_AURA_FORCE_REACTION = 139,
187 &Aura::HandleNULL, //SPELL_AURA_MOD_RANGED_HASTE = 140,
188 &Aura::HandleRangedAmmoHaste, //SPELL_AURA_MOD_RANGED_AMMO_HASTE = 141,
189 &Aura::HandleAuraModBaseResistancePCT, //SPELL_AURA_MOD_BASE_RESISTANCE_PCT = 142,
190 &Aura::HandleAuraModResistanceExclusive, //SPELL_AURA_MOD_RESISTANCE_EXCLUSIVE = 143,
191 &Aura::HandleAuraSafeFall, //SPELL_AURA_SAFE_FALL = 144,
192 &Aura::HandleNULL, //SPELL_AURA_CHARISMA = 145,
193 &Aura::HandleNULL, //SPELL_AURA_PERSUADED = 146,
194 &Aura::HandleNULL, //SPELL_AURA_ADD_CREATURE_IMMUNITY = 147,
195 &Aura::HandleNULL, //SPELL_AURA_RETAIN_COMBO_POINTS = 148,
196 &Aura::HandleNULL, //SPELL_AURA_RESIST_PUSHBACK = 149 ,// Resist Pushback
197 &Aura::HandleModShieldBlock, //SPELL_AURA_MOD_SHIELD_BLOCK = 150 ,// Mod Shield Block %
198 &Aura::HandleNULL, //SPELL_AURA_TRACK_STEALTHED = 151 ,// Track Stealthed
199 &Aura::HandleNULL, //SPELL_AURA_MOD_DETECTED_RANGE = 152 ,// Mod Detected Range
200 &Aura::HandleNULL, //SPELL_AURA_SPLIT_DAMAGE_FLAT = 153 ,// Split Damage Flat
201 &Aura::HandleNULL, //SPELL_AURA_MOD_STEALTH_LEVEL = 154 ,// Stealth Level Modifier
202 &Aura::HandleNULL, //SPELL_AURA_MOD_WATER_BREATHING = 155 ,// Mod Water Breathing
203 &Aura::HandleModReputationGain, //SPELL_AURA_MOD_REPUTATION_GAIN = 156 ,// Mod Reputation Gain
204 &Aura::HandleNULL //SPELL_AURA_PET_DAMAGE_MULTI = 157 ,// Mod Pet Damage
207 // add/remove SPELL_AURA_MOD_SHAPESHIFT (36) linked auras
208 static void HandleShapeshiftBoosts(bool apply, Aura* aura);
210 Aura::Aura(SpellEntry* spellproto, uint32 eff, Unit *target, Unit *caster, Item* castItem) :
211 m_spellId(spellproto->Id), m_effIndex(eff), m_caster_guid(0),m_castItem(castItem),
212 m_target(target), m_timeCla(1000),m_auraSlot(0),m_positive(false), m_permanent(false),
213 m_isPeriodic(false), m_isTrigger(false), m_periodicTimer(0), m_PeriodicEventId(0),
214 m_removeOnDeath(false), m_procCharges(0), m_absorbDmg(0), m_isPersistent(false)
216 assert(target);
217 m_duration = GetDuration(spellproto);
218 if(m_duration == -1)
219 m_permanent = true;
220 m_isPassive = IsPassiveSpell(m_spellId);
221 m_positive = IsPositiveEffect(m_spellId, m_effIndex);
223 sLog.outDebug("Aura: construct Spellid : %u, Aura : %u Duration : %d Target : %d.", spellproto->Id, spellproto->EffectApplyAuraName[eff], m_duration, spellproto->EffectImplicitTargetA[eff]);
225 uint32 type = 0;
226 if(!m_positive)
227 type = 1;
228 uint32 damage;
229 if(!caster)
231 m_caster_guid = target->GetGUID();
232 damage = spellproto->EffectBasePoints[eff]+1; // stored value-1
234 else
236 m_caster_guid = caster->GetGUID();
237 damage = CalculateDamage();
240 m_effIndex = eff;
241 SetModifier(spellproto->EffectApplyAuraName[eff], damage, spellproto->EffectAmplitude[eff], spellproto->EffectMiscValue[eff], type);
244 Aura::~Aura()
248 AreaAura::AreaAura(SpellEntry* spellproto, uint32 eff, Unit *target,
249 Unit *caster, Item* castItem) : Aura(spellproto, eff, target, caster, castItem)
251 m_isAreaAura = true;
254 AreaAura::~AreaAura()
258 PersistentAreaAura::PersistentAreaAura(SpellEntry* spellproto, uint32 eff, Unit *target,
259 Unit *caster, Item* castItem) : Aura(spellproto, eff, target, caster, castItem)
261 m_isPersistent = true;
264 PersistentAreaAura::~PersistentAreaAura()
268 Unit* Aura::GetCaster() const
270 if(m_caster_guid==m_target->GetGUID())
271 return m_target;
273 return ObjectAccessor::Instance().GetUnit(*m_target,m_caster_guid);
276 uint32 Aura::CalculateDamage()
278 SpellEntry* spellproto = GetSpellProto();
279 uint32 value = 0;
280 uint32 level = 0;
281 if(!m_target)
282 return 0;
283 Unit* caster = GetCaster();
284 if(!caster)
285 caster = m_target;
286 /*level= caster->getLevel();
287 if( level > spellproto->maxLevel && spellproto->maxLevel > 0)
288 level = spellproto->maxLevel;*/
290 float basePointsPerLevel = spellproto->EffectRealPointsPerLevel[m_effIndex];
291 float randomPointsPerLevel = spellproto->EffectDicePerLevel[m_effIndex];
292 uint32 basePoints = uint32(spellproto->EffectBasePoints[m_effIndex] + level * basePointsPerLevel);
293 uint32 randomPoints = uint32(spellproto->EffectDieSides[m_effIndex] + level * randomPointsPerLevel);
294 float comboDamage = spellproto->EffectPointsPerComboPoint[m_effIndex];
295 uint8 comboPoints=0;
296 if(caster->GetTypeId() == TYPEID_PLAYER)
297 comboPoints = (uint8)((caster->GetUInt32Value(PLAYER_FIELD_BYTES) & 0xFF00) >> 8);
299 value += spellproto->EffectBaseDice[m_effIndex];
300 if(randomPoints <= 1)
301 value = basePoints+1;
302 else
303 value = basePoints+rand()%randomPoints;
305 if(comboDamage > 0)
307 value += (uint32)(comboDamage * comboPoints);
308 if(caster->GetTypeId() == TYPEID_PLAYER)
309 caster->SetUInt32Value(PLAYER_FIELD_BYTES,((caster->GetUInt32Value(PLAYER_FIELD_BYTES) & ~(0xFF << 8)) | (0x00 << 8)));
312 return value;
315 void Aura::SetModifier(uint8 t, int32 a, uint32 pt, int32 miscValue, uint32 miscValue2)
317 m_modifier.m_auraname = t;
318 m_modifier.m_amount = a;
319 m_modifier.m_miscvalue = miscValue;
320 m_modifier.m_miscvalue2 = miscValue2;
321 m_modifier.periodictime = pt;
323 Unit* caster = GetCaster();
324 if (caster && caster->GetTypeId() == TYPEID_PLAYER)
325 ((Player *)caster)->ApplySpellMod(m_spellId,SPELLMOD_ALL_EFFECTS, m_modifier.m_amount);
328 void Aura::Update(uint32 diff)
330 if (m_duration > 0)
332 m_duration -= diff;
333 if (m_duration < 0)
334 m_duration = 0;
335 m_timeCla -= diff;
337 Unit* caster = GetCaster();
338 if(caster && m_timeCla <= 0)
340 Powers powertype = caster->getPowerType();
341 uint32 curpower = caster->GetPower(powertype);
342 uint32 manaPerSecond = GetSpellProto()->manaPerSecond;
343 uint32 manaPerSecondPerLevel = uint32(GetSpellProto()->manaPerSecondPerLevel*caster->getLevel());
344 m_timeCla = 1000;
345 if(manaPerSecond > curpower)
346 caster->SetPower(powertype,0);
347 else
348 caster->SetPower(powertype,curpower-manaPerSecond);
349 if(manaPerSecondPerLevel > curpower)
350 caster->SetPower(powertype,0);
351 else
352 caster->SetPower(powertype,curpower-manaPerSecondPerLevel);
354 if(caster && m_target->isAlive() && m_target->HasFlag(UNIT_FIELD_FLAGS,(UNIT_STAT_FLEEING<<16)))
356 float x,y,z,angle,speed,pos_x,pos_y,pos_z;
357 angle = m_target->GetAngle( caster->GetPositionX(), caster->GetPositionY() );
358 // If the m_target is player,and if the speed is too slow,change it :P
359 if(m_target->GetTypeId() != TYPEID_PLAYER)
360 speed = m_target->GetSpeed(MOVE_RUN);
361 else speed = m_target->GetSpeed();
362 pos_x = m_target->GetPositionX();
363 pos_y = m_target->GetPositionY();
364 uint32 mapid = m_target->GetMapId();
365 pos_z = MapManager::Instance().GetMap(mapid)->GetHeight(pos_x,pos_y);
366 // Control the max Distance; 20 for temp.
367 if(m_target->GetDistanceSq(caster) <= 20*20)
369 if( m_target->GetPositionX() < caster->GetPositionX() || m_target->GetPositionY() > caster->GetPositionY() )
370 x = m_target->GetPositionX() + speed*diff * sin(angle)/1000;
371 else
372 x = m_target->GetPositionX() - speed*diff * sin(angle)/1000;
373 y = m_target->GetPositionY() - speed*diff * cos(angle)/1000;
374 mapid = m_target->GetMapId();
375 z = MapManager::Instance().GetMap(mapid)->GetHeight(x,y);
376 // Control the target to not climb or drop when dz > |x|,x = 1.3 for temp.
377 // fixed me if it needs checking when the position will be in water?
378 if(z<=pos_z+1.3 && z>=pos_z-1.3)
380 m_target->SendMonsterMove(x,y,z,false,true,diff);
381 if(m_target->GetTypeId() != TYPEID_PLAYER)
382 m_target->Relocate(x,y,z,m_target->GetOrientation());
388 if(m_isPeriodic && (m_duration >= 0 || m_isPassive))
390 m_periodicTimer -= diff;
391 if(m_periodicTimer < 0)
393 if (m_modifier.m_auraname == SPELL_AURA_MOD_REGEN || m_modifier.m_auraname == SPELL_AURA_MOD_POWER_REGEN)
395 ApplyModifier(true);
396 return;
398 // update before applying (aura can be removed in TriggerSpell or PeriodicAuraLog calls)
399 m_periodicTimer += m_modifier.periodictime;
401 if(m_isTrigger)
403 TriggerSpell();
405 else
407 if(Unit* caster = GetCaster())
408 caster->PeriodicAuraLog(m_target, GetSpellProto(), &m_modifier);
409 else
410 m_target->PeriodicAuraLog(m_target, GetSpellProto(), &m_modifier);
416 void AreaAura::Update(uint32 diff)
418 // update for the caster of the aura
419 if(m_caster_guid == m_target->GetGUID())
421 Unit* caster = m_target;
423 uint64 leaderGuid = 0;
424 if (caster->GetTypeId() == TYPEID_PLAYER)
425 leaderGuid = ((Player*)caster)->GetGroupLeader();
426 else if(((Creature*)caster)->isTotem())
428 Unit *owner = ((Totem*)caster)->GetOwner();
429 if (owner && owner->GetTypeId() == TYPEID_PLAYER)
430 leaderGuid = ((Player*)owner)->GetGroupLeader();
433 Group* pGroup = objmgr.GetGroupByLeader(leaderGuid);
434 float radius = GetRadius(sSpellRadius.LookupEntry(GetSpellProto()->EffectRadiusIndex[m_effIndex]));
435 if(pGroup)
437 for(uint32 p=0;p<pGroup->GetMembersCount();p++)
439 Unit* Target = ObjectAccessor::Instance().FindPlayer(pGroup->GetMemberGUID(p));
440 if(!Target || Target->GetGUID() == m_caster_guid || !Target->isAlive())
441 continue;
442 Aura *t_aura = Target->GetAura(m_spellId, m_effIndex);
444 if(caster->GetDistanceSq(Target) > radius * radius )
446 // remove auras of the same caster from out of range players
447 if (t_aura)
448 if (t_aura->GetCasterGUID() == m_caster_guid)
449 Target->RemoveAura(m_spellId, m_effIndex);
451 else
453 // apply aura to players in range that dont have it yet
454 if (!t_aura)
456 Aura *aur = new Aura(GetSpellProto(), m_effIndex, Target, caster);
457 Target->AddAura(aur);
462 else if (caster->GetTypeId() != TYPEID_PLAYER && ((Creature*)caster)->isTotem())
464 // add / remove auras from the totem's owner
465 Unit *owner = ((Totem*)caster)->GetOwner();
466 if (owner)
468 Aura *o_aura = owner->GetAura(m_spellId, m_effIndex);
469 if(caster->GetDistanceSq(owner) > radius * radius )
471 if (o_aura)
472 if (o_aura->GetCasterGUID() == m_caster_guid)
473 owner->RemoveAura(m_spellId, m_effIndex);
475 else
477 if (!o_aura)
479 Aura *aur = new Aura(GetSpellProto(), m_effIndex, owner, caster);
480 owner->AddAura(aur);
487 Aura::Update(diff);
490 void PersistentAreaAura::Update(uint32 diff)
492 bool remove = false;
494 // remove the aura if its caster or the dynamic object causing it was removed
495 // or if the target moves too far from the dynamic object
496 Unit *caster = GetCaster();
497 if (caster)
499 DynamicObject *dynObj = caster->GetDynObject(GetId(), GetEffIndex());
500 if (dynObj)
502 if (m_target->GetDistanceSq(dynObj) > dynObj->GetRadius() * dynObj->GetRadius())
503 remove = true;
505 else
506 remove = true;
508 else
509 remove = true;
511 Aura::Update(diff);
513 if(remove)
514 m_target->RemoveAura(GetId(), GetEffIndex());
517 void Aura::ApplyModifier(bool apply)
519 uint8 aura = 0;
520 aura = m_modifier.m_auraname;
521 if(aura<TOTAL_AURAS)
522 (*this.*AuraHandler [aura])(apply);
525 void Aura::UpdateAuraDuration()
527 if(m_target->GetTypeId() != TYPEID_PLAYER)
528 return;
529 if(m_isPassive)
530 return;
532 WorldPacket data;
533 data.Initialize(SMSG_UPDATE_AURA_DURATION);
534 data << (uint8)m_auraSlot << (uint32)m_duration;
535 //((Player*)m_target)->SendMessageToSet(&data, true); //GetSession()->SendPacket(&data);
536 ((Player*)m_target)->SendDirectMessage(&data);
539 void Aura::_AddAura()
541 if (!m_spellId)
542 return;
543 if(!m_target)
544 return;
546 bool samespell = false;
547 uint8 slot = 0xFF, i;
548 Aura* aura = NULL;
550 for(i = 0; i < 3; i++)
552 aura = m_target->GetAura(m_spellId, i);
553 if(aura)
555 //if (i != m_effIndex)
557 samespell = true;
558 slot = aura->GetAuraSlot();
563 // adding linked auras
564 if(m_modifier.m_auraname == 36) // add the shapeshift aura's boosts
565 HandleShapeshiftBoosts(true, this);
567 m_target->ApplyStats(false);
568 ApplyModifier(true);
569 m_target->ApplyStats(true);
570 sLog.outDebug("Aura %u now is in use", m_modifier.m_auraname);
572 Unit* caster = GetCaster();
574 // passive auras (except totem auras) do not get placed in the slots
575 if(!m_isPassive || (caster && caster->GetTypeId() == TYPEID_UNIT && ((Creature*)caster)->isTotem()))
577 if(!samespell)
579 if (IsPositive())
581 for (i = 0; i < MAX_POSITIVE_AURAS; i++)
583 if (m_target->GetUInt32Value((uint16)(UNIT_FIELD_AURA + i)) == 0)
585 slot = i;
586 break;
590 else
592 for (i = MAX_POSITIVE_AURAS; i < MAX_AURAS; i++)
594 if (m_target->GetUInt32Value((uint16)(UNIT_FIELD_AURA + i)) == 0)
596 slot = i;
597 break;
602 m_target->SetUInt32Value((uint16)(UNIT_FIELD_AURA + slot), GetId());
604 uint8 flagslot = slot >> 3;
605 uint32 value = m_target->GetUInt32Value((uint16)(UNIT_FIELD_AURAFLAGS + flagslot));
607 uint8 value1 = (slot & 7) << 2;
608 value |= ((uint32)AFLAG_SET << value1);
610 m_target->SetUInt32Value((uint16)(UNIT_FIELD_AURAFLAGS + flagslot), value);
612 else
614 /* TODO: increase count */
617 SetAuraSlot( slot );
618 if( m_target->GetTypeId() == TYPEID_PLAYER )
619 UpdateAuraDuration();
624 void Aura::_RemoveAura()
626 // removing linked auras added ad _AddAura call before removing aura
627 if(m_modifier.m_auraname == 36) // remove the shapeshift aura's boosts
628 HandleShapeshiftBoosts(false, this);
630 m_target->ApplyStats(false);
631 sLog.outDebug("Aura %u now is remove", m_modifier.m_auraname);
632 ApplyModifier(false);
633 m_target->ApplyStats(true);
635 Unit* caster = GetCaster();
637 if(caster && IsPersistent())
639 DynamicObject *dynObj = caster->GetDynObject(GetId(), GetEffIndex());
640 if (dynObj)
641 dynObj->RemoveAffected(m_target);
643 //passive auras do not get put in slots
644 if(m_isPassive && !(caster && caster->GetTypeId() == TYPEID_UNIT && ((Creature*)caster)->isTotem()))
645 return;
647 uint8 slot = GetAuraSlot();
648 Aura* aura = m_target->GetAura(m_spellId, m_effIndex);
649 if(!aura)
650 return;
652 if(m_target->GetUInt32Value((uint16)(UNIT_FIELD_AURA + slot)) == 0)
653 return;
655 // count all auras from each effect of the spell
656 Unit::AuraMap& t_Auras = m_target->GetAuras();
657 uint8 count[3], totalcount = 0;
658 for(uint8 i = 0; i < 3; i++)
660 count[i] = t_Auras.count(Unit::spellEffectPair(m_spellId, i));
661 totalcount += count[i];
665 count[m_effIndex]--;
666 // all counts should be the same after the last effect of a spell was taken out
667 for(uint8 i = 0; i < 3; i++)
668 if (count[i] > count[m_effIndex])
669 break;
670 if (i == 3)
671 TODO: decrease count for spell
674 // only remove icon when the last aura of the spell is removed
675 if (totalcount > 1)
676 return;
678 m_target->SetUInt32Value((uint16)(UNIT_FIELD_AURA + slot), 0);
680 uint8 flagslot = slot >> 3;
682 uint32 value = m_target->GetUInt32Value((uint16)(UNIT_FIELD_AURAFLAGS + flagslot));
684 uint8 aurapos = (slot & 7) << 2;
685 uint32 value1 = ~( AFLAG_SET << aurapos );
686 value &= value1;
688 m_target->SetUInt32Value((uint16)(UNIT_FIELD_AURAFLAGS + flagslot), value);
691 /*********************************************************/
692 /*** BASIC AURA FUNCTION ***/
693 /*********************************************************/
695 void Aura::HandleNULL(bool apply)
699 void Aura::HandleAddModifier(bool apply)
701 if(m_target->GetTypeId() != TYPEID_PLAYER)
702 return;
704 Player *p_target = (Player *)m_target;
706 SpellEntry *spellInfo = GetSpellProto();
707 if(!spellInfo) return;
709 uint8 op = spellInfo->EffectMiscValue[m_effIndex];
710 int32 value = spellInfo->EffectBasePoints[m_effIndex]+1;
711 uint8 type = spellInfo->EffectApplyAuraName[m_effIndex];
712 uint32 mask = spellInfo->EffectItemType[m_effIndex];
713 if (!op) return;
714 SpellModList *p_mods = p_target->getSpellModList(op);
715 if (!p_mods) return;
717 if (apply)
719 SpellModifier *mod = new SpellModifier;
720 mod->op = op;
721 mod->value = value;
722 mod->type = type;
723 mod->mask = mask;
724 mod->spellId = m_spellId;
725 mod->charges = spellInfo->procCharges;
726 p_mods->push_back(mod);
727 m_spellmod = mod;
729 uint16 send_val=0, send_mark=0;
730 int16 tmpval=spellInfo->EffectBasePoints[m_effIndex];
731 uint32 shiftdata=0x01, Opcode=SMSG_SET_FLAT_SPELL_MODIFIER;
733 if(tmpval != 0)
735 if(tmpval > 0)
737 send_val = tmpval+1;
738 send_mark = 0x0;
740 else
742 send_val = 0xFFFF + (tmpval+2);
743 send_mark = 0xFFFF;
747 if (mod->type == SPELLMOD_FLAT) Opcode = SMSG_SET_FLAT_SPELL_MODIFIER;
748 else if (mod->type == SPELLMOD_PCT) Opcode = SMSG_SET_PCT_SPELL_MODIFIER;
750 WorldPacket data;
751 for(int eff=0;eff<32;eff++)
753 if ( mask & shiftdata )
755 data.Initialize(Opcode);
756 data << uint8(eff);
757 data << uint8(mod->op);
758 data << uint16(send_val);
759 data << uint16(send_mark);
760 p_target->SendDirectMessage(&data);
762 shiftdata=shiftdata<<1;
765 else
767 SpellModList *p_mods = p_target->getSpellModList(spellInfo->EffectMiscValue[m_effIndex]);
768 p_mods->remove(this->m_spellmod);
772 void Aura::TriggerSpell()
774 SpellEntry *spellInfo = sSpellStore.LookupEntry( GetSpellProto()->EffectTriggerSpell[m_effIndex] );
776 if(!spellInfo)
778 sLog.outError("Auras: unknown TriggerSpell id %i\n from spell: %i", GetSpellProto()->EffectTriggerSpell[m_effIndex],GetSpellProto()->Id);
779 return;
781 if(GetSpellProto()->Id == 1515)
782 spellInfo = sSpellStore.LookupEntry( 13481 );
784 Unit* caster = GetCaster();
786 Spell spell(caster, spellInfo, true, this);
787 Unit* target = m_target;
788 if(!target && caster && caster->GetTypeId() == TYPEID_PLAYER)
790 target = ObjectAccessor::Instance().GetUnit(*caster, ((Player*)caster)->GetSelection());
792 if(!target)
793 return;
794 SpellCastTargets targets;
795 targets.setUnitTarget(target);
796 spell.prepare(&targets);
799 /*********************************************************/
800 /*** AURA EFFECTS ***/
801 /*********************************************************/
803 void Aura::HandleAuraDummy(bool apply)
805 Unit* caster = GetCaster();
807 if(GetSpellProto()->SpellVisual == 5622 && caster && caster->GetTypeId() == TYPEID_PLAYER)
809 Player *player = (Player*)caster;
810 if(GetSpellProto()->SpellIconID == 25 && GetEffIndex() == 0)
812 Unit::AuraList& tAuraProcTriggerDamage = m_target->GetAurasByType(SPELL_AURA_PROC_TRIGGER_DAMAGE);
813 if(apply)
814 tAuraProcTriggerDamage.push_back(this);
815 else
816 tAuraProcTriggerDamage.remove(this);
818 if(apply && !m_procCharges)
820 m_procCharges = GetSpellProto()->procCharges;
821 if (!m_procCharges)
822 m_procCharges = -1;
826 if(GetSpellProto()->SpellVisual == 99 && GetSpellProto()->SpellIconID == 92 && caster
827 && caster->GetTypeId() == TYPEID_PLAYER && m_castItem)
829 if(m_target && m_target->GetTypeId() == TYPEID_PLAYER)
831 Player * player = (Player*)m_target;
832 uint32 spellid = 0;
833 uint32 itemflag = m_castItem->GetUInt32Value(ITEM_FIELD_FLAGS);
834 if(apply)
836 // 1<<20 just a temp value to detect if any one has be stored,
837 // we should find out a field to correctly mask the target.
838 if(itemflag & (1<<20))
839 return;
840 switch(GetId())
842 case 20707:spellid = 3026;break;
843 case 20762:spellid = 20758;break;
844 case 20763:spellid = 20759;break;
845 case 20764:spellid = 20760;break;
846 case 20765:spellid = 20761;break;
847 default:break;
849 if(!spellid)
850 return;
851 m_castItem->ApplyModFlag(ITEM_FIELD_FLAGS,(1<<20),true);
852 player->SetSoulStone(m_castItem);
853 player->SetSoulStoneSpell(spellid);
855 else
857 m_castItem->ApplyModFlag(ITEM_FIELD_FLAGS,(1<<20),false);
861 if(!apply)
863 //probably it's temporary for taming creature..
864 if( GetSpellProto()->Id == 19674 && caster && caster->isAlive())
866 SpellEntry *spell_proto = sSpellStore.LookupEntry(13481);
867 Spell spell(caster, spell_proto, true, 0);
868 Unit* target = NULL;
869 target = m_target;
870 if(!target || !target->isAlive())
871 return;
872 SpellCastTargets targets;
873 targets.setUnitTarget(target);
874 // prevent double stat apply for triggered auras
875 target->ApplyStats(true);
876 spell.prepare(&targets);
877 target->ApplyStats(false);
882 void Aura::HandleAuraMounted(bool apply)
884 if(apply)
886 CreatureInfo const* ci = objmgr.GetCreatureTemplate(m_modifier.m_miscvalue);
887 if(!ci)return;
888 uint32 displayId = ci->DisplayID;
889 if(displayId != 0)
890 m_target->Mount(displayId);
891 }else
893 m_target->Unmount();
897 void Aura::HandleAuraWaterWalk(bool apply)
899 WorldPacket data;
900 if(apply)
901 data.Initialize(SMSG_MOVE_WATER_WALK);
902 else
903 data.Initialize(SMSG_MOVE_LAND_WALK);
904 data << uint8(0xFF) << m_target->GetGUID();
905 m_target->SendMessageToSet(&data,true);
908 void Aura::HandleAuraFeatherFall(bool apply)
910 WorldPacket data;
911 if(apply)
912 data.Initialize(SMSG_MOVE_FEATHER_FALL);
913 else
914 data.Initialize(SMSG_MOVE_NORMAL_FALL);
915 data << uint8(0xFF) << m_target->GetGUID();
916 m_target->SendMessageToSet(&data,true);
919 void Aura::HandleWaterBreathing(bool apply)
921 m_target->waterbreath = apply;
924 void Aura::HandleAuraModShapeshift(bool apply)
926 if(!m_target)
927 return;
928 Unit *unit_target = m_target;
929 uint32 modelid = 0;
930 Powers PowerType = POWER_MANA;
931 uint32 new_bytes_1 = m_modifier.m_miscvalue;
932 switch(m_modifier.m_miscvalue)
934 case FORM_CAT:
935 if(unit_target->getRace() == RACE_NIGHT_ELF)
936 modelid = 892;
937 else if(unit_target->getRace() == RACE_TAUREN)
938 modelid = 8571;
939 PowerType = POWER_ENERGY;
940 break;
941 case FORM_TRAVEL:
942 modelid = 632;
943 break;
944 case FORM_AQUA:
945 if(unit_target->getRace() == RACE_NIGHT_ELF)
946 modelid = 2428;
947 else if(unit_target->getRace() == RACE_TAUREN)
948 modelid = 2428;
949 break;
950 case FORM_BEAR:
951 if(unit_target->getRace() == RACE_NIGHT_ELF)
952 modelid = 2281;
953 else if(unit_target->getRace() == RACE_TAUREN)
954 modelid = 2289;
955 PowerType = POWER_RAGE;
956 break;
957 case FORM_GHOUL:
958 if(unit_target->getRace() == RACE_NIGHT_ELF)
959 modelid = 10045;
960 break;
961 case FORM_DIREBEAR:
962 if(unit_target->getRace() == RACE_NIGHT_ELF)
963 modelid = 2281;
964 else if(unit_target->getRace() == RACE_TAUREN)
965 modelid = 2289;
966 PowerType = POWER_RAGE;
967 break;
968 case FORM_CREATUREBEAR:
969 modelid = 902;
970 break;
971 case FORM_GHOSTWOLF:
972 modelid = 1236;
973 break;
974 case FORM_MOONKIN:
975 if(unit_target->getRace() == RACE_NIGHT_ELF)
976 modelid = 15374;
977 else if(unit_target->getRace() == RACE_TAUREN)
978 modelid = 15375;
979 break;
980 case FORM_AMBIENT:
981 case FORM_BATTLESTANCE:
982 case FORM_BERSERKERSTANCE:
983 case FORM_DEFENSIVESTANCE:
984 case FORM_SHADOW:
985 case FORM_STEALTH:
986 case FORM_TREE:
987 break;
988 default:
989 sLog.outError("Auras: Unknown Shapeshift Type: %u", m_modifier.m_miscvalue);
992 if(apply)
994 unit_target->SetFlag(UNIT_FIELD_BYTES_1, (new_bytes_1<<16) );
995 if(modelid > 0)
997 unit_target->SetUInt32Value(UNIT_FIELD_DISPLAYID,modelid);
1000 if(PowerType != POWER_MANA)
1001 unit_target->setPowerType(PowerType);
1003 unit_target->m_ShapeShiftForm = m_spellId;
1004 unit_target->m_form = m_modifier.m_miscvalue;
1005 if(unit_target->m_form == FORM_DIREBEAR)
1006 if (m_target->getRace() == TAUREN)
1008 m_target->SetFloatValue(OBJECT_FIELD_SCALE_X,1.35f);
1010 else
1011 m_target->SetFloatValue(OBJECT_FIELD_SCALE_X,1.0f);
1013 else
1015 if (m_target->getRace() == TAUREN)
1016 unit_target->SetFloatValue(OBJECT_FIELD_SCALE_X,1.35f);
1017 else
1018 unit_target->SetFloatValue(OBJECT_FIELD_SCALE_X,1.0f);
1019 unit_target->SetUInt32Value(UNIT_FIELD_DISPLAYID,unit_target->GetUInt32Value(UNIT_FIELD_NATIVEDISPLAYID));
1020 unit_target->RemoveFlag(UNIT_FIELD_BYTES_1, (new_bytes_1<<16) );
1021 if(unit_target->getClass() == CLASS_DRUID)
1022 unit_target->setPowerType(POWER_MANA);
1023 unit_target->m_ShapeShiftForm = 0;
1024 unit_target->m_form = 0;
1028 void Aura::HandleAuraTransform(bool apply)
1030 if(!m_target)
1031 return;
1033 if (apply)
1035 CreatureInfo const * ci = objmgr.GetCreatureTemplate(m_modifier.m_miscvalue);
1036 if(!ci)
1038 //pig pink ^_^
1039 m_target->SetUInt32Value (UNIT_FIELD_DISPLAYID, 16358);
1040 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);
1042 else
1044 m_target->SetUInt32Value (UNIT_FIELD_DISPLAYID, ci->DisplayID);
1046 m_target->setTransForm(GetSpellProto()->Id);
1048 else
1050 m_target->SetUInt32Value (UNIT_FIELD_DISPLAYID, m_target->GetUInt32Value(UNIT_FIELD_NATIVEDISPLAYID));
1051 m_target->setTransForm(0);
1054 Unit* caster = GetCaster();
1056 if(caster && caster->GetTypeId() == TYPEID_PLAYER)
1057 m_target->SendUpdateToPlayer((Player*)caster);
1060 void Aura::HandleForceReaction(bool Apply)
1062 if(m_target->GetTypeId() != TYPEID_PLAYER)
1063 return;
1065 if(Apply)
1067 uint32 faction_id = m_modifier.m_miscvalue;
1069 FactionTemplateEntry *factionTemplateEntry;
1071 for(uint32 i = 0; i < sFactionTemplateStore.GetNumRows(); ++i)
1073 factionTemplateEntry = sFactionTemplateStore.LookupEntry(i);
1074 if(!factionTemplateEntry)
1075 continue;
1077 if(factionTemplateEntry->faction == faction_id)
1078 break;
1081 if(!factionTemplateEntry)
1082 return;
1084 m_target->setFaction(factionTemplateEntry->ID);
1086 else
1087 ((Player*)m_target)->setFactionForRace(((Player*)m_target)->getRace());
1090 void Aura::HandleAuraModSkill(bool apply)
1092 if(m_target->GetTypeId() != TYPEID_PLAYER)
1093 return;
1095 SpellEntry* prot=GetSpellProto();
1097 ((Player*)m_target)->ModifySkillBonus(prot->EffectMiscValue[0],
1098 (apply ? (prot->EffectBasePoints[0]+1): (-(prot->EffectBasePoints[0]+1))));
1101 void Aura::HandleChannelDeathItem(bool apply)
1103 if(!apply)
1105 Unit* caster = GetCaster();
1106 if(!caster || caster->GetTypeId() != TYPEID_PLAYER || !m_removeOnDeath)
1107 return;
1108 SpellEntry *spellInfo = GetSpellProto();
1109 if(spellInfo->EffectItemType[m_effIndex] == 0)
1110 return;
1111 uint16 dest;
1112 uint8 msg = ((Player*)caster)->CanStoreNewItem( 0, NULL_SLOT, dest, spellInfo->EffectItemType[m_effIndex], 1, false);
1113 if( msg == EQUIP_ERR_OK )
1114 ((Player*)caster)->StoreNewItem(dest, spellInfo->EffectItemType[m_effIndex], 1, true);
1115 else
1116 ((Player*)caster)->SendEquipError( msg, NULL, NULL );
1120 void Aura::HandleAuraSafeFall(bool apply)
1122 WorldPacket data;
1123 if(apply)
1124 data.Initialize(SMSG_MOVE_FEATHER_FALL);
1125 else
1126 data.Initialize(SMSG_MOVE_NORMAL_FALL);
1127 data << uint8(0xFF) << m_target->GetGUID();
1128 m_target->SendMessageToSet(&data,true);
1131 void Aura::HandleBindSight(bool apply)
1133 if(!m_target)
1134 return;
1136 if(m_target->GetTypeId() != TYPEID_PLAYER)
1137 return;
1139 m_target->SetUInt64Value(PLAYER_FARSIGHT,apply ? m_target->GetGUID() : 0);
1142 void Aura::HandleFarSight(bool apply)
1144 if(!m_target)
1145 return;
1147 if(m_target->GetTypeId() != TYPEID_PLAYER)
1148 return;
1150 m_target->SetUInt64Value(PLAYER_FARSIGHT,apply ? m_modifier.m_miscvalue : 0);
1153 void Aura::HandleAuraTracCreatures(bool apply)
1155 if(m_target->GetTypeId()!=TYPEID_PLAYER)
1156 return;
1158 m_target->SetUInt32Value(PLAYER_TRACK_CREATURES, apply ? ((uint32)1)<<(m_modifier.m_miscvalue-1) : 0 );
1161 void Aura::HandleAuraTracResources(bool apply)
1163 if(m_target->GetTypeId()!=TYPEID_PLAYER)
1164 return;
1166 m_target->SetUInt32Value(PLAYER_TRACK_RESOURCES, apply ? ((uint32)1)<<(m_modifier.m_miscvalue-1): 0 );
1169 void Aura::HandleAuraModScale(bool apply)
1171 m_target->ApplyPercentModFloatValue(OBJECT_FIELD_SCALE_X,10,apply);
1174 void Aura::HandleModPossess(bool apply)
1176 if(!m_target)
1177 return;
1179 if(m_target->GetTypeId() != TYPEID_UNIT)
1180 return;
1182 Creature* creatureTarget = (Creature*)m_target;
1184 if(m_target->getLevel() <= m_modifier.m_amount)
1186 WorldPacket data;
1188 CreatureInfo const *cinfo = ((Creature*)m_target)->GetCreatureInfo();
1189 if( apply )
1191 Unit* caster = GetCaster();
1192 if(caster)
1194 creatureTarget->SetUInt64Value(UNIT_FIELD_CHARMEDBY,caster->GetGUID());
1195 creatureTarget->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE,caster->getFaction());
1196 caster->SetCharm(creatureTarget);
1197 creatureTarget->AIM_Initialize();
1198 if(caster->GetTypeId() == TYPEID_PLAYER)
1200 ((Player*)caster)->PetSpellInitialize();
1204 else
1206 creatureTarget->SetUInt64Value(UNIT_FIELD_CHARMEDBY,0);
1207 creatureTarget->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE,cinfo->faction);
1209 if(Unit* caster = GetCaster())
1211 caster->SetCharm(0);
1213 if(caster->GetTypeId() == TYPEID_PLAYER)
1215 data.Initialize(SMSG_PET_SPELLS);
1216 data << uint64(0);
1217 ((Player*)caster)->GetSession()->SendPacket(&data);
1220 creatureTarget->AIM_Initialize();
1225 void Aura::HandleModCharm(bool apply)
1227 if(!m_target)
1228 return;
1230 if(m_target->GetTypeId() != TYPEID_UNIT)
1231 return;
1233 Creature* creatureTarget = (Creature*)m_target;
1235 if(m_target->getLevel() <= m_modifier.m_amount)
1237 WorldPacket data;
1239 CreatureInfo const *cinfo = ((Creature*)m_target)->GetCreatureInfo();
1240 if( apply )
1242 Unit* caster = GetCaster();
1243 if(caster)
1245 creatureTarget->SetUInt64Value(UNIT_FIELD_CHARMEDBY,caster->GetGUID());
1246 creatureTarget->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE,caster->getFaction());
1247 caster->SetCharm(creatureTarget);
1248 creatureTarget->AIM_Initialize();
1249 if(caster->GetTypeId() == TYPEID_PLAYER)
1251 ((Player*)caster)->PetSpellInitialize();
1255 else
1257 creatureTarget->SetUInt64Value(UNIT_FIELD_CHARMEDBY,0);
1258 creatureTarget->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE,cinfo->faction);
1259 Unit* caster = GetCaster();
1260 if(caster)
1262 caster->SetCharm(0);
1263 if(caster->GetTypeId() == TYPEID_PLAYER)
1265 data.Initialize(SMSG_PET_SPELLS);
1266 data << uint64(0);
1267 ((Player*)caster)->GetSession()->SendPacket(&data);
1270 creatureTarget->AIM_Initialize();
1275 void Aura::HandleModConfuse(bool apply)
1277 uint32 apply_stat = UNIT_STAT_CONFUSED;
1278 if( apply )
1280 m_target->addUnitState(UNIT_STAT_CONFUSED);
1281 m_target->SetFlag(UNIT_FIELD_FLAGS,(apply_stat<<16));
1282 if (m_target->GetTypeId() == TYPEID_UNIT)
1283 (*((Creature*)m_target))->Mutate(new ConfusedMovementGenerator(*((Creature*)m_target)));
1285 else
1287 m_target->clearUnitState(UNIT_STAT_CONFUSED);
1288 m_target->RemoveFlag(UNIT_FIELD_FLAGS,(apply_stat<<16));
1289 if (m_target->GetTypeId() == TYPEID_UNIT)
1290 (*((Creature*)m_target))->MovementExpired();
1294 void Aura::HandleModFear(bool Apply)
1296 uint32 apply_stat = UNIT_STAT_FLEEING;
1297 WorldPacket data;
1298 data.Initialize(SMSG_DEATH_NOTIFY_OBSOLETE);
1299 if( Apply )
1301 m_target->addUnitState(UNIT_STAT_FLEEING);
1302 // m_target->AttackStop();
1304 m_target->SetFlag(UNIT_FIELD_FLAGS,(apply_stat<<16));
1306 data<<m_target->GetGUID();
1307 data<<uint8(0);
1309 else
1311 data<<m_target->GetGUID();
1312 data<<uint8(1);
1313 m_target->clearUnitState(UNIT_STAT_FLEEING);
1314 m_target->RemoveFlag(UNIT_FIELD_FLAGS,(apply_stat<<16));
1315 if(m_target->GetTypeId() != TYPEID_PLAYER)
1316 m_target->Attack(GetCaster());
1318 m_target->SendMessageToSet(&data,true);
1321 void Aura::HandleAuraModStun(bool apply)
1323 WorldPacket data;
1324 if (apply)
1326 m_target->addUnitState(UNIT_STAT_STUNDED);
1327 m_target->SetUInt64Value (UNIT_FIELD_TARGET, 0);
1328 if(m_target->GetTypeId() != TYPEID_PLAYER)
1329 ((Creature *)m_target)->StopMoving();
1331 data.Initialize(SMSG_FORCE_MOVE_ROOT);
1332 data << uint8(0xFF) << m_target->GetGUID();
1333 m_target->SendMessageToSet(&data,true);
1334 m_target->SetFlag(UNIT_FIELD_FLAGS, 0x40000);
1336 else
1338 m_target->clearUnitState(UNIT_STAT_STUNDED);
1339 m_target->RemoveFlag(UNIT_FIELD_FLAGS, 0x40000);
1341 data.Initialize(SMSG_FORCE_MOVE_UNROOT);
1342 data << uint8(0xFF) << m_target->GetGUID();
1343 m_target->SendMessageToSet(&data,true);
1347 void Aura::HandleModStealth(bool apply)
1349 if(apply)
1351 m_target->m_stealthvalue = CalculateDamage();
1352 m_target->SetFlag(UNIT_FIELD_BYTES_1, (0x2<<24) );
1354 else
1356 SendCoolDownEvent();
1357 m_target->m_stealthvalue = 0;
1358 m_target->RemoveFlag(UNIT_FIELD_BYTES_1, (0x2<<24) );
1360 if(m_target->GetTypeId() == TYPEID_PLAYER)
1361 m_target->SendUpdateToPlayer((Player*)m_target);
1364 void Aura::HandleModDetect(bool apply)
1366 if(apply)
1368 m_target->m_detectStealth = CalculateDamage();
1370 else
1372 m_target->m_detectStealth = 0;
1376 void Aura::HandleInvisibility(bool Apply)
1378 if(Apply)
1380 m_target->m_stealthvalue = CalculateDamage();
1381 m_target->SetFlag(UNIT_FIELD_BYTES_1, (0x2000000) );
1383 else
1385 SendCoolDownEvent();
1386 m_target->m_stealthvalue = 0;
1387 m_target->RemoveFlag(UNIT_FIELD_BYTES_1, (0x2000000) );
1389 if(m_target->GetTypeId() == TYPEID_PLAYER)
1390 m_target->SendUpdateToPlayer((Player*)m_target);
1393 void Aura::HandleInvisibilityDetect(bool Apply)
1395 if(Apply)
1397 m_target->m_detectStealth = CalculateDamage();
1399 else
1401 m_target->m_detectStealth = 0;
1405 void Aura::HandleAuraModRoot(bool apply)
1407 uint32 apply_stat = UNIT_STAT_ROOT;
1408 if (apply)
1410 m_target->addUnitState(UNIT_STAT_ROOT);
1411 m_target->SetUInt64Value (UNIT_FIELD_TARGET, 0);
1412 m_target->SetFlag(UNIT_FIELD_FLAGS,(apply_stat<<16));
1413 if(m_target->GetTypeId() == TYPEID_PLAYER)
1415 WorldPacket data;
1416 data.Initialize(SMSG_FORCE_MOVE_ROOT);
1417 data << uint8(0xFF) << m_target->GetGUID() << (uint32)2;
1418 m_target->SendMessageToSet(&data,true);
1420 else
1421 ((Creature *)m_target)->StopMoving();
1423 else
1425 m_target->clearUnitState(UNIT_STAT_ROOT);
1426 m_target->RemoveFlag(UNIT_FIELD_FLAGS,(apply_stat<<16));
1427 WorldPacket data;
1428 if(m_target->GetTypeId() == TYPEID_PLAYER)
1430 WorldPacket data;
1431 data.Initialize(SMSG_FORCE_MOVE_UNROOT);
1432 data << uint8(0xFF) << m_target->GetGUID() << (uint32)2;
1433 m_target->SendMessageToSet(&data,true);
1438 void Aura::HandleAuraModSilence(bool apply)
1440 apply ? m_target->m_silenced = true : m_target->m_silenced = false;
1443 void Aura::HandleModThreat(bool apply)
1445 if(!m_target || !m_target->isAlive())
1446 return;
1448 Unit* caster = GetCaster();
1450 if(!caster || !caster->isAlive())
1451 return;
1453 m_target->AddHostil(m_caster_guid,apply ? float(m_modifier.m_amount) : -float(m_modifier.m_amount));
1456 /*********************************************************/
1457 /*** MODIDY SPEED ***/
1458 /*********************************************************/
1460 void Aura::HandleAuraModIncreaseSpeedAlways(bool apply)
1462 sLog.outDebug("Current Speed:%f \tmodify:%f", m_target->GetSpeed(MOVE_RUN),(float)m_modifier.m_amount);
1463 if(m_modifier.m_amount<=1)
1464 return;
1465 WorldPacket data;
1466 if(apply)
1467 m_target->SetSpeed( m_target->GetSpeed() * (100.0f + m_modifier.m_amount)/100.0f );
1468 else
1469 m_target->SetSpeed( m_target->GetSpeed() * 100.0f/(100.0f + m_modifier.m_amount) );
1470 data.Initialize(MSG_MOVE_SET_RUN_SPEED);
1471 data << m_target->GetGUID();
1472 data << m_target->GetSpeed( MOVE_RUN );
1473 m_target->SendMessageToSet(&data,true);
1474 sLog.outDebug("ChangeSpeedTo:%f", m_target->GetSpeed(MOVE_RUN));
1477 void Aura::HandleAuraModIncreaseSpeed(bool apply)
1479 sLog.outDebug("Current Speed:%f \tmodify:%f", m_target->GetSpeed(MOVE_RUN),(float)m_modifier.m_amount);
1480 if(m_modifier.m_amount<=1)
1481 return;
1482 WorldPacket data;
1483 if(apply)
1484 m_target->SetSpeed( m_target->GetSpeed() * (100.0f + m_modifier.m_amount)/100.0f );
1485 else
1486 m_target->SetSpeed( m_target->GetSpeed() * 100.0f/(100.0f + m_modifier.m_amount) );
1487 data.Initialize(SMSG_FORCE_RUN_SPEED_CHANGE);
1488 data << uint8(0xFF);
1489 data << m_target->GetGUID();
1490 data << (uint32)0;
1491 data << m_target->GetSpeed( MOVE_RUN );
1493 m_target->SendMessageToSet(&data,true);
1494 sLog.outDebug("ChangeSpeedTo:%f", m_target->GetSpeed(MOVE_RUN));
1497 void Aura::HandleAuraModIncreaseMountedSpeed(bool apply)
1499 sLog.outDebug("Current Speed:%f \tmodify:%f", m_target->GetSpeed(MOVE_RUN),(float)m_modifier.m_amount);
1500 if(m_modifier.m_amount<=1)
1501 return;
1502 WorldPacket data;
1503 if(apply)
1504 m_target->SetSpeed( m_target->GetSpeed() * ( m_modifier.m_amount + 100.0f ) / 100.0f );
1505 else
1506 m_target->SetSpeed( m_target->GetSpeed() * 100.0f / ( m_modifier.m_amount + 100.0f ) );
1507 data.Initialize(SMSG_FORCE_RUN_SPEED_CHANGE);
1508 data << uint8(0xFF);
1509 data << m_target->GetGUID();
1510 data << (uint32)0;
1511 data << m_target->GetSpeed( MOVE_RUN );
1512 m_target->SendMessageToSet(&data,true);
1513 sLog.outDebug("ChangeSpeedTo:%f", m_target->GetSpeed(MOVE_RUN));
1516 void Aura::HandleAuraModDecreaseSpeed(bool apply)
1518 sLog.outDebug("Current Speed:%f \tmodify:%f", m_target->GetSpeed(MOVE_RUN),(float)m_modifier.m_amount);
1519 if(m_modifier.m_amount<=1)
1520 return;
1521 WorldPacket data;
1522 if(apply)
1523 m_target->SetSpeed( m_target->GetSpeed() * m_modifier.m_amount/100.0f );
1524 else
1525 m_target->SetSpeed( m_target->GetSpeed() * 100.0f/m_modifier.m_amount );
1526 data.Initialize(SMSG_FORCE_RUN_SPEED_CHANGE);
1527 data << uint8(0xFF);
1528 data << m_target->GetGUID();
1529 data << (uint32)0;
1530 data << m_target->GetSpeed( MOVE_RUN );
1531 m_target->SendMessageToSet(&data,true);
1532 sLog.outDebug("ChangeSpeedTo:%f", m_target->GetSpeed(MOVE_RUN));
1535 void Aura::HandleAuraModIncreaseSwimSpeed(bool Apply)
1537 sLog.outDebug("Current Speed:%f \tmodify:%f", m_target->GetSpeed(MOVE_SWIM),(float)m_modifier.m_amount);
1538 if(m_modifier.m_amount<=1)
1539 return;
1540 WorldPacket data;
1541 if(Apply)
1542 m_target->SetSpeed( m_target->GetSpeed() * ( m_modifier.m_amount + 100.0f ) / 100.0f );
1543 else
1544 m_target->SetSpeed( m_target->GetSpeed() * 100.0f / ( m_modifier.m_amount + 100.0f ) );
1545 data.Initialize(SMSG_FORCE_SWIM_SPEED_CHANGE);
1546 data << uint8(0xFF);
1547 data << m_target->GetGUID();
1548 data << (uint32)0;
1549 data << m_target->GetSpeed( MOVE_SWIM );
1550 m_target->SendMessageToSet(&data,true);
1551 sLog.outDebug("ChangeSpeedTo:%f", m_target->GetSpeed(MOVE_SWIM));
1554 /*********************************************************/
1555 /*** IMMUNITY ***/
1556 /*********************************************************/
1558 void Aura::HandleModMechanicImmunity(bool apply)
1560 m_target->ApplySpellImmune(GetId(),IMMUNITY_MECHANIC,m_modifier.m_miscvalue,apply);
1563 void Aura::HandleAuraModEffectImmunity(bool apply)
1565 m_target->ApplySpellImmune(GetId(),IMMUNITY_EFFECT,m_modifier.m_miscvalue,apply);
1568 void Aura::HandleAuraModStateImmunity(bool apply)
1570 m_target->ApplySpellImmune(GetId(),IMMUNITY_STATE,m_modifier.m_miscvalue,apply);
1573 void Aura::HandleAuraModSchoolImmunity(bool apply)
1575 m_target->ApplySpellImmune(GetId(),IMMUNITY_SCHOOL,m_modifier.m_miscvalue,apply);
1578 void Aura::HandleAuraModDmgImmunity(bool apply)
1580 m_target->ApplySpellImmune(GetId(),IMMUNITY_DAMAGE,m_modifier.m_miscvalue,apply);
1583 void Aura::HandleAuraModDispelImmunity(bool apply)
1585 m_target->ApplySpellImmune(GetId(),IMMUNITY_DISPEL,m_modifier.m_miscvalue,apply);
1588 /*********************************************************/
1589 /*** MANA SHIELD ***/
1590 /*********************************************************/
1592 void Aura::HandleAuraDamageShield(bool apply)
1594 /*if(apply)
1596 for(std::list<struct DamageShield>::iterator i = m_target->m_damageShields.begin();i != m_target->m_damageShields.end();i++)
1597 if(i->m_spellId == GetId() && i->m_caster_guid == m_caster_guid)
1599 m_target->m_damageShields.erase(i);
1600 break;
1602 DamageShield* ds = new DamageShield();
1603 ds->m_caster_guid = m_caster_guid;
1604 ds->m_damage = m_modifier.m_amount;
1605 ds->m_spellId = GetId();
1606 m_target->m_damageShields.push_back((*ds));
1608 else
1610 for(std::list<struct DamageShield>::iterator i = m_target->m_damageShields.begin();i != m_target->m_damageShields.end();i++)
1611 if(i->m_spellId == GetId() && i->m_caster_guid == m_caster_guid)
1613 m_target->m_damageShields.erase(i);
1614 break;
1619 void Aura::HandleAuraManaShield(bool apply)
1621 if (apply && !m_absorbDmg)
1622 m_absorbDmg = m_modifier.m_amount;
1624 /*if(apply)
1627 for(std::list<struct DamageManaShield*>::iterator i = m_target->m_damageManaShield.begin();i != m_target->m_damageManaShield.end();i++)
1629 if(GetId() == (*i)->m_spellId)
1631 delete *i;
1632 m_target->m_damageManaShield.erase(i);
1636 DamageManaShield *dms = new DamageManaShield();
1638 dms->m_spellId = GetId();
1639 dms->m_modType = m_modifier.m_auraname;
1640 dms->m_totalAbsorb = m_modifier.m_amount;
1641 dms->m_currAbsorb = 0;
1642 dms->m_schoolType = m_modifier.m_miscvalue;
1643 m_target->m_damageManaShield.push_back(dms);
1645 else
1647 for(std::list<struct DamageManaShield*>::iterator i = m_target->m_damageManaShield.begin();i != m_target->m_damageManaShield.end();i++)
1649 if(GetId() == (*i)->m_spellId)
1651 delete *i;
1652 m_target->m_damageManaShield.erase(i);
1653 break;
1659 void Aura::HandleAuraSchoolAbsorb(bool apply)
1661 if (apply && !m_absorbDmg)
1662 m_absorbDmg = m_modifier.m_amount;
1663 /*if(apply)
1666 for(std::list<struct DamageManaShield*>::iterator i = m_target->m_damageManaShield.begin();i != m_target->m_damageManaShield.end();i++)
1668 if(GetId() == (*i)->m_spellId)
1670 m_target->m_damageManaShield.erase(i);
1674 DamageManaShield *dms = new DamageManaShield();
1676 dms->m_spellId = GetId();
1677 dms->m_modType = m_modifier.m_auraname;
1678 dms->m_totalAbsorb = m_modifier.m_amount;
1679 dms->m_currAbsorb = 0;
1680 dms->m_schoolType = m_modifier.m_miscvalue;
1681 m_target->m_damageManaShield.push_back(dms);
1683 else
1685 for(std::list<struct DamageManaShield*>::iterator i = m_target->m_damageManaShield.begin();i != m_target->m_damageManaShield.end();i++)
1687 if(GetId() == (*i)->m_spellId)
1689 m_target->m_damageManaShield.erase(i);
1690 break;
1696 /*********************************************************/
1697 /*** REFLECT SPELLS ***/
1698 /*********************************************************/
1700 void Aura::HandleReflectSpells(bool apply)
1702 // has no immediate effect when adding / removing
1705 void Aura::HandleReflectSpellsSchool(bool apply)
1707 // has no immediate effect when adding / removing
1710 /*********************************************************/
1711 /*** PROC TRIGGER ***/
1712 /*********************************************************/
1714 void Aura::HandleAuraProcTriggerSpell(bool apply)
1716 if(apply && !m_procCharges)
1718 m_procCharges = GetSpellProto()->procCharges;
1719 if (!m_procCharges)
1720 m_procCharges = -1;
1724 void Aura::HandleAuraProcTriggerDamage(bool apply)
1726 if(apply && !m_procCharges)
1728 m_procCharges = GetSpellProto()->procCharges;
1729 if (!m_procCharges)
1730 m_procCharges = -1;
1734 /*********************************************************/
1735 /*** PERIODIC ***/
1736 /*********************************************************/
1738 void Aura::HandlePeriodicTriggerSpell(bool apply)
1740 if (m_periodicTimer <= 0)
1741 m_periodicTimer += m_modifier.periodictime;
1743 m_isPeriodic = apply;
1744 m_isTrigger = apply;
1747 void Aura::HandlePeriodicEnergize(bool apply)
1749 if (m_periodicTimer <= 0)
1750 m_periodicTimer += m_modifier.periodictime;
1752 m_isPeriodic = apply;
1755 void Aura::HandlePeriodicHeal(bool apply)
1757 if (m_periodicTimer <= 0)
1758 m_periodicTimer += m_modifier.periodictime;
1760 m_isPeriodic = apply;
1763 void Aura::HandlePeriodicDamage(bool apply)
1765 if (m_periodicTimer <= 0)
1766 m_periodicTimer += m_modifier.periodictime;
1768 m_isPeriodic = apply;
1771 void Aura::HandlePeriodicDamagePCT(bool apply)
1773 if (m_periodicTimer <= 0)
1774 m_periodicTimer += m_modifier.periodictime;
1776 m_isPeriodic = apply;
1779 void Aura::HandlePeriodicLeech(bool apply)
1781 if (m_periodicTimer <= 0)
1782 m_periodicTimer += m_modifier.periodictime;
1784 m_isPeriodic = apply;
1787 void Aura::HandlePeriodicManaLeech(bool apply)
1789 if (m_periodicTimer <= 0)
1790 m_periodicTimer += m_modifier.periodictime;
1792 m_isPeriodic = apply;
1795 /*********************************************************/
1796 /*** MODITY STATES ***/
1797 /*********************************************************/
1799 /********************************/
1800 /*** RESISTANCE ***/
1801 /********************************/
1803 void Aura::HandleAuraModResistanceExclusive(bool apply)
1805 if(m_modifier.m_miscvalue < IMMUNE_SCHOOL_PHYSICAL || m_modifier.m_miscvalue > 127)
1807 sLog.outError("WARNING: Misc Value for SPELL_AURA_MOD_BASE_RESISTANCE_PCT not valid");
1808 return;
1811 bool positive = m_modifier.m_miscvalue2 == 0;
1813 for(int8 x=0;x < 7;x++)
1815 if(m_modifier.m_miscvalue & int32(1<<x))
1817 SpellSchools school = SpellSchools(SPELL_SCHOOL_NORMAL + x);
1819 m_target->ApplyResistanceMod(school,m_modifier.m_amount, apply);
1820 if(m_target->GetTypeId() == TYPEID_PLAYER)
1821 ((Player*)m_target)->ApplyResistanceBuffModsMod(school,positive,m_modifier.m_amount, apply);
1826 void Aura::HandleAuraModResistance(bool apply)
1828 if(m_modifier.m_miscvalue < IMMUNE_SCHOOL_PHYSICAL || m_modifier.m_miscvalue > 127)
1830 sLog.outError("WARNING: Misc Value for SPELL_AURA_MOD_BASE_RESISTANCE_PCT not valid");
1831 return;
1834 bool positive = m_modifier.m_miscvalue2 == 0;
1836 for(int8 x=0;x < 7;x++)
1838 if(m_modifier.m_miscvalue & int32(1<<x))
1840 SpellSchools school = SpellSchools(SPELL_SCHOOL_NORMAL + x);
1842 m_target->ApplyResistanceMod(school,m_modifier.m_amount, apply);
1843 if(m_target->GetTypeId() == TYPEID_PLAYER)
1844 ((Player*)m_target)->ApplyResistanceBuffModsMod(school,positive,m_modifier.m_amount, apply);
1849 void Aura::HandleAuraModBaseResistancePCT(bool apply)
1851 if(m_modifier.m_miscvalue < IMMUNE_SCHOOL_PHYSICAL || m_modifier.m_miscvalue > 127)
1853 sLog.outError("WARNING: Misc Value for SPELL_AURA_MOD_BASE_RESISTANCE_PCT not valid");
1854 return;
1857 // only players have base stats
1858 if(m_target->GetTypeId() != TYPEID_PLAYER)
1859 return;
1860 Player *p_target = (Player*)m_target;
1862 for(int8 x=0;x < 7;x++)
1864 if(m_modifier.m_miscvalue & int32(1<<x))
1866 SpellSchools school = SpellSchools(SPELL_SCHOOL_NORMAL + x);
1867 float curRes = p_target->GetResistance(school);
1868 float baseRes = curRes + p_target->GetResistanceBuffMods(school, false) - p_target->GetResistanceBuffMods(school, true);
1869 float baseRes_new = baseRes * (apply?(100.0f+m_modifier.m_amount)/100.0f : 100.0f / (100.0f+m_modifier.m_amount));
1870 p_target->SetResistance(school, curRes + baseRes_new - baseRes);
1875 void Aura::HandleModResistancePercent(bool apply)
1877 for(int8 i = 0; i < 7; i++)
1879 if(m_modifier.m_miscvalue & int32(1<<i))
1881 m_target->ApplyResistancePercentMod(SpellSchools(i), m_modifier.m_amount, apply );
1882 if(m_target->GetTypeId() == TYPEID_PLAYER)
1884 ((Player*)m_target)->ApplyResistanceBuffModsPercentMod(SpellSchools(i),true,m_modifier.m_amount, apply);
1885 ((Player*)m_target)->ApplyResistanceBuffModsPercentMod(SpellSchools(i),false,m_modifier.m_amount, apply);
1891 void Aura::HandleModBaseResistance(bool apply)
1893 // only players have base stats
1894 if(m_target->GetTypeId() != TYPEID_PLAYER)
1895 return;
1896 Player *p_target = (Player*)m_target;
1898 for(int i = 0; i < 7; i++)
1899 if(m_modifier.m_miscvalue & (1<<i))
1900 p_target->ApplyResistanceMod(SpellSchools(SPELL_SCHOOL_NORMAL + i),m_modifier.m_amount, apply);
1903 /********************************/
1904 /*** STAT ***/
1905 /********************************/
1907 void Aura::HandleAuraModStat(bool apply)
1909 if (m_modifier.m_miscvalue < -1 || m_modifier.m_miscvalue > 4)
1911 sLog.outError("WARNING: Misc Value for SPELL_AURA_MOD_STAT not valid");
1912 return;
1915 for(int32 i = 0; i < 5; i++)
1917 if (m_modifier.m_miscvalue == -1 || m_modifier.m_miscvalue == i)
1919 m_target->ApplyStatMod(Stats(i), m_modifier.m_amount,apply);
1920 if(m_target->GetTypeId() == TYPEID_PLAYER)
1922 if (m_modifier.m_miscvalue2 == 0)
1923 ((Player*)m_target)->ApplyPosStatMod(Stats(i),m_modifier.m_amount,apply);
1924 else
1925 ((Player*)m_target)->ApplyNegStatMod(Stats(i),m_modifier.m_amount,apply);
1931 void Aura::HandleModPercentStat(bool apply)
1933 if (m_modifier.m_miscvalue < -1 || m_modifier.m_miscvalue > 4)
1935 sLog.outError("WARNING: Misc Value for SPELL_AURA_MOD_PERCENT_STAT not valid");
1936 return;
1939 // only players have base stats
1940 if (m_target->GetTypeId() != TYPEID_PLAYER)
1941 return;
1942 Player *p_target = (Player*)m_target;
1944 for (int32 i = 0; i < 5; i++)
1946 if(m_modifier.m_miscvalue == i || m_modifier.m_miscvalue == -1)
1948 float curStat = p_target->GetStat(Stats(i));
1949 float baseStat = curStat + p_target->GetNegStat(Stats(i)) - p_target->GetPosStat(Stats(i));
1950 float baseStat_new = baseStat * (apply?(100.0f+m_modifier.m_amount)/100.0f : 100.0f / (100.0f+m_modifier.m_amount));
1951 p_target->SetStat(Stats(i), curStat + baseStat_new - baseStat);
1952 p_target->ApplyCreateStatPercentMod(Stats(i), m_modifier.m_amount, apply );
1957 void Aura::HandleModTotalPercentStat(bool apply)
1959 if (m_modifier.m_miscvalue < -1 || m_modifier.m_miscvalue > 4)
1961 sLog.outError("WARNING: Misc Value for SPELL_AURA_MOD_PERCENT_STAT not valid");
1962 return;
1965 for (int32 i = 0; i < 5; i++)
1967 if(m_modifier.m_miscvalue == i || m_modifier.m_miscvalue == -1)
1969 m_target->ApplyStatPercentMod(Stats(i), m_modifier.m_amount, apply );
1970 if (m_target->GetTypeId() == TYPEID_PLAYER)
1972 ((Player*)m_target)->ApplyPosStatPercentMod(Stats(i), m_modifier.m_amount, apply );
1973 ((Player*)m_target)->ApplyNegStatPercentMod(Stats(i), m_modifier.m_amount, apply );
1974 ((Player*)m_target)->ApplyCreateStatPercentMod(Stats(i), m_modifier.m_amount, apply );
1980 /********************************/
1981 /*** HEAL & ENERGIZE ***/
1982 /********************************/
1984 void Aura::HandleModRegen(bool apply) // eating
1986 if ((GetSpellProto()->AuraInterruptFlags & (1 << 18)) != 0)
1987 m_target->ApplyModFlag(UNIT_FIELD_BYTES_1,PLAYER_STATE_SIT,apply);
1989 if(apply && m_periodicTimer <= 0)
1991 m_periodicTimer += 5000;
1992 if (m_target->GetHealth() + m_modifier.m_amount <= m_target->GetMaxHealth())
1993 m_target->SetHealth(m_target->GetHealth() + m_modifier.m_amount);
1996 m_isPeriodic = apply;
1999 void Aura::HandleModPowerRegen(bool apply) // drinking
2001 if ((GetSpellProto()->AuraInterruptFlags & (1 << 18)) != 0)
2002 m_target->ApplyModFlag(UNIT_FIELD_BYTES_1,PLAYER_STATE_SIT,apply);
2004 if(apply && m_periodicTimer <= 0)
2006 m_periodicTimer += 5000;
2007 Powers pt = m_target->getPowerType();
2008 // Prevent rage regeneration in combat with rage loss slowdown warrior talant and 0<->1 switching range out combat.
2009 if( !(pt == POWER_RAGE && (m_target->isInCombat() || m_target->GetPower(POWER_RAGE) == 0)) )
2011 if (m_target->GetPower(pt) + m_modifier.m_amount <= m_target->GetMaxPower(pt))
2012 m_target->SetPower(pt, m_target->GetPower(pt) + m_modifier.m_amount);
2016 m_isPeriodic = apply;
2019 void Aura::HandleAuraModIncreaseHealth(bool apply)
2021 m_target->ApplyMaxHealthMod(m_modifier.m_amount,apply);
2024 void Aura::HandleAuraModIncreaseEnergy(bool apply)
2026 Powers powerType = m_target->getPowerType();
2027 if(int32(powerType) != m_modifier.m_miscvalue)
2028 return;
2030 uint32 newValue = m_target->GetPower(powerType);
2031 apply ? newValue += m_modifier.m_amount : newValue -= m_modifier.m_amount;
2032 m_target->SetPower(powerType,newValue);
2035 void Aura::HandleAuraModIncreaseEnergyPercent(bool apply)
2037 m_target->ApplyPowerPercentMod(POWER_ENERGY,m_modifier.m_amount,apply);
2040 void Aura::HandleAuraModIncreaseHealthPercent(bool apply)
2042 m_target->ApplyMaxHealthPercentMod(m_modifier.m_amount,apply);
2045 /********************************/
2046 /*** FIGHT ***/
2047 /********************************/
2049 void Aura::HandleAuraModParryPercent(bool apply)
2051 if(m_target->GetTypeId()!=TYPEID_PLAYER)
2052 return;
2054 m_target->ApplyModFloatValue(PLAYER_PARRY_PERCENTAGE,m_modifier.m_amount,apply);
2057 void Aura::HandleAuraModDodgePercent(bool apply)
2059 if(m_target->GetTypeId()!=TYPEID_PLAYER)
2060 return;
2062 m_target->ApplyModFloatValue(PLAYER_DODGE_PERCENTAGE,m_modifier.m_amount,apply);
2065 void Aura::HandleAuraModBlockPercent(bool apply)
2067 if(m_target->GetTypeId()!=TYPEID_PLAYER)
2068 return;
2070 m_target->ApplyModFloatValue(PLAYER_BLOCK_PERCENTAGE,m_modifier.m_amount,apply);
2073 void Aura::HandleAuraModCritPercent(bool apply)
2075 if(m_target->GetTypeId()!=TYPEID_PLAYER)
2076 return;
2078 m_target->ApplyModFloatValue(PLAYER_CRIT_PERCENTAGE,m_modifier.m_amount,apply);
2081 void Aura::HandleModShieldBlock(bool apply)
2083 if(m_target->GetTypeId() != TYPEID_PLAYER)
2084 return;
2086 ((Player*)m_target)->ApplyBlockValueMod(m_modifier.m_amount,apply);
2089 void Aura::HandleModHitChance(bool Apply)
2091 m_target->m_modHitChance = Apply?m_modifier.m_amount:0;
2094 void Aura::HandleModSpellHitChance(bool Apply)
2096 m_target->m_modSpellHitChance = Apply?m_modifier.m_amount:0;
2099 void Aura::HandleModSpellCritChance(bool Apply)
2101 m_target->m_baseSpellCritChance += Apply?m_modifier.m_amount:(-m_modifier.m_amount);
2104 void Aura::HandleModSpellCritChanceShool(bool Apply)
2106 // has no immediate effect when adding / removing
2109 /********************************/
2110 /*** ATTACK SPEED ***/
2111 /********************************/
2113 void Aura::HandleModCastingSpeed(bool apply)
2115 m_target->m_modCastSpeedPct += apply ? m_modifier.m_amount : (-m_modifier.m_amount);
2118 void Aura::HandleModAttackSpeed(bool apply)
2120 if(!m_target || !m_target->isAlive() )
2121 return;
2123 m_target->ApplyAttackTimePercentMod(BASE_ATTACK,m_modifier.m_amount,apply);
2126 void Aura::HandleHaste(bool apply)
2128 m_target->ApplyAttackTimePercentMod(BASE_ATTACK,m_modifier.m_amount,apply);
2129 m_target->ApplyAttackTimePercentMod(OFF_ATTACK,m_modifier.m_amount,apply);
2130 m_target->ApplyAttackTimePercentMod(RANGED_ATTACK,m_modifier.m_amount,apply);
2133 void Aura::HandleRangedAmmoHaste(bool apply)
2135 if(m_target->GetTypeId() != TYPEID_PLAYER)
2136 return;
2137 m_target->ApplyAttackTimePercentMod(RANGED_ATTACK,m_modifier.m_amount, apply);
2140 /********************************/
2141 /*** ATTACK POWER ***/
2142 /********************************/
2144 void Aura::HandleAuraModAttackPower(bool apply)
2146 m_target->ApplyModUInt32Value(UNIT_FIELD_ATTACK_POWER_MODS, m_modifier.m_amount, apply);
2149 void Aura::HandleAuraModRangedAttackPower(bool apply)
2151 m_target->ApplyModUInt32Value(UNIT_FIELD_RANGED_ATTACK_POWER_MODS,m_modifier.m_amount,apply);
2154 /********************************/
2155 /*** DAMAGE BONUS ***/
2156 /********************************/
2158 void Aura::HandleModDamagePCTTaken(bool apply)
2160 m_target->m_modDamagePCT = apply ? m_modifier.m_amount : 0;
2163 void Aura::HandleModPCTRegen(bool apply)
2165 // has no immediate effect when adding / removing
2168 void Aura::HandleModCreatureAttackPower(bool apply)
2170 // has no immediate effect when adding / removing
2173 void Aura::HandleModDamageDoneCreature(bool Apply)
2175 // has no immediate effect when adding / removing
2178 void Aura::HandleModDamageDone(bool apply)
2180 // physical damage modifier is applied to damage fields
2181 if(m_modifier.m_miscvalue & (int32)(1<<SPELL_SCHOOL_NORMAL))
2183 m_target->ApplyModFloatValue(UNIT_FIELD_MINDAMAGE,m_modifier.m_amount,apply);
2184 m_target->ApplyModFloatValue(UNIT_FIELD_MAXDAMAGE,m_modifier.m_amount,apply);
2185 // TODO: add ranged support and maybe offhand ?
2186 // not completely sure how this should work
2187 if(m_target->GetTypeId() == TYPEID_PLAYER)
2189 if(m_modifier.m_miscvalue2)
2190 m_target->ApplyModFloatValue(PLAYER_FIELD_MOD_DAMAGE_DONE_NEG,m_modifier.m_amount,apply);
2191 else
2192 m_target->ApplyModFloatValue(PLAYER_FIELD_MOD_DAMAGE_DONE_POS,m_modifier.m_amount,apply);
2197 void Aura::HandleModDamageTaken(bool apply)
2199 // has no immediate effect when adding / removing
2202 void Aura::HandleModDamagePercentDone(bool apply)
2204 sLog.outDebug("AURA MOD DAMAGE type:%u type2:%u", m_modifier.m_miscvalue, m_modifier.m_miscvalue2);
2206 // FIX ME: This is wrong code.
2207 // It not work with 20218 18791 spells
2209 // m_modifier.m_miscvalue is bitmask of spell schools
2210 // 1 ( 0-bit ) - normal school damage
2211 // 126 - full bitmask all magic damages
2212 // 127 - full bitmask any damages
2214 // mods must be applied base at equiped weapon class amd subclass comparison
2215 // with spell->EquippedItemClass and EquippedItemSubClass
2216 // m_modifier.m_miscvalue comparison with item generated damage types
2218 if(m_modifier.m_miscvalue == 1)
2220 m_target->ApplyPercentModFloatValue(UNIT_FIELD_MINDAMAGE, m_modifier.m_amount, apply );
2221 m_target->ApplyPercentModFloatValue(UNIT_FIELD_MAXDAMAGE, m_modifier.m_amount, apply );
2223 if(m_modifier.m_miscvalue == 126)
2225 m_target->ApplyPercentModFloatValue(UNIT_FIELD_MINOFFHANDDAMAGE, m_modifier.m_amount, apply );
2226 m_target->ApplyPercentModFloatValue(UNIT_FIELD_MAXOFFHANDDAMAGE, m_modifier.m_amount, apply );
2228 if(m_modifier.m_miscvalue == 127)
2230 m_target->ApplyPercentModFloatValue(UNIT_FIELD_MINRANGEDDAMAGE, m_modifier.m_amount, apply );
2231 m_target->ApplyPercentModFloatValue(UNIT_FIELD_MAXRANGEDDAMAGE, m_modifier.m_amount, apply );
2235 /********************************/
2236 /*** POWER COST ***/
2237 /********************************/
2239 void Aura::HandleModPowerCost(bool apply)
2241 m_target->ApplyModUInt32Value(UNIT_FIELD_POWER_COST_MODIFIER, m_modifier.m_amount, apply);
2244 void Aura::HandleModPowerCostSchool(bool apply)
2246 // has no immediate effect when adding / removing
2249 /*********************************************************/
2250 /*** OTHERS ***/
2251 /*********************************************************/
2253 void Aura::HandleModReputationGain(bool apply)
2255 // has no immediate effect when adding / removing
2258 void Aura::SendCoolDownEvent()
2260 Unit* caster = GetCaster();
2261 if(caster)
2263 WorldPacket data;
2264 data.Initialize(SMSG_COOLDOWN_EVENT);
2265 data << uint32(m_spellId) << m_caster_guid;
2266 data << uint32(0); //CoolDown Time ?
2267 caster->SendMessageToSet(&data,true);
2271 // FIX-ME!!
2272 void HandleTriggerSpellEvent(void *obj)
2274 Aura *Aur = ((Aura*)obj);
2275 if(!Aur)
2276 return;
2277 SpellEntry *spellInfo = sSpellStore.LookupEntry(Aur->GetSpellProto()->EffectTriggerSpell[Aur->GetEffIndex()]);
2279 if(!spellInfo)
2281 sLog.outError("WORLD: unknown spell id %i\n", Aur->GetSpellProto()->EffectTriggerSpell[Aur->GetEffIndex()]);
2282 return;
2285 Spell spell(Aur->GetCaster(), spellInfo, true, Aur);
2286 SpellCastTargets targets;
2287 targets.setUnitTarget(Aur->GetTarget());
2288 //WorldPacket dump;
2289 //dump.Initialize(0);
2290 //dump << uint16(2) << GetUInt32Value(UNIT_FIELD_CHANNEL_OBJECT) << GetUInt32Value(UNIT_FIELD_CHANNEL_OBJECT+1);
2291 //targets.read(&dump,this);
2292 spell.prepare(&targets);
2294 /*else if(m_spellProto->EffectApplyAuraName[i] == 23)
2296 unitTarget->tmpAura->SetPeriodicTriggerSpell(m_spellProto->EffectTriggerSpell[i],m_spellProto->EffectAmplitude[i]);
2300 void HandleDOTEvent(void *obj)
2302 Aura *Aur = ((Aura*)obj);
2303 //Aur->GetCaster()->AddPeriodicAura(Aur);
2304 if(Unit* caster = Aur->GetCaster())
2305 caster->PeriodicAuraLog(Aur->GetTarget(), Aur->GetSpellProto(), Aur->GetModifier());
2308 void HandleHealEvent(void *obj)
2310 Aura *Aur = ((Aura*)obj);
2311 if(Unit* caster = Aur->GetCaster())
2312 Aur->GetTarget()->PeriodicAuraLog(caster, Aur->GetSpellProto(), Aur->GetModifier());
2315 void HandleShapeshiftBoosts(bool apply, Aura* aura)
2317 if(!aura->GetTarget())
2318 return;
2320 Unit *unit_target = aura->GetTarget();
2321 /*uint32 spellId = 0;
2322 uint32 spellId2 = 0;
2324 switch(aura->GetModifier()->m_miscvalue)
2326 case FORM_CAT:
2327 spellId = 3025;
2328 break;
2329 case FORM_TREE:
2330 spellId = 3122;
2331 break;
2332 case FORM_TRAVEL:
2333 spellId = 5419;
2334 break;
2335 case FORM_AQUA:
2336 spellId = 5421;
2337 break;
2338 case FORM_BEAR:
2339 spellId = 1178;
2340 break;
2341 case FORM_DIREBEAR:
2342 spellId = 9635;
2343 break;
2344 case FORM_CREATUREBEAR:
2345 spellId = 2882;
2346 break;
2347 case FORM_DEFENSIVESTANCE:
2348 spellId = 7376;
2349 break;
2350 case FORM_BERSERKERSTANCE:
2351 spellId = 7381;
2352 break;
2353 case FORM_MOONKIN:
2354 spellId = 24905;
2355 // aura from effect trigger spell
2356 spellId2 = 24907;
2357 break;
2358 case FORM_GHOSTWOLF:
2359 case FORM_BATTLESTANCE:
2360 case FORM_AMBIENT:
2361 case FORM_GHOUL:
2362 case FORM_SHADOW:
2363 case FORM_STEALTH:
2364 spellId = 0;
2365 break;
2368 SpellEntry *spellInfo = sSpellStore.LookupEntry( spellId );*/
2370 double healthPercentage = (double)unit_target->GetHealth() / (double)unit_target->GetMaxHealth();
2371 uint32 form = aura->GetModifier()->m_miscvalue-1;
2373 if(apply)
2375 if(unit_target->m_ShapeShiftForm)
2377 unit_target->RemoveAurasDueToSpell(unit_target->m_ShapeShiftForm);
2380 if(unit_target->GetTypeId() == TYPEID_PLAYER)
2382 const PlayerSpellMap& sp_list = ((Player *)unit_target)->GetSpellMap();
2383 for (PlayerSpellMap::const_iterator itr = sp_list.begin(); itr != sp_list.end(); ++itr)
2385 if(itr->second->state == PLAYERSPELL_REMOVED) continue;
2386 SpellEntry *spellInfo = sSpellStore.LookupEntry(itr->first);
2387 if (!spellInfo || !IsPassiveSpell(itr->first)) continue;
2388 if (spellInfo->Stances & (1<<form))
2389 unit_target->CastSpell(unit_target, itr->first, true);
2393 if (aura->GetModifier()->m_miscvalue == FORM_TRAVEL)
2394 unit_target->CastSpell(unit_target, 5419, true);
2396 else
2398 Unit::AuraMap& tAuras = unit_target->GetAuras();
2399 for (Unit::AuraMap::iterator itr = tAuras.begin(); itr != tAuras.end();)
2401 if ((*itr).second->GetSpellProto()->Stances & uint32(1<<form))
2402 unit_target->RemoveAura(itr);
2403 else
2404 ++itr;
2407 if (aura->GetModifier()->m_miscvalue == FORM_TRAVEL)
2408 unit_target->RemoveAurasDueToSpell(5419);
2411 unit_target->SetHealth(uint32(ceil((double)unit_target->GetMaxHealth() * healthPercentage)));