OregonCore  revision be9e804-git
Your Favourite TBC server
SpellMgr.cpp File Reference
#include "Unit.h"
#include "SpellMgr.h"
#include "ObjectMgr.h"
#include "SpellAuraDefines.h"
#include "DBCStores.h"
#include "Chat.h"
#include "Spell.h"
#include "CreatureAI.h"
#include "BattlegroundMgr.h"

Go to the source code of this file.

Classes

struct  SpellRankEntry
 
struct  SpellRankValue
 

Functions

int32 GetSpellDuration (SpellEntry const *spellInfo)
 
int32 GetSpellMaxDuration (SpellEntry const *spellInfo)
 
uint32 GetSpellCastTime (SpellEntry const *spellInfo, Spell const *spell)
 
bool IsPassiveSpell (uint32 spellId)
 
bool IsPassiveSpell (SpellEntry const *spellInfo)
 
bool IsAutocastableSpell (uint32 spellId)
 
uint32 CalculatePowerCost (SpellEntry const *spellInfo, Unit const *caster, SpellSchoolMask schoolMask)
 
int32 CompareAuraRanks (uint32 spellId_1, uint32 effIndex_1, uint32 spellId_2, uint32 effIndex_2)
 
SpellSpecific GetSpellSpecific (uint32 spellId)
 
bool IsPositiveTarget (uint32 targetA, uint32 targetB)
 
bool IsPositiveEffect (uint32 spellId, uint32 effIndex)
 
bool IsPositiveSpell (uint32 spellId)
 
bool IsSingleTargetSpell (SpellEntry const *spellInfo)
 
bool IsSingleTargetSpells (SpellEntry const *spellInfo1, SpellEntry const *spellInfo2)
 
bool IsAuraAddedBySpell (uint32 auraType, uint32 spellId)
 
SpellCastResult GetErrorAtShapeshiftedCast (SpellEntry const *spellInfo, uint32 form)
 
IsNoStackSpellDueToSpell

Determines whether a spell can stack, based on parameters of another spell

Parameters
spellId_1Spell to compare
spellId_2Spell we are comparing to
sameCasterAre these spells casted by the same entity?
SpellCastResult IsSpellAllowedInLocation (SpellEntry const *spellInfo, uint32 map_id, uint32 zone_id, uint32 area_id)
 
DiminishingGroup GetDiminishingReturnsGroupForSpell (SpellEntry const *spellproto, bool triggered)
 
bool IsDiminishingReturnsGroupDurationLimited (DiminishingGroup group)
 
DiminishingReturnsType GetDiminishingReturnsGroupType (DiminishingGroup group)
 

Variables

bool IsAreaEffectTarget [TOTAL_SPELL_TARGETS]
 

Function Documentation

uint32 CalculatePowerCost ( SpellEntry const *  spellInfo,
Unit const *  caster,
SpellSchoolMask  schoolMask 
)

Definition at line 303 of file SpellMgr.cpp.

References SpellEntry::Attributes, SpellEntry::AttributesEx, SpellEntry::AttributesEx4, Unit::GetAttackTime(), Unit::GetCreateHealth(), Unit::GetCreateMana(), GetFirstSchoolInMask(), Object::GetFloatValue(), Unit::GetHealth(), Object::GetInt32Value(), Unit::getLevel(), Unit::GetMaxPower(), Unit::GetPower(), Unit::GetSpellModOwner(), SpellEntry::Id, Unit::IsControlledByPlayer(), SpellEntry::manaCost, SpellEntry::ManaCostPercentage, MAX_POWERS, OFF_ATTACK, POWER_ENERGY, POWER_FOCUS, POWER_HAPPINESS, POWER_HEALTH, POWER_MANA, POWER_RAGE, SpellEntry::powerType, GtNPCManaCostScalerEntry::ratio, sGtNPCManaCostScalerStore, sLog, SPELL_ATTR0_LEVEL_DAMAGE_CALCULATION, SPELL_ATTR1_DRAIN_ALL_POWER, SPELL_ATTR4_SPELL_VS_EXTEND_COST, SpellEntry::spellLevel, SPELLMOD_COST, UNIT_FIELD_POWER_COST_MODIFIER, and UNIT_FIELD_POWER_COST_MULTIPLIER.

Referenced by CreatureEventAI::CanCast(), IsDeathOnlySpell(), Spell::prepare(), and SmartScript::ProcessAction().

304 {
305  // Spell drain all exist power on cast (Only paladin lay of Hands)
306  if (spellInfo->AttributesEx & SPELL_ATTR1_DRAIN_ALL_POWER)
307  {
308  // If power type - health drain all
309  if (spellInfo->powerType == POWER_HEALTH)
310  return caster->GetHealth();
311  // Else drain all power
312  if (spellInfo->powerType < MAX_POWERS)
313  return caster->GetPower(Powers(spellInfo->powerType));
314  sLog.outError("CalculateManaCost: Unknown power type '%d' in spell %d", spellInfo->powerType, spellInfo->Id);
315  return 0;
316  }
317 
318  // Base powerCost
319  int32 powerCost = spellInfo->manaCost;
320  // PCT cost from total amount
321  if (spellInfo->ManaCostPercentage)
322  {
323  switch (spellInfo->powerType)
324  {
325  // health as power used
326  case POWER_HEALTH:
327  powerCost += spellInfo->ManaCostPercentage * caster->GetCreateHealth() / 100;
328  break;
329  case POWER_MANA:
330  powerCost += spellInfo->ManaCostPercentage * caster->GetCreateMana() / 100;
331  break;
332  case POWER_RAGE:
333  case POWER_FOCUS:
334  case POWER_ENERGY:
335  case POWER_HAPPINESS:
336  powerCost += spellInfo->ManaCostPercentage * caster->GetMaxPower(Powers(spellInfo->powerType)) / 100;
337  break;
338  default:
339  sLog.outError("CalculateManaCost: Unknown power type '%d' in spell %d", spellInfo->powerType, spellInfo->Id);
340  return 0;
341  }
342  }
343  SpellSchools school = GetFirstSchoolInMask(schoolMask);
344  // Flat mod from caster auras by spell school
345  powerCost += caster->GetInt32Value(UNIT_FIELD_POWER_COST_MODIFIER + school);
346  // Shiv - costs 20 + weaponSpeed*10 energy (apply only to non-triggered spell with energy cost)
347  if (spellInfo->AttributesEx4 & SPELL_ATTR4_SPELL_VS_EXTEND_COST)
348  powerCost += caster->GetAttackTime(OFF_ATTACK) / 100;
349  // Apply cost mod by spell
350  if (Player* modOwner = caster->GetSpellModOwner())
351  modOwner->ApplySpellMod(spellInfo->Id, SPELLMOD_COST, powerCost);
352 
353  if (!caster->IsControlledByPlayer() && spellInfo->Attributes & SPELL_ATTR0_LEVEL_DAMAGE_CALCULATION)
354  {
355  GtNPCManaCostScalerEntry const* spellScaler = sGtNPCManaCostScalerStore.LookupEntry(spellInfo->spellLevel - 1);
356  GtNPCManaCostScalerEntry const* casterScaler = sGtNPCManaCostScalerStore.LookupEntry(caster->getLevel() - 1);
357  if (spellScaler && casterScaler)
358  powerCost *= casterScaler->ratio / spellScaler->ratio;
359  }
360 
361  // PCT mod from user auras by school
362  powerCost = int32(powerCost * (1.0f + caster->GetFloatValue(UNIT_FIELD_POWER_COST_MULTIPLIER + school)));
363  if (powerCost < 0)
364  powerCost = 0;
365  return powerCost;
366 }
SpellSchools GetFirstSchoolInMask(SpellSchoolMask mask)
SpellSchools
DBCStorage< GtNPCManaCostScalerEntry > sGtNPCManaCostScalerStore(GtNPCManaCostScalerfmt)
#define sLog
Log class singleton.
Definition: Log.h:187
ACE_INT32 int32
Definition: Define.h:67
#define MAX_POWERS
Powers
Player * GetSpellModOwner() const
Definition: Unit.cpp:11862
Definition: Player.h:923
int32 CompareAuraRanks ( uint32  spellId_1,
uint32  effIndex_1,
uint32  spellId_2,
uint32  effIndex_2 
)

Definition at line 384 of file SpellMgr.cpp.

References SpellEntry::EffectBasePoints, and sSpellStore.

Referenced by IsDeathOnlySpell(), and Unit::RemoveNoStackAurasDueToAura().

385 {
386  SpellEntry const* spellInfo_1 = sSpellStore.LookupEntry(spellId_1);
387  SpellEntry const* spellInfo_2 = sSpellStore.LookupEntry(spellId_2);
388  if (!spellInfo_1 || !spellInfo_2) return 0;
389  if (spellId_1 == spellId_2) return 0;
390 
391  int32 diff = spellInfo_1->EffectBasePoints[effIndex_1] - spellInfo_2->EffectBasePoints[effIndex_2];
392  if (spellInfo_1->EffectBasePoints[effIndex_1] + 1 < 0 && spellInfo_2->EffectBasePoints[effIndex_2] + 1 < 0) return -diff;
393  else return diff;
394 }
ACE_INT32 int32
Definition: Define.h:67
int32 EffectBasePoints[MAX_SPELL_EFFECTS]
Definition: DBCStructure.h:729
DBCStorage< SpellEntry > sSpellStore(SpellEntryfmt)
DiminishingGroup GetDiminishingReturnsGroupForSpell ( SpellEntry const *  spellproto,
bool  triggered 
)

Definition at line 3058 of file SpellMgr.cpp.

References SpellEntry::Attributes, DIMINISHING_BANISH, DIMINISHING_BLIND_CYCLONE, DIMINISHING_CONTROLLED_ROOT, DIMINISHING_CONTROLLED_STUN, DIMINISHING_DISARM, DIMINISHING_DISORIENT, DIMINISHING_ENTRAPMENT, DIMINISHING_FEAR, DIMINISHING_FREEZE, DIMINISHING_HORROR, DIMINISHING_KIDNEYSHOT, DIMINISHING_LIMITONLY, DIMINISHING_MIND_CONTROL, DIMINISHING_NONE, DIMINISHING_ROOT, DIMINISHING_SILENCE, DIMINISHING_SLEEP, DIMINISHING_STUN, SpellEntry::GetAllEffectsMechanicMask(), SpellEntry::Id, IsPositiveSpell(), MECHANIC_BANISH, MECHANIC_CHARM, MECHANIC_DISARM, MECHANIC_FEAR, MECHANIC_FREEZE, MECHANIC_HORROR, MECHANIC_KNOCKOUT, MECHANIC_POLYMORPH, MECHANIC_ROOT, MECHANIC_SAPPED, MECHANIC_SHACKLE, MECHANIC_SLEEP, MECHANIC_STUN, SPELLFAMILY_DRUID, SPELLFAMILY_HUNTER, SPELLFAMILY_MAGE, SPELLFAMILY_PALADIN, SPELLFAMILY_ROGUE, SPELLFAMILY_UNK1, SPELLFAMILY_WARLOCK, SPELLFAMILY_WARRIOR, SpellEntry::SpellFamilyFlags, SpellEntry::SpellFamilyName, SpellEntry::SpellIconID, and SpellEntry::SpellVisual.

Referenced by Spell::DoSpellHitOnUnit(), GetDispelMask(), and Spell::handle_immediate().

3059 {
3060  if (!spellproto || IsPositiveSpell(spellproto->Id))
3061  return DIMINISHING_NONE;
3062 
3063  // Explicit Diminishing Groups
3064  switch (spellproto->SpellFamilyName)
3065  {
3066  // Event + General spells
3067  case SPELLFAMILY_UNK1:
3068  return DIMINISHING_NONE;
3069  case SPELLFAMILY_MAGE:
3070  {
3071  // Item "Magic Dust" shouldn't be limited in PvP and
3072  // does not share DR with other sleep mechanics.
3073  if (spellproto->SpellIconID == 44)
3074  return DIMINISHING_NONE;
3075  break;
3076  // Frost Nova / Freeze (Water Elemental)
3077  if (spellproto->SpellIconID == 193)
3079  break;
3080  }
3081  case SPELLFAMILY_WARRIOR:
3082  {
3083  // Hamstring - limit duration to 10s in PvP
3084  if (spellproto->SpellFamilyFlags & 0x00000000002LL)
3085  return DIMINISHING_LIMITONLY;
3086  break;
3087  }
3088  case SPELLFAMILY_WARLOCK:
3089  {
3090  // Death Coil
3091  if (spellproto->SpellFamilyFlags & 0x00000080000LL)
3092  return DIMINISHING_HORROR;
3093  // Seduction
3094  else if (spellproto->SpellFamilyFlags & 0x00040000000LL)
3095  return DIMINISHING_FEAR;
3096  // Curses/etc
3097  else if (spellproto->SpellFamilyFlags & 0x00080000000LL)
3098  return DIMINISHING_LIMITONLY;
3099  // Unstable affliction dispel silence
3100  else if (spellproto->Id == 31117)
3101  return DIMINISHING_SILENCE;
3102  break;
3103  }
3104  case SPELLFAMILY_DRUID:
3105  {
3106  // Cyclone
3107  if (spellproto->SpellFamilyFlags & 0x02000000000LL)
3109  // Nature's Grasp trigger
3110  if (spellproto->SpellFamilyFlags & 0x00000000200LL && spellproto->Attributes == 0x49010000)
3112  break;
3113  }
3114  case SPELLFAMILY_ROGUE:
3115  {
3116  // Kidney Shot
3117  if (spellproto->SpellFamilyFlags & 0x00000200000LL)
3118  return DIMINISHING_KIDNEYSHOT;
3119  // Gouge
3120  else if (spellproto->SpellFamilyFlags & 0x00000000008LL)
3121  return DIMINISHING_DISORIENT;
3122  // Blind
3123  else if (spellproto->SpellFamilyFlags & 0x00001000000LL)
3125  break;
3126  }
3127  case SPELLFAMILY_HUNTER:
3128  {
3129  // Freezing trap
3130  if (spellproto->SpellFamilyFlags & 0x00000000008LL)
3131  return DIMINISHING_FREEZE;
3132  // Intimidation
3133  else if (spellproto->Id == 24394)
3135  // Entrapment (own diminishing)
3136  else if (spellproto->SpellVisual == 7484 && spellproto->SpellIconID == 20)
3137  return DIMINISHING_ENTRAPMENT;
3138  break;
3139  }
3140  case SPELLFAMILY_PALADIN:
3141  {
3142  // Turn Evil shared diminishing with fear
3143  if (spellproto->Id == 10326)
3144  return DIMINISHING_FEAR;
3145  break;
3146  }
3147  default:
3148  {
3149  if (spellproto->Id == 12494) // frostbite
3150  return DIMINISHING_ROOT;
3151  break;
3152  }
3153  }
3154 
3155  // Lastly - Set diminishing depending on mechanic
3156  uint32 mechanic = spellproto->GetAllEffectsMechanicMask();
3157  if (mechanic & (1 << MECHANIC_CHARM))
3158  return DIMINISHING_MIND_CONTROL;
3159  if (mechanic & (1 << MECHANIC_SLEEP))
3160  return DIMINISHING_SLEEP;
3161  if (mechanic & ((1 << MECHANIC_SAPPED) | (1 << MECHANIC_POLYMORPH) | (1 << MECHANIC_SHACKLE)))
3162  return DIMINISHING_DISORIENT;
3163  if (mechanic & (1 << MECHANIC_KNOCKOUT))
3164  return DIMINISHING_DISORIENT;
3165  if (mechanic & (1 << MECHANIC_DISARM))
3166  return DIMINISHING_DISARM;
3167  if (mechanic & (1 << MECHANIC_FEAR))
3168  return DIMINISHING_FEAR;
3169  if (mechanic & (1 << MECHANIC_STUN))
3170  return triggered ? DIMINISHING_STUN : DIMINISHING_CONTROLLED_STUN;
3171  if (mechanic & (1 << MECHANIC_BANISH))
3172  return DIMINISHING_BANISH;
3173  if (mechanic & (1 << MECHANIC_ROOT))
3174  return triggered ? DIMINISHING_ROOT : DIMINISHING_CONTROLLED_ROOT;
3175  if (mechanic & (1 << MECHANIC_FREEZE))
3176  return DIMINISHING_FREEZE;
3177  if (mechanic & (1 << MECHANIC_HORROR))
3178  return DIMINISHING_HORROR;
3179 
3180  return DIMINISHING_NONE;
3181 }
bool IsPositiveSpell(uint32 spellId)
Definition: SpellMgr.cpp:773
ACE_UINT32 uint32
Definition: Define.h:71
DiminishingReturnsType GetDiminishingReturnsGroupType ( DiminishingGroup  group)

Definition at line 3208 of file SpellMgr.cpp.

References DIMINISHING_BANISH, DIMINISHING_BLIND_CYCLONE, DIMINISHING_CONTROLLED_ROOT, DIMINISHING_CONTROLLED_STUN, DIMINISHING_DISARM, DIMINISHING_DISORIENT, DIMINISHING_FEAR, DIMINISHING_FREEZE, DIMINISHING_HORROR, DIMINISHING_KIDNEYSHOT, DIMINISHING_MIND_CONTROL, DIMINISHING_ROOT, DIMINISHING_SILENCE, DIMINISHING_SLEEP, DIMINISHING_STUN, DIMINISHING_WARLOCK_FEAR, DRTYPE_ALL, DRTYPE_NONE, and DRTYPE_PLAYER.

Referenced by Unit::ApplyDiminishingToDuration(), Spell::DoSpellHitOnUnit(), and GetDispelMask().

3209 {
3210  switch (group)
3211  {
3214  case DIMINISHING_STUN:
3216  return DRTYPE_ALL;
3217  case DIMINISHING_SLEEP:
3219  case DIMINISHING_ROOT:
3220  case DIMINISHING_FEAR:
3222  case DIMINISHING_DISORIENT:
3223  case DIMINISHING_DISARM:
3224  case DIMINISHING_HORROR:
3225  case DIMINISHING_FREEZE:
3226  case DIMINISHING_BANISH:
3228  case DIMINISHING_SILENCE:
3229  return DRTYPE_PLAYER;
3230  default:
3231  break;
3232  }
3233 
3234  return DRTYPE_NONE;
3235 }
SpellCastResult GetErrorAtShapeshiftedCast ( SpellEntry const *  spellInfo,
uint32  form 
)

Definition at line 842 of file SpellMgr.cpp.

References SpellEntry::Attributes, SpellEntry::AttributesEx2, SpellEntry::Effect, SpellShapeshiftEntry::flags1, GetTalentSpellCost(), SpellEntry::Id, sLog, SPELL_ATTR0_NOT_SHAPESHIFT, SPELL_ATTR2_NOT_NEED_SHAPESHIFT, SPELL_CAST_OK, SPELL_EFFECT_LEARN_SPELL, SPELL_FAILED_NOT_SHAPESHIFT, SPELL_FAILED_ONLY_SHAPESHIFT, sSpellShapeshiftStore, SpellEntry::Stances, and SpellEntry::StancesNot.

Referenced by Player::ApplyEquipSpell(), Spell::CheckCast(), and IsAutoRepeatRangedSpell().

843 {
844  // talents that learn spells can have stance requirements that need ignore
845  // (this requirement only for client-side stance show in talent description)
846  if (GetTalentSpellCost(spellInfo->Id) > 0 &&
847  (spellInfo->Effect[0] == SPELL_EFFECT_LEARN_SPELL || spellInfo->Effect[1] == SPELL_EFFECT_LEARN_SPELL || spellInfo->Effect[2] == SPELL_EFFECT_LEARN_SPELL))
848  return SPELL_CAST_OK;
849 
850  uint32 stanceMask = (form ? 1 << (form - 1) : 0);
851 
852  if (stanceMask & spellInfo->StancesNot) // can explicitly not be casted in this stance
854 
855  if (stanceMask & spellInfo->Stances) // can explicitly be casted in this stance
856  return SPELL_CAST_OK;
857 
858  bool actAsShifted = false;
859  if (form > 0)
860  {
861  SpellShapeshiftEntry const* shapeInfo = sSpellShapeshiftStore.LookupEntry(form);
862  if (!shapeInfo)
863  {
864  sLog.outError("GetErrorAtShapeshiftedCast: unknown shapeshift %u", form);
865  return SPELL_CAST_OK;
866  }
867  actAsShifted = !(shapeInfo->flags1 & 1); // shapeshift acts as normal form for spells
868  }
869 
870  if (actAsShifted)
871  {
872  if (spellInfo->Attributes & SPELL_ATTR0_NOT_SHAPESHIFT) // not while shapeshifted
874  else if (spellInfo->Stances != 0) // needs other shapeshift
876  }
877  else
878  {
879  // needs shapeshift
880  if (!(spellInfo->AttributesEx2 & SPELL_ATTR2_NOT_NEED_SHAPESHIFT) && spellInfo->Stances != 0)
882  }
883 
884  return SPELL_CAST_OK;
885 }
#define sLog
Log class singleton.
Definition: Log.h:187
uint32 GetTalentSpellCost(uint32 spellId)
Definition: DBCStores.cpp:598
ACE_UINT32 uint32
Definition: Define.h:71
DBCStorage< SpellShapeshiftEntry > sSpellShapeshiftStore(SpellShapeshiftfmt)
uint32 GetSpellCastTime ( SpellEntry const *  spellInfo,
Spell const *  spell 
)

Definition at line 248 of file SpellMgr.cpp.

References SpellEntry::Attributes, SpellEntry::CastingTimeIndex, SpellCastTimesEntry::CastTime, Spell::GetCaster(), Object::GetFloatValue(), Unit::GetSpellModOwner(), SpellEntry::Id, Spell::IsAutoRepeat(), Spell::IsRangedSpell(), Unit::m_modAttackSpeedPct, RANGED_ATTACK, SPELL_ATTR0_ABILITY, SPELL_ATTR0_RANGED, SPELL_ATTR0_TRADESPELL, SPELLMOD_CASTING_TIME, sSpellCastTimesStore, and UNIT_MOD_CAST_SPEED.

Referenced by GameObject::CastSpell(), Unit::GetCastingTimeForBonus(), GetSpellRadiusForFriend(), Totem::InitStats(), Spell::prepare(), Unit::ProcDamageAndSpellFor(), Unit::SpellDamageBonus(), and Unit::SpellHealingBonus().

249 {
250  SpellCastTimesEntry const* spellCastTimeEntry = sSpellCastTimesStore.LookupEntry(spellInfo->CastingTimeIndex);
251 
252  // not all spells have cast time index and this is all is pasiive abilities
253  if (!spellCastTimeEntry)
254  return 0;
255 
256  int32 castTime = spellCastTimeEntry->CastTime;
257 
258  if (spell)
259  {
260  if (Player* modOwner = spell->GetCaster()->GetSpellModOwner())
261  modOwner->ApplySpellMod(spellInfo->Id, SPELLMOD_CASTING_TIME, castTime, spell);
262 
263  if (!(spellInfo->Attributes & (SPELL_ATTR0_ABILITY | SPELL_ATTR0_TRADESPELL)))
264  castTime = int32(castTime * spell->GetCaster()->GetFloatValue(UNIT_MOD_CAST_SPEED));
265  else
266  {
267  if (spell->IsRangedSpell() && !spell->IsAutoRepeat())
268  castTime = int32(castTime * spell->GetCaster()->m_modAttackSpeedPct[RANGED_ATTACK]);
269  }
270  }
271 
272  if (spellInfo->Attributes & SPELL_ATTR0_RANGED && (!spell || !spell->IsAutoRepeat()))
273  castTime += 500;
274 
275  return (castTime > 0) ? uint32(castTime) : 0;
276 }
DBCStorage< SpellCastTimesEntry > sSpellCastTimesStore(SpellCastTimefmt)
ACE_INT32 int32
Definition: Define.h:67
Player * GetSpellModOwner() const
Definition: Unit.cpp:11862
ACE_UINT32 uint32
Definition: Define.h:71
Definition: Player.h:923
int32 GetSpellMaxDuration ( SpellEntry const *  spellInfo)

Definition at line 238 of file SpellMgr.cpp.

References SpellDurationEntry::Duration, SpellEntry::DurationIndex, and sSpellDurationStore.

Referenced by Unit::CalculateSpellDuration(), and GetSpellRecoveryTime().

239 {
240  if (!spellInfo)
241  return 0;
242  SpellDurationEntry const* du = sSpellDurationStore.LookupEntry(spellInfo->DurationIndex);
243  if (!du)
244  return 0;
245  return (du->Duration[2] == -1) ? -1 : abs(du->Duration[2]);
246 }
DBCStorage< SpellDurationEntry > sSpellDurationStore(SpellDurationfmt)
SpellSpecific GetSpellSpecific ( uint32  spellId)

Definition at line 396 of file SpellMgr.cpp.

References SpellEntry::activeIconID, SpellEntry::Attributes, SpellEntry::AttributesEx3, AURA_INTERRUPT_FLAG_NOT_SEATED, SpellEntry::AuraInterruptFlags, SpellEntry::Dispel, DISPEL_CURSE, DISPEL_POISON, SpellEntry::Effect, SpellEntry::EffectApplyAuraName, GetSpellSchoolMask(), SpellEntry::Id, IsElementalShield(), IsSealSpell(), MAX_SPELL_EFFECTS, SPELL_AURA_MOD_CHARM, SPELL_AURA_MOD_CONFUSE, SPELL_AURA_MOD_POSSESS, SPELL_AURA_MOD_POSSESS_PET, SPELL_AURA_MOD_POWER_REGEN, SPELL_AURA_MOD_REGEN, SPELL_AURA_OBS_MOD_HEALTH, SPELL_AURA_TRACK_CREATURES, SPELL_AURA_TRACK_RESOURCES, SPELL_AURA_TRACK_STEALTHED, SPELL_EFFECT_APPLY_AREA_AURA_PARTY, SPELL_EFFECT_APPLY_AURA, SPELL_SCHOOL_MASK_NATURE, SPELL_SPECIFIC_ARMOR_REDUCE, SPELL_SPECIFIC_ASPECT, SPELL_SPECIFIC_AURA, SPELL_SPECIFIC_CHARM, SPELL_SPECIFIC_CURSE, SPELL_SPECIFIC_DRINK, SPELL_SPECIFIC_ELEMENTAL_SHIELD, SPELL_SPECIFIC_FOOD, SPELL_SPECIFIC_JUDGEMENT, SPELL_SPECIFIC_MAGE_ARMOR, SPELL_SPECIFIC_MAGE_POLYMORPH, SPELL_SPECIFIC_NORMAL, SPELL_SPECIFIC_SEAL, SPELL_SPECIFIC_STING, SPELL_SPECIFIC_TRACKER, SPELL_SPECIFIC_WARLOCK_ARMOR, SPELL_SPECIFIC_WARLOCK_CORRUPTION, SPELL_SPECIFIC_WARRIOR_ENRAGE, SPELLFAMILY_GENERIC, SPELLFAMILY_HUNTER, SPELLFAMILY_MAGE, SPELLFAMILY_PALADIN, SPELLFAMILY_ROGUE, SPELLFAMILY_SHAMAN, SPELLFAMILY_WARLOCK, SPELLFAMILY_WARRIOR, SpellEntry::SpellFamilyFlags, SpellEntry::SpellFamilyName, SpellEntry::SpellIconID, SpellEntry::SpellVisual, and sSpellStore.

Referenced by SpellMgr::IsNoStackSpellDueToSpell(), Unit::IsPolymorphed(), IsSingleTargetSpell(), and IsSingleTargetSpells().

397 {
398  SpellEntry const* spellInfo = sSpellStore.LookupEntry(spellId);
399  if (!spellInfo)
400  return SPELL_SPECIFIC_NORMAL;
401 
402  switch (spellInfo->SpellFamilyName)
403  {
404  case SPELLFAMILY_GENERIC:
405  {
406  // Food / Drinks (mostly)
408  {
409  for (int i = 0; i < MAX_SPELL_EFFECTS; i++)
410  {
411  if (spellInfo->EffectApplyAuraName[i] == SPELL_AURA_MOD_POWER_REGEN)
412  return SPELL_SPECIFIC_DRINK;
413 
414  if (spellInfo->EffectApplyAuraName[i] == SPELL_AURA_MOD_REGEN ||
416  return SPELL_SPECIFIC_FOOD;
417  }
418  }
419 
420  switch (spellInfo->Id)
421  {
422  case 12880: // warrior's Enrage rank 1
423  case 14201: // Enrage rank 2
424  case 14202: // Enrage rank 3
425  case 14203: // Enrage rank 4
426  case 14204: // Enrage rank 5
427  case 12292: // Death Wish
429  break;
430  default:
431  break;
432  }
433  break;
434  }
435  case SPELLFAMILY_MAGE:
436  {
437  // family flags 18(Molten), 25(Frost/Ice), 28(Mage)
438  if (spellInfo->SpellFamilyFlags & 0x12040000)
440 
441  if ((spellInfo->SpellFamilyFlags & 0x1000000) && spellInfo->EffectApplyAuraName[0] == SPELL_AURA_MOD_CONFUSE)
443 
444  break;
445  }
446  case SPELLFAMILY_WARRIOR:
447  {
448  // Sunder Armor (vs Expose Armor)
449  if (spellInfo->SpellFamilyFlags & 0x00000000004000LL)
451 
452  break;
453  }
454  case SPELLFAMILY_WARLOCK:
455  {
456  // only warlock curses have this
457  if (spellInfo->Dispel == DISPEL_CURSE)
458  return SPELL_SPECIFIC_CURSE;
459 
460  // family flag 37 (only part spells have family name)
461  if (spellInfo->SpellFamilyFlags & 0x2000000000LL)
463 
464  //seed of corruption and corruption
465  if (spellInfo->SpellFamilyFlags & 0x1000000002LL)
467  break;
468  }
469  case SPELLFAMILY_HUNTER:
470  {
471  // only hunter stings have this
472  if (spellInfo->Dispel == DISPEL_POISON)
473  return SPELL_SPECIFIC_STING;
474 
475  break;
476  }
477  case SPELLFAMILY_PALADIN:
478  {
479  if (IsSealSpell(spellInfo))
480  return SPELL_SPECIFIC_SEAL;
481 
482  if ((spellInfo->SpellFamilyFlags & 0x00000820180400LL) && (spellInfo->AttributesEx3 & 0x200))
484 
485  for (int i = 0; i < MAX_SPELL_EFFECTS; i++)
486  {
487  // only paladin auras have this
488  if (spellInfo->Effect[i] == SPELL_EFFECT_APPLY_AREA_AURA_PARTY)
489  return SPELL_SPECIFIC_AURA;
490  }
491  break;
492  }
493  case SPELLFAMILY_SHAMAN:
494  {
495  if (IsElementalShield(spellInfo))
497 
498  break;
499  }
500  case SPELLFAMILY_ROGUE:
501  {
502  // Expose Armor (vs Sunder Armor)
503  if (spellInfo->SpellFamilyFlags & 0x00000000080000LL)
505  break;
506  }
507  }
508 
509  // only warlock armor/skin have this (in additional to family cases)
510  if (spellInfo->SpellVisual == 130 && spellInfo->SpellIconID == 89)
512 
513  // only hunter aspects have this (but not all aspects in hunter family)
514  if (spellInfo->activeIconID == 122 && (GetSpellSchoolMask(spellInfo) & SPELL_SCHOOL_MASK_NATURE) &&
515  (spellInfo->Attributes & 0x50000) != 0 && (spellInfo->Attributes & 0x9000010) == 0)
516  return SPELL_SPECIFIC_ASPECT;
517 
518  for (int i = 0; i < MAX_SPELL_EFFECTS; ++i)
519  {
520  if (spellInfo->Effect[i] == SPELL_EFFECT_APPLY_AURA)
521  {
522  switch (spellInfo->EffectApplyAuraName[i])
523  {
527  return SPELL_SPECIFIC_CHARM;
531  return SPELL_SPECIFIC_TRACKER;
532  }
533  }
534  }
535 
536  return SPELL_SPECIFIC_NORMAL;
537 }
uint32 AuraInterruptFlags
Definition: DBCStructure.h:700
uint32 SpellVisual
Definition: DBCStructure.h:743
uint32 Effect[MAX_SPELL_EFFECTS]
Definition: DBCStructure.h:724
DBCStorage< SpellEntry > sSpellStore(SpellEntryfmt)
uint32 EffectApplyAuraName[MAX_SPELL_EFFECTS]
Definition: DBCStructure.h:734
SpellSchoolMask GetSpellSchoolMask(SpellEntry const *spellInfo)
Definition: SpellMgr.h:481
uint32 Attributes
Definition: DBCStructure.h:679
uint32 Dispel
Definition: DBCStructure.h:677
uint32 AttributesEx3
Definition: DBCStructure.h:682
uint64 SpellFamilyFlags
Definition: DBCStructure.h:761
uint32 SpellIconID
Definition: DBCStructure.h:745
bool IsSealSpell(SpellEntry const *spellInfo)
Definition: SpellMgr.h:215
bool IsElementalShield(SpellEntry const *spellInfo)
Definition: SpellMgr.h:223
uint32 SpellFamilyName
Definition: DBCStructure.h:760
#define MAX_SPELL_EFFECTS
Definition: DBCStructure.h:670
uint32 activeIconID
Definition: DBCStructure.h:746
bool IsAuraAddedBySpell ( uint32  auraType,
uint32  spellId 
)

Definition at line 831 of file SpellMgr.cpp.

References SpellEntry::EffectApplyAuraName, MAX_SPELL_EFFECTS, and sSpellStore.

Referenced by IsBinarySpell().

832 {
833  SpellEntry const* spellproto = sSpellStore.LookupEntry(spellId);
834  if (!spellproto) return false;
835 
836  for (int i = 0; i < MAX_SPELL_EFFECTS; i++)
837  if (spellproto->EffectApplyAuraName[i] == auraType)
838  return true;
839  return false;
840 }
DBCStorage< SpellEntry > sSpellStore(SpellEntryfmt)
uint32 EffectApplyAuraName[MAX_SPELL_EFFECTS]
Definition: DBCStructure.h:734
#define MAX_SPELL_EFFECTS
Definition: DBCStructure.h:670
bool IsAutocastableSpell ( uint32  spellId)

Definition at line 291 of file SpellMgr.cpp.

References SpellEntry::Attributes, SpellEntry::AttributesEx, SPELL_ATTR0_PASSIVE, SPELL_ATTR1_UNAUTOCASTABLE_BY_PET, and sSpellStore.

Referenced by Pet::addSpell(), WorldSession::HandlePetSpellAutocastOpcode(), IsDeathOnlySpell(), Pet::LoadPetFromDB(), and Pet::ToggleAutocast().

292 {
293  SpellEntry const* spellInfo = sSpellStore.LookupEntry(spellId);
294  if (!spellInfo)
295  return false;
296  if (spellInfo->Attributes & SPELL_ATTR0_PASSIVE)
297  return false;
299  return false;
300  return true;
301 }
uint32 AttributesEx
Definition: DBCStructure.h:680
DBCStorage< SpellEntry > sSpellStore(SpellEntryfmt)
uint32 Attributes
Definition: DBCStructure.h:679
bool IsDiminishingReturnsGroupDurationLimited ( DiminishingGroup  group)

Definition at line 3183 of file SpellMgr.cpp.

References DIMINISHING_BANISH, DIMINISHING_BLIND_CYCLONE, DIMINISHING_CONTROLLED_ROOT, DIMINISHING_CONTROLLED_STUN, DIMINISHING_DISORIENT, DIMINISHING_FEAR, DIMINISHING_FREEZE, DIMINISHING_KIDNEYSHOT, DIMINISHING_LIMITONLY, DIMINISHING_MIND_CONTROL, DIMINISHING_ROOT, DIMINISHING_SLEEP, DIMINISHING_STUN, and DIMINISHING_WARLOCK_FEAR.

Referenced by Unit::ApplyDiminishingToDuration(), and GetDispelMask().

bool IsPassiveSpell ( SpellEntry const *  spellInfo)

Definition at line 286 of file SpellMgr.cpp.

References SpellEntry::Attributes, and SPELL_ATTR0_PASSIVE.

287 {
288  return (spellInfo->Attributes & SPELL_ATTR0_PASSIVE) != 0;
289 }
bool IsPositiveEffect ( uint32  spellId,
uint32  effIndex 
)

Definition at line 561 of file SpellMgr.cpp.

References SpellEntry::Attributes, SpellEntry::Effect, SpellEntry::EffectApplyAuraName, SpellEntry::EffectBaseDice, SpellEntry::EffectBasePoints, SpellEntry::EffectImplicitTargetA, SpellEntry::EffectImplicitTargetB, SpellEntry::EffectMiscValue, SpellEntry::EffectTriggerSpell, SpellEntry::Id, IsPositiveEffect(), IsPositiveTarget(), MAX_SPELL_EFFECTS, SpellEntry::Mechanic, MECHANIC_BANDAGE, MECHANIC_IMMUNE_SHIELD, MECHANIC_INVULNERABILITY, MECHANIC_MOUNT, MECHANIC_SHIELD, SPELL_ATTR0_NEGATIVE_1, SPELL_AURA_ADD_FLAT_MODIFIER, SPELL_AURA_ADD_PCT_MODIFIER, SPELL_AURA_ADD_TARGET_TRIGGER, SPELL_AURA_GHOST, SPELL_AURA_MECHANIC_IMMUNITY, SPELL_AURA_MOD_DAMAGE_DONE, SPELL_AURA_MOD_DAMAGE_PERCENT_DONE, SPELL_AURA_MOD_DAMAGE_TAKEN, SPELL_AURA_MOD_DECREASE_SPEED, SPELL_AURA_MOD_DODGE_PERCENT, SPELL_AURA_MOD_HEALING_DONE, SPELL_AURA_MOD_HEALING_PCT, SPELL_AURA_MOD_PACIFY_SILENCE, SPELL_AURA_MOD_ROOT, SPELL_AURA_MOD_SILENCE, SPELL_AURA_MOD_SKILL, SPELL_AURA_MOD_SPELL_CRIT_CHANCE, SPELL_AURA_MOD_STALKED, SPELL_AURA_MOD_STAT, SPELL_AURA_MOD_STUN, SPELL_AURA_PERIODIC_DAMAGE, SPELL_AURA_PERIODIC_DAMAGE_PERCENT, SPELL_AURA_PERIODIC_LEECH, SPELL_AURA_PERIODIC_TRIGGER_SPELL, SPELL_AURA_PERIODIC_TRIGGER_SPELL_WITH_VALUE, SPELL_AURA_PROC_TRIGGER_SPELL, SPELL_EFFECT_APPLY_AREA_AURA_ENEMY, SPELL_EFFECT_APPLY_AREA_AURA_FRIEND, SPELL_EFFECT_APPLY_AURA, SPELL_EFFECT_ENERGIZE_PCT, SPELL_EFFECT_HEAL, SPELL_EFFECT_HEAL_PCT, SPELL_EFFECT_LEARN_SPELL, SPELL_EFFECT_SKILL_STEP, SPELLFAMILY_GENERIC, SPELLFAMILY_MAGE, SpellEntry::SpellFamilyFlags, SpellEntry::SpellFamilyName, SPELLMOD_COST, sSpellStore, and TARGET_UNIT_CASTER.

Referenced by Pet::_LoadAuras(), Player::_LoadAuras(), Aura::Aura(), Spell::CheckCast(), IsNonCombatSpell(), IsPositiveEffect(), IsPositiveSpell(), SpellMgr::SelectAuraRankForPlayerLevel(), and Spell::SetTargetMap().

562 {
563  SpellEntry const* spellproto = sSpellStore.LookupEntry(spellId);
564  if (!spellproto)
565  return false;
566 
567  // not found a single positive spell with this attribute
568  if (spellproto->Attributes & SPELL_ATTR0_NEGATIVE_1)
569  return false;
570 
571  switch (spellproto->SpellFamilyName)
572  {
573  case SPELLFAMILY_GENERIC:
574  switch (spellproto->Id)
575  {
576  case 6716: // Test of Faith
577  case 23333: // Warsong Flag
578  case 23335: // Silverwing Flag
579  case 34976: // Netherstorm Flag
580  return true;
581  case 1852: // Silenced (GM)
582  case 46392: // Focused Assault
583  case 46393: // Brutal Assault
584  case 43437: // Paralyzed
585  case 28441: // AB Effect 000
586  case 37675: // Chaos Blast
587  case 41519: // Mark of Stormrage
588  case 34877: // Custodian of Time
589  case 34700: // Allergic Reaction
590  case 31719: // Suspension
591  case 43501: // Siphon Soul (Hexlord Spell)
592  case 30457: // Complete vulnerability
593  case 30529: // Recently In Game - Chess Event
594  case 37465: // Rain of Fire
595  case 45661: // Encapsulate (Felmyst - Sunwell Plateau)
596  case 45662:
597  case 45665:
598  return false;
599  default:
600  break;
601  }
602  break;
603  case SPELLFAMILY_MAGE:
604  {
605  // Amplify Magic, Dampen Magic
606  if (spellproto->SpellFamilyFlags == 0x00002000)
607  return true;
608 
609  switch (spellproto->Id)
610  {
611  case 31579: // Arcane Empowerment Rank1 talent aura with one positive and one negative (check not needed in wotlk)
612  case 31582: // Arcane Empowerment Rank2
613  case 31583: // Arcane Empowerment Rank3
614  return true;
615  default:
616  break;
617  }
618  }
619  break;
620  default:
621  break;
622  }
623 
624  switch (spellproto->Mechanic)
625  {
627  return true;
628  default:
629  break;
630  }
631 
632  switch (spellproto->Effect[effIndex])
633  {
634  // always positive effects (check before target checks that provided non-positive result in some case for positive effects)
635  case SPELL_EFFECT_HEAL:
640  return true;
642  return false;
643 
644  // non-positive aura use
647  {
648  switch (spellproto->EffectApplyAuraName[effIndex])
649  {
650  case SPELL_AURA_MOD_DAMAGE_DONE: // dependent from bas point sign (negative -> negative)
651  case SPELL_AURA_MOD_STAT:
657  if (spellproto->EffectBasePoints[effIndex] + int32(spellproto->EffectBaseDice[effIndex]) < 0)
658  return false;
659  break;
660  case SPELL_AURA_MOD_DAMAGE_TAKEN: // dependent from bas point sign (positive -> negative)
661  if (spellproto->EffectBasePoints[effIndex] + int32(spellproto->EffectBaseDice[effIndex]) > 0)
662  return false;
663  break;
665  if (spellproto->EffectBasePoints[effIndex] + int32(spellproto->EffectBaseDice[effIndex]) > 0)
666  return true; // some expected positive spells have SPELL_ATTR1_NEGATIVE
667  break;
669  return true;
672  if (spellId != spellproto->EffectTriggerSpell[effIndex])
673  {
674  uint32 spellTriggeredId = spellproto->EffectTriggerSpell[effIndex];
675  SpellEntry const* spellTriggeredProto = sSpellStore.LookupEntry(spellTriggeredId);
676 
677  if (spellTriggeredProto)
678  {
679  // non-positive targets of main spell return early
680  for (int i = 0; i < MAX_SPELL_EFFECTS; ++i)
681  {
682  // if non-positive trigger cast targeted to positive target this main cast is non-positive
683  // this will place this spell auras as debuffs
684  if (!IsPositiveTarget(spellTriggeredProto->EffectImplicitTargetA[i], spellTriggeredProto->EffectImplicitTargetB[i]) && !IsPositiveEffect(spellTriggeredId, i))
685  return false;
686  }
687  }
688  }
689  break;
691  // many positive auras have negative triggered spells at damage for example and this not make it negative (it can be canceled for example)
692  break;
693  case SPELL_AURA_MOD_STUN: //have positive and negative spells, we can't sort its correctly at this moment.
694  if (effIndex == 0 && spellproto->Effect[1] == 0 && spellproto->Effect[2] == 0)
695  return false; // but all single stun aura spells is negative
696  break;
698  if (spellproto->Id == 24740) // Wisp Costume
699  return true;
700  return false;
701  case SPELL_AURA_MOD_ROOT:
703  case SPELL_AURA_GHOST:
707  return false;
708  case SPELL_AURA_PERIODIC_DAMAGE: // used in positive spells also.
709  // part of negative spell if casted at self (prevent cancel)
710  if (spellproto->EffectImplicitTargetA[effIndex] == TARGET_UNIT_CASTER)
711  return false;
712  break;
713  case SPELL_AURA_MOD_DECREASE_SPEED: // used in positive spells also
714  // part of positive spell if casted at self
715  if (spellproto->EffectImplicitTargetA[effIndex] != TARGET_UNIT_CASTER)
716  return false;
717  // but not this if this first effect (didn't find better check)
718  if (spellproto->Attributes & SPELL_ATTR0_NEGATIVE_1 && effIndex == 0)
719  return false;
720  break;
722  {
723  // non-positive immunities
724  switch (spellproto->EffectMiscValue[effIndex])
725  {
726  case MECHANIC_BANDAGE:
727  case MECHANIC_SHIELD:
728  case MECHANIC_MOUNT:
730  return false;
731  default:
732  break;
733  }
734  break;
735  }
736  case SPELL_AURA_ADD_FLAT_MODIFIER: // mods
738  {
739  // non-positive mods
740  switch (spellproto->EffectMiscValue[effIndex])
741  {
742  case SPELLMOD_COST: // dependent from bas point sign (negative -> positive)
743  if (spellproto->EffectBasePoints[effIndex] + int32(spellproto->EffectBaseDice[effIndex]) > 0)
744  {
745  if (spellproto->Id == 12042) // Arcane Power is a positive spell
746  return true;
747 
748  return false;
749  }
750  break;
751  default:
752  break;
753  }
754  break;
755  }
756  default:
757  break;
758  }
759  break;
760  }
761  default:
762  break;
763  }
764 
765  // non-positive targets
766  if (!IsPositiveTarget(spellproto->EffectImplicitTargetA[effIndex], spellproto->EffectImplicitTargetB[effIndex]))
767  return false;
768 
769  // ok, positive
770  return true;
771 }
uint32 EffectTriggerSpell[MAX_SPELL_EFFECTS]
Definition: DBCStructure.h:741
int32 EffectBaseDice[MAX_SPELL_EFFECTS]
Definition: DBCStructure.h:726
ACE_INT32 int32
Definition: Define.h:67
uint32 Effect[MAX_SPELL_EFFECTS]
Definition: DBCStructure.h:724
int32 EffectBasePoints[MAX_SPELL_EFFECTS]
Definition: DBCStructure.h:729
DBCStorage< SpellEntry > sSpellStore(SpellEntryfmt)
uint32 EffectApplyAuraName[MAX_SPELL_EFFECTS]
Definition: DBCStructure.h:734
uint32 Attributes
Definition: DBCStructure.h:679
bool IsPositiveEffect(uint32 spellId, uint32 effIndex)
Definition: SpellMgr.cpp:561
uint32 EffectImplicitTargetB[MAX_SPELL_EFFECTS]
Definition: DBCStructure.h:732
uint64 SpellFamilyFlags
Definition: DBCStructure.h:761
uint32 EffectImplicitTargetA[MAX_SPELL_EFFECTS]
Definition: DBCStructure.h:731
int32 EffectMiscValue[MAX_SPELL_EFFECTS]
Definition: DBCStructure.h:739
uint32 SpellFamilyName
Definition: DBCStructure.h:760
uint32 Mechanic
Definition: DBCStructure.h:678
#define MAX_SPELL_EFFECTS
Definition: DBCStructure.h:670
bool IsPositiveTarget(uint32 targetA, uint32 targetB)
Definition: SpellMgr.cpp:539
ACE_UINT32 uint32
Definition: Define.h:71
bool IsPositiveSpell ( uint32  spellId)
bool IsPositiveTarget ( uint32  targetA,
uint32  targetB 
)
bool IsSingleTargetSpell ( SpellEntry const *  spellInfo)

Definition at line 783 of file SpellMgr.cpp.

References SpellEntry::AttributesEx5, GetSpellSpecific(), SpellEntry::Id, SPELL_ATTR5_SINGLE_TARGET_SPELL, and SPELL_SPECIFIC_JUDGEMENT.

Referenced by Pet::_LoadAuras(), Player::_LoadAuras(), Pet::_SaveAuras(), Player::_SaveAuras(), Aura::Aura(), IsNonCombatSpell(), and Unit::RemoveNotOwnSingleTargetAuras().

784 {
785  // all other single target spells have if it has AttributesEx5
786  if (spellInfo->AttributesEx5 & SPELL_ATTR5_SINGLE_TARGET_SPELL)
787  return true;
788 
789  // TODO - need found Judgements rule
790  switch (GetSpellSpecific(spellInfo->Id))
791  {
793  return true;
794  default:
795  break;
796  }
797 
798  // single target triggered spell.
799  // Not real client side single target spell, but it' not triggered until prev. aura expired.
800  // This is allow store it in single target spells list for caster for spell proc checking
801  if (spellInfo->Id == 38324) // Regeneration (triggered by 38299 (HoTs on Heals))
802  return true;
803 
804  return false;
805 }
SpellSpecific GetSpellSpecific(uint32 spellId)
Definition: SpellMgr.cpp:396
bool IsSingleTargetSpells ( SpellEntry const *  spellInfo1,
SpellEntry const *  spellInfo2 
)

Definition at line 807 of file SpellMgr.cpp.

References GetSpellSpecific(), SpellEntry::Id, SPELL_SPECIFIC_JUDGEMENT, SPELL_SPECIFIC_MAGE_POLYMORPH, SpellEntry::SpellFamilyName, and SpellEntry::SpellIconID.

Referenced by Unit::AddAura(), and IsNonCombatSpell().

808 {
809  // TODO - need better check
810  // Equal icon and spellfamily
811  if (spellInfo1->SpellFamilyName == spellInfo2->SpellFamilyName &&
812  spellInfo1->SpellIconID == spellInfo2->SpellIconID)
813  return true;
814 
815  // TODO - need found Judgements rule
816  SpellSpecific spec1 = GetSpellSpecific(spellInfo1->Id);
817  // spell with single target specific types
818  switch (spec1)
819  {
822  if (GetSpellSpecific(spellInfo2->Id) == spec1)
823  return true;
824  default:
825  break;
826  }
827 
828  return false;
829 }
SpellSpecific
Definition: SpellMgr.h:95
SpellSpecific GetSpellSpecific(uint32 spellId)
Definition: SpellMgr.cpp:396
SpellCastResult IsSpellAllowedInLocation ( SpellEntry const *  spellInfo,
uint32  map_id,
uint32  zone_id,
uint32  area_id 
)

Definition at line 2903 of file SpellMgr.cpp.

References MapEntry::addon, SpellEntry::AreaId, GetVirtualMapForMapAndZone(), SpellEntry::HasAttribute(), SpellEntry::Id, MapEntry::IsBattleground(), MapEntry::IsContinent(), MapEntry::IsRaid(), MapEntry::MapID, MapEntry::multimap_id, sMapStore, SPELL_ATTR4_CAST_ONLY_IN_OUTLAND, SPELL_ATTR6_NOT_IN_RAID_INSTANCE, SPELL_CAST_OK, SPELL_FAILED_DONT_REPORT, SPELL_FAILED_REQUIRES_AREA, and SPELL_FAILED_TARGET_NOT_IN_RAID.

Referenced by Spell::CheckCast(), IsBinarySpell(), and Player::UpdateAreaDependentAuras().

2904 {
2905  // normal case
2906  if (spellInfo->AreaId && spellInfo->AreaId != zone_id && spellInfo->AreaId != area_id)
2908 
2909  // continent limitation (virtual continent)
2910  if (spellInfo->HasAttribute(SPELL_ATTR4_CAST_ONLY_IN_OUTLAND))
2911  {
2912  uint32 v_map = GetVirtualMapForMapAndZone(map_id, zone_id);
2913  MapEntry const* mapEntry = sMapStore.LookupEntry(v_map);
2914  if (!mapEntry || mapEntry->addon < 1 || !mapEntry->IsContinent())
2916  }
2917 
2918  // raid instance limitation
2919  if (spellInfo->HasAttribute(SPELL_ATTR6_NOT_IN_RAID_INSTANCE))
2920  {
2921  MapEntry const* mapEntry = sMapStore.LookupEntry(map_id);
2922  if (!mapEntry || mapEntry->IsRaid())
2924  }
2925 
2926  // special cases zone check (maps checked by multimap common id)
2927  switch (spellInfo->Id)
2928  {
2929  case 46838: // Shattrath Flask of Pure Death
2930  case 41607: // Shattrath Flask of Fortification
2931  case 41605: // Shattrath Flask of Mighty Restoration
2932  case 41604: // Shattrath Flask of Supreme Power
2933  case 41606: // Shattrath Flask of Relentless Assault
2934  case 46840: // Shattrath Flask of Blinding Light
2935  {
2936  MapEntry const* mapEntry = sMapStore.LookupEntry(map_id);
2937  if (!mapEntry)
2939 
2940  // Tempest Keep // Black Temple // Serpentshrine Cavern // Sunwell // Mount Hyjal
2941  if (mapEntry->multimap_id == 206 || mapEntry->MapID == 564 || mapEntry->MapID == 548 || mapEntry->MapID == 580 || mapEntry->MapID == 534)
2942  return SPELL_CAST_OK;
2943  else
2944  return SPELL_FAILED_DONT_REPORT;
2945  }
2946  case 23333: // Warsong Flag
2947  case 23335: // Silverwing Flag
2948  case 46392: // Focused Assault
2949  case 46393: // Brutal Assault
2950  {
2951  MapEntry const* mapEntry = sMapStore.LookupEntry(map_id);
2952  if (!mapEntry)
2954 
2955  if (!mapEntry->IsBattleground())
2957 
2958  if (zone_id == 3277)
2959  return SPELL_CAST_OK;
2960 
2962  }
2963  case 34976: // Netherstorm Flag
2964  {
2965  MapEntry const* mapEntry = sMapStore.LookupEntry(map_id);
2966  if (!mapEntry)
2968 
2969  if (!mapEntry->IsBattleground())
2971 
2972  if (zone_id == 3820)
2973  return SPELL_CAST_OK;
2974 
2976  }
2977  case 32724: // Gold Team (Alliance)
2978  case 32725: // Green Team (Alliance)
2979  case 32727: // Arena Preparation
2980  case 35774: // Gold Team (Horde)
2981  case 35775: // Green Team (Horde)
2982  {
2983  MapEntry const* mapEntry = sMapStore.LookupEntry(map_id);
2984  if (!mapEntry)
2986 
2987  //the follow code doesn't work.
2988  //if (!mapEntry->IsBattleArena())
2989  // return false;
2990 
2991  //this is the working code, HACK
2992  if (zone_id == 3702 || zone_id == 3968 || zone_id == 3698)
2993  return SPELL_CAST_OK;
2994 
2996  }
2997  case 41618: // Bottled Nethergon Energy
2998  case 41620: // Bottled Nethergon Vapor
2999  {
3000  MapEntry const* mapEntry = sMapStore.LookupEntry(map_id);
3001  if (!mapEntry)
3003 
3004  return mapEntry->multimap_id == 206 ? SPELL_CAST_OK : SPELL_FAILED_REQUIRES_AREA;
3005  }
3006  case 41617: // Cenarion Mana Salve
3007  case 41619: // Cenarion Healing Salve
3008  {
3009  MapEntry const* mapEntry = sMapStore.LookupEntry(map_id);
3010  if (!mapEntry)
3012 
3013  return mapEntry->multimap_id == 207 ? SPELL_CAST_OK : SPELL_FAILED_REQUIRES_AREA;
3014  }
3015  case 40216: // Dragonmaw Illusion
3016  case 42016: // Dragonmaw Illusion
3017  return (area_id == 3759 || area_id == 3966 || area_id == 3939) ? SPELL_CAST_OK : SPELL_FAILED_REQUIRES_AREA;
3018  case 2584: // Waiting to Resurrect
3019  case 22011: // Spirit Heal Channel
3020  case 22012: // Spirit Heal
3021  case 24171: // Resurrection Impact Visual
3022  case 42792: // Recently Dropped Flag
3023  case 43681: // Inactive
3024  case 44535: // Spirit Heal (mana)
3025  case 44521: // Preparation
3026  {
3027  MapEntry const* mapEntry = sMapStore.LookupEntry(map_id);
3028  if (!mapEntry)
3030 
3031  if (!mapEntry->IsBattleground())
3033  }
3034  }
3035 
3036  return SPELL_CAST_OK;
3037 }
uint32 GetVirtualMapForMapAndZone(uint32 mapid, uint32 zoneId)
Definition: DBCStores.cpp:652
uint32 MapID
Definition: DBCStructure.h:514
bool IsContinent() const
Definition: DBCStructure.h:583
uint32 addon
Definition: DBCStructure.h:542
DBCStorage< MapEntry > sMapStore(MapEntryfmt)
uint32 multimap_id
Definition: DBCStructure.h:528
bool IsBattleground() const
Definition: DBCStructure.h:562
bool IsRaid() const
Definition: DBCStructure.h:558
ACE_UINT32 uint32
Definition: Define.h:71

Variable Documentation