Files
TCPlayerbotCore/src/server/game/Spells/SpellMgr.h
T

694 lines
32 KiB
C++
Raw Normal View History

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
2009-10-17 15:51:44 -07:00
#include <ace/Singleton.h>
#include "Common.h"
2010-06-08 13:05:47 -06:00
#include "SharedDefines.h"
2011-08-21 17:07:32 +02:00
#include "Unit.h"
2009-10-17 15:51:44 -07:00
class SpellInfo;
2008-11-17 22:07:21 -06:00
class Player;
class Unit;
class ProcEventInfo;
struct SkillLineAbilityEntry;
2009-10-17 15:51:44 -07:00
// only used in code
enum SpellCategories
{
SPELLCATEGORY_HEALTH_MANA_POTIONS = 4,
SPELLCATEGORY_DEVOUR_MAGIC = 12,
SPELLCATEGORY_JUDGEMENT = 1210, // Judgement (seal trigger)
SPELLCATEGORY_FOOD = 11,
SPELLCATEGORY_DRINK = 59,
};
2009-10-17 15:51:44 -07:00
//SpellFamilyFlags
enum SpellFamilyFlag
{
// SPELLFAMILYFLAG = SpellFamilyFlags[0]
// SPELLFAMILYFLAG1 = SpellFamilyFlags[1]
// SPELLFAMILYFLAG2 = SpellFamilyFlags[2]
// Rogue
SPELLFAMILYFLAG_ROGUE_VANISH = 0x00000800,
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
// Warrior
SPELLFAMILYFLAG_WARRIOR_CHARGE = 0x00000001,
SPELLFAMILYFLAG_WARRIOR_SLAM = 0x00200000,
SPELLFAMILYFLAG_WARRIOR_EXECUTE = 0x20000000,
SPELLFAMILYFLAG_WARRIOR_CONCUSSION_BLOW = 0x04000000,
// Warlock
SPELLFAMILYFLAG_WARLOCK_LIFETAP = 0x00040000,
// Druid
SPELLFAMILYFLAG2_DRUID_STARFALL = 0x00000100,
// Paladin
SPELLFAMILYFLAG1_PALADIN_DIVINESTORM = 0x00020000,
// Shaman
SPELLFAMILYFLAG_SHAMAN_FROST_SHOCK = 0x80000000,
SPELLFAMILYFLAG_SHAMAN_HEALING_STREAM = 0x00002000,
SPELLFAMILYFLAG_SHAMAN_MANA_SPRING = 0x00004000,
SPELLFAMILYFLAG2_SHAMAN_LAVA_LASH = 0x00000004,
2010-02-14 19:13:14 -07:00
SPELLFAMILYFLAG_SHAMAN_FIRE_NOVA = 0x28000000,
// Deathknight
SPELLFAMILYFLAG_DK_DEATH_STRIKE = 0x00000010,
SPELLFAMILYFLAG_DK_DEATH_COIL = 0x00002000,
// 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
};
2009-10-17 15:51:44 -07:00
#define SPELL_LINKED_MAX_SPELLS 200000
2009-10-17 15:51:44 -07: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
2008-11-17 22:07:21 -06:00
// Spell proc event related declarations (accessed using SpellMgr functions)
enum ProcFlags
{
PROC_FLAG_NONE = 0x00000000,
2009-10-17 15:51:44 -07:00
PROC_FLAG_KILLED = 0x00000001, // 00 Killed by agressor - not sure about this flag
PROC_FLAG_KILL = 0x00000002, // 01 Kill target (in most cases need XP/Honor reward)
2009-10-17 15:51:44 -07: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
2010-10-08 19:17:49 +02:00
PROC_FLAG_DONE_SPELL_MELEE_DMG_CLASS = 0x00000010, // 04 Done attack by Spell that has dmg class melee
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
2010-10-08 19:17:49 +02:00
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
2010-10-08 19:17:49 +02:00
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
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
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
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
PROC_FLAG_DONE_PERIODIC = 0x00040000, // 18 Successful do periodic (damage / healing)
PROC_FLAG_TAKEN_PERIODIC = 0x00080000, // 19 Taken spell periodic (damage / healing)
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)
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
PROC_FLAG_DEATH = 0x01000000, // 24 Died in any way
// flag masks
AUTO_ATTACK_PROC_FLAG_MASK = PROC_FLAG_DONE_MELEE_AUTO_ATTACK | PROC_FLAG_TAKEN_MELEE_AUTO_ATTACK
| PROC_FLAG_DONE_RANGED_AUTO_ATTACK | PROC_FLAG_TAKEN_RANGED_AUTO_ATTACK,
MELEE_PROC_FLAG_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_MAINHAND_ATTACK | PROC_FLAG_DONE_OFFHAND_ATTACK,
RANGED_PROC_FLAG_MASK = 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,
SPELL_PROC_FLAG_MASK = PROC_FLAG_DONE_SPELL_MELEE_DMG_CLASS | PROC_FLAG_TAKEN_SPELL_MELEE_DMG_CLASS
| PROC_FLAG_DONE_SPELL_RANGED_DMG_CLASS | PROC_FLAG_TAKEN_SPELL_RANGED_DMG_CLASS
| PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_POS | PROC_FLAG_TAKEN_SPELL_NONE_DMG_CLASS_POS
| PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_NEG | PROC_FLAG_TAKEN_SPELL_NONE_DMG_CLASS_NEG
| PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_POS | PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_POS
| PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG | PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_NEG,
SPELL_CAST_PROC_FLAG_MASK = SPELL_PROC_FLAG_MASK | PROC_FLAG_DONE_TRAP_ACTIVATION | RANGED_PROC_FLAG_MASK,
PERIODIC_PROC_FLAG_MASK = PROC_FLAG_DONE_PERIODIC | PROC_FLAG_TAKEN_PERIODIC,
DONE_HIT_PROC_FLAG_MASK = PROC_FLAG_DONE_MELEE_AUTO_ATTACK | PROC_FLAG_DONE_RANGED_AUTO_ATTACK
| PROC_FLAG_DONE_SPELL_MELEE_DMG_CLASS | PROC_FLAG_DONE_SPELL_RANGED_DMG_CLASS
| PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_POS | PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_NEG
| PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_POS | PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG
| PROC_FLAG_DONE_PERIODIC | PROC_FLAG_DONE_MAINHAND_ATTACK | PROC_FLAG_DONE_OFFHAND_ATTACK,
TAKEN_HIT_PROC_FLAG_MASK = PROC_FLAG_TAKEN_MELEE_AUTO_ATTACK | PROC_FLAG_TAKEN_RANGED_AUTO_ATTACK
| PROC_FLAG_TAKEN_SPELL_MELEE_DMG_CLASS | PROC_FLAG_TAKEN_SPELL_RANGED_DMG_CLASS
| PROC_FLAG_TAKEN_SPELL_NONE_DMG_CLASS_POS | PROC_FLAG_TAKEN_SPELL_NONE_DMG_CLASS_NEG
| PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_POS | PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_NEG
| PROC_FLAG_TAKEN_PERIODIC | PROC_FLAG_TAKEN_DAMAGE,
REQ_SPELL_PHASE_PROC_FLAG_MASK = SPELL_PROC_FLAG_MASK & DONE_HIT_PROC_FLAG_MASK,
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
enum ProcFlagsExLegacy
{
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,
PROC_EX_INTERRUPT = 0x0001000, // Melee hit result can be Interrupt (not used)
PROC_EX_FULL_BLOCK = 0x0002000, // block al attack damage
PROC_EX_RESERVED2 = 0x0004000,
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
// 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
enum ProcFlagsSpellType
{
PROC_SPELL_TYPE_NONE = 0x0000000,
PROC_SPELL_TYPE_DAMAGE = 0x0000001, // damage type of spell
PROC_SPELL_TYPE_HEAL = 0x0000002, // heal type of spell
PROC_SPELL_TYPE_NO_DMG_HEAL = 0x0000004, // other spells
PROC_SPELL_TYPE_MASK_ALL = PROC_SPELL_TYPE_DAMAGE | PROC_SPELL_TYPE_HEAL | PROC_SPELL_TYPE_NO_DMG_HEAL
};
enum ProcFlagsSpellPhase
{
PROC_SPELL_PHASE_NONE = 0x0000000,
PROC_SPELL_PHASE_CAST = 0x0000001,
PROC_SPELL_PHASE_HIT = 0x0000002,
PROC_SPELL_PHASE_FINISH = 0x0000004,
PROC_SPELL_PHASE_MASK_ALL = PROC_SPELL_PHASE_CAST | PROC_SPELL_PHASE_HIT | PROC_SPELL_PHASE_FINISH
};
enum ProcFlagsHit
{
PROC_HIT_NONE = 0x0000000, // no value - PROC_HIT_NORMAL | PROC_HIT_CRITICAL for TAKEN proc type, PROC_HIT_NORMAL | PROC_HIT_CRITICAL | PROC_HIT_ABSORB for DONE
PROC_HIT_NORMAL = 0x0000001, // non-critical hits
PROC_HIT_CRITICAL = 0x0000002,
PROC_HIT_MISS = 0x0000004,
PROC_HIT_FULL_RESIST = 0x0000008,
PROC_HIT_DODGE = 0x0000010,
PROC_HIT_PARRY = 0x0000020,
PROC_HIT_BLOCK = 0x0000040, // partial or full block
PROC_HIT_EVADE = 0x0000080,
PROC_HIT_IMMUNE = 0x0000100,
PROC_HIT_DEFLECT = 0x0000200,
PROC_HIT_ABSORB = 0x0000400, // partial or full absorb
PROC_HIT_REFLECT = 0x0000800,
PROC_HIT_INTERRUPT = 0x0001000, // (not used atm)
PROC_HIT_FULL_BLOCK = 0x0002000,
PROC_HIT_MASK_ALL = 0x2FFF,
};
enum ProcAttributes
{
PROC_ATTR_REQ_EXP_OR_HONOR = 0x0000010,
};
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
typedef UNORDERED_MAP<uint32, SpellProcEventEntry> SpellProcEventMap;
struct SpellProcEntry
{
uint32 schoolMask; // if nonzero - bitmask for matching proc condition based on spell's school
uint32 spellFamilyName; // if nonzero - for matching proc condition based on candidate spell's SpellFamilyName
flag96 spellFamilyMask; // if nonzero - bitmask for matching proc condition based on candidate spell's SpellFamilyFlags
uint32 typeMask; // if nonzero - owerwrite procFlags field for given Spell.dbc entry, bitmask for matching proc condition, see enum ProcFlags
uint32 spellTypeMask; // if nonzero - bitmask for matching proc condition based on candidate spell's damage/heal effects, see enum ProcFlagsSpellType
uint32 spellPhaseMask; // if nonzero - bitmask for matching phase of a spellcast on which proc occurs, see enum ProcFlagsSpellPhase
uint32 hitMask; // if nonzero - bitmask for matching proc condition based on hit result, see enum ProcFlagsHit
uint32 attributesMask; // bitmask, see ProcAttributes
float ratePerMinute; // if nonzero - chance to proc is equal to value * aura caster's weapon speed / 60
float chance; // if nonzero - owerwrite procChance field for given Spell.dbc entry, defines chance of proc to occur, not used if perMinuteRate set
uint32 cooldown; // if nonzero - cooldown in secs for aura proc, applied to aura
uint32 charges; // if nonzero - owerwrite procCharges field for given Spell.dbc entry, defines how many times proc can occur before aura remove, 0 - infinite
2009-01-29 19:33:39 -06:00
};
2009-10-17 15:51:44 -07:00
typedef UNORDERED_MAP<uint32, SpellProcEntry> SpellProcMap;
2009-10-17 15:51:44 -07:00
struct SpellEnchantProcEntry
{
uint32 customChance;
float PPMChance;
uint32 procEx;
};
2009-10-17 15:51:44 -07:00
typedef UNORDERED_MAP<uint32, SpellEnchantProcEntry> SpellEnchantProcEventMap;
struct SpellBonusEntry
{
float direct_damage;
float dot_damage;
float ap_bonus;
float ap_dot_bonus;
};
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
// 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;
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,
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
#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
{
2011-07-06 13:28:59 +02:00
private:
typedef UNORDERED_MAP<uint32, uint32> PetAuraMap;
2008-11-17 22:07:21 -06:00
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
{
2011-07-06 13:28:59 +02:00
PetAuraMap::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;
2011-07-06 13:28:59 +02:00
PetAuraMap::const_iterator itr2 = auras.find(0);
2010-04-07 19:14:10 +02:00
if (itr2 != auras.end())
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:
2011-07-06 13:28:59 +02:00
PetAuraMap auras;
2008-11-17 22:07:21 -06:00
bool removeOnChangePet;
int32 damage;
};
typedef std::map<uint32, PetAura> SpellPetAuraMap;
2009-10-17 15:51:44 -07: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)
2011-07-06 13:28:59 +02:00
uint32 questEnd; // quest end (quest must not be rewarded for spell apply)
int32 auraSpell; // spell aura must be applied for spell apply)if possitive) and it must not be applied in other case
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
// 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;
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
{
SpellInfo const* prev;
SpellInfo const* next;
SpellInfo const* first;
SpellInfo const* 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
// 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
// req_spell spell_id
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;
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
typedef std::multimap<uint32, uint32> PetLevelupSpellSet;
typedef std::map<uint32, PetLevelupSpellSet> PetLevelupSpellMap;
2009-10-17 15:51:44 -07: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;
typedef std::vector<uint32> SpellCustomAttribute;
typedef std::vector<bool> EnchantCustomAttribute;
2009-10-17 15:51:44 -07:00
typedef std::vector<SpellInfo*> SpellInfoMap;
2009-10-17 15:51:44 -07:00
typedef std::map<int32, std::vector<int32> > SpellLinkedMap;
bool IsPrimaryProfessionSkill(uint32 skill);
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
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);
// spell diminishing returns
DiminishingGroup GetDiminishingReturnsGroupForSpell(SpellInfo const* spellproto, bool triggered);
DiminishingReturnsType GetDiminishingReturnsGroupType(DiminishingGroup group);
DiminishingLevels GetDiminishingReturnsMaxLevel(DiminishingGroup group);
int32 GetDiminishingReturnsLimitDuration(DiminishingGroup group, SpellInfo const* spellproto);
bool IsDiminishingReturnsGroupDurationLimited(DiminishingGroup group);
2008-11-17 22:07:21 -06:00
class SpellMgr
{
friend class ACE_Singleton<SpellMgr, ACE_Null_Mutex>;
// Constructors
private:
2008-11-17 22:07:21 -06:00
SpellMgr();
~SpellMgr();
2009-10-17 15:51:44 -07:00
// Accessors (const or static functions)
2008-11-17 22:07:21 -06:00
public:
// Spell correctess for client using
static bool IsSpellValid(SpellInfo const* spellInfo, Player* pl = NULL, bool msg = true);
// Spell difficulty
uint32 GetSpellDifficultyId(uint32 spellId) const;
void SetSpellDifficultyId(uint32 spellId, uint32 id);
uint32 GetSpellIdForDifficulty(uint32 spellId, Unit const* caster) const;
SpellInfo const* GetSpellForDifficultyFromSpell(SpellInfo const* spell, Unit const* caster) const;
// Spell Ranks table
SpellChainNode const* GetSpellChainNode(uint32 spell_id) const;
uint32 GetFirstSpellInChain(uint32 spell_id) const;
uint32 GetLastSpellInChain(uint32 spell_id) const;
uint32 GetNextSpellInChain(uint32 spell_id) const;
uint32 GetPrevSpellInChain(uint32 spell_id) const;
uint8 GetSpellRank(uint32 spell_id) const;
// not strict check returns provided spell if rank not avalible
uint32 GetSpellWithRank(uint32 spell_id, uint32 rank, bool strict = false) const;
2009-10-17 15:51:44 -07:00
// Spell Required table
SpellRequiredMapBounds GetSpellsRequiredForSpellBounds(uint32 spell_id) const;
SpellsRequiringSpellMapBounds GetSpellsRequiringSpellBounds(uint32 spell_id) const;
bool IsSpellRequiringSpell(uint32 spellid, uint32 req_spellid) const;
const SpellsRequiringSpellMap GetSpellsRequiringSpell();
uint32 GetSpellRequired(uint32 spell_id) 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;
SpellLearnSpellMapBounds GetSpellLearnSpellMapBounds(uint32 spell_id) const;
bool IsSpellLearnSpell(uint32 spell_id) const;
bool IsSpellLearnToSpell(uint32 spell_id1, uint32 spell_id2) const;
2009-10-17 15:51:44 -07:00
// Spell target coordinates
SpellTargetPosition const* GetSpellTargetPosition(uint32 spell_id) const;
2009-10-17 15:51:44 -07:00
// Spell Groups table
SpellSpellGroupMapBounds GetSpellSpellGroupMapBounds(uint32 spell_id) const;
uint32 IsSpellMemberOfSpellGroup(uint32 spellid, SpellGroup groupid) const;
2009-10-17 15:51:44 -07:00
SpellGroupSpellMapBounds GetSpellGroupSpellMapBounds(SpellGroup group_id) const;
void GetSetOfSpellsInSpellGroup(SpellGroup group_id, std::set<uint32>& foundSpells) const;
void GetSetOfSpellsInSpellGroup(SpellGroup group_id, std::set<uint32>& foundSpells, std::set<SpellGroup>& usedGroups) const;
2009-10-17 15:51:44 -07:00
// Spell Group Stack Rules table
SpellGroupStackRule CheckSpellGroupStackRules(SpellInfo const* spellInfo1, SpellInfo const* spellInfo2) const;
2009-10-17 15:51:44 -07:00
// Spell proc event table
SpellProcEventEntry const* GetSpellProcEvent(uint32 spellId) const;
bool IsSpellProcEventCanTriggeredBy(SpellProcEventEntry const* spellProcEvent, uint32 EventProcFlag, SpellInfo const* procSpell, uint32 procFlags, uint32 procExtra, bool active);
2009-10-17 15:51:44 -07:00
// Spell proc table
SpellProcEntry const* GetSpellProcEntry(uint32 spellId) const;
bool CanSpellTriggerProcOnEvent(SpellProcEntry const& procEntry, ProcEventInfo& eventInfo);
2009-10-17 15:51:44 -07:00
// Spell bonus data table
SpellBonusEntry const* GetSpellBonusData(uint32 spellId) const;
2009-10-17 15:51:44 -07:00
// Spell threat table
uint16 GetSpellThreat(uint32 spellid) const;
2009-10-17 15:51:44 -07:00
SkillLineAbilityMapBounds GetSkillLineAbilityMapBounds(uint32 spell_id) const;
2009-10-17 15:51:44 -07:00
PetAura const* GetPetAura(uint32 spell_id, uint8 eff);
2009-10-17 15:51:44 -07:00
SpellEnchantProcEntry const* GetSpellEnchantProcEvent(uint32 enchId) const;
bool IsArenaAllowedEnchancment(uint32 ench_id) const;
2009-10-17 15:51:44 -07:00
const std::vector<int32> *GetSpellLinked(int32 spell_id) const;
2010-04-07 18:09:10 +02:00
PetLevelupSpellSet const* GetPetLevelupSpellList(uint32 petFamily) const;
PetDefaultSpellsEntry const* GetPetDefaultSpellsEntry(int32 id) const;
2010-04-07 18:09:10 +02:00
// Spell area
SpellAreaMapBounds GetSpellAreaMapBounds(uint32 spell_id) const;
SpellAreaForQuestMapBounds GetSpellAreaForQuestMapBounds(uint32 quest_id, bool active) const;
SpellAreaForQuestMapBounds GetSpellAreaForQuestEndMapBounds(uint32 quest_id) const;
SpellAreaForAuraMapBounds GetSpellAreaForAuraMapBounds(uint32 spell_id) const;
SpellAreaForAreaMapBounds GetSpellAreaForAreaMapBounds(uint32 area_id) const;
2010-02-14 19:13:14 -07:00
// SpellInfo object management
SpellInfo const* GetSpellInfo(uint32 spellId) const { return spellId < GetSpellInfoStoreSize() ? mSpellInfoMap[spellId] : NULL; }
uint32 GetSpellInfoStoreSize() const { return mSpellInfoMap.size(); }
2010-02-14 19:13:14 -07: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
void LoadSpellInfos();
void LoadSpellRanks();
void LoadSpellRequired();
2008-11-17 22:07:21 -06:00
void LoadSpellLearnSkills();
void LoadSpellLearnSpells();
void LoadSpellTargetPositions();
2010-02-01 19:22:32 +01:00
void LoadSpellGroups();
void LoadSpellGroupStackRules();
2008-11-17 22:07:21 -06:00
void LoadSpellProcEvents();
void LoadSpellProcs();
2009-01-29 19:33:39 -06:00
void LoadSpellBonusess();
2008-11-17 22:07:21 -06:00
void LoadSpellThreats();
void LoadSkillLineAbilityMap();
void LoadSpellPetAuras();
void LoadEnchantCustomAttr();
void LoadSpellEnchantProcData();
2008-11-17 22:07:21 -06:00
void LoadSpellLinked();
void LoadPetLevelupSpellMap();
2009-05-24 12:16:12 -05:00
void LoadPetDefaultSpells();
void LoadSpellAreas();
void LoadSpellInfoStore();
void UnloadSpellInfoStore();
void LoadSpellCustomAttr();
void LoadDbcDataCorrections();
2009-10-17 15:51:44 -07:00
2008-11-17 22:07:21 -06:00
private:
SpellDifficultySearcherMap mSpellDifficultySearcherMap;
SpellChainMap mSpellChains;
SpellsRequiringSpellMap mSpellsReqSpell;
SpellRequiredMap mSpellReq;
SpellLearnSkillMap mSpellLearnSkills;
SpellLearnSpellMap mSpellLearnSpells;
SpellTargetPositionMap mSpellTargetPositions;
SpellSpellGroupMap mSpellSpellGroup;
SpellGroupSpellMap mSpellGroupSpell;
SpellGroupStackMap mSpellGroupStack;
SpellProcEventMap mSpellProcEventMap;
SpellProcMap mSpellProcMap;
SpellBonusMap mSpellBonusMap;
SpellThreatMap mSpellThreatMap;
SpellPetAuraMap mSpellPetAuraMap;
SpellLinkedMap mSpellLinkedMap;
SpellEnchantProcEventMap mSpellEnchantProcEventMap;
EnchantCustomAttribute mEnchantCustomAttr;
SpellAreaMap mSpellAreaMap;
SpellAreaForQuestMap mSpellAreaForQuestMap;
SpellAreaForQuestMap mSpellAreaForActiveQuestMap;
SpellAreaForQuestMap mSpellAreaForQuestEndMap;
SpellAreaForAuraMap mSpellAreaForAuraMap;
SpellAreaForAreaMap mSpellAreaForAreaMap;
SkillLineAbilityMap mSkillLineAbilityMap;
PetLevelupSpellMap mPetLevelupSpellMap;
PetDefaultSpellsMap mPetDefaultSpellsMap; // only spells not listed in related mPetLevelupSpellMap entry
SpellInfoMap mSpellInfoMap;
2008-11-17 22:07:21 -06:00
};
2009-10-17 15:51:44 -07:00
#define sSpellMgr ACE_Singleton<SpellMgr, ACE_Null_Mutex>::instance()
2008-11-17 22:07:21 -06:00
#endif