/*
* Copyright (C) 2008-2012 TrinityCore
* Copyright (C) 2005-2009 MaNGOS
*
* 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 .
*/
#ifndef _SPELLMGR_H
#define _SPELLMGR_H
// For static or at-server-startup loaded spell data
#include
#include "Common.h"
#include "SharedDefines.h"
#include "Unit.h"
class SpellInfo;
class Player;
class Unit;
class ProcEventInfo;
struct SkillLineAbilityEntry;
// 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,
};
//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
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,
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
};
#define SPELL_LINKED_MAX_SPELLS 200000
enum SpellLinkedType
{
SPELL_LINK_CAST = 0, // +: cast; -: remove
SPELL_LINK_HIT = 1 * 200000,
SPELL_LINK_AURA = 2 * 200000, // +: aura; -: immune
SPELL_LINK_REMOVE = 0,
};
// Spell proc event related declarations (accessed using SpellMgr functions)
enum ProcFlags
{
PROC_FLAG_NONE = 0x00000000,
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)
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
PROC_FLAG_TAKEN_SPELL_MELEE_DMG_CLASS = 0x00000020, // 05 Taken attack by Spell that has dmg class melee
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
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)
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,
};
#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)
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
};
#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)
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,
};
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
flag96 spellFamilyMask; // if nonzero - for matching proc condition based on candidate spell's SpellFamilyFlags (like auras 107 and 108 do)
uint32 procFlags; // bitmask for matching proc event
uint32 procEx; // proc Extend info (see ProcFlagsEx)
float ppmRate; // for melee (ranged?) damage spells - proc rate per minute. if zero, falls back to flat chance from Spell.dbc
float customChance; // Owerride chance (in most cases for debug only)
uint32 cooldown; // hidden cooldown used for some spell proc events, applied to _triggered_spell_
};
typedef UNORDERED_MAP 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
};
typedef UNORDERED_MAP SpellProcMap;
struct SpellEnchantProcEntry
{
uint32 customChance;
float PPMChance;
uint32 procEx;
};
typedef UNORDERED_MAP SpellEnchantProcEventMap;
struct SpellBonusEntry
{
float direct_damage;
float dot_damage;
float ap_bonus;
float ap_dot_bonus;
};
typedef UNORDERED_MAP SpellBonusMap;
enum SpellGroup
{
SPELL_GROUP_NONE = 0,
SPELL_GROUP_ELIXIR_BATTLE = 1,
SPELL_GROUP_ELIXIR_GUARDIAN = 2,
SPELL_GROUP_ELIXIR_UNSTABLE = 3,
SPELL_GROUP_ELIXIR_SHATTRATH = 4,
SPELL_GROUP_CORE_RANGE_MAX = 5,
};
#define SPELL_GROUP_DB_RANGE_MIN 1000
// spell_id, group_id
typedef std::multimap SpellSpellGroupMap;
typedef std::pair SpellSpellGroupMapBounds;
// group_id, spell_id
typedef std::multimap SpellGroupSpellMap;
typedef std::pair SpellGroupSpellMapBounds;
enum SpellGroupStackRule
{
SPELL_GROUP_STACK_RULE_DEFAULT = 0,
SPELL_GROUP_STACK_RULE_EXCLUSIVE = 1,
SPELL_GROUP_STACK_RULE_EXCLUSIVE_FROM_SAME_CASTER = 2,
SPELL_GROUP_STACK_RULE_EXCLUSIVE_SAME_EFFECT = 3,
};
#define SPELL_GROUP_STACK_RULE_MAX 4
typedef std::map SpellGroupStackMap;
struct SpellThreatEntry
{
int32 flatMod; // flat threat-value for this Spell - default: 0
float pctMod; // threat-multiplier for this Spell - default: 1.0f
float apPctMod; // Pct of AP that is added as Threat - default: 0.0f
};
typedef std::map SpellThreatMap;
// coordinates for spells (accessed using SpellMgr functions)
struct SpellTargetPosition
{
uint32 target_mapId;
float target_X;
float target_Y;
float target_Z;
float target_Orientation;
};
// Enum with EffectRadiusIndex and their actual radius
enum EffectRadiusIndex
{
EFFECT_RADIUS_2_YARDS = 7,
EFFECT_RADIUS_5_YARDS = 8,
EFFECT_RADIUS_20_YARDS = 9,
EFFECT_RADIUS_30_YARDS = 10,
EFFECT_RADIUS_45_YARDS = 11,
EFFECT_RADIUS_100_YARDS = 12,
EFFECT_RADIUS_10_YARDS = 13,
EFFECT_RADIUS_8_YARDS = 14,
EFFECT_RADIUS_3_YARDS = 15,
EFFECT_RADIUS_1_YARD = 16,
EFFECT_RADIUS_13_YARDS = 17,
EFFECT_RADIUS_15_YARDS = 18,
EFFECT_RADIUS_18_YARDS = 19,
EFFECT_RADIUS_25_YARDS = 20,
EFFECT_RADIUS_35_YARDS = 21,
EFFECT_RADIUS_200_YARDS = 22,
EFFECT_RADIUS_40_YARDS = 23,
EFFECT_RADIUS_65_YARDS = 24,
EFFECT_RADIUS_70_YARDS = 25,
EFFECT_RADIUS_4_YARDS = 26,
EFFECT_RADIUS_50_YARDS = 27,
EFFECT_RADIUS_50000_YARDS = 28,
EFFECT_RADIUS_6_YARDS = 29,
EFFECT_RADIUS_500_YARDS = 30,
EFFECT_RADIUS_80_YARDS = 31,
EFFECT_RADIUS_12_YARDS = 32,
EFFECT_RADIUS_99_YARDS = 33,
EFFECT_RADIUS_55_YARDS = 35,
EFFECT_RADIUS_0_YARDS = 36,
EFFECT_RADIUS_7_YARDS = 37,
EFFECT_RADIUS_21_YARDS = 38,
EFFECT_RADIUS_34_YARDS = 39,
EFFECT_RADIUS_9_YARDS = 40,
EFFECT_RADIUS_150_YARDS = 41,
EFFECT_RADIUS_11_YARDS = 42,
EFFECT_RADIUS_16_YARDS = 43,
EFFECT_RADIUS_0_5_YARDS = 44, // 0.5 yards
EFFECT_RADIUS_10_YARDS_2 = 45,
EFFECT_RADIUS_5_YARDS_2 = 46,
EFFECT_RADIUS_15_YARDS_2 = 47,
EFFECT_RADIUS_60_YARDS = 48,
EFFECT_RADIUS_90_YARDS = 49,
EFFECT_RADIUS_15_YARDS_3 = 50,
EFFECT_RADIUS_60_YARDS_2 = 51,
EFFECT_RADIUS_5_YARDS_3 = 52,
EFFECT_RADIUS_60_YARDS_3 = 53,
EFFECT_RADIUS_50000_YARDS_2 = 54,
EFFECT_RADIUS_130_YARDS = 55,
EFFECT_RADIUS_38_YARDS = 56,
EFFECT_RADIUS_45_YARDS_2 = 57,
EFFECT_RADIUS_32_YARDS = 59,
EFFECT_RADIUS_44_YARDS = 60,
EFFECT_RADIUS_14_YARDS = 61,
EFFECT_RADIUS_47_YARDS = 62,
EFFECT_RADIUS_23_YARDS = 63,
EFFECT_RADIUS_3_5_YARDS = 64, // 3.5 yards
EFFECT_RADIUS_80_YARDS_2 = 65
};
typedef UNORDERED_MAP SpellTargetPositionMap;
// Spell pet auras
class PetAura
{
private:
typedef UNORDERED_MAP PetAuraMap;
public:
PetAura()
{
auras.clear();
}
PetAura(uint32 petEntry, uint32 aura, bool _removeOnChangePet, int _damage) :
removeOnChangePet(_removeOnChangePet), damage(_damage)
{
auras[petEntry] = aura;
}
uint32 GetAura(uint32 petEntry) const
{
PetAuraMap::const_iterator itr = auras.find(petEntry);
if (itr != auras.end())
return itr->second;
PetAuraMap::const_iterator itr2 = auras.find(0);
if (itr2 != auras.end())
return itr2->second;
return 0;
}
void AddAura(uint32 petEntry, uint32 aura)
{
auras[petEntry] = aura;
}
bool IsRemovedOnChangePet() const
{
return removeOnChangePet;
}
int32 GetDamage() const
{
return damage;
}
private:
PetAuraMap auras;
bool removeOnChangePet;
int32 damage;
};
typedef std::map SpellPetAuraMap;
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 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
// helpers
bool IsFitToRequirements(Player const* player, uint32 newZone, uint32 newArea) const;
};
typedef std::multimap SpellAreaMap;
typedef std::multimap SpellAreaForQuestMap;
typedef std::multimap SpellAreaForAuraMap;
typedef std::multimap SpellAreaForAreaMap;
typedef std::pair SpellAreaMapBounds;
typedef std::pair SpellAreaForQuestMapBounds;
typedef std::pair SpellAreaForAuraMapBounds;
typedef std::pair SpellAreaForAreaMapBounds;
// Spell rank chain (accessed using SpellMgr functions)
struct SpellChainNode
{
SpellInfo const* prev;
SpellInfo const* next;
SpellInfo const* first;
SpellInfo const* last;
uint8 rank;
};
typedef UNORDERED_MAP SpellChainMap;
// spell_id req_spell
typedef std::multimap SpellRequiredMap;
typedef std::pair SpellRequiredMapBounds;
// req_spell spell_id
typedef std::multimap SpellsRequiringSpellMap;
typedef std::pair SpellsRequiringSpellMapBounds;
// Spell learning properties (accessed using SpellMgr functions)
struct SpellLearnSkillNode
{
uint16 skill;
uint16 step;
uint16 value; // 0 - max skill value for player level
uint16 maxvalue; // 0 - max skill value for player level
};
typedef std::map SpellLearnSkillMap;
struct SpellLearnSpellNode
{
uint32 spell;
bool active; // show in spellbook or not
bool autoLearned;
};
typedef std::multimap SpellLearnSpellMap;
typedef std::pair SpellLearnSpellMapBounds;
typedef std::multimap SkillLineAbilityMap;
typedef std::pair SkillLineAbilityMapBounds;
typedef std::multimap PetLevelupSpellSet;
typedef std::map PetLevelupSpellMap;
typedef std::map SpellDifficultySearcherMap;
struct PetDefaultSpellsEntry
{
uint32 spellid[MAX_CREATURE_SPELL_DATA_SLOT];
};
// < 0 for petspelldata id, > 0 for creature_id
typedef std::map PetDefaultSpellsMap;
typedef std::vector SpellCustomAttribute;
typedef std::vector EnchantCustomAttribute;
typedef std::vector SpellInfoMap;
typedef std::map > SpellLinkedMap;
bool IsPrimaryProfessionSkill(uint32 skill);
inline bool IsProfessionSkill(uint32 skill)
{
return IsPrimaryProfessionSkill(skill) || skill == SKILL_FISHING || skill == SKILL_COOKING || skill == SKILL_FIRST_AID;
}
inline bool IsProfessionOrRidingSkill(uint32 skill)
{
return IsProfessionSkill(skill) || skill == SKILL_RIDING;
}
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);
class SpellMgr
{
friend class ACE_Singleton;
// Constructors
private:
SpellMgr();
~SpellMgr();
// Accessors (const or static functions)
public:
// Spell correctness for client using
static bool IsSpellValid(SpellInfo const* spellInfo, Player* player = 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;
// 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;
// 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;
// Spell target coordinates
SpellTargetPosition const* GetSpellTargetPosition(uint32 spell_id) const;
// Spell Groups table
SpellSpellGroupMapBounds GetSpellSpellGroupMapBounds(uint32 spell_id) const;
uint32 IsSpellMemberOfSpellGroup(uint32 spellid, SpellGroup groupid) const;
SpellGroupSpellMapBounds GetSpellGroupSpellMapBounds(SpellGroup group_id) const;
void GetSetOfSpellsInSpellGroup(SpellGroup group_id, std::set& foundSpells) const;
void GetSetOfSpellsInSpellGroup(SpellGroup group_id, std::set& foundSpells, std::set& usedGroups) const;
// Spell Group Stack Rules table
bool AddSameEffectStackRuleSpellGroups(SpellInfo const* spellInfo, int32 amount, std::map& groups) const;
SpellGroupStackRule CheckSpellGroupStackRules(SpellInfo const* spellInfo1, SpellInfo const* spellInfo2) const;
// 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);
// Spell proc table
SpellProcEntry const* GetSpellProcEntry(uint32 spellId) const;
bool CanSpellTriggerProcOnEvent(SpellProcEntry const& procEntry, ProcEventInfo& eventInfo);
// Spell bonus data table
SpellBonusEntry const* GetSpellBonusData(uint32 spellId) const;
// Spell threat table
SpellThreatEntry const* GetSpellThreatEntry(uint32 spellID) const;
SkillLineAbilityMapBounds GetSkillLineAbilityMapBounds(uint32 spell_id) const;
PetAura const* GetPetAura(uint32 spell_id, uint8 eff);
SpellEnchantProcEntry const* GetSpellEnchantProcEvent(uint32 enchId) const;
bool IsArenaAllowedEnchancment(uint32 ench_id) const;
const std::vector *GetSpellLinked(int32 spell_id) const;
PetLevelupSpellSet const* GetPetLevelupSpellList(uint32 petFamily) const;
PetDefaultSpellsEntry const* GetPetDefaultSpellsEntry(int32 id) const;
// 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;
// SpellInfo object management
SpellInfo const* GetSpellInfo(uint32 spellId) const { return spellId < GetSpellInfoStoreSize() ? mSpellInfoMap[spellId] : NULL; }
uint32 GetSpellInfoStoreSize() const { return mSpellInfoMap.size(); }
// Modifiers
public:
// Loading data at server startup
void LoadSpellRanks();
void LoadSpellRequired();
void LoadSpellLearnSkills();
void LoadSpellLearnSpells();
void LoadSpellTargetPositions();
void LoadSpellGroups();
void LoadSpellGroupStackRules();
void LoadSpellProcEvents();
void LoadSpellProcs();
void LoadSpellBonusess();
void LoadSpellThreats();
void LoadSkillLineAbilityMap();
void LoadSpellPetAuras();
void LoadEnchantCustomAttr();
void LoadSpellEnchantProcData();
void LoadSpellLinked();
void LoadPetLevelupSpellMap();
void LoadPetDefaultSpells();
void LoadSpellAreas();
void LoadSpellInfoStore();
void UnloadSpellInfoStore();
void UnloadSpellInfoImplicitTargetConditionLists();
void LoadSpellCustomAttr();
void LoadDbcDataCorrections();
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;
};
#define sSpellMgr ACE_Singleton::instance()
#endif