root/trunk/src/game/SpellMgr.h @ 122

Revision 122, 35.2 kB (checked in by yumileroy, 17 years ago)

[svn] Fix a compile error about M_PI_2.
Update Felmyst script to test new setActive function.
Fix the bug that priest's fear is unbreakable (dirty hack before find the correct way).
(some unfinished unused content included, just ignore them, will finish them later)

Original author: megamage
Date: 2008-10-27 10:57:53-05:00

Line 
1/*
2 * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
3 *
4 * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21#ifndef _SPELLMGR_H
22#define _SPELLMGR_H
23
24// For static or at-server-startup loaded spell data
25// For more high level function for sSpellStore data
26
27#include "SharedDefines.h"
28#include "Database/DBCStructure.h"
29#include "Database/SQLStorage.h"
30
31#include "Utilities/HashMap.h"
32#include <map>
33
34class Player;
35class Spell;
36
37extern SQLStorage sSpellThreatStore;
38
39enum SpellFailedReason
40{
41    SPELL_FAILED_AFFECTING_COMBAT               = 0x00,
42    SPELL_FAILED_ALREADY_AT_FULL_HEALTH         = 0x01,
43    SPELL_FAILED_ALREADY_AT_FULL_MANA           = 0x02,
44    SPELL_FAILED_ALREADY_AT_FULL_POWER          = 0x03,
45    SPELL_FAILED_ALREADY_BEING_TAMED            = 0x04,
46    SPELL_FAILED_ALREADY_HAVE_CHARM             = 0x05,
47    SPELL_FAILED_ALREADY_HAVE_SUMMON            = 0x06,
48    SPELL_FAILED_ALREADY_OPEN                   = 0x07,
49    SPELL_FAILED_AURA_BOUNCED                   = 0x08,
50    SPELL_FAILED_AUTOTRACK_INTERRUPTED          = 0x09,
51    SPELL_FAILED_BAD_IMPLICIT_TARGETS           = 0x0A,
52    SPELL_FAILED_BAD_TARGETS                    = 0x0B,
53    SPELL_FAILED_CANT_BE_CHARMED                = 0x0C,
54    SPELL_FAILED_CANT_BE_DISENCHANTED           = 0x0D,
55    SPELL_FAILED_CANT_BE_DISENCHANTED_SKILL     = 0x0E,
56    SPELL_FAILED_CANT_BE_PROSPECTED             = 0x0F,
57    SPELL_FAILED_CANT_CAST_ON_TAPPED            = 0x10,
58    SPELL_FAILED_CANT_DUEL_WHILE_INVISIBLE      = 0x11,
59    SPELL_FAILED_CANT_DUEL_WHILE_STEALTHED      = 0x12,
60    SPELL_FAILED_CANT_STEALTH                   = 0x13,
61    SPELL_FAILED_CASTER_AURASTATE               = 0x14,
62    SPELL_FAILED_CASTER_DEAD                    = 0x15,
63    SPELL_FAILED_CHARMED                        = 0x16,
64    SPELL_FAILED_CHEST_IN_USE                   = 0x17,
65    SPELL_FAILED_CONFUSED                       = 0x18,
66    SPELL_FAILED_DONT_REPORT                    = 0x19,
67    SPELL_FAILED_EQUIPPED_ITEM                  = 0x1A,
68    SPELL_FAILED_EQUIPPED_ITEM_CLASS            = 0x1B,
69    SPELL_FAILED_EQUIPPED_ITEM_CLASS_MAINHAND   = 0x1C,
70    SPELL_FAILED_EQUIPPED_ITEM_CLASS_OFFHAND    = 0x1D,
71    SPELL_FAILED_ERROR                          = 0x1E,
72    SPELL_FAILED_FIZZLE                         = 0x1F,
73    SPELL_FAILED_FLEEING                        = 0x20,
74    SPELL_FAILED_FOOD_LOWLEVEL                  = 0x21,
75    SPELL_FAILED_HIGHLEVEL                      = 0x22,
76    SPELL_FAILED_HUNGER_SATIATED                = 0x23,
77    SPELL_FAILED_IMMUNE                         = 0x24,
78    SPELL_FAILED_INTERRUPTED                    = 0x25,
79    SPELL_FAILED_INTERRUPTED_COMBAT             = 0x26,
80    SPELL_FAILED_ITEM_ALREADY_ENCHANTED         = 0x27,
81    SPELL_FAILED_ITEM_GONE                      = 0x28,
82    SPELL_FAILED_ITEM_NOT_FOUND                 = 0x29,
83    SPELL_FAILED_ITEM_NOT_READY                 = 0x2A,
84    SPELL_FAILED_LEVEL_REQUIREMENT              = 0x2B,
85    SPELL_FAILED_LINE_OF_SIGHT                  = 0x2C,
86    SPELL_FAILED_LOWLEVEL                       = 0x2D,
87    SPELL_FAILED_LOW_CASTLEVEL                  = 0x2E,
88    SPELL_FAILED_MAINHAND_EMPTY                 = 0x2F,
89    SPELL_FAILED_MOVING                         = 0x30,
90    SPELL_FAILED_NEED_AMMO                      = 0x31,
91    SPELL_FAILED_NEED_AMMO_POUCH                = 0x32,
92    SPELL_FAILED_NEED_EXOTIC_AMMO               = 0x33,
93    SPELL_FAILED_NOPATH                         = 0x34,
94    SPELL_FAILED_NOT_BEHIND                     = 0x35,
95    SPELL_FAILED_NOT_FISHABLE                   = 0x36,
96    SPELL_FAILED_NOT_FLYING                     = 0x37,
97    SPELL_FAILED_NOT_HERE                       = 0x38,
98    SPELL_FAILED_NOT_INFRONT                    = 0x39,
99    SPELL_FAILED_NOT_IN_CONTROL                 = 0x3A,
100    SPELL_FAILED_NOT_KNOWN                      = 0x3B,
101    SPELL_FAILED_NOT_MOUNTED                    = 0x3C,
102    SPELL_FAILED_NOT_ON_TAXI                    = 0x3D,
103    SPELL_FAILED_NOT_ON_TRANSPORT               = 0x3E,
104    SPELL_FAILED_NOT_READY                      = 0x3F,
105    SPELL_FAILED_NOT_SHAPESHIFT                 = 0x40,
106    SPELL_FAILED_NOT_STANDING                   = 0x41,
107    SPELL_FAILED_NOT_TRADEABLE                  = 0x42,
108    SPELL_FAILED_NOT_TRADING                    = 0x43,
109    SPELL_FAILED_NOT_UNSHEATHED                 = 0x44,
110    SPELL_FAILED_NOT_WHILE_GHOST                = 0x45,
111    SPELL_FAILED_NO_AMMO                        = 0x46,
112    SPELL_FAILED_NO_CHARGES_REMAIN              = 0x47,
113    SPELL_FAILED_NO_CHAMPION                    = 0x48,
114    SPELL_FAILED_NO_COMBO_POINTS                = 0x49,
115    SPELL_FAILED_NO_DUELING                     = 0x4A,
116    SPELL_FAILED_NO_ENDURANCE                   = 0x4B,
117    SPELL_FAILED_NO_FISH                        = 0x4C,
118    SPELL_FAILED_NO_ITEMS_WHILE_SHAPESHIFTED    = 0x4D,
119    SPELL_FAILED_NO_MOUNTS_ALLOWED              = 0x4E,
120    SPELL_FAILED_NO_PET                         = 0x4F,
121    SPELL_FAILED_NO_POWER                       = 0x50,
122    SPELL_FAILED_NOTHING_TO_DISPEL              = 0x51,
123    SPELL_FAILED_NOTHING_TO_STEAL               = 0x52,
124    SPELL_FAILED_ONLY_ABOVEWATER                = 0x53,
125    SPELL_FAILED_ONLY_DAYTIME                   = 0x54,
126    SPELL_FAILED_ONLY_INDOORS                   = 0x55,
127    SPELL_FAILED_ONLY_MOUNTED                   = 0x56,
128    SPELL_FAILED_ONLY_NIGHTTIME                 = 0x57,
129    SPELL_FAILED_ONLY_OUTDOORS                  = 0x58,
130    SPELL_FAILED_ONLY_SHAPESHIFT                = 0x59,
131    SPELL_FAILED_ONLY_STEALTHED                 = 0x5A,
132    SPELL_FAILED_ONLY_UNDERWATER                = 0x5B,
133    SPELL_FAILED_OUT_OF_RANGE                   = 0x5C,
134    SPELL_FAILED_PACIFIED                       = 0x5D,
135    SPELL_FAILED_POSSESSED                      = 0x5E,
136    SPELL_FAILED_REAGENTS                       = 0x5F,
137    SPELL_FAILED_REQUIRES_AREA                  = 0x60,
138    SPELL_FAILED_REQUIRES_SPELL_FOCUS           = 0x61,
139    SPELL_FAILED_ROOTED                         = 0x62,
140    SPELL_FAILED_SILENCED                       = 0x63,
141    SPELL_FAILED_SPELL_IN_PROGRESS              = 0x64,
142    SPELL_FAILED_SPELL_LEARNED                  = 0x65,
143    SPELL_FAILED_SPELL_UNAVAILABLE              = 0x66,
144    SPELL_FAILED_STUNNED                        = 0x67,
145    SPELL_FAILED_TARGETS_DEAD                   = 0x68,
146    SPELL_FAILED_TARGET_AFFECTING_COMBAT        = 0x69,
147    SPELL_FAILED_TARGET_AURASTATE               = 0x6A,
148    SPELL_FAILED_TARGET_DUELING                 = 0x6B,
149    SPELL_FAILED_TARGET_ENEMY                   = 0x6C,
150    SPELL_FAILED_TARGET_ENRAGED                 = 0x6D,
151    SPELL_FAILED_TARGET_FRIENDLY                = 0x6E,
152    SPELL_FAILED_TARGET_IN_COMBAT               = 0x6F,
153    SPELL_FAILED_TARGET_IS_PLAYER               = 0x70,
154    SPELL_FAILED_TARGET_IS_PLAYER_CONTROLLED    = 0x71,
155    SPELL_FAILED_TARGET_NOT_DEAD                = 0x72,
156    SPELL_FAILED_TARGET_NOT_IN_PARTY            = 0x73,
157    SPELL_FAILED_TARGET_NOT_LOOTED              = 0x74,
158    SPELL_FAILED_TARGET_NOT_PLAYER              = 0x75,
159    SPELL_FAILED_TARGET_NO_POCKETS              = 0x76,
160    SPELL_FAILED_TARGET_NO_WEAPONS              = 0x77,
161    SPELL_FAILED_TARGET_UNSKINNABLE             = 0x78,
162    SPELL_FAILED_THIRST_SATIATED                = 0x79,
163    SPELL_FAILED_TOO_CLOSE                      = 0x7A,
164    SPELL_FAILED_TOO_MANY_OF_ITEM               = 0x7B,
165    SPELL_FAILED_TOTEM_CATEGORY                 = 0x7C,
166    SPELL_FAILED_TOTEMS                         = 0x7D,
167    SPELL_FAILED_TRAINING_POINTS                = 0x7E,
168    SPELL_FAILED_TRY_AGAIN                      = 0x7F,
169    SPELL_FAILED_UNIT_NOT_BEHIND                = 0x80,
170    SPELL_FAILED_UNIT_NOT_INFRONT               = 0x81,
171    SPELL_FAILED_WRONG_PET_FOOD                 = 0x82,
172    SPELL_FAILED_NOT_WHILE_FATIGUED             = 0x83,
173    SPELL_FAILED_TARGET_NOT_IN_INSTANCE         = 0x84,
174    SPELL_FAILED_NOT_WHILE_TRADING              = 0x85,
175    SPELL_FAILED_TARGET_NOT_IN_RAID             = 0x86,
176    SPELL_FAILED_DISENCHANT_WHILE_LOOTING       = 0x87,
177    SPELL_FAILED_PROSPECT_WHILE_LOOTING         = 0x88,
178    SPELL_FAILED_PROSPECT_NEED_MORE             = 0x89,
179    SPELL_FAILED_TARGET_FREEFORALL              = 0x8A,
180    SPELL_FAILED_NO_EDIBLE_CORPSES              = 0x8B,
181    SPELL_FAILED_ONLY_BATTLEGROUNDS             = 0x8C,
182    SPELL_FAILED_TARGET_NOT_GHOST               = 0x8D,
183    SPELL_FAILED_TOO_MANY_SKILLS                = 0x8E,
184    SPELL_FAILED_TRANSFORM_UNUSABLE             = 0x8F,
185    SPELL_FAILED_WRONG_WEATHER                  = 0x90,
186    SPELL_FAILED_DAMAGE_IMMUNE                  = 0x91,
187    SPELL_FAILED_PREVENTED_BY_MECHANIC          = 0x92,
188    SPELL_FAILED_PLAY_TIME                      = 0x93,
189    SPELL_FAILED_REPUTATION                     = 0x94,
190    SPELL_FAILED_MIN_SKILL                      = 0x95,
191    SPELL_FAILED_NOT_IN_ARENA                   = 0x96,
192    SPELL_FAILED_NOT_ON_SHAPESHIFT              = 0x97,
193    SPELL_FAILED_NOT_ON_STEALTHED               = 0x98,
194    SPELL_FAILED_NOT_ON_DAMAGE_IMMUNE           = 0x99,
195    SPELL_FAILED_NOT_ON_MOUNTED                 = 0x9A,
196    SPELL_FAILED_TOO_SHALLOW                    = 0x9B,
197    SPELL_FAILED_TARGET_NOT_IN_SANCTUARY        = 0x9C,
198    SPELL_FAILED_TARGET_IS_TRIVIAL              = 0x9D,
199    SPELL_FAILED_BM_OR_INVISGOD                 = 0x9E,
200    SPELL_FAILED_EXPERT_RIDING_REQUIREMENT      = 0x9F,
201    SPELL_FAILED_ARTISAN_RIDING_REQUIREMENT     = 0xA0,
202    SPELL_FAILED_NOT_IDLE                       = 0xA1,
203    SPELL_FAILED_NOT_INACTIVE                   = 0xA2,
204    SPELL_FAILED_PARTIAL_PLAYTIME               = 0xA3,
205    SPELL_FAILED_NO_PLAYTIME                    = 0xA4,
206    SPELL_FAILED_NOT_IN_BATTLEGROUND            = 0xA5,
207    SPELL_FAILED_ONLY_IN_ARENA                  = 0xA6,
208    SPELL_FAILED_TARGET_LOCKED_TO_RAID_INSTANCE = 0xA7,
209    SPELL_FAILED_UNKNOWN                        = 0xA8,
210};
211
212enum SpellFamilyNames
213{
214    SPELLFAMILY_GENERIC     = 0,
215    SPELLFAMILY_UNK1        = 1,                            // events, holidays
216    // 2 - unused
217    SPELLFAMILY_MAGE        = 3,
218    SPELLFAMILY_WARRIOR     = 4,
219    SPELLFAMILY_WARLOCK     = 5,
220    SPELLFAMILY_PRIEST      = 6,
221    SPELLFAMILY_DRUID       = 7,
222    SPELLFAMILY_ROGUE       = 8,
223    SPELLFAMILY_HUNTER      = 9,
224    SPELLFAMILY_PALADIN     = 10,
225    SPELLFAMILY_SHAMAN      = 11,
226    SPELLFAMILY_UNK2        = 12,
227    SPELLFAMILY_POTION      = 13
228};
229
230enum SpellDisableTypes
231{
232    SPELL_DISABLE_PLAYER = 1,
233    SPELL_DISABLE_CREATURE = 2
234};
235
236//Some SpellFamilyFlags
237#define SPELLFAMILYFLAG_ROGUE_VANISH            0x000000800LL
238#define SPELLFAMILYFLAG_ROGUE_STEALTH           0x000400000LL
239#define SPELLFAMILYFLAG_ROGUE_BACKSTAB          0x000800004LL
240#define SPELLFAMILYFLAG_ROGUE_SAP               0x000000080LL
241#define SPELLFAMILYFLAG_ROGUE_FEINT             0x008000000LL
242#define SPELLFAMILYFLAG_ROGUE_KIDNEYSHOT        0x000200000LL
243#define SPELLFAMILYFLAG_ROGUE__FINISHING_MOVE   0x9003E0000LL
244
245// Spell clasification
246enum SpellSpecific
247{
248    SPELL_NORMAL            = 0,
249    SPELL_SEAL              = 1,
250    SPELL_BLESSING          = 2,
251    SPELL_AURA              = 3,
252    SPELL_STING             = 4,
253    SPELL_CURSE             = 5,
254    SPELL_ASPECT            = 6,
255    SPELL_TRACKER           = 7,
256    SPELL_WARLOCK_ARMOR     = 8,
257    SPELL_MAGE_ARMOR        = 9,
258    SPELL_ELEMENTAL_SHIELD  = 10,
259    SPELL_MAGE_POLYMORPH    = 11,
260    SPELL_POSITIVE_SHOUT    = 12,
261    SPELL_JUDGEMENT         = 13,
262    SPELL_BATTLE_ELIXIR     = 14,
263    SPELL_GUARDIAN_ELIXIR   = 15,
264    SPELL_FLASK_ELIXIR      = 16
265};
266
267SpellSpecific GetSpellSpecific(uint32 spellId);
268
269// Different spell properties
270inline float GetSpellRadius(SpellRadiusEntry const *radius) { return (radius ? radius->Radius : 0); }
271uint32 GetSpellCastTime(SpellEntry const* spellInfo, Spell const* spell = NULL);
272inline float GetSpellMinRange(SpellRangeEntry const *range) { return (range ? range->minRange : 0); }
273inline float GetSpellMaxRange(SpellRangeEntry const *range) { return (range ? range->maxRange : 0); }
274inline uint32 GetSpellRecoveryTime(SpellEntry const *spellInfo) { return spellInfo->RecoveryTime > spellInfo->CategoryRecoveryTime ? spellInfo->RecoveryTime : spellInfo->CategoryRecoveryTime; }
275int32 GetSpellDuration(SpellEntry const *spellInfo);
276int32 GetSpellMaxDuration(SpellEntry const *spellInfo);
277
278inline bool IsSpellHaveEffect(SpellEntry const *spellInfo, SpellEffects effect)
279{
280    for(int i= 0; i < 3; ++i)
281        if(spellInfo->Effect[i]==effect)
282            return true;
283    return false;
284}
285
286bool IsNoStackAuraDueToAura(uint32 spellId_1, uint32 effIndex_1, uint32 spellId_2, uint32 effIndex_2);
287
288inline bool IsSealSpell(SpellEntry const *spellInfo)
289{
290    //Collection of all the seal family flags. No other paladin spell has any of those.
291    return spellInfo->SpellFamilyName == SPELLFAMILY_PALADIN &&
292        ( spellInfo->SpellFamilyFlags & 0x4000A000200LL );
293}
294
295inline bool IsElementalShield(SpellEntry const *spellInfo)
296{
297    // family flags 10 (Lightning), 42 (Earth), 37 (Water), proc shield from T2 8 pieces bonus
298    return (spellInfo->SpellFamilyFlags & 0x42000000400LL) || spellInfo->Id == 23552;
299}
300
301int32 CompareAuraRanks(uint32 spellId_1, uint32 effIndex_1, uint32 spellId_2, uint32 effIndex_2);
302bool IsSingleFromSpellSpecificPerCaster(uint32 spellSpec1,uint32 spellSpec2);
303bool IsPassiveSpell(uint32 spellId);
304
305inline bool IsDeathPersistentSpell(SpellEntry const *spellInfo)
306{
307    switch(spellInfo->Id)
308    {
309        case 40214:                                     // Dragonmaw Illusion
310        case 35480: case 35481: case 35482:             // Human Illusion
311        case 35483: case 39824:                         // Human Illusion
312            return true;
313    }
314
315    return spellInfo->AttributesEx3 & SPELL_ATTR_EX3_DEATH_PERSISTENT;
316}
317
318inline bool IsNonCombatSpell(SpellEntry const *spellInfo)
319{
320    return (spellInfo->Attributes & SPELL_ATTR_CANT_USED_IN_COMBAT) != 0;
321}
322
323bool IsPositiveSpell(uint32 spellId);
324bool IsPositiveEffect(uint32 spellId, uint32 effIndex);
325bool IsPositiveTarget(uint32 targetA, uint32 targetB);
326
327bool IsSingleTargetSpell(SpellEntry const *spellInfo);
328bool IsSingleTargetSpells(SpellEntry const *spellInfo1, SpellEntry const *spellInfo2);
329
330bool IsSpellAllowedInLocation(SpellEntry const *spellInfo,uint32 map_id,uint32 zone_id,uint32 area_id);
331
332inline bool IsAreaEffectTarget( Targets target )
333{
334    switch (target )
335    {
336        case TARGET_AREAEFFECT_CUSTOM:
337        case TARGET_ALL_ENEMY_IN_AREA:
338        case TARGET_ALL_ENEMY_IN_AREA_INSTANT:
339        case TARGET_ALL_PARTY_AROUND_CASTER:
340        case TARGET_ALL_AROUND_CASTER:
341        case TARGET_ALL_ENEMY_IN_AREA_CHANNELED:
342        case TARGET_ALL_FRIENDLY_UNITS_AROUND_CASTER:
343        case TARGET_ALL_PARTY:
344        case TARGET_ALL_PARTY_AROUND_CASTER_2:
345        case TARGET_AREAEFFECT_PARTY:
346        case TARGET_AREAEFFECT_CUSTOM_2:
347        case TARGET_AREAEFFECT_PARTY_AND_CLASS:
348        case TARGET_IN_FRONT_OF_CASTER:
349        case TARGET_ALL_FRIENDLY_UNITS_IN_AREA:
350            return true;
351        default:
352            break;
353    }
354    return false;
355}
356
357inline bool IsAreaOfEffectSpell(SpellEntry const *spellInfo)
358{
359    if(IsAreaEffectTarget(Targets(spellInfo->EffectImplicitTargetA[0])) || IsAreaEffectTarget(Targets(spellInfo->EffectImplicitTargetB[0])))
360        return true;
361    if(IsAreaEffectTarget(Targets(spellInfo->EffectImplicitTargetA[1])) || IsAreaEffectTarget(Targets(spellInfo->EffectImplicitTargetB[1])))
362        return true;
363    if(IsAreaEffectTarget(Targets(spellInfo->EffectImplicitTargetA[2])) || IsAreaEffectTarget(Targets(spellInfo->EffectImplicitTargetB[2])))
364        return true;
365    return false;
366}
367
368inline bool IsAreaAuraEffect(uint32 effect)
369{
370    if( effect == SPELL_EFFECT_APPLY_AREA_AURA_PARTY    ||
371        effect == SPELL_EFFECT_APPLY_AREA_AURA_FRIEND   ||
372        effect == SPELL_EFFECT_APPLY_AREA_AURA_ENEMY    ||
373        effect == SPELL_EFFECT_APPLY_AREA_AURA_PET      ||
374        effect == SPELL_EFFECT_APPLY_AREA_AURA_OWNER)
375        return true;
376    return false;
377}
378
379inline bool IsDispelSpell(SpellEntry const *spellInfo)
380{
381    if (spellInfo->Effect[0] == SPELL_EFFECT_DISPEL ||
382        spellInfo->Effect[1] == SPELL_EFFECT_DISPEL ||
383        spellInfo->Effect[2] == SPELL_EFFECT_DISPEL )
384        return true;
385    return false;
386}
387inline bool isSpellBreakStealth(SpellEntry const* spellInfo)
388{
389    return !(spellInfo->AttributesEx & SPELL_ATTR_EX_NOT_BREAK_STEALTH);
390}
391
392uint8 GetErrorAtShapeshiftedCast (SpellEntry const *spellInfo, uint32 form);
393
394inline bool IsChanneledSpell(SpellEntry const* spellInfo)
395{
396    return (spellInfo->AttributesEx & (SPELL_ATTR_EX_CHANNELED_1 | SPELL_ATTR_EX_CHANNELED_2));
397}
398
399inline bool NeedsComboPoints(SpellEntry const* spellInfo)
400{
401    return (spellInfo->AttributesEx & (SPELL_ATTR_EX_REQ_COMBO_POINTS1 | SPELL_ATTR_EX_REQ_COMBO_POINTS2));
402}
403
404inline SpellSchoolMask GetSpellSchoolMask(SpellEntry const* spellInfo)
405{
406    return SpellSchoolMask(spellInfo->SchoolMask);
407}
408
409inline uint32 GetSpellMechanicMask(SpellEntry const* spellInfo, int32 effect)
410{
411    uint32 mask = 0;
412    if (spellInfo->Mechanic)
413        mask |= 1<<spellInfo->Mechanic;
414    if (spellInfo->EffectMechanic[effect])
415        mask |= 1<<spellInfo->EffectMechanic[effect];
416    return mask;
417}
418
419inline Mechanics GetEffectMechanic(SpellEntry const* spellInfo, int32 effect)
420{
421    if (spellInfo->EffectMechanic[effect])
422        return Mechanics(spellInfo->EffectMechanic[effect]);
423    if (spellInfo->Mechanic)
424        return Mechanics(spellInfo->Mechanic);
425    return MECHANIC_NONE;
426}
427
428inline uint32 GetDispellMask(DispelType dispel)
429{
430    // If dispell all
431    if (dispel == DISPEL_ALL)
432        return DISPEL_ALL_MASK;
433    else
434        return (1 << dispel);
435}
436
437// Diminishing Returns interaction with spells
438DiminishingGroup GetDiminishingReturnsGroupForSpell(SpellEntry const* spellproto, bool triggered);
439bool IsDiminishingReturnsGroupDurationLimited(DiminishingGroup group);
440DiminishingReturnsType GetDiminishingReturnsGroupType(DiminishingGroup group);
441
442// Spell affects related declarations (accessed using SpellMgr functions)
443typedef std::map<uint32, uint64> SpellAffectMap;
444
445// Spell proc event related declarations (accessed using SpellMgr functions)
446enum ProcFlags
447{
448    PROC_FLAG_NONE                  = 0x00000000,           // None
449    PROC_FLAG_HIT_MELEE             = 0x00000001,           // On melee hit
450    PROC_FLAG_STRUCK_MELEE          = 0x00000002,           // On being struck melee
451    PROC_FLAG_KILL_XP_GIVER         = 0x00000004,           // On kill target giving XP or honor
452    PROC_FLAG_SPECIAL_DROP          = 0x00000008,           //
453    PROC_FLAG_DODGE                 = 0x00000010,           // On dodge melee attack
454    PROC_FLAG_PARRY                 = 0x00000020,           // On parry melee attack
455    PROC_FLAG_BLOCK                 = 0x00000040,           // On block attack
456    PROC_FLAG_TOUCH                 = 0x00000080,           // On being touched (for bombs, probably?)
457    PROC_FLAG_TARGET_LOW_HEALTH     = 0x00000100,           // On deal damage to enemy with 20% or less health
458    PROC_FLAG_LOW_HEALTH            = 0x00000200,           // On health dropped below 20%
459    PROC_FLAG_STRUCK_RANGED         = 0x00000400,           // On being struck ranged
460    PROC_FLAG_HIT_SPECIAL           = 0x00000800,           // (!)Removed, may be reassigned in future
461    PROC_FLAG_CRIT_MELEE            = 0x00001000,           // On crit melee
462    PROC_FLAG_STRUCK_CRIT_MELEE     = 0x00002000,           // On being critically struck in melee
463    PROC_FLAG_CAST_SPELL            = 0x00004000,           // On cast spell
464    PROC_FLAG_TAKE_DAMAGE           = 0x00008000,           // On take damage
465    PROC_FLAG_CRIT_SPELL            = 0x00010000,           // On crit spell
466    PROC_FLAG_HIT_SPELL             = 0x00020000,           // On hit spell
467    PROC_FLAG_STRUCK_CRIT_SPELL     = 0x00040000,           // On being critically struck by a spell
468    PROC_FLAG_HIT_RANGED            = 0x00080000,           // On getting ranged hit
469    PROC_FLAG_STRUCK_SPELL          = 0x00100000,           // On being struck by a spell
470    PROC_FLAG_TRAP                  = 0x00200000,           // On trap activation (?)
471    PROC_FLAG_CRIT_RANGED           = 0x00400000,           // On getting ranged crit
472    PROC_FLAG_STRUCK_CRIT_RANGED    = 0x00800000,           // On being critically struck by a ranged attack
473    PROC_FLAG_RESIST_SPELL          = 0x01000000,           // On resist enemy spell
474    PROC_FLAG_TARGET_RESISTS        = 0x02000000,           // On enemy resisted spell
475    PROC_FLAG_TARGET_DODGE_OR_PARRY = 0x04000000,           // On enemy dodges/parries
476    PROC_FLAG_HEAL                  = 0x08000000,           // On heal
477    PROC_FLAG_CRIT_HEAL             = 0x10000000,           // On critical healing effect
478    PROC_FLAG_HEALED                = 0x20000000,           // On healing
479    PROC_FLAG_TARGET_BLOCK          = 0x40000000,           // On enemy blocks
480    PROC_FLAG_MISS                  = 0x80000000            // On miss melee attack
481};
482
483struct SpellProcEventEntry
484{
485    uint32      schoolMask;                                 // if nonzero - bit mask for matching proc condition based on spell candidate's school: Fire=2, Mask=1<<(2-1)=2
486    uint32      category;                                   // if nonzero - match proc condition based on candidate spell's category
487    uint32      skillId;                                    // if nonzero - for matching proc condition based on candidate spell's skillId from SkillLineAbility.dbc (Shadow Bolt = Destruction)
488    uint32      spellFamilyName;                            // if nonzero - for matching proc condition based on candidate spell's SpellFamilyNamer value
489    uint64      spellFamilyMask;                            // if nonzero - for matching proc condition based on candidate spell's SpellFamilyFlags (like auras 107 and 108 do)
490    uint32      procFlags;                                  // bitmask for matching proc event
491    float       ppmRate;                                    // for melee (ranged?) damage spells - proc rate per minute. if zero, falls back to flat chance from Spell.dbc
492    uint32      cooldown;                                   // hidden cooldown used for some spell proc events, applied to _triggered_spell_
493};
494
495typedef HM_NAMESPACE::hash_map<uint32, SpellProcEventEntry> SpellProcEventMap;
496
497#define ELIXIR_BATTLE_MASK    0x1
498#define ELIXIR_GUARDIAN_MASK  0x2
499#define ELIXIR_FLASK_MASK     (ELIXIR_BATTLE_MASK|ELIXIR_GUARDIAN_MASK)
500#define ELIXIR_UNSTABLE_MASK  0x4
501#define ELIXIR_SHATTRATH_MASK 0x8
502
503typedef std::map<uint32, uint8> SpellElixirMap;
504
505// Spell script target related declarations (accessed using SpellMgr functions)
506enum SpellTargetType
507{
508    SPELL_TARGET_TYPE_GAMEOBJECT = 0,
509    SPELL_TARGET_TYPE_CREATURE   = 1,
510    SPELL_TARGET_TYPE_DEAD       = 2
511};
512
513#define MAX_SPELL_TARGET_TYPE 3
514
515struct SpellTargetEntry
516{
517    SpellTargetEntry(SpellTargetType type_,uint32 targetEntry_) : type(type_), targetEntry(targetEntry_) {}
518    SpellTargetType type;
519    uint32 targetEntry;
520};
521
522typedef std::multimap<uint32,SpellTargetEntry> SpellScriptTarget;
523
524// coordinates for spells (accessed using SpellMgr functions)
525struct SpellTargetPosition
526{
527    uint32 target_mapId;
528    float  target_X;
529    float  target_Y;
530    float  target_Z;
531    float  target_Orientation;
532};
533
534typedef HM_NAMESPACE::hash_map<uint32, SpellTargetPosition> SpellTargetPositionMap;
535
536// Spell pet auras
537class PetAura
538{
539    public:
540        PetAura()
541        {
542            auras.clear();
543        }
544
545        PetAura(uint16 petEntry, uint16 aura, bool _removeOnChangePet, int _damage) :
546        removeOnChangePet(_removeOnChangePet), damage(_damage)
547        {
548            auras[petEntry] = aura;
549        }
550
551        uint16 GetAura(uint16 petEntry) const
552        {
553            std::map<uint16, uint16>::const_iterator itr = auras.find(petEntry);
554            if(itr != auras.end())
555                return itr->second;
556            else
557            {
558                std::map<uint16, uint16>::const_iterator itr = auras.find(0);
559                if(itr != auras.end())
560                    return itr->second;
561                else
562                    return 0;
563            }
564        }
565
566        void AddAura(uint16 petEntry, uint16 aura)
567        {
568            auras[petEntry] = aura;
569        }
570
571        bool IsRemovedOnChangePet() const
572        {
573            return removeOnChangePet;
574        }
575
576        int32 GetDamage() const
577        {
578            return damage;
579        }
580
581    private:
582        std::map<uint16, uint16> auras;
583        bool removeOnChangePet;
584        int32 damage;
585};
586typedef std::map<uint16, PetAura> SpellPetAuraMap;
587
588// Spell rank chain  (accessed using SpellMgr functions)
589struct SpellChainNode
590{
591    uint32 prev;
592    uint32 first;
593    uint32 req;
594    uint8  rank;
595};
596
597typedef HM_NAMESPACE::hash_map<uint32, SpellChainNode> SpellChainMap;
598typedef std::multimap<uint32, uint32> SpellChainMapNext;
599
600// Spell learning properties (accessed using SpellMgr functions)
601struct SpellLearnSkillNode
602{
603    uint32 skill;
604    uint32 value;                                           // 0  - max skill value for player level
605    uint32 maxvalue;                                        // 0  - max skill value for player level
606};
607
608typedef std::map<uint32, SpellLearnSkillNode> SpellLearnSkillMap;
609
610struct SpellLearnSpellNode
611{
612    uint32 spell;
613    bool autoLearned;
614};
615
616typedef std::multimap<uint32, SpellLearnSpellNode> SpellLearnSpellMap;
617
618typedef std::multimap<uint32, SkillLineAbilityEntry const*> SkillLineAbilityMap;
619
620inline bool IsPrimaryProfessionSkill(uint32 skill)
621{
622    SkillLineEntry const *pSkill = sSkillLineStore.LookupEntry(skill);
623    if(!pSkill)
624        return false;
625
626    if(pSkill->categoryId != SKILL_CATEGORY_PROFESSION)
627        return false;
628
629    return true;
630}
631
632inline bool IsProfessionSkill(uint32 skill)
633{
634    return  IsPrimaryProfessionSkill(skill) || skill == SKILL_FISHING || skill == SKILL_COOKING || skill == SKILL_FIRST_AID;
635}
636
637enum SpellExtraAttributeType
638{
639    SPELL_EXTRA_ATTR_MAX_TARGETS,
640    SPELL_EXTRA_ATTR_CONE_TYPE,
641    SPELL_EXTRA_ATTR_SHARE_DAMAGE
642};
643
644struct SpellExtraAttribute
645{
646    uint32 attr[3];
647};
648
649typedef std::map<uint32, SpellExtraAttribute> SpellExtraAttrMap;
650
651typedef std::map<int32, int32> SpellLinkedMap;
652
653class SpellMgr
654{
655    // Constructors
656    public:
657        SpellMgr();
658        ~SpellMgr();
659
660        // Accessors (const or static functions)
661    public:
662        // Spell affects
663        uint64 GetSpellAffectMask(uint16 spellId, uint8 effectId) const
664        {
665            SpellAffectMap::const_iterator itr = mSpellAffectMap.find((spellId<<8) + effectId);
666            if( itr != mSpellAffectMap.end( ) )
667                return itr->second;
668            return 0;
669        }
670
671        bool IsAffectedBySpell(SpellEntry const *spellInfo, uint32 spellId, uint8 effectId, uint64 familyFlags) const;
672
673        SpellElixirMap const& GetSpellElixirMap() const { return mSpellElixirs; }
674
675        uint32 GetSpellElixirMask(uint32 spellid) const
676        {
677            SpellElixirMap::const_iterator itr = mSpellElixirs.find(spellid);
678            if(itr==mSpellElixirs.end())
679                return 0x0;
680
681            return itr->second;
682        }
683
684        SpellSpecific GetSpellElixirSpecific(uint32 spellid) const
685        {
686            uint32 mask = GetSpellElixirMask(spellid);
687            if((mask & ELIXIR_FLASK_MASK)==ELIXIR_FLASK_MASK)
688                return SPELL_FLASK_ELIXIR;
689            else if(mask & ELIXIR_BATTLE_MASK)
690                return SPELL_BATTLE_ELIXIR;
691            else if(mask & ELIXIR_GUARDIAN_MASK)
692                return SPELL_GUARDIAN_ELIXIR;
693            else
694                return SPELL_NORMAL;
695        }
696
697        // Spell proc events
698        SpellProcEventEntry const* GetSpellProcEvent(uint32 spellId) const
699        {
700            SpellProcEventMap::const_iterator itr = mSpellProcEventMap.find(spellId);
701            if( itr != mSpellProcEventMap.end( ) )
702                return &itr->second;
703            return NULL;
704        }
705
706        static bool IsSpellProcEventCanTriggeredBy( SpellProcEventEntry const * spellProcEvent, SpellEntry const * procSpell, uint32 procFlags );
707
708        // Spell target coordinates
709        SpellTargetPosition const* GetSpellTargetPosition(uint32 spell_id) const
710        {
711            SpellTargetPositionMap::const_iterator itr = mSpellTargetPositions.find( spell_id );
712            if( itr != mSpellTargetPositions.end( ) )
713                return &itr->second;
714            return NULL;
715        }
716
717        // Spell ranks chains
718        SpellChainNode const* GetSpellChainNode(uint32 spell_id) const
719        {
720            SpellChainMap::const_iterator itr = mSpellChains.find(spell_id);
721            if(itr == mSpellChains.end())
722                return NULL;
723
724            return &itr->second;
725        }
726
727        uint32 GetFirstSpellInChain(uint32 spell_id) const
728        {
729            if(SpellChainNode const* node = GetSpellChainNode(spell_id))
730                return node->first;
731
732            return spell_id;
733        }
734
735        uint32 GetPrevSpellInChain(uint32 spell_id) const
736        {
737            if(SpellChainNode const* node = GetSpellChainNode(spell_id))
738                return node->prev;
739
740            return 0;
741        }
742
743        SpellChainMapNext const& GetSpellChainNext() const { return mSpellChainsNext; }
744
745        // Note: not use rank for compare to spell ranks: spell chains isn't linear order
746        // Use IsHighRankOfSpell instead
747        uint8 GetSpellRank(uint32 spell_id) const
748        {
749            if(SpellChainNode const* node = GetSpellChainNode(spell_id))
750                return node->rank;
751
752            return 0;
753        }
754
755        uint8 IsHighRankOfSpell(uint32 spell1,uint32 spell2) const
756        {
757            SpellChainMap::const_iterator itr = mSpellChains.find(spell1);
758
759            uint32 rank2 = GetSpellRank(spell2);
760
761            // not ordered correctly by rank value
762            if(itr == mSpellChains.end() || !rank2 || itr->second.rank <= rank2)
763                return false;
764
765            // check present in same rank chain
766            for(; itr != mSpellChains.end(); itr = mSpellChains.find(itr->second.prev))
767                if(itr->second.prev==spell2)
768                    return true;
769
770            return false;
771        }
772
773        bool IsRankSpellDueToSpell(SpellEntry const *spellInfo_1,uint32 spellId_2) const;
774        static bool canStackSpellRanks(SpellEntry const *spellInfo);
775        bool IsNoStackSpellDueToSpell(uint32 spellId_1, uint32 spellId_2) const;
776
777        SpellEntry const* SelectAuraRankForPlayerLevel(SpellEntry const* spellInfo, uint32 playerLevel) const;
778
779        // Spell learning
780        SpellLearnSkillNode const* GetSpellLearnSkill(uint32 spell_id) const
781        {
782            SpellLearnSkillMap::const_iterator itr = mSpellLearnSkills.find(spell_id);
783            if(itr != mSpellLearnSkills.end())
784                return &itr->second;
785            else
786                return NULL;
787        }
788
789        bool IsSpellLearnSpell(uint32 spell_id) const
790        {
791            return mSpellLearnSpells.count(spell_id)!=0;
792        }
793
794        SpellLearnSpellMap::const_iterator GetBeginSpellLearnSpell(uint32 spell_id) const
795        {
796            return mSpellLearnSpells.lower_bound(spell_id);
797        }
798
799        SpellLearnSpellMap::const_iterator GetEndSpellLearnSpell(uint32 spell_id) const
800        {
801            return mSpellLearnSpells.upper_bound(spell_id);
802        }
803
804        bool IsSpellLearnToSpell(uint32 spell_id1,uint32 spell_id2) const
805        {
806            SpellLearnSpellMap::const_iterator b = GetBeginSpellLearnSpell(spell_id1);
807            SpellLearnSpellMap::const_iterator e = GetEndSpellLearnSpell(spell_id1);
808            for(SpellLearnSpellMap::const_iterator i = b; i != e; ++i)
809                if(i->second.spell==spell_id2)
810                    return true;
811            return false;
812        }
813
814        static bool IsProfessionSpell(uint32 spellId);
815        static bool IsPrimaryProfessionSpell(uint32 spellId);
816        bool IsPrimaryProfessionFirstRankSpell(uint32 spellId) const;
817
818        // Spell script targets
819        SpellScriptTarget::const_iterator GetBeginSpellScriptTarget(uint32 spell_id) const
820        {
821            return mSpellScriptTarget.lower_bound(spell_id);
822        }
823
824        SpellScriptTarget::const_iterator GetEndSpellScriptTarget(uint32 spell_id) const
825        {
826            return mSpellScriptTarget.upper_bound(spell_id);
827        }
828
829        // Spell correctess for client using
830        static bool IsSpellValid(SpellEntry const * spellInfo, Player* pl = NULL, bool msg = true);
831
832        SkillLineAbilityMap::const_iterator GetBeginSkillLineAbilityMap(uint32 spell_id) const
833        {
834            return mSkillLineAbilityMap.lower_bound(spell_id);
835        }
836
837        SkillLineAbilityMap::const_iterator GetEndSkillLineAbilityMap(uint32 spell_id) const
838        {
839            return mSkillLineAbilityMap.upper_bound(spell_id);
840        }
841
842        PetAura const* GetPetAura(uint16 spell_id)
843        {
844            SpellPetAuraMap::const_iterator itr = mSpellPetAuraMap.find(spell_id);
845            if(itr != mSpellPetAuraMap.end())
846                return &itr->second;
847            else
848                return NULL;
849        }
850
851        uint32 GetSpellExtraAttr(uint32 spell_id, uint32 type) const
852        {
853            SpellExtraAttrMap::const_iterator itr = mSpellExtraAttrMap.find(spell_id);
854            if(itr != mSpellExtraAttrMap.end())
855                return itr->second.attr[type];
856            else
857                return 0;
858        }
859
860        int32 GetSpellLinked(int32 spell_id) const
861        {
862            SpellLinkedMap::const_iterator itr = mSpellLinkedMap.find(spell_id);
863            if(itr != mSpellLinkedMap.end())
864                return itr->second;
865            else
866                return 0;
867        }
868
869        // Modifiers
870    public:
871        static SpellMgr& Instance();
872
873        // Loading data at server startup
874        void LoadSpellChains();
875        void LoadSpellLearnSkills();
876        void LoadSpellLearnSpells();
877        void LoadSpellScriptTarget();
878        void LoadSpellAffects();
879        void LoadSpellElixirs();
880        void LoadSpellProcEvents();
881        void LoadSpellTargetPositions();
882        void LoadSpellThreats();
883        void LoadSkillLineAbilityMap();
884        void LoadSpellPetAuras();
885        void LoadSpellExtraAttr();
886        void LoadSpellLinked();
887
888    private:
889        SpellScriptTarget  mSpellScriptTarget;
890        SpellChainMap      mSpellChains;
891        SpellChainMapNext  mSpellChainsNext;
892        SpellLearnSkillMap mSpellLearnSkills;
893        SpellLearnSpellMap mSpellLearnSpells;
894        SpellTargetPositionMap mSpellTargetPositions;
895        SpellAffectMap     mSpellAffectMap;
896        SpellElixirMap     mSpellElixirs;
897        SpellProcEventMap  mSpellProcEventMap;
898        SkillLineAbilityMap mSkillLineAbilityMap;
899        SpellPetAuraMap     mSpellPetAuraMap;
900        SpellExtraAttrMap   mSpellExtraAttrMap;
901        SpellLinkedMap      mSpellLinkedMap;
902};
903
904#define spellmgr SpellMgr::Instance()
905#endif
Note: See TracBrowser for help on using the browser.