[10130] Proper stacking 30108/348 anr ranks from 3.2.x
[getmangos.git] / src / game / SpellMgr.h
blob88fc5ab759b0e8e36cd7d55da34b56c35efd474f
1 /*
2 * Copyright (C) 2005-2010 MaNGOS <http://getmangos.com/>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 #ifndef _SPELLMGR_H
20 #define _SPELLMGR_H
22 // For static or at-server-startup loaded spell data
23 // For more high level function for sSpellStore data
25 #include "SharedDefines.h"
26 #include "SpellAuraDefines.h"
27 #include "DBCStructure.h"
28 #include "DBCStores.h"
29 #include "Database/SQLStorage.h"
31 #include "Utilities/UnorderedMap.h"
33 #include <map>
35 class Player;
36 class Spell;
37 struct SpellModifier;
39 // only used in code
40 enum SpellCategories
42 SPELLCATEGORY_HEALTH_MANA_POTIONS = 4,
43 SPELLCATEGORY_DEVOUR_MAGIC = 12,
44 SPELLCATEGORY_JUDGEMENT = 1210, // Judgement (seal trigger)
47 enum SpellFamilyNames
49 SPELLFAMILY_GENERIC = 0,
50 SPELLFAMILY_UNK1 = 1, // events, holidays
51 // 2 - unused
52 SPELLFAMILY_MAGE = 3,
53 SPELLFAMILY_WARRIOR = 4,
54 SPELLFAMILY_WARLOCK = 5,
55 SPELLFAMILY_PRIEST = 6,
56 SPELLFAMILY_DRUID = 7,
57 SPELLFAMILY_ROGUE = 8,
58 SPELLFAMILY_HUNTER = 9,
59 SPELLFAMILY_PALADIN = 10,
60 SPELLFAMILY_SHAMAN = 11,
61 SPELLFAMILY_UNK2 = 12, // 2 spells (silence resistance)
62 SPELLFAMILY_POTION = 13,
63 // 14 - unused
64 SPELLFAMILY_DEATHKNIGHT = 15,
65 // 16 - unused
66 SPELLFAMILY_PET = 17
69 //Some SpellFamilyFlags
70 #define SPELLFAMILYFLAG_ROGUE_VANISH UI64LIT(0x0000000000000800)
71 #define SPELLFAMILYFLAG_ROGUE_STEALTH UI64LIT(0x0000000000400000)
72 #define SPELLFAMILYFLAG_ROGUE_BACKSTAB UI64LIT(0x0000000000800004)
73 #define SPELLFAMILYFLAG_ROGUE_SAP UI64LIT(0x0000000000000080)
74 #define SPELLFAMILYFLAG_ROGUE_FEINT UI64LIT(0x0000000008000000)
75 #define SPELLFAMILYFLAG_ROGUE_KIDNEYSHOT UI64LIT(0x0000000000200000)
76 #define SPELLFAMILYFLAG_ROGUE__FINISHING_MOVE UI64LIT(0x00000009003E0000)
78 #define SPELLFAMILYFLAG_PALADIN_SEALS UI64LIT(0x26000C000A000000)
80 // Spell clasification
81 enum SpellSpecific
83 SPELL_NORMAL = 0,
84 SPELL_SEAL = 1,
85 SPELL_BLESSING = 2,
86 SPELL_AURA = 3,
87 SPELL_STING = 4,
88 SPELL_CURSE = 5,
89 SPELL_ASPECT = 6,
90 SPELL_TRACKER = 7,
91 SPELL_WARLOCK_ARMOR = 8,
92 SPELL_MAGE_ARMOR = 9,
93 SPELL_ELEMENTAL_SHIELD = 10,
94 SPELL_MAGE_POLYMORPH = 11,
95 SPELL_POSITIVE_SHOUT = 12,
96 SPELL_JUDGEMENT = 13,
97 SPELL_BATTLE_ELIXIR = 14,
98 SPELL_GUARDIAN_ELIXIR = 15,
99 SPELL_FLASK_ELIXIR = 16,
100 SPELL_PRESENCE = 17,
101 SPELL_HAND = 18,
102 SPELL_WELL_FED = 19,
103 SPELL_FOOD = 20,
104 SPELL_DRINK = 21,
105 SPELL_FOOD_AND_DRINK = 22,
106 SPELL_UA_IMMOLATE = 23, // Unstable Affliction and Immolate
109 SpellSpecific GetSpellSpecific(uint32 spellId);
111 // Different spell properties
112 inline float GetSpellRadius(SpellRadiusEntry const *radius) { return (radius ? radius->Radius : 0); }
113 uint32 GetSpellCastTime(SpellEntry const* spellInfo, Spell const* spell = NULL);
114 uint32 GetSpellCastTimeForBonus( SpellEntry const *spellProto, DamageEffectType damagetype );
115 float CalculateDefaultCoefficient(SpellEntry const *spellProto, DamageEffectType const damagetype);
116 inline float GetSpellMinRange(SpellRangeEntry const *range, bool friendly = false)
118 if(!range)
119 return 0;
120 return (friendly ? range->minRangeFriendly : range->minRange);
122 inline float GetSpellMaxRange(SpellRangeEntry const *range, bool friendly = false)
124 if(!range)
125 return 0;
126 return (friendly ? range->maxRangeFriendly : range->maxRange);
128 inline uint32 GetSpellRecoveryTime(SpellEntry const *spellInfo) { return spellInfo->RecoveryTime > spellInfo->CategoryRecoveryTime ? spellInfo->RecoveryTime : spellInfo->CategoryRecoveryTime; }
129 int32 GetSpellDuration(SpellEntry const *spellInfo);
130 int32 GetSpellMaxDuration(SpellEntry const *spellInfo);
131 uint16 GetSpellAuraMaxTicks(SpellEntry const* spellInfo);
132 WeaponAttackType GetWeaponAttackType(SpellEntry const *spellInfo);
134 inline bool IsSpellHaveEffect(SpellEntry const *spellInfo, SpellEffects effect)
136 for(int i = 0; i < MAX_EFFECT_INDEX; ++i)
137 if(SpellEffects(spellInfo->Effect[i])==effect)
138 return true;
139 return false;
142 inline bool IsEffectHandledOnDelayedSpellLaunch(SpellEntry const *spellInfo, SpellEffectIndex effecIdx)
144 switch (spellInfo->Effect[effecIdx])
146 case SPELL_EFFECT_SCHOOL_DAMAGE:
147 case SPELL_EFFECT_WEAPON_DAMAGE_NOSCHOOL:
148 case SPELL_EFFECT_WEAPON_PERCENT_DAMAGE:
149 case SPELL_EFFECT_WEAPON_DAMAGE:
150 case SPELL_EFFECT_NORMALIZED_WEAPON_DMG:
151 return true;
152 default:
153 return false;
157 inline bool IsSpellHaveAura(SpellEntry const *spellInfo, AuraType aura)
159 for(int i = 0; i < MAX_EFFECT_INDEX; ++i)
160 if(AuraType(spellInfo->EffectApplyAuraName[i])==aura)
161 return true;
162 return false;
165 inline bool IsSpellLastAuraEffect(SpellEntry const *spellInfo, SpellEffectIndex effecIdx)
167 for(int i = effecIdx+1; i < MAX_EFFECT_INDEX; ++i)
168 if(spellInfo->EffectApplyAuraName[i])
169 return false;
170 return true;
173 bool IsNoStackAuraDueToAura(uint32 spellId_1, SpellEffectIndex effIndex_1, uint32 spellId_2, SpellEffectIndex effIndex_2);
175 inline bool IsSealSpell(SpellEntry const *spellInfo)
177 //Collection of all the seal family flags. No other paladin spell has any of those.
178 return spellInfo->SpellFamilyName == SPELLFAMILY_PALADIN &&
179 ( spellInfo->SpellFamilyFlags & SPELLFAMILYFLAG_PALADIN_SEALS ) &&
180 // avoid counting target triggered effect as seal for avoid remove it or seal by it.
181 spellInfo->EffectImplicitTargetA[EFFECT_INDEX_0] == TARGET_SELF;
184 inline bool IsElementalShield(SpellEntry const *spellInfo)
186 // family flags 10 (Lightning), 42 (Earth), 37 (Water), proc shield from T2 8 pieces bonus
187 return (spellInfo->SpellFamilyFlags & UI64LIT(0x42000000400)) || spellInfo->Id == 23552;
190 inline bool IsExplicitDiscoverySpell(SpellEntry const *spellInfo)
192 return (((spellInfo->Effect[EFFECT_INDEX_0] == SPELL_EFFECT_CREATE_RANDOM_ITEM
193 || spellInfo->Effect[EFFECT_INDEX_0] == SPELL_EFFECT_CREATE_ITEM_2)
194 && spellInfo->Effect[EFFECT_INDEX_1] == SPELL_EFFECT_SCRIPT_EFFECT)
195 || spellInfo->Id == 64323); // Book of Glyph Mastery (Effect0==SPELL_EFFECT_SCRIPT_EFFECT without any other data)
198 inline bool IsLootCraftingSpell(SpellEntry const *spellInfo)
200 return (spellInfo->Effect[EFFECT_INDEX_0] == SPELL_EFFECT_CREATE_RANDOM_ITEM ||
201 // different random cards from Inscription (121==Virtuoso Inking Set category) r without explicit item
202 (spellInfo->Effect[EFFECT_INDEX_0] == SPELL_EFFECT_CREATE_ITEM_2 &&
203 (spellInfo->TotemCategory[0] != 0 || spellInfo->EffectItemType[0]==0)));
206 int32 CompareAuraRanks(uint32 spellId_1, SpellEffectIndex effIndex_1, uint32 spellId_2, SpellEffectIndex effIndex_2);
208 // order from less to more strict
209 bool IsSingleFromSpellSpecificPerTargetPerCaster(SpellSpecific spellSpec1,SpellSpecific spellSpec2);
210 bool IsSingleFromSpellSpecificSpellRanksPerTarget(SpellSpecific spellSpec1,SpellSpecific spellSpec2);
211 bool IsSingleFromSpellSpecificPerTarget(SpellSpecific spellSpec1,SpellSpecific spellSpec2);
213 bool IsPassiveSpell(uint32 spellId);
214 bool IsPassiveSpell(SpellEntry const* spellProto);
216 inline bool IsPassiveSpellStackableWithRanks(SpellEntry const* spellProto)
218 if(!IsPassiveSpell(spellProto))
219 return false;
221 return !IsSpellHaveEffect(spellProto,SPELL_EFFECT_APPLY_AURA);
224 inline bool IsDeathOnlySpell(SpellEntry const *spellInfo)
226 return spellInfo->AttributesEx3 & SPELL_ATTR_EX3_CAST_ON_DEAD
227 || spellInfo->Id == 2584;
230 inline bool IsDeathPersistentSpell(SpellEntry const *spellInfo)
232 return spellInfo->AttributesEx3 & SPELL_ATTR_EX3_DEATH_PERSISTENT;
235 inline bool IsNonCombatSpell(SpellEntry const *spellInfo)
237 return (spellInfo->Attributes & SPELL_ATTR_CANT_USED_IN_COMBAT) != 0;
240 bool IsPositiveSpell(uint32 spellId);
241 bool IsPositiveEffect(uint32 spellId, SpellEffectIndex effIndex);
242 bool IsPositiveTarget(uint32 targetA, uint32 targetB);
244 bool IsExplicitPositiveTarget(uint32 targetA);
245 bool IsExplicitNegativeTarget(uint32 targetA);
247 bool IsSingleTargetSpell(SpellEntry const *spellInfo);
248 bool IsSingleTargetSpells(SpellEntry const *spellInfo1, SpellEntry const *spellInfo2);
250 inline bool IsCasterSourceTarget(uint32 target)
252 switch (target )
254 case TARGET_SELF:
255 case TARGET_PET:
256 case TARGET_ALL_PARTY_AROUND_CASTER:
257 case TARGET_IN_FRONT_OF_CASTER:
258 case TARGET_MASTER:
259 case TARGET_MINION:
260 case TARGET_ALL_PARTY:
261 case TARGET_ALL_PARTY_AROUND_CASTER_2:
262 case TARGET_SELF_FISHING:
263 case TARGET_TOTEM_EARTH:
264 case TARGET_TOTEM_WATER:
265 case TARGET_TOTEM_AIR:
266 case TARGET_TOTEM_FIRE:
267 case TARGET_AREAEFFECT_CUSTOM_2:
268 case TARGET_ALL_RAID_AROUND_CASTER:
269 case TARGET_SELF2:
270 case TARGET_DIRECTLY_FORWARD:
271 case TARGET_NONCOMBAT_PET:
272 case TARGET_IN_FRONT_OF_CASTER_30:
273 return true;
274 default:
275 break;
277 return false;
280 inline bool IsSpellWithCasterSourceTargetsOnly(SpellEntry const* spellInfo)
282 for(int i = 0; i < MAX_EFFECT_INDEX; ++i)
284 uint32 targetA = spellInfo->EffectImplicitTargetA[i];
285 if(targetA && !IsCasterSourceTarget(targetA))
286 return false;
288 uint32 targetB = spellInfo->EffectImplicitTargetB[i];
289 if(targetB && !IsCasterSourceTarget(targetB))
290 return false;
292 if(!targetA && !targetB)
293 return false;
295 return true;
298 inline bool IsPointEffectTarget( Targets target )
300 switch (target )
302 case TARGET_INNKEEPER_COORDINATES:
303 case TARGET_TABLE_X_Y_Z_COORDINATES:
304 case TARGET_CASTER_COORDINATES:
305 case TARGET_SCRIPT_COORDINATES:
306 case TARGET_CURRENT_ENEMY_COORDINATES:
307 case TARGET_DUELVSPLAYER_COORDINATES:
308 case TARGET_DYNAMIC_OBJECT_COORDINATES:
309 case TARGET_POINT_AT_NORTH:
310 case TARGET_POINT_AT_SOUTH:
311 case TARGET_POINT_AT_EAST:
312 case TARGET_POINT_AT_WEST:
313 case TARGET_POINT_AT_NE:
314 case TARGET_POINT_AT_NW:
315 case TARGET_POINT_AT_SE:
316 case TARGET_POINT_AT_SW:
317 return true;
318 default:
319 break;
321 return false;
324 inline bool IsAreaEffectPossitiveTarget( Targets target )
326 switch (target )
328 case TARGET_ALL_PARTY_AROUND_CASTER:
329 case TARGET_ALL_FRIENDLY_UNITS_AROUND_CASTER:
330 case TARGET_ALL_FRIENDLY_UNITS_IN_AREA:
331 case TARGET_ALL_PARTY:
332 case TARGET_ALL_PARTY_AROUND_CASTER_2:
333 case TARGET_AREAEFFECT_PARTY:
334 case TARGET_ALL_RAID_AROUND_CASTER:
335 case TARGET_AREAEFFECT_PARTY_AND_CLASS:
336 return true;
337 default:
338 break;
340 return false;
343 inline bool IsAreaEffectTarget( Targets target )
345 switch (target )
347 case TARGET_AREAEFFECT_INSTANT:
348 case TARGET_AREAEFFECT_CUSTOM:
349 case TARGET_ALL_ENEMY_IN_AREA:
350 case TARGET_ALL_ENEMY_IN_AREA_INSTANT:
351 case TARGET_ALL_PARTY_AROUND_CASTER:
352 case TARGET_IN_FRONT_OF_CASTER:
353 case TARGET_ALL_ENEMY_IN_AREA_CHANNELED:
354 case TARGET_ALL_FRIENDLY_UNITS_AROUND_CASTER:
355 case TARGET_ALL_FRIENDLY_UNITS_IN_AREA:
356 case TARGET_ALL_PARTY:
357 case TARGET_ALL_PARTY_AROUND_CASTER_2:
358 case TARGET_AREAEFFECT_PARTY:
359 case TARGET_AREAEFFECT_CUSTOM_2:
360 case TARGET_ALL_RAID_AROUND_CASTER:
361 case TARGET_AREAEFFECT_PARTY_AND_CLASS:
362 case TARGET_IN_FRONT_OF_CASTER_30:
363 return true;
364 default:
365 break;
367 return false;
370 inline bool IsAreaOfEffectSpell(SpellEntry const *spellInfo)
372 if(IsAreaEffectTarget(Targets(spellInfo->EffectImplicitTargetA[EFFECT_INDEX_0])) || IsAreaEffectTarget(Targets(spellInfo->EffectImplicitTargetB[EFFECT_INDEX_0])))
373 return true;
374 if(IsAreaEffectTarget(Targets(spellInfo->EffectImplicitTargetA[EFFECT_INDEX_1])) || IsAreaEffectTarget(Targets(spellInfo->EffectImplicitTargetB[EFFECT_INDEX_1])))
375 return true;
376 if(IsAreaEffectTarget(Targets(spellInfo->EffectImplicitTargetA[EFFECT_INDEX_2])) || IsAreaEffectTarget(Targets(spellInfo->EffectImplicitTargetB[EFFECT_INDEX_2])))
377 return true;
378 return false;
381 inline bool IsAreaAuraEffect(uint32 effect)
383 if( effect == SPELL_EFFECT_APPLY_AREA_AURA_PARTY ||
384 effect == SPELL_EFFECT_APPLY_AREA_AURA_RAID ||
385 effect == SPELL_EFFECT_APPLY_AREA_AURA_FRIEND ||
386 effect == SPELL_EFFECT_APPLY_AREA_AURA_ENEMY ||
387 effect == SPELL_EFFECT_APPLY_AREA_AURA_PET ||
388 effect == SPELL_EFFECT_APPLY_AREA_AURA_OWNER)
389 return true;
390 return false;
393 inline bool IsDispelSpell(SpellEntry const *spellInfo)
395 return IsSpellHaveEffect(spellInfo, SPELL_EFFECT_DISPEL);
398 inline bool isSpellBreakStealth(SpellEntry const* spellInfo)
400 return !(spellInfo->AttributesEx & SPELL_ATTR_EX_NOT_BREAK_STEALTH);
403 inline bool IsAutoRepeatRangedSpell(SpellEntry const* spellInfo)
405 return (spellInfo->Attributes & SPELL_ATTR_RANGED) && (spellInfo->AttributesEx2 & SPELL_ATTR_EX2_AUTOREPEAT_FLAG);
408 SpellCastResult GetErrorAtShapeshiftedCast (SpellEntry const *spellInfo, uint32 form);
410 inline bool IsChanneledSpell(SpellEntry const* spellInfo)
412 return (spellInfo->AttributesEx & (SPELL_ATTR_EX_CHANNELED_1 | SPELL_ATTR_EX_CHANNELED_2));
415 inline bool NeedsComboPoints(SpellEntry const* spellInfo)
417 return (spellInfo->AttributesEx & (SPELL_ATTR_EX_REQ_COMBO_POINTS1 | SPELL_ATTR_EX_REQ_COMBO_POINTS2));
420 inline SpellSchoolMask GetSpellSchoolMask(SpellEntry const* spellInfo)
422 return SpellSchoolMask(spellInfo->SchoolMask);
425 inline uint32 GetSpellMechanicMask(SpellEntry const* spellInfo, int32 effect)
427 uint32 mask = 0;
428 if (spellInfo->Mechanic)
429 mask |= 1 << (spellInfo->Mechanic - 1);
430 if (spellInfo->EffectMechanic[effect])
431 mask |= 1 << (spellInfo->EffectMechanic[effect] - 1);
432 return mask;
435 inline uint32 GetAllSpellMechanicMask(SpellEntry const* spellInfo)
437 uint32 mask = 0;
438 if (spellInfo->Mechanic)
439 mask |= 1 << (spellInfo->Mechanic - 1);
440 for (int i=0; i< MAX_EFFECT_INDEX; ++i)
441 if (spellInfo->EffectMechanic[i])
442 mask |= 1 << (spellInfo->EffectMechanic[i]-1);
443 return mask;
446 inline Mechanics GetEffectMechanic(SpellEntry const* spellInfo, SpellEffectIndex effect)
448 if (spellInfo->EffectMechanic[effect])
449 return Mechanics(spellInfo->EffectMechanic[effect]);
450 if (spellInfo->Mechanic)
451 return Mechanics(spellInfo->Mechanic);
452 return MECHANIC_NONE;
455 inline uint32 GetDispellMask(DispelType dispel)
457 // If dispell all
458 if (dispel == DISPEL_ALL)
459 return DISPEL_ALL_MASK;
460 else
461 return (1 << dispel);
464 // Diminishing Returns interaction with spells
465 DiminishingGroup GetDiminishingReturnsGroupForSpell(SpellEntry const* spellproto, bool triggered);
466 bool IsDiminishingReturnsGroupDurationLimited(DiminishingGroup group);
467 DiminishingReturnsType GetDiminishingReturnsGroupType(DiminishingGroup group);
468 int32 GetDiminishingReturnsLimitDuration(DiminishingGroup group, SpellEntry const* spellproto);
470 SpellEntry const* GetSpellEntryByDifficulty(uint32 id, Difficulty difficulty);
472 // Spell proc event related declarations (accessed using SpellMgr functions)
473 enum ProcFlags
475 PROC_FLAG_NONE = 0x00000000,
477 PROC_FLAG_KILLED = 0x00000001, // 00 Killed by aggressor
478 PROC_FLAG_KILL = 0x00000002, // 01 Kill target (in most cases need XP/Honor reward, see Unit::IsTriggeredAtSpellProcEvent for additinoal check)
480 PROC_FLAG_SUCCESSFUL_MELEE_HIT = 0x00000004, // 02 Successful melee auto attack
481 PROC_FLAG_TAKEN_MELEE_HIT = 0x00000008, // 03 Taken damage from melee auto attack hit
483 PROC_FLAG_SUCCESSFUL_MELEE_SPELL_HIT = 0x00000010, // 04 Successful attack by Spell that use melee weapon
484 PROC_FLAG_TAKEN_MELEE_SPELL_HIT = 0x00000020, // 05 Taken damage by Spell that use melee weapon
486 PROC_FLAG_SUCCESSFUL_RANGED_HIT = 0x00000040, // 06 Successful Ranged auto attack
487 PROC_FLAG_TAKEN_RANGED_HIT = 0x00000080, // 07 Taken damage from ranged auto attack
489 PROC_FLAG_SUCCESSFUL_RANGED_SPELL_HIT = 0x00000100, // 08 Successful Ranged attack by Spell that use ranged weapon
490 PROC_FLAG_TAKEN_RANGED_SPELL_HIT = 0x00000200, // 09 Taken damage by Spell that use ranged weapon
492 PROC_FLAG_SUCCESSFUL_POSITIVE_AOE_HIT = 0x00000400, // 10 Successful AoE (not 100% shure unused)
493 PROC_FLAG_TAKEN_POSITIVE_AOE = 0x00000800, // 11 Taken AoE (not 100% shure unused)
495 PROC_FLAG_SUCCESSFUL_AOE_SPELL_HIT = 0x00001000, // 12 Successful AoE damage spell hit (not 100% shure unused)
496 PROC_FLAG_TAKEN_AOE_SPELL_HIT = 0x00002000, // 13 Taken AoE damage spell hit (not 100% shure unused)
498 PROC_FLAG_SUCCESSFUL_POSITIVE_SPELL = 0x00004000, // 14 Successful cast positive spell (by default only on healing)
499 PROC_FLAG_TAKEN_POSITIVE_SPELL = 0x00008000, // 15 Taken positive spell hit (by default only on healing)
501 PROC_FLAG_SUCCESSFUL_NEGATIVE_SPELL_HIT = 0x00010000, // 16 Successful negative spell cast (by default only on damage)
502 PROC_FLAG_TAKEN_NEGATIVE_SPELL_HIT = 0x00020000, // 17 Taken negative spell (by default only on damage)
504 PROC_FLAG_ON_DO_PERIODIC = 0x00040000, // 18 Successful do periodic (damage / healing, determined from 14-17 flags)
505 PROC_FLAG_ON_TAKE_PERIODIC = 0x00080000, // 19 Taken spell periodic (damage / healing, determined from 14-17 flags)
507 PROC_FLAG_TAKEN_ANY_DAMAGE = 0x00100000, // 20 Taken any damage
508 PROC_FLAG_ON_TRAP_ACTIVATION = 0x00200000, // 21 On trap activation
510 PROC_FLAG_TAKEN_OFFHAND_HIT = 0x00400000, // 22 Taken off-hand melee attacks(not used)
511 PROC_FLAG_SUCCESSFUL_OFFHAND_HIT = 0x00800000 // 23 Successful off-hand melee attacks
514 #define MELEE_BASED_TRIGGER_MASK (PROC_FLAG_SUCCESSFUL_MELEE_HIT | \
515 PROC_FLAG_TAKEN_MELEE_HIT | \
516 PROC_FLAG_SUCCESSFUL_MELEE_SPELL_HIT | \
517 PROC_FLAG_TAKEN_MELEE_SPELL_HIT | \
518 PROC_FLAG_SUCCESSFUL_RANGED_HIT | \
519 PROC_FLAG_TAKEN_RANGED_HIT | \
520 PROC_FLAG_SUCCESSFUL_RANGED_SPELL_HIT | \
521 PROC_FLAG_TAKEN_RANGED_SPELL_HIT)
523 #define NEGATIVE_TRIGGER_MASK (MELEE_BASED_TRIGGER_MASK | \
524 PROC_FLAG_SUCCESSFUL_AOE_SPELL_HIT | \
525 PROC_FLAG_TAKEN_AOE_SPELL_HIT | \
526 PROC_FLAG_SUCCESSFUL_NEGATIVE_SPELL_HIT | \
527 PROC_FLAG_TAKEN_NEGATIVE_SPELL_HIT)
529 enum ProcFlagsEx
531 PROC_EX_NONE = 0x0000000, // If none can tigger on Hit/Crit only (passive spells MUST defined by SpellFamily flag)
532 PROC_EX_NORMAL_HIT = 0x0000001, // If set only from normal hit (only damage spells)
533 PROC_EX_CRITICAL_HIT = 0x0000002,
534 PROC_EX_MISS = 0x0000004,
535 PROC_EX_RESIST = 0x0000008,
536 PROC_EX_DODGE = 0x0000010,
537 PROC_EX_PARRY = 0x0000020,
538 PROC_EX_BLOCK = 0x0000040,
539 PROC_EX_EVADE = 0x0000080,
540 PROC_EX_IMMUNE = 0x0000100,
541 PROC_EX_DEFLECT = 0x0000200,
542 PROC_EX_ABSORB = 0x0000400,
543 PROC_EX_REFLECT = 0x0000800,
544 PROC_EX_INTERRUPT = 0x0001000, // Melee hit result can be Interrupt (not used)
545 PROC_EX_FULL_BLOCK = 0x0002000, // block al attack damage
546 PROC_EX_RESERVED2 = 0x0004000,
547 PROC_EX_RESERVED3 = 0x0008000,
548 PROC_EX_EX_TRIGGER_ALWAYS = 0x0010000, // If set trigger always ( no matter another flags) used for drop charges
549 PROC_EX_EX_ONE_TIME_TRIGGER = 0x0020000 // If set trigger always but only one time (not used)
552 struct SpellProcEventEntry
554 uint32 schoolMask; // if nonzero - bit mask for matching proc condition based on spell candidate's school: Fire=2, Mask=1<<(2-1)=2
555 uint32 spellFamilyName; // if nonzero - for matching proc condition based on candidate spell's SpellFamilyNamer value
556 uint64 spellFamilyMask; // if nonzero - for matching proc condition based on candidate spell's SpellFamilyFlags (like auras 107 and 108 do)
557 uint32 spellFamilyMask2; // if nonzero - for matching proc condition based on candidate spell's SpellFamilyFlags2 (like auras 107 and 108 do)
558 uint32 procFlags; // bitmask for matching proc event
559 uint32 procEx; // proc Extend info (see ProcFlagsEx)
560 float ppmRate; // for melee (ranged?) damage spells - proc rate per minute. if zero, falls back to flat chance from Spell.dbc
561 float customChance; // Owerride chance (in most cases for debug only)
562 uint32 cooldown; // hidden cooldown used for some spell proc events, applied to _triggered_spell_
565 struct SpellBonusEntry
567 float direct_damage;
568 float dot_damage;
569 float ap_bonus;
572 typedef UNORDERED_MAP<uint32, SpellProcEventEntry> SpellProcEventMap;
573 typedef UNORDERED_MAP<uint32, SpellBonusEntry> SpellBonusMap;
575 #define ELIXIR_BATTLE_MASK 0x01
576 #define ELIXIR_GUARDIAN_MASK 0x02
577 #define ELIXIR_FLASK_MASK (ELIXIR_BATTLE_MASK|ELIXIR_GUARDIAN_MASK)
578 #define ELIXIR_UNSTABLE_MASK 0x04
579 #define ELIXIR_SHATTRATH_MASK 0x08
580 #define ELIXIR_WELL_FED 0x10 // Some foods have SPELLFAMILY_POTION
582 typedef std::map<uint32, uint8> SpellElixirMap;
583 typedef std::map<uint32, float> SpellProcItemEnchantMap;
584 typedef std::map<uint32, uint16> SpellThreatMap;
586 // Spell script target related declarations (accessed using SpellMgr functions)
587 enum SpellTargetType
589 SPELL_TARGET_TYPE_GAMEOBJECT = 0,
590 SPELL_TARGET_TYPE_CREATURE = 1,
591 SPELL_TARGET_TYPE_DEAD = 2
594 #define MAX_SPELL_TARGET_TYPE 3
596 struct SpellTargetEntry
598 SpellTargetEntry(SpellTargetType type_,uint32 targetEntry_) : type(type_), targetEntry(targetEntry_) {}
599 SpellTargetType type;
600 uint32 targetEntry;
603 typedef std::multimap<uint32,SpellTargetEntry> SpellScriptTarget;
604 typedef std::pair<SpellScriptTarget::const_iterator,SpellScriptTarget::const_iterator> SpellScriptTargetBounds;
606 // coordinates for spells (accessed using SpellMgr functions)
607 struct SpellTargetPosition
609 uint32 target_mapId;
610 float target_X;
611 float target_Y;
612 float target_Z;
613 float target_Orientation;
616 typedef UNORDERED_MAP<uint32, SpellTargetPosition> SpellTargetPositionMap;
618 // Spell pet auras
619 class PetAura
621 public:
622 PetAura()
624 auras.clear();
627 PetAura(uint32 petEntry, uint32 aura, bool _removeOnChangePet, int _damage) :
628 removeOnChangePet(_removeOnChangePet), damage(_damage)
630 auras[petEntry] = aura;
633 uint32 GetAura(uint32 petEntry) const
635 std::map<uint32, uint32>::const_iterator itr = auras.find(petEntry);
636 if(itr != auras.end())
637 return itr->second;
638 else
640 std::map<uint32, uint32>::const_iterator itr2 = auras.find(0);
641 if(itr2 != auras.end())
642 return itr2->second;
643 else
644 return 0;
648 void AddAura(uint32 petEntry, uint32 aura)
650 auras[petEntry] = aura;
653 bool IsRemovedOnChangePet() const
655 return removeOnChangePet;
658 int32 GetDamage() const
660 return damage;
663 private:
664 std::map<uint32, uint32> auras;
665 bool removeOnChangePet;
666 int32 damage;
668 typedef std::map<uint32, PetAura> SpellPetAuraMap;
670 struct SpellArea
672 uint32 spellId;
673 uint32 areaId; // zone/subzone/or 0 is not limited to zone
674 uint32 questStart; // quest start (quest must be active or rewarded for spell apply)
675 uint32 questEnd; // quest end (quest don't must be rewarded for spell apply)
676 int32 auraSpell; // spell aura must be applied for spell apply )if possitive) and it don't must be applied in other case
677 uint32 raceMask; // can be applied only to races
678 Gender gender; // can be applied only to gender
679 bool questStartCanActive; // if true then quest start can be active (not only rewarded)
680 bool autocast; // if true then auto applied at area enter, in other case just allowed to cast
682 // helpers
683 bool IsFitToRequirements(Player const* player, uint32 newZone, uint32 newArea) const;
686 typedef std::multimap<uint32,SpellArea> SpellAreaMap;
687 typedef std::multimap<uint32,SpellArea const*> SpellAreaForQuestMap;
688 typedef std::multimap<uint32,SpellArea const*> SpellAreaForAuraMap;
689 typedef std::multimap<uint32,SpellArea const*> SpellAreaForAreaMap;
690 typedef std::pair<SpellAreaMap::const_iterator,SpellAreaMap::const_iterator> SpellAreaMapBounds;
691 typedef std::pair<SpellAreaForQuestMap::const_iterator,SpellAreaForQuestMap::const_iterator> SpellAreaForQuestMapBounds;
692 typedef std::pair<SpellAreaForAuraMap::const_iterator, SpellAreaForAuraMap::const_iterator> SpellAreaForAuraMapBounds;
693 typedef std::pair<SpellAreaForAreaMap::const_iterator, SpellAreaForAreaMap::const_iterator> SpellAreaForAreaMapBounds;
696 // Spell rank chain (accessed using SpellMgr functions)
697 struct SpellChainNode
699 uint32 prev;
700 uint32 first;
701 uint32 req;
702 uint8 rank;
705 typedef UNORDERED_MAP<uint32, SpellChainNode> SpellChainMap;
706 typedef std::multimap<uint32, uint32> SpellChainMapNext;
708 // Spell learning properties (accessed using SpellMgr functions)
709 struct SpellLearnSkillNode
711 uint16 skill;
712 uint16 step;
713 uint16 value; // 0 - max skill value for player level
714 uint16 maxvalue; // 0 - max skill value for player level
717 typedef std::map<uint32, SpellLearnSkillNode> SpellLearnSkillMap;
719 struct SpellLearnSpellNode
721 uint32 spell;
722 bool active; // show in spellbook or not
723 bool autoLearned;
726 typedef std::multimap<uint32, SpellLearnSpellNode> SpellLearnSpellMap;
727 typedef std::pair<SpellLearnSpellMap::const_iterator,SpellLearnSpellMap::const_iterator> SpellLearnSpellMapBounds;
729 typedef std::multimap<uint32, SkillLineAbilityEntry const*> SkillLineAbilityMap;
730 typedef std::pair<SkillLineAbilityMap::const_iterator,SkillLineAbilityMap::const_iterator> SkillLineAbilityMapBounds;
732 typedef std::multimap<uint32, uint32> PetLevelupSpellSet;
733 typedef std::map<uint32, PetLevelupSpellSet> PetLevelupSpellMap;
735 struct PetDefaultSpellsEntry
737 uint32 spellid[MAX_CREATURE_SPELL_DATA_SLOT];
740 // < 0 for petspelldata id, > 0 for creature_id
741 typedef std::map<int32, PetDefaultSpellsEntry> PetDefaultSpellsMap;
744 inline bool IsPrimaryProfessionSkill(uint32 skill)
746 SkillLineEntry const *pSkill = sSkillLineStore.LookupEntry(skill);
747 if(!pSkill)
748 return false;
750 if(pSkill->categoryId != SKILL_CATEGORY_PROFESSION)
751 return false;
753 return true;
756 inline bool IsProfessionSkill(uint32 skill)
758 return IsPrimaryProfessionSkill(skill) || skill == SKILL_FISHING || skill == SKILL_COOKING || skill == SKILL_FIRST_AID;
761 inline bool IsProfessionOrRidingSkill(uint32 skill)
763 return IsProfessionSkill(skill) || skill == SKILL_RIDING;
766 class SpellMgr
768 friend struct DoSpellBonuses;
769 friend struct DoSpellProcEvent;
770 friend struct DoSpellProcItemEnchant;
772 // Constructors
773 public:
774 SpellMgr();
775 ~SpellMgr();
777 // Accessors (const or static functions)
778 public:
780 SpellElixirMap const& GetSpellElixirMap() const { return mSpellElixirs; }
782 uint32 GetSpellElixirMask(uint32 spellid) const
784 SpellElixirMap::const_iterator itr = mSpellElixirs.find(spellid);
785 if(itr==mSpellElixirs.end())
786 return 0x0;
788 return itr->second;
791 SpellSpecific GetSpellElixirSpecific(uint32 spellid) const
793 uint32 mask = GetSpellElixirMask(spellid);
794 if((mask & ELIXIR_FLASK_MASK)==ELIXIR_FLASK_MASK)
795 return SPELL_FLASK_ELIXIR;
796 else if(mask & ELIXIR_BATTLE_MASK)
797 return SPELL_BATTLE_ELIXIR;
798 else if(mask & ELIXIR_GUARDIAN_MASK)
799 return SPELL_GUARDIAN_ELIXIR;
800 else if(mask & ELIXIR_WELL_FED)
801 return SPELL_WELL_FED;
802 else
803 return SPELL_NORMAL;
806 uint16 GetSpellThreat(uint32 spellid) const
808 SpellThreatMap::const_iterator itr = mSpellThreatMap.find(spellid);
809 if(itr==mSpellThreatMap.end())
810 return 0;
812 return itr->second;
815 // Spell proc events
816 SpellProcEventEntry const* GetSpellProcEvent(uint32 spellId) const
818 SpellProcEventMap::const_iterator itr = mSpellProcEventMap.find(spellId);
819 if( itr != mSpellProcEventMap.end( ) )
820 return &itr->second;
821 return NULL;
824 // Spell procs from item enchants
825 float GetItemEnchantProcChance(uint32 spellid) const
827 SpellProcItemEnchantMap::const_iterator itr = mSpellProcItemEnchantMap.find(spellid);
828 if(itr==mSpellProcItemEnchantMap.end())
829 return 0.0f;
831 return itr->second;
834 static bool IsSpellProcEventCanTriggeredBy( SpellProcEventEntry const * spellProcEvent, uint32 EventProcFlag, SpellEntry const * procSpell, uint32 procFlags, uint32 procExtra, bool active);
836 // Spell bonus data
837 SpellBonusEntry const* GetSpellBonusData(uint32 spellId) const
839 // Lookup data
840 SpellBonusMap::const_iterator itr = mSpellBonusMap.find(spellId);
841 if( itr != mSpellBonusMap.end( ) )
842 return &itr->second;
844 return NULL;
847 // Spell target coordinates
848 SpellTargetPosition const* GetSpellTargetPosition(uint32 spell_id) const
850 SpellTargetPositionMap::const_iterator itr = mSpellTargetPositions.find( spell_id );
851 if( itr != mSpellTargetPositions.end( ) )
852 return &itr->second;
853 return NULL;
856 // Spell ranks chains
857 SpellChainNode const* GetSpellChainNode(uint32 spell_id) const
859 SpellChainMap::const_iterator itr = mSpellChains.find(spell_id);
860 if(itr == mSpellChains.end())
861 return NULL;
863 return &itr->second;
866 uint32 GetFirstSpellInChain(uint32 spell_id) const
868 if(SpellChainNode const* node = GetSpellChainNode(spell_id))
869 return node->first;
871 return spell_id;
874 uint32 GetPrevSpellInChain(uint32 spell_id) const
876 if(SpellChainNode const* node = GetSpellChainNode(spell_id))
877 return node->prev;
879 return 0;
882 SpellChainMapNext const& GetSpellChainNext() const { return mSpellChainsNext; }
884 template<typename Worker>
885 void doForHighRanks(uint32 spellid, Worker& worker)
887 SpellChainMapNext const& nextMap = GetSpellChainNext();
888 for(SpellChainMapNext::const_iterator itr = nextMap.lower_bound(spellid); itr != nextMap.upper_bound(spellid); ++itr)
890 worker(itr->second);
891 doForHighRanks(itr->second,worker);
895 // Note: not use rank for compare to spell ranks: spell chains isn't linear order
896 // Use IsHighRankOfSpell instead
897 uint8 GetSpellRank(uint32 spell_id) const
899 if(SpellChainNode const* node = GetSpellChainNode(spell_id))
900 return node->rank;
902 return 0;
905 uint8 IsHighRankOfSpell(uint32 spell1,uint32 spell2) const
907 SpellChainMap::const_iterator itr = mSpellChains.find(spell1);
909 uint32 rank2 = GetSpellRank(spell2);
911 // not ordered correctly by rank value
912 if(itr == mSpellChains.end() || !rank2 || itr->second.rank <= rank2)
913 return false;
915 // check present in same rank chain
916 for(; itr != mSpellChains.end(); itr = mSpellChains.find(itr->second.prev))
917 if(itr->second.prev==spell2)
918 return true;
920 return false;
923 bool IsRankSpellDueToSpell(SpellEntry const *spellInfo_1,uint32 spellId_2) const;
924 static bool canStackSpellRanks(SpellEntry const *spellInfo);
925 bool IsNoStackSpellDueToSpell(uint32 spellId_1, uint32 spellId_2) const;
927 SpellEntry const* SelectAuraRankForLevel(SpellEntry const* spellInfo, uint32 Level) const;
929 // Spell learning
930 SpellLearnSkillNode const* GetSpellLearnSkill(uint32 spell_id) const
932 SpellLearnSkillMap::const_iterator itr = mSpellLearnSkills.find(spell_id);
933 if(itr != mSpellLearnSkills.end())
934 return &itr->second;
935 else
936 return NULL;
939 bool IsSpellLearnSpell(uint32 spell_id) const
941 return mSpellLearnSpells.find(spell_id) != mSpellLearnSpells.end();
944 SpellLearnSpellMapBounds GetSpellLearnSpellMapBounds(uint32 spell_id) const
946 return SpellLearnSpellMapBounds(mSpellLearnSpells.lower_bound(spell_id),mSpellLearnSpells.upper_bound(spell_id));
949 bool IsSpellLearnToSpell(uint32 spell_id1,uint32 spell_id2) const
951 SpellLearnSpellMapBounds bounds = GetSpellLearnSpellMapBounds(spell_id1);
952 for(SpellLearnSpellMap::const_iterator i = bounds.first; i != bounds.second; ++i)
953 if (i->second.spell==spell_id2)
954 return true;
955 return false;
958 static bool IsProfessionOrRidingSpell(uint32 spellId);
959 static bool IsProfessionSpell(uint32 spellId);
960 static bool IsPrimaryProfessionSpell(uint32 spellId);
961 bool IsPrimaryProfessionFirstRankSpell(uint32 spellId) const;
963 bool IsSkillBonusSpell(uint32 spellId) const;
966 // Spell script targets
967 SpellScriptTargetBounds GetSpellScriptTargetBounds(uint32 spell_id) const
969 return SpellScriptTargetBounds(mSpellScriptTarget.lower_bound(spell_id),mSpellScriptTarget.upper_bound(spell_id));
972 // Spell correctess for client using
973 static bool IsSpellValid(SpellEntry const * spellInfo, Player* pl = NULL, bool msg = true);
975 SkillLineAbilityMapBounds GetSkillLineAbilityMapBounds(uint32 spell_id) const
977 return SkillLineAbilityMapBounds(mSkillLineAbilityMap.lower_bound(spell_id),mSkillLineAbilityMap.upper_bound(spell_id));
980 PetAura const* GetPetAura(uint32 spell_id, SpellEffectIndex eff)
982 SpellPetAuraMap::const_iterator itr = mSpellPetAuraMap.find((spell_id<<8) + eff);
983 if(itr != mSpellPetAuraMap.end())
984 return &itr->second;
985 else
986 return NULL;
989 PetLevelupSpellSet const* GetPetLevelupSpellList(uint32 petFamily) const
991 PetLevelupSpellMap::const_iterator itr = mPetLevelupSpellMap.find(petFamily);
992 if(itr != mPetLevelupSpellMap.end())
993 return &itr->second;
994 else
995 return NULL;
998 // < 0 for petspelldata id, > 0 for creature_id
999 PetDefaultSpellsEntry const* GetPetDefaultSpellsEntry(int32 id) const
1001 PetDefaultSpellsMap::const_iterator itr = mPetDefaultSpellsMap.find(id);
1002 if(itr != mPetDefaultSpellsMap.end())
1003 return &itr->second;
1004 return NULL;
1007 SpellCastResult GetSpellAllowedInLocationError(SpellEntry const *spellInfo, uint32 map_id, uint32 zone_id, uint32 area_id, Player const* player = NULL);
1009 SpellAreaMapBounds GetSpellAreaMapBounds(uint32 spell_id) const
1011 return SpellAreaMapBounds(mSpellAreaMap.lower_bound(spell_id),mSpellAreaMap.upper_bound(spell_id));
1014 SpellAreaForQuestMapBounds GetSpellAreaForQuestMapBounds(uint32 quest_id, bool active) const
1016 if(active)
1017 return SpellAreaForQuestMapBounds(mSpellAreaForActiveQuestMap.lower_bound(quest_id),mSpellAreaForActiveQuestMap.upper_bound(quest_id));
1018 else
1019 return SpellAreaForQuestMapBounds(mSpellAreaForQuestMap.lower_bound(quest_id),mSpellAreaForQuestMap.upper_bound(quest_id));
1022 SpellAreaForQuestMapBounds GetSpellAreaForQuestEndMapBounds(uint32 quest_id) const
1024 return SpellAreaForQuestMapBounds(mSpellAreaForQuestEndMap.lower_bound(quest_id),mSpellAreaForQuestEndMap.upper_bound(quest_id));
1027 SpellAreaForAuraMapBounds GetSpellAreaForAuraMapBounds(uint32 spell_id) const
1029 return SpellAreaForAuraMapBounds(mSpellAreaForAuraMap.lower_bound(spell_id),mSpellAreaForAuraMap.upper_bound(spell_id));
1032 SpellAreaForAreaMapBounds GetSpellAreaForAreaMapBounds(uint32 area_id) const
1034 return SpellAreaForAreaMapBounds(mSpellAreaForAreaMap.lower_bound(area_id),mSpellAreaForAreaMap.upper_bound(area_id));
1037 // Modifiers
1038 public:
1039 static SpellMgr& Instance();
1041 void CheckUsedSpells(char const* table);
1043 // Loading data at server startup
1044 void LoadSpellChains();
1045 void LoadSpellLearnSkills();
1046 void LoadSpellLearnSpells();
1047 void LoadSpellScriptTarget();
1048 void LoadSpellElixirs();
1049 void LoadSpellProcEvents();
1050 void LoadSpellProcItemEnchant();
1051 void LoadSpellBonuses();
1052 void LoadSpellTargetPositions();
1053 void LoadSpellThreats();
1054 void LoadSkillLineAbilityMap();
1055 void LoadSpellPetAuras();
1056 void LoadPetLevelupSpellMap();
1057 void LoadPetDefaultSpells();
1058 void LoadSpellAreas();
1060 private:
1061 SpellScriptTarget mSpellScriptTarget;
1062 SpellChainMap mSpellChains;
1063 SpellChainMapNext mSpellChainsNext;
1064 SpellLearnSkillMap mSpellLearnSkills;
1065 SpellLearnSpellMap mSpellLearnSpells;
1066 SpellTargetPositionMap mSpellTargetPositions;
1067 SpellElixirMap mSpellElixirs;
1068 SpellThreatMap mSpellThreatMap;
1069 SpellProcEventMap mSpellProcEventMap;
1070 SpellProcItemEnchantMap mSpellProcItemEnchantMap;
1071 SpellBonusMap mSpellBonusMap;
1072 SkillLineAbilityMap mSkillLineAbilityMap;
1073 SpellPetAuraMap mSpellPetAuraMap;
1074 PetLevelupSpellMap mPetLevelupSpellMap;
1075 PetDefaultSpellsMap mPetDefaultSpellsMap; // only spells not listed in related mPetLevelupSpellMap entry
1076 SpellAreaMap mSpellAreaMap;
1077 SpellAreaForQuestMap mSpellAreaForQuestMap;
1078 SpellAreaForQuestMap mSpellAreaForActiveQuestMap;
1079 SpellAreaForQuestMap mSpellAreaForQuestEndMap;
1080 SpellAreaForAuraMap mSpellAreaForAuraMap;
1081 SpellAreaForAreaMap mSpellAreaForAreaMap;
1084 #define sSpellMgr SpellMgr::Instance()
1085 #endif