TrinityCore
Loading...
Searching...
No Matches
SpellInfo Class Reference

#include <SpellInfo.h>

Classes

struct  ScalingInfo
 

Public Member Functions

 SpellInfo (SpellNameEntry const *spellName, ::Difficulty difficulty, SpellInfoLoadHelper const &data)
 
 SpellInfo (SpellNameEntry const *spellName, ::Difficulty difficulty, std::vector< SpellEffectEntry > const &effects)
 
 SpellInfo (SpellInfo const &)=delete
 
 SpellInfo (SpellInfo &&)=delete
 
 ~SpellInfo ()
 
SpellInfooperator= (SpellInfo const &)=delete
 
SpellInfooperator= (SpellInfo &&) noexcept=delete
 
uint32 GetCategory () const
 
bool HasEffect (SpellEffectName effect) const
 
bool HasAura (AuraType aura) const
 
bool HasAreaAuraEffect () const
 
bool HasOnlyDamageEffects () const
 
bool HasTargetType (::Targets target) const
 
bool HasAttribute (SpellAttr0 attribute) const
 
bool HasAttribute (SpellAttr1 attribute) const
 
bool HasAttribute (SpellAttr2 attribute) const
 
bool HasAttribute (SpellAttr3 attribute) const
 
bool HasAttribute (SpellAttr4 attribute) const
 
bool HasAttribute (SpellAttr5 attribute) const
 
bool HasAttribute (SpellAttr6 attribute) const
 
bool HasAttribute (SpellAttr7 attribute) const
 
bool HasAttribute (SpellAttr8 attribute) const
 
bool HasAttribute (SpellAttr9 attribute) const
 
bool HasAttribute (SpellAttr10 attribute) const
 
bool HasAttribute (SpellAttr11 attribute) const
 
bool HasAttribute (SpellAttr12 attribute) const
 
bool HasAttribute (SpellAttr13 attribute) const
 
bool HasAttribute (SpellAttr14 attribute) const
 
bool HasAttribute (SpellCustomAttributes customAttribute) const
 
bool CanBeInterrupted (WorldObject const *interruptCaster, Unit const *interruptTarget, bool ignoreImmunity=false) const
 
bool HasAnyAuraInterruptFlag () const
 
bool HasAuraInterruptFlag (SpellAuraInterruptFlags flag) const
 
bool HasAuraInterruptFlag (SpellAuraInterruptFlags2 flag) const
 
bool HasChannelInterruptFlag (SpellAuraInterruptFlags flag) const
 
bool HasChannelInterruptFlag (SpellAuraInterruptFlags2 flag) const
 
bool IsExplicitDiscovery () const
 
bool IsLootCrafting () const
 
bool IsProfession () const
 
bool IsPrimaryProfession () const
 
bool IsPrimaryProfessionFirstRank () const
 
bool IsAbilityOfSkillType (uint32 skillType) const
 
bool IsAffectingArea () const
 
bool IsTargetingArea () const
 
bool NeedsExplicitUnitTarget () const
 
bool NeedsToBeTriggeredByCaster (SpellInfo const *triggeringSpell) const
 
bool IsPassive () const
 
bool IsAutocastable () const
 
bool IsStackableWithRanks () const
 
bool IsPassiveStackableWithRanks () const
 
bool IsMultiSlotAura () const
 
bool IsStackableOnOneSlotWithDifferentCasters () const
 
bool IsCooldownStartedOnEvent () const
 
bool IsDeathPersistent () const
 
bool IsRequiringDeadTarget () const
 
bool IsAllowingDeadTarget () const
 
bool IsGroupBuff () const
 
bool CanBeUsedInCombat (Unit const *caster) const
 
bool IsPositive () const
 
bool IsPositiveEffect (uint8 effIndex) const
 
bool IsChanneled () const
 
bool IsMoveAllowedChannel () const
 
bool IsNextMeleeSwingSpell () const
 
bool IsRangedWeaponSpell () const
 
bool IsAutoRepeatRangedSpell () const
 
bool HasInitialAggro () const
 
bool HasHitDelay () const
 
WeaponAttackType GetAttackType () const
 
bool IsItemFitToSpellRequirements (Item const *item) const
 
bool IsAffected (uint32 familyName, flag128 const &familyFlags) const
 
bool IsAffectedBySpellMods () const
 
bool IsAffectedBySpellMod (SpellModifier const *mod) const
 
bool CanPierceImmuneAura (SpellInfo const *auraSpellInfo) const
 
bool CanDispelAura (SpellInfo const *auraSpellInfo) const
 
bool IsSingleTarget () const
 
bool IsAuraExclusiveBySpecificWith (SpellInfo const *spellInfo) const
 
bool IsAuraExclusiveBySpecificPerCasterWith (SpellInfo const *spellInfo) const
 
SpellCastResult CheckShapeshift (uint32 form) const
 
SpellCastResult CheckLocation (uint32 map_id, uint32 zone_id, uint32 area_id, Player const *player=nullptr) const
 
SpellCastResult CheckTarget (WorldObject const *caster, WorldObject const *target, bool implicit=true) const
 
SpellCastResult CheckExplicitTarget (WorldObject const *caster, WorldObject const *target, Item const *itemTarget=nullptr) const
 
SpellCastResult CheckVehicle (Unit const *caster) const
 
bool CheckTargetCreatureType (Unit const *target) const
 
SpellSchoolMask GetSchoolMask () const
 
uint64 GetAllEffectsMechanicMask () const
 
uint64 GetEffectMechanicMask (SpellEffIndex effIndex) const
 
uint64 GetSpellMechanicMaskByEffectMask (uint32 effectMask) const
 
Mechanics GetEffectMechanic (SpellEffIndex effIndex) const
 
uint32 GetDispelMask () const
 
uint32 GetExplicitTargetMask () const
 
AuraStateType GetAuraState () const
 
SpellSpecificType GetSpellSpecific () const
 
float GetMinRange (bool positive=false) const
 
float GetMaxRange (bool positive=false, WorldObject *caster=nullptr, Spell *spell=nullptr) const
 
int32 CalcDuration (WorldObject const *caster=nullptr) const
 
int32 GetDuration () const
 
int32 GetMaxDuration () const
 
uint32 GetMaxTicks () const
 
uint32 CalcCastTime (Spell *spell=nullptr) const
 
uint32 GetRecoveryTime () const
 
Optional< SpellPowerCostCalcPowerCost (Powers powerType, bool optionalCost, WorldObject const *caster, SpellSchoolMask schoolMask, Spell *spell=nullptr) const
 
Optional< SpellPowerCostCalcPowerCost (SpellPowerEntry const *power, bool optionalCost, WorldObject const *caster, SpellSchoolMask schoolMask, Spell *spell=nullptr) const
 
std::vector< SpellPowerCostCalcPowerCost (WorldObject const *caster, SpellSchoolMask schoolMask, Spell *spell=nullptr) const
 
float CalcProcPPM (Unit *caster, int32 itemLevel) const
 
bool IsRanked () const
 
uint8 GetRank () const
 
SpellInfo const * GetFirstRankSpell () const
 
SpellInfo const * GetLastRankSpell () const
 
SpellInfo const * GetNextRankSpell () const
 
SpellInfo const * GetPrevRankSpell () const
 
SpellInfo const * GetAuraRankForLevel (uint8 level) const
 
bool IsRankOf (SpellInfo const *spellInfo) const
 
bool IsDifferentRankOf (SpellInfo const *spellInfo) const
 
bool IsHighRankOf (SpellInfo const *spellInfo) const
 
uint32 GetSpellXSpellVisualId (WorldObject const *caster=nullptr, WorldObject const *viewer=nullptr) const
 
uint32 GetSpellVisual (WorldObject const *caster=nullptr, WorldObject const *viewer=nullptr) const
 
std::vector< SpellEffectInfo > const & GetEffects () const
 
SpellEffectInfo const & GetEffect (SpellEffIndex index) const
 
DiminishingGroup GetDiminishingReturnsGroupForSpell () const
 
DiminishingReturnsType GetDiminishingReturnsGroupType () const
 
DiminishingLevels GetDiminishingReturnsMaxLevel () const
 
int32 GetDiminishingReturnsLimitDuration () const
 
void ApplyAllSpellImmunitiesTo (Unit *target, SpellEffectInfo const &spellEffectInfo, bool apply) const
 
bool CanSpellProvideImmunityAgainstAura (SpellInfo const *auraSpellInfo) const
 
bool SpellCancelsAuraEffect (AuraEffect const *aurEff) const
 
uint64 GetAllowedMechanicMask () const
 
uint64 GetMechanicImmunityMask (Unit const *caster) const
 
bool MeetsFutureSpellPlayerCondition (Player const *player) const
 
bool HasLabel (uint32 labelId) const
 

Static Public Member Functions

static uint32 GetDispelMask (DispelType type)
 

Public Attributes

uint32 const Id = 0
 
::Difficulty const Difficulty = DIFFICULTY_NONE
 
uint32 CategoryId = 0
 
uint32 Dispel = 0
 
uint32 Mechanic = 0
 
uint32 Attributes = 0
 
uint32 AttributesEx = 0
 
uint32 AttributesEx2 = 0
 
uint32 AttributesEx3 = 0
 
uint32 AttributesEx4 = 0
 
uint32 AttributesEx5 = 0
 
uint32 AttributesEx6 = 0
 
uint32 AttributesEx7 = 0
 
uint32 AttributesEx8 = 0
 
uint32 AttributesEx9 = 0
 
uint32 AttributesEx10 = 0
 
uint32 AttributesEx11 = 0
 
uint32 AttributesEx12 = 0
 
uint32 AttributesEx13 = 0
 
uint32 AttributesEx14 = 0
 
uint32 AttributesCu = 0
 
std::bitset< MAX_SPELL_EFFECTSNegativeEffects
 
uint64 Stances = 0
 
uint64 StancesNot = 0
 
uint32 Targets = 0
 
uint32 TargetCreatureType = 0
 
uint32 RequiresSpellFocus = 0
 
uint32 FacingCasterFlags = 0
 
uint32 CasterAuraState = 0
 
uint32 TargetAuraState = 0
 
uint32 ExcludeCasterAuraState = 0
 
uint32 ExcludeTargetAuraState = 0
 
uint32 CasterAuraSpell = 0
 
uint32 TargetAuraSpell = 0
 
uint32 ExcludeCasterAuraSpell = 0
 
uint32 ExcludeTargetAuraSpell = 0
 
AuraType CasterAuraType = SPELL_AURA_NONE
 
AuraType TargetAuraType = SPELL_AURA_NONE
 
AuraType ExcludeCasterAuraType = SPELL_AURA_NONE
 
AuraType ExcludeTargetAuraType = SPELL_AURA_NONE
 
SpellCastTimesEntry const * CastTimeEntry = nullptr
 
uint32 RecoveryTime = 0
 
uint32 CategoryRecoveryTime = 0
 
uint32 StartRecoveryCategory = 0
 
uint32 StartRecoveryTime = 0
 
uint32 CooldownAuraSpellId = 0
 
EnumFlag< SpellInterruptFlagsInterruptFlags = SpellInterruptFlags::None
 
EnumFlag< SpellAuraInterruptFlagsAuraInterruptFlags = SpellAuraInterruptFlags::None
 
EnumFlag< SpellAuraInterruptFlags2AuraInterruptFlags2 = SpellAuraInterruptFlags2::None
 
EnumFlag< SpellAuraInterruptFlagsChannelInterruptFlags = SpellAuraInterruptFlags::None
 
EnumFlag< SpellAuraInterruptFlags2ChannelInterruptFlags2 = SpellAuraInterruptFlags2::None
 
ProcFlagsInit ProcFlags
 
uint32 ProcChance = 0
 
uint32 ProcCharges = 0
 
uint32 ProcCooldown = 0
 
float ProcBasePPM = 0.0f
 
std::vector< SpellProcsPerMinuteModEntry const * > ProcPPMMods
 
uint32 MaxLevel = 0
 
uint32 BaseLevel = 0
 
uint32 SpellLevel = 0
 
SpellDurationEntry const * DurationEntry = nullptr
 
std::array< SpellPowerEntry const *, MAX_POWERS_PER_SPELLPowerCosts = {}
 
SpellRangeEntry const * RangeEntry = nullptr
 
float Speed = 0.0f
 
float LaunchDelay = 0.0f
 
uint32 StackAmount = 0
 
std::array< int32, MAX_SPELL_TOTEMSTotem = {}
 
std::array< uint16, MAX_SPELL_TOTEMSTotemCategory = {}
 
std::array< int32, MAX_SPELL_REAGENTSReagent = {}
 
std::array< int16, MAX_SPELL_REAGENTSReagentCount = {}
 
std::vector< SpellReagentsCurrencyEntry const * > ReagentsCurrency
 
int32 EquippedItemClass = -1
 
int32 EquippedItemSubClassMask = 0
 
int32 EquippedItemInventoryTypeMask = 0
 
uint32 IconFileDataId = 0
 
uint32 ActiveIconFileDataId = 0
 
uint32 ContentTuningId = 0
 
uint32 ShowFutureSpellPlayerConditionID = 0
 
LocalizedString const * SpellName = nullptr
 
float ConeAngle = 0.0f
 
float Width = 0.0f
 
uint32 MaxTargetLevel = 0
 
uint32 MaxAffectedTargets = 0
 
uint32 SpellFamilyName = 0
 
flag128 SpellFamilyFlags
 
uint32 DmgClass = 0
 
uint32 PreventionType = 0
 
int32 RequiredAreasID = -1
 
uint32 SchoolMask = 0
 
uint32 ChargeCategoryId = 0
 
std::unordered_set< uint32Labels
 
struct SpellInfo::ScalingInfo Scaling
 
uint32 ExplicitTargetMask = 0
 
SpellChainNode const * ChainEntry = nullptr
 
struct {
   int32   MaxTargets = 0
 
   int32   NumNonDiminishedTargets = 0
 
SqrtDamageAndHealingDiminishing
 

Private Member Functions

void _InitializeExplicitTargetMask ()
 
void _InitializeSpellPositivity ()
 
void _LoadSpellSpecific ()
 
void _LoadAuraState ()
 
void _LoadSpellDiminishInfo ()
 
void _LoadImmunityInfo ()
 
void _LoadSqrtTargetLimit (int32 maxTargets, int32 numNonDiminishedTargets, Optional< SpellEffIndex > maxTargetsEffectValueHolder, Optional< SpellEffIndex > numNonDiminishedTargetsEffectValueHolder)
 
void _UnloadImplicitTargetConditionLists ()
 

Private Attributes

std::vector< SpellEffectInfo_effects
 
SpellVisualVector _visuals
 
SpellSpecificType _spellSpecific = SPELL_SPECIFIC_NORMAL
 
AuraStateType _auraState = AURA_STATE_NONE
 
SpellDiminishInfo _diminishInfo
 
uint64 _allowedMechanicMask = 0
 

Friends

class SpellMgr
 

Detailed Description

Definition at line 320 of file SpellInfo.h.

Constructor & Destructor Documentation

◆ SpellInfo() [1/4]

SpellInfo::SpellInfo ( SpellNameEntry const *  spellName,
::Difficulty  difficulty,
SpellInfoLoadHelper const &  data 
)
explicit

Definition at line 1154 of file SpellInfo.cpp.

1155 : Id(spellName->ID), Difficulty(difficulty)
1156{
1157 _effects.reserve(32);
1158 for (SpellEffectEntry const* spellEffect : data.Effects)
1159 {
1160 if (!spellEffect)
1161 continue;
1162
1164 }
1165
1166 // Correct EffectIndex for blank effects
1167 for (size_t i = 0; i < _effects.size(); ++i)
1168 {
1169 _effects[i]._spellInfo = this;
1170 _effects[i].EffectIndex = SpellEffIndex(i);
1171 }
1172
1173 _effects.shrink_to_fit();
1174
1175 SpellName = &spellName->Name;
1176
1177 // SpellMiscEntry
1178 if (SpellMiscEntry const* _misc = data.Misc)
1179 {
1180 Attributes = _misc->Attributes[0];
1181 AttributesEx = _misc->Attributes[1];
1182 AttributesEx2 = _misc->Attributes[2];
1183 AttributesEx3 = _misc->Attributes[3];
1184 AttributesEx4 = _misc->Attributes[4];
1185 AttributesEx5 = _misc->Attributes[5];
1186 AttributesEx6 = _misc->Attributes[6];
1187 AttributesEx7 = _misc->Attributes[7];
1188 AttributesEx8 = _misc->Attributes[8];
1189 AttributesEx9 = _misc->Attributes[9];
1190 AttributesEx10 = _misc->Attributes[10];
1191 AttributesEx11 = _misc->Attributes[11];
1192 AttributesEx12 = _misc->Attributes[12];
1193 AttributesEx13 = _misc->Attributes[13];
1194 AttributesEx14 = _misc->Attributes[14];
1195 CastTimeEntry = sSpellCastTimesStore.LookupEntry(_misc->CastingTimeIndex);
1196 DurationEntry = sSpellDurationStore.LookupEntry(_misc->DurationIndex);
1197 RangeEntry = sSpellRangeStore.LookupEntry(_misc->RangeIndex);
1198 Speed = _misc->Speed;
1199 LaunchDelay = _misc->LaunchDelay;
1200 SchoolMask = _misc->SchoolMask;
1201 IconFileDataId = _misc->SpellIconFileDataID;
1202 ActiveIconFileDataId = _misc->ActiveIconFileDataID;
1203 ContentTuningId = _misc->ContentTuningID;
1204 ShowFutureSpellPlayerConditionID = _misc->ShowFutureSpellPlayerConditionID;
1205 }
1206
1207 // SpellScalingEntry
1208 if (SpellScalingEntry const* _scaling = data.Scaling)
1209 {
1210 Scaling.MinScalingLevel = _scaling->MinScalingLevel;
1211 Scaling.MaxScalingLevel = _scaling->MaxScalingLevel;
1212 Scaling.ScalesFromItemLevel = _scaling->ScalesFromItemLevel;
1213 }
1214
1215 // SpellAuraOptionsEntry
1216 if (SpellAuraOptionsEntry const* _options = data.AuraOptions)
1217 {
1218 ProcFlags = _options->ProcTypeMask;
1219 ProcChance = _options->ProcChance;
1220 ProcCharges = _options->ProcCharges;
1221 ProcCooldown = _options->ProcCategoryRecovery;
1222 StackAmount = _options->CumulativeAura;
1223 if (SpellProcsPerMinuteEntry const* _ppm = sSpellProcsPerMinuteStore.LookupEntry(_options->SpellProcsPerMinuteID))
1224 {
1225 ProcBasePPM = _ppm->BaseProcRate;
1226 ProcPPMMods = sDB2Manager.GetSpellProcsPerMinuteMods(_ppm->ID);
1227 }
1228 }
1229
1230 // SpellAuraRestrictionsEntry
1231 if (SpellAuraRestrictionsEntry const* _aura = data.AuraRestrictions)
1232 {
1233 CasterAuraState = _aura->CasterAuraState;
1234 TargetAuraState = _aura->TargetAuraState;
1235 ExcludeCasterAuraState = _aura->ExcludeCasterAuraState;
1236 ExcludeTargetAuraState = _aura->ExcludeTargetAuraState;
1237 CasterAuraSpell = _aura->CasterAuraSpell;
1238 TargetAuraSpell = _aura->TargetAuraSpell;
1239 ExcludeCasterAuraSpell = _aura->ExcludeCasterAuraSpell;
1240 ExcludeTargetAuraSpell = _aura->ExcludeTargetAuraSpell;
1241 CasterAuraType = AuraType(_aura->CasterAuraType);
1242 TargetAuraType = AuraType(_aura->TargetAuraType);
1243 ExcludeCasterAuraType = AuraType(_aura->ExcludeCasterAuraType);
1244 ExcludeTargetAuraType = AuraType(_aura->ExcludeTargetAuraType);
1245 }
1246
1247 // SpellCastingRequirementsEntry
1248 if (SpellCastingRequirementsEntry const* _castreq = data.CastingRequirements)
1249 {
1250 RequiresSpellFocus = _castreq->RequiresSpellFocus;
1251 FacingCasterFlags = _castreq->FacingCasterFlags;
1252 RequiredAreasID = _castreq->RequiredAreasID;
1253 }
1254
1255 // SpellCategoriesEntry
1256 if (SpellCategoriesEntry const* _categories = data.Categories)
1257 {
1258 CategoryId = _categories->Category;
1259 Dispel = _categories->DispelType;
1260 Mechanic = _categories->Mechanic;
1261 StartRecoveryCategory = _categories->StartRecoveryCategory;
1262 DmgClass = _categories->DefenseType;
1263 PreventionType = _categories->PreventionType;
1264 ChargeCategoryId = _categories->ChargeCategory;
1265 }
1266
1267 // SpellClassOptionsEntry
1268 if (SpellClassOptionsEntry const* _class = data.ClassOptions)
1269 {
1270 SpellFamilyName = _class->SpellClassSet;
1271 SpellFamilyFlags = _class->SpellClassMask;
1272 }
1273
1274 // SpellCooldownsEntry
1275 if (SpellCooldownsEntry const* _cooldowns = data.Cooldowns)
1276 {
1277 RecoveryTime = _cooldowns->RecoveryTime;
1278 CategoryRecoveryTime = _cooldowns->CategoryRecoveryTime;
1279 StartRecoveryTime = _cooldowns->StartRecoveryTime;
1280 CooldownAuraSpellId = _cooldowns->AuraSpellID;
1281 }
1282
1283 // SpellEquippedItemsEntry
1284 if (SpellEquippedItemsEntry const* _equipped = data.EquippedItems)
1285 {
1286 EquippedItemClass = _equipped->EquippedItemClass;
1287 EquippedItemSubClassMask = _equipped->EquippedItemSubclass;
1288 EquippedItemInventoryTypeMask = _equipped->EquippedItemInvTypes;
1289 }
1290
1291 // SpellInterruptsEntry
1292 if (SpellInterruptsEntry const* _interrupt = data.Interrupts)
1293 {
1294 InterruptFlags = SpellInterruptFlags(_interrupt->InterruptFlags);
1295 AuraInterruptFlags = SpellAuraInterruptFlags(_interrupt->AuraInterruptFlags[0]);
1296 AuraInterruptFlags2 = SpellAuraInterruptFlags2(_interrupt->AuraInterruptFlags[1]);
1297 ChannelInterruptFlags = SpellAuraInterruptFlags(_interrupt->ChannelInterruptFlags[0]);
1298 ChannelInterruptFlags2 = SpellAuraInterruptFlags2(_interrupt->ChannelInterruptFlags[1]);
1299 }
1300
1301 for (SpellLabelEntry const* label : data.Labels)
1302 Labels.insert(label->LabelID);
1303
1304 // SpellLevelsEntry
1305 if (SpellLevelsEntry const* _levels = data.Levels)
1306 {
1307 MaxLevel = _levels->MaxLevel;
1308 BaseLevel = _levels->BaseLevel;
1309 SpellLevel = _levels->SpellLevel;
1310 }
1311
1312 // SpellPowerEntry
1313 PowerCosts = data.Powers;
1314
1315 // SpellReagentsEntry
1316 if (SpellReagentsEntry const* _reagents = data.Reagents)
1317 {
1318 Reagent = _reagents->Reagent;
1319 ReagentCount = _reagents->ReagentCount;
1320 }
1321
1322 ReagentsCurrency = data.ReagentsCurrency;
1323
1324 // SpellShapeshiftEntry
1325 if (SpellShapeshiftEntry const* _shapeshift = data.Shapeshift)
1326 {
1327 Stances = MAKE_PAIR64(_shapeshift->ShapeshiftMask[0], _shapeshift->ShapeshiftMask[1]);
1328 StancesNot = MAKE_PAIR64(_shapeshift->ShapeshiftExclude[0], _shapeshift->ShapeshiftExclude[1]);
1329 }
1330
1331 // SpellTargetRestrictionsEntry
1332 if (SpellTargetRestrictionsEntry const* _target = data.TargetRestrictions)
1333 {
1334 ConeAngle = _target->ConeDegrees;
1335 Width = _target->Width;
1336 Targets = _target->Targets;
1337 TargetCreatureType = _target->TargetCreatureType;
1338 MaxAffectedTargets = _target->MaxTargets;
1339 MaxTargetLevel = _target->MaxTargetLevel;
1340 }
1341
1342 // SpellTotemsEntry
1343 if (SpellTotemsEntry const* _totem = data.Totems)
1344 {
1345 TotemCategory = _totem->RequiredTotemCategoryID;
1346 Totem = _totem->Totem;
1347 }
1348
1349 _visuals = data.Visuals;
1350}
DB2Storage< SpellRangeEntry > sSpellRangeStore("SpellRange.db2", &SpellRangeLoadInfo::Instance)
DB2Storage< SpellDurationEntry > sSpellDurationStore("SpellDuration.db2", &SpellDurationLoadInfo::Instance)
DB2Storage< SpellProcsPerMinuteEntry > sSpellProcsPerMinuteStore("SpellProcsPerMinute.db2", &SpellProcsPerMinuteLoadInfo::Instance)
DB2Storage< SpellCastTimesEntry > sSpellCastTimesStore("SpellCastTimes.db2", &SpellCastTimesLoadInfo::Instance)
#define sDB2Manager
Definition: DB2Stores.h:533
uint64 MAKE_PAIR64(uint32 l, uint32 h)
Definition: ObjectDefines.h:87
SpellEffIndex
Definition: SharedDefines.h:29
Targets
TotemCategory
AuraType
SpellInterruptFlags
Definition: SpellDefines.h:58
SpellAuraInterruptFlags2
Definition: SpellDefines.h:117
SpellAuraInterruptFlags
Definition: SpellDefines.h:76
ProcFlags
Definition: SpellMgr.h:132
std::array< SpellPowerEntry const *, MAX_POWERS_PER_SPELL > PowerCosts
Definition: SpellInfo.h:386
uint32 RequiresSpellFocus
Definition: SpellInfo.h:351
uint32 BaseLevel
Definition: SpellInfo.h:383
uint32 MaxLevel
Definition: SpellInfo.h:382
uint32 SpellLevel
Definition: SpellInfo.h:384
uint32 AttributesEx13
Definition: SpellInfo.h:343
uint32 ActiveIconFileDataId
Definition: SpellInfo.h:400
uint32 TargetAuraState
Definition: SpellInfo.h:354
std::array< int32, MAX_SPELL_REAGENTS > Reagent
Definition: SpellInfo.h:393
uint32 ExcludeTargetAuraSpell
Definition: SpellInfo.h:360
uint32 PreventionType
Definition: SpellInfo.h:411
uint32 CasterAuraSpell
Definition: SpellInfo.h:357
float Width
Definition: SpellInfo.h:405
uint32 MaxTargetLevel
Definition: SpellInfo.h:406
std::unordered_set< uint32 > Labels
Definition: SpellInfo.h:415
uint32 const Id
Definition: SpellInfo.h:325
uint32 RecoveryTime
Definition: SpellInfo.h:366
EnumFlag< SpellAuraInterruptFlags2 > AuraInterruptFlags2
Definition: SpellInfo.h:373
uint32 AttributesEx8
Definition: SpellInfo.h:338
std::array< int16, MAX_SPELL_REAGENTS > ReagentCount
Definition: SpellInfo.h:394
SpellVisualVector _visuals
Definition: SpellInfo.h:616
EnumFlag< SpellAuraInterruptFlags > ChannelInterruptFlags
Definition: SpellInfo.h:374
uint32 StackAmount
Definition: SpellInfo.h:390
::Difficulty const Difficulty
Definition: SpellInfo.h:326
uint32 Mechanic
Definition: SpellInfo.h:329
SpellRangeEntry const * RangeEntry
Definition: SpellInfo.h:387
uint32 ProcCharges
Definition: SpellInfo.h:378
int32 RequiredAreasID
Definition: SpellInfo.h:412
uint32 ShowFutureSpellPlayerConditionID
Definition: SpellInfo.h:402
uint32 AttributesEx14
Definition: SpellInfo.h:344
uint32 Dispel
Definition: SpellInfo.h:328
std::vector< SpellProcsPerMinuteModEntry const * > ProcPPMMods
Definition: SpellInfo.h:381
uint32 ExcludeCasterAuraState
Definition: SpellInfo.h:355
float Speed
Definition: SpellInfo.h:388
uint32 CooldownAuraSpellId
Definition: SpellInfo.h:370
int32 EquippedItemClass
Definition: SpellInfo.h:396
std::vector< SpellEffectInfo > _effects
Definition: SpellInfo.h:615
struct SpellInfo::ScalingInfo Scaling
uint32 SchoolMask
Definition: SpellInfo.h:413
uint32 CasterAuraState
Definition: SpellInfo.h:353
float ProcBasePPM
Definition: SpellInfo.h:380
uint32 CategoryRecoveryTime
Definition: SpellInfo.h:367
uint64 StancesNot
Definition: SpellInfo.h:348
AuraType TargetAuraType
Definition: SpellInfo.h:362
EnumFlag< SpellInterruptFlags > InterruptFlags
Definition: SpellInfo.h:371
flag128 SpellFamilyFlags
Definition: SpellInfo.h:409
uint32 AttributesEx3
Definition: SpellInfo.h:333
float LaunchDelay
Definition: SpellInfo.h:389
std::vector< SpellReagentsCurrencyEntry const * > ReagentsCurrency
Definition: SpellInfo.h:395
SpellDurationEntry const * DurationEntry
Definition: SpellInfo.h:385
uint32 Attributes
Definition: SpellInfo.h:330
uint32 AttributesEx
Definition: SpellInfo.h:331
uint32 ChargeCategoryId
Definition: SpellInfo.h:414
uint32 IconFileDataId
Definition: SpellInfo.h:399
uint32 MaxAffectedTargets
Definition: SpellInfo.h:407
uint32 AttributesEx12
Definition: SpellInfo.h:342
uint32 AttributesEx6
Definition: SpellInfo.h:336
uint32 AttributesEx7
Definition: SpellInfo.h:337
int32 EquippedItemSubClassMask
Definition: SpellInfo.h:397
uint32 AttributesEx9
Definition: SpellInfo.h:339
uint32 FacingCasterFlags
Definition: SpellInfo.h:352
uint32 StartRecoveryTime
Definition: SpellInfo.h:369
uint32 ContentTuningId
Definition: SpellInfo.h:401
uint32 TargetAuraSpell
Definition: SpellInfo.h:358
AuraType ExcludeTargetAuraType
Definition: SpellInfo.h:364
uint32 AttributesEx10
Definition: SpellInfo.h:340
uint32 ProcCooldown
Definition: SpellInfo.h:379
LocalizedString const * SpellName
Definition: SpellInfo.h:403
SpellCastTimesEntry const * CastTimeEntry
Definition: SpellInfo.h:365
int32 EquippedItemInventoryTypeMask
Definition: SpellInfo.h:398
uint32 ExcludeTargetAuraState
Definition: SpellInfo.h:356
EnumFlag< SpellAuraInterruptFlags2 > ChannelInterruptFlags2
Definition: SpellInfo.h:375
AuraType ExcludeCasterAuraType
Definition: SpellInfo.h:363
uint32 TargetCreatureType
Definition: SpellInfo.h:350
uint32 ProcChance
Definition: SpellInfo.h:377
uint32 AttributesEx2
Definition: SpellInfo.h:332
uint32 DmgClass
Definition: SpellInfo.h:410
AuraType CasterAuraType
Definition: SpellInfo.h:361
uint32 AttributesEx5
Definition: SpellInfo.h:335
uint32 AttributesEx4
Definition: SpellInfo.h:334
EnumFlag< SpellAuraInterruptFlags > AuraInterruptFlags
Definition: SpellInfo.h:372
uint32 ExcludeCasterAuraSpell
Definition: SpellInfo.h:359
uint32 StartRecoveryCategory
Definition: SpellInfo.h:368
uint32 AttributesEx11
Definition: SpellInfo.h:341
uint32 CategoryId
Definition: SpellInfo.h:327
float ConeAngle
Definition: SpellInfo.h:404
uint32 SpellFamilyName
Definition: SpellInfo.h:408
Definition: Totem.h:31
Totem(SummonPropertiesEntry const *properties, Unit *owner)
Definition: Totem.cpp:29
decltype(auto) EnsureWritableVectorIndex(std::vector< T > &vec, typename std::vector< T >::size_type i)
Definition: Containers.h:295
+ Here is the call graph for this function:

◆ SpellInfo() [2/4]

SpellInfo::SpellInfo ( SpellNameEntry const *  spellName,
::Difficulty  difficulty,
std::vector< SpellEffectEntry > const &  effects 
)
explicit

Definition at line 1352 of file SpellInfo.cpp.

1353 : Id(spellName->ID), Difficulty(difficulty)
1354{
1355 SpellName = &spellName->Name;
1356
1357 _effects.reserve(32);
1358 for (SpellEffectEntry const& spellEffect : effects)
1359 Trinity::Containers::EnsureWritableVectorIndex(_effects, spellEffect.EffectIndex) = SpellEffectInfo(this, spellEffect);
1360
1361 // Correct EffectIndex for blank effects
1362 for (size_t i = 0; i < _effects.size(); ++i)
1363 {
1364 _effects[i]._spellInfo = this;
1365 _effects[i].EffectIndex = SpellEffIndex(i);
1366 }
1367
1368 _effects.shrink_to_fit();
1369}
+ Here is the call graph for this function:

◆ SpellInfo() [3/4]

SpellInfo::SpellInfo ( SpellInfo const &  )
delete

◆ SpellInfo() [4/4]

SpellInfo::SpellInfo ( SpellInfo &&  )
delete

◆ ~SpellInfo()

SpellInfo::~SpellInfo ( )

Definition at line 1371 of file SpellInfo.cpp.

1372{
1374}
void _UnloadImplicitTargetConditionLists()
Definition: SpellInfo.cpp:5050
+ Here is the call graph for this function:

Member Function Documentation

◆ _InitializeExplicitTargetMask()

void SpellInfo::_InitializeExplicitTargetMask ( )
private

Definition at line 4523 of file SpellInfo.cpp.

4524{
4525 bool srcSet = false;
4526 bool dstSet = false;
4527 uint32 targetMask = Targets;
4528 // prepare target mask using effect target entries
4529 for (SpellEffectInfo const& effect : GetEffects())
4530 {
4531 if (!effect.IsEffect())
4532 continue;
4533
4534 targetMask |= effect.TargetA.GetExplicitTargetMask(srcSet, dstSet);
4535 targetMask |= effect.TargetB.GetExplicitTargetMask(srcSet, dstSet);
4536
4537 // add explicit target flags based on spell effects which have EFFECT_IMPLICIT_TARGET_EXPLICIT and no valid target provided
4538 if (effect.GetImplicitTargetType() != EFFECT_IMPLICIT_TARGET_EXPLICIT)
4539 continue;
4540
4541 // extend explicit target mask only if valid targets for effect could not be provided by target types
4542 uint32 effectTargetMask = effect.GetMissingTargetMask(srcSet, dstSet, targetMask);
4543
4544 // don't add explicit object/dest flags when spell has no max range
4545 if (GetMaxRange(true) == 0.0f && GetMaxRange(false) == 0.0f)
4547
4548 targetMask |= effectTargetMask;
4549 }
4550
4551 ExplicitTargetMask = targetMask;
4552}
uint32_t uint32
Definition: Define.h:143
@ TARGET_FLAG_GAMEOBJECT
Definition: SpellDefines.h:291
@ TARGET_FLAG_DEST_LOCATION
Definition: SpellDefines.h:286
@ TARGET_FLAG_UNIT_MASK
Definition: SpellDefines.h:307
@ TARGET_FLAG_CORPSE_MASK
Definition: SpellDefines.h:310
@ EFFECT_IMPLICIT_TARGET_EXPLICIT
Definition: SpellInfo.h:113
float GetMaxRange(bool positive=false, WorldObject *caster=nullptr, Spell *spell=nullptr) const
Definition: SpellInfo.cpp:3897
uint32 ExplicitTargetMask
Definition: SpellInfo.h:425
std::vector< SpellEffectInfo > const & GetEffects() const
Definition: SpellInfo.h:576
uint32 Targets
Definition: SpellInfo.h:349
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ _InitializeSpellPositivity()

void SpellInfo::_InitializeSpellPositivity ( )
private

Definition at line 5011 of file SpellInfo.cpp.

5012{
5013 std::unordered_set<std::pair<SpellInfo const*, SpellEffIndex /*effIndex*/>> visited;
5014
5015 for (SpellEffectInfo const& effect : GetEffects())
5016 if (!_isPositiveEffectImpl(this, effect, visited))
5017 NegativeEffects[effect.EffectIndex] = true;
5018
5019 // additional checks after effects marked
5020 for (SpellEffectInfo const& effect : GetEffects())
5021 {
5022 if (!effect.IsEffect() || !IsPositiveEffect(effect.EffectIndex))
5023 continue;
5024
5025 switch (effect.ApplyAuraName)
5026 {
5027 // has other non positive effect?
5028 // then it should be marked negative if has same target as negative effect (ex 8510, 8511, 8893, 10267)
5029 case SPELL_AURA_DUMMY:
5036 {
5037 for (size_t j = effect.EffectIndex + 1; j < GetEffects().size(); ++j)
5038 if (!IsPositiveEffect(j)
5039 && effect.TargetA.GetTarget() == GetEffect(SpellEffIndex(j)).TargetA.GetTarget()
5040 && effect.TargetB.GetTarget() == GetEffect(SpellEffIndex(j)).TargetB.GetTarget())
5041 NegativeEffects[effect.EffectIndex] = true;
5042 break;
5043 }
5044 default:
5045 break;
5046 }
5047 }
5048}
@ SPELL_AURA_MOD_ATTACKSPEED
@ SPELL_AURA_MOD_FEAR
@ SPELL_AURA_DUMMY
@ SPELL_AURA_MOD_TAUNT
@ SPELL_AURA_MOD_DECREASE_SPEED
@ SPELL_AURA_TRANSFORM
@ SPELL_AURA_MOD_STUN
bool _isPositiveEffectImpl(SpellInfo const *spellInfo, SpellEffectInfo const &effect, std::unordered_set< std::pair< SpellInfo const *, SpellEffIndex > > &visited)
Definition: SpellInfo.cpp:4563
SpellEffectInfo const & GetEffect(SpellEffIndex index) const
Definition: SpellInfo.h:577
std::bitset< MAX_SPELL_EFFECTS > NegativeEffects
Definition: SpellInfo.h:346
bool IsPositiveEffect(uint8 effIndex) const
Definition: SpellInfo.cpp:1704
constexpr std::size_t size()
Definition: UpdateField.h:786
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ _LoadAuraState()

void SpellInfo::_LoadAuraState ( )
private

Definition at line 2529 of file SpellInfo.cpp.

2530{
2531 _auraState = [this]()->AuraStateType
2532 {
2533 // Faerie Fire (Feral)
2534 if (GetCategory() == 1133)
2536
2537 // Swiftmend state on Regrowth, Rejuvenation, Wild Growth
2538 if (SpellFamilyName == SPELLFAMILY_DRUID && (SpellFamilyFlags[0] & 0x50 || SpellFamilyFlags[1] & 0x4000000))
2540
2541 // Deadly poison aura state
2542 if (SpellFamilyName == SPELLFAMILY_ROGUE && SpellFamilyFlags[0] & 0x10000)
2544
2545 // Enrage aura state
2546 if (Dispel == DISPEL_ENRAGE)
2547 return AURA_STATE_ENRAGED;
2548
2549 // Bleeding aura state
2551 return AURA_STATE_BLEED;
2552
2554 for (SpellEffectInfo const& effect : GetEffects())
2555 if (effect.IsAura(SPELL_AURA_MOD_STUN) || effect.IsAura(SPELL_AURA_MOD_ROOT) || effect.IsAura(SPELL_AURA_MOD_ROOT_2))
2556 return AURA_STATE_FROZEN;
2557
2558 switch (Id)
2559 {
2560 case 1064: // Dazed
2561 return AURA_STATE_DAZED;
2562 case 32216: // Victorious
2563 return AURA_STATE_VICTORIOUS;
2564 case 71465: // Divine Surge
2565 case 50241: // Evasive Charges
2566 case 81262: // Efflorescence
2568 case 6950: // Faerie Fire
2569 case 9806: // Phantom Strike
2570 case 9991: // Touch of Zanzil
2571 case 13424: // Faerie Fire
2572 case 13752: // Faerie Fire
2573 case 16432: // Plague Mist
2574 case 20656: // Faerie Fire
2575 case 25602: // Faerie Fire
2576 case 32129: // Faerie Fire
2577 case 35325: // Glowing Blood
2578 case 35328: // Lambent Blood
2579 case 35329: // Vibrant Blood
2580 case 35331: // Black Blood
2581 case 49163: // Perpetual Instability
2582 case 65863: // Faerie Fire
2583 case 79559: // Luxscale Light
2584 case 82855: // Dazzling
2585 case 102953: // In the Rumpus
2586 case 127907: // Phosphorescence
2587 case 127913: // Phosphorescence
2588 case 129007: // Zijin Sting
2589 case 130159: // Fae Touch
2590 case 142537: // Spotter Smoke
2591 case 168455: // Spotted!
2592 case 176905: // Super Sticky Glitter Bomb
2593 case 189502: // Marked
2594 case 201785: // Intruder Alert!
2595 case 201786: // Intruder Alert!
2596 case 201935: // Spotted!
2597 case 239233: // Smoke Bomb
2598 case 319400: // Glitter Burst
2599 case 321470: // Dimensional Shifter Mishap
2600 case 331134: // Spotted
2602 default:
2603 break;
2604 }
2605
2606 return AURA_STATE_NONE;
2607 }();
2608}
@ SPELL_SCHOOL_MASK_FROST
@ MECHANIC_BLEED
AuraStateType
@ AURA_STATE_NONE
@ AURA_STATE_BLEED
@ AURA_STATE_FROZEN
@ AURA_STATE_VICTORIOUS
@ AURA_STATE_FAERIE_FIRE
@ AURA_STATE_ENRAGED
@ AURA_STATE_DAZED
@ AURA_STATE_DRUID_PERIODIC_HEAL
@ AURA_STATE_RAID_ENCOUNTER
@ AURA_STATE_ROGUE_POISONED
@ SPELLFAMILY_ROGUE
@ SPELLFAMILY_DRUID
@ DISPEL_ENRAGE
@ SPELL_AURA_MOD_ROOT_2
@ SPELL_AURA_MOD_ROOT
uint32 GetCategory() const
Definition: SpellInfo.cpp:1376
uint64 GetAllEffectsMechanicMask() const
Definition: SpellInfo.cpp:2456
AuraStateType _auraState
Definition: SpellInfo.h:618
SpellSchoolMask GetSchoolMask() const
Definition: SpellInfo.cpp:2451
+ Here is the call graph for this function:

◆ _LoadImmunityInfo()

void SpellInfo::_LoadImmunityInfo ( )
private

Definition at line 3294 of file SpellInfo.cpp.

3295{
3296 std::unique_ptr<SpellEffectInfo::ImmunityInfo> workBuffer = std::make_unique<SpellEffectInfo::ImmunityInfo>();
3297
3298 for (SpellEffectInfo& effect : _effects)
3299 {
3300 uint32 schoolImmunityMask = 0;
3301 uint32 applyHarmfulAuraImmunityMask = 0;
3302 uint64 mechanicImmunityMask = 0;
3303 uint32 dispelImmunity = 0;
3304 uint32 damageImmunityMask = 0;
3305
3306 int32 miscVal = effect.MiscValue;
3307 int32 amount = effect.CalcValue();
3308
3309 SpellEffectInfo::ImmunityInfo& immuneInfo = *workBuffer;
3310
3311 switch (effect.ApplyAuraName)
3312 {
3314 {
3315 switch (miscVal)
3316 {
3317 case 96: // Free Friend, Uncontrollable Frenzy, Warlord's Presence
3318 {
3320
3327 break;
3328 }
3329 case 1615: // Incite Rage, Wolf Spirit, Overload, Lightning Tendrils
3330 {
3331 switch (Id)
3332 {
3333 case 43292: // Incite Rage
3334 case 49172: // Wolf Spirit
3336
3343 [[fallthrough]];
3344 case 61869: // Overload
3345 case 63481:
3346 case 61887: // Lightning Tendrils
3347 case 63486:
3348 mechanicImmunityMask |= (1 << MECHANIC_INTERRUPT) | (1 << MECHANIC_SILENCE);
3349
3352 break;
3353 default:
3354 break;
3355 }
3356 break;
3357 }
3358 case 679: // Mind Control, Avenging Fury
3359 {
3360 if (Id == 57742) // Avenging Fury
3361 {
3363
3370 }
3371 break;
3372 }
3373 case 1557: // Startling Roar, Warlord Roar, Break Bonds, Stormshield
3374 {
3375 if (Id == 64187) // Stormshield
3376 {
3377 mechanicImmunityMask |= (1 << MECHANIC_STUN);
3379 }
3380 else
3381 {
3383
3390 }
3391 break;
3392 }
3393 case 1614: // Fixate
3394 case 1694: // Fixated, Lightning Tendrils
3395 {
3398 break;
3399 }
3400 case 1630: // Fervor, Berserk
3401 {
3402 if (Id == 64112) // Berserk
3403 {
3406 }
3407 else
3408 {
3410
3417 }
3418 break;
3419 }
3420 case 477: // Bladestorm
3421 case 1733: // Bladestorm, Killing Spree
3422 {
3423 if (!amount)
3424 {
3426
3429
3436 }
3437 break;
3438 }
3439 case 878: // Whirlwind, Fog of Corruption, Determination
3440 {
3441 if (Id == 66092) // Determination
3442 {
3443 mechanicImmunityMask |= (1 << MECHANIC_SNARE) | (1 << MECHANIC_STUN)
3444 | (1 << MECHANIC_DISORIENTED) | (1 << MECHANIC_FREEZE);
3445
3448 }
3449 break;
3450 }
3451 default:
3452 break;
3453 }
3454
3455 if (immuneInfo.AuraTypeImmune.empty())
3456 {
3457 if (miscVal & (1 << 10))
3459 if (miscVal & (1 << 1))
3461
3462 // These flag can be recognized wrong:
3463 if (miscVal & (1 << 6))
3465 if (miscVal & (1 << 0))
3466 {
3469 }
3470 if (miscVal & (1 << 2))
3472 if (miscVal & (1 << 9))
3474 if (miscVal & (1 << 7))
3476 }
3477 break;
3478 }
3480 {
3481 switch (Id)
3482 {
3483 case 42292: // PvP trinket
3484 case 59752: // Every Man for Himself
3487 break;
3488 case 34471: // The Beast Within
3489 case 19574: // Bestial Wrath
3490 case 46227: // Medallion of Immunity
3491 case 53490: // Bullheaded
3492 case 65547: // PvP Trinket
3493 case 134946: // Supremacy of the Alliance
3494 case 134956: // Supremacy of the Horde
3495 case 195710: // Honorable Medallion
3496 case 208683: // Gladiator's Medallion
3498 break;
3499 case 54508: // Demonic Empowerment
3500 mechanicImmunityMask |= (1 << MECHANIC_SNARE) | (1 << MECHANIC_ROOT) | (1 << MECHANIC_STUN);
3501 break;
3502 default:
3503 if (miscVal < 1)
3504 break;
3505
3506 mechanicImmunityMask |= UI64LIT(1) << miscVal;
3507 break;
3508 }
3509 break;
3510 }
3512 {
3513 immuneInfo.SpellEffectImmune.insert(static_cast<SpellEffectName>(miscVal));
3514 break;
3515 }
3517 {
3518 immuneInfo.AuraTypeImmune.insert(static_cast<AuraType>(miscVal));
3519 break;
3520 }
3522 {
3523 schoolImmunityMask |= uint32(miscVal);
3524 break;
3525 }
3527 {
3528 applyHarmfulAuraImmunityMask |= uint32(miscVal);
3529 break;
3530 }
3532 {
3533 damageImmunityMask |= uint32(miscVal);
3534 break;
3535 }
3537 {
3538 dispelImmunity = uint32(miscVal);
3539 break;
3540 }
3541 default:
3542 break;
3543 }
3544
3545 immuneInfo.SchoolImmuneMask = schoolImmunityMask;
3546 immuneInfo.ApplyHarmfulAuraImmuneMask = applyHarmfulAuraImmunityMask;
3547 immuneInfo.MechanicImmuneMask = mechanicImmunityMask;
3548 immuneInfo.DispelImmune = dispelImmunity;
3549 immuneInfo.DamageSchoolMask = damageImmunityMask;
3550
3551 immuneInfo.AuraTypeImmune.shrink_to_fit();
3552 immuneInfo.SpellEffectImmune.shrink_to_fit();
3553
3554 if (immuneInfo.SchoolImmuneMask
3555 || immuneInfo.ApplyHarmfulAuraImmuneMask
3556 || immuneInfo.MechanicImmuneMask
3557 || immuneInfo.DispelImmune
3558 || immuneInfo.DamageSchoolMask
3559 || !immuneInfo.AuraTypeImmune.empty()
3560 || !immuneInfo.SpellEffectImmune.empty())
3561 {
3562 effect._immunityInfo = std::move(workBuffer);
3563 workBuffer = std::make_unique<SpellEffectInfo::ImmunityInfo>();
3564 }
3565
3567 }
3568
3570 {
3571 switch (Id)
3572 {
3573 case 22812: // Barkskin
3574 case 47585: // Dispersion
3576 (1 << MECHANIC_STUN) |
3577 (1 << MECHANIC_FREEZE) |
3578 (1 << MECHANIC_KNOCKOUT) |
3579 (1 << MECHANIC_SLEEP);
3580 break;
3581 case 49039: // Lichborne, don't allow normal stuns
3582 break;
3583 default:
3585 break;
3586 }
3587 }
3588
3591
3593 {
3594 switch (Id)
3595 {
3596 case 22812: // Barkskin
3597 case 47585: // Dispersion
3599 break;
3600 default:
3602 break;
3603 }
3604 }
3605}
int32_t int32
Definition: Define.h:139
uint64_t uint64
Definition: Define.h:142
#define UI64LIT(N)
Definition: Define.h:128
@ SPELL_ATTR5_ALLOW_WHILE_STUNNED
@ SPELL_ATTR5_ALLOW_WHILE_FLEEING
@ SPELL_ATTR5_ALLOW_WHILE_CONFUSED
SpellEffectName
@ SPELL_EFFECT_ATTACK_ME
@ SPELL_EFFECT_KNOCK_BACK_DEST
@ SPELL_EFFECT_KNOCK_BACK
@ MECHANIC_FEAR
@ MECHANIC_DISORIENTED
@ MECHANIC_KNOCKOUT
@ MECHANIC_STUN
@ MECHANIC_FREEZE
@ MECHANIC_INTERRUPT
@ MECHANIC_ROOT
@ MECHANIC_SLEEP
@ MECHANIC_SNARE
@ MECHANIC_SILENCE
@ MECHANIC_HORROR
#define IMMUNE_TO_MOVEMENT_IMPAIRMENT_AND_LOSS_CONTROL_MASK
@ SPELL_AURA_DISPEL_IMMUNITY
@ SPELL_AURA_MOD_DISARM
@ SPELL_AURA_SCHOOL_IMMUNITY
@ SPELL_AURA_MECHANIC_IMMUNITY
@ SPELL_AURA_EFFECT_IMMUNITY
@ SPELL_AURA_MOD_IMMUNE_AURA_APPLY_SCHOOL
@ SPELL_AURA_DAMAGE_IMMUNITY
@ SPELL_AURA_MOD_CONFUSE
@ SPELL_AURA_STATE_IMMUNITY
@ SPELL_AURA_USE_NORMAL_MOVEMENT_SPEED
@ SPELL_AURA_MECHANIC_IMMUNITY_MASK
bool HasAttribute(SpellAttr0 attribute) const
Definition: SpellInfo.h:449
uint64 _allowedMechanicMask
Definition: SpellInfo.h:621
std::pair< iterator, bool > insert(Key const &key)
Definition: FlatSet.h:73
Trinity::Containers::FlatSet< AuraType > AuraTypeImmune
Definition: SpellInfo.cpp:237
Trinity::Containers::FlatSet< SpellEffectName > SpellEffectImmune
Definition: SpellInfo.cpp:238
+ Here is the call graph for this function:

◆ _LoadSpellDiminishInfo()

void SpellInfo::_LoadSpellDiminishInfo ( )
private

Definition at line 2803 of file SpellInfo.cpp.

2804{
2805 auto diminishingGroupCompute = [this]() -> DiminishingGroup
2806 {
2807 if (IsPositive())
2808 return DIMINISHING_NONE;
2809
2811 return DIMINISHING_TAUNT;
2812
2813 switch (Id)
2814 {
2815 case 20549: // War Stomp (Racial - Tauren)
2816 case 24394: // Intimidation
2817 case 118345: // Pulverize (Primal Earth Elemental)
2818 case 118905: // Static Charge (Capacitor Totem)
2819 return DIMINISHING_STUN;
2820 case 107079: // Quaking Palm
2822 case 155145: // Arcane Torrent (Racial - Blood Elf)
2823 return DIMINISHING_SILENCE;
2824 case 108199: // Gorefiend's Grasp
2825 case 191244: // Sticky Bomb
2827 default:
2828 break;
2829 }
2830
2831 // Explicit Diminishing Groups
2832 switch (SpellFamilyName)
2833 {
2835 // Frost Tomb
2836 if (Id == 48400)
2837 return DIMINISHING_NONE;
2838 // Gnaw
2839 else if (Id == 47481)
2840 return DIMINISHING_STUN;
2841 // ToC Icehowl Arctic Breath
2842 else if (Id == 66689)
2843 return DIMINISHING_NONE;
2844 // Black Plague
2845 else if (Id == 64155)
2846 return DIMINISHING_NONE;
2847 // Screams of the Dead (King Ymiron)
2848 else if (Id == 51750)
2849 return DIMINISHING_NONE;
2850 // Crystallize (Keristrasza heroic)
2851 else if (Id == 48179)
2852 return DIMINISHING_NONE;
2853 break;
2854 case SPELLFAMILY_MAGE:
2855 {
2856 // Frost Nova -- 122
2857 if (SpellFamilyFlags[0] & 0x40)
2858 return DIMINISHING_ROOT;
2859 // Freeze (Water Elemental) -- 33395
2860 if (SpellFamilyFlags[2] & 0x200)
2861 return DIMINISHING_ROOT;
2862
2863 // Dragon's Breath -- 31661
2864 if (SpellFamilyFlags[0] & 0x800000)
2866 // Polymorph -- 118
2867 if (SpellFamilyFlags[0] & 0x1000000)
2869 // Ring of Frost -- 82691
2870 if (SpellFamilyFlags[2] & 0x40)
2872 // Ice Nova -- 157997
2873 if (SpellFamilyFlags[2] & 0x800000)
2875 break;
2876 }
2878 {
2879 // Shockwave -- 132168
2880 if (SpellFamilyFlags[1] & 0x8000)
2881 return DIMINISHING_STUN;
2882 // Storm Bolt -- 132169
2883 if (SpellFamilyFlags[2] & 0x1000)
2884 return DIMINISHING_STUN;
2885
2886 // Intimidating Shout -- 5246
2887 if (SpellFamilyFlags[0] & 0x40000)
2888 return DIMINISHING_DISORIENT;
2889 break;
2890 }
2892 {
2893 // Mortal Coil -- 6789
2894 if (SpellFamilyFlags[0] & 0x80000)
2896 // Banish -- 710
2897 if (SpellFamilyFlags[1] & 0x8000000)
2899
2900 // Fear -- 118699
2901 if (SpellFamilyFlags[1] & 0x400)
2902 return DIMINISHING_DISORIENT;
2903 // Howl of Terror -- 5484
2904 if (SpellFamilyFlags[1] & 0x8)
2905 return DIMINISHING_DISORIENT;
2906
2907 // Shadowfury -- 30283
2908 if (SpellFamilyFlags[1] & 0x1000)
2909 return DIMINISHING_STUN;
2910 // Summon Infernal -- 22703
2911 if (SpellFamilyFlags[0] & 0x1000)
2912 return DIMINISHING_STUN;
2913
2914 // 170995 -- Cripple
2915 if (Id == 170995)
2916 return DIMINISHING_LIMITONLY;
2917 break;
2918 }
2920 {
2921 // Fellash -- 115770
2922 // Whiplash -- 6360
2923 if (SpellFamilyFlags[0] & 0x8000000)
2925
2926 // Mesmerize (Shivarra pet) -- 115268
2927 // Seduction (Succubus pet) -- 6358
2928 if (SpellFamilyFlags[0] & 0x2000000)
2929 return DIMINISHING_DISORIENT;
2930
2931 // Axe Toss (Felguard pet) -- 89766
2932 if (SpellFamilyFlags[1] & 0x4)
2933 return DIMINISHING_STUN;
2934 break;
2935 }
2936 case SPELLFAMILY_DRUID:
2937 {
2938 // Maim -- 22570
2939 if (SpellFamilyFlags[1] & 0x80)
2940 return DIMINISHING_STUN;
2941 // Mighty Bash -- 5211
2942 if (SpellFamilyFlags[0] & 0x2000)
2943 return DIMINISHING_STUN;
2944 // Rake -- 163505 -- no flags on the stun
2945 if (Id == 163505)
2946 return DIMINISHING_STUN;
2947
2948 // Incapacitating Roar -- 99, no flags on the stun, 14
2949 if (SpellFamilyFlags[1] & 0x1)
2951
2952 // Cyclone -- 33786
2953 if (SpellFamilyFlags[1] & 0x20)
2954 return DIMINISHING_DISORIENT;
2955
2956 // Solar Beam -- 81261
2957 if (Id == 81261)
2958 return DIMINISHING_SILENCE;
2959
2960 // Typhoon -- 61391
2961 if (SpellFamilyFlags[1] & 0x1000000)
2963 // Ursol's Vortex -- 118283, no family flags
2964 if (Id == 118283)
2966
2967 // Entangling Roots -- 339
2968 if (SpellFamilyFlags[0] & 0x200)
2969 return DIMINISHING_ROOT;
2970 // Mass Entanglement -- 102359
2971 if (SpellFamilyFlags[2] & 0x4)
2972 return DIMINISHING_ROOT;
2973 break;
2974 }
2975 case SPELLFAMILY_ROGUE:
2976 {
2977 // Between the Eyes -- 199804
2978 if (SpellFamilyFlags[0] & 0x800000)
2979 return DIMINISHING_STUN;
2980 // Cheap Shot -- 1833
2981 if (SpellFamilyFlags[0] & 0x400)
2982 return DIMINISHING_STUN;
2983 // Kidney Shot -- 408
2984 if (SpellFamilyFlags[0] & 0x200000)
2985 return DIMINISHING_STUN;
2986
2987 // Gouge -- 1776
2988 if (SpellFamilyFlags[0] & 0x8)
2990 // Sap -- 6770
2991 if (SpellFamilyFlags[0] & 0x80)
2993
2994 // Blind -- 2094
2995 if (SpellFamilyFlags[0] & 0x1000000)
2996 return DIMINISHING_DISORIENT;
2997
2998 // Garrote -- 1330
2999 if (SpellFamilyFlags[1] & 0x20000000)
3000 return DIMINISHING_SILENCE;
3001 break;
3002 }
3003 case SPELLFAMILY_HUNTER:
3004 {
3005 // Charge (Tenacity pet) -- 53148, no flags
3006 if (Id == 53148)
3007 return DIMINISHING_ROOT;
3008 // Ranger's Net -- 200108
3009 // Tracker's Net -- 212638
3010 if (Id == 200108 || Id == 212638)
3011 return DIMINISHING_ROOT;
3012
3013 // Binding Shot -- 117526, no flags
3014 if (Id == 117526)
3015 return DIMINISHING_STUN;
3016
3017 // Freezing Trap -- 3355
3018 if (SpellFamilyFlags[0] & 0x8)
3020 // Wyvern Sting -- 19386
3021 if (SpellFamilyFlags[1] & 0x1000)
3023
3024 // Bursting Shot -- 224729
3025 if (SpellFamilyFlags[2] & 0x40)
3026 return DIMINISHING_DISORIENT;
3027 // Scatter Shot -- 213691
3028 if (SpellFamilyFlags[2] & 0x8000)
3029 return DIMINISHING_DISORIENT;
3030
3031 // Spider Sting -- 202933
3032 if (Id == 202933)
3033 return DIMINISHING_SILENCE;
3034 break;
3035 }
3037 {
3038 // Repentance -- 20066
3039 if (SpellFamilyFlags[0] & 0x4)
3041
3042 // Blinding Light -- 105421
3043 if (Id == 105421)
3044 return DIMINISHING_DISORIENT;
3045
3046 // Avenger's Shield -- 31935
3047 if (SpellFamilyFlags[0] & 0x4000)
3048 return DIMINISHING_SILENCE;
3049
3050 // Hammer of Justice -- 853
3051 if (SpellFamilyFlags[0] & 0x800)
3052 return DIMINISHING_STUN;
3053 break;
3054 }
3055 case SPELLFAMILY_SHAMAN:
3056 {
3057 // Hex -- 51514
3058 // Hex -- 196942 (Voodoo Totem)
3059 if (SpellFamilyFlags[1] & 0x8000)
3061
3062 // Thunderstorm -- 51490
3063 if (SpellFamilyFlags[1] & 0x2000)
3065
3066 // Earthgrab Totem -- 64695
3067 if (SpellFamilyFlags[2] & 0x4000)
3068 return DIMINISHING_ROOT;
3069
3070 // Lightning Lasso -- 204437
3071 if (SpellFamilyFlags[3] & 0x2000000)
3072 return DIMINISHING_STUN;
3073 break;
3074 }
3076 {
3077 // Chains of Ice -- 96294
3078 if (Id == 96294)
3079 return DIMINISHING_ROOT;
3080
3081 // Blinding Sleet -- 207167
3082 if (Id == 207167)
3083 return DIMINISHING_DISORIENT;
3084
3085 // Strangulate -- 47476
3086 if (SpellFamilyFlags[0] & 0x200)
3087 return DIMINISHING_SILENCE;
3088
3089 // Asphyxiate -- 108194
3090 if (SpellFamilyFlags[2] & 0x100000)
3091 return DIMINISHING_STUN;
3092 // Gnaw (Ghoul) -- 91800, no flags
3093 if (Id == 91800)
3094 return DIMINISHING_STUN;
3095 // Monstrous Blow (Ghoul w/ Dark Transformation active) -- 91797
3096 if (Id == 91797)
3097 return DIMINISHING_STUN;
3098 // Winter is Coming -- 207171
3099 if (Id == 207171)
3100 return DIMINISHING_STUN;
3101 break;
3102 }
3103 case SPELLFAMILY_PRIEST:
3104 {
3105 // Holy Word: Chastise -- 200200
3106 if (SpellFamilyFlags[2] & 0x20 && GetSpellVisual() == 52021)
3107 return DIMINISHING_STUN;
3108 // Mind Bomb -- 226943
3109 if (Id == 226943)
3110 return DIMINISHING_STUN;
3111
3112 // Mind Control -- 605
3113 if (SpellFamilyFlags[0] & 0x20000 && GetSpellVisual() == 39068)
3115 // Holy Word: Chastise -- 200196
3116 if (SpellFamilyFlags[2] & 0x20 && GetSpellVisual() == 52019)
3118
3119 // Psychic Scream -- 8122
3120 if (SpellFamilyFlags[0] & 0x10000)
3121 return DIMINISHING_DISORIENT;
3122
3123 // Silence -- 15487
3124 if (SpellFamilyFlags[1] & 0x200000 && GetSpellVisual() == 39025)
3125 return DIMINISHING_SILENCE;
3126
3127 // Shining Force -- 204263
3128 if (Id == 204263)
3130 break;
3131 }
3132 case SPELLFAMILY_MONK:
3133 {
3134 // Disable -- 116706, no flags
3135 if (Id == 116706)
3136 return DIMINISHING_ROOT;
3137
3138 // Fists of Fury -- 120086
3139 if (SpellFamilyFlags[1] & 0x800000 && !(SpellFamilyFlags[2] & 0x8))
3140 return DIMINISHING_STUN;
3141 // Leg Sweep -- 119381
3142 if (SpellFamilyFlags[1] & 0x200)
3143 return DIMINISHING_STUN;
3144
3145 // Incendiary Breath (honor talent) -- 202274, no flags
3146 if (Id == 202274)
3148 // Paralysis -- 115078
3149 if (SpellFamilyFlags[2] & 0x800000)
3151
3152 // Song of Chi-Ji -- 198909
3153 if (Id == 198909)
3154 return DIMINISHING_DISORIENT;
3155 break;
3156 }
3158 {
3159 switch (Id)
3160 {
3161 case 179057: // Chaos Nova
3162 case 211881: // Fel Eruption
3163 case 200166: // Metamorphosis
3164 case 205630: // Illidan's Grasp
3165 return DIMINISHING_STUN;
3166 case 217832: // Imprison
3167 case 221527: // Imprison
3169 default:
3170 break;
3171 }
3172 break;
3173 }
3174 default:
3175 break;
3176 }
3177
3178 return DIMINISHING_NONE;
3179 };
3180
3181 auto diminishingTypeCompute = [](DiminishingGroup group) -> DiminishingReturnsType
3182 {
3183 switch (group)
3184 {
3185 case DIMINISHING_TAUNT:
3186 case DIMINISHING_STUN:
3187 return DRTYPE_ALL;
3189 case DIMINISHING_NONE:
3190 return DRTYPE_NONE;
3191 default:
3192 return DRTYPE_PLAYER;
3193 }
3194 };
3195
3196 auto diminishingMaxLevelCompute = [](DiminishingGroup group) -> DiminishingLevels
3197 {
3198 switch (group)
3199 {
3200 case DIMINISHING_TAUNT:
3203 return DIMINISHING_LEVEL_2;
3204 default:
3206 }
3207 };
3208
3209 auto diminishingLimitDurationCompute = [this]() -> int32
3210 {
3211 // Explicit diminishing duration
3212 switch (SpellFamilyName)
3213 {
3214 case SPELLFAMILY_MAGE:
3215 {
3216 // Dragon's Breath - 3 seconds in PvP
3217 if (SpellFamilyFlags[0] & 0x800000)
3218 return 3 * IN_MILLISECONDS;
3219 break;
3220 }
3222 {
3223 // Cripple - 4 seconds in PvP
3224 if (Id == 170995)
3225 return 4 * IN_MILLISECONDS;
3226 break;
3227 }
3228 case SPELLFAMILY_HUNTER:
3229 {
3230 // Binding Shot - 3 seconds in PvP
3231 if (Id == 117526)
3232 return 3 * IN_MILLISECONDS;
3233
3234 // Wyvern Sting - 6 seconds in PvP
3235 if (SpellFamilyFlags[1] & 0x1000)
3236 return 6 * IN_MILLISECONDS;
3237 break;
3238 }
3239 case SPELLFAMILY_MONK:
3240 {
3241 // Paralysis - 4 seconds in PvP regardless of if they are facing you
3242 if (SpellFamilyFlags[2] & 0x800000)
3243 return 4 * IN_MILLISECONDS;
3244 break;
3245 }
3247 {
3248 switch (Id)
3249 {
3250 case 217832: // Imprison
3251 case 221527: // Imprison
3252 return 4 * IN_MILLISECONDS;
3253 default:
3254 break;
3255 }
3256 break;
3257 }
3258 default:
3259 break;
3260 }
3261
3262 return 8 * IN_MILLISECONDS;
3263 };
3264
3265 SpellDiminishInfo diminishInfo;
3266 diminishInfo.DiminishGroup = diminishingGroupCompute();
3267 diminishInfo.DiminishReturnType = diminishingTypeCompute(diminishInfo.DiminishGroup);
3268 diminishInfo.DiminishMaxLevel = diminishingMaxLevelCompute(diminishInfo.DiminishGroup);
3269 diminishInfo.DiminishDurationLimit = diminishingLimitDurationCompute();
3270
3271 _diminishInfo = diminishInfo;
3272}
@ IN_MILLISECONDS
Definition: Common.h:35
DiminishingLevels
@ DIMINISHING_LEVEL_IMMUNE
@ DIMINISHING_LEVEL_TAUNT_IMMUNE
@ DIMINISHING_LEVEL_2
DiminishingGroup
@ DIMINISHING_AOE_KNOCKBACK
@ DIMINISHING_NONE
@ DIMINISHING_STUN
@ DIMINISHING_LIMITONLY
@ DIMINISHING_DISORIENT
@ DIMINISHING_ROOT
@ DIMINISHING_TAUNT
@ DIMINISHING_SILENCE
@ DIMINISHING_INCAPACITATE
DiminishingReturnsType
@ DRTYPE_NONE
@ DRTYPE_PLAYER
@ DRTYPE_ALL
@ SPELLFAMILY_PRIEST
@ SPELLFAMILY_WARLOCK_PET
@ SPELLFAMILY_WARLOCK
@ SPELLFAMILY_MAGE
@ SPELLFAMILY_GENERIC
@ SPELLFAMILY_WARRIOR
@ SPELLFAMILY_PALADIN
@ SPELLFAMILY_HUNTER
@ SPELLFAMILY_DEMON_HUNTER
@ SPELLFAMILY_SHAMAN
@ SPELLFAMILY_DEATHKNIGHT
@ SPELLFAMILY_MONK
uint32 GetSpellVisual(WorldObject const *caster=nullptr, WorldObject const *viewer=nullptr) const
Definition: SpellInfo.cpp:4510
SpellDiminishInfo _diminishInfo
Definition: SpellInfo.h:620
bool IsPositive() const
Definition: SpellInfo.cpp:1699
int32 DiminishDurationLimit
Definition: SpellInfo.h:311
DiminishingReturnsType DiminishReturnType
Definition: SpellInfo.h:309
DiminishingLevels DiminishMaxLevel
Definition: SpellInfo.h:310
DiminishingGroup DiminishGroup
Definition: SpellInfo.h:308
+ Here is the call graph for this function:

◆ _LoadSpellSpecific()

void SpellInfo::_LoadSpellSpecific ( )
private

@workaround For non-stacking tracking spells (We need generic solution)

Definition at line 2615 of file SpellInfo.cpp.

2616{
2618 {
2619 switch (SpellFamilyName)
2620 {
2622 {
2623 // Food / Drinks (mostly)
2624 if (HasAuraInterruptFlag(SpellAuraInterruptFlags::Standing))
2625 {
2626 bool food = false;
2627 bool drink = false;
2628 for (SpellEffectInfo const& effect : GetEffects())
2629 {
2630 if (!effect.IsAura())
2631 continue;
2632 switch (effect.ApplyAuraName)
2633 {
2634 // Food
2637 food = true;
2638 break;
2639 // Drink
2642 drink = true;
2643 break;
2644 default:
2645 break;
2646 }
2647 }
2648
2649 if (food && drink)
2651 else if (food)
2652 return SPELL_SPECIFIC_FOOD;
2653 else if (drink)
2654 return SPELL_SPECIFIC_DRINK;
2655 }
2656 // scrolls effects
2657 else
2658 {
2659 SpellInfo const* firstRankSpellInfo = GetFirstRankSpell();
2660 switch (firstRankSpellInfo->Id)
2661 {
2662 case 8118: // Strength
2663 case 8099: // Stamina
2664 case 8112: // Spirit
2665 case 8096: // Intellect
2666 case 8115: // Agility
2667 case 8091: // Armor
2668 return SPELL_SPECIFIC_SCROLL;
2669 default:
2670 break;
2671 }
2672 }
2673 break;
2674 }
2675 case SPELLFAMILY_MAGE:
2676 {
2677 // family flags 18(Molten), 25(Frost/Ice), 28(Mage)
2678 if (SpellFamilyFlags[0] & 0x12040000)
2680
2681 // Arcane brillance and Arcane intelect (normal check fails because of flags difference)
2682 if (SpellFamilyFlags[0] & 0x400)
2684
2685 if ((SpellFamilyFlags[0] & 0x1000000) && GetEffect(EFFECT_0).IsAura(SPELL_AURA_MOD_CONFUSE))
2687
2688 break;
2689 }
2691 {
2692 if (Id == 12292) // Death Wish
2694
2695 break;
2696 }
2698 {
2699 // Warlock (Bane of Doom | Bane of Agony | Bane of Havoc)
2700 if (Id == 603 || Id == 980 || Id == 80240)
2701 return SPELL_SPECIFIC_BANE;
2702
2703 // only warlock curses have this
2704 if (Dispel == DISPEL_CURSE)
2705 return SPELL_SPECIFIC_CURSE;
2706
2707 // Warlock (Demon Armor | Demon Skin | Fel Armor)
2708 if (SpellFamilyFlags[1] & 0x20000020 || SpellFamilyFlags[2] & 0x00000010)
2710
2711 //seed of corruption and corruption
2712 if (SpellFamilyFlags[1] & 0x10 || SpellFamilyFlags[0] & 0x2)
2714 break;
2715 }
2716 case SPELLFAMILY_PRIEST:
2717 {
2718 // Divine Spirit and Prayer of Spirit
2719 if (SpellFamilyFlags[0] & 0x20)
2721
2722 break;
2723 }
2724 case SPELLFAMILY_HUNTER:
2725 {
2726 // only hunter stings have this
2727 if (Dispel == DISPEL_POISON)
2728 return SPELL_SPECIFIC_STING;
2729
2730 // only hunter aspects have this (but not all aspects in hunter family)
2731 if (SpellFamilyFlags & flag128(0x00200000, 0x00000000, 0x00001010, 0x00000000))
2732 return SPELL_SPECIFIC_ASPECT;
2733
2734 break;
2735 }
2737 {
2738 // Collection of all the seal family flags. No other paladin spell has any of those.
2739 if (SpellFamilyFlags[1] & 0xA2000800)
2740 return SPELL_SPECIFIC_SEAL;
2741
2742 if (SpellFamilyFlags[0] & 0x00002190)
2743 return SPELL_SPECIFIC_HAND;
2744
2745 // only paladin auras have this (for palaldin class family)
2746 switch (Id)
2747 {
2748 case 465: // Devotion Aura
2749 case 32223: // Crusader Aura
2750 case 183435: // Retribution Aura
2751 case 317920: // Concentration Aura
2752 return SPELL_SPECIFIC_AURA;
2753 default:
2754 break;
2755 }
2756
2757 break;
2758 }
2759 case SPELLFAMILY_SHAMAN:
2760 {
2761 // family flags 10 (Lightning), 42 (Earth), 37 (Water), proc shield from T2 8 pieces bonus
2762 if (SpellFamilyFlags[1] & 0x420
2763 || SpellFamilyFlags[0] & 0x00000400
2764 || Id == 23552)
2766
2767 break;
2768 }
2770 if (Id == 48266 || Id == 48263 || Id == 48265)
2772 break;
2773 }
2774
2775 for (SpellEffectInfo const& effect : GetEffects())
2776 {
2777 if (effect.IsEffect(SPELL_EFFECT_APPLY_AURA))
2778 {
2779 switch (effect.ApplyAuraName)
2780 {
2785 return SPELL_SPECIFIC_CHARM;
2788 if (Id == 30645) // Gas Cloud Tracking
2789 return SPELL_SPECIFIC_NORMAL;
2790 [[fallthrough]];
2794 default:
2795 break;
2796 }
2797 }
2798 }
2799 return SPELL_SPECIFIC_NORMAL;
2800 }();
2801}
@ EFFECT_0
Definition: SharedDefines.h:30
@ SPELL_EFFECT_APPLY_AURA
@ DISPEL_POISON
@ DISPEL_CURSE
@ SPELL_AURA_TRACK_RESOURCES
@ SPELL_AURA_OBS_MOD_HEALTH
@ SPELL_AURA_MOD_POSSESS_PET
@ SPELL_AURA_MOD_POWER_REGEN
@ SPELL_AURA_OBS_MOD_POWER
@ SPELL_AURA_TRACK_STEALTHED
@ SPELL_AURA_MOD_CHARM
@ SPELL_AURA_AOE_CHARM
@ SPELL_AURA_TRACK_CREATURES
@ SPELL_AURA_MOD_POSSESS
@ SPELL_AURA_MOD_REGEN
SpellSpecificType
Definition: SpellInfo.h:119
@ SPELL_SPECIFIC_FOOD
Definition: SpellInfo.h:132
@ SPELL_SPECIFIC_MAGE_ARMOR
Definition: SpellInfo.h:128
@ SPELL_SPECIFIC_NORMAL
Definition: SpellInfo.h:120
@ SPELL_SPECIFIC_STING
Definition: SpellInfo.h:123
@ SPELL_SPECIFIC_MAGE_ARCANE_BRILLANCE
Definition: SpellInfo.h:138
@ SPELL_SPECIFIC_ASPECT
Definition: SpellInfo.h:125
@ SPELL_SPECIFIC_PRIEST_DIVINE_SPIRIT
Definition: SpellInfo.h:140
@ SPELL_SPECIFIC_ELEMENTAL_SHIELD
Definition: SpellInfo.h:129
@ SPELL_SPECIFIC_WARLOCK_CORRUPTION
Definition: SpellInfo.h:131
@ SPELL_SPECIFIC_BANE
Definition: SpellInfo.h:143
@ SPELL_SPECIFIC_PRESENCE
Definition: SpellInfo.h:135
@ SPELL_SPECIFIC_CURSE
Definition: SpellInfo.h:124
@ SPELL_SPECIFIC_DRINK
Definition: SpellInfo.h:133
@ SPELL_SPECIFIC_HAND
Definition: SpellInfo.h:141
@ SPELL_SPECIFIC_AURA
Definition: SpellInfo.h:122
@ SPELL_SPECIFIC_WARRIOR_ENRAGE
Definition: SpellInfo.h:139
@ SPELL_SPECIFIC_WARLOCK_ARMOR
Definition: SpellInfo.h:127
@ SPELL_SPECIFIC_SCROLL
Definition: SpellInfo.h:137
@ SPELL_SPECIFIC_MAGE_POLYMORPH
Definition: SpellInfo.h:130
@ SPELL_SPECIFIC_TRACKER
Definition: SpellInfo.h:126
@ SPELL_SPECIFIC_SEAL
Definition: SpellInfo.h:121
@ SPELL_SPECIFIC_FOOD_AND_DRINK
Definition: SpellInfo.h:134
@ SPELL_SPECIFIC_CHARM
Definition: SpellInfo.h:136
SpellInfo const * GetFirstRankSpell() const
Definition: SpellInfo.cpp:4401
SpellSpecificType _spellSpecific
Definition: SpellInfo.h:617
bool HasAuraInterruptFlag(SpellAuraInterruptFlags flag) const
Definition: SpellInfo.h:469
+ Here is the call graph for this function:

◆ _LoadSqrtTargetLimit()

void SpellInfo::_LoadSqrtTargetLimit ( int32  maxTargets,
int32  numNonDiminishedTargets,
Optional< SpellEffIndex maxTargetsEffectValueHolder,
Optional< SpellEffIndex numNonDiminishedTargetsEffectValueHolder 
)
private

Definition at line 3607 of file SpellInfo.cpp.

3609{
3610 SqrtDamageAndHealingDiminishing.MaxTargets = maxTargets;
3611 SqrtDamageAndHealingDiminishing.NumNonDiminishedTargets = numNonDiminishedTargets;
3612
3613 if (maxTargetsEffectValueHolder)
3614 {
3615 if (maxTargetsEffectValueHolder < GetEffects().size())
3616 {
3617 SpellEffectInfo const& valueHolder = GetEffect(*maxTargetsEffectValueHolder);
3618 int32 expectedValue = valueHolder.CalcBaseValue(nullptr, nullptr, 0, -1);
3619 if (maxTargets != expectedValue)
3620 TC_LOG_ERROR("spells", "SpellInfo::_LoadSqrtTargetLimit(maxTargets): Spell {} has different value in effect {} than expected, recheck target caps (expected {}, got {})",
3621 Id, AsUnderlyingType(*maxTargetsEffectValueHolder), maxTargets, expectedValue);
3622 }
3623 else
3624 TC_LOG_ERROR("spells", "SpellInfo::_LoadSqrtTargetLimit(maxTargets): Spell {} does not have effect {}", Id, AsUnderlyingType(*maxTargetsEffectValueHolder));
3625 }
3626
3627 if (numNonDiminishedTargetsEffectValueHolder)
3628 {
3629 if (numNonDiminishedTargetsEffectValueHolder < GetEffects().size())
3630 {
3631 SpellEffectInfo const& valueHolder = GetEffect(*numNonDiminishedTargetsEffectValueHolder);
3632 int32 expectedValue = valueHolder.CalcBaseValue(nullptr, nullptr, 0, -1);
3633 if (numNonDiminishedTargets != expectedValue)
3634 TC_LOG_ERROR("spells", "SpellInfo::_LoadSqrtTargetLimit(numNonDiminishedTargets): Spell {} has different value in effect {} than expected, recheck target caps (expected {}, got {})",
3635 Id, AsUnderlyingType(*numNonDiminishedTargetsEffectValueHolder), numNonDiminishedTargets, expectedValue);
3636 }
3637 else
3638 TC_LOG_ERROR("spells", "SpellInfo::_LoadSqrtTargetLimit(numNonDiminishedTargets): Spell {} does not have effect {}", Id, AsUnderlyingType(*numNonDiminishedTargetsEffectValueHolder));
3639 }
3640}
#define TC_LOG_ERROR(filterType__,...)
Definition: Log.h:165
constexpr std::underlying_type< E >::type AsUnderlyingType(E enumValue)
Definition: Util.h:489
int32 CalcBaseValue(WorldObject const *caster, Unit const *target, uint32 itemId, int32 itemLevel) const
Definition: SpellInfo.cpp:553
struct SpellInfo::@333 SqrtDamageAndHealingDiminishing
+ Here is the call graph for this function:

◆ _UnloadImplicitTargetConditionLists()

void SpellInfo::_UnloadImplicitTargetConditionLists ( )
private

Definition at line 5050 of file SpellInfo.cpp.

5051{
5052 // find the same instances of ConditionList and delete them.
5053 for (SpellEffectInfo const& effect : _effects)
5054 {
5055 ConditionContainer* cur = effect.ImplicitTargetConditions;
5056 if (!cur)
5057 continue;
5058
5059 for (size_t j = effect.EffectIndex; j < _effects.size(); ++j)
5060 if (_effects[j].ImplicitTargetConditions == cur)
5061 _effects[j].ImplicitTargetConditions = nullptr;
5062
5063 delete cur;
5064 }
5065}
std::vector< Condition * > ConditionContainer
Definition: ConditionMgr.h:267
+ Here is the caller graph for this function:

◆ ApplyAllSpellImmunitiesTo()

void SpellInfo::ApplyAllSpellImmunitiesTo ( Unit target,
SpellEffectInfo const &  spellEffectInfo,
bool  apply 
) const

Definition at line 3642 of file SpellInfo.cpp.

3643{
3644 SpellEffectInfo::ImmunityInfo const* immuneInfo = spellEffectInfo.GetImmunityInfo();
3645 if (!immuneInfo)
3646 return;
3647
3648 if (uint32 schoolImmunity = immuneInfo->SchoolImmuneMask)
3649 {
3650 target->ApplySpellImmune(Id, IMMUNITY_SCHOOL, schoolImmunity, apply);
3651
3653 {
3654 target->RemoveAppliedAuras([this, schoolImmunity](AuraApplication const* aurApp) -> bool
3655 {
3656 SpellInfo const* auraSpellInfo = aurApp->GetBase()->GetSpellInfo();
3657 return ((auraSpellInfo->GetSchoolMask() & schoolImmunity) != 0 && // Check for school mask
3658 CanDispelAura(auraSpellInfo) &&
3659 (IsPositive() != aurApp->IsPositive()) && // Check spell vs aura possitivity
3660 !auraSpellInfo->IsPassive() && // Don't remove passive auras
3661 auraSpellInfo->Id != Id); // Don't remove self
3662 });
3663 }
3664
3665 if (apply && schoolImmunity & SPELL_SCHOOL_MASK_NORMAL)
3666 target->RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags::InvulnerabilityBuff);
3667 }
3668
3669 if (uint64 mechanicImmunity = immuneInfo->MechanicImmuneMask)
3670 {
3671 for (uint32 i = 0; i < MAX_MECHANIC; ++i)
3672 if (mechanicImmunity & (UI64LIT(1) << i))
3673 target->ApplySpellImmune(Id, IMMUNITY_MECHANIC, i, apply);
3674
3676 {
3677 if (apply)
3678 target->RemoveAurasWithMechanic(mechanicImmunity, AURA_REMOVE_BY_DEFAULT, Id);
3679 else
3680 {
3681 std::vector<Aura*> aurasToUpdateTargets;
3682 target->RemoveAppliedAuras([mechanicImmunity, &aurasToUpdateTargets](AuraApplication const* aurApp)
3683 {
3684 Aura* aura = aurApp->GetBase();
3685 if (aura->GetSpellInfo()->GetAllEffectsMechanicMask() & mechanicImmunity)
3686 aurasToUpdateTargets.push_back(aura);
3687
3688 // only update targets, don't remove anything
3689 return false;
3690 });
3691
3692 for (Aura* aura : aurasToUpdateTargets)
3693 aura->UpdateTargetMap(aura->GetCaster());
3694 }
3695 }
3696 }
3697
3698 if (uint32 dispelImmunity = immuneInfo->DispelImmune)
3699 {
3700 target->ApplySpellImmune(Id, IMMUNITY_DISPEL, dispelImmunity, apply);
3701
3703 {
3704 target->RemoveAppliedAuras([dispelImmunity](AuraApplication const* aurApp) -> bool
3705 {
3706 SpellInfo const* spellInfo = aurApp->GetBase()->GetSpellInfo();
3707 if (spellInfo->Dispel == dispelImmunity)
3708 return true;
3709
3710 return false;
3711 });
3712 }
3713 }
3714
3715 if (uint32 damageImmunity = immuneInfo->DamageSchoolMask)
3716 {
3717 target->ApplySpellImmune(Id, IMMUNITY_DAMAGE, damageImmunity, apply);
3718
3719 if (apply && damageImmunity & SPELL_SCHOOL_MASK_NORMAL)
3720 target->RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags::InvulnerabilityBuff);
3721 }
3722
3723 for (AuraType auraType : immuneInfo->AuraTypeImmune)
3724 {
3725 target->ApplySpellImmune(Id, IMMUNITY_STATE, auraType, apply);
3727 target->RemoveAurasByType(auraType, [](AuraApplication const* aurApp) -> bool
3728 {
3729 // if the aura has SPELL_ATTR0_NO_IMMUNITIES, then it cannot be removed by immunity
3730 return !aurApp->GetBase()->GetSpellInfo()->HasAttribute(SPELL_ATTR0_NO_IMMUNITIES);
3731 });
3732 }
3733
3734 for (SpellEffectName effectType : immuneInfo->SpellEffectImmune)
3735 target->ApplySpellImmune(Id, IMMUNITY_EFFECT, effectType, apply);
3736}
@ SPELL_SCHOOL_MASK_NORMAL
@ SPELL_ATTR1_IMMUNITY_PURGES_EFFECT
@ MAX_MECHANIC
@ IMMUNITY_STATE
@ IMMUNITY_EFFECT
@ IMMUNITY_DAMAGE
@ IMMUNITY_MECHANIC
@ IMMUNITY_SCHOOL
@ IMMUNITY_DISPEL
@ SPELL_ATTR0_NO_IMMUNITIES
@ AURA_REMOVE_BY_DEFAULT
bool IsPositive() const
Definition: SpellAuras.h:83
Aura * GetBase() const
Definition: SpellAuras.h:77
Unit * GetCaster() const
Definition: SpellAuras.cpp:513
void UpdateTargetMap(Unit *caster, bool apply=true)
Definition: SpellAuras.cpp:612
SpellInfo const * GetSpellInfo() const
Definition: SpellAuras.h:133
bool CanDispelAura(SpellInfo const *auraSpellInfo) const
Definition: SpellInfo.cpp:1858
bool IsPassive() const
Definition: SpellInfo.cpp:1582
void ApplySpellImmune(uint32 spellId, SpellImmunity op, uint32 type, bool apply)
Definition: Unit.cpp:7722
void RemoveAurasByType(AuraType auraType, std::function< bool(AuraApplication const *)> const &check, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition: Unit.cpp:3721
void RemoveAurasWithInterruptFlags(InterruptFlags flag, SpellInfo const *source=nullptr)
Definition: Unit.cpp:4010
void RemoveAppliedAuras(std::function< bool(AuraApplication const *)> const &check, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition: Unit.cpp:3667
void RemoveAurasWithMechanic(uint64 mechanicMaskToRemove, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT, uint32 exceptSpellId=0, bool withEffectMechanics=false)
Definition: Unit.cpp:4071
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ CalcCastTime()

uint32 SpellInfo::CalcCastTime ( Spell spell = nullptr) const

Definition at line 3934 of file SpellInfo.cpp.

3935{
3936 int32 castTime = 0;
3937 if (CastTimeEntry)
3938 castTime = std::max(CastTimeEntry->Base, CastTimeEntry->Minimum);
3939
3940 if (castTime <= 0)
3941 return 0;
3942
3943 if (spell)
3944 spell->GetCaster()->ModSpellCastTime(this, castTime, spell);
3945
3947 castTime += 500;
3948
3949 return (castTime > 0) ? uint32(castTime) : 0;
3950}
@ SPELL_ATTR9_AIMED_SHOT
@ SPELL_ATTR0_USES_RANGED_SLOT
bool IsAutoRepeatRangedSpell() const
Definition: SpellInfo.cpp:1731
WorldObject * GetCaster() const
Definition: Spell.h:637
void ModSpellCastTime(SpellInfo const *spellInfo, int32 &castTime, Spell *spell=nullptr) const
Definition: Object.cpp:2453
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ CalcDuration()

int32 SpellInfo::CalcDuration ( WorldObject const *  caster = nullptr) const

Definition at line 3909 of file SpellInfo.cpp.

3910{
3911 int32 duration = GetDuration();
3912
3913 if (caster)
3914 if (Player* modOwner = caster->GetSpellModOwner())
3915 modOwner->ApplySpellMod(this, SpellModOp::Duration, duration);
3916
3917 return duration;
3918}
int32 GetDuration() const
Definition: SpellInfo.cpp:3920
Player * GetSpellModOwner() const
Definition: Object.cpp:2259
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ CalcPowerCost() [1/3]

Optional< SpellPowerCost > SpellInfo::CalcPowerCost ( Powers  powerType,
bool  optionalCost,
WorldObject const *  caster,
SpellSchoolMask  schoolMask,
Spell spell = nullptr 
) const

Definition at line 3999 of file SpellInfo.cpp.

4000{
4001 // gameobject casts don't use power
4002 Unit const* unitCaster = caster->ToUnit();
4003 if (!unitCaster)
4004 return {};
4005
4006 auto itr = std::find_if(PowerCosts.cbegin(), PowerCosts.cend(), [powerType](SpellPowerEntry const* spellPowerEntry)
4007 {
4008 return spellPowerEntry && spellPowerEntry->PowerType == powerType;
4009 });
4010 if (itr == PowerCosts.cend())
4011 return {};
4012
4013 return CalcPowerCost(*itr, optionalCost, caster, schoolMask, spell);
4014}
static Unit * ToUnit(Object *o)
Definition: Object.h:212
Optional< SpellPowerCost > CalcPowerCost(Powers powerType, bool optionalCost, WorldObject const *caster, SpellSchoolMask schoolMask, Spell *spell=nullptr) const
Definition: SpellInfo.cpp:3999
Definition: Unit.h:747
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ CalcPowerCost() [2/3]

Optional< SpellPowerCost > SpellInfo::CalcPowerCost ( SpellPowerEntry const *  power,
bool  optionalCost,
WorldObject const *  caster,
SpellSchoolMask  schoolMask,
Spell spell = nullptr 
) const

Definition at line 4016 of file SpellInfo.cpp.

4017{
4018 // gameobject casts don't use power
4019 Unit const* unitCaster = caster->ToUnit();
4020 if (!unitCaster)
4021 return {};
4022
4023 if (power->RequiredAuraSpellID && !unitCaster->HasAura(power->RequiredAuraSpellID))
4024 return {};
4025
4026 // Spell drain all exist power on cast (Only paladin lay of Hands)
4028 {
4029 if (optionalCost)
4030 return {};
4031
4032 // If power type - health drain all
4033 if (power->PowerType == POWER_HEALTH)
4034 return SpellPowerCost{ .Power = POWER_HEALTH, .Amount = int32(unitCaster->GetHealth()) };
4035
4036 // Else drain all power
4037 if (power->PowerType < MAX_POWERS)
4038 return SpellPowerCost{ .Power = Powers(power->PowerType), .Amount = unitCaster->GetPower(Powers(power->PowerType)) };
4039
4040 TC_LOG_ERROR("spells", "SpellInfo::CalcPowerCost: Unknown power type '{}' in spell {}", power->PowerType, Id);
4041 return {};
4042 }
4043
4044 // Base powerCost
4045 int32 powerCost = 0;
4046 if (!optionalCost)
4047 {
4048 powerCost = power->ManaCost;
4049 // PCT cost from total amount
4050 if (power->PowerCostPct)
4051 {
4052 switch (power->PowerType)
4053 {
4054 // health as power used
4055 case POWER_HEALTH:
4056 if (G3D::fuzzyEq(power->PowerCostPct, 0.0f))
4057 powerCost += int32(CalculatePct(unitCaster->GetMaxHealth(), power->PowerCostMaxPct));
4058 else
4059 powerCost += int32(CalculatePct(unitCaster->GetMaxHealth(), power->PowerCostPct));
4060 break;
4061 case POWER_MANA:
4062 powerCost += int32(CalculatePct(unitCaster->GetCreateMana(), power->PowerCostPct));
4063 break;
4065 TC_LOG_ERROR("spells", "SpellInfo::CalcPowerCost: Unknown power type POWER_ALTERNATE_POWER in spell {}", Id);
4066 return {};
4067 default:
4068 {
4069 if (PowerTypeEntry const* powerTypeEntry = sDB2Manager.GetPowerTypeEntry(Powers(power->PowerType)))
4070 {
4071 powerCost += int32(CalculatePct(powerTypeEntry->MaxBasePower, power->PowerCostPct));
4072 break;
4073 }
4074
4075 TC_LOG_ERROR("spells", "SpellInfo::CalcPowerCost: Unknown power type '{}' in spell {}", power->PowerType, Id);
4076 return {};
4077 }
4078 }
4079 }
4080 }
4081 else
4082 {
4083 powerCost = int32(power->OptionalCost);
4084
4085 if (power->OptionalCostPct)
4086 {
4087 switch (power->PowerType)
4088 {
4089 // health as power used
4090 case POWER_HEALTH:
4091 powerCost += int32(CalculatePct(unitCaster->GetMaxHealth(), power->OptionalCostPct));
4092 break;
4093 case POWER_MANA:
4094 powerCost += int32(CalculatePct(unitCaster->GetCreateMana(), power->OptionalCostPct));
4095 break;
4097 TC_LOG_ERROR("spells", "SpellInfo::CalcPowerCost: Unsupported power type POWER_ALTERNATE_POWER in spell {} for optional cost percent", Id);
4098 return {};
4099 default:
4100 {
4101 if (PowerTypeEntry const* powerTypeEntry = sDB2Manager.GetPowerTypeEntry(Powers(power->PowerType)))
4102 {
4103 powerCost += int32(CalculatePct(powerTypeEntry->MaxBasePower, power->OptionalCostPct));
4104 break;
4105 }
4106
4107 TC_LOG_ERROR("spells", "SpellInfo::CalcPowerCost: Unknown power type '{}' in spell {} for optional cost percent", power->PowerType, Id);
4108 return {};
4109 }
4110 }
4111 }
4112
4113 powerCost += unitCaster->GetTotalAuraModifier(SPELL_AURA_MOD_ADDITIONAL_POWER_COST, [this, power](AuraEffect const* aurEff) -> bool
4114 {
4115 return aurEff->GetMiscValue() == power->PowerType
4116 && aurEff->IsAffectingSpell(this);
4117 });
4118 }
4119
4120 bool initiallyNegative = powerCost < 0;
4121
4122 // Shiv - costs 20 + weaponSpeed*10 energy (apply only to non-triggered spell with energy cost)
4124 {
4125 uint32 speed = 0;
4126 if (SpellShapeshiftFormEntry const* ss = sSpellShapeshiftFormStore.LookupEntry(unitCaster->GetShapeshiftForm()))
4127 speed = ss->CombatRoundTime;
4128 else
4129 {
4132 slot = OFF_ATTACK;
4133
4134 speed = unitCaster->GetBaseAttackTime(slot);
4135 }
4136
4137 powerCost += speed / 100;
4138 }
4139
4140 if (power->PowerType != POWER_HEALTH)
4141 {
4142 if (!optionalCost)
4143 {
4144 // Flat mod from caster auras by spell school and power type
4146 {
4147 if (!(aura->GetMiscValue() & schoolMask))
4148 continue;
4149
4150 if (!(aura->GetMiscValueB() & (1 << power->PowerType)))
4151 continue;
4152
4153 powerCost += aura->GetAmount();
4154 }
4155 }
4156
4157 // PCT mod from user auras by spell school and power type
4158 for (auto schoolCostPct : unitCaster->GetAuraEffectsByType(SPELL_AURA_MOD_POWER_COST_SCHOOL_PCT))
4159 {
4160 if (!(schoolCostPct->GetMiscValue() & schoolMask))
4161 continue;
4162
4163 if (!(schoolCostPct->GetMiscValueB() & (1 << power->PowerType)))
4164 continue;
4165
4166 powerCost += CalculatePct(powerCost, schoolCostPct->GetAmount());
4167 }
4168 }
4169
4170 // Apply cost mod by spell
4171 if (Player* modOwner = unitCaster->GetSpellModOwner())
4172 {
4174 switch (power->OrderIndex)
4175 {
4176 case 0:
4177 mod = SpellModOp::PowerCost0;
4178 break;
4179 case 1:
4180 mod = SpellModOp::PowerCost1;
4181 break;
4182 case 2:
4183 mod = SpellModOp::PowerCost2;
4184 break;
4185 default:
4186 break;
4187 }
4188
4189 if (mod)
4190 {
4191 if (!optionalCost)
4192 modOwner->ApplySpellMod(this, *mod, powerCost, spell);
4193 else
4194 {
4195 // optional cost ignores flat modifiers
4196 int32 flatMod = 0;
4197 float pctMod = 1.0f;
4198 modOwner->GetSpellModValues(this, *mod, spell, powerCost, &flatMod, &pctMod);
4199 powerCost = int32(powerCost * pctMod);
4200 }
4201 }
4202 }
4203
4204 if (!unitCaster->IsControlledByPlayer() && G3D::fuzzyEq(power->PowerCostPct, 0.0f) && SpellLevel && power->PowerType == POWER_MANA)
4205 {
4207 {
4209 GtNpcManaCostScalerEntry const* casterScaler = sNpcManaCostScalerGameTable.GetRow(unitCaster->GetLevel());
4210 if (spellScaler && casterScaler)
4211 powerCost *= casterScaler->Scaler / spellScaler->Scaler;
4212 }
4213 }
4214
4215 if (power->PowerType == POWER_MANA)
4216 powerCost = float(powerCost) * (1.0f + unitCaster->m_unitData->ManaCostMultiplier);
4217
4218 // power cost cannot become negative if initially positive
4219 if (initiallyNegative != (powerCost < 0))
4220 powerCost = 0;
4221
4222 return SpellPowerCost{ .Power = Powers(power->PowerType), .Amount = powerCost };
4223}
DB2Storage< SpellShapeshiftFormEntry > sSpellShapeshiftFormStore("SpellShapeshiftForm.db2", &SpellShapeshiftFormLoadInfo::Instance)
GameTable< GtNpcManaCostScalerEntry > sNpcManaCostScalerGameTable
Definition: GameTables.cpp:37
std::optional< T > Optional
Optional helper class to wrap optional values within.
Definition: Optional.h:25
@ SPELL_ATTR1_USE_ALL_MANA
@ SPELL_ATTR3_REQUIRES_MAIN_HAND_WEAPON
@ SPELL_ATTR3_REQUIRES_OFF_HAND_WEAPON
WeaponAttackType
@ OFF_ATTACK
@ BASE_ATTACK
Powers
@ MAX_POWERS
@ POWER_ALTERNATE_POWER
@ POWER_HEALTH
@ POWER_MANA
@ SPELL_ATTR0_SCALES_WITH_CREATURE_LEVEL
@ SPELL_ATTR4_WEAPON_SPEED_COST_SCALING
@ SPELL_AURA_MOD_POWER_COST_SCHOOL_PCT
@ SPELL_AURA_MOD_POWER_COST_SCHOOL
@ SPELL_AURA_MOD_ADDITIONAL_POWER_COST
T CalculatePct(T base, U pct)
Definition: Util.h:70
bool IsAffectingSpell(SpellInfo const *spell) const
int32 GetMiscValue() const
AuraEffectList const & GetAuraEffectsByType(AuraType type) const
Definition: Unit.h:1428
UF::UpdateField< UF::UnitData, 0, TYPEID_UNIT > m_unitData
Definition: Unit.h:1911
ShapeshiftForm GetShapeshiftForm() const
Definition: Unit.h:1570
uint32 GetBaseAttackTime(WeaponAttackType att) const
Definition: Unit.cpp:10398
uint64 GetMaxHealth() const
Definition: Unit.h:897
uint64 GetHealth() const
Definition: Unit.h:896
int32 GetTotalAuraModifier(AuraType auraType) const
Definition: Unit.cpp:4838
int32 GetPower(Powers power) const
Definition: Unit.cpp:9239
bool HasAura(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemCasterGUID=ObjectGuid::Empty, uint32 reqEffMask=0) const
Definition: Unit.cpp:4573
bool IsControlledByPlayer() const
Definition: Unit.h:1300
uint32 GetCreateMana() const
Definition: Unit.h:1503
uint8 GetLevel() const
Definition: Unit.h:866
Powers Power
Definition: SpellInfo.h:316
+ Here is the call graph for this function:

◆ CalcPowerCost() [3/3]

std::vector< SpellPowerCost > SpellInfo::CalcPowerCost ( WorldObject const *  caster,
SpellSchoolMask  schoolMask,
Spell spell = nullptr 
) const

Definition at line 4225 of file SpellInfo.cpp.

4226{
4227 std::vector<SpellPowerCost> costs;
4228 if (caster->IsUnit())
4229 {
4230 costs.reserve(MAX_POWERS_PER_SPELL);
4231
4232 auto getOrCreatePowerCost = [&](Powers powerType) -> SpellPowerCost&
4233 {
4234 auto itr = std::find_if(costs.begin(), costs.end(), [powerType](SpellPowerCost const& cost)
4235 {
4236 return cost.Power == powerType;
4237 });
4238 if (itr != costs.end())
4239 return *itr;
4240
4241 return costs.emplace_back<SpellPowerCost>({ .Power = powerType, .Amount = 0 });
4242 };
4243
4244 for (SpellPowerEntry const* power : PowerCosts)
4245 {
4246 if (!power)
4247 continue;
4248
4249 if (Optional<SpellPowerCost> cost = CalcPowerCost(power, false, caster, schoolMask, spell))
4250 getOrCreatePowerCost(cost->Power).Amount += cost->Amount;
4251
4252 if (Optional<SpellPowerCost> optionalCost = CalcPowerCost(power, true, caster, schoolMask, spell))
4253 {
4254 SpellPowerCost& cost = getOrCreatePowerCost(optionalCost->Power);
4255 int32 remainingPower = caster->ToUnit()->GetPower(optionalCost->Power) - cost.Amount;
4256 if (remainingPower > 0)
4257 cost.Amount += std::min(optionalCost->Amount, remainingPower);
4258 }
4259 }
4260 }
4261
4262 return costs;
4263}
constexpr std::size_t MAX_POWERS_PER_SPELL
Definition: DBCEnums.h:1983
+ Here is the call graph for this function:

◆ CalcProcPPM()

float SpellInfo::CalcProcPPM ( Unit caster,
int32  itemLevel 
) const

Definition at line 4331 of file SpellInfo.cpp.

4332{
4333 float ppm = ProcBasePPM;
4334 if (!caster)
4335 return ppm;
4336
4337 for (SpellProcsPerMinuteModEntry const* mod : ProcPPMMods)
4338 {
4339 switch (mod->Type)
4340 {
4342 {
4343 ppm *= 1.0f + CalcPPMHasteMod(mod, caster);
4344 break;
4345 }
4346 case SPELL_PPM_MOD_CRIT:
4347 {
4348 ppm *= 1.0f + CalcPPMCritMod(mod, caster);
4349 break;
4350 }
4352 {
4353 if (caster->GetClassMask() & mod->Param)
4354 ppm *= 1.0f + mod->Coeff;
4355 break;
4356 }
4357 case SPELL_PPM_MOD_SPEC:
4358 {
4359 if (Player* plrCaster = caster->ToPlayer())
4360 if (plrCaster->GetPrimarySpecialization() == ChrSpecialization(mod->Param))
4361 ppm *= 1.0f + mod->Coeff;
4362 break;
4363 }
4364 case SPELL_PPM_MOD_RACE:
4365 {
4366 if (caster->GetRaceMask() & mod->Param)
4367 ppm *= 1.0f + mod->Coeff;
4368 break;
4369 }
4371 {
4372 ppm *= 1.0f + CalcPPMItemLevelMod(mod, itemLevel);
4373 break;
4374 }
4376 {
4377 if (caster->GetMap()->IsBattlegroundOrArena())
4378 ppm *= 1.0f + mod->Coeff;
4379 break;
4380 }
4381 default:
4382 break;
4383 }
4384 }
4385
4386 return ppm;
4387}
ChrSpecialization
Definition: DBCEnums.h:355
@ SPELL_PPM_MOD_CRIT
Definition: DBCEnums.h:1975
@ SPELL_PPM_MOD_ITEM_LEVEL
Definition: DBCEnums.h:1979
@ SPELL_PPM_MOD_CLASS
Definition: DBCEnums.h:1976
@ SPELL_PPM_MOD_SPEC
Definition: DBCEnums.h:1977
@ SPELL_PPM_MOD_RACE
Definition: DBCEnums.h:1978
@ SPELL_PPM_MOD_HASTE
Definition: DBCEnums.h:1974
@ SPELL_PPM_MOD_BATTLEGROUND
Definition: DBCEnums.h:1980
float CalcPPMHasteMod(SpellProcsPerMinuteModEntry const *mod, Unit *caster)
Definition: SpellInfo.cpp:4265
float CalcPPMCritMod(SpellProcsPerMinuteModEntry const *mod, Unit *caster)
Definition: SpellInfo.cpp:4291
float CalcPPMItemLevelMod(SpellProcsPerMinuteModEntry const *mod, int32 itemLevel)
Definition: SpellInfo.cpp:4318
bool IsBattlegroundOrArena() const
Definition: Map.cpp:3286
static Player * ToPlayer(Object *o)
Definition: Object.h:200
uint32 GetClassMask() const
Definition: Unit.h:874
uint64 GetRaceMask() const
Definition: Unit.h:871
Map * GetMap() const
Definition: Object.h:604
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ CanBeInterrupted()

bool SpellInfo::CanBeInterrupted ( WorldObject const *  interruptCaster,
Unit const *  interruptTarget,
bool  ignoreImmunity = false 
) const

Definition at line 1443 of file SpellInfo.cpp.

1444{
1446 || HasChannelInterruptFlag(SpellAuraInterruptFlags::Damage | SpellAuraInterruptFlags::EnteringCombat)
1447 || (interruptTarget->IsPlayer() && InterruptFlags.HasFlag(SpellInterruptFlags::DamageCancelsPlayerOnly))
1448 || InterruptFlags.HasFlag(SpellInterruptFlags::DamageCancels)
1449 || (interruptCaster && interruptCaster->IsUnit() && interruptCaster->ToUnit()->HasAuraTypeWithMiscvalue(SPELL_AURA_ALLOW_INTERRUPT_SPELL, Id))
1450 || ((!(interruptTarget->GetMechanicImmunityMask() & (1 << MECHANIC_INTERRUPT)) || ignoreImmunity)
1451 && !interruptTarget->HasAuraTypeWithAffectMask(SPELL_AURA_PREVENT_INTERRUPT, this)
1453}
@ SPELL_ATTR7_NO_UI_NOT_INTERRUPTIBLE
@ SPELL_PREVENTION_TYPE_SILENCE
@ SPELL_AURA_PREVENT_INTERRUPT
@ SPELL_AURA_ALLOW_INTERRUPT_SPELL
constexpr bool HasFlag(T flag) const
Definition: EnumFlag.h:106
bool HasChannelInterruptFlag(SpellAuraInterruptFlags flag) const
Definition: SpellInfo.h:472
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ CanBeUsedInCombat()

bool SpellInfo::CanBeUsedInCombat ( Unit const *  caster) const

Definition at line 1693 of file SpellInfo.cpp.

1694{
1696 || (caster->HasAuraType(SPELL_AURA_ALLOW_MOUNT_IN_COMBAT) && HasAura(SPELL_AURA_MOUNTED));
1697}
@ SPELL_ATTR0_NOT_IN_COMBAT_ONLY_PEACEFUL
@ SPELL_AURA_ALLOW_MOUNT_IN_COMBAT
@ SPELL_AURA_MOUNTED
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ CanDispelAura()

bool SpellInfo::CanDispelAura ( SpellInfo const *  auraSpellInfo) const

Definition at line 1858 of file SpellInfo.cpp.

1859{
1860 // These auras (like Divine Shield) can't be dispelled
1861 if (auraSpellInfo->HasAttribute(SPELL_ATTR0_NO_IMMUNITIES))
1862 return false;
1863
1864 // These spells (like Mass Dispel) can dispel all auras
1866 return true;
1867
1868 // These auras (Cyclone for example) are not dispelable
1869 if ((auraSpellInfo->HasAttribute(SPELL_ATTR1_IMMUNITY_TO_HOSTILE_AND_FRIENDLY_EFFECTS) && auraSpellInfo->Mechanic != MECHANIC_NONE)
1870 || auraSpellInfo->HasAttribute(SPELL_ATTR2_NO_SCHOOL_IMMUNITIES))
1871 return false;
1872
1873 return true;
1874}
@ SPELL_ATTR2_NO_SCHOOL_IMMUNITIES
@ SPELL_ATTR1_IMMUNITY_TO_HOSTILE_AND_FRIENDLY_EFFECTS
@ MECHANIC_NONE
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ CanPierceImmuneAura()

bool SpellInfo::CanPierceImmuneAura ( SpellInfo const *  auraSpellInfo) const

Definition at line 1831 of file SpellInfo.cpp.

1832{
1833 // aura can't be pierced
1834 if (!auraSpellInfo || auraSpellInfo->HasAttribute(SPELL_ATTR0_NO_IMMUNITIES))
1835 return false;
1836
1837 // these spells pierce all available spells (Resurrection Sickness for example)
1839 return true;
1840
1841 // these spells (Cyclone for example) can pierce all...
1843 {
1844 // ...but not these (Divine shield, Ice block, Cyclone and Banish for example)
1845 if (auraSpellInfo->Mechanic != MECHANIC_IMMUNE_SHIELD &&
1846 auraSpellInfo->Mechanic != MECHANIC_INVULNERABILITY &&
1847 (auraSpellInfo->Mechanic != MECHANIC_BANISH || (IsRankOf(auraSpellInfo) && auraSpellInfo->Dispel != DISPEL_NONE))) // Banish shouldn't be immune to itself, but Cyclone should
1848 return true;
1849 }
1850
1851 // Dispels other auras on immunity, check if this spell makes the unit immune to aura
1853 return true;
1854
1855 return false;
1856}
@ MECHANIC_INVULNERABILITY
@ MECHANIC_BANISH
@ MECHANIC_IMMUNE_SHIELD
@ DISPEL_NONE
bool IsRankOf(SpellInfo const *spellInfo) const
Definition: SpellInfo.cpp:4470
bool CanSpellProvideImmunityAgainstAura(SpellInfo const *auraSpellInfo) const
Definition: SpellInfo.cpp:3738
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ CanSpellProvideImmunityAgainstAura()

bool SpellInfo::CanSpellProvideImmunityAgainstAura ( SpellInfo const *  auraSpellInfo) const

Definition at line 3738 of file SpellInfo.cpp.

3739{
3740 if (!auraSpellInfo)
3741 return false;
3742
3743 for (SpellEffectInfo const& effectInfo : _effects)
3744 {
3745 if (!effectInfo.IsEffect())
3746 continue;
3747
3748 SpellEffectInfo::ImmunityInfo const* immuneInfo = effectInfo.GetImmunityInfo();
3749 if (!immuneInfo)
3750 continue;
3751
3752 if (!auraSpellInfo->HasAttribute(SPELL_ATTR1_IMMUNITY_TO_HOSTILE_AND_FRIENDLY_EFFECTS) && !auraSpellInfo->HasAttribute(SPELL_ATTR2_NO_SCHOOL_IMMUNITIES))
3753 {
3754 if (uint32 schoolImmunity = immuneInfo->SchoolImmuneMask)
3755 if ((auraSpellInfo->SchoolMask & schoolImmunity) != 0)
3756 return true;
3757 }
3758
3759 if (uint64 mechanicImmunity = immuneInfo->MechanicImmuneMask)
3760 if ((mechanicImmunity & (UI64LIT(1) << auraSpellInfo->Mechanic)) != 0)
3761 return true;
3762
3763 if (uint32 dispelImmunity = immuneInfo->DispelImmune)
3764 if (auraSpellInfo->Dispel == dispelImmunity)
3765 return true;
3766
3767 bool immuneToAllEffects = true;
3768 for (SpellEffectInfo const& auraSpellEffectInfo : auraSpellInfo->GetEffects())
3769 {
3770 if (!auraSpellEffectInfo.IsEffect())
3771 continue;
3772
3773 auto spellImmuneItr = immuneInfo->SpellEffectImmune.find(auraSpellEffectInfo.Effect);
3774 if (spellImmuneItr == immuneInfo->SpellEffectImmune.end())
3775 {
3776 immuneToAllEffects = false;
3777 break;
3778 }
3779
3780 if (uint32 mechanic = auraSpellEffectInfo.Mechanic)
3781 {
3782 if (!(immuneInfo->MechanicImmuneMask & (UI64LIT(1) << mechanic)))
3783 {
3784 immuneToAllEffects = false;
3785 break;
3786 }
3787 }
3788
3789 if (!auraSpellInfo->HasAttribute(SPELL_ATTR3_ALWAYS_HIT))
3790 {
3791 if (AuraType auraName = auraSpellEffectInfo.ApplyAuraName)
3792 {
3793 bool isImmuneToAuraEffectApply = false;
3794 auto auraImmuneItr = immuneInfo->AuraTypeImmune.find(auraName);
3795 if (auraImmuneItr != immuneInfo->AuraTypeImmune.end())
3796 isImmuneToAuraEffectApply = true;
3797
3798 if (!isImmuneToAuraEffectApply && !auraSpellInfo->IsPositiveEffect(auraSpellEffectInfo.EffectIndex) && !auraSpellInfo->HasAttribute(SPELL_ATTR2_NO_SCHOOL_IMMUNITIES))
3799 {
3800 if (uint32 applyHarmfulAuraImmunityMask = immuneInfo->ApplyHarmfulAuraImmuneMask)
3801 if ((auraSpellInfo->GetSchoolMask() & applyHarmfulAuraImmunityMask) != 0)
3802 isImmuneToAuraEffectApply = true;
3803 }
3804
3805 if (!isImmuneToAuraEffectApply)
3806 {
3807 immuneToAllEffects = false;
3808 break;
3809 }
3810 }
3811 }
3812 }
3813
3814 if (immuneToAllEffects)
3815 return true;
3816 }
3817
3818 return false;
3819}
@ SPELL_ATTR3_ALWAYS_HIT
auto find(Key const &value) const
Definition: FlatSet.h:41
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ CheckExplicitTarget()

SpellCastResult SpellInfo::CheckExplicitTarget ( WorldObject const *  caster,
WorldObject const *  target,
Item const *  itemTarget = nullptr 
) const

Definition at line 2345 of file SpellInfo.cpp.

2346{
2347 uint32 neededTargets = GetExplicitTargetMask();
2348 if (!target)
2349 {
2351 if (!(neededTargets & TARGET_FLAG_GAMEOBJECT_ITEM) || !itemTarget)
2353 return SPELL_CAST_OK;
2354 }
2355
2356 if (Unit const* unitTarget = target->ToUnit())
2357 {
2359 {
2360 Unit const* unitCaster = caster->ToUnit();
2361 if (neededTargets & TARGET_FLAG_UNIT_ENEMY)
2362 if (caster->IsValidAttackTarget(unitTarget, this))
2363 return SPELL_CAST_OK;
2364 if ((neededTargets & TARGET_FLAG_UNIT_ALLY)
2365 || ((neededTargets & TARGET_FLAG_UNIT_PARTY) && unitCaster && unitCaster->IsInPartyWith(unitTarget))
2366 || ((neededTargets & TARGET_FLAG_UNIT_RAID) && unitCaster && unitCaster->IsInRaidWith(unitTarget)))
2367 if (caster->IsValidAssistTarget(unitTarget, this))
2368 return SPELL_CAST_OK;
2369 if ((neededTargets & TARGET_FLAG_UNIT_MINIPET) && unitCaster)
2370 if (unitTarget->GetGUID() == unitCaster->GetCritterGUID())
2371 return SPELL_CAST_OK;
2372 if ((neededTargets & TARGET_FLAG_UNIT_PASSENGER) && unitCaster)
2373 if (unitTarget->IsOnVehicle(unitCaster))
2374 return SPELL_CAST_OK;
2376 }
2377 }
2378 return SPELL_CAST_OK;
2379}
@ SPELL_FAILED_BAD_TARGETS
@ SPELL_CAST_OK
@ TARGET_FLAG_UNIT_RAID
Definition: SpellDefines.h:282
@ TARGET_FLAG_UNIT_ENEMY
Definition: SpellDefines.h:287
@ TARGET_FLAG_UNIT_MINIPET
Definition: SpellDefines.h:296
@ TARGET_FLAG_UNIT_PASSENGER
Definition: SpellDefines.h:300
@ TARGET_FLAG_GAMEOBJECT_ITEM
Definition: SpellDefines.h:294
@ TARGET_FLAG_UNIT_ALLY
Definition: SpellDefines.h:288
@ TARGET_FLAG_GAMEOBJECT_MASK
Definition: SpellDefines.h:309
@ TARGET_FLAG_UNIT_PARTY
Definition: SpellDefines.h:283
uint32 GetExplicitTargetMask() const
Definition: SpellInfo.cpp:2519
ObjectGuid GetCritterGUID() const
Definition: Unit.h:1287
bool IsInRaidWith(Unit const *unit) const
Definition: Unit.cpp:11626
bool IsInPartyWith(Unit const *unit) const
Definition: Unit.cpp:11607
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ CheckLocation()

SpellCastResult SpellInfo::CheckLocation ( uint32  map_id,
uint32  zone_id,
uint32  area_id,
Player const *  player = nullptr 
) const

Definition at line 1985 of file SpellInfo.cpp.

1986{
1987 // normal case
1988 if (RequiredAreasID > 0)
1989 {
1990 bool found = false;
1991 std::vector<uint32> areaGroupMembers = sDB2Manager.GetAreasForGroup(RequiredAreasID);
1992 for (uint32 areaId : areaGroupMembers)
1993 {
1994 if (DB2Manager::IsInArea(area_id, areaId))
1995 {
1996 found = true;
1997 break;
1998 }
1999 }
2000
2001 if (!found)
2003 }
2004
2005 // continent limitation (virtual continent)
2007 {
2008 EnumFlag<AreaMountFlags> mountFlags = AreaMountFlags::None;
2009 if (player && player->HasAuraType(SPELL_AURA_MOUNT_RESTRICTIONS))
2010 {
2011 for (AuraEffect const* auraEffect : player->GetAuraEffectsByType(SPELL_AURA_MOUNT_RESTRICTIONS))
2012 mountFlags |= AreaMountFlags(auraEffect->GetMiscValue());
2013 }
2014 else if (AreaTableEntry const* areaTable = sAreaTableStore.LookupEntry(area_id))
2015 mountFlags = areaTable->GetMountFlags();
2016
2017 if (!(mountFlags.HasFlag(AreaMountFlags::AllowFlyingMounts)))
2019
2020 if (player)
2021 {
2022 uint32 mapToCheck = map_id;
2023 if (MapEntry const* mapEntry = sMapStore.LookupEntry(map_id))
2024 mapToCheck = mapEntry->CosmeticParentMapID;
2025
2026 if ((mapToCheck == 1116 || mapToCheck == 1464) && !player->HasSpell(191645)) // Draenor Pathfinder
2028 else if (mapToCheck == 1220 && !player->HasSpell(233368)) // Broken Isles Pathfinder
2030 else if ((mapToCheck == 1642 || mapToCheck == 1643) && !player->HasSpell(278833)) // Battle for Azeroth Pathfinder
2032 }
2033 }
2034
2035 // raid instance limitation
2037 {
2038 MapEntry const* mapEntry = sMapStore.LookupEntry(map_id);
2039 if (!mapEntry || mapEntry->IsRaid())
2041 }
2042
2044 {
2045 MapEntry const* mapEntry = sMapStore.LookupEntry(map_id);
2046 if (!mapEntry || !mapEntry->IsDungeon())
2048 }
2049
2051 {
2052 MapEntry const* mapEntry = sMapStore.LookupEntry(map_id);
2053 if (!mapEntry || mapEntry->IsBattleground())
2055 }
2056
2057 // DB base check (if non empty then must fit at least single for allow)
2058 SpellAreaMapBounds saBounds = sSpellMgr->GetSpellAreaMapBounds(Id);
2059 if (saBounds.first != saBounds.second)
2060 {
2061 for (SpellAreaMap::const_iterator itr = saBounds.first; itr != saBounds.second; ++itr)
2062 {
2063 if (itr->second.IsFitToRequirements(player, zone_id, area_id))
2064 return SPELL_CAST_OK;
2065 }
2067 }
2068
2069 // bg spell checks
2070 switch (Id)
2071 {
2072 case 23333: // Warsong Flag
2073 case 23335: // Silverwing Flag
2074 return map_id == 489 && player && player->InBattleground() ? SPELL_CAST_OK : SPELL_FAILED_REQUIRES_AREA;
2075 case 2584: // Waiting to Resurrect
2076 case 42792: // Recently Dropped Flag
2077 case 43681: // Inactive
2078 case 44535: // Spirit Heal (mana)
2079 {
2080 MapEntry const* mapEntry = sMapStore.LookupEntry(map_id);
2081 if (!mapEntry)
2083
2084 return zone_id == AREA_WINTERGRASP || (mapEntry->IsBattleground() && player && player->InBattleground()) ? SPELL_CAST_OK : SPELL_FAILED_REQUIRES_AREA;
2085 }
2086 case 44521: // Preparation
2087 {
2088 if (!player)
2090
2091 MapEntry const* mapEntry = sMapStore.LookupEntry(map_id);
2092 if (!mapEntry)
2094
2095 if (!mapEntry->IsBattleground())
2097
2098 Battleground* bg = player->GetBattleground();
2100 }
2101 case 32724: // Gold Team (Alliance)
2102 case 32725: // Green Team (Alliance)
2103 case 35774: // Gold Team (Horde)
2104 case 35775: // Green Team (Horde)
2105 {
2106 MapEntry const* mapEntry = sMapStore.LookupEntry(map_id);
2107 if (!mapEntry)
2109
2110 return mapEntry->IsBattleArena() && player && player->InBattleground() ? SPELL_CAST_OK : SPELL_FAILED_REQUIRES_AREA;
2111 }
2112 case 32727: // Arena Preparation
2113 {
2114 if (!player)
2116
2117 MapEntry const* mapEntry = sMapStore.LookupEntry(map_id);
2118 if (!mapEntry)
2120
2121 if (!mapEntry->IsBattleArena())
2123
2124 Battleground* bg = player->GetBattleground();
2126 }
2127 }
2128
2129 // aura limitations
2130 if (player)
2131 {
2132 for (SpellEffectInfo const& effect : GetEffects())
2133 {
2134 if (!effect.IsAura())
2135 continue;
2136
2137 switch (effect.ApplyAuraName)
2138 {
2140 {
2141 if (SpellShapeshiftFormEntry const* spellShapeshiftForm = sSpellShapeshiftFormStore.LookupEntry(effect.MiscValue))
2142 if (uint32 mountType = spellShapeshiftForm->MountTypeID)
2143 if (!player->GetMountCapability(mountType))
2144 return SPELL_FAILED_NOT_HERE;
2145 break;
2146 }
2147 case SPELL_AURA_MOUNTED:
2148 {
2149 uint32 mountType = effect.MiscValueB;
2150 if (MountEntry const* mountEntry = sDB2Manager.GetMount(Id))
2151 mountType = mountEntry->MountTypeID;
2152 if (mountType && !player->GetMountCapability(mountType))
2153 return SPELL_FAILED_NOT_HERE;
2154 break;
2155 }
2156 default:
2157 break;
2158 }
2159 }
2160 }
2161
2162 return SPELL_CAST_OK;
2163}
@ STATUS_WAIT_JOIN
Definition: Battleground.h:164
DB2Storage< MapEntry > sMapStore("Map.db2", &MapLoadInfo::Instance)
DB2Storage< AreaTableEntry > sAreaTableStore("AreaTable.db2", &AreaTableLoadInfo::Instance)
AreaMountFlags
Definition: DBCEnums.h:167
@ SPELL_FAILED_NOT_HERE
@ SPELL_FAILED_INCORRECT_AREA
@ SPELL_FAILED_NOT_IN_BATTLEGROUND
@ SPELL_FAILED_TARGET_NOT_IN_INSTANCE
@ SPELL_FAILED_NOT_IN_RAID_INSTANCE
@ SPELL_FAILED_REQUIRES_AREA
@ AREA_WINTERGRASP
@ SPELL_ATTR4_ONLY_FLYING_AREAS
@ SPELL_ATTR8_NOT_IN_BATTLEGROUND
@ SPELL_ATTR8_REMOVE_OUTSIDE_DUNGEONS_AND_RAIDS
@ SPELL_ATTR6_NOT_IN_RAID_INSTANCES
@ SPELL_AURA_MOD_SHAPESHIFT
@ SPELL_AURA_MOUNT_RESTRICTIONS
std::pair< SpellAreaMap::const_iterator, SpellAreaMap::const_iterator > SpellAreaMapBounds
Definition: SpellMgr.h:552
#define sSpellMgr
Definition: SpellMgr.h:825
BattlegroundStatus GetStatus() const
Definition: Battleground.h:282
static bool IsInArea(uint32 objectAreaId, uint32 areaId)
Definition: DB2Stores.cpp:1889
bool IsBattleground() const
bool IsDungeon() const
bool IsRaid() const
bool IsBattleArena() const
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ CheckShapeshift()

SpellCastResult SpellInfo::CheckShapeshift ( uint32  form) const

Definition at line 1936 of file SpellInfo.cpp.

1937{
1938 // talents that learn spells can have stance requirements that need ignore
1939 // (this requirement only for client-side stance show in talent description)
1940 /* TODO: 6.x fix this in proper way (probably spell flags/attributes?)
1941 if (GetTalentSpellCost(Id) > 0 && HasEffect(SPELL_EFFECT_LEARN_SPELL))
1942 return SPELL_CAST_OK;*/
1943
1944 //if (HasAttribute(SPELL_ATTR13_ACTIVATES_REQUIRED_SHAPESHIFT))
1945 // return SPELL_CAST_OK;
1946
1947 uint64 stanceMask = (form ? UI64LIT(1) << (form - 1) : 0);
1948
1949 if (stanceMask & StancesNot) // can explicitly not be cast in this stance
1951
1952 if (stanceMask & Stances) // can explicitly be cast in this stance
1953 return SPELL_CAST_OK;
1954
1955 bool actAsShifted = false;
1956 SpellShapeshiftFormEntry const* shapeInfo = nullptr;
1957 if (form > 0)
1958 {
1959 shapeInfo = sSpellShapeshiftFormStore.LookupEntry(form);
1960 if (!shapeInfo)
1961 {
1962 TC_LOG_ERROR("spells", "GetErrorAtShapeshiftedCast: unknown shapeshift {}", form);
1963 return SPELL_CAST_OK;
1964 }
1965 actAsShifted = !shapeInfo->GetFlags().HasFlag(SpellShapeshiftFormFlags::Stance);
1966 }
1967
1968 if (actAsShifted)
1969 {
1970 if (HasAttribute(SPELL_ATTR0_NOT_SHAPESHIFTED) || (shapeInfo && shapeInfo->GetFlags().HasFlag(SpellShapeshiftFormFlags::CanOnlyCastShapeshiftSpells))) // not while shapeshifted
1972 else if (Stances != 0) // needs other shapeshift
1974 }
1975 else
1976 {
1977 // needs shapeshift
1980 }
1981
1982 return SPELL_CAST_OK;
1983}
@ SPELL_ATTR2_ALLOW_WHILE_NOT_SHAPESHIFTED_CASTER_FORM
@ SPELL_ATTR0_NOT_SHAPESHIFTED
@ SPELL_FAILED_ONLY_SHAPESHIFT
@ SPELL_FAILED_NOT_SHAPESHIFT
EnumFlag< SpellShapeshiftFormFlags > GetFlags() const
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ CheckTarget()

SpellCastResult SpellInfo::CheckTarget ( WorldObject const *  caster,
WorldObject const *  target,
bool  implicit = true 
) const

Definition at line 2165 of file SpellInfo.cpp.

2166{
2167 if (HasAttribute(SPELL_ATTR1_EXCLUDE_CASTER) && caster == target)
2169
2170 // check visibility - ignore invisibility/stealth for implicit (area) targets
2171 if (!HasAttribute(SPELL_ATTR6_IGNORE_PHASE_SHIFT) && !caster->CanSeeOrDetect(target, implicit))
2173
2174 Unit const* unitTarget = target->ToUnit();
2175
2177 {
2178 auto getCreatorOrSelf = [](WorldObject const* obj)
2179 {
2180 ObjectGuid creator = obj->GetCreatorGUID();
2181 if (creator.IsEmpty())
2182 creator = obj->GetGUID();
2183
2184 return creator;
2185 };
2186 if (getCreatorOrSelf(caster) != getCreatorOrSelf(target))
2188 }
2189
2190 // creature/player specific target checks
2191 if (unitTarget)
2192 {
2193 // spells cannot be cast if target has a pet in combat either
2196
2197 // only spells with SPELL_ATTR3_ONLY_TARGET_GHOSTS can target ghosts
2199 {
2202 else
2204 }
2205
2206 if (caster != unitTarget)
2207 {
2208 if (caster->GetTypeId() == TYPEID_PLAYER)
2209 {
2210 // Do not allow these spells to target creatures not tapped by us (Banish, Polymorph, many quest spells)
2212 if (Creature const* targetCreature = unitTarget->ToCreature())
2213 if (targetCreature->hasLootRecipient() && !targetCreature->isTappedBy(caster->ToPlayer()))
2215
2217 {
2218 Creature const* targetCreature = unitTarget->ToCreature();
2219 if (!targetCreature)
2221
2222 if (!targetCreature->CanHaveLoot() || !LootTemplates_Pickpocketing.HaveLootFor(targetCreature->GetCreatureDifficulty()->PickPocketLootID))
2224 }
2225
2226 // Not allow disarm unarmed player
2228 {
2229 if (unitTarget->GetTypeId() == TYPEID_PLAYER)
2230 {
2231 Player const* player = unitTarget->ToPlayer();
2232 if (!player->GetWeaponForAttack(BASE_ATTACK) || !player->IsUseEquipedWeapon(true))
2234 }
2235 else if (!unitTarget->GetVirtualItemId(0))
2237 }
2238 }
2239 }
2240
2242 if (!unitTarget->IsSummon() || unitTarget->ToTempSummon()->GetSummonerGUID() != caster->GetGUID())
2244 }
2245 // corpse specific target checks
2246 else if (Corpse const* corpseTarget = target->ToCorpse())
2247 {
2248 // cannot target bare bones
2249 if (corpseTarget->GetType() == CORPSE_BONES)
2251 // we have to use owner for some checks (aura preventing resurrection for example)
2252 if (Player* owner = ObjectAccessor::FindPlayer(corpseTarget->GetOwnerGUID()))
2253 unitTarget = owner;
2254 // we're not interested in corpses without owner
2255 else
2257 }
2258 // other types of objects - always valid
2259 else return SPELL_CAST_OK;
2260
2261 // corpseOwner and unit specific target checks
2262 if (!unitTarget->IsPlayer())
2263 {
2266
2269 }
2272
2273 if (!IsAllowingDeadTarget() && !unitTarget->IsAlive())
2275
2276 // check this flag only for implicit targets (chain and area), allow to explicitly target units for spells like Shield of Righteousness
2279
2280 // checked in Unit::IsValidAttack/AssistTarget, shouldn't be checked for ENTRY targets
2281 //if (!HasAttribute(SPELL_ATTR6_CAN_TARGET_UNTARGETABLE) && target->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNINTERACTIBLE))
2282 // return SPELL_FAILED_BAD_TARGETS;
2283
2284 if (!CheckTargetCreatureType(unitTarget))
2285 {
2286 if (target->GetTypeId() == TYPEID_PLAYER)
2288 else
2290 }
2291
2292 // check GM mode and GM invisibility - only for player casts (npc casts are controlled by AI) and negative spells
2293 if (unitTarget != caster && (caster->GetAffectingPlayer() || !IsPositive()) && unitTarget->GetTypeId() == TYPEID_PLAYER)
2294 {
2295 if (!unitTarget->ToPlayer()->IsVisible())
2297
2298 if (unitTarget->ToPlayer()->IsGameMaster())
2300 }
2301
2302 // not allow casting on flying player
2305
2306 /* TARGET_UNIT_MASTER gets blocked here for passengers, because the whole idea of this check is to
2307 not allow passengers to be implicitly hit by spells, however this target type should be an exception,
2308 if this is left it kills spells that award kill credit from vehicle to master (few spells),
2309 the use of these 2 covers passenger target check, logically, if vehicle cast this to master it should always hit
2310 him, because it would be it's passenger, there's no such case where this gets to fail legitimacy, this problem
2311 cannot be solved from within the check in other way since target type cannot be called for the spell currently
2312 Spell examples: [ID - 52864 Devour Water, ID - 52862 Devour Wind, ID - 49370 Wyrmrest Defender: Destabilize Azure Dragonshrine Effect] */
2313 if (Unit const* unitCaster = caster->ToUnit())
2314 {
2315 if (!unitCaster->IsVehicle() && !(unitCaster->GetCharmerOrOwner() == target))
2316 {
2317 if (TargetAuraState && !unitTarget->HasAuraState(AuraStateType(TargetAuraState), this, unitCaster))
2319
2320 if (ExcludeTargetAuraState && unitTarget->HasAuraState(AuraStateType(ExcludeTargetAuraState), this, unitCaster))
2322 }
2323 }
2324
2325 if (TargetAuraSpell && !unitTarget->HasAura(TargetAuraSpell))
2327
2330
2334
2336 if (Map* map = caster->GetMap())
2337 if (InstanceMap* iMap = map->ToInstanceMap())
2338 if (InstanceScript* instance = iMap->GetInstanceScript())
2339 if (instance->GetCombatResurrectionCharges() == 0 && instance->IsEncounterInProgress())
2341
2342 return SPELL_CAST_OK;
2343}
@ CORPSE_BONES
Definition: Corpse.h:31
LootStore LootTemplates_Pickpocketing("pickpocketing_loot_template", "creature pickpocket lootid", true)
@ TYPEID_PLAYER
Definition: ObjectGuid.h:41
@ SPELL_ATTR7_BYPASS_NO_RESURRECT_AURA
@ SPELL_ATTR5_NOT_ON_PLAYER_CONTROLLED_NPC
@ SPELL_ATTR5_NOT_ON_PLAYER
@ SPELL_ATTR2_CANNOT_CAST_ON_TAPPED
@ SPELL_ATTR1_EXCLUDE_CASTER
@ SPELL_ATTR1_ONLY_PEACEFUL_TARGETS
@ SPELL_ATTR3_ONLY_ON_GHOSTS
@ SPELL_ATTR3_ONLY_ON_PLAYER
@ SPELL_EFFECT_SELF_RESURRECT
@ SPELL_EFFECT_RESURRECT
@ MECHANIC_DISARM
@ SPELL_FAILED_TARGET_NOT_PLAYER
@ SPELL_FAILED_TARGET_NO_POCKETS
@ SPELL_FAILED_TARGET_IS_PLAYER
@ SPELL_FAILED_CANT_CAST_ON_TAPPED
@ SPELL_FAILED_TARGET_AURASTATE
@ SPELL_FAILED_BM_OR_INVISGOD
@ SPELL_FAILED_TARGET_IS_PLAYER_CONTROLLED
@ SPELL_FAILED_TARGETS_DEAD
@ SPELL_FAILED_TARGET_NOT_GHOST
@ SPELL_FAILED_TARGET_CANNOT_BE_RESURRECTED
@ SPELL_FAILED_TARGET_NO_WEAPONS
@ SPELL_FAILED_TARGET_AFFECTING_COMBAT
@ SPELL_ATTR8_ENFORCE_IN_COMBAT_RESSURECTION_LIMIT
@ SPELL_ATTR8_ONLY_TARGET_IF_SAME_CREATOR
@ SPELL_ATTR8_ONLY_TARGET_OWN_SUMMONS
@ SPELL_ATTR6_DO_NOT_CHAIN_TO_CROWD_CONTROLLED_TARGETS
@ SPELL_ATTR6_IGNORE_PHASE_SHIFT
@ SPELL_AURA_PREVENT_RESURRECTION
@ SPELL_AURA_GHOST
@ SPELL_ATTR0_CU_ALLOW_INFLIGHT_TARGET
Definition: SpellInfo.h:166
@ SPELL_ATTR0_CU_PICKPOCKET
Definition: SpellInfo.h:158
@ UNIT_FLAG_PET_IN_COMBAT
Definition: UnitDefines.h:155
@ UNIT_STATE_IN_FLIGHT
Definition: Unit.h:260
Definition: Corpse.h:53
CreatureDifficulty const * GetCreatureDifficulty() const
Definition: Creature.h:219
bool CanHaveLoot() const
Definition: Creature.h:240
bool HaveLootFor(uint32 loot_id) const
Definition: LootMgr.h:83
Definition: Map.h:187
InstanceMap * ToInstanceMap()
Definition: Map.h:450
bool IsEmpty() const
Definition: ObjectGuid.h:317
static Creature * ToCreature(Object *o)
Definition: Object.h:206
bool IsPlayer() const
Definition: Object.h:199
TypeID GetTypeId() const
Definition: Object.h:172
static Corpse * ToCorpse(Object *o)
Definition: Object.h:224
bool IsGameMaster() const
Definition: Player.h:1174
Item * GetWeaponForAttack(WeaponAttackType attackType, bool useable=false) const
Definition: Player.cpp:9634
bool IsUseEquipedWeapon(bool mainhand) const
Definition: Player.cpp:13303
bool HasEffect(SpellEffectName effect) const
Definition: SpellInfo.cpp:1381
bool CheckTargetCreatureType(Unit const *target) const
Definition: SpellInfo.cpp:2431
bool IsAllowingDeadTarget() const
Definition: SpellInfo.cpp:1658
ObjectGuid GetSummonerGUID() const
bool HasUnitFlag(UnitFlags flags) const
Definition: Unit.h:952
bool CanFreeMove() const
Definition: Unit.cpp:9161
bool IsAlive() const
Definition: Unit.h:1273
TempSummon * ToTempSummon()
Definition: Unit.h:1863
uint32 GetVirtualItemId(uint32 slot) const
Definition: Unit.cpp:13632
bool IsSummon() const
Definition: Unit.h:858
bool HasAuraState(AuraStateType flag, SpellInfo const *spellProto=nullptr, Unit const *Caster=nullptr) const
Definition: Unit.cpp:5869
bool IsVisible() const
Definition: Unit.cpp:8222
bool HasAuraType(AuraType auraType) const
Definition: Unit.cpp:4583
bool HasUnitState(const uint32 f) const
Definition: Unit.h:852
bool IsInCombat() const
Definition: Unit.h:1162
TC_GAME_API Player * FindPlayer(ObjectGuid const &)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ CheckTargetCreatureType()

bool SpellInfo::CheckTargetCreatureType ( Unit const *  target) const

Definition at line 2431 of file SpellInfo.cpp.

2432{
2433 // Curse of Doom & Exorcism: not find another way to fix spell target check :/
2435 {
2436 // not allow cast at player
2437 if (target->GetTypeId() == TYPEID_PLAYER)
2438 return false;
2439 else
2440 return true;
2441 }
2442
2443 // if target is magnet (i.e Grounding Totem) the check is skipped
2444 if (target->IsMagnet())
2445 return true;
2446
2447 uint32 creatureType = target->GetCreatureTypeMask();
2448 return !TargetCreatureType || !creatureType || (creatureType & TargetCreatureType) || target->HasAuraType(SPELL_AURA_IGNORE_SPELL_CREATURE_TYPE_REQUIREMENTS);
2449}
@ SPELL_AURA_IGNORE_SPELL_CREATURE_TYPE_REQUIREMENTS
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ CheckVehicle()

SpellCastResult SpellInfo::CheckVehicle ( Unit const *  caster) const

Definition at line 2381 of file SpellInfo.cpp.

2382{
2383 // All creatures should be able to cast as passengers freely, restriction and attribute are only for players
2384 if (caster->GetTypeId() != TYPEID_PLAYER)
2385 return SPELL_CAST_OK;
2386
2387 Vehicle* vehicle = caster->GetVehicle();
2388 if (vehicle)
2389 {
2390 uint16 checkMask = 0;
2391 for (SpellEffectInfo const& effect : GetEffects())
2392 {
2393 if (effect.IsAura(SPELL_AURA_MOD_SHAPESHIFT))
2394 {
2395 SpellShapeshiftFormEntry const* shapeShiftFromEntry = sSpellShapeshiftFormStore.LookupEntry(effect.MiscValue);
2396 if (shapeShiftFromEntry && (shapeShiftFromEntry->Flags & 1) == 0) // unk flag
2397 checkMask |= VEHICLE_SEAT_FLAG_UNCONTROLLED;
2398 break;
2399 }
2400 }
2401
2404
2405 if (!checkMask)
2406 checkMask = VEHICLE_SEAT_FLAG_CAN_ATTACK;
2407
2408 VehicleSeatEntry const* vehicleSeat = vehicle->GetSeatForPassenger(caster);
2410 && (vehicleSeat->Flags & checkMask) != checkMask)
2412
2413 // Can only summon uncontrolled minions/guardians when on controlled vehicle
2415 {
2416 for (SpellEffectInfo const& effect : GetEffects())
2417 {
2418 if (!effect.IsEffect(SPELL_EFFECT_SUMMON))
2419 continue;
2420
2421 SummonPropertiesEntry const* props = sSummonPropertiesStore.LookupEntry(effect.MiscValueB);
2422 if (props && props->Control != SUMMON_CATEGORY_WILD)
2424 }
2425 }
2426 }
2427
2428 return SPELL_CAST_OK;
2429}
DB2Storage< SummonPropertiesEntry > sSummonPropertiesStore("SummonProperties.db2", &SummonPropertiesLoadInfo::Instance)
@ VEHICLE_SEAT_FLAG_UNK2
Definition: DBCEnums.h:2445
@ VEHICLE_SEAT_FLAG_CAN_CAST_MOUNT_SPELL
Definition: DBCEnums.h:2427
@ VEHICLE_SEAT_FLAG_CAN_CONTROL
Definition: DBCEnums.h:2426
@ VEHICLE_SEAT_FLAG_UNCONTROLLED
Definition: DBCEnums.h:2428
@ VEHICLE_SEAT_FLAG_CAN_ATTACK
Definition: DBCEnums.h:2429
uint16_t uint16
Definition: Define.h:144
@ SPELL_EFFECT_SUMMON
@ SPELL_ATTR0_ALLOW_WHILE_MOUNTED
@ SPELL_FAILED_CANT_DO_THAT_RIGHT_NOW
@ SUMMON_CATEGORY_WILD
@ SPELL_ATTR6_ALLOW_WHILE_RIDING_VEHICLE
VehicleSeatEntry const * GetSeatForPassenger(Unit const *passenger) const
Returns information on the seat of specified passenger, represented by the format in VehicleSeat....
Definition: Vehicle.cpp:646
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ GetAllEffectsMechanicMask()

uint64 SpellInfo::GetAllEffectsMechanicMask ( ) const

Definition at line 2456 of file SpellInfo.cpp.

2457{
2458 uint64 mask = 0;
2459 if (Mechanic)
2460 mask |= UI64LIT(1) << Mechanic;
2461
2462 for (SpellEffectInfo const& effect : GetEffects())
2463 if (effect.IsEffect() && effect.Mechanic)
2464 mask |= UI64LIT(1) << effect.Mechanic;
2465
2466 return mask;
2467}
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ GetAllowedMechanicMask()

uint64 SpellInfo::GetAllowedMechanicMask ( ) const

Definition at line 3868 of file SpellInfo.cpp.

3869{
3870 return _allowedMechanicMask;
3871}
+ Here is the caller graph for this function:

◆ GetAttackType()

WeaponAttackType SpellInfo::GetAttackType ( ) const

Definition at line 1746 of file SpellInfo.cpp.

1747{
1748 WeaponAttackType result;
1749 switch (DmgClass)
1750 {
1753 result = OFF_ATTACK;
1754 else
1755 result = BASE_ATTACK;
1756 break;
1759 break;
1760 default:
1761 // Wands
1763 result = RANGED_ATTACK;
1764 else
1765 result = BASE_ATTACK;
1766 break;
1767 }
1768
1769 return result;
1770}
@ SPELL_DAMAGE_CLASS_RANGED
@ SPELL_DAMAGE_CLASS_MELEE
@ RANGED_ATTACK
bool IsRangedWeaponSpell() const
Definition: SpellInfo.cpp:1724
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ GetAuraRankForLevel()

SpellInfo const * SpellInfo::GetAuraRankForLevel ( uint8  level) const

Definition at line 4429 of file SpellInfo.cpp.

4430{
4431 // ignore passive spells
4432 if (IsPassive())
4433 return this;
4434
4435 // Client ignores spell with these attributes (sub_53D9D0)
4437 return this;
4438
4439 bool needRankSelection = false;
4440 for (SpellEffectInfo const& effect : GetEffects())
4441 {
4442 if (IsPositiveEffect(effect.EffectIndex) &&
4443 (effect.Effect == SPELL_EFFECT_APPLY_AURA ||
4444 effect.Effect == SPELL_EFFECT_APPLY_AREA_AURA_PARTY ||
4445 effect.Effect == SPELL_EFFECT_APPLY_AREA_AURA_RAID) &&
4446 !effect.Scaling.Coefficient)
4447 {
4448 needRankSelection = true;
4449 break;
4450 }
4451 }
4452
4453 // not required
4454 if (!needRankSelection)
4455 return this;
4456
4457 for (SpellInfo const* nextSpellInfo = this; nextSpellInfo != nullptr; nextSpellInfo = nextSpellInfo->GetPrevRankSpell())
4458 {
4459 // if found appropriate level
4460 if (uint32(level + 10) >= nextSpellInfo->SpellLevel)
4461 return nextSpellInfo;
4462
4463 // one rank less then
4464 }
4465
4466 // not found
4467 return nullptr;
4468}
@ SPELL_ATTR2_ALLOW_LOW_LEVEL_BUFF
@ SPELL_ATTR3_ONLY_PROC_ON_CASTER
@ SPELL_EFFECT_APPLY_AREA_AURA_PARTY
@ SPELL_EFFECT_APPLY_AREA_AURA_RAID
@ SPELL_ATTR0_AURA_IS_DEBUFF
SpellInfo const * GetPrevRankSpell() const
Definition: SpellInfo.cpp:4422
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ GetAuraState()

AuraStateType SpellInfo::GetAuraState ( ) const

Definition at line 2524 of file SpellInfo.cpp.

2525{
2526 return _auraState;
2527}
+ Here is the caller graph for this function:

◆ GetCategory()

uint32 SpellInfo::GetCategory ( ) const

Definition at line 1376 of file SpellInfo.cpp.

1377{
1378 return CategoryId;
1379}
+ Here is the caller graph for this function:

◆ GetDiminishingReturnsGroupForSpell()

DiminishingGroup SpellInfo::GetDiminishingReturnsGroupForSpell ( ) const

Definition at line 3274 of file SpellInfo.cpp.

3275{
3277}
+ Here is the caller graph for this function:

◆ GetDiminishingReturnsGroupType()

DiminishingReturnsType SpellInfo::GetDiminishingReturnsGroupType ( ) const

Definition at line 3279 of file SpellInfo.cpp.

3280{
3282}
+ Here is the caller graph for this function:

◆ GetDiminishingReturnsLimitDuration()

int32 SpellInfo::GetDiminishingReturnsLimitDuration ( ) const

Definition at line 3289 of file SpellInfo.cpp.

3290{
3292}
+ Here is the caller graph for this function:

◆ GetDiminishingReturnsMaxLevel()

DiminishingLevels SpellInfo::GetDiminishingReturnsMaxLevel ( ) const

Definition at line 3284 of file SpellInfo.cpp.

3285{
3287}
+ Here is the caller graph for this function:

◆ GetDispelMask() [1/2]

uint32 SpellInfo::GetDispelMask ( ) const

Definition at line 2505 of file SpellInfo.cpp.

2506{
2508}
DispelType
uint32 GetDispelMask() const
Definition: SpellInfo.cpp:2505
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ GetDispelMask() [2/2]

uint32 SpellInfo::GetDispelMask ( DispelType  type)
static

Definition at line 2510 of file SpellInfo.cpp.

2511{
2512 // If dispel all
2513 if (type == DISPEL_ALL)
2514 return DISPEL_ALL_MASK;
2515 else
2516 return uint32(1 << type);
2517}
#define DISPEL_ALL_MASK
@ DISPEL_ALL

◆ GetDuration()

int32 SpellInfo::GetDuration ( ) const

Definition at line 3920 of file SpellInfo.cpp.

3921{
3922 if (!DurationEntry)
3923 return IsPassive() ? -1 : 0;
3924 return (DurationEntry->Duration == -1) ? -1 : abs(DurationEntry->Duration);
3925}
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ GetEffect()

SpellEffectInfo const & SpellInfo::GetEffect ( SpellEffIndex  index) const
inline

Definition at line 577 of file SpellInfo.h.

577{ ASSERT(index < _effects.size()); return _effects[index]; }
#define ASSERT
Definition: Errors.h:68
+ Here is the caller graph for this function:

◆ GetEffectMechanic()

Mechanics SpellInfo::GetEffectMechanic ( SpellEffIndex  effIndex) const

Definition at line 2494 of file SpellInfo.cpp.

2495{
2496 if (GetEffect(effIndex).IsEffect() && GetEffect(effIndex).Mechanic)
2497 return GetEffect(effIndex).Mechanic;
2498
2499 if (Mechanic)
2500 return Mechanics(Mechanic);
2501
2502 return MECHANIC_NONE;
2503}
Mechanics
Mechanics Mechanic
Definition: SpellInfo.h:229
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ GetEffectMechanicMask()

uint64 SpellInfo::GetEffectMechanicMask ( SpellEffIndex  effIndex) const

Definition at line 2469 of file SpellInfo.cpp.

2470{
2471 uint64 mask = 0;
2472 if (Mechanic)
2473 mask |= UI64LIT(1) << Mechanic;
2474
2475 if (GetEffect(effIndex).IsEffect() && GetEffect(effIndex).Mechanic)
2476 mask |= UI64LIT(1) << GetEffect(effIndex).Mechanic;
2477
2478 return mask;
2479}
+ Here is the call graph for this function:

◆ GetEffects()

std::vector< SpellEffectInfo > const & SpellInfo::GetEffects ( ) const
inline

Definition at line 576 of file SpellInfo.h.

576{ return _effects; }
+ Here is the caller graph for this function:

◆ GetExplicitTargetMask()

uint32 SpellInfo::GetExplicitTargetMask ( ) const

Definition at line 2519 of file SpellInfo.cpp.

2520{
2521 return ExplicitTargetMask;
2522}
+ Here is the caller graph for this function:

◆ GetFirstRankSpell()

SpellInfo const * SpellInfo::GetFirstRankSpell ( ) const

Definition at line 4401 of file SpellInfo.cpp.

4402{
4403 if (!ChainEntry)
4404 return this;
4405 return ChainEntry->first;
4406}
SpellChainNode const * ChainEntry
Definition: SpellInfo.h:426
SpellInfo const * first
Definition: SpellMgr.h:562
+ Here is the caller graph for this function:

◆ GetLastRankSpell()

SpellInfo const * SpellInfo::GetLastRankSpell ( ) const

Definition at line 4408 of file SpellInfo.cpp.

4409{
4410 if (!ChainEntry)
4411 return nullptr;
4412 return ChainEntry->last;
4413}
SpellInfo const * last
Definition: SpellMgr.h:563

◆ GetMaxDuration()

int32 SpellInfo::GetMaxDuration ( ) const

Definition at line 3927 of file SpellInfo.cpp.

3928{
3929 if (!DurationEntry)
3930 return IsPassive() ? -1 : 0;
3931 return (DurationEntry->MaxDuration == -1) ? -1 : abs(DurationEntry->MaxDuration);
3932}
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ GetMaxRange()

float SpellInfo::GetMaxRange ( bool  positive = false,
WorldObject caster = nullptr,
Spell spell = nullptr 
) const

Definition at line 3897 of file SpellInfo.cpp.

3898{
3899 if (!RangeEntry)
3900 return 0.0f;
3901 float range = RangeEntry->RangeMax[positive ? 1 : 0];
3902 if (caster)
3903 if (Player* modOwner = caster->GetSpellModOwner())
3904 modOwner->ApplySpellMod(this, SpellModOp::Range, range, spell);
3905
3906 return range;
3907}
std::array< float, 2 > RangeMax
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ GetMaxTicks()

uint32 SpellInfo::GetMaxTicks ( ) const

Definition at line 3952 of file SpellInfo.cpp.

3953{
3954 uint32 totalTicks = 0;
3955 int32 DotDuration = GetDuration();
3956
3957 for (SpellEffectInfo const& effect : GetEffects())
3958 {
3959 if (effect.IsEffect(SPELL_EFFECT_APPLY_AURA))
3960 {
3961 switch (effect.ApplyAuraName)
3962 {
3977 // skip infinite periodics
3978 if (effect.ApplyAuraPeriod > 0 && DotDuration > 0)
3979 {
3980 totalTicks = static_cast<uint32>(DotDuration) / effect.ApplyAuraPeriod;
3982 ++totalTicks;
3983 }
3984 break;
3985 default:
3986 break;
3987 }
3988 }
3989 }
3990
3991 return totalTicks;
3992}
@ SPELL_ATTR5_EXTRA_INITIAL_PERIOD
@ SPELL_AURA_PERIODIC_DAMAGE
@ SPELL_AURA_PERIODIC_HEALTH_FUNNEL
@ SPELL_AURA_PERIODIC_MANA_LEECH
@ SPELL_AURA_PERIODIC_HEAL
@ SPELL_AURA_PERIODIC_DAMAGE_PERCENT
@ SPELL_AURA_PERIODIC_TRIGGER_SPELL_WITH_VALUE
@ SPELL_AURA_PERIODIC_ENERGIZE
@ SPELL_AURA_PERIODIC_LEECH
@ SPELL_AURA_POWER_BURN
@ SPELL_AURA_PERIODIC_DUMMY
@ SPELL_AURA_PERIODIC_TRIGGER_SPELL_FROM_CLIENT
@ SPELL_AURA_PERIODIC_TRIGGER_SPELL
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ GetMechanicImmunityMask()

uint64 SpellInfo::GetMechanicImmunityMask ( Unit const *  caster) const

Definition at line 3873 of file SpellInfo.cpp.

3874{
3875 uint64 casterMechanicImmunityMask = caster->GetMechanicImmunityMask();
3876 uint64 mechanicImmunityMask = 0;
3877
3878 if (CanBeInterrupted(nullptr, caster, true))
3879 {
3880 if (casterMechanicImmunityMask & (1 << MECHANIC_SILENCE))
3881 mechanicImmunityMask |= (1 << MECHANIC_SILENCE);
3882
3883 if (casterMechanicImmunityMask & (1 << MECHANIC_INTERRUPT))
3884 mechanicImmunityMask |= (1 << MECHANIC_INTERRUPT);
3885 }
3886
3887 return mechanicImmunityMask;
3888}
bool CanBeInterrupted(WorldObject const *interruptCaster, Unit const *interruptTarget, bool ignoreImmunity=false) const
Definition: SpellInfo.cpp:1443
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ GetMinRange()

float SpellInfo::GetMinRange ( bool  positive = false) const

Definition at line 3890 of file SpellInfo.cpp.

3891{
3892 if (!RangeEntry)
3893 return 0.0f;
3894 return RangeEntry->RangeMin[positive ? 1 : 0];
3895}
std::array< float, 2 > RangeMin
+ Here is the caller graph for this function:

◆ GetNextRankSpell()

SpellInfo const * SpellInfo::GetNextRankSpell ( ) const

Definition at line 4415 of file SpellInfo.cpp.

4416{
4417 if (!ChainEntry)
4418 return nullptr;
4419 return ChainEntry->next;
4420}
SpellInfo const * next
Definition: SpellMgr.h:561
+ Here is the caller graph for this function:

◆ GetPrevRankSpell()

SpellInfo const * SpellInfo::GetPrevRankSpell ( ) const

Definition at line 4422 of file SpellInfo.cpp.

4423{
4424 if (!ChainEntry)
4425 return nullptr;
4426 return ChainEntry->prev;
4427}
SpellInfo const * prev
Definition: SpellMgr.h:560
+ Here is the caller graph for this function:

◆ GetRank()

uint8 SpellInfo::GetRank ( ) const

Definition at line 4394 of file SpellInfo.cpp.

4395{
4396 if (!ChainEntry)
4397 return 1;
4398 return ChainEntry->rank;
4399}
+ Here is the caller graph for this function:

◆ GetRecoveryTime()

uint32 SpellInfo::GetRecoveryTime ( ) const

Definition at line 3994 of file SpellInfo.cpp.

+ Here is the caller graph for this function:

◆ GetSchoolMask()

SpellSchoolMask SpellInfo::GetSchoolMask ( ) const

Definition at line 2451 of file SpellInfo.cpp.

2452{
2454}
SpellSchoolMask
+ Here is the caller graph for this function:

◆ GetSpellMechanicMaskByEffectMask()

uint64 SpellInfo::GetSpellMechanicMaskByEffectMask ( uint32  effectMask) const

Definition at line 2481 of file SpellInfo.cpp.

2482{
2483 uint64 mask = 0;
2484 if (Mechanic)
2485 mask |= UI64LIT(1) << Mechanic;
2486
2487 for (SpellEffectInfo const& effect : GetEffects())
2488 if ((effectMask & (1 << effect.EffectIndex)) && effect.Mechanic)
2489 mask |= UI64LIT(1) << effect.Mechanic;
2490
2491 return mask;
2492}
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ GetSpellSpecific()

SpellSpecificType SpellInfo::GetSpellSpecific ( ) const

Definition at line 2610 of file SpellInfo.cpp.

2611{
2612 return _spellSpecific;
2613};
+ Here is the caller graph for this function:

◆ GetSpellVisual()

uint32 SpellInfo::GetSpellVisual ( WorldObject const *  caster = nullptr,
WorldObject const *  viewer = nullptr 
) const

Definition at line 4510 of file SpellInfo.cpp.

4511{
4512 if (SpellXSpellVisualEntry const* visual = sSpellXSpellVisualStore.LookupEntry(GetSpellXSpellVisualId(caster, viewer)))
4513 {
4514 //if (visual->LowViolenceSpellVisualID && forPlayer->GetViolenceLevel() operator 2)
4515 // return visual->LowViolenceSpellVisualID;
4516
4517 return visual->SpellVisualID;
4518 }
4519
4520 return 0;
4521}
DB2Storage< SpellXSpellVisualEntry > sSpellXSpellVisualStore("SpellXSpellVisual.db2", &SpellXSpellVisualLoadInfo::Instance)
uint32 GetSpellXSpellVisualId(WorldObject const *caster=nullptr, WorldObject const *viewer=nullptr) const
Definition: SpellInfo.cpp:4492
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ GetSpellXSpellVisualId()

uint32 SpellInfo::GetSpellXSpellVisualId ( WorldObject const *  caster = nullptr,
WorldObject const *  viewer = nullptr 
) const

Definition at line 4492 of file SpellInfo.cpp.

4493{
4494 for (SpellXSpellVisualEntry const* visual : _visuals)
4495 {
4496 if (PlayerConditionEntry const* playerCondition = sPlayerConditionStore.LookupEntry(visual->CasterPlayerConditionID))
4497 if (!caster || !caster->IsPlayer() || !ConditionMgr::IsPlayerMeetingCondition(caster->ToPlayer(), playerCondition))
4498 continue;
4499
4500 if (UnitConditionEntry const* unitCondition = sUnitConditionStore.LookupEntry(visual->CasterUnitConditionID))
4501 if (!caster || !caster->IsUnit() || !ConditionMgr::IsUnitMeetingCondition(caster->ToUnit(), Object::ToUnit(viewer), unitCondition))
4502 continue;
4503
4504 return visual->ID;
4505 }
4506
4507 return 0;
4508}
DB2Storage< UnitConditionEntry > sUnitConditionStore("UnitCondition.db2", &UnitConditionLoadInfo::Instance)
DB2Storage< PlayerConditionEntry > sPlayerConditionStore("PlayerCondition.db2", &PlayerConditionLoadInfo::Instance)
static bool IsPlayerMeetingCondition(Player const *player, PlayerConditionEntry const *condition)
static bool IsUnitMeetingCondition(Unit const *unit, Unit const *otherUnit, UnitConditionEntry const *condition)
Unit * ToUnit()
Definition: Object.h:214
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ HasAnyAuraInterruptFlag()

bool SpellInfo::HasAnyAuraInterruptFlag ( ) const

Definition at line 1455 of file SpellInfo.cpp.

1456{
1457 return AuraInterruptFlags != SpellAuraInterruptFlags::None || AuraInterruptFlags2 != SpellAuraInterruptFlags2::None;
1458}
+ Here is the caller graph for this function:

◆ HasAreaAuraEffect()

bool SpellInfo::HasAreaAuraEffect ( ) const

Definition at line 1399 of file SpellInfo.cpp.

1400{
1401 for (SpellEffectInfo const& effect : GetEffects())
1402 if (effect.IsAreaAuraEffect())
1403 return true;
1404
1405 return false;
1406}
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ HasAttribute() [1/16]

bool SpellInfo::HasAttribute ( SpellAttr0  attribute) const
inline

Definition at line 449 of file SpellInfo.h.

449{ return !!(Attributes & attribute); }

◆ HasAttribute() [2/16]

bool SpellInfo::HasAttribute ( SpellAttr1  attribute) const
inline

Definition at line 450 of file SpellInfo.h.

450{ return !!(AttributesEx & attribute); }

◆ HasAttribute() [3/16]

bool SpellInfo::HasAttribute ( SpellAttr10  attribute) const
inline

Definition at line 459 of file SpellInfo.h.

459{ return !!(AttributesEx10 & attribute); }

◆ HasAttribute() [4/16]

bool SpellInfo::HasAttribute ( SpellAttr11  attribute) const
inline

Definition at line 460 of file SpellInfo.h.

460{ return !!(AttributesEx11 & attribute); }

◆ HasAttribute() [5/16]

bool SpellInfo::HasAttribute ( SpellAttr12  attribute) const
inline

Definition at line 461 of file SpellInfo.h.

461{ return !!(AttributesEx12 & attribute); }

◆ HasAttribute() [6/16]

bool SpellInfo::HasAttribute ( SpellAttr13  attribute) const
inline

Definition at line 462 of file SpellInfo.h.

462{ return !!(AttributesEx13 & attribute); }

◆ HasAttribute() [7/16]

bool SpellInfo::HasAttribute ( SpellAttr14  attribute) const
inline

Definition at line 463 of file SpellInfo.h.

463{ return !!(AttributesEx14 & attribute); }

◆ HasAttribute() [8/16]

bool SpellInfo::HasAttribute ( SpellAttr2  attribute) const
inline

Definition at line 451 of file SpellInfo.h.

451{ return !!(AttributesEx2 & attribute); }

◆ HasAttribute() [9/16]

bool SpellInfo::HasAttribute ( SpellAttr3  attribute) const
inline

Definition at line 452 of file SpellInfo.h.

452{ return !!(AttributesEx3 & attribute); }

◆ HasAttribute() [10/16]

bool SpellInfo::HasAttribute ( SpellAttr4  attribute) const
inline

Definition at line 453 of file SpellInfo.h.

453{ return !!(AttributesEx4 & attribute); }

◆ HasAttribute() [11/16]

bool SpellInfo::HasAttribute ( SpellAttr5  attribute) const
inline

Definition at line 454 of file SpellInfo.h.

454{ return !!(AttributesEx5 & attribute); }

◆ HasAttribute() [12/16]

bool SpellInfo::HasAttribute ( SpellAttr6  attribute) const
inline

Definition at line 455 of file SpellInfo.h.

455{ return !!(AttributesEx6 & attribute); }

◆ HasAttribute() [13/16]

bool SpellInfo::HasAttribute ( SpellAttr7  attribute) const
inline

Definition at line 456 of file SpellInfo.h.

456{ return !!(AttributesEx7 & attribute); }

◆ HasAttribute() [14/16]

bool SpellInfo::HasAttribute ( SpellAttr8  attribute) const
inline

Definition at line 457 of file SpellInfo.h.

457{ return !!(AttributesEx8 & attribute); }

◆ HasAttribute() [15/16]

bool SpellInfo::HasAttribute ( SpellAttr9  attribute) const
inline

Definition at line 458 of file SpellInfo.h.

458{ return !!(AttributesEx9 & attribute); }

◆ HasAttribute() [16/16]

bool SpellInfo::HasAttribute ( SpellCustomAttributes  customAttribute) const
inline

Definition at line 464 of file SpellInfo.h.

464{ return !!(AttributesCu & customAttribute); }
uint32 AttributesCu
Definition: SpellInfo.h:345

◆ HasAura()

bool SpellInfo::HasAura ( AuraType  aura) const

Definition at line 1390 of file SpellInfo.cpp.

1391{
1392 for (SpellEffectInfo const& effect : GetEffects())
1393 if (effect.IsAura(aura))
1394 return true;
1395
1396 return false;
1397}
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ HasAuraInterruptFlag() [1/2]

bool SpellInfo::HasAuraInterruptFlag ( SpellAuraInterruptFlags  flag) const
inline

Definition at line 469 of file SpellInfo.h.

469{ return AuraInterruptFlags.HasFlag(flag); }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ HasAuraInterruptFlag() [2/2]

bool SpellInfo::HasAuraInterruptFlag ( SpellAuraInterruptFlags2  flag) const
inline

Definition at line 470 of file SpellInfo.h.

470{ return AuraInterruptFlags2.HasFlag(flag); }
+ Here is the call graph for this function:

◆ HasChannelInterruptFlag() [1/2]

bool SpellInfo::HasChannelInterruptFlag ( SpellAuraInterruptFlags  flag) const
inline

Definition at line 472 of file SpellInfo.h.

472{ return ChannelInterruptFlags.HasFlag(flag); }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ HasChannelInterruptFlag() [2/2]

bool SpellInfo::HasChannelInterruptFlag ( SpellAuraInterruptFlags2  flag) const
inline

Definition at line 473 of file SpellInfo.h.

473{ return ChannelInterruptFlags2.HasFlag(flag); }
+ Here is the call graph for this function:

◆ HasEffect()

bool SpellInfo::HasEffect ( SpellEffectName  effect) const

Definition at line 1381 of file SpellInfo.cpp.

1382{
1383 for (SpellEffectInfo const& eff : GetEffects())
1384 if (eff.IsEffect(effect))
1385 return true;
1386
1387 return false;
1388}
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ HasHitDelay()

bool SpellInfo::HasHitDelay ( ) const

Definition at line 1741 of file SpellInfo.cpp.

1742{
1743 return Speed > 0.0f || LaunchDelay > 0.0f;
1744}
+ Here is the caller graph for this function:

◆ HasInitialAggro()

bool SpellInfo::HasInitialAggro ( ) const

Definition at line 1736 of file