2010-10-07 15:54:07 +02:00
/*
2011-01-01 15:01:13 +01:00
* Copyright (C) 2008-2011 TrinityCore <http://www.trinitycore.org/>
2010-10-07 15:54:07 +02:00
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
2008-11-17 22:07:21 -06:00
*/
2009-10-17 15:51:44 -07:00
2008-11-17 22:07:21 -06:00
#ifndef _SPELLMGR_H
#define _SPELLMGR_H
2009-10-17 15:51:44 -07:00
2008-11-17 22:07:21 -06:00
// For static or at-server-startup loaded spell data
// For more high level function for sSpellStore data
2010-12-22 20:52:47 +01:00
#include <ace/Singleton.h>
2009-10-17 15:51:44 -07:00
2010-06-08 13:05:47 -06:00
#include "SharedDefines.h"
2009-07-20 11:54:49 +08:00
#include "SpellAuraDefines.h"
2009-03-27 09:58:20 -06:00
#include "DBCStructure.h"
2009-07-20 11:54:49 +08:00
#include "DBCStores.h"
2009-10-17 15:51:44 -07:00
2010-06-08 13:05:47 -06:00
#include "UnorderedMap.h"
2009-10-17 15:51:44 -07:00
2009-07-20 22:50:36 +02:00
#include "Player.h"
2009-10-17 15:51:44 -07:00
2008-11-17 22:07:21 -06:00
#include <map>
2009-10-17 15:51:44 -07:00
2008-11-17 22:07:21 -06:00
class Player ;
class Spell ;
2009-07-20 11:54:49 +08:00
struct SpellModifier ;
2009-10-17 15:51:44 -07:00
2009-03-02 16:53:50 -06:00
// only used in code
enum SpellCategories
{
SPELLCATEGORY_HEALTH_MANA_POTIONS = 4 ,
2009-08-05 16:39:09 -05:00
SPELLCATEGORY_DEVOUR_MAGIC = 12 ,
SPELLCATEGORY_JUDGEMENT = 1210 , // Judgement (seal trigger)
2009-08-11 19:57:27 +02:00
SPELLCATEGORY_FOOD = 11 ,
SPELLCATEGORY_DRINK = 59 ,
2009-03-02 16:53:50 -06:00
};
2009-10-17 15:51:44 -07:00
2008-12-19 18:31:46 -06:00
enum SpellEffectTargetTypes
{
SPELL_REQUIRE_NONE ,
SPELL_REQUIRE_UNIT ,
SPELL_REQUIRE_DEST ,
2008-12-24 18:45:06 -06:00
SPELL_REQUIRE_ITEM ,
2008-12-26 16:15:44 -06:00
SPELL_REQUIRE_CASTER ,
2009-05-21 10:01:03 -05:00
SPELL_REQUIRE_GOBJECT ,
2008-12-19 18:31:46 -06:00
};
2009-10-17 15:51:44 -07:00
2008-12-20 19:33:03 -06:00
enum SpellSelectTargetTypes
{
TARGET_TYPE_DEFAULT ,
TARGET_TYPE_UNIT_CASTER ,
TARGET_TYPE_UNIT_TARGET ,
2009-05-02 11:28:11 -05:00
TARGET_TYPE_UNIT_NEARBY ,
TARGET_TYPE_AREA_SRC ,
TARGET_TYPE_AREA_DST ,
TARGET_TYPE_AREA_CONE ,
2008-12-20 19:33:03 -06:00
TARGET_TYPE_DEST_CASTER ,
TARGET_TYPE_DEST_TARGET ,
TARGET_TYPE_DEST_DEST ,
2009-05-02 11:28:11 -05:00
TARGET_TYPE_DEST_SPECIAL ,
TARGET_TYPE_CHANNEL ,
2008-12-20 19:33:03 -06:00
};
2009-10-17 15:51:44 -07:00
2009-12-24 12:37:26 -06:00
//SpellFamilyFlags
enum SpellFamilyFlag
{
// SPELLFAMILYFLAG = SpellFamilyFlags[0]
// SPELLFAMILYFLAG1 = SpellFamilyFlags[1]
// SPELLFAMILYFLAG2 = SpellFamilyFlags[2]
// Rogue
SPELLFAMILYFLAG_ROGUE_VANISH = 0x00000800 ,
SPELLFAMILYFLAG_ROGUE_STEALTH = 0x00400000 ,
SPELLFAMILYFLAG_ROGUE_BACKSTAB = 0x00800004 ,
SPELLFAMILYFLAG_ROGUE_SAP = 0x00000080 ,
SPELLFAMILYFLAG_ROGUE_FEINT = 0x08000000 ,
SPELLFAMILYFLAG_ROGUE_KIDNEYSHOT = 0x00200000 ,
SPELLFAMILYFLAG1_ROGUE_HUNGERFORBLOOD = 0x01000000 ,
SPELLFAMILYFLAG_ROGUE_VAN_EVAS_SPRINT = 0x00000860 , // Vanish, Evasion, Sprint
SPELLFAMILYFLAG1_ROGUE_COLDB_SHADOWSTEP = 0x00000240 , // Cold Blood, Shadowstep
2010-05-14 21:42:55 +02:00
SPELLFAMILYFLAG_ROGUE_KICK = 0x00000010 , // Kick
SPELLFAMILYFLAG1_ROGUE_DISMANTLE = 0x00100000 , // Dismantle
SPELLFAMILYFLAG_ROGUE_BLADE_FLURRY = 0x40000000 , // Blade Flurry
SPELLFAMILYFLAG1_ROGUE_BLADE_FLURRY = 0x00000800 , // Blade Flurry
2009-12-24 12:37:26 -06:00
//SPELLFAMILYFLAG_ROGUE__FINISHING_MOVE = 0x9003E0000LL,
// Warrior
SPELLFAMILYFLAG_WARRIOR_SUNDERARMOR = 0x00004000 ,
SPELLFAMILYFLAG_WARRIOR_CHARGE = 0x00000001 ,
SPELLFAMILYFLAG_WARRIOR_SLAM = 0x00200000 ,
SPELLFAMILYFLAG_WARRIOR_EXECUTE = 0x20000000 ,
SPELLFAMILYFLAG_WARRIOR_CONCUSSION_BLOW = 0x04000000 ,
// Warlock
SPELLFAMILYFLAG_WARLOCK_LIFETAP = 0x00040000 ,
// Priest
SPELLFAMILYFLAG1_PRIEST_PENANCE = 0x00800000 ,
// Druid
SPELLFAMILYFLAG2_DRUID_STARFALL = 0x00000100 ,
// Paladin
2010-01-17 01:53:28 -03:00
SPELLFAMILYFLAG1_PALADIN_DIVINESTORM = 0x00020000 ,
2009-12-24 12:37:26 -06:00
// Shaman
SPELLFAMILYFLAG_SHAMAN_FROST_SHOCK = 0x80000000 ,
SPELLFAMILYFLAG_SHAMAN_HEALING_STREAM = 0x00002000 ,
SPELLFAMILYFLAG_SHAMAN_MANA_SPRING = 0x00004000 ,
SPELLFAMILYFLAG2_SHAMAN_LAVA_LASH = 0x00000004 ,
SPELLFAMILYFLAG_SHAMAN_FLAMETONGUE = 0x00200000 ,
2010-02-14 19:13:14 -07:00
SPELLFAMILYFLAG_SHAMAN_FIRE_NOVA = 0x28000000 ,
2009-12-24 12:37:26 -06:00
// Deathknight
SPELLFAMILYFLAG_DK_DEATH_STRIKE = 0x00000010 ,
SPELLFAMILYFLAG1_DK_SCOURGE_STRIKE = 0x08000000 ,
SPELLFAMILYFLAG_DK_DEATH_COIL = 0x00002000 ,
SPELLFAMILYFLAG1_DK_HUNGERING_COLD = 0x00001000 ,
// TODO: Figure out a more accurate name for the following familyflag(s)
SPELLFAMILYFLAG_SHAMAN_TOTEM_EFFECTS = 0x04000000 , // Seems to be linked to most totems and some totem effects
};
2008-11-17 22:07:21 -06:00
// Spell clasification
enum SpellSpecific
{
2010-01-10 01:23:15 +01:00
SPELL_SPECIFIC_NORMAL = 0 ,
SPELL_SPECIFIC_SEAL = 1 ,
SPELL_SPECIFIC_AURA = 3 ,
SPELL_SPECIFIC_STING = 4 ,
SPELL_SPECIFIC_CURSE = 5 ,
SPELL_SPECIFIC_ASPECT = 6 ,
SPELL_SPECIFIC_TRACKER = 7 ,
SPELL_SPECIFIC_WARLOCK_ARMOR = 8 ,
SPELL_SPECIFIC_MAGE_ARMOR = 9 ,
SPELL_SPECIFIC_ELEMENTAL_SHIELD = 10 ,
SPELL_SPECIFIC_MAGE_POLYMORPH = 11 ,
SPELL_SPECIFIC_JUDGEMENT = 13 ,
SPELL_SPECIFIC_WARLOCK_CORRUPTION = 17 ,
SPELL_SPECIFIC_FOOD = 19 ,
SPELL_SPECIFIC_DRINK = 20 ,
SPELL_SPECIFIC_FOOD_AND_DRINK = 21 ,
SPELL_SPECIFIC_PRESENCE = 22 ,
SPELL_SPECIFIC_CHARM = 23 ,
SPELL_SPECIFIC_SCROLL = 24 ,
SPELL_SPECIFIC_MAGE_ARCANE_BRILLANCE = 25 ,
SPELL_SPECIFIC_WARRIOR_ENRAGE = 26 ,
SPELL_SPECIFIC_PRIEST_DIVINE_SPIRIT = 27 ,
SPELL_SPECIFIC_HAND = 28 ,
SPELL_SPECIFIC_PHASE = 29 ,
2008-11-17 22:07:21 -06:00
};
2009-10-17 15:51:44 -07:00
2009-02-05 22:49:07 -06:00
#define SPELL_LINKED_MAX_SPELLS 200000
2009-10-17 15:51:44 -07:00
2009-02-05 22:49:07 -06:00
enum SpellLinkedType
{
SPELL_LINK_CAST = 0 , // +: cast; -: remove
SPELL_LINK_HIT = 1 * 200000 ,
SPELL_LINK_AURA = 2 * 200000 , // +: aura; -: immune
SPELL_LINK_REMOVE = 0 ,
};
2009-10-17 15:51:44 -07:00
2011-06-11 22:35:29 +02:00
bool IsSpellRequiringFocusedTarget ( SpellEntry const * spellInfo );
Unit * GetTriggeredSpellCaster ( SpellEntry const * spellInfo , Unit * caster , Unit * target );
SpellSpecific GetSpellSpecific ( SpellEntry const * spellInfo );
AuraState GetSpellAuraState ( SpellEntry const * spellInfo );
2009-10-17 15:51:44 -07:00
2008-11-17 22:07:21 -06:00
// Different spell properties
2009-02-14 15:56:04 +01:00
inline float GetSpellRadiusForHostile ( SpellRadiusEntry const * radius ) { return ( radius ? radius -> radiusHostile : 0 ); }
inline float GetSpellRadiusForFriend ( SpellRadiusEntry const * radius ) { return ( radius ? radius -> radiusFriend : 0 ); }
2011-06-11 22:35:29 +02:00
uint32 GetSpellCastTime ( SpellEntry const * spellInfo , Spell * spell = NULL );
2010-06-27 04:03:30 +02:00
uint32 GetDispelChance ( Unit * auraCaster , Unit * target , uint32 spellId , bool offensive , bool * result );
2009-02-14 15:56:04 +01:00
inline float GetSpellMinRangeForHostile ( SpellRangeEntry const * range ) { return ( range ? range -> minRangeHostile : 0 ); }
inline float GetSpellMaxRangeForHostile ( SpellRangeEntry const * range ) { return ( range ? range -> maxRangeHostile : 0 ); }
inline float GetSpellMinRangeForFriend ( SpellRangeEntry const * range ) { return ( range ? range -> minRangeFriend : 0 ); }
inline float GetSpellMaxRangeForFriend ( SpellRangeEntry const * range ) { return ( range ? range -> maxRangeFriend : 0 ); }
2008-12-04 23:00:35 -06:00
inline uint32 GetSpellRangeType ( SpellRangeEntry const * range ) { return ( range ? range -> type : 0 ); }
2008-11-17 22:07:21 -06:00
inline uint32 GetSpellRecoveryTime ( SpellEntry const * spellInfo ) { return spellInfo -> RecoveryTime > spellInfo -> CategoryRecoveryTime ? spellInfo -> RecoveryTime : spellInfo -> CategoryRecoveryTime ; }
int32 GetSpellDuration ( SpellEntry const * spellInfo );
int32 GetSpellMaxDuration ( SpellEntry const * spellInfo );
2009-05-02 13:30:55 -05:00
inline float GetSpellRadius ( SpellEntry const * spellInfo , uint32 effectIdx , bool positive )
{
return positive
? GetSpellRadiusForFriend ( sSpellRadiusStore . LookupEntry ( spellInfo -> EffectRadiusIndex [ effectIdx ]))
: GetSpellRadiusForHostile ( sSpellRadiusStore . LookupEntry ( spellInfo -> EffectRadiusIndex [ effectIdx ]));
}
2009-10-17 15:51:44 -07:00
2009-05-02 13:30:55 -05:00
inline float GetSpellMaxRange ( SpellEntry const * spellInfo , bool positive )
{
return positive
? GetSpellMaxRangeForFriend ( sSpellRangeStore . LookupEntry ( spellInfo -> rangeIndex ))
: GetSpellMaxRangeForHostile ( sSpellRangeStore . LookupEntry ( spellInfo -> rangeIndex ));
}
2009-10-17 15:51:44 -07:00
2009-05-06 10:35:37 -05:00
inline float GetSpellMinRange ( SpellEntry const * spellInfo , bool positive )
{
return positive
? GetSpellMinRangeForFriend ( sSpellRangeStore . LookupEntry ( spellInfo -> rangeIndex ))
: GetSpellMinRangeForHostile ( sSpellRangeStore . LookupEntry ( spellInfo -> rangeIndex ));
}
2009-10-17 15:51:44 -07:00
2009-08-23 14:20:07 -05:00
inline float GetSpellMinRange ( uint32 id , bool positive )
{
SpellEntry const * spellInfo = GetSpellStore () -> LookupEntry ( id );
2010-04-07 19:14:10 +02:00
if ( ! spellInfo ) return 0 ;
2009-08-23 14:20:07 -05:00
return GetSpellMinRange ( spellInfo , positive );
}
2009-10-17 15:51:44 -07:00
2009-05-20 11:44:38 -05:00
inline float GetSpellMaxRange ( uint32 id , bool positive )
{
SpellEntry const * spellInfo = GetSpellStore () -> LookupEntry ( id );
2010-04-07 19:14:10 +02:00
if ( ! spellInfo ) return 0 ;
2009-05-20 11:44:38 -05:00
return GetSpellMaxRange ( spellInfo , positive );
}
2009-10-17 15:51:44 -07:00
2009-04-06 13:31:14 +02:00
/*struct DispelEntry
2009-03-23 01:54:50 +01:00
{
uint64 casterGuid;
uint32 spellId;
2011-06-11 22:35:29 +02:00
Unit* caster;
2009-03-23 01:54:50 +01:00
uint8 stackAmount;
2009-10-17 15:51:44 -07:00
2009-03-23 01:54:50 +01:00
bool operator < (const DispelEntry & _Right) const
{
return (spellId != _Right.spellId ? spellId < _Right.spellId : casterGuid < _Right.casterGuid);
}
2009-04-06 13:31:14 +02:00
};*/
2009-10-17 15:51:44 -07:00
2008-11-17 22:07:21 -06:00
inline bool IsSpellHaveEffect ( SpellEntry const * spellInfo , SpellEffects effect )
{
2010-09-28 08:21:51 +03:00
for ( int i = 0 ; i < MAX_SPELL_EFFECTS ; ++ i )
2010-04-07 23:25:02 +02:00
if ( SpellEffects ( spellInfo -> Effect [ i ]) == effect )
2008-11-17 22:07:21 -06:00
return true ;
return false ;
}
2009-10-17 15:51:44 -07:00
2009-07-16 10:13:12 +08:00
inline bool IsSpellHaveAura ( SpellEntry const * spellInfo , AuraType aura )
{
2010-09-28 08:21:51 +03:00
for ( int i = 0 ; i < MAX_SPELL_EFFECTS ; ++ i )
2010-04-07 23:25:02 +02:00
if ( AuraType ( spellInfo -> EffectApplyAuraName [ i ]) == aura )
2009-07-16 10:13:12 +08:00
return true ;
return false ;
}
2009-10-17 15:51:44 -07:00
2008-11-20 18:13:10 -06:00
//bool IsNoStackAuraDueToAura(uint32 spellId_1, uint32 effIndex_1, uint32 spellId_2, uint32 effIndex_2);
2009-10-17 15:51:44 -07:00
2008-11-17 22:07:21 -06:00
inline bool IsSealSpell ( SpellEntry const * spellInfo )
{
//Collection of all the seal family flags. No other paladin spell has any of those.
return spellInfo -> SpellFamilyName == SPELLFAMILY_PALADIN &&
2010-04-07 22:59:46 +02:00
( spellInfo -> SpellFamilyFlags [ 1 ] & 0x26000C00
|| spellInfo -> SpellFamilyFlags [ 0 ] & 0x0A000000 );
2008-11-17 22:07:21 -06:00
}
2009-10-17 15:51:44 -07:00
2008-11-17 22:07:21 -06:00
inline bool IsElementalShield ( SpellEntry const * spellInfo )
{
// family flags 10 (Lightning), 42 (Earth), 37 (Water), proc shield from T2 8 pieces bonus
2009-02-02 17:01:56 +01:00
return ( spellInfo -> SpellFamilyFlags [ 1 ] & 0x420
2009-02-02 17:42:05 +01:00
|| spellInfo -> SpellFamilyFlags [ 0 ] & 0x00000400 )
|| spellInfo -> Id == 23552 ;
2008-11-17 22:07:21 -06:00
}
2009-10-17 15:51:44 -07:00
2009-01-20 19:59:43 -06:00
inline bool IsExplicitDiscoverySpell ( SpellEntry const * spellInfo )
{
2010-04-11 11:24:05 +04:00
return ((( spellInfo -> Effect [ 0 ] == SPELL_EFFECT_CREATE_RANDOM_ITEM
|| spellInfo -> Effect [ 0 ] == SPELL_EFFECT_CREATE_ITEM_2 )
2009-09-18 14:10:37 -07:00
&& spellInfo -> Effect [ 1 ] == SPELL_EFFECT_SCRIPT_EFFECT )
2010-04-07 23:25:02 +02:00
|| spellInfo -> Id == 64323 ); // Book of Glyph Mastery (Effect0 == SPELL_EFFECT_SCRIPT_EFFECT without any other data)
2009-01-20 19:59:43 -06:00
}
2009-10-17 15:51:44 -07:00
2009-02-05 23:02:07 -06:00
inline bool IsLootCraftingSpell ( SpellEntry const * spellInfo )
{
2010-04-07 23:25:02 +02:00
return ( spellInfo -> Effect [ 0 ] == SPELL_EFFECT_CREATE_RANDOM_ITEM ||
2010-04-11 20:20:38 +02:00
// different random cards from Inscription (121==Virtuoso Inking Set category) r without explicit item
( spellInfo -> Effect [ 0 ] == SPELL_EFFECT_CREATE_ITEM_2 &&
2010-04-11 11:24:05 +04:00
( spellInfo -> TotemCategory [ 0 ] != 0 || spellInfo -> EffectItemType [ 0 ] == 0 )));
2009-02-05 23:02:07 -06:00
}
2009-10-17 15:51:44 -07:00
2011-06-23 13:28:52 +02:00
inline bool IsQuestTameSpell ( SpellEntry const * spellInfo )
{
return spellInfo -> Effect [ 0 ] == SPELL_EFFECT_THREAT && spellInfo -> Effect [ 1 ] == SPELL_EFFECT_APPLY_AURA && spellInfo -> EffectApplyAuraName [ 1 ] == SPELL_AURA_DUMMY ;
}
2011-04-29 20:47:02 +02:00
bool IsHigherHankOfSpell ( uint32 spellId_1 , uint32 spellId_2 );
2009-08-24 20:17:33 -05:00
bool IsSingleFromSpellSpecificPerCaster ( SpellSpecific spellSpec1 , SpellSpecific spellSpec2 );
bool IsSingleFromSpellSpecificPerTarget ( SpellSpecific spellSpec1 , SpellSpecific spellSpec2 );
2008-11-17 22:07:21 -06:00
bool IsPassiveSpell ( uint32 spellId );
2011-06-11 22:35:29 +02:00
bool IsPassiveSpell ( SpellEntry const * spellInfo );
2009-03-21 18:05:43 -06:00
bool IsAutocastableSpell ( uint32 spellId );
2009-10-17 15:51:44 -07:00
2011-06-11 22:35:29 +02:00
uint32 CalculatePowerCost ( SpellEntry const * spellInfo , Unit const * caster , SpellSchoolMask schoolMask );
2009-10-17 15:51:44 -07:00
2008-12-31 10:05:45 -06:00
inline bool IsPassiveSpellStackableWithRanks ( SpellEntry const * spellProto )
{
2010-04-07 19:14:10 +02:00
if ( ! IsPassiveSpell ( spellProto -> Id ))
2008-12-31 10:05:45 -06:00
return false ;
2009-10-17 15:51:44 -07:00
2011-04-29 20:47:02 +02:00
return ! IsSpellHaveEffect ( spellProto , SPELL_EFFECT_APPLY_AURA );
2008-12-31 10:05:45 -06:00
}
2008-11-17 22:07:21 -06:00
inline bool IsDeathPersistentSpell ( SpellEntry const * spellInfo )
{
2010-12-19 05:15:47 +01:00
return spellInfo -> AttributesEx3 & SPELL_ATTR3_DEATH_PERSISTENT ;
2008-11-17 22:07:21 -06:00
}
2009-10-17 15:51:44 -07:00
2010-08-30 17:32:51 +02:00
inline bool IsRequiringDeadTargetSpell ( SpellEntry const * spellInfo )
{
2010-12-19 05:15:47 +01:00
return spellInfo -> AttributesEx3 & SPELL_ATTR3_REQUIRE_DEAD_TARGET ;
2010-08-30 17:32:51 +02:00
}
inline bool IsAllowingDeadTargetSpell ( SpellEntry const * spellInfo )
{
2010-12-19 05:15:47 +01:00
return spellInfo -> AttributesEx2 & SPELL_ATTR2_ALLOW_DEAD_TARGET ;
2010-08-30 17:32:51 +02:00
}
inline bool IsDeadTargetSpell ( SpellEntry const * spellInfo )
{
return IsAllowingDeadTargetSpell ( spellInfo ) || IsRequiringDeadTargetSpell ( spellInfo );
}
2008-11-17 22:07:21 -06:00
inline bool IsNonCombatSpell ( SpellEntry const * spellInfo )
{
2010-12-19 05:15:47 +01:00
return ( spellInfo -> Attributes & SPELL_ATTR0_CANT_USED_IN_COMBAT ) != 0 ;
2008-11-17 22:07:21 -06:00
}
2009-10-17 15:51:44 -07:00
2009-08-06 11:24:14 -05:00
bool IsPositiveSpell ( uint32 spellId );
bool IsPositiveEffect ( uint32 spellId , uint32 effIndex );
2008-11-17 22:07:21 -06:00
bool IsPositiveTarget ( uint32 targetA , uint32 targetB );
2011-06-11 22:35:29 +02:00
bool CanSpellDispelAura ( SpellEntry const * dispelSpell , SpellEntry const * aura );
bool CanSpellPierceImmuneAura ( SpellEntry const * pierceSpell , SpellEntry const * aura );
2009-10-17 15:51:44 -07:00
2011-06-17 12:00:11 +02:00
bool IsSingleTargetSpell ( SpellEntry const * spellInfo );
bool IsSingleTargetSpells ( SpellEntry const * spellInfo1 , SpellEntry const * spellInfo2 );
2009-10-17 15:51:44 -07:00
2009-01-30 01:11:51 -06:00
extern bool IsAreaEffectTarget [ TOTAL_SPELL_TARGETS ];
2009-08-17 15:54:39 -05:00
extern SpellEffectTargetTypes EffectTargetType [ TOTAL_SPELL_EFFECTS ];
extern SpellSelectTargetTypes SpellTargetType [ TOTAL_SPELL_TARGETS ];
2009-10-17 15:51:44 -07:00
2009-08-17 15:54:39 -05:00
inline bool IsCasterSourceTarget ( uint32 target )
{
switch ( SpellTargetType [ target ])
{
case TARGET_TYPE_UNIT_CASTER :
case TARGET_TYPE_AREA_SRC :
case TARGET_TYPE_AREA_CONE :
case TARGET_TYPE_DEST_CASTER :
return true ;
default :
break ;
}
return false ;
}
2009-10-17 15:51:44 -07:00
2009-08-23 00:46:21 -05:00
inline bool IsPositionTarget ( uint32 target )
{
switch ( SpellTargetType [ target ])
{
case TARGET_TYPE_DEST_CASTER :
case TARGET_TYPE_DEST_TARGET :
case TARGET_TYPE_DEST_DEST :
return true ;
default :
break ;
}
return false ;
}
2009-10-17 15:51:44 -07:00
2009-08-17 15:54:39 -05:00
inline bool IsSpellWithCasterSourceTargetsOnly ( SpellEntry const * spellInfo )
{
2010-09-28 08:21:51 +03:00
for ( int i = 0 ; i < MAX_SPELL_EFFECTS ; ++ i )
2009-08-17 15:54:39 -05:00
{
uint32 targetA = spellInfo -> EffectImplicitTargetA [ i ];
2010-04-07 19:14:10 +02:00
if ( targetA && ! IsCasterSourceTarget ( targetA ))
2009-08-17 15:54:39 -05:00
return false ;
2009-10-17 15:51:44 -07:00
2009-08-17 15:54:39 -05:00
uint32 targetB = spellInfo -> EffectImplicitTargetB [ i ];
2010-04-07 19:14:10 +02:00
if ( targetB && ! IsCasterSourceTarget ( targetB ))
2009-08-17 15:54:39 -05:00
return false ;
2009-10-17 15:51:44 -07:00
2010-04-07 19:14:10 +02:00
if ( ! targetA && ! targetB )
2009-08-17 15:54:39 -05:00
return false ;
}
return true ;
}
2009-10-17 15:51:44 -07:00
2008-11-17 22:07:21 -06:00
inline bool IsAreaOfEffectSpell ( SpellEntry const * spellInfo )
{
2010-04-07 19:14:10 +02:00
if ( IsAreaEffectTarget [ spellInfo -> EffectImplicitTargetA [ 0 ]] || IsAreaEffectTarget [ spellInfo -> EffectImplicitTargetB [ 0 ]])
2008-11-17 22:07:21 -06:00
return true ;
2010-04-07 19:14:10 +02:00
if ( IsAreaEffectTarget [ spellInfo -> EffectImplicitTargetA [ 1 ]] || IsAreaEffectTarget [ spellInfo -> EffectImplicitTargetB [ 1 ]])
2008-11-17 22:07:21 -06:00
return true ;
2010-04-07 19:14:10 +02:00
if ( IsAreaEffectTarget [ spellInfo -> EffectImplicitTargetA [ 2 ]] || IsAreaEffectTarget [ spellInfo -> EffectImplicitTargetB [ 2 ]])
2008-11-17 22:07:21 -06:00
return true ;
return false ;
}
2009-10-17 15:51:44 -07:00
2010-12-05 20:43:09 +01:00
inline bool IsAreaOfEffectSpellEffect ( SpellEntry const * spellInfo , uint8 effIndex )
{
if ( IsAreaEffectTarget [ spellInfo -> EffectImplicitTargetA [ effIndex ]] || IsAreaEffectTarget [ spellInfo -> EffectImplicitTargetB [ effIndex ]])
return true ;
return false ;
}
2010-07-29 19:48:40 +02:00
inline bool IsFarUnitTargetEffect ( uint32 effect )
{
return ( effect == SPELL_EFFECT_SUMMON_PLAYER );
}
inline bool IsFarDestTargetEffect ( uint32 effect )
{
return ( effect == SPELL_EFFECT_TELEPORT_UNITS );
}
2008-11-17 22:07:21 -06:00
inline bool IsAreaAuraEffect ( uint32 effect )
{
2010-04-07 22:59:46 +02:00
if ( effect == SPELL_EFFECT_APPLY_AREA_AURA_PARTY ||
2008-12-24 09:58:26 -06:00
effect == SPELL_EFFECT_APPLY_AREA_AURA_RAID ||
2008-11-17 22:07:21 -06:00
effect == SPELL_EFFECT_APPLY_AREA_AURA_FRIEND ||
effect == SPELL_EFFECT_APPLY_AREA_AURA_ENEMY ||
effect == SPELL_EFFECT_APPLY_AREA_AURA_PET ||
effect == SPELL_EFFECT_APPLY_AREA_AURA_OWNER )
return true ;
return false ;
}
2010-01-10 01:23:15 +01:00
2010-07-21 01:22:52 +02:00
inline bool HasAreaAuraEffect ( SpellEntry const * spellInfo )
{
for ( uint8 i = 0 ; i < MAX_SPELL_EFFECTS ; ++ i )
if ( IsAreaAuraEffect ( spellInfo -> Effect [ i ]))
return true ;
return false ;
}
2010-01-10 01:23:15 +01:00
inline bool IsUnitOwnedAuraEffect ( uint32 effect )
{
return ( IsAreaAuraEffect ( effect ) || effect == SPELL_EFFECT_APPLY_AURA );
}
2009-01-20 21:10:38 +01:00
inline bool IsDispel ( SpellEntry const * spellInfo )
2008-11-17 22:07:21 -06:00
{
2009-01-09 21:21:04 +01:00
//spellsteal is also dispel
2008-11-17 22:07:21 -06:00
if ( spellInfo -> Effect [ 0 ] == SPELL_EFFECT_DISPEL ||
spellInfo -> Effect [ 1 ] == SPELL_EFFECT_DISPEL ||
2009-01-20 21:10:38 +01:00
spellInfo -> Effect [ 2 ] == SPELL_EFFECT_DISPEL )
return true ;
return false ;
}
2009-10-17 15:51:44 -07:00
2009-01-20 21:10:38 +01:00
inline bool IsDispelSpell ( SpellEntry const * spellInfo )
{
//spellsteal is also dispel
if ( spellInfo -> Effect [ 0 ] == SPELL_EFFECT_STEAL_BENEFICIAL_BUFF ||
2009-01-09 21:21:04 +01:00
spellInfo -> Effect [ 1 ] == SPELL_EFFECT_STEAL_BENEFICIAL_BUFF ||
2009-01-20 21:10:38 +01:00
spellInfo -> Effect [ 2 ] == SPELL_EFFECT_STEAL_BENEFICIAL_BUFF
|| IsDispel ( spellInfo ))
2008-11-17 22:07:21 -06:00
return true ;
return false ;
}
2009-10-17 15:51:44 -07:00
2008-11-17 22:07:21 -06:00
inline bool isSpellBreakStealth ( SpellEntry const * spellInfo )
{
2010-12-19 05:15:47 +01:00
return ! ( spellInfo -> AttributesEx & SPELL_ATTR1_NOT_BREAK_STEALTH );
2008-11-17 22:07:21 -06:00
}
2009-10-17 15:51:44 -07:00
2008-12-31 10:05:45 -06:00
inline bool IsAutoRepeatRangedSpell ( SpellEntry const * spellInfo )
{
2010-12-19 05:15:47 +01:00
return spellInfo -> AttributesEx2 & SPELL_ATTR2_AUTOREPEAT_FLAG ;
2009-05-08 00:49:02 -05:00
}
2009-10-17 15:51:44 -07:00
2009-05-08 00:49:02 -05:00
inline bool IsRangedWeaponSpell ( SpellEntry const * spellInfo )
{
//spell->DmgClass == SPELL_DAMAGE_CLASS_RANGED should be checked outside
2009-07-19 00:40:54 +02:00
return ( spellInfo -> SpellFamilyName == SPELLFAMILY_HUNTER && ! ( spellInfo -> SpellFamilyFlags [ 1 ] & 0x10000000 )) // for 53352, cannot find better way
2009-05-08 00:49:02 -05:00
|| ( spellInfo -> EquippedItemSubClassMask & ITEM_SUBCLASS_MASK_WEAPON_RANGED );
2008-12-31 10:05:45 -06:00
}
2009-10-17 15:51:44 -07:00
2011-06-17 12:00:11 +02:00
SpellCastResult GetErrorAtShapeshiftedCast ( SpellEntry const * spellInfo , uint32 form );
2009-10-17 15:51:44 -07:00
2008-11-17 22:07:21 -06:00
inline bool IsChanneledSpell ( SpellEntry const * spellInfo )
{
2010-12-19 05:15:47 +01:00
return ( spellInfo -> AttributesEx & ( SPELL_ATTR1_CHANNELED_1 | SPELL_ATTR1_CHANNELED_2 ));
2008-11-17 22:07:21 -06:00
}
2009-10-17 15:51:44 -07:00
2008-11-17 22:07:21 -06:00
inline bool NeedsComboPoints ( SpellEntry const * spellInfo )
{
2010-12-19 05:15:47 +01:00
return ( spellInfo -> AttributesEx & ( SPELL_ATTR1_REQ_COMBO_POINTS1 | SPELL_ATTR1_REQ_COMBO_POINTS2 ));
2008-11-17 22:07:21 -06:00
}
2009-10-17 15:51:44 -07:00
2008-11-17 22:07:21 -06:00
inline SpellSchoolMask GetSpellSchoolMask ( SpellEntry const * spellInfo )
{
return SpellSchoolMask ( spellInfo -> SchoolMask );
}
2009-10-17 15:51:44 -07:00
2008-11-17 22:07:21 -06:00
inline uint32 GetSpellMechanicMask ( SpellEntry const * spellInfo , int32 effect )
{
uint32 mask = 0 ;
if ( spellInfo -> Mechanic )
mask |= 1 << spellInfo -> Mechanic ;
if ( spellInfo -> EffectMechanic [ effect ])
mask |= 1 << spellInfo -> EffectMechanic [ effect ];
return mask ;
}
2009-10-17 15:51:44 -07:00
2009-01-09 16:06:17 -06:00
inline uint32 GetAllSpellMechanicMask ( SpellEntry const * spellInfo )
{
uint32 mask = 0 ;
if ( spellInfo -> Mechanic )
mask |= 1 << spellInfo -> Mechanic ;
2010-09-28 08:21:51 +03:00
for ( int i = 0 ; i < MAX_SPELL_EFFECTS ; ++ i )
2010-07-21 01:30:25 +02:00
if ( spellInfo -> Effect [ i ] && spellInfo -> EffectMechanic [ i ])
2009-01-09 16:06:17 -06:00
mask |= 1 << spellInfo -> EffectMechanic [ i ];
return mask ;
}
2009-10-17 15:51:44 -07:00
2008-11-17 22:07:21 -06:00
inline Mechanics GetEffectMechanic ( SpellEntry const * spellInfo , int32 effect )
{
if ( spellInfo -> EffectMechanic [ effect ])
return Mechanics ( spellInfo -> EffectMechanic [ effect ]);
if ( spellInfo -> Mechanic )
return Mechanics ( spellInfo -> Mechanic );
return MECHANIC_NONE ;
}
2009-10-17 15:51:44 -07:00
2008-11-17 22:07:21 -06:00
inline uint32 GetDispellMask ( DispelType dispel )
{
// If dispel all
if ( dispel == DISPEL_ALL )
return DISPEL_ALL_MASK ;
else
2011-03-08 19:11:02 +01:00
return uint32 ( 1 << dispel );
2008-11-17 22:07:21 -06:00
}
2009-10-17 15:51:44 -07:00
2008-11-17 22:07:21 -06:00
// Diminishing Returns interaction with spells
DiminishingGroup GetDiminishingReturnsGroupForSpell ( SpellEntry const * spellproto , bool triggered );
bool IsDiminishingReturnsGroupDurationLimited ( DiminishingGroup group );
DiminishingReturnsType GetDiminishingReturnsGroupType ( DiminishingGroup group );
2010-02-14 19:13:14 -07:00
DiminishingLevels GetDiminishingReturnsMaxLevel ( DiminishingGroup group );
2009-06-27 18:24:40 -05:00
int32 GetDiminishingReturnsLimitDuration ( DiminishingGroup group , SpellEntry const * spellproto );
2009-10-17 15:51:44 -07:00
2008-11-17 22:07:21 -06:00
// Spell proc event related declarations (accessed using SpellMgr functions)
enum ProcFlags
{
2009-07-02 21:32:19 +02:00
PROC_FLAG_NONE = 0x00000000 ,
2009-10-17 15:51:44 -07:00
2010-10-08 19:17:49 +02:00
PROC_FLAG_KILLED = 0x00000001 , // 00 Killed by agressor - not sure about this flag
2009-07-02 21:32:19 +02:00
PROC_FLAG_KILL = 0x00000002 , // 01 Kill target (in most cases need XP/Honor reward)
2009-10-17 15:51:44 -07:00
2010-10-08 19:17:49 +02:00
PROC_FLAG_DONE_MELEE_AUTO_ATTACK = 0x00000004 , // 02 Done melee auto attack
PROC_FLAG_TAKEN_MELEE_AUTO_ATTACK = 0x00000008 , // 03 Taken melee auto attack
PROC_FLAG_DONE_SPELL_MELEE_DMG_CLASS = 0x00000010 , // 04 Done attack by Spell that has dmg class melee
2010-10-08 21:33:44 +02:00
PROC_FLAG_TAKEN_SPELL_MELEE_DMG_CLASS = 0x00000020 , // 05 Taken attack by Spell that has dmg class melee
2010-10-08 19:17:49 +02:00
PROC_FLAG_DONE_RANGED_AUTO_ATTACK = 0x00000040 , // 06 Done ranged auto attack
PROC_FLAG_TAKEN_RANGED_AUTO_ATTACK = 0x00000080 , // 07 Taken ranged auto attack
PROC_FLAG_DONE_SPELL_RANGED_DMG_CLASS = 0x00000100 , // 08 Done attack by Spell that has dmg class ranged
PROC_FLAG_TAKEN_SPELL_RANGED_DMG_CLASS = 0x00000200 , // 09 Taken attack by Spell that has dmg class ranged
PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_POS = 0x00000400 , // 10 Done positive spell that has dmg class none
PROC_FLAG_TAKEN_SPELL_NONE_DMG_CLASS_POS = 0x00000800 , // 11 Taken positive spell that has dmg class none
2010-12-13 22:37:56 +01:00
2010-10-08 19:17:49 +02:00
PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_NEG = 0x00001000 , // 12 Done negative spell that has dmg class none
PROC_FLAG_TAKEN_SPELL_NONE_DMG_CLASS_NEG = 0x00002000 , // 13 Taken negative spell that has dmg class none
2010-12-13 22:37:56 +01:00
2010-10-08 19:17:49 +02:00
PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_POS = 0x00004000 , // 14 Done positive spell that has dmg class magic
PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_POS = 0x00008000 , // 15 Taken positive spell that has dmg class magic
2010-12-13 22:37:56 +01:00
2010-10-08 19:17:49 +02:00
PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG = 0x00010000 , // 16 Done negative spell that has dmg class magic
PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_NEG = 0x00020000 , // 17 Taken negative spell that has dmg class magic
2010-12-13 22:37:56 +01:00
2010-10-08 19:17:49 +02:00
PROC_FLAG_DONE_PERIODIC = 0x00040000 , // 18 Successful do periodic (damage / healing)
PROC_FLAG_TAKEN_PERIODIC = 0x00080000 , // 19 Taken spell periodic (damage / healing)
2010-12-13 22:37:56 +01:00
2010-10-08 19:17:49 +02:00
PROC_FLAG_TAKEN_DAMAGE = 0x00100000 , // 20 Taken any damage
PROC_FLAG_DONE_TRAP_ACTIVATION = 0x00200000 , // 21 On trap activation (possibly needs name change to ON_GAMEOBJECT_CAST or USE)
2010-12-13 22:37:56 +01:00
2010-10-08 19:17:49 +02:00
PROC_FLAG_DONE_MAINHAND_ATTACK = 0x00400000 , // 22 Done main-hand melee attacks (spell and autoattack)
PROC_FLAG_DONE_OFFHAND_ATTACK = 0x00800000 , // 23 Done off-hand melee attacks (spell and autoattack)
2009-10-17 15:51:44 -07:00
2009-07-02 21:32:19 +02:00
PROC_FLAG_DEATH = 0x01000000 // 24 Died in any way
2008-11-26 15:14:03 -06:00
};
2009-10-17 15:51:44 -07:00
2010-10-08 19:17:49 +02:00
#define MELEE_BASED_TRIGGER_MASK (PROC_FLAG_DONE_MELEE_AUTO_ATTACK | \
PROC_FLAG_TAKEN_MELEE_AUTO_ATTACK | \
PROC_FLAG_DONE_SPELL_MELEE_DMG_CLASS | \
PROC_FLAG_TAKEN_SPELL_MELEE_DMG_CLASS | \
PROC_FLAG_DONE_RANGED_AUTO_ATTACK | \
PROC_FLAG_TAKEN_RANGED_AUTO_ATTACK | \
PROC_FLAG_DONE_SPELL_RANGED_DMG_CLASS | \
PROC_FLAG_TAKEN_SPELL_RANGED_DMG_CLASS)
2009-10-17 15:51:44 -07:00
2008-11-26 15:14:03 -06:00
enum ProcFlagsEx
{
PROC_EX_NONE = 0x0000000 , // If none can tigger on Hit/Crit only (passive spells MUST defined by SpellFamily flag)
PROC_EX_NORMAL_HIT = 0x0000001 , // If set only from normal hit (only damage spells)
PROC_EX_CRITICAL_HIT = 0x0000002 ,
PROC_EX_MISS = 0x0000004 ,
PROC_EX_RESIST = 0x0000008 ,
PROC_EX_DODGE = 0x0000010 ,
PROC_EX_PARRY = 0x0000020 ,
PROC_EX_BLOCK = 0x0000040 ,
PROC_EX_EVADE = 0x0000080 ,
PROC_EX_IMMUNE = 0x0000100 ,
PROC_EX_DEFLECT = 0x0000200 ,
PROC_EX_ABSORB = 0x0000400 ,
PROC_EX_REFLECT = 0x0000800 ,
2008-12-28 12:10:31 -06:00
PROC_EX_INTERRUPT = 0x0001000 , // Melee hit result can be Interrupt (not used)
2010-02-14 19:13:14 -07:00
PROC_EX_FULL_BLOCK = 0x0002000 , // block al attack damage
PROC_EX_RESERVED2 = 0x0004000 ,
2009-07-09 23:49:46 +02:00
PROC_EX_NOT_ACTIVE_SPELL = 0x0008000 , // Spell mustn't do damage/heal to proc
PROC_EX_EX_TRIGGER_ALWAYS = 0x0010000 , // If set trigger always no matter of hit result
PROC_EX_EX_ONE_TIME_TRIGGER = 0x0020000 , // If set trigger always but only one time (not implemented yet)
PROC_EX_ONLY_ACTIVE_SPELL = 0x0040000 , // Spell has to do damage/heal to proc
2009-10-17 15:51:44 -07:00
2009-07-02 21:32:19 +02:00
// Flags for internal use - do not use these in db!
PROC_EX_INTERNAL_CANT_PROC = 0x0800000 ,
PROC_EX_INTERNAL_DOT = 0x1000000 ,
PROC_EX_INTERNAL_HOT = 0x2000000 ,
PROC_EX_INTERNAL_TRIGGERED = 0x4000000 ,
PROC_EX_INTERNAL_REQ_FAMILY = 0x8000000
2008-11-17 22:07:21 -06:00
};
2009-10-17 15:51:44 -07:00
2009-04-18 21:25:48 +02:00
#define AURA_SPELL_PROC_EX_MASK \
(PROC_EX_NORMAL_HIT | PROC_EX_CRITICAL_HIT | PROC_EX_MISS | \
PROC_EX_RESIST | PROC_EX_DODGE | PROC_EX_PARRY | PROC_EX_BLOCK | \
PROC_EX_EVADE | PROC_EX_IMMUNE | PROC_EX_DEFLECT | \
PROC_EX_ABSORB | PROC_EX_REFLECT | PROC_EX_INTERRUPT)
2009-10-17 15:51:44 -07:00
2008-11-17 22:07:21 -06:00
struct SpellProcEventEntry
{
uint32 schoolMask ; // if nonzero - bit mask for matching proc condition based on spell candidate's school: Fire=2, Mask=1<<(2-1)=2
uint32 spellFamilyName ; // if nonzero - for matching proc condition based on candidate spell's SpellFamilyNamer value
2009-02-02 17:01:56 +01:00
flag96 spellFamilyMask ; // if nonzero - for matching proc condition based on candidate spell's SpellFamilyFlags (like auras 107 and 108 do)
2008-11-17 22:07:21 -06:00
uint32 procFlags ; // bitmask for matching proc event
2008-11-26 15:14:03 -06:00
uint32 procEx ; // proc Extend info (see ProcFlagsEx)
2008-11-17 22:07:21 -06:00
float ppmRate ; // for melee (ranged?) damage spells - proc rate per minute. if zero, falls back to flat chance from Spell.dbc
2008-11-26 15:14:03 -06:00
float customChance ; // Owerride chance (in most cases for debug only)
2008-11-17 22:07:21 -06:00
uint32 cooldown ; // hidden cooldown used for some spell proc events, applied to _triggered_spell_
};
2009-10-17 15:51:44 -07:00
2009-01-29 19:33:39 -06:00
struct SpellBonusEntry
{
float direct_damage ;
float dot_damage ;
float ap_bonus ;
2009-07-18 22:18:47 +02:00
float ap_dot_bonus ;
2009-01-29 19:33:39 -06:00
};
2009-10-17 15:51:44 -07:00
2008-11-17 22:07:21 -06:00
typedef UNORDERED_MAP < uint32 , SpellProcEventEntry > SpellProcEventMap ;
2009-10-17 15:51:44 -07:00
2009-05-15 16:37:22 +02:00
struct SpellEnchantProcEntry
{
uint32 customChance ;
float PPMChance ;
uint32 procEx ;
};
2009-10-17 15:51:44 -07:00
2009-05-15 16:37:22 +02:00
typedef UNORDERED_MAP < uint32 , SpellEnchantProcEntry > SpellEnchantProcEventMap ;
2009-01-29 19:33:39 -06:00
typedef UNORDERED_MAP < uint32 , SpellBonusEntry > SpellBonusMap ;
2009-10-17 15:51:44 -07:00
2010-02-01 19:22:32 +01:00
enum SpellGroup
{
SPELL_GROUP_ELIXIR_BATTLE = 1 ,
SPELL_GROUP_ELIXIR_GUARDIAN = 2 ,
SPELL_GROUP_ELIXIR_UNSTABLE = 3 ,
SPELL_GROUP_ELIXIR_SHATTRATH = 4 ,
2010-02-02 22:35:01 +01:00
SPELL_GROUP_CORE_RANGE_MAX = 5 ,
2010-02-01 19:22:32 +01:00
};
2010-02-02 22:35:01 +01:00
#define SPELL_GROUP_DB_RANGE_MIN 1000
2010-02-03 02:41:10 +01:00
// spell_id, group_id
2010-02-02 22:35:01 +01:00
typedef std :: multimap < uint32 , SpellGroup > SpellSpellGroupMap ;
2011-04-29 20:47:02 +02:00
typedef std :: pair < SpellSpellGroupMap :: const_iterator , SpellSpellGroupMap :: const_iterator > SpellSpellGroupMapBounds ;
2010-02-01 19:22:32 +01:00
// group_id, spell_id
2010-02-02 22:35:01 +01:00
typedef std :: multimap < SpellGroup , int32 > SpellGroupSpellMap ;
2011-04-29 20:47:02 +02:00
typedef std :: pair < SpellGroupSpellMap :: const_iterator , SpellGroupSpellMap :: const_iterator > SpellGroupSpellMapBounds ;
2010-02-01 19:22:32 +01:00
2010-02-02 22:35:01 +01:00
enum SpellGroupStackRule
{
SPELL_GROUP_STACK_RULE_DEFAULT = 0 ,
SPELL_GROUP_STACK_RULE_EXCLUSIVE = 1 ,
SPELL_GROUP_STACK_RULE_EXCLUSIVE_FROM_SAME_CASTER = 2 ,
};
#define SPELL_GROUP_STACK_RULE_MAX 3
typedef std :: map < SpellGroup , SpellGroupStackRule > SpellGroupStackMap ;
2009-07-30 11:37:08 +08:00
typedef std :: map < uint32 , uint16 > SpellThreatMap ;
2009-10-17 15:51:44 -07:00
2008-11-17 22:07:21 -06:00
// Spell script target related declarations (accessed using SpellMgr functions)
2008-12-20 19:33:03 -06:00
enum SpellScriptTargetType
2008-11-17 22:07:21 -06:00
{
SPELL_TARGET_TYPE_GAMEOBJECT = 0 ,
SPELL_TARGET_TYPE_CREATURE = 1 ,
2009-08-04 19:28:31 +02:00
SPELL_TARGET_TYPE_DEAD = 2 ,
SPELL_TARGET_TYPE_CONTROLLED = 3 ,
2008-11-17 22:07:21 -06:00
};
2009-10-17 15:51:44 -07:00
2009-08-04 19:28:31 +02:00
#define MAX_SPELL_TARGET_TYPE 4
2009-10-17 15:51:44 -07:00
2008-11-17 22:07:21 -06:00
// coordinates for spells (accessed using SpellMgr functions)
struct SpellTargetPosition
{
uint32 target_mapId ;
float target_X ;
float target_Y ;
float target_Z ;
float target_Orientation ;
};
2009-10-17 15:51:44 -07:00
2008-11-17 22:07:21 -06:00
typedef UNORDERED_MAP < uint32 , SpellTargetPosition > SpellTargetPositionMap ;
2009-10-17 15:51:44 -07:00
2008-11-17 22:07:21 -06:00
// Spell pet auras
class PetAura
{
public :
PetAura ()
{
auras . clear ();
}
2009-10-17 15:51:44 -07:00
2009-07-01 18:07:20 -05:00
PetAura ( uint32 petEntry , uint32 aura , bool _removeOnChangePet , int _damage ) :
2008-11-17 22:07:21 -06:00
removeOnChangePet ( _removeOnChangePet ), damage ( _damage )
{
auras [ petEntry ] = aura ;
}
2009-10-17 15:51:44 -07:00
2009-07-01 18:07:20 -05:00
uint32 GetAura ( uint32 petEntry ) const
2008-11-17 22:07:21 -06:00
{
2009-07-01 18:07:20 -05:00
std :: map < uint32 , uint32 >:: const_iterator itr = auras . find ( petEntry );
2010-04-07 19:14:10 +02:00
if ( itr != auras . end ())
2008-11-17 22:07:21 -06:00
return itr -> second ;
2009-07-12 02:34:24 +02:00
std :: map < uint32 , uint32 >:: const_iterator itr2 = auras . find ( 0 );
2010-04-07 19:14:10 +02:00
if ( itr2 != auras . end ())
2009-07-12 02:34:24 +02:00
return itr2 -> second ;
return 0 ;
2008-11-17 22:07:21 -06:00
}
2009-10-17 15:51:44 -07:00
2009-07-01 18:07:20 -05:00
void AddAura ( uint32 petEntry , uint32 aura )
2008-11-17 22:07:21 -06:00
{
auras [ petEntry ] = aura ;
}
2009-10-17 15:51:44 -07:00
2008-11-17 22:07:21 -06:00
bool IsRemovedOnChangePet () const
{
return removeOnChangePet ;
}
2009-10-17 15:51:44 -07:00
2008-11-17 22:07:21 -06:00
int32 GetDamage () const
{
return damage ;
}
2009-10-17 15:51:44 -07:00
2008-11-17 22:07:21 -06:00
private :
2009-07-01 18:07:20 -05:00
std :: map < uint32 , uint32 > auras ;
2008-11-17 22:07:21 -06:00
bool removeOnChangePet ;
int32 damage ;
};
2009-06-23 14:05:37 +02:00
typedef std :: map < uint32 , PetAura > SpellPetAuraMap ;
2009-10-17 15:51:44 -07:00
2009-02-27 12:53:27 -06:00
struct SpellArea
{
uint32 spellId ;
uint32 areaId ; // zone/subzone/or 0 is not limited to zone
uint32 questStart ; // quest start (quest must be active or rewarded for spell apply)
uint32 questEnd ; // quest end (quest don't must be rewarded for spell apply)
2010-04-07 22:59:46 +02:00
int32 auraSpell ; // spell aura must be applied for spell apply)if possitive) and it don't must be applied in other case
2009-02-27 12:53:27 -06:00
uint32 raceMask ; // can be applied only to races
Gender gender ; // can be applied only to gender
bool questStartCanActive ; // if true then quest start can be active (not only rewarded)
bool autocast ; // if true then auto applied at area enter, in other case just allowed to cast
2009-10-17 15:51:44 -07:00
2009-02-27 12:53:27 -06:00
// helpers
bool IsFitToRequirements ( Player const * player , uint32 newZone , uint32 newArea ) const ;
};
2009-10-17 15:51:44 -07:00
2011-04-29 20:47:02 +02:00
typedef std :: multimap < uint32 , SpellArea > SpellAreaMap ;
typedef std :: multimap < uint32 , SpellArea const *> SpellAreaForQuestMap ;
typedef std :: multimap < uint32 , SpellArea const *> SpellAreaForAuraMap ;
typedef std :: multimap < uint32 , SpellArea const *> SpellAreaForAreaMap ;
typedef std :: pair < SpellAreaMap :: const_iterator , SpellAreaMap :: const_iterator > SpellAreaMapBounds ;
typedef std :: pair < SpellAreaForQuestMap :: const_iterator , SpellAreaForQuestMap :: const_iterator > SpellAreaForQuestMapBounds ;
2009-02-27 12:53:27 -06:00
typedef std :: pair < SpellAreaForAuraMap :: const_iterator , SpellAreaForAuraMap :: const_iterator > SpellAreaForAuraMapBounds ;
typedef std :: pair < SpellAreaForAreaMap :: const_iterator , SpellAreaForAreaMap :: const_iterator > SpellAreaForAreaMapBounds ;
2008-11-17 22:07:21 -06:00
// Spell rank chain (accessed using SpellMgr functions)
struct SpellChainNode
{
uint32 prev ;
2008-12-14 23:01:02 +01:00
uint32 next ;
2008-11-17 22:07:21 -06:00
uint32 first ;
2008-12-14 23:01:02 +01:00
uint32 last ;
2008-11-17 22:07:21 -06:00
uint8 rank ;
};
2009-10-17 15:51:44 -07:00
2008-11-17 22:07:21 -06:00
typedef UNORDERED_MAP < uint32 , SpellChainNode > SpellChainMap ;
2009-10-17 15:51:44 -07:00
2010-01-30 19:25:04 +01:00
// spell_id req_spell
typedef std :: multimap < uint32 , uint32 > SpellRequiredMap ;
2011-04-29 20:47:02 +02:00
typedef std :: pair < SpellRequiredMap :: const_iterator , SpellRequiredMap :: const_iterator > SpellRequiredMapBounds ;
2009-10-17 15:51:44 -07:00
2010-01-30 19:25:04 +01:00
// req_spell spell_id
2008-12-22 02:11:11 +01:00
typedef std :: multimap < uint32 , uint32 > SpellsRequiringSpellMap ;
2011-04-29 20:47:02 +02:00
typedef std :: pair < SpellsRequiringSpellMap :: const_iterator , SpellsRequiringSpellMap :: const_iterator > SpellsRequiringSpellMapBounds ;
2009-10-17 15:51:44 -07:00
2008-11-17 22:07:21 -06:00
// Spell learning properties (accessed using SpellMgr functions)
struct SpellLearnSkillNode
{
2010-04-11 20:20:38 +02:00
uint16 skill ;
uint16 step ;
2010-04-11 11:16:42 +04:00
uint16 value ; // 0 - max skill value for player level
uint16 maxvalue ; // 0 - max skill value for player level
2008-11-17 22:07:21 -06:00
};
2009-10-17 15:51:44 -07:00
2008-11-17 22:07:21 -06:00
typedef std :: map < uint32 , SpellLearnSkillNode > SpellLearnSkillMap ;
2009-10-17 15:51:44 -07:00
2008-11-17 22:07:21 -06:00
struct SpellLearnSpellNode
{
uint32 spell ;
2009-01-12 10:53:53 -06:00
bool active ; // show in spellbook or not
2008-11-17 22:07:21 -06:00
bool autoLearned ;
};
2009-10-17 15:51:44 -07:00
2008-11-17 22:07:21 -06:00
typedef std :: multimap < uint32 , SpellLearnSpellNode > SpellLearnSpellMap ;
2011-04-29 20:47:02 +02:00
typedef std :: pair < SpellLearnSpellMap :: const_iterator , SpellLearnSpellMap :: const_iterator > SpellLearnSpellMapBounds ;
2009-10-17 15:51:44 -07:00
2008-11-17 22:07:21 -06:00
typedef std :: multimap < uint32 , SkillLineAbilityEntry const *> SkillLineAbilityMap ;
2011-04-29 20:47:02 +02:00
typedef std :: pair < SkillLineAbilityMap :: const_iterator , SkillLineAbilityMap :: const_iterator > SkillLineAbilityMapBounds ;
2009-10-17 15:51:44 -07:00
2009-05-17 10:57:55 -05:00
typedef std :: multimap < uint32 , uint32 > PetLevelupSpellSet ;
typedef std :: map < uint32 , PetLevelupSpellSet > PetLevelupSpellMap ;
2009-10-17 15:51:44 -07:00
2010-04-09 10:47:11 +02:00
typedef std :: map < uint32 , uint32 > SpellDifficultySearcherMap ;
2009-05-24 12:16:12 -05:00
struct PetDefaultSpellsEntry
{
uint32 spellid [ MAX_CREATURE_SPELL_DATA_SLOT ];
};
2009-10-17 15:51:44 -07:00
2009-05-24 12:16:12 -05:00
// < 0 for petspelldata id, > 0 for creature_id
typedef std :: map < int32 , PetDefaultSpellsEntry > PetDefaultSpellsMap ;
2008-11-17 22:07:21 -06:00
inline bool IsPrimaryProfessionSkill ( uint32 skill )
{
SkillLineEntry const * pSkill = sSkillLineStore . LookupEntry ( skill );
2010-04-07 19:14:10 +02:00
if ( ! pSkill )
2008-11-17 22:07:21 -06:00
return false ;
2009-10-17 15:51:44 -07:00
2010-04-07 19:14:10 +02:00
if ( pSkill -> categoryId != SKILL_CATEGORY_PROFESSION )
2008-11-17 22:07:21 -06:00
return false ;
2009-10-17 15:51:44 -07:00
2008-11-17 22:07:21 -06:00
return true ;
}
2009-10-17 15:51:44 -07:00
2008-11-17 22:07:21 -06:00
inline bool IsProfessionSkill ( uint32 skill )
{
return IsPrimaryProfessionSkill ( skill ) || skill == SKILL_FISHING || skill == SKILL_COOKING || skill == SKILL_FIRST_AID ;
}
2009-10-17 15:51:44 -07:00
2010-12-21 11:40:20 +01:00
enum SpellCustomAttributes
{
SPELL_ATTR0_CU_ENCHANT_PROC = 0x00000001 ,
SPELL_ATTR0_CU_CONE_BACK = 0x00000002 ,
SPELL_ATTR0_CU_CONE_LINE = 0x00000004 ,
SPELL_ATTR0_CU_SHARE_DAMAGE = 0x00000008 ,
SPELL_ATTR0_CU_NONE1 = 0x00000010 , // UNUSED
SPELL_ATTR0_CU_NONE2 = 0x00000020 , // UNUSED
SPELL_ATTR0_CU_AURA_CC = 0x00000040 ,
SPELL_ATTR0_CU_DIRECT_DAMAGE = 0x00000100 ,
SPELL_ATTR0_CU_CHARGE = 0x00000200 ,
SPELL_ATTR0_CU_LINK_CAST = 0x00000400 ,
SPELL_ATTR0_CU_LINK_HIT = 0x00000800 ,
SPELL_ATTR0_CU_LINK_AURA = 0x00001000 ,
SPELL_ATTR0_CU_LINK_REMOVE = 0x00002000 ,
SPELL_ATTR0_CU_PICKPOCKET = 0x00004000 ,
SPELL_ATTR0_CU_EXCLUDE_SELF = 0x00008000 ,
SPELL_ATTR0_CU_NEGATIVE_EFF0 = 0x00010000 ,
SPELL_ATTR0_CU_NEGATIVE_EFF1 = 0x00020000 ,
SPELL_ATTR0_CU_NEGATIVE_EFF2 = 0x00040000 ,
SPELL_ATTR0_CU_IGNORE_ARMOR = 0x00080000 ,
SPELL_ATTR0_CU_NEGATIVE = SPELL_ATTR0_CU_NEGATIVE_EFF0 | SPELL_ATTR0_CU_NEGATIVE_EFF1 | SPELL_ATTR0_CU_NEGATIVE_EFF2 ,
};
2008-12-09 17:40:33 -06:00
typedef std :: vector < uint32 > SpellCustomAttribute ;
2009-05-24 22:54:13 +02:00
typedef std :: vector < bool > EnchantCustomAttribute ;
2009-10-17 15:51:44 -07:00
2008-11-17 22:07:21 -06:00
typedef std :: map < int32 , std :: vector < int32 > > SpellLinkedMap ;
2009-10-17 15:51:44 -07:00
2009-01-14 00:35:13 -06:00
inline bool IsProfessionOrRidingSkill ( uint32 skill )
{
return IsProfessionSkill ( skill ) || skill == SKILL_RIDING ;
}
2009-10-17 15:51:44 -07:00
2010-12-27 22:27:11 +01:00
bool IsPartOfSkillLine ( uint32 skillId , uint32 spellId );
2008-11-17 22:07:21 -06:00
class SpellMgr
{
2010-12-22 20:52:47 +01:00
friend class ACE_Singleton < SpellMgr , ACE_Null_Mutex > ;
2008-11-17 22:07:21 -06:00
SpellMgr ();
~ SpellMgr ();
2009-10-17 15:51:44 -07:00
2009-02-13 19:50:20 -06:00
// Accessors (const or static functions)
2008-11-17 22:07:21 -06:00
public :
2009-10-17 15:51:44 -07:00
2008-12-24 09:58:26 -06:00
bool IsAffectedByMod ( SpellEntry const * spellInfo , SpellModifier * mod ) const ;
2009-10-17 15:51:44 -07:00
2010-04-07 18:09:10 +02:00
SpellSpellGroupMapBounds GetSpellSpellGroupMapBounds ( uint32 spell_id ) const
2008-11-17 22:07:21 -06:00
{
2010-02-01 19:22:32 +01:00
spell_id = GetFirstSpellInChain ( spell_id );
2011-04-29 20:47:02 +02:00
return SpellSpellGroupMapBounds ( mSpellSpellGroup . lower_bound ( spell_id ), mSpellSpellGroup . upper_bound ( spell_id ));
2010-02-01 19:22:32 +01:00
}
uint32 IsSpellMemberOfSpellGroup ( uint32 spellid , SpellGroup groupid ) const
{
SpellSpellGroupMapBounds spellGroup = GetSpellSpellGroupMapBounds ( spellid );
2010-04-07 22:59:46 +02:00
for ( SpellSpellGroupMap :: const_iterator itr = spellGroup . first ; itr != spellGroup . second ; ++ itr )
2010-02-01 19:22:32 +01:00
{
if ( itr -> second == groupid )
return true ;
}
return false ;
2008-11-17 22:07:21 -06:00
}
2009-10-17 15:51:44 -07:00
2010-04-07 18:09:10 +02:00
SpellGroupSpellMapBounds GetSpellGroupSpellMapBounds ( SpellGroup group_id ) const
2010-02-01 19:22:32 +01:00
{
2011-04-29 20:47:02 +02:00
return SpellGroupSpellMapBounds ( mSpellGroupSpell . lower_bound ( group_id ), mSpellGroupSpell . upper_bound ( group_id ));
2010-02-01 19:22:32 +01:00
}
2010-04-07 18:09:10 +02:00
void GetSetOfSpellsInSpellGroup ( SpellGroup group_id , std :: set < uint32 >& foundSpells ) const
2008-11-17 22:07:21 -06:00
{
2010-02-02 22:35:01 +01:00
std :: set < SpellGroup > usedGroups ;
GetSetOfSpellsInSpellGroup ( group_id , foundSpells , usedGroups );
}
2010-04-07 18:09:10 +02:00
void GetSetOfSpellsInSpellGroup ( SpellGroup group_id , std :: set < uint32 >& foundSpells , std :: set < SpellGroup >& usedGroups ) const
2010-02-02 22:35:01 +01:00
{
if ( usedGroups . find ( group_id ) != usedGroups . end ())
return ;
usedGroups . insert ( group_id );
SpellGroupSpellMapBounds groupSpell = GetSpellGroupSpellMapBounds ( group_id );
2010-04-07 22:59:46 +02:00
for ( SpellGroupSpellMap :: const_iterator itr = groupSpell . first ; itr != groupSpell . second ; ++ itr )
2010-02-01 19:22:32 +01:00
{
2010-02-02 22:35:01 +01:00
if ( itr -> second < 0 )
2010-02-01 19:22:32 +01:00
{
2010-02-02 22:35:01 +01:00
SpellGroup currGroup = ( SpellGroup ) abs ( itr -> second );
GetSetOfSpellsInSpellGroup ( currGroup , foundSpells , usedGroups );
}
else
{
foundSpells . insert ( itr -> second );
2010-02-01 19:22:32 +01:00
}
}
2008-11-17 22:07:21 -06:00
}
2009-10-17 15:51:44 -07:00
2010-02-02 22:35:01 +01:00
SpellGroupStackRule CheckSpellGroupStackRules ( uint32 spellid_1 , uint32 spellid_2 ) const
2010-01-23 17:05:20 +01:00
{
2010-02-02 22:35:01 +01:00
spellid_1 = GetFirstSpellInChain ( spellid_1 );
spellid_2 = GetFirstSpellInChain ( spellid_2 );
2010-02-04 18:34:46 +01:00
if ( spellid_1 == spellid_2 )
return SPELL_GROUP_STACK_RULE_DEFAULT ;
2010-02-02 22:35:01 +01:00
// find SpellGroups which are common for both spells
SpellSpellGroupMapBounds spellGroup1 = GetSpellSpellGroupMapBounds ( spellid_1 );
std :: set < SpellGroup > groups ;
2010-04-07 22:59:46 +02:00
for ( SpellSpellGroupMap :: const_iterator itr = spellGroup1 . first ; itr != spellGroup1 . second ; ++ itr )
2010-01-23 17:05:20 +01:00
{
2010-02-02 22:35:01 +01:00
if ( IsSpellMemberOfSpellGroup ( spellid_2 , itr -> second ))
{
bool add = true ;
SpellGroupSpellMapBounds groupSpell = GetSpellGroupSpellMapBounds ( itr -> second );
2010-04-07 22:59:46 +02:00
for ( SpellGroupSpellMap :: const_iterator itr2 = groupSpell . first ; itr2 != groupSpell . second ; ++ itr2 )
2010-02-02 22:35:01 +01:00
{
if ( itr2 -> second < 0 )
{
SpellGroup currGroup = ( SpellGroup ) abs ( itr2 -> second );
if ( IsSpellMemberOfSpellGroup ( spellid_1 , currGroup ) && IsSpellMemberOfSpellGroup ( spellid_2 , currGroup ))
{
add = false ;
break ;
}
}
}
if ( add )
groups . insert ( itr -> second );
}
2010-01-23 17:05:20 +01:00
}
2010-02-02 22:35:01 +01:00
SpellGroupStackRule rule = SPELL_GROUP_STACK_RULE_DEFAULT ;
for ( std :: set < SpellGroup >:: iterator itr = groups . begin () ; itr != groups . end () ; ++ itr )
{
SpellGroupStackMap :: const_iterator found = mSpellGroupStack . find ( * itr );
if ( found != mSpellGroupStack . end ())
rule = found -> second ;
if ( rule )
break ;
}
return rule ;
2010-01-23 17:05:20 +01:00
}
2009-07-30 11:37:08 +08:00
uint16 GetSpellThreat ( uint32 spellid ) const
{
SpellThreatMap :: const_iterator itr = mSpellThreatMap . find ( spellid );
2010-04-07 23:25:02 +02:00
if ( itr == mSpellThreatMap . end ())
2009-07-30 11:37:08 +08:00
return 0 ;
2009-10-17 15:51:44 -07:00
2009-07-30 11:37:08 +08:00
return itr -> second ;
}
2009-10-17 15:51:44 -07:00
2008-11-17 22:07:21 -06:00
// Spell proc events
SpellProcEventEntry const * GetSpellProcEvent ( uint32 spellId ) const
{
SpellProcEventMap :: const_iterator itr = mSpellProcEventMap . find ( spellId );
2010-04-07 22:59:46 +02:00
if ( itr != mSpellProcEventMap . end ())
2008-11-17 22:07:21 -06:00
return & itr -> second ;
return NULL ;
}
2009-10-17 15:51:44 -07:00
2011-06-11 22:35:29 +02:00
bool IsSpellProcEventCanTriggeredBy ( SpellProcEventEntry const * spellProcEvent , uint32 EventProcFlag , SpellEntry const * procSpell , uint32 procFlags , uint32 procExtra , bool active );
2009-10-17 15:51:44 -07:00
2009-05-15 16:37:22 +02:00
SpellEnchantProcEntry const * GetSpellEnchantProcEvent ( uint32 enchId ) const
{
SpellEnchantProcEventMap :: const_iterator itr = mSpellEnchantProcEventMap . find ( enchId );
2010-04-07 22:59:46 +02:00
if ( itr != mSpellEnchantProcEventMap . end ())
2009-05-15 16:37:22 +02:00
return & itr -> second ;
return NULL ;
}
2009-10-17 15:51:44 -07:00
2009-01-29 19:33:39 -06:00
// Spell bonus data
SpellBonusEntry const * GetSpellBonusData ( uint32 spellId ) const
{
// Lookup data
SpellBonusMap :: const_iterator itr = mSpellBonusMap . find ( spellId );
2010-04-07 22:59:46 +02:00
if ( itr != mSpellBonusMap . end ())
2009-01-29 19:33:39 -06:00
return & itr -> second ;
2009-07-31 13:21:01 +02:00
// Not found, try lookup for 1 spell rank if exist
if ( uint32 rank_1 = GetFirstSpellInChain ( spellId ))
{
SpellBonusMap :: const_iterator itr2 = mSpellBonusMap . find ( rank_1 );
2010-04-07 22:59:46 +02:00
if ( itr2 != mSpellBonusMap . end ())
2009-07-31 13:21:01 +02:00
return & itr2 -> second ;
}
2009-01-29 19:33:39 -06:00
return NULL ;
}
2009-10-17 15:51:44 -07:00
2011-05-17 13:17:42 +02:00
uint32 GetSpellIdForDifficulty ( uint32 spellId , Unit * caster ) const
2010-04-09 10:47:11 +02:00
{
2011-05-17 13:17:42 +02:00
if ( ! sSpellStore . LookupEntry ( spellId ))
return spellId ;
2010-04-10 10:20:01 +02:00
2011-05-17 13:17:42 +02:00
if ( ! caster || ! caster -> GetMap () || ! caster -> GetMap () -> IsDungeon ())
return spellId ;
uint32 mode = uint32 ( caster -> GetMap () -> GetSpawnMode ());
2010-04-22 19:39:19 +02:00
if ( mode >= MAX_DIFFICULTY )
2010-04-09 10:47:11 +02:00
{
2011-05-17 13:17:42 +02:00
sLog -> outError ( "SpellMgr::GetSpellIdForDifficulty: Incorrect Difficulty for spell %u." , spellId );
return spellId ; //return source spell
2010-04-09 10:47:11 +02:00
}
2010-04-10 10:20:01 +02:00
2011-05-17 13:17:42 +02:00
uint32 difficultyId = GetSpellDifficultyId ( spellId );
if ( ! difficultyId )
return spellId ; //return source spell, it has only REGULAR_DIFFICULTY
SpellDifficultyEntry const * difficultyEntry = sSpellDifficultyStore . LookupEntry ( difficultyId );
if ( ! difficultyEntry )
2010-04-09 10:47:11 +02:00
{
2011-05-17 13:17:42 +02:00
sLog -> outDebug ( LOG_FILTER_SPELLS_AURAS , "SpellMgr::GetSpellIdForDifficulty: SpellDifficultyEntry not found for spell %u. This should never happen." , spellId );
return spellId ; //return source spell
2010-04-09 10:47:11 +02:00
}
2011-05-17 13:17:42 +02:00
if ( difficultyEntry -> SpellID [ mode ] <= 0 && mode > DUNGEON_DIFFICULTY_HEROIC )
2010-04-09 10:47:11 +02:00
{
2011-05-17 13:17:42 +02:00
sLog -> outDebug ( LOG_FILTER_SPELLS_AURAS , "SpellMgr::GetSpellIdForDifficulty: spell %u mode %u spell is NULL, using mode %u" , spellId , mode , mode - 2 );
2010-04-09 10:47:11 +02:00
mode -= 2 ;
}
2011-05-17 13:17:42 +02:00
if ( difficultyEntry -> SpellID [ mode ] <= 0 )
2010-04-09 10:47:11 +02:00
{
2011-05-17 13:17:42 +02:00
sLog -> outErrorDb ( "SpellMgr::GetSpellIdForDifficulty: spell %u mode %u spell is 0. Check spelldifficulty_dbc!" , spellId , mode );
return spellId ;
2010-04-10 10:20:01 +02:00
}
2011-05-17 13:17:42 +02:00
sLog -> outDebug ( LOG_FILTER_SPELLS_AURAS , "SpellMgr::GetSpellIdForDifficulty: spellid for spell %u in mode %u is %d" , spellId , mode , difficultyEntry -> SpellID [ mode ]);
return uint32 ( difficultyEntry -> SpellID [ mode ]);
}
// Spell Difficulty data
SpellEntry const * GetSpellForDifficultyFromSpell ( SpellEntry const * spell , Unit * caster ) const
{
uint32 newSpellId = GetSpellIdForDifficulty ( spell -> Id , caster );
SpellEntry const * newSpell = sSpellStore . LookupEntry ( newSpellId );
2010-04-10 10:20:01 +02:00
if ( ! newSpell )
{
2011-05-17 13:17:42 +02:00
sLog -> outDebug ( LOG_FILTER_SPELLS_AURAS , "SpellMgr::GetSpellForDifficultyFromSpell: spell %u not found in sSpellStore. Check spelldifficulty_dbc!" , newSpellId );
2010-04-11 20:20:38 +02:00
return spell ;
2010-04-09 10:47:11 +02:00
}
2011-05-17 13:17:42 +02:00
sLog -> outDebug ( LOG_FILTER_SPELLS_AURAS , "SpellMgr::GetSpellForDifficultyFromSpell: Spell id for instance mode is %u (original %u)" , newSpell -> Id , spell -> Id );
2010-04-10 10:20:01 +02:00
return newSpell ;
2010-04-09 10:47:11 +02:00
}
2008-11-17 22:07:21 -06:00
// Spell target coordinates
SpellTargetPosition const * GetSpellTargetPosition ( uint32 spell_id ) const
{
2010-04-07 22:59:46 +02:00
SpellTargetPositionMap :: const_iterator itr = mSpellTargetPositions . find ( spell_id );
if ( itr != mSpellTargetPositions . end ())
2008-11-17 22:07:21 -06:00
return & itr -> second ;
return NULL ;
}
2009-10-17 15:51:44 -07:00
2008-11-17 22:07:21 -06:00
// Spell ranks chains
SpellChainNode const * GetSpellChainNode ( uint32 spell_id ) const
{
SpellChainMap :: const_iterator itr = mSpellChains . find ( spell_id );
2010-04-07 19:14:10 +02:00
if ( itr == mSpellChains . end ())
2008-11-17 22:07:21 -06:00
return NULL ;
2009-10-17 15:51:44 -07:00
2008-11-17 22:07:21 -06:00
return & itr -> second ;
}
2009-10-17 15:51:44 -07:00
2008-11-17 22:07:21 -06:00
uint32 GetFirstSpellInChain ( uint32 spell_id ) const
{
2010-04-07 19:14:10 +02:00
if ( SpellChainNode const * node = GetSpellChainNode ( spell_id ))
2008-11-17 22:07:21 -06:00
return node -> first ;
2009-10-17 15:51:44 -07:00
2008-11-17 22:07:21 -06:00
return spell_id ;
}
2009-10-17 15:51:44 -07:00
2010-08-01 03:23:14 +02:00
// not strict check returns provided spell if rank not avalible
uint32 GetSpellWithRank ( uint32 spell_id , uint32 rank , bool strict = false ) const
2009-08-14 13:26:38 +02:00
{
2010-04-07 19:14:10 +02:00
if ( SpellChainNode const * node = GetSpellChainNode ( spell_id ))
2009-08-14 13:26:38 +02:00
{
if ( rank != node -> rank )
2010-08-01 03:23:14 +02:00
return GetSpellWithRank ( node -> rank < rank ? node -> next : node -> prev , rank , strict );
2009-08-14 13:26:38 +02:00
}
2010-08-01 03:23:14 +02:00
else if ( strict && rank > 1 )
return 0 ;
2009-08-14 13:26:38 +02:00
return spell_id ;
}
2009-10-17 15:51:44 -07:00
2008-11-17 22:07:21 -06:00
uint32 GetPrevSpellInChain ( uint32 spell_id ) const
{
2010-04-07 19:14:10 +02:00
if ( SpellChainNode const * node = GetSpellChainNode ( spell_id ))
2008-11-17 22:07:21 -06:00
return node -> prev ;
2009-10-17 15:51:44 -07:00
2008-11-17 22:07:21 -06:00
return 0 ;
}
2009-10-17 15:51:44 -07:00
2009-01-25 16:35:14 -06:00
uint32 GetNextSpellInChain ( uint32 spell_id ) const
{
2010-04-07 19:14:10 +02:00
if ( SpellChainNode const * node = GetSpellChainNode ( spell_id ))
2009-01-25 16:35:14 -06:00
return node -> next ;
2009-10-17 15:51:44 -07:00
2009-01-25 16:35:14 -06:00
return 0 ;
}
2009-10-17 15:51:44 -07:00
2010-04-07 18:09:10 +02:00
SpellRequiredMapBounds GetSpellsRequiredForSpellBounds ( uint32 spell_id ) const
{
2011-04-29 20:47:02 +02:00
return SpellRequiredMapBounds ( mSpellReq . lower_bound ( spell_id ), mSpellReq . upper_bound ( spell_id ));
2010-01-30 19:25:04 +01:00
}
2010-04-07 18:09:10 +02:00
SpellsRequiringSpellMapBounds GetSpellsRequiringSpellBounds ( uint32 spell_id ) const
{
2011-04-29 20:47:02 +02:00
return SpellsRequiringSpellMapBounds ( mSpellsReqSpell . lower_bound ( spell_id ), mSpellsReqSpell . upper_bound ( spell_id ));
2010-01-30 19:25:04 +01:00
}
2010-04-07 18:09:10 +02:00
bool IsSpellRequiringSpell ( uint32 spellid , uint32 req_spellid ) const
2010-01-30 19:25:04 +01:00
{
SpellsRequiringSpellMapBounds spellsRequiringSpell = GetSpellsRequiringSpellBounds ( req_spellid );
for ( SpellsRequiringSpellMap :: const_iterator itr = spellsRequiringSpell . first ; itr != spellsRequiringSpell . second ; ++ itr )
{
if ( itr -> second == spellid )
return true ;
}
return false ;
}
2009-10-17 15:51:44 -07:00
2008-11-17 22:07:21 -06:00
uint8 GetSpellRank ( uint32 spell_id ) const
{
2010-04-07 19:14:10 +02:00
if ( SpellChainNode const * node = GetSpellChainNode ( spell_id ))
2008-11-17 22:07:21 -06:00
return node -> rank ;
2009-10-17 15:51:44 -07:00
2008-11-17 22:07:21 -06:00
return 0 ;
}
2009-10-17 15:51:44 -07:00
2008-12-13 16:08:39 +01:00
uint32 GetLastSpellInChain ( uint32 spell_id ) const
{
2010-04-07 19:14:10 +02:00
if ( SpellChainNode const * node = GetSpellChainNode ( spell_id ))
2008-12-14 23:01:02 +01:00
return node -> last ;
2009-10-17 15:51:44 -07:00
2008-12-13 16:08:39 +01:00
return spell_id ;
}
2009-10-17 15:51:44 -07:00
2011-03-08 19:11:02 +01:00
bool IsArenaAllowedEnchancment ( uint32 ench_id ) const
2009-05-24 22:54:13 +02:00
{
return mEnchantCustomAttr [ ench_id ];
}
2009-10-17 15:51:44 -07:00
2011-04-29 20:47:02 +02:00
uint8 IsHighRankOfSpell ( uint32 spell1 , uint32 spell2 ) const
2008-11-17 22:07:21 -06:00
{
2010-02-02 22:35:01 +01:00
SpellChainMap :: const_iterator itr1 = mSpellChains . find ( spell1 );
SpellChainMap :: const_iterator itr2 = mSpellChains . find ( spell2 );
2010-02-03 02:41:10 +01:00
if ( itr1 == mSpellChains . end () || itr2 == mSpellChains . end ())
return false ;
2009-10-17 15:51:44 -07:00
2010-02-02 22:35:01 +01:00
if ( itr1 -> second . first == itr2 -> second . first )
2010-02-03 02:41:10 +01:00
if ( itr1 -> second . rank > itr2 -> second . rank )
2008-11-17 22:07:21 -06:00
return true ;
return false ;
}
2009-10-17 15:51:44 -07:00
2011-04-29 20:47:02 +02:00
bool IsRankSpellDueToSpell ( SpellEntry const * spellInfo_1 , uint32 spellId_2 ) const ;
2008-11-17 22:07:21 -06:00
static bool canStackSpellRanks ( SpellEntry const * spellInfo );
2010-12-21 11:40:20 +01:00
bool CanAurasStack ( Aura const * aura1 , Aura const * aura2 , bool sameCaster ) const ;
2009-10-17 15:51:44 -07:00
2008-11-17 22:07:21 -06:00
SpellEntry const * SelectAuraRankForPlayerLevel ( SpellEntry const * spellInfo , uint32 playerLevel ) const ;
2009-10-17 15:51:44 -07:00
2008-11-17 22:07:21 -06:00
// Spell learning
SpellLearnSkillNode const * GetSpellLearnSkill ( uint32 spell_id ) const
{
SpellLearnSkillMap :: const_iterator itr = mSpellLearnSkills . find ( spell_id );
2010-04-07 19:14:10 +02:00
if ( itr != mSpellLearnSkills . end ())
2008-11-17 22:07:21 -06:00
return & itr -> second ;
else
return NULL ;
}
2009-10-17 15:51:44 -07:00
2008-11-17 22:07:21 -06:00
bool IsSpellLearnSpell ( uint32 spell_id ) const
{
2009-02-21 17:03:39 -06:00
return mSpellLearnSpells . find ( spell_id ) != mSpellLearnSpells . end ();
2008-11-17 22:07:21 -06:00
}
2009-10-17 15:51:44 -07:00
2009-08-27 20:27:55 -05:00
SpellLearnSpellMapBounds GetSpellLearnSpellMapBounds ( uint32 spell_id ) const
2008-11-17 22:07:21 -06:00
{
2011-04-29 20:47:02 +02:00
return SpellLearnSpellMapBounds ( mSpellLearnSpells . lower_bound ( spell_id ), mSpellLearnSpells . upper_bound ( spell_id ));
2008-11-17 22:07:21 -06:00
}
2009-10-17 15:51:44 -07:00
2011-04-29 20:47:02 +02:00
bool IsSpellLearnToSpell ( uint32 spell_id1 , uint32 spell_id2 ) const
2008-11-17 22:07:21 -06:00
{
2009-08-27 20:27:55 -05:00
SpellLearnSpellMapBounds bounds = GetSpellLearnSpellMapBounds ( spell_id1 );
2009-10-17 16:20:24 -07:00
for ( SpellLearnSpellMap :: const_iterator i = bounds . first ; i != bounds . second ; ++ i )
2010-04-07 23:25:02 +02:00
if ( i -> second . spell == spell_id2 )
2008-11-17 22:07:21 -06:00
return true ;
return false ;
}
2009-10-17 15:51:44 -07:00
2009-01-14 00:35:13 -06:00
static bool IsProfessionOrRidingSpell ( uint32 spellId );
2008-11-17 22:07:21 -06:00
static bool IsProfessionSpell ( uint32 spellId );
static bool IsPrimaryProfessionSpell ( uint32 spellId );
bool IsPrimaryProfessionFirstRankSpell ( uint32 spellId ) const ;
2009-10-17 15:51:44 -07:00
2009-01-25 16:35:14 -06:00
bool IsSkillBonusSpell ( uint32 spellId ) const ;
2009-05-01 15:40:49 +02:00
bool IsSkillTypeSpell ( uint32 spellId , SkillType type ) const ;
2011-06-11 22:35:29 +02:00
static int32 CalculateSpellEffectAmount ( SpellEntry const * spellEntry , uint8 effIndex , Unit const * caster = NULL , int32 const * basePoints = NULL , Unit const * target = NULL );
static int32 CalculateSpellEffectBaseAmount ( int32 value , SpellEntry const * spellEntry , uint8 effIndex );
static float CalculateSpellEffectValueMultiplier ( SpellEntry const * spellEntry , uint8 effIndex , Unit * caster , Spell * spell = NULL );
static float CalculateSpellEffectDamageMultiplier ( SpellEntry const * spellEntry , uint8 effIndex , Unit * caster , Spell * spell = NULL );
2009-01-25 16:35:14 -06:00
2008-11-17 22:07:21 -06:00
// Spell correctess for client using
2011-06-11 22:35:29 +02:00
static bool IsSpellValid ( SpellEntry const * spellInfo , Player * pl = NULL , bool msg = true );
2009-10-17 15:51:44 -07:00
2009-08-27 20:27:55 -05:00
SkillLineAbilityMapBounds GetSkillLineAbilityMapBounds ( uint32 spell_id ) const
2008-11-17 22:07:21 -06:00
{
2011-04-29 20:47:02 +02:00
return SkillLineAbilityMapBounds ( mSkillLineAbilityMap . lower_bound ( spell_id ), mSkillLineAbilityMap . upper_bound ( spell_id ));
2008-11-17 22:07:21 -06:00
}
2009-10-17 15:51:44 -07:00
2009-07-01 18:07:20 -05:00
PetAura const * GetPetAura ( uint32 spell_id , uint8 eff )
2008-11-17 22:07:21 -06:00
{
2009-06-23 14:05:37 +02:00
SpellPetAuraMap :: const_iterator itr = mSpellPetAuraMap . find (( spell_id << 8 ) + eff );
2010-04-07 19:14:10 +02:00
if ( itr != mSpellPetAuraMap . end ())
2008-11-17 22:07:21 -06:00
return & itr -> second ;
else
return NULL ;
}
2009-10-17 15:51:44 -07:00
2009-05-17 10:57:55 -05:00
PetLevelupSpellSet const * GetPetLevelupSpellList ( uint32 petFamily ) const
{
PetLevelupSpellMap :: const_iterator itr = mPetLevelupSpellMap . find ( petFamily );
2010-04-07 19:14:10 +02:00
if ( itr != mPetLevelupSpellMap . end ())
2009-05-17 10:57:55 -05:00
return & itr -> second ;
else
return NULL ;
}
2009-10-17 15:51:44 -07:00
2008-11-17 22:07:21 -06:00
uint32 GetSpellCustomAttr ( uint32 spell_id ) const
{
2010-04-07 19:14:10 +02:00
if ( spell_id >= mSpellCustomAttr . size ())
2008-12-09 17:40:33 -06:00
return 0 ;
else
return mSpellCustomAttr [ spell_id ];
2008-11-17 22:07:21 -06:00
}
2009-10-17 15:51:44 -07:00
2008-11-17 22:07:21 -06:00
const std :: vector < int32 > * GetSpellLinked ( int32 spell_id ) const
{
SpellLinkedMap :: const_iterator itr = mSpellLinkedMap . find ( spell_id );
return itr != mSpellLinkedMap . end () ? & ( itr -> second ) : NULL ;
}
2009-10-17 15:51:44 -07:00
2009-05-24 12:16:12 -05:00
// < 0 for petspelldata id, > 0 for creature_id
PetDefaultSpellsEntry const * GetPetDefaultSpellsEntry ( int32 id ) const
{
PetDefaultSpellsMap :: const_iterator itr = mPetDefaultSpellsMap . find ( id );
2010-04-07 19:14:10 +02:00
if ( itr != mPetDefaultSpellsMap . end ())
2009-05-24 12:16:12 -05:00
return & itr -> second ;
return NULL ;
}
2009-10-17 15:51:44 -07:00
2009-03-16 12:00:14 -06:00
SpellCastResult GetSpellAllowedInLocationError ( SpellEntry const * spellInfo , uint32 map_id , uint32 zone_id , uint32 area_id , Player const * player = NULL );
2009-10-17 15:51:44 -07:00
2009-02-27 12:53:27 -06:00
SpellAreaMapBounds GetSpellAreaMapBounds ( uint32 spell_id ) const
{
2011-04-29 20:47:02 +02:00
return SpellAreaMapBounds ( mSpellAreaMap . lower_bound ( spell_id ), mSpellAreaMap . upper_bound ( spell_id ));
2009-02-27 12:53:27 -06:00
}
2009-10-17 15:51:44 -07:00
2009-02-27 12:53:27 -06:00
SpellAreaForQuestMapBounds GetSpellAreaForQuestMapBounds ( uint32 quest_id , bool active ) const
{
2010-04-07 19:14:10 +02:00
if ( active )
2011-04-29 20:47:02 +02:00
return SpellAreaForQuestMapBounds ( mSpellAreaForActiveQuestMap . lower_bound ( quest_id ), mSpellAreaForActiveQuestMap . upper_bound ( quest_id ));
2009-02-27 12:53:27 -06:00
else
2011-04-29 20:47:02 +02:00
return SpellAreaForQuestMapBounds ( mSpellAreaForQuestMap . lower_bound ( quest_id ), mSpellAreaForQuestMap . upper_bound ( quest_id ));
2009-02-27 12:53:27 -06:00
}
2009-10-17 15:51:44 -07:00
2009-02-27 12:53:27 -06:00
SpellAreaForQuestMapBounds GetSpellAreaForQuestEndMapBounds ( uint32 quest_id ) const
{
2011-04-29 20:47:02 +02:00
return SpellAreaForQuestMapBounds ( mSpellAreaForQuestEndMap . lower_bound ( quest_id ), mSpellAreaForQuestEndMap . upper_bound ( quest_id ));
2009-02-27 12:53:27 -06:00
}
2009-10-17 15:51:44 -07:00
2009-02-27 12:53:27 -06:00
SpellAreaForAuraMapBounds GetSpellAreaForAuraMapBounds ( uint32 spell_id ) const
{
2011-04-29 20:47:02 +02:00
return SpellAreaForAuraMapBounds ( mSpellAreaForAuraMap . lower_bound ( spell_id ), mSpellAreaForAuraMap . upper_bound ( spell_id ));
2009-02-27 12:53:27 -06:00
}
2009-10-17 15:51:44 -07:00
2009-02-27 12:53:27 -06:00
SpellAreaForAreaMapBounds GetSpellAreaForAreaMapBounds ( uint32 area_id ) const
{
2011-04-29 20:47:02 +02:00
return SpellAreaForAreaMapBounds ( mSpellAreaForAreaMap . lower_bound ( area_id ), mSpellAreaForAreaMap . upper_bound ( area_id ));
2009-02-27 12:53:27 -06:00
}
2009-10-17 15:51:44 -07:00
2009-07-05 20:21:25 +02:00
bool IsSrcTargetSpell ( SpellEntry const * spellInfo ) const ;
2009-10-17 15:51:44 -07:00
2009-08-02 10:03:38 +08:00
inline bool IsCasterSourceTarget ( uint32 target )
{
switch ( SpellTargetType [ target ])
{
case TARGET_TYPE_UNIT_TARGET :
case TARGET_TYPE_DEST_TARGET :
return false ;
default :
break ;
}
return true ;
}
2009-10-17 15:51:44 -07:00
2009-08-02 10:03:38 +08:00
inline bool IsSpellWithCasterSourceTargetsOnly ( SpellEntry const * spellInfo )
{
2010-09-28 08:21:51 +03:00
for ( int i = 0 ; i < MAX_SPELL_EFFECTS ; ++ i )
2010-04-07 19:14:10 +02:00
if ( uint32 target = spellInfo -> EffectImplicitTargetA [ i ])
if ( ! IsCasterSourceTarget ( target ))
2009-08-02 10:03:38 +08:00
return false ;
return true ;
}
2011-05-17 13:17:42 +02:00
uint32 GetSpellDifficultyId ( uint32 spellId ) const
2010-04-22 19:39:19 +02:00
{
2010-04-29 23:12:16 +02:00
SpellDifficultySearcherMap :: const_iterator i = mSpellDifficultySearcherMap . find ( spellId );
2010-04-22 19:39:19 +02:00
return i == mSpellDifficultySearcherMap . end () ? 0 : ( * i ). second ;
}
2010-04-09 10:47:11 +02:00
void SetSpellDifficultyId ( uint32 spellId , uint32 id ) { mSpellDifficultySearcherMap [ spellId ] = id ; }
2009-10-17 15:51:44 -07:00
2010-07-14 16:57:13 +02:00
const SpellsRequiringSpellMap GetSpellsRequiringSpell ()
{
return this -> mSpellsReqSpell ;
}
2010-04-07 18:09:10 +02:00
2010-07-14 16:57:13 +02:00
uint32 GetSpellRequired ( uint32 spell_id ) const
{
SpellRequiredMap :: const_iterator itr = mSpellReq . find ( spell_id );
2010-04-07 18:09:10 +02:00
2010-07-14 16:57:13 +02:00
if ( itr == mSpellReq . end ())
2011-04-23 15:53:48 +02:00
return 0 ;
2010-02-14 19:13:14 -07:00
2010-07-14 16:57:13 +02:00
return itr -> second ;
}
2010-02-14 19:13:14 -07:00
2009-02-13 19:50:20 -06:00
// Modifiers
2008-11-17 22:07:21 -06:00
public :
2009-10-17 15:51:44 -07:00
2008-11-17 22:07:21 -06:00
// Loading data at server startup
2010-01-29 17:54:29 +01:00
void LoadSpellRanks ();
2008-12-22 02:11:11 +01:00
void LoadSpellRequired ();
2008-11-17 22:07:21 -06:00
void LoadSpellLearnSkills ();
void LoadSpellLearnSpells ();
2010-02-01 19:22:32 +01:00
void LoadSpellGroups ();
2008-11-17 22:07:21 -06:00
void LoadSpellProcEvents ();
2009-01-29 19:33:39 -06:00
void LoadSpellBonusess ();
2008-11-17 22:07:21 -06:00
void LoadSpellTargetPositions ();
void LoadSpellThreats ();
void LoadSkillLineAbilityMap ();
void LoadSpellPetAuras ();
void LoadSpellCustomAttr ();
2009-05-24 22:54:13 +02:00
void LoadEnchantCustomAttr ();
2009-07-30 11:44:23 +02:00
void LoadSpellEnchantProcData ();
2008-11-17 22:07:21 -06:00
void LoadSpellLinked ();
2008-12-24 09:58:26 -06:00
void LoadPetLevelupSpellMap ();
2009-05-24 12:16:12 -05:00
void LoadPetDefaultSpells ();
2009-02-27 12:53:27 -06:00
void LoadSpellAreas ();
2010-02-02 22:35:01 +01:00
void LoadSpellGroupStackRules ();
2009-10-17 15:51:44 -07:00
2008-11-17 22:07:21 -06:00
private :
2009-08-06 11:24:14 -05:00
bool _isPositiveSpell ( uint32 spellId , bool deep ) const ;
bool _isPositiveEffect ( uint32 spellId , uint32 effIndex , bool deep ) const ;
2009-10-17 15:51:44 -07:00
2008-11-17 22:07:21 -06:00
SpellChainMap mSpellChains ;
2008-12-22 02:11:11 +01:00
SpellsRequiringSpellMap mSpellsReqSpell ;
2008-12-14 23:01:02 +01:00
SpellRequiredMap mSpellReq ;
2008-11-17 22:07:21 -06:00
SpellLearnSkillMap mSpellLearnSkills ;
SpellLearnSpellMap mSpellLearnSpells ;
SpellTargetPositionMap mSpellTargetPositions ;
2010-02-01 19:22:32 +01:00
SpellSpellGroupMap mSpellSpellGroup ;
SpellGroupSpellMap mSpellGroupSpell ;
2009-07-30 11:37:08 +08:00
SpellThreatMap mSpellThreatMap ;
2008-11-17 22:07:21 -06:00
SpellProcEventMap mSpellProcEventMap ;
2009-01-29 19:33:39 -06:00
SpellBonusMap mSpellBonusMap ;
2008-11-17 22:07:21 -06:00
SkillLineAbilityMap mSkillLineAbilityMap ;
SpellPetAuraMap mSpellPetAuraMap ;
2008-12-09 17:40:33 -06:00
SpellCustomAttribute mSpellCustomAttr ;
2008-11-17 22:07:21 -06:00
SpellLinkedMap mSpellLinkedMap ;
2010-02-02 22:35:01 +01:00
SpellGroupStackMap mSpellGroupStack ;
2009-05-15 16:37:22 +02:00
SpellEnchantProcEventMap mSpellEnchantProcEventMap ;
2009-05-24 22:54:13 +02:00
EnchantCustomAttribute mEnchantCustomAttr ;
2009-02-27 12:28:10 -06:00
PetLevelupSpellMap mPetLevelupSpellMap ;
2009-05-24 12:16:12 -05:00
PetDefaultSpellsMap mPetDefaultSpellsMap ; // only spells not listed in related mPetLevelupSpellMap entry
2009-02-27 12:53:27 -06:00
SpellAreaMap mSpellAreaMap ;
SpellAreaForQuestMap mSpellAreaForQuestMap ;
SpellAreaForQuestMap mSpellAreaForActiveQuestMap ;
SpellAreaForQuestMap mSpellAreaForQuestEndMap ;
SpellAreaForAuraMap mSpellAreaForAuraMap ;
SpellAreaForAreaMap mSpellAreaForAreaMap ;
2010-04-09 10:47:11 +02:00
SpellDifficultySearcherMap mSpellDifficultySearcherMap ;
2008-11-17 22:07:21 -06:00
};
2009-10-17 15:51:44 -07:00
2010-12-22 21:25:23 +01:00
#define sSpellMgr ACE_Singleton<SpellMgr, ACE_Null_Mutex>::instance()
2010-12-22 20:52:47 +01:00
2008-11-17 22:07:21 -06:00
#endif