TrinityCore
Spell Class Reference

#include <Spell.h>

Classes

struct  CorpseTargetInfo
 
struct  GOTargetInfo
 
struct  HitTriggerSpell
 
struct  ItemTargetInfo
 
struct  TargetInfo
 
struct  TargetInfoBase
 

Public Types

typedef std::unordered_set< Aura * > UsedSpellMods
 

Public Member Functions

void EffectNULL ()
 
void EffectUnused ()
 
void EffectDistract ()
 
void EffectSchoolDMG ()
 
void EffectEnvironmentalDMG ()
 
void EffectInstaKill ()
 
void EffectDummy ()
 
void EffectTeleportUnits ()
 
void EffectTeleportUnitsWithVisualLoadingScreen ()
 
void EffectApplyAura ()
 
void EffectSendEvent ()
 
void EffectPowerBurn ()
 
void EffectPowerDrain ()
 
void EffectHeal ()
 
void EffectBind ()
 
void EffectTeleportToReturnPoint ()
 
void EffectHealthLeech ()
 
void EffectQuestComplete ()
 
void EffectCreateItem ()
 
void EffectCreateItem2 ()
 
void EffectCreateRandomItem ()
 
void EffectPersistentAA ()
 
void EffectEnergize ()
 
void EffectOpenLock ()
 
void EffectSummonChangeItem ()
 
void EffectProficiency ()
 
void EffectSummonType ()
 
void EffectLearnSpell ()
 
void EffectDispel ()
 
void EffectDualWield ()
 
void EffectPickPocket ()
 
void EffectAddFarsight ()
 
void EffectUntrainTalents ()
 
void EffectHealMechanical ()
 
void EffectJump ()
 
void EffectJumpDest ()
 
void EffectLeapBack ()
 
void EffectQuestClear ()
 
void EffectTeleUnitsFaceCaster ()
 
void EffectLearnSkill ()
 
void EffectPlayMovie ()
 
void EffectTradeSkill ()
 
void EffectEnchantItemPerm ()
 
void EffectEnchantItemTmp ()
 
void EffectTameCreature ()
 
void EffectSummonPet ()
 
void EffectLearnPetSpell ()
 
void EffectWeaponDmg ()
 
void EffectForceCast ()
 
void EffectTriggerSpell ()
 
void EffectTriggerMissileSpell ()
 
void EffectThreat ()
 
void EffectHealMaxHealth ()
 
void EffectInterruptCast ()
 
void EffectSummonObjectWild ()
 
void EffectScriptEffect ()
 
void EffectSanctuary ()
 
void EffectDuel ()
 
void EffectStuck ()
 
void EffectSummonPlayer ()
 
void EffectActivateObject ()
 
void EffectApplyGlyph ()
 
void EffectEnchantHeldItem ()
 
void EffectSummonObject ()
 
void EffectChangeRaidMarker ()
 
void EffectResurrect ()
 
void EffectParry ()
 
void EffectBlock ()
 
void EffectLeap ()
 
void EffectTransmitted ()
 
void EffectDisEnchant ()
 
void EffectInebriate ()
 
void EffectFeedPet ()
 
void EffectDismissPet ()
 
void EffectReputation ()
 
void EffectForceDeselect ()
 
void EffectSelfResurrect ()
 
void EffectSkinning ()
 
void EffectCharge ()
 
void EffectChargeDest ()
 
void EffectProspecting ()
 
void EffectMilling ()
 
void EffectRenamePet ()
 
void EffectSendTaxi ()
 
void EffectKnockBack ()
 
void EffectPullTowards ()
 
void EffectPullTowardsDest ()
 
void EffectDispelMechanic ()
 
void EffectResurrectPet ()
 
void EffectDestroyAllTotems ()
 
void EffectDurabilityDamage ()
 
void EffectSkill ()
 
void EffectTaunt ()
 
void EffectDurabilityDamagePCT ()
 
void EffectModifyThreatPercent ()
 
void EffectResurrectNew ()
 
void EffectAddExtraAttacks ()
 
void EffectSpiritHeal ()
 
void EffectSkinPlayerCorpse ()
 
void EffectStealBeneficialBuff ()
 
void EffectUnlearnSpecialization ()
 
void EffectHealPct ()
 
void EffectEnergizePct ()
 
void EffectTriggerRitualOfSummoning ()
 
void EffectSummonRaFFriend ()
 
void EffectUnlockGuildVaultTab ()
 
void EffectKillCreditPersonal ()
 
void EffectKillCredit ()
 
void EffectQuestFail ()
 
void EffectQuestStart ()
 
void EffectRedirectThreat ()
 
void EffectGameObjectDamage ()
 
void EffectGameObjectRepair ()
 
void EffectGameObjectSetDestructionState ()
 
void EffectCreateTamedPet ()
 
void EffectDiscoverTaxi ()
 
void EffectTitanGrip ()
 
void EffectEnchantItemPrismatic ()
 
void EffectPlayMusic ()
 
void EffectActivateSpec ()
 
void EffectPlaySound ()
 
void EffectRemoveAura ()
 
void EffectDamageFromMaxHealthPCT ()
 
void EffectCastButtons ()
 
void EffectRechargeItem ()
 
void EffectGiveCurrency ()
 
void EffectSummonPersonalGameObject ()
 
void EffectResurrectWithAura ()
 
void EffectCreateAreaTrigger ()
 
void EffectRemoveTalent ()
 
void EffectDestroyItem ()
 
void EffectLearnGarrisonBuilding ()
 
void EffectCreateGarrison ()
 
void EffectCreateConversation ()
 
void EffectCancelConversation ()
 
void EffectAddGarrisonFollower ()
 
void EffectActivateGarrisonBuilding ()
 
void EffectGrantBattlePetLevel ()
 
void EffectHealBattlePetPct ()
 
void EffectEnableBattlePets ()
 
void EffectChangeBattlePetQuality ()
 
void EffectLaunchQuestChoice ()
 
void EffectUncageBattlePet ()
 
void EffectCreateHeirloomItem ()
 
void EffectUpgradeHeirloom ()
 
void EffectApplyEnchantIllusion ()
 
void EffectUpdatePlayerPhase ()
 
void EffectUpdateZoneAurasAndPhases ()
 
void EffectGiveArtifactPower ()
 
void EffectGiveArtifactPowerNoBonus ()
 
void EffectPlaySceneScriptPackage ()
 
void EffectCreateSceneObject ()
 
void EffectCreatePrivateSceneObject ()
 
void EffectPlayScene ()
 
void EffectGiveHonor ()
 
void EffectJumpCharge ()
 
void EffectLearnTransmogSet ()
 
void EffectRespecAzeriteEmpoweredItem ()
 
void EffectLearnAzeriteEssencePower ()
 
void EffectCreatePrivateConversation ()
 
void EffectSendChatMessage ()
 
void EffectGrantBattlePetExperience ()
 
void EffectLearnTransmogIllusion ()
 
 Spell (WorldObject *caster, SpellInfo const *info, TriggerCastFlags triggerFlags, ObjectGuid originalCasterGUID=ObjectGuid::Empty, ObjectGuid originalCastId=ObjectGuid::Empty)
 
 ~Spell ()
 
void InitExplicitTargets (SpellCastTargets const &targets)
 
void SelectExplicitTargets ()
 
void SelectSpellTargets ()
 
void SelectEffectImplicitTargets (SpellEffectInfo const &spellEffectInfo, SpellImplicitTargetInfo const &targetType, uint32 &processedEffectMask)
 
void SelectImplicitChannelTargets (SpellEffectInfo const &spellEffectInfo, SpellImplicitTargetInfo const &targetType)
 
void SelectImplicitNearbyTargets (SpellEffectInfo const &spellEffectInfo, SpellImplicitTargetInfo const &targetType, uint32 effMask)
 
void SelectImplicitConeTargets (SpellEffectInfo const &spellEffectInfo, SpellImplicitTargetInfo const &targetType, uint32 effMask)
 
void SelectImplicitAreaTargets (SpellEffectInfo const &spellEffectInfo, SpellImplicitTargetInfo const &targetType, uint32 effMask)
 
void SelectImplicitCasterDestTargets (SpellEffectInfo const &spellEffectInfo, SpellImplicitTargetInfo const &targetType)
 
void SelectImplicitTargetDestTargets (SpellEffectInfo const &spellEffectInfo, SpellImplicitTargetInfo const &targetType)
 
void SelectImplicitDestDestTargets (SpellEffectInfo const &spellEffectInfo, SpellImplicitTargetInfo const &targetType)
 
void SelectImplicitCasterObjectTargets (SpellEffectInfo const &spellEffectInfo, SpellImplicitTargetInfo const &targetType)
 
void SelectImplicitTargetObjectTargets (SpellEffectInfo const &spellEffectInfo, SpellImplicitTargetInfo const &targetType)
 
void SelectImplicitChainTargets (SpellEffectInfo const &spellEffectInfo, SpellImplicitTargetInfo const &targetType, WorldObject *target, uint32 effMask)
 
void SelectImplicitTrajTargets (SpellEffectInfo const &spellEffectInfo, SpellImplicitTargetInfo const &targetType)
 
void SelectImplicitLineTargets (SpellEffectInfo const &spellEffectInfo, SpellImplicitTargetInfo const &targetType, uint32 effMask)
 
void SelectEffectTypeImplicitTargets (SpellEffectInfo const &spellEffectInfo)
 
uint32 GetSearcherTypeMask (SpellTargetObjectTypes objType, ConditionContainer *condList)
 
template<class SEARCHER >
void SearchTargets (SEARCHER &searcher, uint32 containerMask, WorldObject *referer, Position const *pos, float radius)
 
WorldObjectSearchNearbyTarget (float range, SpellTargetObjectTypes objectType, SpellTargetCheckTypes selectionType, ConditionContainer *condList=nullptr)
 
void SearchAreaTargets (std::list< WorldObject *> &targets, float range, Position const *position, WorldObject *referer, SpellTargetObjectTypes objectType, SpellTargetCheckTypes selectionType, ConditionContainer *condList)
 
void SearchChainTargets (std::list< WorldObject *> &targets, uint32 chainTargets, WorldObject *target, SpellTargetObjectTypes objectType, SpellTargetCheckTypes selectType, SpellEffectInfo const &spellEffectInfo, bool isChainHeal)
 
GameObjectSearchSpellFocus ()
 
SpellCastResult prepare (SpellCastTargets const &targets, AuraEffect const *triggeredByAura=nullptr)
 
void cancel ()
 
void update (uint32 difftime)
 
void cast (bool skipCheck=false)
 
void finish (bool ok=true)
 
void TakePower ()
 
void TakeRunePower (bool didHit)
 
void TakeReagents ()
 
void TakeCastItem ()
 
SpellCastResult CheckCast (bool strict, int32 *param1=nullptr, int32 *param2=nullptr)
 
SpellCastResult CheckPetCast (Unit *target)
 
void handle_immediate ()
 
uint64 handle_delayed (uint64 t_offset)
 
void _handle_immediate_phase ()
 
void _handle_finish_phase ()
 
SpellCastResult CheckItems (int32 *param1, int32 *param2) const
 
SpellCastResult CheckRange (bool strict) const
 
SpellCastResult CheckPower () const
 
SpellCastResult CheckRuneCost () const
 
SpellCastResult CheckCasterAuras (int32 *param1) const
 
SpellCastResult CheckArenaAndRatedBattlegroundCastRules ()
 
SpellCastResult CheckMovement () const
 
bool CheckSpellCancelsAuraEffect (AuraType auraType, int32 *param1) const
 
bool CheckSpellCancelsCharm (int32 *param1) const
 
bool CheckSpellCancelsStun (int32 *param1) const
 
bool CheckSpellCancelsSilence (int32 *param1) const
 
bool CheckSpellCancelsPacify (int32 *param1) const
 
bool CheckSpellCancelsFear (int32 *param1) const
 
bool CheckSpellCancelsConfuse (int32 *param1) const
 
bool CheckSpellCancelsNoActions (int32 *param1) const
 
int32 CalculateDamage (SpellEffectInfo const &spellEffectInfo, Unit const *target, float *var=nullptr) const
 
void Delayed ()
 
void DelayedChannel ()
 
uint32 getState () const
 
void setState (uint32 state)
 
void DoCreateItem (uint32 itemId, ItemContext context=ItemContext::NONE, std::vector< int32 > const &bonusListIDs=std::vector< int32 >())
 
bool CheckEffectTarget (Unit const *target, SpellEffectInfo const &spellEffectInfo, Position const *losPosition) const
 
bool CheckEffectTarget (GameObject const *target, SpellEffectInfo const &spellEffectInfo) const
 
bool CheckEffectTarget (Item const *target, SpellEffectInfo const &spellEffectInfo) const
 
bool CanAutoCast (Unit *target)
 
void CheckSrc ()
 
void CheckDst ()
 
void SendCastResult (SpellCastResult result, int32 *param1=nullptr, int32 *param2=nullptr) const
 
void SendPetCastResult (SpellCastResult result, int32 *param1=nullptr, int32 *param2=nullptr) const
 
void SendMountResult (MountResult result)
 
void SendSpellStart ()
 
void SendSpellGo ()
 
void SendSpellCooldown ()
 
void SendSpellExecuteLog ()
 
SpellLogEffectGetExecuteLogEffect (SpellEffectName effect)
 
template<typename T >
std::vector< T > & GetExecuteLogEffectTargets (SpellEffectName effect, Optional< std::vector< T >> SpellLogEffect::*member)
 
void ExecuteLogEffectTakeTargetPower (SpellEffectName effect, Unit *target, uint32 powerType, uint32 points, float amplitude)
 
void ExecuteLogEffectExtraAttacks (SpellEffectName effect, Unit *victim, uint32 numAttacks)
 
void ExecuteLogEffectDurabilityDamage (SpellEffectName effect, Unit *victim, int32 itemId, int32 amount)
 
void ExecuteLogEffectOpenLock (SpellEffectName effect, Object *obj)
 
void ExecuteLogEffectCreateItem (SpellEffectName effect, uint32 entry)
 
void ExecuteLogEffectDestroyItem (SpellEffectName effect, uint32 entry)
 
void ExecuteLogEffectSummonObject (SpellEffectName effect, WorldObject *obj)
 
void ExecuteLogEffectUnsummonObject (SpellEffectName effect, WorldObject *obj)
 
void ExecuteLogEffectResurrect (SpellEffectName effect, Unit *target)
 
void SendSpellInterruptLog (Unit *victim, uint32 spellId)
 
void SendInterrupted (uint8 result)
 
void SendChannelUpdate (uint32 time)
 
void SendChannelStart (uint32 duration)
 
void SendResurrectRequest (Player *target)
 
void HandleEffects (Unit *pUnitTarget, Item *pItemTarget, GameObject *pGoTarget, Corpse *pCorpseTarget, SpellEffectInfo const &spellEffectInfo, SpellEffectHandleMode mode)
 
void HandleThreatSpells ()
 
int32 GetCastTime () const
 
bool IsAutoRepeat () const
 
void SetAutoRepeat (bool rep)
 
void ReSetTimer ()
 
bool IsTriggered () const
 
bool IsIgnoringCooldowns () const
 
bool IsFocusDisabled () const
 
bool IsProcDisabled () const
 
bool IsChannelActive () const
 
bool IsAutoActionResetSpell () const
 
bool IsPositive () const
 
bool IsTriggeredByAura (SpellInfo const *auraSpellInfo) const
 
bool IsDeletable () const
 
void SetReferencedFromCurrent (bool yes)
 
bool IsInterruptable () const
 
void SetExecutedCurrently (bool yes)
 
uint64 GetDelayStart () const
 
void SetDelayStart (uint64 m_time)
 
uint64 GetDelayMoment () const
 
uint64 CalculateDelayMomentForDst (float launchDelay) const
 
void RecalculateDelayMomentForDst ()
 
uint8 GetRuneState () const
 
void SetRuneState (uint8 value)
 
bool IsNeedSendToClient () const
 
CurrentSpellTypes GetCurrentContainer () const
 
WorldObjectGetCaster () const
 
ObjectGuid GetOriginalCasterGUID () const
 
UnitGetOriginalCaster () const
 
SpellInfo const * GetSpellInfo () const
 
Difficulty GetCastDifficulty () const
 
std::vector< SpellPowerCost > const & GetPowerCost () const
 
bool HasPowerTypeCost (Powers power) const
 
Optional< int32GetPowerTypeCostAmount (Powers power) const
 
bool UpdatePointers ()
 
void CleanupTargetList ()
 
void SetSpellValue (SpellValueMod mod, int32 value)
 
SpellInfo const * GetTriggeredByAuraSpell () const
 
int32 GetTimer () const
 
int64 GetUnitTargetCountForEffect (SpellEffIndex effect) const
 
int64 GetGameObjectTargetCountForEffect (SpellEffIndex effect) const
 
int64 GetItemTargetCountForEffect (SpellEffIndex effect) const
 
int64 GetCorpseTargetCountForEffect (SpellEffIndex effect) const
 
std::string GetDebugInfo () const
 
void CallScriptOnResistAbsorbCalculateHandlers (DamageInfo const &damageInfo, uint32 &resistAmount, int32 &absorbAmount)
 
void CallScriptCalcCritChanceHandlers (Unit const *victim, float &chance)
 

Static Public Member Functions

static void SendCastResult (Player *caster, SpellInfo const *spellInfo, SpellCastVisual spellVisual, ObjectGuid cast_count, SpellCastResult result, SpellCustomErrors customError=SPELL_CUSTOM_ERROR_NONE, int32 *param1=nullptr, int32 *param2=nullptr)
 
static Spell const * ExtractSpellFromEvent (BasicEvent *event)
 

Public Attributes

SpellInfo const *const m_spellInfo
 
Itemm_CastItem
 
ObjectGuid m_castItemGUID
 
uint32 m_castItemEntry
 
int32 m_castItemLevel
 
ObjectGuid m_castId
 
ObjectGuid m_originalCastId
 
bool m_fromClient
 
uint32 m_castFlagsEx
 
union {
   uint32   TalentId
 
   uint32   SpellId
 
   uint32   SpecializationId
 
   struct {
      uint32   Id
 
      uint32   AbilityId
 
   }   GarrFollower
 
   uint32   GarrMissionId
 
   uint32   ItemId
 
   struct {
      uint32   Data [2]
 
   }   Raw
 
m_misc
 
SpellCastVisual m_SpellVisual
 
SpellCastTargets m_targets
 
int8 m_comboPointGain
 
SpellCustomErrors m_customError
 
UsedSpellMods m_appliedMods
 
Spell ** m_selfContainer
 

Protected Types

typedef std::vector< HitTriggerSpellHitTriggerSpellList
 

Protected Member Functions

bool HasGlobalCooldown () const
 
void TriggerGlobalCooldown ()
 
void CancelGlobalCooldown ()
 
void _cast (bool skipCheck=false)
 
void SendLoot (ObjectGuid guid, LootType loottype)
 
std::pair< float, float > GetMinMaxRange (bool strict) const
 
bool IsDelayableNoMore ()
 
UnitGetUnitCasterForEffectHandlers () const
 
void prepareDataForTriggerSystem ()
 
template<class Container >
void DoProcessTargetContainer (Container &targetContainer)
 
void AddUnitTarget (Unit *target, uint32 effectMask, bool checkIfValid=true, bool implicit=true, Position const *losPosition=nullptr)
 
void AddGOTarget (GameObject *target, uint32 effectMask)
 
void AddItemTarget (Item *item, uint32 effectMask)
 
void AddCorpseTarget (Corpse *target, uint32 effectMask)
 
void AddDestTarget (SpellDestination const &dest, uint32 effIndex)
 
SpellMissInfo PreprocessSpellHit (Unit *unit, TargetInfo &targetInfo)
 
void DoSpellEffectHit (Unit *unit, SpellEffectInfo const &spellEffectInfo, TargetInfo &targetInfo)
 
void DoTriggersOnSpellHit (Unit *unit)
 
bool UpdateChanneledTargetList ()
 
bool IsValidDeadOrAliveTarget (Unit const *target) const
 
void HandleLaunchPhase ()
 
void DoEffectOnLaunchTarget (TargetInfo &targetInfo, float multiplier, SpellEffectInfo const &spellEffectInfo)
 
void PrepareTargetProcessing ()
 
void FinishTargetProcessing ()
 
void LoadScripts ()
 
void CallScriptOnPrecastHandler ()
 
void CallScriptBeforeCastHandlers ()
 
void CallScriptOnCastHandlers ()
 
void CallScriptAfterCastHandlers ()
 
SpellCastResult CallScriptCheckCastHandlers ()
 
bool CallScriptEffectHandlers (SpellEffIndex effIndex, SpellEffectHandleMode mode)
 
void CallScriptSuccessfulDispel (SpellEffIndex effIndex)
 
void CallScriptBeforeHitHandlers (SpellMissInfo missInfo)
 
void CallScriptOnHitHandlers ()
 
void CallScriptAfterHitHandlers ()
 
void CallScriptObjectAreaTargetSelectHandlers (std::list< WorldObject *> &targets, SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
 
void CallScriptObjectTargetSelectHandlers (WorldObject *&target, SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
 
void CallScriptDestinationTargetSelectHandlers (SpellDestination &target, SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
 
bool CheckScriptEffectImplicitTargets (uint32 effIndex, uint32 effIndexToCheck)
 
bool CanExecuteTriggersOnHit (Unit *unit, SpellInfo const *triggeredByAura=nullptr) const
 
void PrepareTriggersExecutedOnHit ()
 
void SummonGuardian (SpellEffectInfo const *effect, uint32 entry, SummonPropertiesEntry const *properties, uint32 numSummons, ObjectGuid privateObjectOwner)
 
void CalculateJumpSpeeds (SpellEffectInfo const *effInfo, float dist, float &speedXY, float &speedZ)
 
void UpdateSpellCastDataTargets (WorldPackets::Spells::SpellCastData &data)
 Writes miss and hit targets for a SMSG_SPELL_GO packet. More...
 
void UpdateSpellCastDataAmmo (WorldPackets::Spells::SpellAmmo &data)
 
SpellCastResult CanOpenLock (SpellEffectInfo const &effect, uint32 lockid, SkillType &skillid, int32 &reqSkillValue, int32 &skillValue)
 
 Spell (Spell const &right)=delete
 
Spelloperator= (Spell const &right)=delete
 

Protected Attributes

WorldObject *const m_caster
 
SpellValue *const m_spellValue
 
ObjectGuid m_originalCasterGUID
 
Unitm_originalCaster
 
SpellSchoolMask m_spellSchoolMask
 
WeaponAttackType m_attackType
 
std::vector< SpellPowerCostm_powerCost
 
int32 m_casttime
 
int32 m_channeledDuration
 
bool m_canReflect
 
bool m_autoRepeat
 
uint8 m_runesState
 
uint8 m_delayAtDamageCount
 
uint64 m_delayStart
 
uint64 m_delayMoment
 
bool m_launchHandled
 
bool m_immediateHandled
 
bool m_referencedFromCurrentSpell
 
bool m_executedCurrently
 
bool m_needComboPoints
 
uint32 m_applyMultiplierMask
 
float m_damageMultipliers [MAX_SPELL_EFFECTS]
 
UnitunitTarget
 
ItemitemTarget
 
GameObjectgameObjTarget
 
Corpsem_corpseTarget
 
WorldLocationdestTarget
 
int32 damage
 
SpellMissInfo targetMissInfo
 
float variance
 
SpellEffectHandleMode effectHandleMode
 
SpellEffectInfo const * effectInfo
 
UnitAura_spellAura
 
DynObjAura_dynObjAura
 
GameObjectfocusObject
 
int32 m_damage
 
int32 m_healing
 
ProcFlagsInit m_procAttacker
 
ProcFlagsInit m_procVictim
 
ProcFlagsHit m_hitMask
 
std::vector< TargetInfom_UniqueTargetInfo
 
uint32 m_channelTargetEffectMask
 
std::vector< GOTargetInfom_UniqueGOTargetInfo
 
std::vector< ItemTargetInfom_UniqueItemInfo
 
std::vector< CorpseTargetInfom_UniqueCorpseTargetInfo
 
SpellDestination m_destTargets [MAX_SPELL_EFFECTS]
 
std::vector< SpellScript * > m_loadedScripts
 
HitTriggerSpellList m_hitTriggerSpells
 
uint32 m_spellState
 
int32 m_timer
 
SpellEvent_spellEvent
 
TriggerCastFlags _triggeredCastFlags
 
SpellInfo const * m_triggeredByAuraSpell
 
std::unique_ptr< PathGeneratorm_preGeneratedPath
 
std::vector< SpellLogEffect_executeLogEffects
 

Friends

class SpellScript
 

Member Typedef Documentation

◆ HitTriggerSpellList

typedef std::vector<HitTriggerSpell> Spell::HitTriggerSpellList
protected

◆ UsedSpellMods

typedef std::unordered_set<Aura*> Spell::UsedSpellMods

Constructor & Destructor Documentation

◆ Spell() [1/2]

Spell::Spell ( WorldObject caster,
SpellInfo const *  info,
TriggerCastFlags  triggerFlags,
ObjectGuid  originalCasterGUID = ObjectGuid::Empty,
ObjectGuid  originalCastId = ObjectGuid::Empty 
)
493  :
494 m_spellInfo(info), m_caster((info->HasAttribute(SPELL_ATTR6_ORIGINATE_FROM_CONTROLLER) && caster->GetCharmerOrOwner()) ? caster->GetCharmerOrOwner() : caster),
495 m_spellValue(new SpellValue(m_spellInfo, caster)), _spellEvent(nullptr)
496 {
498  m_fromClient = false;
499  m_selfContainer = nullptr;
501  m_executedCurrently = false;
503  m_comboPointGain = 0;
504  m_delayStart = 0;
506 
508  memset(m_damageMultipliers, 0, sizeof(m_damageMultipliers));
509 
510  // Get data for type of attack
511  m_attackType = info->GetAttackType();
512 
513  m_spellSchoolMask = info->GetSchoolMask(); // Can be override for some spell (wand shoot for example)
514 
515  if (Player const* playerCaster = m_caster->ToPlayer())
516  {
517  // wand case
519  if ((playerCaster->GetClassMask() & CLASSMASK_WAND_USERS) != 0)
520  if (Item* pItem = playerCaster->GetWeaponForAttack(RANGED_ATTACK))
521  m_spellSchoolMask = SpellSchoolMask(1 << pItem->GetTemplate()->GetDamageType());
522  }
523 
524  if (Player const* modOwner = caster->GetSpellModOwner())
525  modOwner->ApplySpellMod(info, SpellModOp::Doses, m_spellValue->AuraStackAmount, this);
526 
527  if (!originalCasterGUID.IsEmpty())
528  m_originalCasterGUID = originalCasterGUID;
529  else
531 
534  else
535  {
538  m_originalCaster = nullptr;
539  }
540 
542  _triggeredCastFlags = triggerFlags;
543 
544  if (info->HasAttribute(SPELL_ATTR2_DO_NOT_REPORT_SPELL_FAILURE))
546 
547  if (info->HasAttribute(SPELL_ATTR4_ALLOW_CAST_WHILE_CASTING))
549 
550  m_CastItem = nullptr;
552  m_castItemEntry = 0;
553  m_castItemLevel = -1;
554  m_castFlagsEx = 0;
555 
556  if (IsIgnoringCooldowns())
558 
559  unitTarget = nullptr;
560  itemTarget = nullptr;
561  gameObjTarget = nullptr;
562  m_corpseTarget = nullptr;
563  destTarget = nullptr;
564  damage = 0;
566  variance = 0.0f;
568  effectInfo = nullptr;
569  m_damage = 0;
570  m_healing = 0;
572  focusObject = nullptr;
574  m_originalCastId = originalCastId;
575  memset(m_misc.Raw.Data, 0, sizeof(m_misc.Raw.Data));
577  m_triggeredByAuraSpell = nullptr;
578  _spellAura = nullptr;
579  _dynObjAura = nullptr;
580 
581  //Auto Shot & Shoot (wand)
583 
584  m_runesState = 0;
585  m_casttime = 0; // setup to correct value in Spell::prepare, must not be used before.
586  m_timer = 0; // will set to castime in prepare
587  m_channeledDuration = 0; // will be setup in Spell::handle_immediate
588  m_launchHandled = false;
589  m_immediateHandled = false;
590 
592 
593  // Determine if spell can be reflected back to the caster
594  // Patch 1.2 notes: Spell Reflection no longer reflects abilities
597  && !m_spellInfo->IsPassive();
598 
600 
601  for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
603 }
GameObject * focusObject
Definition: Spell.h:708
Will allow periodic aura timers to keep ticking (instead of resetting)
Definition: SpellDefines.h:259
Definition: Spell.h:218
static Player * ToPlayer(Object *o)
Definition: Object.h:198
GameObject * gameObjTarget
Definition: Spell.h:694
SpellInfo const *const m_spellInfo
Definition: Spell.h:532
uint32 m_spellState
Definition: Spell.h:866
float m_damageMultipliers[MAX_SPELL_EFFECTS]
Definition: Spell.h:689
SpellMissInfo targetMissInfo
Definition: Spell.h:698
SpellEffectInfo const * effectInfo
Definition: Spell.h:701
uint32 m_channelTargetEffectMask
Definition: Spell.h:768
TC_GAME_API Unit * GetUnit(WorldObject const &, ObjectGuid const &guid)
Definition: ObjectAccessor.cpp:206
int32 m_casttime
Definition: Spell.h:662
int8 m_comboPointGain
Definition: Spell.h:576
TriggerCastFlags
Definition: SpellDefines.h:238
bool m_canReflect
Definition: Spell.h:664
uint32 DmgClass
Definition: SpellInfo.h:427
SpellEvent * _spellEvent
Definition: Spell.h:869
union Spell::@328 m_misc
DynObjAura * _dynObjAura
Definition: Spell.h:705
uint64 m_delayStart
Definition: Spell.h:679
static ObjectGuid GetGUID(Object const *o)
Definition: Object.h:156
SpellInfo const * m_triggeredByAuraSpell
Definition: Spell.h:875
WorldObject *const m_caster
Definition: Spell.h:649
Definition: SharedDefines.h:647
bool IsInWorld() const
Definition: Object.h:151
Definition: SpellMgr.h:272
Definition: Spell.h:203
int32 AuraStackAmount
Definition: Spell.h:210
uint32 m_castItemEntry
Definition: Spell.h:535
WorldLocation * destTarget
Definition: Spell.h:696
bool m_launchHandled
Definition: Spell.h:681
bool IsPassive() const
Definition: SpellInfo.cpp:1519
int32 m_timer
Definition: Spell.h:867
Definition: SharedDefines.h:411
bool m_immediateHandled
Definition: Spell.h:682
Item * m_CastItem
Definition: Spell.h:533
SpellValue *const m_spellValue
Definition: Spell.h:651
Definition: SharedDefines.h:436
Definition: Spell.h:124
#define MAX_SPELL_EFFECTS
Definition: DBCEnums.h:1512
bool IsIgnoringCooldowns() const
Definition: Spell.cpp:7966
Corpse * m_corpseTarget
Definition: Spell.h:695
bool m_autoRepeat
Definition: Spell.h:665
SpellSchoolMask
Definition: SharedDefines.h:310
Definition: SharedDefines.h:1765
Map * GetMap() const
Definition: Object.h:555
uint32 const Id
Definition: SpellInfo.h:347
Definition: SpellDefines.h:305
uint32 m_applyMultiplierMask
Definition: Spell.h:688
Unit * unitTarget
Definition: Spell.h:692
Unit * m_originalCaster
Definition: Spell.h:655
bool HasAttribute(SpellAttr0 attribute) const
Definition: SpellInfo.h:461
int32 damage
Definition: Spell.h:697
ObjectGuid m_castItemGUID
Definition: Spell.h:534
Definition: Item.h:169
bool IsAutoRepeatRangedSpell() const
Definition: SpellInfo.cpp:1672
uint32_t uint32
Definition: Define.h:143
ObjectGuid m_castId
Definition: Spell.h:537
ProcFlagsHit m_hitMask
Definition: Spell.h:719
Item * itemTarget
Definition: Spell.h:693
int32 m_damage
Definition: Spell.h:711
void CleanupTargetList()
Definition: Spell.cpp:2247
Definition: SharedDefines.h:488
float variance
Definition: Spell.h:699
WeaponAttackType m_attackType
Definition: Spell.h:659
Definition: SharedDefines.h:2686
Definition: SharedDefines.h:562
bool IsUnit() const
Definition: Object.h:209
Definition: SharedDefines.h:2716
void Clear()
Definition: ObjectGuid.h:277
ObjectGuid m_originalCasterGUID
Definition: Spell.h:653
bool IsEmpty() const
Definition: ObjectGuid.h:310
bool m_executedCurrently
Definition: Spell.h:686
uint32 GetMapId() const
Definition: Position.h:186
Definition: SharedDefines.h:6549
virtual uint32 GetCastSpellXSpellVisualId(SpellInfo const *spellInfo) const
Definition: Object.cpp:3169
ObjectGuid m_originalCastId
Definition: Spell.h:538
Unit * GetCharmerOrOwner() const
Definition: Object.cpp:2110
Definition: SharedDefines.h:451
#define CLASSMASK_WAND_USERS
Definition: SharedDefines.h:182
uint8 m_runesState
Definition: Spell.h:666
uint32 m_castFlagsEx
Definition: Spell.h:540
uint8_t uint8
Definition: Define.h:145
uint32 SpellXSpellVisualID
Definition: SpellDefines.h:486
uint8 m_delayAtDamageCount
Definition: Spell.h:668
SpellSchoolMask m_spellSchoolMask
Definition: Spell.h:658
Player * GetSpellModOwner() const
Definition: Object.cpp:2148
int32 m_channeledDuration
Definition: Spell.h:663
int32 m_castItemLevel
Definition: Spell.h:536
Definition: Spell.h:140
static Unit * ToUnit(Object *o)
Definition: Object.h:210
SpellCustomErrors m_customError
Definition: Spell.h:577
ObjectGuid::LowType GenerateLowGuid()
Definition: Map.h:600
TriggerCastFlags _triggeredCastFlags
Definition: Spell.h:870
SpellCastVisual m_SpellVisual
Definition: Spell.h:574
Spell ** m_selfContainer
Definition: Spell.h:626
bool NeedsComboPoints() const
Definition: SpellInfo.cpp:1655
Definition: Player.h:1131
int32 m_healing
Definition: Spell.h:712
bool m_referencedFromCurrentSpell
Definition: Spell.h:685
bool m_needComboPoints
Definition: Spell.h:687
SpellDestination m_destTargets[MAX_SPELL_EFFECTS]
Definition: Spell.h:799
bool m_fromClient
Definition: Spell.h:539
UnitAura * _spellAura
Definition: Spell.h:704
Will ignore aura scaling.
Definition: SpellDefines.h:246
SpellEffectHandleMode effectHandleMode
Definition: Spell.h:700
Definition: Spell.h:228
+ Here is the call graph for this function:

◆ ~Spell()

Spell::~Spell ( )
606 {
607  // unload scripts
608  for (auto itr = m_loadedScripts.begin(); itr != m_loadedScripts.end(); ++itr)
609  {
610  (*itr)->_Unload();
611  delete (*itr);
612  }
613 
615  {
616  // Clean the reference to avoid later crash.
617  // If this error is repeating, we may have to add an ASSERT to better track down how we get into this case.
618  TC_LOG_ERROR("spells", "SPELL: deleting spell for spell ID %u. However, spell still referenced.", m_spellInfo->Id);
619  *m_selfContainer = nullptr;
620  }
621 
624 
625  delete m_spellValue;
626 }
static Player * ToPlayer(Object *o)
Definition: Object.h:198
SpellInfo const *const m_spellInfo
Definition: Spell.h:532
TypeID GetTypeId() const
Definition: Object.h:170
#define TC_LOG_ERROR(filterType__,...)
Definition: Log.h:185
Spell * m_spellModTakingSpell
Definition: Player.h:2641
WorldObject *const m_caster
Definition: Spell.h:649
std::vector< SpellScript * > m_loadedScripts
Definition: Spell.h:838
SpellValue *const m_spellValue
Definition: Spell.h:651
uint32 const Id
Definition: SpellInfo.h:347
Definition: ObjectGuid.h:40
#define ASSERT
Definition: Errors.h:68
Spell ** m_selfContainer
Definition: Spell.h:626
bool m_referencedFromCurrentSpell
Definition: Spell.h:685
+ Here is the call graph for this function:

◆ Spell() [2/2]

Spell::Spell ( Spell const &  right)
protecteddelete

Member Function Documentation

◆ _cast()

void Spell::_cast ( bool  skipCheck = false)
protected

Not own traded item (in trader trade slot) req. reagents including triggered spell case

3539 {
3540  // update pointers base at GUIDs to prevent access to non-existed already object
3541  if (!UpdatePointers())
3542  {
3543  // cancel the spell if UpdatePointers() returned false, something wrong happened there
3544  cancel();
3545  return;
3546  }
3547 
3548  // cancel at lost explicit target during cast
3550  {
3551  cancel();
3552  return;
3553  }
3554 
3555  if (Player* playerCaster = m_caster->ToPlayer())
3556  {
3557  // now that we've done the basic check, now run the scripts
3558  // should be done before the spell is actually executed
3559  sScriptMgr->OnPlayerSpellCast(playerCaster, this, skipCheck);
3560 
3561  // As of 3.0.2 pets begin attacking their owner's target immediately
3562  // Let any pets know we've attacked something. Check DmgClass for harmful spells only
3563  // This prevents spells such as Hunter's Mark from triggering pet attack
3564  if (GetSpellInfo()->DmgClass != SPELL_DAMAGE_CLASS_NONE)
3565  if (Unit* target = m_targets.GetUnitTarget())
3566  for (Unit* controlled : playerCaster->m_Controlled)
3567  if (Creature* cControlled = controlled->ToCreature())
3568  if (CreatureAI* controlledAI = cControlled->AI())
3569  controlledAI->OwnerAttacked(target);
3570  }
3571 
3572  SetExecutedCurrently(true);
3573 
3574  // Should this be done for original caster?
3575  Player* modOwner = m_caster->GetSpellModOwner();
3576  if (modOwner)
3577  {
3578  // Set spell which will drop charges for triggered cast spells
3579  // if not successfully cast, will be remove in finish(false)
3580  modOwner->SetSpellModTakingSpell(this, true);
3581  }
3582 
3584 
3585  // skip check if done already (for instant cast spells for example)
3586  if (!skipCheck)
3587  {
3588  auto cleanupSpell = [this, modOwner](SpellCastResult res, int32* p1 = nullptr, int32* p2 = nullptr)
3589  {
3590  SendCastResult(res, p1, p2);
3591  SendInterrupted(0);
3592 
3593  if (modOwner)
3594  modOwner->SetSpellModTakingSpell(this, false);
3595 
3596  finish(false);
3597  SetExecutedCurrently(false);
3598  };
3599 
3600  int32 param1 = 0, param2 = 0;
3601  SpellCastResult castResult = CheckCast(false, &param1, &param2);
3602  if (castResult != SPELL_CAST_OK)
3603  {
3604  cleanupSpell(castResult, &param1, &param2);
3605  return;
3606  }
3607 
3608  // additional check after cast bar completes (must not be in CheckCast)
3609  // if trade not complete then remember it in trade data
3611  {
3612  if (modOwner)
3613  {
3614  if (TradeData* my_trade = modOwner->GetTradeData())
3615  {
3616  if (!my_trade->IsInAcceptProcess())
3617  {
3618  // Spell will be cast after completing the trade. Silently ignore at this place
3619  my_trade->SetSpell(m_spellInfo->Id, m_CastItem);
3620  cleanupSpell(SPELL_FAILED_DONT_REPORT);
3621  return;
3622  }
3623  }
3624  }
3625  }
3626 
3627  // check diminishing returns (again, only after finish cast bar, tested on retail)
3628  if (Unit* target = m_targets.GetUnitTarget())
3629  {
3630  uint32 aura_effmask = 0;
3631  for (SpellEffectInfo const& spellEffectInfo : m_spellInfo->GetEffects())
3632  if (spellEffectInfo.IsUnitOwnedAuraEffect())
3633  aura_effmask |= 1 << spellEffectInfo.EffectIndex;
3634 
3635  if (aura_effmask)
3636  {
3638  {
3640  if (type == DRTYPE_ALL || (type == DRTYPE_PLAYER && target->IsAffectedByDiminishingReturns()))
3641  {
3642  if (Unit* caster = m_originalCaster ? m_originalCaster : m_caster->ToUnit())
3643  {
3644  if (target->HasStrongerAuraWithDR(m_spellInfo, caster))
3645  {
3646  cleanupSpell(SPELL_FAILED_AURA_BOUNCED);
3647  return;
3648  }
3649  }
3650  }
3651  }
3652  }
3653  }
3654  }
3655  // The spell focusing is making sure that we have a valid cast target guid when we need it so only check for a guid value here.
3656  if (Creature* creatureCaster = m_caster->ToCreature())
3657  if (!creatureCaster->GetTarget().IsEmpty() && !creatureCaster->HasUnitFlag(UNIT_FLAG_POSSESSED))
3658  if (WorldObject const* target = ObjectAccessor::GetUnit(*creatureCaster, creatureCaster->GetTarget()))
3659  creatureCaster->SetInFront(target);
3660 
3662 
3663  // Spell may be finished after target map check
3665  {
3666  SendInterrupted(0);
3667 
3668  // cleanup after mod system
3669  // triggered spell pointer can be not removed in some cases
3670  if (m_caster->GetTypeId() == TYPEID_PLAYER)
3671  m_caster->ToPlayer()->SetSpellModTakingSpell(this, false);
3672 
3673  finish(false);
3674  SetExecutedCurrently(false);
3675  return;
3676  }
3677 
3678  if (Unit* unitCaster = m_caster->ToUnit())
3680  if (Creature* pet = ObjectAccessor::GetCreature(*m_caster, unitCaster->GetPetGUID()))
3681  pet->DespawnOrUnsummon();
3682 
3684 
3686 
3687  // traded items have trade slot instead of guid in m_itemTargetGUID
3688  // set to real guid to be sent later to the client
3690 
3691  if (Player* player = m_caster->ToPlayer())
3692  {
3694  {
3695  player->StartCriteriaTimer(CriteriaStartEvent::UseItem, m_CastItem->GetEntry());
3696  player->UpdateCriteria(CriteriaType::UseItem, m_CastItem->GetEntry());
3697  }
3698 
3699  player->UpdateCriteria(CriteriaType::CastSpell, m_spellInfo->Id);
3700  }
3701 
3703  {
3704  // Powers have to be taken before SendSpellGo
3705  TakePower();
3706  TakeReagents(); // we must remove reagents before HandleEffects to allow place crafted item in same slot
3707  }
3708  else if (Item* targetItem = m_targets.GetItemTarget())
3709  {
3711  if (targetItem->GetOwnerGUID() != m_caster->GetGUID())
3712  TakeReagents();
3713  }
3714 
3715  // CAST SPELL
3718 
3719  if (!m_spellInfo->LaunchDelay)
3720  {
3722  m_launchHandled = true;
3723  }
3724 
3725  // we must send smsg_spell_go packet before m_castItem delete in TakeCastItem()...
3726  SendSpellGo();
3727 
3728  if (!m_spellInfo->IsChanneled())
3729  if (Creature* creatureCaster = m_caster->ToCreature())
3730  creatureCaster->ReleaseSpellFocus(this);
3731 
3732  // Okay, everything is prepared. Now we need to distinguish between immediate and evented delayed spells
3734  {
3735  // Remove used for cast item if need (it can be already NULL after TakeReagents call
3736  // in case delayed spell remove item at cast delay start
3737  TakeCastItem();
3738 
3739  // Okay, maps created, now prepare flags
3740  m_immediateHandled = false;
3742  SetDelayStart(0);
3743 
3744  if (Unit* unitCaster = m_caster->ToUnit())
3745  if (unitCaster->HasUnitState(UNIT_STATE_CASTING) && !unitCaster->IsNonMeleeSpellCast(false, false, true))
3746  unitCaster->ClearUnitState(UNIT_STATE_CASTING);
3747  }
3748  else
3749  {
3750  // Immediate spell, no big deal
3751  handle_immediate();
3752  }
3753 
3755 
3756  if (std::vector<int32> const* spell_triggered = sSpellMgr->GetSpellLinked(m_spellInfo->Id))
3757  {
3758  for (int32 id : *spell_triggered)
3759  {
3760  if (id < 0)
3761  {
3762  if (Unit* unitCaster = m_caster->ToUnit())
3763  unitCaster->RemoveAurasDueToSpell(-id);
3764  }
3765  else
3767  .SetTriggeringSpell(this));
3768  }
3769  }
3770 
3771  if (modOwner)
3772  {
3773  modOwner->SetSpellModTakingSpell(this, false);
3774 
3775  //Clear spell cooldowns after every spell is cast if .cheat cooldown is enabled.
3777  {
3780  }
3781  }
3782 
3783  SetExecutedCurrently(false);
3784 
3785  if (!m_originalCaster)
3786  return;
3787 
3788  // Handle procs on cast
3789  ProcFlagsInit procAttacker = m_procAttacker;
3790  if (!procAttacker)
3791  {
3793  {
3794  if (IsPositive())
3795  procAttacker |= PROC_FLAG_DEAL_HELPFUL_PERIODIC;
3796  else
3797  procAttacker |= PROC_FLAG_DEAL_HARMFUL_PERIODIC;
3798  }
3800  {
3801  if (IsPositive())
3802  procAttacker |= PROC_FLAG_DEAL_HELPFUL_ABILITY;
3803  else
3804  procAttacker |= PROC_FLAG_DEAL_HARMFUL_ABILITY;
3805  }
3806  else
3807  {
3808  if (IsPositive())
3809  procAttacker |= PROC_FLAG_DEAL_HELPFUL_SPELL;
3810  else
3811  procAttacker |= PROC_FLAG_DEAL_HARMFUL_SPELL;
3812  }
3813  }
3814 
3815  procAttacker |= PROC_FLAG_2_CAST_SUCCESSFUL;
3816 
3817  ProcFlagsHit hitMask = m_hitMask;
3818  if (!(hitMask & PROC_HIT_CRITICAL))
3819  hitMask |= PROC_HIT_NORMAL;
3820 
3823 
3825  Unit::ProcSkillsAndAuras(m_originalCaster, nullptr, procAttacker, PROC_FLAG_NONE, PROC_SPELL_TYPE_MASK_ALL, PROC_SPELL_PHASE_CAST, hitMask, this, nullptr, nullptr);
3826 
3827  // Call CreatureAI hook OnSpellCast
3828  if (Creature* caster = m_originalCaster->ToCreature())
3829  if (caster->IsAIEnabled())
3830  caster->AI()->OnSpellCast(GetSpellInfo());
3831 }
Definition: SharedDefines.h:874
bool IsChanneled() const
Definition: SpellInfo.cpp:1645
Definition: SharedDefines.h:5833
void handle_immediate()
Definition: Spell.cpp:3848
Item * GetItemTarget() const
Definition: SpellDefines.h:351
void UpdateTradeSlotItem()
Definition: Spell.cpp:307
void CallScriptAfterCastHandlers()
Definition: Spell.cpp:8406
static Player * ToPlayer(Object *o)
Definition: Object.h:198
uint32 id
Definition: EventMap.cpp:184
SpellInfo const *const m_spellInfo
Definition: Spell.h:532
uint32 m_spellState
Definition: Spell.h:866
Definition: Spell.h:223
Definition: Player.h:978
Definition: SpellMgr.h:163
Definition: SpellMgr.h:234
Definition: SpellDefines.h:283
TypeID GetTypeId() const
Definition: Object.h:170
bool HasHitDelay() const
Definition: SpellInfo.cpp:1682
TC_GAME_API Unit * GetUnit(WorldObject const &, ObjectGuid const &guid)
Definition: ObjectAccessor.cpp:206
bool IsPositive() const
Definition: Spell.cpp:7997
static void ProcSkillsAndAuras(Unit *actor, Unit *actionTarget, ProcFlagsInit const &typeMaskActor, ProcFlagsInit const &typeMaskActionTarget, ProcFlagsSpellType spellTypeMask, ProcFlagsSpellPhase spellPhaseMask, ProcFlagsHit hitMask, Spell *spell, DamageInfo *damageInfo, HealInfo *healInfo)
Definition: Unit.cpp:5269
Definition: SpellMgr.h:151
SpellCastTargets m_targets
Definition: Spell.h:575
void TakeCastItem()
Definition: Spell.cpp:5116
void SendSpellGo()
Definition: Spell.cpp:4663
Definition: SharedDefines.h:509
static ObjectGuid GetGUID(Object const *o)
Definition: Object.h:156
Definition: SharedDefines.h:1454
WorldObject *const m_caster
Definition: Spell.h:649
In Spell::prepare, will be cast directly without setting containers for executed spell.
Definition: SpellDefines.h:249
Definition: SpellMgr.h:274
bool m_launchHandled
Definition: Spell.h:681
Definition: Object.h:430
static void SendCastResult(Player *caster, SpellInfo const *spellInfo, SpellCastVisual spellVisual, ObjectGuid cast_count, SpellCastResult result, SpellCustomErrors customError=SPELL_CUSTOM_ERROR_NONE, int32 *param1=nullptr, int32 *param2=nullptr)
Definition: Spell.cpp:4526
Definition: Creature.h:69
uint32 ChargeCategoryId
Definition: SpellInfo.h:431
Definition: SharedDefines.h:411
bool m_immediateHandled
Definition: Spell.h:682
Item * m_CastItem
Definition: Spell.h:533
Definition: Unit.h:257
Definition: SharedDefines.h:2715
void SetExecutedCurrently(bool yes)
Definition: Spell.h:598
float LaunchDelay
Definition: SpellInfo.h:406
Definition: SharedDefines.h:5834
DiminishingReturnsType GetDiminishingReturnsGroupType() const
Definition: SpellInfo.cpp:3189
uint32 const Id
Definition: SpellInfo.h:347
SpellHistory * GetSpellHistory()
Definition: Unit.h:1538
Unit * m_originalCaster
Definition: Spell.h:655
void finish(bool ok=true)
Definition: Spell.cpp:4194
ObjectGuid GetObjectTargetGUID() const
Definition: Spell.cpp:275
bool HasAttribute(SpellAttr0 attribute) const
Definition: SpellInfo.h:461
void TakePower()
Definition: Spell.cpp:5184
Definition: SpellMgr.h:134
Definition: SharedDefines.h:534
Definition: TradeData.h:34
Definition: SpellMgr.h:273
Definition: SharedDefines.h:543
Unit * GetUnitTarget() const
Definition: Spell.cpp:210
SpellInfo const * GetSpellInfo() const
Definition: Spell.h:614
Definition: SpellMgr.h:157
Definition: SpellMgr.h:154
Definition: Item.h:169
CastSpellExtraArgs & SetTriggeringSpell(Spell const *triggeringSpell)
Definition: Spell.cpp:9075
Definition: SpellMgr.h:254
#define sSpellMgr
Definition: SpellMgr.h:825
Definition: SpellInfo.h:233
int32_t int32
Definition: Define.h:139
Definition: CreatureAI.h:58
void SetSpellModTakingSpell(Spell *spell, bool apply)
Definition: Player.cpp:22671
uint32_t uint32
Definition: Define.h:143
void RemoveAurasWithInterruptFlags(InterruptFlags flag, SpellInfo const *source=nullptr)
Definition: Unit.cpp:3956
uint32 GetTargetMask() const
Definition: SpellDefines.h:330
bool GetCommandStatus(uint32 command) const
Definition: Player.h:1230
ProcFlagsHit m_hitMask
Definition: Spell.h:719
Definition: SpellMgr.h:160
ProcFlagsHit
Definition: SpellMgr.h:270
DiminishingReturnsType
Definition: SharedDefines.h:5830
void RestoreCharge(uint32 chargeCategoryId)
Definition: SpellHistory.cpp:840
Definition: SpellMgr.h:168
static Creature * ToCreature(Object *o)
Definition: Object.h:204
Will ignore power and reagent cost.
Definition: SpellDefines.h:244
void HandleLaunchPhase()
Definition: Spell.cpp:8150
std::vector< SpellEffectInfo > const & GetEffects() const
Definition: SpellInfo.h:589
TC_GAME_API Creature * GetCreature(WorldObject const &u, ObjectGuid const &guid)
Definition: ObjectAccessor.cpp:217
ControlList m_Controlled
Definition: Unit.h:1296
ProcFlagsInit m_procAttacker
Definition: Spell.h:717
void SendSpellCooldown()
Definition: Spell.cpp:4093
Definition: SharedDefines.h:1476
Definition: SpellDefines.h:434
uint32 GetEntry() const
Definition: Object.h:158
bool IsEmpty() const
Definition: ObjectGuid.h:310
void SetDelayStart(uint64 m_time)
Definition: Spell.h:600
Will ignore Spell and Category cooldowns.
Definition: SpellDefines.h:243
void ResetCooldown(uint32 spellId, bool update=false)
Definition: SpellHistory.cpp:622
Definition: ObjectGuid.h:40
void TakeReagents()
Definition: Spell.cpp:5301
void CallScriptBeforeCastHandlers()
Definition: Spell.cpp:8380
DiminishingGroup GetDiminishingReturnsGroupForSpell() const
Definition: SpellInfo.cpp:3184
Will return SPELL_FAILED_DONT_REPORT in CheckCast functions.
Definition: SpellDefines.h:260
Definition: UnitDefines.h:149
void cancel()
Definition: Spell.cpp:3467
Definition: SharedDefines.h:444
TradeData * GetTradeData() const
Definition: Player.h:1508
SpellCastResult
Definition: SharedDefines.h:1442
Player * GetSpellModOwner() const
Definition: Object.cpp:2148
#define sScriptMgr
Definition: ScriptMgr.h:1409
static Unit * ToUnit(Object *o)
Definition: Object.h:210
SpellCastResult CheckCast(bool strict, int32 *param1=nullptr, int32 *param2=nullptr)
Definition: Spell.cpp:5437
void SendInterrupted(uint8 result)
Definition: Spell.cpp:4982
Definition: SpellDefines.h:493
TriggerCastFlags _triggeredCastFlags
Definition: Spell.h:870
void CallScriptOnCastHandlers()
Definition: Spell.cpp:8393
Definition: Unit.h:746
void SelectSpellTargets()
Definition: Spell.cpp:727
SpellCastResult CastSpell(CastSpellTargetArg const &targets, uint32 spellId, CastSpellExtraArgs const &args={ })
Definition: Object.cpp:2730
Definition: Player.h:1131
WorldObject * GetObjectTarget() const
Definition: Spell.cpp:270
Definition: SharedDefines.h:1760
Definition: Spell.h:221
Definition: SpellMgr.h:262
bool UpdatePointers()
Definition: Spell.cpp:7780
void PrepareTriggersExecutedOnHit()
Definition: Spell.cpp:8635
Definition: SharedDefines.h:559
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ _handle_finish_phase()

void Spell::_handle_finish_phase ( )
4044 {
4045  if (Unit* unitCaster = m_caster->ToUnit())
4046  {
4047  // Take for real after all targets are processed
4048  if (m_needComboPoints)
4049  unitCaster->ClearComboPoints();
4050 
4051  // Real add combo points from effects
4052  if (m_comboPointGain)
4053  unitCaster->AddComboPoints(m_comboPointGain);
4054 
4056  unitCaster->SetLastExtraAttackSpell(m_spellInfo->Id);
4057  }
4058 
4059  // Handle procs on finish
4060  if (!m_originalCaster)
4061  return;
4062 
4063  ProcFlagsInit procAttacker = m_procAttacker;
4064  if (!procAttacker)
4065  {
4067  {
4068  if (IsPositive())
4069  procAttacker |= PROC_FLAG_DEAL_HELPFUL_PERIODIC;
4070  else
4071  procAttacker |= PROC_FLAG_DEAL_HARMFUL_PERIODIC;
4072  }
4074  {
4075  if (IsPositive())
4076  procAttacker |= PROC_FLAG_DEAL_HELPFUL_ABILITY;
4077  else
4078  procAttacker |= PROC_FLAG_DEAL_HARMFUL_ABILITY;
4079  }
4080  else
4081  {
4082  if (IsPositive())
4083  procAttacker |= PROC_FLAG_DEAL_HELPFUL_SPELL;
4084  else
4085  procAttacker |= PROC_FLAG_DEAL_HARMFUL_SPELL;
4086  }
4087  }
4088 
4091 }
SpellInfo const *const m_spellInfo
Definition: Spell.h:532
Definition: SpellMgr.h:163
bool IsPositive() const
Definition: Spell.cpp:7997
int8 m_comboPointGain
Definition: Spell.h:576
static void ProcSkillsAndAuras(Unit *actor, Unit *actionTarget, ProcFlagsInit const &typeMaskActor, ProcFlagsInit const &typeMaskActionTarget, ProcFlagsSpellType spellTypeMask, ProcFlagsSpellPhase spellPhaseMask, ProcFlagsHit hitMask, Spell *spell, DamageInfo *damageInfo, HealInfo *healInfo)
Definition: Unit.cpp:5269
Definition: SpellMgr.h:151
bool HasEffect(SpellEffectName effect) const
Definition: SpellInfo.cpp:1318
WorldObject *const m_caster
Definition: Spell.h:649
Definition: SharedDefines.h:1167
Definition: SharedDefines.h:411
Definition: SpellMgr.h:264
uint32 const Id
Definition: SpellInfo.h:347
Unit * m_originalCaster
Definition: Spell.h:655
bool HasAttribute(SpellAttr0 attribute) const
Definition: SpellInfo.h:461
Definition: SpellMgr.h:134
Definition: SharedDefines.h:534
Definition: SharedDefines.h:543
Definition: SpellMgr.h:157
Definition: SpellMgr.h:154
Definition: SpellMgr.h:254
ProcFlagsHit m_hitMask
Definition: Spell.h:719
Definition: SpellMgr.h:160
Definition: SpellMgr.h:168
ProcFlagsInit m_procAttacker
Definition: Spell.h:717
static Unit * ToUnit(Object *o)
Definition: Object.h:210
Definition: SpellDefines.h:493
Definition: Unit.h:746
bool m_needComboPoints
Definition: Spell.h:687
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ _handle_immediate_phase()

void Spell::_handle_immediate_phase ( )
4024 {
4025  // handle some immediate features of the spell here
4027 
4028  // handle effects with SPELL_EFFECT_HANDLE_HIT mode
4029  for (SpellEffectInfo const& spellEffectInfo : m_spellInfo->GetEffects())
4030  {
4031  // don't do anything for empty effect
4032  if (!spellEffectInfo.IsEffect())
4033  continue;
4034 
4035  // call effect handlers to handle destination hit
4036  HandleEffects(nullptr, nullptr, nullptr, nullptr, spellEffectInfo, SPELL_EFFECT_HANDLE_HIT);
4037  }
4038 
4039  // process items
4041 }
SpellInfo const *const m_spellInfo
Definition: Spell.h:532
std::vector< ItemTargetInfo > m_UniqueItemInfo
Definition: Spell.h:785
Definition: Spell.h:230
Definition: SpellInfo.h:233
std::vector< SpellEffectInfo > const & GetEffects() const
Definition: SpellInfo.h:589
void HandleThreatSpells()
Definition: Spell.cpp:5355
void DoProcessTargetContainer(Container &targetContainer)
Definition: Spell.cpp:3834
void HandleEffects(Unit *pUnitTarget, Item *pItemTarget, GameObject *pGoTarget, Corpse *pCorpseTarget, SpellEffectInfo const &spellEffectInfo, SpellEffectHandleMode mode)
Definition: Spell.cpp:5411
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ AddCorpseTarget()

void Spell::AddCorpseTarget ( Corpse target,
uint32  effectMask 
)
protected
2470 {
2471  for (SpellEffectInfo const& spellEffectInfo : m_spellInfo->GetEffects())
2472  if (!spellEffectInfo.IsEffect())
2473  effectMask &= ~(1 << spellEffectInfo.EffectIndex);
2474 
2475  // no effects left
2476  if (!effectMask)
2477  return;
2478 
2479  ObjectGuid targetGUID = corpse->GetGUID();
2480 
2481  // Lookup target in already in list
2482  auto ihit = std::find_if(std::begin(m_UniqueCorpseTargetInfo), std::end(m_UniqueCorpseTargetInfo), [targetGUID](CorpseTargetInfo const& target) { return target.TargetGUID == targetGUID; });
2483  if (ihit != std::end(m_UniqueCorpseTargetInfo)) // Found in list
2484  {
2485  // Add only effect mask
2486  ihit->EffectMask |= effectMask;
2487  return;
2488  }
2489 
2490  // This is new target calculate data for him
2491  CorpseTargetInfo target;
2492  target.TargetGUID = targetGUID;
2493  target.EffectMask = effectMask;
2494 
2495  // Spell have speed - need calculate incoming time
2496  if (m_caster != corpse)
2497  {
2498  float hitDelay = m_spellInfo->LaunchDelay;
2500  hitDelay += m_spellInfo->Speed;
2501  else if (m_spellInfo->Speed > 0.0f)
2502  {
2503  // calculate spell incoming interval
2504  float dist = std::max(m_caster->GetDistance(corpse->GetPositionX(), corpse->GetPositionY(), corpse->GetPositionZ()), 5.0f);
2505  hitDelay += dist / m_spellInfo->Speed;
2506  }
2507 
2508  target.TimeDelay = uint64(std::floor(hitDelay * 1000.0f));
2509  }
2510  else
2511  target.TimeDelay = 0LL;
2512 
2513  // Calculate minimum incoming time
2514  if (target.TimeDelay && (!m_delayMoment || m_delayMoment > target.TimeDelay))
2515  m_delayMoment = target.TimeDelay;
2516 
2517  // Add target to list
2518  m_UniqueCorpseTargetInfo.emplace_back(std::move(target));
2519 }
SpellInfo const *const m_spellInfo
Definition: Spell.h:532
std::vector< CorpseTargetInfo > m_UniqueCorpseTargetInfo
Definition: Spell.h:794
WorldObject *const m_caster
Definition: Spell.h:649
Definition: SharedDefines.h:744
float LaunchDelay
Definition: SpellInfo.h:406
bool HasAttribute(SpellAttr0 attribute) const
Definition: SpellInfo.h:461
uint64 m_delayMoment
Definition: Spell.h:680
Definition: SpellInfo.h:233
uint64_t uint64
Definition: Define.h:142
float GetDistance(WorldObject const *obj) const
Definition: Object.cpp:986
std::vector< SpellEffectInfo > const & GetEffects() const
Definition: SpellInfo.h:589
float Speed
Definition: SpellInfo.h:405
Definition: ObjectGuid.h:258
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ AddDestTarget()

void Spell::AddDestTarget ( SpellDestination const &  dest,
uint32  effIndex 
)
protected
2522 {
2523  m_destTargets[effIndex] = dest;
2524 }
SpellDestination m_destTargets[MAX_SPELL_EFFECTS]
Definition: Spell.h:799
+ Here is the caller graph for this function:

◆ AddGOTarget()

void Spell::AddGOTarget ( GameObject target,
uint32  effectMask 
)
protected
2389 {
2390  for (SpellEffectInfo const& spellEffectInfo : m_spellInfo->GetEffects())
2391  if (!spellEffectInfo.IsEffect() || !CheckEffectTarget(go, spellEffectInfo))
2392  effectMask &= ~(1 << spellEffectInfo.EffectIndex);
2393 
2394  // no effects left
2395  if (!effectMask)
2396  return;
2397 
2398  ObjectGuid targetGUID = go->GetGUID();
2399 
2400  // Lookup target in already in list
2401  auto ihit = std::find_if(std::begin(m_UniqueGOTargetInfo), std::end(m_UniqueGOTargetInfo), [targetGUID](GOTargetInfo const& target) { return target.TargetGUID == targetGUID; });
2402  if (ihit != std::end(m_UniqueGOTargetInfo)) // Found in list
2403  {
2404  // Add only effect mask
2405  ihit->EffectMask |= effectMask;
2406  return;
2407  }
2408 
2409  // This is new target calculate data for him
2410 
2411  GOTargetInfo target;
2412  target.TargetGUID = targetGUID;
2413  target.EffectMask = effectMask;
2414 
2415  // Spell have speed - need calculate incoming time
2416  if (static_cast<WorldObject*>(m_caster) != go)
2417  {
2418  float hitDelay = m_spellInfo->LaunchDelay;
2420  hitDelay += m_spellInfo->Speed;
2421  else if (m_spellInfo->Speed > 0.0f)
2422  {
2423  // calculate spell incoming interval
2424  float dist = std::max(m_caster->GetDistance(go->GetPositionX(), go->GetPositionY(), go->GetPositionZ()), 5.0f);
2425  hitDelay += dist / m_spellInfo->Speed;
2426  }
2427 
2428  target.TimeDelay = uint64(std::floor(hitDelay * 1000.0f));
2429  }
2430  else
2431  target.TimeDelay = 0ULL;
2432 
2433  // Calculate minimum incoming time
2434  if (target.TimeDelay && (!m_delayMoment || m_delayMoment > target.TimeDelay))
2435  m_delayMoment = target.TimeDelay;
2436 
2437  // Add target to list
2438  m_UniqueGOTargetInfo.emplace_back(std::move(target));
2439 }
SpellInfo const *const m_spellInfo
Definition: Spell.h:532
WorldObject *const m_caster
Definition: Spell.h:649
Definition: SharedDefines.h:744
float LaunchDelay
Definition: SpellInfo.h:406
bool HasAttribute(SpellAttr0 attribute) const
Definition: SpellInfo.h:461
uint64 m_delayMoment
Definition: Spell.h:680
Definition: SpellInfo.h:233
uint64_t uint64
Definition: Define.h:142
float GetDistance(WorldObject const *obj) const
Definition: Object.cpp:986
std::vector< SpellEffectInfo > const & GetEffects() const
Definition: SpellInfo.h:589
float Speed
Definition: SpellInfo.h:405
std::vector< GOTargetInfo > m_UniqueGOTargetInfo
Definition: Spell.h:777
bool CheckEffectTarget(Unit const *target, SpellEffectInfo const &spellEffectInfo, Position const *losPosition) const
Definition: Spell.cpp:7852
Definition: ObjectGuid.h:258
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ AddItemTarget()

void Spell::AddItemTarget ( Item item,
uint32  effectMask 
)
protected
2442 {
2443  for (SpellEffectInfo const& spellEffectInfo : m_spellInfo->GetEffects())
2444  if (!spellEffectInfo.IsEffect() || !CheckEffectTarget(item, spellEffectInfo))
2445  effectMask &= ~(1 << spellEffectInfo.EffectIndex);
2446 
2447  // no effects left
2448  if (!effectMask)
2449  return;
2450 
2451  // Lookup target in already in list
2452  auto ihit = std::find_if(std::begin(m_UniqueItemInfo), std::end(m_UniqueItemInfo), [item](ItemTargetInfo const& target) { return target.TargetItem == item; });
2453  if (ihit != std::end(m_UniqueItemInfo)) // Found in list
2454  {
2455  // Add only effect mask
2456  ihit->EffectMask |= effectMask;
2457  return;
2458  }
2459 
2460  // This is new target add data
2461 
2462  ItemTargetInfo target;
2463  target.TargetItem = item;
2464  target.EffectMask = effectMask;
2465 
2466  m_UniqueItemInfo.emplace_back(std::move(target));
2467 }
SpellInfo const *const m_spellInfo
Definition: Spell.h:532
std::vector< ItemTargetInfo > m_UniqueItemInfo
Definition: Spell.h:785
Definition: SpellInfo.h:233
std::vector< SpellEffectInfo > const & GetEffects() const
Definition: SpellInfo.h:589
bool CheckEffectTarget(Unit const *target, SpellEffectInfo const &spellEffectInfo, Position const *losPosition) const
Definition: Spell.cpp:7852
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ AddUnitTarget()

void Spell::AddUnitTarget ( Unit target,
uint32  effectMask,
bool  checkIfValid = true,
bool  implicit = true,
Position const *  losPosition = nullptr 
)
protected
Todo:
this is a hack
2282 {
2283  for (SpellEffectInfo const& spellEffectInfo : m_spellInfo->GetEffects())
2284  if (!spellEffectInfo.IsEffect() || !CheckEffectTarget(target, spellEffectInfo, losPosition))
2285  effectMask &= ~(1 << spellEffectInfo.EffectIndex);
2286 
2287  // no effects left
2288  if (!effectMask)
2289  return;
2290 
2291  if (checkIfValid)
2292  if (m_spellInfo->CheckTarget(m_caster, target, implicit) != SPELL_CAST_OK) // skip stealth checks for AOE
2293  return;
2294 
2295  // Check for effect immune skip if immuned
2296  for (SpellEffectInfo const& spellEffectInfo : m_spellInfo->GetEffects())
2297  if (target->IsImmunedToSpellEffect(m_spellInfo, spellEffectInfo, m_caster))
2298  effectMask &= ~(1 << spellEffectInfo.EffectIndex);
2299 
2300  ObjectGuid targetGUID = target->GetGUID();
2301 
2302  // Lookup target in already in list
2303  auto ihit = std::find_if(std::begin(m_UniqueTargetInfo), std::end(m_UniqueTargetInfo), [targetGUID](TargetInfo const& target) { return target.TargetGUID == targetGUID; });
2304  if (ihit != std::end(m_UniqueTargetInfo)) // Found in list
2305  {
2306  // Immune effects removed from mask
2307  ihit->EffectMask |= effectMask;
2308  return;
2309  }
2310 
2311  // This is new target calculate data for him
2312 
2313  // Get spell hit result on target
2314  TargetInfo targetInfo;
2315  targetInfo.TargetGUID = targetGUID; // Store target GUID
2316  targetInfo.EffectMask = effectMask; // Store all effects not immune
2317  targetInfo.IsAlive = target->IsAlive();
2318  targetInfo.Damage = 0;
2319  targetInfo.Healing = 0;
2320  targetInfo.IsCrit = false;
2321 
2322  // Calculate hit result
2324  targetInfo.MissCondition = caster->SpellHitResult(target, m_spellInfo, m_canReflect && !(IsPositive() && m_caster->IsFriendlyTo(target)));
2325 
2326  // Spell have speed - need calculate incoming time
2327  // Incoming time is zero for self casts. At least I think so.
2328  if (m_caster != target)
2329  {
2330  float hitDelay = m_spellInfo->LaunchDelay;
2331  WorldObject const* missileSource = m_caster;
2333  {
2334  auto previousTargetItr = std::find_if(m_UniqueTargetInfo.rbegin(), m_UniqueTargetInfo.rend(), [effectMask](TargetInfo const& target)
2335  {
2336  return (target.EffectMask & effectMask) != 0;
2337  });
2338  if (previousTargetItr != std::rend(m_UniqueTargetInfo))
2339  {
2340  hitDelay = 0.0f; // this is not the first target in chain, LaunchDelay was already included
2341 
2342  if (WorldObject* previousTarget = ObjectAccessor::GetWorldObject(*m_caster, previousTargetItr->TargetGUID))
2343  missileSource = previousTarget;
2344 
2345  targetInfo.TimeDelay += previousTargetItr->TimeDelay;
2346  }
2347  }
2348 
2350  hitDelay += m_spellInfo->Speed;
2351  else if (m_spellInfo->Speed > 0.0f)
2352  {
2353  // calculate spell incoming interval
2355  float dist = std::max(missileSource->GetDistance(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ()), 5.0f);
2356  hitDelay += dist / m_spellInfo->Speed;
2357  }
2358 
2359  targetInfo.TimeDelay += uint64(std::floor(hitDelay * 1000.0f));
2360  }
2361  else
2362  targetInfo.TimeDelay = 0ULL;
2363 
2364  // If target reflect spell back to caster
2365  if (targetInfo.MissCondition == SPELL_MISS_REFLECT)
2366  {
2367  // Calculate reflected spell result on caster (shouldn't be able to reflect gameobject spells)
2368  Unit* unitCaster = ASSERT_NOTNULL(m_caster->ToUnit());
2369  targetInfo.ReflectResult = unitCaster->SpellHitResult(unitCaster, m_spellInfo, false); // can't reflect twice
2370 
2371  // Proc spell reflect aura when missile hits the original target
2372  target->m_Events.AddEvent(new ProcReflectDelayed(target, m_originalCasterGUID), target->m_Events.CalculateTime(Milliseconds(targetInfo.TimeDelay)));
2373 
2374  // Increase time interval for reflected spells by 1.5
2375  targetInfo.TimeDelay += targetInfo.TimeDelay >> 1;
2376  }
2377  else
2378  targetInfo.ReflectResult = SPELL_MISS_NONE;
2379 
2380  // Calculate minimum incoming time
2381  if (targetInfo.TimeDelay && (!m_delayMoment || m_delayMoment > targetInfo.TimeDelay))
2382  m_delayMoment = targetInfo.TimeDelay;
2383 
2384  // Add target to list
2385  m_UniqueTargetInfo.emplace_back(std::move(targetInfo));
2386 }
SpellMissInfo SpellHitResult(Unit *victim, SpellInfo const *spellInfo, bool canReflect=false) const
Definition: Object.cpp:2474
SpellInfo const *const m_spellInfo
Definition: Spell.h:532
bool IsPositive() const
Definition: Spell.cpp:7997
bool m_canReflect
Definition: Spell.h:664
static ObjectGuid GetGUID(Object const *o)
Definition: Object.h:156
WorldObject *const m_caster
Definition: Spell.h:649
Definition: Spell.cpp:2255
Definition: Object.h:430
virtual bool IsImmunedToSpellEffect(SpellInfo const *spellInfo, SpellEffectInfo const &spellEffectInfo, WorldObject const *caster) const
Definition: Unit.cpp:7317
Definition: SharedDefines.h:744
#define ASSERT_NOTNULL(pointer)
Definition: Errors.h:84
TC_GAME_API WorldObject * GetWorldObject(WorldObject const &, ObjectGuid const &)
Definition: ObjectAccessor.cpp:101
float LaunchDelay
Definition: SpellInfo.h:406
std::chrono::milliseconds Milliseconds
Milliseconds shorthand typedef.
Definition: Duration.h:24
Definition: SharedDefines.h:573
std::vector< TargetInfo > m_UniqueTargetInfo
Definition: Spell.h:767
Unit * m_originalCaster
Definition: Spell.h:655
bool HasAttribute(SpellAttr0 attribute) const
Definition: SpellInfo.h:461
uint64 m_delayMoment
Definition: Spell.h:680
Definition: SpellInfo.h:233
uint64_t uint64
Definition: Define.h:142
SpellCastResult CheckTarget(WorldObject const *caster, WorldObject const *target, bool implicit=true) const
Definition: SpellInfo.cpp:2096
float GetDistance(WorldObject const *obj) const
Definition: Object.cpp:986
std::vector< SpellEffectInfo > const & GetEffects() const
Definition: SpellInfo.h:589
Definition: SharedDefines.h:2686
float Speed
Definition: SpellInfo.h:405
ObjectGuid m_originalCasterGUID
Definition: Spell.h:653
bool IsFriendlyTo(WorldObject const *target) const
Definition: Object.cpp:2699
Definition: SharedDefines.h:2697
bool CheckEffectTarget(Unit const *target, SpellEffectInfo const &spellEffectInfo, Position const *losPosition) const
Definition: Spell.cpp:7852
Definition: ObjectGuid.h:258
static Unit * ToUnit(Object *o)
Definition: Object.h:210
Definition: Unit.h:746
Definition: SharedDefines.h:1760
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ CalculateDamage()

int32 Spell::CalculateDamage ( SpellEffectInfo const &  spellEffectInfo,
Unit const *  target,
float *  var = nullptr 
) const
6894 {
6895  bool needRecalculateBasePoints = !(m_spellValue->CustomBasePointsMask & (1 << spellEffectInfo.EffectIndex));
6896  return m_caster->CalculateSpellDamage(target, spellEffectInfo, needRecalculateBasePoints ? nullptr : &m_spellValue->EffectBasePoints[spellEffectInfo.EffectIndex], var, m_castItemEntry, m_castItemLevel);
6897 }
int32 CalculateSpellDamage(Unit const *target, SpellEffectInfo const &spellEffectInfo, int32 const *basePoints=nullptr, float *variance=nullptr, uint32 castItemId=0, int32 itemLevel=-1) const
Definition: Object.cpp:2173
WorldObject *const m_caster
Definition: Spell.h:649
uint32 m_castItemEntry
Definition: Spell.h:535
SpellValue *const m_spellValue
Definition: Spell.h:651
uint32 CustomBasePointsMask
Definition: Spell.h:207
int32 EffectBasePoints[MAX_SPELL_EFFECTS]
Definition: Spell.h:206
int32 m_castItemLevel
Definition: Spell.h:536
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ CalculateDelayMomentForDst()

uint64 Spell::CalculateDelayMomentForDst ( float  launchDelay) const
823 {
824  if (m_targets.HasDst())
825  {
826  if (m_targets.HasTraj())
827  {
828  float speed = m_targets.GetSpeedXY();
829  if (speed > 0.0f)
830  return uint64(std::floor((m_targets.GetDist2d() / speed + launchDelay) * 1000.0f));
831  }
833  return uint64(std::floor((m_spellInfo->Speed + launchDelay) * 1000.0f));
834  else if (m_spellInfo->Speed > 0.0f)
835  {
836  // We should not subtract caster size from dist calculation (fixes execution time desync with animation on client, eg. Malleable Goo cast by PP)
837  float dist = m_caster->GetExactDist(*m_targets.GetDstPos());
838  return uint64(std::floor((dist / m_spellInfo->Speed + launchDelay) * 1000.0f));
839  }
840 
841  return uint64(std::floor(launchDelay * 1000.0f));
842  }
843 
844  return 0;
845 }
SpellInfo const *const m_spellInfo
Definition: Spell.h:532
SpellCastTargets m_targets
Definition: Spell.h:575
WorldObject *const m_caster
Definition: Spell.h:649
float GetSpeedXY() const
Definition: SpellDefines.h:386
Definition: SharedDefines.h:744
float GetDist2d() const
Definition: SpellDefines.h:385
bool HasAttribute(SpellAttr0 attribute) const
Definition: SpellInfo.h:461
uint64_t uint64
Definition: Define.h:142
bool HasDst() const
Definition: Spell.cpp:417
float Speed
Definition: SpellInfo.h:405
WorldLocation const * GetDstPos() const
Definition: Spell.cpp:360
bool HasTraj() const
Definition: SpellDefines.h:378
float GetExactDist(float x, float y, float z) const
Definition: Position.h:119
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ CalculateJumpSpeeds()

void Spell::CalculateJumpSpeeds ( SpellEffectInfo const *  effInfo,
float  dist,
float &  speedXY,
float &  speedZ 
)
protected
809 {
810  Unit* unitCaster = GetUnitCasterForEffectHandlers();
811  ASSERT(unitCaster);
812  float runSpeed = unitCaster->IsControlledByPlayer() ? playerBaseMoveSpeed[MOVE_RUN] : baseMoveSpeed[MOVE_RUN];
813  if (Creature* creature = unitCaster->ToCreature())
814  runSpeed *= creature->GetCreatureTemplate()->speed_run;
815 
816  float multiplier = effInfo->Amplitude;
817  if (multiplier <= 0.0f)
818  multiplier = 1.0f;
819 
820  speedXY = std::min(runSpeed * 3.0f * multiplier, std::max(28.0f, unitCaster->GetSpeed(MOVE_RUN) * 4.0f));
821 
822  float duration = dist / speedXY;
823  float durationSqr = duration * duration;
824  float minHeight = effInfo->MiscValue ? effInfo->MiscValue / 10.0f : 0.5f; // Lower bound is blizzlike
825  float maxHeight = effInfo->MiscValueB ? effInfo->MiscValueB / 10.0f : 1000.0f; // Upper bound is unknown
826  float height;
827  if (durationSqr < minHeight * 8 / Movement::gravity)
828  height = minHeight;
829  else if (durationSqr > maxHeight * 8 / Movement::gravity)
830  height = maxHeight;
831  else
832  height = Movement::gravity * durationSqr / 8;
833 
834  speedZ = std::sqrt(2 * Movement::gravity * height);
835 }
Definition: Creature.h:69
Definition: UnitDefines.h:109
float GetSpeed(UnitMoveType mtype) const
Definition: Unit.cpp:8242
float constexpr gravity
Definition: MovementTypedefs.h:79
float playerBaseMoveSpeed[MAX_MOVE_TYPE]
Definition: Unit.cpp:102
static Creature * ToCreature(Object *o)
Definition: Object.h:204
Unit * GetUnitCasterForEffectHandlers() const
Definition: Spell.cpp:8008
float baseMoveSpeed[MAX_MOVE_TYPE]
Definition: Unit.cpp:89
#define ASSERT
Definition: Errors.h:68
Definition: Unit.h:746
bool IsControlledByPlayer() const
Definition: Unit.h:1278
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ CallScriptAfterCastHandlers()

void Spell::CallScriptAfterCastHandlers ( )
protected
8407 {
8408  for (auto scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8409  {
8410  (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_AFTER_CAST);
8411  auto hookItrEnd = (*scritr)->AfterCast.end(), hookItr = (*scritr)->AfterCast.begin();
8412  for (; hookItr != hookItrEnd; ++hookItr)
8413  (*hookItr).Call(*scritr);
8414 
8415  (*scritr)->_FinishScriptCall();
8416  }
8417 }
std::vector< SpellScript * > m_loadedScripts
Definition: Spell.h:838
Definition: SpellScript.h:216
+ Here is the caller graph for this function:

◆ CallScriptAfterHitHandlers()

void Spell::CallScriptAfterHitHandlers ( )
protected
8529 {
8530  for (auto scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8531  {
8532  (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_AFTER_HIT);
8533  auto hookItrEnd = (*scritr)->AfterHit.end(), hookItr = (*scritr)->AfterHit.begin();
8534  for (; hookItr != hookItrEnd; ++hookItr)
8535  (*hookItr).Call(*scritr);
8536 
8537  (*scritr)->_FinishScriptCall();
8538  }
8539 }
Definition: SpellScript.h:208
std::vector< SpellScript * > m_loadedScripts
Definition: Spell.h:838
+ Here is the caller graph for this function:

◆ CallScriptBeforeCastHandlers()

void Spell::CallScriptBeforeCastHandlers ( )
protected
8381 {
8382  for (auto scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8383  {
8384  (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_BEFORE_CAST);
8385  auto hookItrEnd = (*scritr)->BeforeCast.end(), hookItr = (*scritr)->BeforeCast.begin();
8386  for (; hookItr != hookItrEnd; ++hookItr)
8387  (*hookItr).Call(*scritr);
8388 
8389  (*scritr)->_FinishScriptCall();
8390  }
8391 }
std::vector< SpellScript * > m_loadedScripts
Definition: Spell.h:838
Definition: SpellScript.h:213
+ Here is the caller graph for this function:

◆ CallScriptBeforeHitHandlers()

void Spell::CallScriptBeforeHitHandlers ( SpellMissInfo  missInfo)
protected
8502 {
8503  for (auto scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8504  {
8505  (*scritr)->_InitHit();
8506  (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_BEFORE_HIT);
8507  auto hookItrEnd = (*scritr)->BeforeHit.end(), hookItr = (*scritr)->BeforeHit.begin();
8508  for (; hookItr != hookItrEnd; ++hookItr)
8509  (*hookItr).Call(*scritr, missInfo);
8510 
8511  (*scritr)->_FinishScriptCall();
8512  }
8513 }
std::vector< SpellScript * > m_loadedScripts
Definition: Spell.h:838
Definition: SpellScript.h:206
+ Here is the caller graph for this function:

◆ CallScriptCalcCritChanceHandlers()

void Spell::CallScriptCalcCritChanceHandlers ( Unit const *  victim,
float &  chance 
)
8542 {
8543  for (SpellScript* loadedScript : m_loadedScripts)
8544  {
8545  loadedScript->_PrepareScriptCall(SPELL_SCRIPT_HOOK_CALC_CRIT_CHANCE);
8546  for (SpellScript::OnCalcCritChanceHandler const& hook : loadedScript->OnCalcCritChance)
8547  hook.Call(loadedScript, victim, critChance);
8548 
8549  loadedScript->_FinishScriptCall();
8550  }
8551 }
std::vector< SpellScript * > m_loadedScripts
Definition: Spell.h:838
Definition: SpellScript.h:224
Definition: SpellScript.h:315
void Call(SpellScript *spellScript, Unit const *victim, float &critChance) const
Definition: SpellScript.cpp:300
Definition: SpellScript.h:217
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ CallScriptCheckCastHandlers()

SpellCastResult Spell::CallScriptCheckCastHandlers ( )
protected
8420 {
8421  SpellCastResult retVal = SPELL_CAST_OK;
8422  for (auto scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8423  {
8424  (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_CHECK_CAST);
8425  auto hookItrEnd = (*scritr)->OnCheckCast.end(), hookItr = (*scritr)->OnCheckCast.begin();
8426  for (; hookItr != hookItrEnd; ++hookItr)
8427  {
8428  SpellCastResult tempResult = (*hookItr).Call(*scritr);
8429  if (retVal == SPELL_CAST_OK)
8430  retVal = tempResult;
8431  }
8432 
8433  (*scritr)->_FinishScriptCall();
8434  }
8435  return retVal;
8436 }
std::vector< SpellScript * > m_loadedScripts
Definition: Spell.h:838
SpellCastResult
Definition: SharedDefines.h:1442
Definition: SharedDefines.h:1760
Definition: SpellScript.h:212
+ Here is the caller graph for this function:

◆ CallScriptDestinationTargetSelectHandlers()

void Spell::CallScriptDestinationTargetSelectHandlers ( SpellDestination target,
SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType 
)
protected
8582 {
8583  for (auto scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8584  {
8585  (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_DESTINATION_TARGET_SELECT);
8586  auto hookItrEnd = (*scritr)->OnDestinationTargetSelect.end(), hookItr = (*scritr)->OnDestinationTargetSelect.begin();
8587  for (; hookItr != hookItrEnd; ++hookItr)
8588  if (hookItr->IsEffectAffected(m_spellInfo, effIndex) && targetType.GetTarget() == hookItr->GetTarget())
8589  hookItr->Call(*scritr, target);
8590 
8591  (*scritr)->_FinishScriptCall();
8592  }
8593 }
SpellInfo const *const m_spellInfo
Definition: Spell.h:532
std::vector< SpellScript * > m_loadedScripts
Definition: Spell.h:838
Definition: SpellScript.h:211
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ CallScriptEffectHandlers()

bool Spell::CallScriptEffectHandlers ( SpellEffIndex  effIndex,
SpellEffectHandleMode  mode 
)
protected
8439 {
8440  // execute script effect handler hooks and check if effects was prevented
8441  bool preventDefault = false;
8442  for (auto scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8443  {
8444  (*scritr)->_InitHit();
8445 
8447  SpellScriptHookType hookType;
8448  switch (mode)
8449  {
8451  effItr = (*scritr)->OnEffectLaunch.begin();
8452  effEndItr = (*scritr)->OnEffectLaunch.end();
8454  break;
8456  effItr = (*scritr)->OnEffectLaunchTarget.begin();
8457  effEndItr = (*scritr)->OnEffectLaunchTarget.end();
8459  break;
8461  effItr = (*scritr)->OnEffectHit.begin();
8462  effEndItr = (*scritr)->OnEffectHit.end();
8463  hookType = SPELL_SCRIPT_HOOK_EFFECT_HIT;
8464  break;
8466  effItr = (*scritr)->OnEffectHitTarget.begin();
8467  effEndItr = (*scritr)->OnEffectHitTarget.end();
8469  break;
8470  default:
8471  ABORT();
8472  return false;
8473  }
8474  (*scritr)->_PrepareScriptCall(hookType);
8475  for (; effItr != effEndItr; ++effItr)
8476  // effect execution can be prevented
8477  if (!(*scritr)->_IsEffectPrevented(effIndex) && (*effItr).IsEffectAffected(m_spellInfo, effIndex))
8478  (*effItr).Call(*scritr, effIndex);
8479 
8480  if (!preventDefault)
8481  preventDefault = (*scritr)->_IsDefaultEffectPrevented(effIndex);
8482 
8483  (*scritr)->_FinishScriptCall();
8484  }
8485  return preventDefault;
8486 }
SpellScriptHookType
Definition: SpellScript.h:199
Definition: SpellScript.h:203
SpellInfo const *const m_spellInfo
Definition: Spell.h:532
iterator end()
Definition: Util.h:424
std::vector< SpellScript * > m_loadedScripts
Definition: Spell.h:838
iterator begin()
Definition: Util.h:419
Definition: SpellScript.h:202
Definition: Spell.h:231
Definition: Spell.h:230
Definition: Spell.h:229
Definition: SpellScript.h:204
#define ABORT
Definition: Errors.h:74
Definition: SpellScript.h:201
Definition: Util.h:397
Definition: Spell.h:228
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ CallScriptObjectAreaTargetSelectHandlers()

void Spell::CallScriptObjectAreaTargetSelectHandlers ( std::list< WorldObject *> &  targets,
SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType 
)
protected
8554 {
8555  for (auto scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8556  {
8557  (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_OBJECT_AREA_TARGET_SELECT);
8558  auto hookItrEnd = (*scritr)->OnObjectAreaTargetSelect.end(), hookItr = (*scritr)->OnObjectAreaTargetSelect.begin();
8559  for (; hookItr != hookItrEnd; ++hookItr)
8560  if (hookItr->IsEffectAffected(m_spellInfo, effIndex) && targetType.GetTarget() == hookItr->GetTarget())
8561  hookItr->Call(*scritr, targets);
8562 
8563  (*scritr)->_FinishScriptCall();
8564  }
8565 }
SpellInfo const *const m_spellInfo
Definition: Spell.h:532
std::vector< SpellScript * > m_loadedScripts
Definition: Spell.h:838
Definition: SpellScript.h:209
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ CallScriptObjectTargetSelectHandlers()

void Spell::CallScriptObjectTargetSelectHandlers ( WorldObject *&  target,
SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType 
)
protected
8568 {
8569  for (auto scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8570  {
8571  (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_OBJECT_TARGET_SELECT);
8572  auto hookItrEnd = (*scritr)->OnObjectTargetSelect.end(), hookItr = (*scritr)->OnObjectTargetSelect.begin();
8573  for (; hookItr != hookItrEnd; ++hookItr)
8574  if (hookItr->IsEffectAffected(m_spellInfo, effIndex) && targetType.GetTarget() == hookItr->GetTarget())
8575  hookItr->Call(*scritr, target);
8576 
8577  (*scritr)->_FinishScriptCall();
8578  }
8579 }
Definition: SpellScript.h:210
SpellInfo const *const m_spellInfo
Definition: Spell.h:532
std::vector< SpellScript * > m_loadedScripts
Definition: Spell.h:838
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ CallScriptOnCastHandlers()

void Spell::CallScriptOnCastHandlers ( )
protected
8394 {
8395  for (auto scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8396  {
8397  (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_ON_CAST);
8398  auto hookItrEnd = (*scritr)->OnCast.end(), hookItr = (*scritr)->OnCast.begin();
8399  for (; hookItr != hookItrEnd; ++hookItr)
8400  (*hookItr).Call(*scritr);
8401 
8402  (*scritr)->_FinishScriptCall();
8403  }
8404 }
std::vector< SpellScript * > m_loadedScripts
Definition: Spell.h:838
Definition: SpellScript.h:214
+ Here is the caller graph for this function:

◆ CallScriptOnHitHandlers()

void Spell::CallScriptOnHitHandlers ( )
protected
8516 {
8517  for (auto scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8518  {
8519  (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_HIT);
8520  auto hookItrEnd = (*scritr)->OnHit.end(), hookItr = (*scritr)->OnHit.begin();
8521  for (; hookItr != hookItrEnd; ++hookItr)
8522  (*hookItr).Call(*scritr);
8523 
8524  (*scritr)->_FinishScriptCall();
8525  }
8526 }
Definition: SpellScript.h:207
std::vector< SpellScript * > m_loadedScripts
Definition: Spell.h:838
+ Here is the caller graph for this function:

◆ CallScriptOnPrecastHandler()

void Spell::CallScriptOnPrecastHandler ( )
protected
8371 {
8372  for (auto scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8373  {
8374  (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_ON_PRECAST);
8375  (*scritr)->OnPrecast();
8376  (*scritr)->_FinishScriptCall();
8377  }
8378 }
std::vector< SpellScript * > m_loadedScripts
Definition: Spell.h:838
Definition: SpellScript.h:218
+ Here is the caller graph for this function:

◆ CallScriptOnResistAbsorbCalculateHandlers()

void Spell::CallScriptOnResistAbsorbCalculateHandlers ( DamageInfo const &  damageInfo,
uint32 resistAmount,
int32 absorbAmount 
)
8759 {
8760  for (auto scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8761  {
8762  (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_ON_RESIST_ABSORB_CALCULATION);
8763  auto hookItrEnd = (*scritr)->OnCalculateResistAbsorb.end(), hookItr = (*scritr)->OnCalculateResistAbsorb.begin();
8764  for (; hookItr != hookItrEnd; ++hookItr)
8765  hookItr->Call(*scritr, damageInfo, resistAmount, absorbAmount);
8766 
8767  (*scritr)->_FinishScriptCall();
8768  }
8769 }
std::vector< SpellScript * > m_loadedScripts
Definition: Spell.h:838
+ Here is the caller graph for this function:

◆ CallScriptSuccessfulDispel()

void Spell::CallScriptSuccessfulDispel ( SpellEffIndex  effIndex)
protected
8489 {
8490  for (auto scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8491  {
8492  (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_EFFECT_SUCCESSFUL_DISPEL);
8493  auto hookItrEnd = (*scritr)->OnEffectSuccessfulDispel.end(), hookItr = (*scritr)->OnEffectSuccessfulDispel.begin();
8494  for (; hookItr != hookItrEnd; ++hookItr)
8495  hookItr->Call(*scritr, effIndex);
8496 
8497  (*scritr)->_FinishScriptCall();
8498  }
8499 }
std::vector< SpellScript * > m_loadedScripts
Definition: Spell.h:838
Definition: SpellScript.h:205
+ Here is the caller graph for this function:

◆ CanAutoCast()

bool Spell::CanAutoCast ( Unit target)
6900 {
6901  if (!target)
6902  return (CheckPetCast(target) == SPELL_CAST_OK);
6903 
6904  ObjectGuid targetguid = target->GetGUID();
6905 
6906  // check if target already has the same or a more powerful aura
6907  for (SpellEffectInfo const& spellEffectInfo : m_spellInfo->GetEffects())
6908  {
6909  if (!spellEffectInfo.IsAura())
6910  continue;
6911 
6912  AuraType const& auraType = spellEffectInfo.ApplyAuraName;
6913  Unit::AuraEffectList const& auras = target->GetAuraEffectsByType(auraType);
6914  for (Unit::AuraEffectList::const_iterator auraIt = auras.begin(); auraIt != auras.end(); ++auraIt)
6915  {
6916  if (GetSpellInfo()->Id == (*auraIt)->GetSpellInfo()->Id)
6917  return false;
6918 
6919  switch (sSpellMgr->CheckSpellGroupStackRules(GetSpellInfo(), (*auraIt)->GetSpellInfo()))
6920  {
6922  return false;
6924  if (GetCaster() == (*auraIt)->GetCaster())
6925  return false;
6926  break;
6927  case SPELL_GROUP_STACK_RULE_EXCLUSIVE_SAME_EFFECT: // this one has further checks, but i don't think they're necessary for autocast logic
6929  if (abs(spellEffectInfo.BasePoints) <= abs((*auraIt)->GetAmount()))
6930  return false;
6931  break;
6933  default:
6934  break;
6935  }
6936  }
6937  }
6938 
6939  SpellCastResult result = CheckPetCast(target);
6940  if (result == SPELL_CAST_OK || result == SPELL_FAILED_UNIT_NOT_INFRONT)
6941  {
6942  // do not check targets for ground-targeted spells (we target them on top of the intended target anyway)
6943  if (GetSpellInfo()->ExplicitTargetMask & TARGET_FLAG_DEST_LOCATION)
6944  return true;
6946  //check if among target units, our WANTED target is as well (->only self cast spells return false)
6947  for (auto ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
6948  if (ihit->TargetGUID == targetguid)
6949  return true;
6950  }
6951  // either the cast failed or the intended target wouldn't be hit
6952  return false;
6953 }
Definition: SharedDefines.h:1599
SpellInfo const *const m_spellInfo
Definition: Spell.h:532
static ObjectGuid GetGUID(Object const *o)
Definition: Object.h:156
std::list< AuraEffect * > AuraEffectList
Definition: Unit.h:764
AuraType
Definition: SpellAuraDefines.h:92
uint32 const Id
Definition: SpellInfo.h:347
std::vector< TargetInfo > m_UniqueTargetInfo
Definition: Spell.h:767
AuraEffectList const & GetAuraEffectsByType(AuraType type) const
Definition: Unit.h:1406
SpellInfo const * GetSpellInfo() const
Definition: Spell.h:614
#define sSpellMgr
Definition: SpellMgr.h:825
Definition: SpellInfo.h:233
Definition: SpellMgr.h:382
std::vector< SpellEffectInfo > const & GetEffects() const
Definition: SpellInfo.h:589
SpellCastResult CheckPetCast(Unit *target)
Definition: Spell.cpp:6606
Definition: SpellMgr.h:381
Definition: SpellDefines.h:277
SpellCastResult
Definition: SharedDefines.h:1442
Definition: ObjectGuid.h:258
WorldObject * GetCaster() const
Definition: Spell.h:611
void SelectSpellTargets()
Definition: Spell.cpp:727
Definition: SharedDefines.h:1760
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ cancel()

void Spell::cancel ( )
3468 {
3470  return;
3471 
3472  uint32 oldState = m_spellState;
3474 
3475  m_autoRepeat = false;
3476  switch (oldState)
3477  {
3478  case SPELL_STATE_PREPARING:
3480  [[fallthrough]];
3481  case SPELL_STATE_DELAYED:
3482  SendInterrupted(0);
3484  break;
3485 
3486  case SPELL_STATE_CASTING:
3487  for (TargetInfo const& targetInfo : m_UniqueTargetInfo)
3488  if (targetInfo.MissCondition == SPELL_MISS_NONE)
3489  if (Unit* unit = m_caster->GetGUID() == targetInfo.TargetGUID ? m_caster->ToUnit() : ObjectAccessor::GetUnit(*m_caster, targetInfo.TargetGUID))
3490  unit->RemoveOwnedAura(m_spellInfo->Id, m_originalCasterGUID, 0, AURA_REMOVE_BY_CANCEL);
3491 
3492  SendChannelUpdate(0);
3493  SendInterrupted(0);
3495 
3496  m_appliedMods.clear();
3497  break;
3498 
3499  default:
3500  break;
3501  }
3502 
3503  SetReferencedFromCurrent(false);
3504  if (m_selfContainer && *m_selfContainer == this)
3505  *m_selfContainer = nullptr;
3506 
3507  // originalcaster handles gameobjects/dynobjects for gob caster
3508  if (m_originalCaster)
3509  {
3511  if (m_spellInfo->IsChanneled()) // if not channeled then the object for the current cast wasn't summoned yet
3513  }
3514 
3515  //set state back so finish will be processed
3516  m_spellState = oldState;
3517 
3518  finish(false);
3519 }
bool IsChanneled() const
Definition: SpellInfo.cpp:1645
SpellInfo const *const m_spellInfo
Definition: Spell.h:532
uint32 m_spellState
Definition: Spell.h:866
Definition: Spell.h:223
TC_GAME_API Unit * GetUnit(WorldObject const &, ObjectGuid const &guid)
Definition: ObjectAccessor.cpp:206
UsedSpellMods m_appliedMods
Definition: Spell.h:579
static ObjectGuid GetGUID(Object const *o)
Definition: Object.h:156
void CancelGlobalCooldown()
Definition: Spell.cpp:8734
WorldObject *const m_caster
Definition: Spell.h:649
static void SendCastResult(Player *caster, SpellInfo const *spellInfo, SpellCastVisual spellVisual, ObjectGuid cast_count, SpellCastResult result, SpellCustomErrors customError=SPELL_CUSTOM_ERROR_NONE, int32 *param1=nullptr, int32 *param2=nullptr)
Definition: Spell.cpp:4526
bool m_autoRepeat
Definition: Spell.h:665
uint32 const Id
Definition: SpellInfo.h:347
std::vector< TargetInfo > m_UniqueTargetInfo
Definition: Spell.h:767
Unit * m_originalCaster
Definition: Spell.h:655
void finish(bool ok=true)
Definition: Spell.cpp:4194
void SendChannelUpdate(uint32 time)
Definition: Spell.cpp:5001
uint32_t uint32
Definition: Define.h:143
Definition: Spell.h:220
Definition: SharedDefines.h:2686
Definition: Spell.h:219
ObjectGuid m_originalCasterGUID
Definition: Spell.h:653
void RemoveGameObject(GameObject *gameObj, bool del)
Definition: Unit.cpp:5096
void SetReferencedFromCurrent(bool yes)
Definition: Spell.h:596
static Unit * ToUnit(Object *o)
Definition: Object.h:210
void SendInterrupted(uint8 result)
Definition: Spell.cpp:4982
Spell ** m_selfContainer
Definition: Spell.h:626
void RemoveDynObject(uint32 spellId)
Definition: Unit.cpp:5036
Definition: SpellAuraDefines.h:67
Definition: Unit.h:746
Definition: Spell.h:221
Definition: SharedDefines.h:1507
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ CancelGlobalCooldown()

void Spell::CancelGlobalCooldown ( )
protected
8735 {
8737  return;
8738 
8740  return;
8741 
8742  // Cancel global cooldown when interrupting current cast
8744  return;
8745 
8747 }
SpellInfo const *const m_spellInfo
Definition: Spell.h:532
Definition: Unit.h:587
WorldObject *const m_caster
Definition: Spell.h:649
void CancelGlobalCooldown(SpellInfo const *spellInfo)
Definition: SpellHistory.cpp:937
SpellHistory * GetSpellHistory()
Definition: Unit.h:1538
Spell * GetCurrentSpell(CurrentSpellTypes spellType) const
Definition: Unit.h:1527
bool CanHaveGlobalCooldown(WorldObject const *caster)
Definition: Spell.cpp:8666
static Unit * ToUnit(Object *o)
Definition: Object.h:210
uint32 StartRecoveryTime
Definition: SpellInfo.h:387
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ CanExecuteTriggersOnHit()

bool Spell::CanExecuteTriggersOnHit ( Unit unit,
SpellInfo const *  triggeredByAura = nullptr 
) const
protected
8619 {
8620  bool onlyOnTarget = (triggeredByAura && (triggeredByAura->HasAttribute(SPELL_ATTR4_CLASS_TRIGGER_ONLY_ON_TARGET)));
8621  if (!onlyOnTarget)
8622  return true;
8623 
8624  // If triggeredByAura has SPELL_ATTR4_CLASS_TRIGGER_ONLY_ON_TARGET then it can only proc on either noncaster units...
8625  if (unit != m_caster)
8626  return true;
8627 
8628  // ... or caster if it is the only target
8629  if (m_UniqueTargetInfo.size() == 1)
8630  return true;
8631 
8632  return false;
8633 }
WorldObject *const m_caster
Definition: Spell.h:649
std::vector< TargetInfo > m_UniqueTargetInfo
Definition: Spell.h:767
Definition: SharedDefines.h:556
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ CanOpenLock()

SpellCastResult Spell::CanOpenLock ( SpellEffectInfo const &  effect,
uint32  lockid,
SkillType skillid,
int32 reqSkillValue,
int32 skillValue 
)
protected
8244 {
8245  if (!lockId) // possible case for GO and maybe for items.
8246  return SPELL_CAST_OK;
8247 
8248  Unit const* unitCaster = m_caster->ToUnit();
8249  if (!unitCaster)
8250  return SPELL_FAILED_BAD_TARGETS;
8251 
8252  // Get LockInfo
8253  LockEntry const* lockInfo = sLockStore.LookupEntry(lockId);
8254 
8255  if (!lockInfo)
8256  return SPELL_FAILED_BAD_TARGETS;
8257 
8258  bool reqKey = false; // some locks not have reqs
8259 
8260  for (int j = 0; j < MAX_LOCK_CASE; ++j)
8261  {
8262  switch (lockInfo->Type[j])
8263  {
8264  // check key item (many fit cases can be)
8265  case LOCK_KEY_ITEM:
8266  if (lockInfo->Index[j] && m_CastItem && int32(m_CastItem->GetEntry()) == lockInfo->Index[j])
8267  return SPELL_CAST_OK;
8268  reqKey = true;
8269  break;
8270  // check key skill (only single first fit case can be)
8271  case LOCK_KEY_SKILL:
8272  {
8273  reqKey = true;
8274 
8275  // wrong locktype, skip
8276  if (effect.MiscValue != lockInfo->Index[j])
8277  continue;
8278 
8279  skillId = SkillByLockType(LockType(lockInfo->Index[j]));
8280 
8281  if (skillId != SKILL_NONE || lockInfo->Index[j] == LOCKTYPE_LOCKPICKING)
8282  {
8283  reqSkillValue = lockInfo->Skill[j];
8284 
8285  // castitem check: rogue using skeleton keys. the skill values should not be added in this case.
8286  skillValue = 0;
8287  if (!m_CastItem && unitCaster->GetTypeId() == TYPEID_PLAYER)
8288  skillValue = unitCaster->ToPlayer()->GetSkillValue(skillId);
8289  else if (lockInfo->Index[j] == LOCKTYPE_LOCKPICKING)
8290  skillValue = unitCaster->GetLevel() * 5;
8291 
8292  // skill bonus provided by casting spell (mostly item spells)
8293  // add the effect base points modifier from the spell cast (cheat lock / skeleton key etc.)
8294  if (effect.TargetA.GetTarget() == TARGET_GAMEOBJECT_ITEM_TARGET || effect.TargetB.GetTarget() == TARGET_GAMEOBJECT_ITEM_TARGET)
8295  skillValue += effect.CalcValue();
8296 
8297  if (skillValue < reqSkillValue)
8299  }
8300 
8301  return SPELL_CAST_OK;
8302  }
8303  case LOCK_KEY_SPELL:
8304  if (m_spellInfo->Id == uint32(lockInfo->Index[j]))
8305  return SPELL_CAST_OK;
8306  reqKey = true;
8307  break;
8308  }
8309  }
8310 
8311  if (reqKey)
8312  return SPELL_FAILED_BAD_TARGETS;
8313 
8314  return SPELL_CAST_OK;
8315 }
static Player * ToPlayer(Object *o)
Definition: Object.h:198
SpellInfo const *const m_spellInfo
Definition: Spell.h:532
Definition: SharedDefines.h:2554
TypeID GetTypeId() const
Definition: Object.h:170
Definition: SharedDefines.h:5209
constexpr SkillType SkillByLockType(LockType locktype)
Definition: SharedDefines.h:5547
WorldObject *const m_caster
Definition: Spell.h:649
Definition: SharedDefines.h:4373
std::array< int32, MAX_LOCK_CASE > Index
Definition: DB2Structure.h:2476
Definition: DB2Structure.h:2472
Item * m_CastItem
Definition: Spell.h:533
std::array< uint16, MAX_LOCK_CASE > Skill
Definition: DB2Structure.h:2477
LockType
Definition: SharedDefines.h:4377
DB2Storage< LockEntry > sLockStore("Lock.db2", LockLoadInfo::Instance())
uint32 const Id
Definition: SpellInfo.h:347
Definition: SharedDefines.h:4371
Definition: SharedDefines.h:4372
Definition: SharedDefines.h:1457
uint8 GetLevel() const
Definition: Unit.h:863
int32_t int32
Definition: Define.h:139
uint32_t uint32
Definition: Define.h:143
uint32 GetEntry() const
Definition: Object.h:158
Definition: ObjectGuid.h:40
std::array< uint8, MAX_LOCK_CASE > Type
Definition: DB2Structure.h:2478
static Unit * ToUnit(Object *o)
Definition: Object.h:210
#define MAX_LOCK_CASE
Definition: DB2Structure.h:2470
Definition: SharedDefines.h:1516
Definition: Unit.h:746
Definition: SharedDefines.h:1760
uint16 GetSkillValue(uint32 skill) const
Definition: Player.cpp:5905
Definition: SharedDefines.h:4379
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ cast()

void Spell::cast ( bool  skipCheck = false)
3522 {
3523  Player* modOwner = m_caster->GetSpellModOwner();
3524  Spell* lastSpellMod = nullptr;
3525  if (modOwner)
3526  {
3527  lastSpellMod = modOwner->m_spellModTakingSpell;
3528  if (lastSpellMod)
3529  modOwner->SetSpellModTakingSpell(lastSpellMod, false);
3530  }
3531 
3532  _cast(skipCheck);
3533 
3534  if (lastSpellMod)
3535  modOwner->SetSpellModTakingSpell(lastSpellMod, true);
3536 }
Spell * m_spellModTakingSpell
Definition: Player.h:2641
WorldObject *const m_caster
Definition: Spell.h:649
void _cast(bool skipCheck=false)
Definition: Spell.cpp:3538
void SetSpellModTakingSpell(Spell *spell, bool apply)
Definition: Player.cpp:22671
Player * GetSpellModOwner() const
Definition: Object.cpp:2148
Definition: Player.h:1131
Definition: Spell.h:238
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ CheckArenaAndRatedBattlegroundCastRules()

SpellCastResult Spell::CheckArenaAndRatedBattlegroundCastRules ( )
6837 {
6838  bool isRatedBattleground = false; // NYI
6839  bool isArena = !isRatedBattleground;
6840 
6841  // check USABLE attributes
6842  // USABLE takes precedence over NOT_USABLE
6844  return SPELL_CAST_OK;
6845 
6847  return SPELL_CAST_OK;
6848 
6849  // check NOT_USABLE attributes
6852 
6855 
6856  // check cooldowns
6857  uint32 spellCooldown = m_spellInfo->GetRecoveryTime();
6858  if (isArena && spellCooldown > 10 * MINUTE * IN_MILLISECONDS) // not sure if still needed
6860 
6861  if (isRatedBattleground && spellCooldown > 15 * MINUTE * IN_MILLISECONDS)
6863 
6864  return SPELL_CAST_OK;
6865 }
SpellInfo const *const m_spellInfo
Definition: Spell.h:532
Definition: SharedDefines.h:754
Definition: SharedDefines.h:1617
Definition: Common.h:62
Definition: SharedDefines.h:571
bool HasAttribute(SpellAttr0 attribute) const
Definition: SpellInfo.h:461
Definition: Common.h:68
uint32_t uint32
Definition: Define.h:143
uint32 GetRecoveryTime() const
Definition: SpellInfo.cpp:3834
Definition: SharedDefines.h:749
Definition: SharedDefines.h:1684
Definition: SharedDefines.h:572
Definition: SharedDefines.h:1760
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ CheckCast()

SpellCastResult Spell::CheckCast ( bool  strict,
int32 param1 = nullptr,
int32 param2 = nullptr 
)
Todo:
determine if there is some flag to enable/disable the check
5438 {
5439  // check death state
5441  return SPELL_FAILED_CASTER_DEAD;
5442 
5443  // Prevent cheating in case the player has an immunity effect and tries to interact with a non-allowed gameobject. The error message is handled by the client so we don't report anything here
5444  if (m_caster->ToPlayer() && m_targets.GetGOTarget())
5445  {
5447  return SPELL_FAILED_DONT_REPORT;
5448  }
5449 
5450  // check cooldowns to prevent cheating
5451  if (!m_spellInfo->IsPassive())
5452  {
5453  if (Player const* playerCaster = m_caster->ToPlayer())
5454  {
5455  //can cast triggered (by aura only?) spells while have this flag
5457  {
5458  // These two auras check SpellFamilyName defined by db2 class data instead of current spell SpellFamilyName
5459  if (playerCaster->HasAuraType(SPELL_AURA_DISABLE_CASTING_EXCEPT_ABILITIES)
5463  && !playerCaster->HasAuraTypeWithFamilyFlags(SPELL_AURA_DISABLE_CASTING_EXCEPT_ABILITIES, sChrClassesStore.AssertEntry(playerCaster->GetClass())->SpellClassSet, m_spellInfo->SpellFamilyFlags))
5465 
5466  if (playerCaster->HasAuraType(SPELL_AURA_DISABLE_ATTACKING_EXCEPT_ABILITIES))
5467  {
5468  if (!playerCaster->HasAuraTypeWithFamilyFlags(SPELL_AURA_DISABLE_ATTACKING_EXCEPT_ABILITIES, sChrClassesStore.AssertEntry(playerCaster->GetClass())->SpellClassSet, m_spellInfo->SpellFamilyFlags))
5469  {
5480  }
5481  }
5482  }
5483 
5484  // check if we are using a potion in combat for the 2nd+ time. Cooldown is added only after caster gets out of combat
5485  if (!IsIgnoringCooldowns() && playerCaster->GetLastPotionId() && m_CastItem && (m_CastItem->IsPotion() || m_spellInfo->IsCooldownStartedOnEvent()))
5486  return SPELL_FAILED_NOT_READY;
5487  }
5488 
5489  if (!IsIgnoringCooldowns() && m_caster->ToUnit())
5490  {
5492  {
5494  return SPELL_FAILED_DONT_REPORT;
5495  else
5496  return SPELL_FAILED_NOT_READY;
5497  }
5498 
5500  return SPELL_FAILED_DONT_REPORT;
5501  }
5502  }
5503 
5505  {
5508  }
5509 
5510  // Check global cooldown
5513 
5514  // only triggered spells can be processed an ended battleground
5515  if (!IsTriggered() && m_caster->GetTypeId() == TYPEID_PLAYER)
5517  if (bg->GetStatus() == STATUS_WAIT_LEAVE)
5518  return SPELL_FAILED_DONT_REPORT;
5519 
5521  {
5523  !m_caster->IsOutdoors())
5525 
5527  m_caster->IsOutdoors())
5529  }
5530 
5531  if (Unit* unitCaster = m_caster->ToUnit())
5532  {
5533  if (m_spellInfo->HasAttribute(SPELL_ATTR5_NOT_AVAILABLE_WHILE_CHARMED) && unitCaster->IsCharmed())
5534  return SPELL_FAILED_CHARMED;
5535 
5536  // only check at first call, Stealth auras are already removed at second call
5537  // for now, ignore triggered spells
5539  {
5540  bool checkForm = true;
5541  // Ignore form req aura
5542  Unit::AuraEffectList const& ignore = unitCaster->GetAuraEffectsByType(SPELL_AURA_MOD_IGNORE_SHAPESHIFT);
5543  for (AuraEffect const* aurEff : ignore)
5544  {
5545  if (!aurEff->IsAffectingSpell(m_spellInfo))
5546  continue;
5547 
5548  checkForm = false;
5549  break;
5550  }
5551 
5552  if (checkForm)
5553  {
5554  // Cannot be used in this stance/form
5555  SpellCastResult shapeError = m_spellInfo->CheckShapeshift(unitCaster->GetShapeshiftForm());
5556  if (shapeError != SPELL_CAST_OK)
5557  return shapeError;
5558 
5559  if (m_spellInfo->HasAttribute(SPELL_ATTR0_ONLY_STEALTHED) && !(unitCaster->HasStealthAura()))
5561  }
5562  }
5563 
5564  bool reqCombat = true;
5565  Unit::AuraEffectList const& stateAuras = unitCaster->GetAuraEffectsByType(SPELL_AURA_ABILITY_IGNORE_AURASTATE);
5566  for (Unit::AuraEffectList::const_iterator j = stateAuras.begin(); j != stateAuras.end(); ++j)
5567  {
5568  if ((*j)->IsAffectingSpell(m_spellInfo))
5569  {
5570  m_needComboPoints = false;
5571  if ((*j)->GetMiscValue() == 1)
5572  {
5573  reqCombat = false;
5574  break;
5575  }
5576  }
5577  }
5578 
5579  // caster state requirements
5580  // not for triggered spells (needed by execute)
5581  if (!(_triggeredCastFlags & TRIGGERED_IGNORE_CASTER_AURASTATE))
5582  {
5583  if (m_spellInfo->CasterAuraState && !unitCaster->HasAuraState(AuraStateType(m_spellInfo->CasterAuraState), m_spellInfo, unitCaster))
5585  if (m_spellInfo->ExcludeCasterAuraState && unitCaster->HasAuraState(AuraStateType(m_spellInfo->ExcludeCasterAuraState), m_spellInfo, unitCaster))
5587 
5588  // Note: spell 62473 requres casterAuraSpell = triggering spell
5589  if (m_spellInfo->CasterAuraSpell && !unitCaster->HasAura(m_spellInfo->CasterAuraSpell))
5593 
5594  if (reqCombat && unitCaster->IsInCombat() && !m_spellInfo->CanBeUsedInCombat())
5596  }
5597 
5598  // Check vehicle flags
5600  {
5601  SpellCastResult vehicleCheck = m_spellInfo->CheckVehicle(unitCaster);
5602  if (vehicleCheck != SPELL_CAST_OK)
5603  return vehicleCheck;
5604  }
5605  }
5606 
5607  // check spell cast conditions from database
5608  {
5610  if (!sConditionMgr->IsObjectMeetingNotGroupedConditions(CONDITION_SOURCE_TYPE_SPELL, m_spellInfo->Id, condInfo))
5611  {
5612  // mLastFailedCondition can be NULL if there was an error processing the condition in Condition::Meets (i.e. wrong data for ConditionTarget or others)
5613  if (condInfo.mLastFailedCondition && condInfo.mLastFailedCondition->ErrorType)
5614  {
5618  }
5619 
5620  if (!condInfo.mLastFailedCondition || !condInfo.mLastFailedCondition->ConditionTarget)
5622  return SPELL_FAILED_BAD_TARGETS;
5623  }
5624  }
5625 
5626  // Don't check explicit target for passive spells (workaround) (check should be skipped only for learn case)
5627  // those spells may have incorrect target entries or not filled at all (for example 15332)
5628  // such spells when learned are not targeting anyone using targeting system, they should apply directly to caster instead
5629  // also, such casts shouldn't be sent to client
5631  {
5632  // Check explicit target for m_originalCaster - todo: get rid of such workarounds
5633  WorldObject* caster = m_caster;
5634  // in case of gameobjects like traps, we need the gameobject itself to check target validity
5635  // otherwise, if originalCaster is far away and cannot detect the target, the trap would not hit the target
5636  if (m_originalCaster && !caster->ToGameObject())
5637  caster = m_originalCaster;
5638 
5640  if (castResult != SPELL_CAST_OK)
5641  return castResult;
5642  }
5643 
5644  if (Unit* target = m_targets.GetUnitTarget())
5645  {
5646  SpellCastResult castResult = m_spellInfo->CheckTarget(m_caster, target, m_caster->GetTypeId() == TYPEID_GAMEOBJECT); // skip stealth checks for GO casts
5647  if (castResult != SPELL_CAST_OK)
5648  return castResult;
5649 
5650  // If it's not a melee spell, check if vision is obscured by SPELL_AURA_INTERFERE_TARGETTING
5652  {
5653  if (Unit const* unitCaster = m_caster->ToUnit())
5654  {
5655  for (AuraEffect const* auraEff : unitCaster->GetAuraEffectsByType(SPELL_AURA_INTERFERE_TARGETTING))
5656  if (!unitCaster->IsFriendlyTo(auraEff->GetCaster()) && !target->HasAura(auraEff->GetId(), auraEff->GetCasterGUID()))
5658 
5659  for (AuraEffect const* auraEff : target->GetAuraEffectsByType(SPELL_AURA_INTERFERE_TARGETTING))
5660  if (!unitCaster->IsFriendlyTo(auraEff->GetCaster()) && (!target->HasAura(auraEff->GetId(), auraEff->GetCasterGUID()) || !unitCaster->HasAura(auraEff->GetId(), auraEff->GetCasterGUID())))
5662  }
5663  }
5664 
5665  if (target != m_caster)
5666  {
5667  // Must be behind the target
5668  if ((m_spellInfo->HasAttribute(SPELL_ATTR0_CU_REQ_CASTER_BEHIND_TARGET)) && target->HasInArc(static_cast<float>(M_PI), m_caster))
5669  return SPELL_FAILED_NOT_BEHIND;
5670 
5671  // Target must be facing you
5672  if ((m_spellInfo->HasAttribute(SPELL_ATTR0_CU_REQ_TARGET_FACING_CASTER)) && !target->HasInArc(static_cast<float>(M_PI), m_caster))
5673  return SPELL_FAILED_NOT_INFRONT;
5674 
5675  // Ignore LOS for gameobjects casts
5677  {
5678  WorldObject* losTarget = m_caster;
5681  losTarget = dynObj;
5682 
5685  }
5686  }
5687  }
5688 
5689  // Check for line of sight for spells with dest
5690  if (m_targets.HasDst())
5691  {
5692  float x, y, z;
5693  m_targets.GetDstPos()->GetPosition(x, y, z);
5694 
5697  }
5698 
5699  // check pet presence
5700  if (Unit* unitCaster = m_caster->ToUnit())
5701  {
5703  if (!unitCaster->GetPetGUID().IsEmpty())
5705 
5706  for (SpellEffectInfo const& spellEffectInfo : m_spellInfo->GetEffects())
5707  {
5708  if (spellEffectInfo.TargetA.GetTarget() == TARGET_UNIT_PET)
5709  {
5710  if (!unitCaster->GetGuardianPet())
5711  {
5712  if (m_triggeredByAuraSpell) // not report pet not existence for triggered spells
5713  return SPELL_FAILED_DONT_REPORT;
5714  else
5715  return SPELL_FAILED_NO_PET;
5716  }
5717  break;
5718  }
5719  }
5720  }
5721 
5722  // Spell cast only in battleground
5724  if (!m_caster->GetMap()->IsBattleground())
5726 
5727  // do not allow spells to be cast in arenas or rated battlegrounds
5728  if (Player* player = m_caster->ToPlayer())
5729  if (player->InArena()/* || player->InRatedBattleGround() NYI*/)
5730  {
5732  if (castResult != SPELL_CAST_OK)
5733  return castResult;
5734  }
5735 
5736  // zone check
5738  {
5739  uint32 zone, area;
5740  m_caster->GetZoneAndAreaId(zone, area);
5741 
5743  if (locRes != SPELL_CAST_OK)
5744  return locRes;
5745  }
5746 
5747  // not let players cast spells at mount (and let do it to creatures)
5748  if (!(_triggeredCastFlags & TRIGGERED_IGNORE_CASTER_MOUNTED_OR_ON_VEHICLE))
5749  {
5751  {
5752  if (m_caster->ToPlayer()->IsInFlight())
5753  return SPELL_FAILED_NOT_ON_TAXI;
5754  else
5755  return SPELL_FAILED_NOT_MOUNTED;
5756  }
5757  }
5758 
5759  // check spell focus object
5761  {
5763  {
5765  if (!focusObject)
5767  }
5768  }
5769 
5770  SpellCastResult castResult = SPELL_CAST_OK;
5771 
5772  // always (except passive spells) check items (only player related checks)
5773  if (!m_spellInfo->IsPassive())
5774  {
5775  castResult = CheckItems(param1, param2);
5776  if (castResult != SPELL_CAST_OK)
5777  return castResult;
5778  }
5779 
5780  // Triggered spells also have range check
5782  castResult = CheckRange(strict);
5783  if (castResult != SPELL_CAST_OK)
5784  return castResult;
5785 
5787  {
5788  castResult = CheckPower();
5789  if (castResult != SPELL_CAST_OK)
5790  return castResult;
5791  }
5792 
5794  {
5795  castResult = CheckCasterAuras(param1);
5796  if (castResult != SPELL_CAST_OK)
5797  return castResult;
5798  }
5799 
5800  // script hook
5801  castResult = CallScriptCheckCastHandlers();
5802  if (castResult != SPELL_CAST_OK)
5803  return castResult;
5804 
5805  uint32 approximateAuraEffectMask = 0;
5806  uint32 nonAuraEffectMask = 0;
5807  for (SpellEffectInfo const& spellEffectInfo : m_spellInfo->GetEffects())
5808  {
5809  // for effects of spells that have only one target
5810  switch (spellEffectInfo.Effect)
5811  {
5812  case SPELL_EFFECT_DUMMY:
5813  {
5814  if (m_spellInfo->Id == 19938) // Awaken Peon
5815  {
5816  Unit* unit = m_targets.GetUnitTarget();
5817  if (!unit || !unit->HasAura(17743))
5818  return SPELL_FAILED_BAD_TARGETS;
5819  }
5820  else if (m_spellInfo->Id == 31789) // Righteous Defense
5821  {
5822  if (m_caster->GetTypeId() != TYPEID_PLAYER)
5823  return SPELL_FAILED_DONT_REPORT;
5824 
5825  Unit* target = m_targets.GetUnitTarget();
5826  if (!target || !target->IsFriendlyTo(m_caster) || target->getAttackers().empty())
5827  return SPELL_FAILED_BAD_TARGETS;
5828 
5829  }
5830  break;
5831  }
5833  {
5834  if (spellEffectInfo.TargetA.GetTarget() != TARGET_UNIT_PET)
5835  break;
5836 
5837  Pet* pet = m_caster->ToPlayer()->GetPet();
5838  if (!pet)
5839  return SPELL_FAILED_NO_PET;
5840 
5841  SpellInfo const* learn_spellproto = sSpellMgr->GetSpellInfo(spellEffectInfo.TriggerSpell, DIFFICULTY_NONE);
5842  if (!learn_spellproto)
5843  return SPELL_FAILED_NOT_KNOWN;
5844 
5845  if (m_spellInfo->SpellLevel > pet->GetLevel())
5846  return SPELL_FAILED_LOWLEVEL;
5847 
5848  break;
5849  }
5851  {
5852  if (m_caster->GetTypeId() != TYPEID_PLAYER)
5853  return SPELL_FAILED_BAD_TARGETS;
5854  if (Guild* guild = m_caster->ToPlayer()->GetGuild())
5855  if (guild->GetLeaderGUID() != m_caster->ToPlayer()->GetGUID())
5857  break;
5858  }
5860  {
5861  // check target only for unit target case
5862  if (Unit* unit = m_targets.GetUnitTarget())
5863  {
5864  if (m_caster->GetTypeId() != TYPEID_PLAYER)
5865  return SPELL_FAILED_BAD_TARGETS;
5866 
5867  Pet* pet = unit->ToPet();
5868  if (!pet || pet->GetOwner() != m_caster)
5869  return SPELL_FAILED_BAD_TARGETS;
5870 
5871  SpellInfo const* learn_spellproto = sSpellMgr->GetSpellInfo(spellEffectInfo.TriggerSpell, DIFFICULTY_NONE);
5872 
5873  if (!learn_spellproto)
5874  return SPELL_FAILED_NOT_KNOWN;
5875 
5876  if (m_spellInfo->SpellLevel > pet->GetLevel())
5877  return SPELL_FAILED_LOWLEVEL;
5878  }
5879  break;
5880  }
5882  {
5883  if (m_caster->GetTypeId() != TYPEID_PLAYER)
5885 
5886  Player* caster = m_caster->ToPlayer();
5887  if (!caster->HasSpell(m_misc.SpellId))
5888  return SPELL_FAILED_NOT_KNOWN;
5889 
5890  if (uint32 glyphId = spellEffectInfo.MiscValue)
5891  {
5892  GlyphPropertiesEntry const* glyphProperties = sGlyphPropertiesStore.LookupEntry(glyphId);
5893  if (!glyphProperties)
5895 
5896  std::vector<uint32> const* glyphBindableSpells = sDB2Manager.GetGlyphBindableSpells(glyphId);
5897  if (!glyphBindableSpells)
5899 
5900  if (std::find(glyphBindableSpells->begin(), glyphBindableSpells->end(), m_misc.SpellId) == glyphBindableSpells->end())
5902 
5903  if (std::vector<uint32> const* glyphRequiredSpecs = sDB2Manager.GetGlyphRequiredSpecs(glyphId))
5904  {
5905  if (!caster->GetPrimarySpecialization())
5907 
5908  if (std::find(glyphRequiredSpecs->begin(), glyphRequiredSpecs->end(), caster->GetPrimarySpecialization()) == glyphRequiredSpecs->end())
5910  }
5911 
5912  uint32 replacedGlyph = 0;
5913  for (uint32 activeGlyphId : caster->GetGlyphs(caster->GetActiveTalentGroup()))
5914  {
5915  if (std::vector<uint32> const* activeGlyphBindableSpells = sDB2Manager.GetGlyphBindableSpells(activeGlyphId))
5916  {
5917  if (std::find(activeGlyphBindableSpells->begin(), activeGlyphBindableSpells->end(), m_misc.SpellId) != activeGlyphBindableSpells->end())
5918  {
5919  replacedGlyph = activeGlyphId;
5920  break;
5921  }
5922  }
5923  }
5924 
5925  for (uint32 activeGlyphId : caster->GetGlyphs(caster->GetActiveTalentGroup()))
5926  {
5927  if (activeGlyphId == replacedGlyph)
5928  continue;
5929 
5930  if (activeGlyphId == glyphId)
5932 
5933  if (sGlyphPropertiesStore.AssertEntry(activeGlyphId)->GlyphExclusiveCategoryID == glyphProperties->GlyphExclusiveCategoryID)
5935  }
5936  }
5937  break;
5938  }
5939  case SPELL_EFFECT_FEED_PET:
5940  {
5941  if (m_caster->GetTypeId() != TYPEID_PLAYER)
5942  return SPELL_FAILED_BAD_TARGETS;
5943 
5944  Item* foodItem = m_targets.GetItemTarget();
5945  if (!foodItem)
5946  return SPELL_FAILED_BAD_TARGETS;
5947 
5948  Pet* pet = m_caster->ToPlayer()->GetPet();
5949  if (!pet)
5950  return SPELL_FAILED_NO_PET;
5951 
5952  if (!pet->HaveInDiet(foodItem->GetTemplate()))
5954 
5955  if (foodItem->GetTemplate()->GetBaseItemLevel() + 30 <= pet->GetLevel())
5957 
5958  if (m_caster->ToPlayer()->IsInCombat() || pet->IsInCombat())
5960 
5961  break;
5962  }
5963  case SPELL_EFFECT_CHARGE:
5964  {
5965  Unit* unitCaster = m_caster->ToUnit();
5966  if (!unitCaster)
5967  return SPELL_FAILED_BAD_TARGETS;
5968 
5969  if (!(_triggeredCastFlags & TRIGGERED_IGNORE_CASTER_AURAS) && unitCaster->HasUnitState(UNIT_STATE_ROOT))
5970  return SPELL_FAILED_ROOTED;
5971 
5973  {
5974  Unit* target = m_targets.GetUnitTarget();
5975  if (!target)
5976  return SPELL_FAILED_DONT_REPORT;
5977 
5978  // first we must check to see if the target is in LoS. A path can usually be built but LoS matters for charge spells
5979  if (!target->IsWithinLOSInMap(unitCaster)) //Do full LoS/Path check. Don't exclude m2
5981 
5982  float objSize = target->GetCombatReach();
5983  float range = m_spellInfo->GetMaxRange(true, unitCaster, this) * 1.5f + objSize; // can't be overly strict
5984 
5985  m_preGeneratedPath = std::make_unique<PathGenerator>(unitCaster);
5986  m_preGeneratedPath->SetPathLengthLimit(range);
5987 
5988  // first try with raycast, if it fails fall back to normal path
5989  bool result = m_preGeneratedPath->CalculatePath(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), false);
5990  if (m_preGeneratedPath->GetPathType() & PATHFIND_SHORT)
5991  return SPELL_FAILED_NOPATH;
5992  else if (!result || m_preGeneratedPath->GetPathType() & (PATHFIND_NOPATH | PATHFIND_INCOMPLETE))
5993  return SPELL_FAILED_NOPATH;
5994  else if (m_preGeneratedPath->IsInvalidDestinationZ(target)) // Check position z, if not in a straight line
5995  return SPELL_FAILED_NOPATH;
5996 
5997  m_preGeneratedPath->ShortenPathUntilDist(PositionToVector3(target), objSize); // move back
5998  }
5999  break;
6000  }
6001  case SPELL_EFFECT_SKINNING:
6002  {
6004  return SPELL_FAILED_BAD_TARGETS;
6005 
6008 
6009  Creature* creature = m_targets.GetUnitTarget()->ToCreature();
6010  if (!creature->IsCritter() && !creature->loot.isLooted())
6012 
6013  uint32 skill = creature->GetCreatureTemplate()->GetRequiredLootSkill();
6014 
6015  int32 skillValue = m_caster->ToPlayer()->GetSkillValue(skill);
6017  int32 ReqValue = (skillValue < 100 ? (TargetLevel-10) * 10 : TargetLevel * 5);
6018  if (ReqValue > skillValue)
6020 
6021  break;
6022  }
6024  {
6025  if (spellEffectInfo.TargetA.GetTarget() != TARGET_GAMEOBJECT_TARGET &&
6026  spellEffectInfo.TargetA.GetTarget() != TARGET_GAMEOBJECT_ITEM_TARGET)
6027  break;
6028 
6029  if (m_caster->GetTypeId() != TYPEID_PLAYER // only players can open locks, gather etc.
6030  // we need a go target in case of TARGET_GAMEOBJECT_TARGET
6031  || (spellEffectInfo.TargetA.GetTarget() == TARGET_GAMEOBJECT_TARGET && !m_targets.GetGOTarget()))
6032  return SPELL_FAILED_BAD_TARGETS;
6033 
6034  Item* pTempItem = nullptr;
6036  {
6037  if (TradeData* pTrade = m_caster->ToPlayer()->GetTradeData())
6038  pTempItem = pTrade->GetTraderData()->GetItem(TRADE_SLOT_NONTRADED);
6039  }
6042 
6043  // we need a go target, or an openable item target in case of TARGET_GAMEOBJECT_ITEM_TARGET
6044  if (spellEffectInfo.TargetA.GetTarget() == TARGET_GAMEOBJECT_ITEM_TARGET &&
6045  !m_targets.GetGOTarget() &&
6046  (!pTempItem || !pTempItem->GetTemplate()->GetLockID() || !pTempItem->IsLocked()))
6047  return SPELL_FAILED_BAD_TARGETS;
6048 
6049  if (m_spellInfo->Id != 1842 || (m_targets.GetGOTarget() &&
6051  if (m_caster->ToPlayer()->InBattleground() && // In Battleground players can use only flags and banners
6053  return SPELL_FAILED_TRY_AGAIN;
6054 
6055  // get the lock entry
6056  uint32 lockId = 0;
6057  if (GameObject* go = m_targets.GetGOTarget())
6058  {
6059  lockId = go->GetGOInfo()->GetLockId();
6060  if (!lockId)
6061  return SPELL_FAILED_BAD_TARGETS;
6062  }
6063  else if (Item* itm = m_targets.GetItemTarget())
6064  lockId = itm->GetTemplate()->GetLockID();
6065 
6066  SkillType skillId = SKILL_NONE;
6067  int32 reqSkillValue = 0;
6068  int32 skillValue = 0;
6069 
6070  // check lock compatibility
6071  SpellCastResult res = CanOpenLock(spellEffectInfo, lockId, skillId, reqSkillValue, skillValue);
6072  if (res != SPELL_CAST_OK)
6073  return res;
6074  break;
6075  }
6077  {
6078  Player* playerCaster = m_caster->ToPlayer();
6079  if (!playerCaster || !playerCaster->GetPetStable())
6080  return SPELL_FAILED_BAD_TARGETS;
6081 
6082  Pet* pet = playerCaster->GetPet();
6083  if (pet && pet->IsAlive())
6085 
6086  PetStable const* petStable = playerCaster->GetPetStable();
6087  auto deadPetItr = std::find_if(petStable->ActivePets.begin(), petStable->ActivePets.end(), [](Optional<PetStable::PetInfo> const& petInfo)
6088  {
6089  return petInfo && !petInfo->Health;
6090  });
6091 
6092  if (deadPetItr == petStable->ActivePets.end())
6093  return SPELL_FAILED_BAD_TARGETS;
6094 
6095  break;
6096  }
6097  // This is generic summon effect
6098  case SPELL_EFFECT_SUMMON:
6099  {
6100  Unit* unitCaster = m_caster->ToUnit();
6101  if (!unitCaster)
6102  break;
6103 
6104  SummonPropertiesEntry const* SummonProperties = sSummonPropertiesStore.LookupEntry(spellEffectInfo.MiscValueB);
6105  if (!SummonProperties)
6106  break;
6107 
6108  switch (SummonProperties->Control)
6109  {
6110  case SUMMON_CATEGORY_PET:
6113  [[fallthrough]]; // check both GetPetGUID() and GetCharmGUID for SUMMON_CATEGORY_PET
6115  if (!unitCaster->GetCharmedGUID().IsEmpty())
6117  break;
6118  }
6119  break;
6120  }
6122  {
6123  if (m_targets.GetUnitTarget())
6124  {
6126  return SPELL_FAILED_BAD_TARGETS;
6129  }
6130  break;
6131  }
6133  {
6134  Unit* unitCaster = m_caster->ToUnit();
6135  if (!unitCaster)
6136  return SPELL_FAILED_BAD_TARGETS;
6137 
6138  if (!unitCaster->GetPetGUID().IsEmpty()) //let warlock do a replacement summon
6139  {
6140  if (unitCaster->GetTypeId() == TYPEID_PLAYER)
6141  {
6142  if (strict) //starting cast, trigger pet stun (cast by pet so it doesn't attack player)
6143  if (Pet* pet = unitCaster->ToPlayer()->GetPet())
6145  .SetOriginalCaster(pet->GetGUID())
6146  .SetTriggeringSpell(this));
6147  }
6150  }
6151 
6152  if (!unitCaster->GetCharmedGUID().IsEmpty())
6154 
6155  Player* playerCaster = unitCaster->ToPlayer();
6156  if (playerCaster && playerCaster->GetPetStable())
6157  {
6158  Optional<PetSaveMode> petSlot;
6159  if (!spellEffectInfo.MiscValue)
6160  {
6161  petSlot = PetSaveMode(spellEffectInfo.CalcValue());
6162 
6163  // No pet can be summoned if any pet is dead
6164  for (Optional<PetStable::PetInfo> const& activePet : playerCaster->GetPetStable()->ActivePets)
6165  {
6166  if (activePet && !activePet->Health)
6167  {
6168  playerCaster->SendTameFailure(PetTameResult::Dead);
6169  return SPELL_FAILED_DONT_REPORT;
6170  }
6171  }
6172  }
6173 
6174  std::pair<PetStable::PetInfo const*, PetSaveMode> info = Pet::GetLoadPetInfo(*playerCaster->GetPetStable(), spellEffectInfo.MiscValue, 0, petSlot);
6175  if (info.first)
6176  {
6177  if (info.first->Type == HUNTER_PET)
6178  {
6179  CreatureTemplate const* creatureInfo = sObjectMgr->GetCreatureTemplate(info.first->CreatureId);
6180  if (!creatureInfo || !creatureInfo->IsTameable(playerCaster->CanTameExoticPets()))
6181  {
6182  // if problem in exotic pet
6183  if (creatureInfo && creatureInfo->IsTameable(true))
6185  else
6187 
6188  return SPELL_FAILED_DONT_REPORT;
6189  }
6190  }
6191  }
6192  else if (!spellEffectInfo.MiscValue) // when miscvalue is present it is allowed to create new pets
6193  {
6195  return SPELL_FAILED_DONT_REPORT;
6196  }
6197  }
6198 
6199  break;
6200  }
6202  {
6203  Player* playerCaster = m_caster->ToPlayer();
6204  if (!playerCaster)
6205  return SPELL_FAILED_BAD_TARGETS;
6206 
6207  Pet* pet = playerCaster->GetPet();
6208  if (!pet)
6209  return SPELL_FAILED_NO_PET;
6210 
6211  if (!pet->IsAlive())
6213 
6214  break;
6215  }
6217  {
6218  if (m_caster->GetTypeId() != TYPEID_PLAYER)
6219  return SPELL_FAILED_BAD_TARGETS;
6220 
6221  if (!m_caster->ToPlayer()->GetTarget())
6222  return SPELL_FAILED_BAD_TARGETS;
6223 
6225  if (!target || m_caster->ToPlayer() == target || (!target->IsInSameRaidWith(m_caster->ToPlayer()) && m_spellInfo->Id != 48955)) // refer-a-friend spell
6226  return SPELL_FAILED_BAD_TARGETS;
6227 
6228  if (target->HasSummonPending())
6230 
6231  // check if our map is dungeon
6232  MapEntry const* map = sMapStore.LookupEntry(m_caster->GetMapId());
6233  if (map->IsDungeon())
6234  {
6235  uint32 mapId = m_caster->GetMap()->GetId();
6236  Difficulty difficulty = m_caster->GetMap()->GetDifficultyID();
6237  if (map->IsRaid())
6238  if (InstancePlayerBind* targetBind = target->GetBoundInstance(mapId, difficulty))
6239  if (InstancePlayerBind* casterBind = m_caster->ToPlayer()->GetBoundInstance(mapId, difficulty))
6240  if (targetBind->perm && targetBind->save != casterBind->save)
6242 
6243  InstanceTemplate const* instance = sObjectMgr->GetInstanceTemplate(mapId);
6244  if (!instance)
6246  if (!target->Satisfy(sObjectMgr->GetAccessRequirement(mapId, difficulty), mapId))
6247  return SPELL_FAILED_BAD_TARGETS;
6248  }
6249  break;
6250  }
6251  // RETURN HERE
6253  {
6254  if (m_caster->GetTypeId() != TYPEID_PLAYER)
6255  return SPELL_FAILED_BAD_TARGETS;
6256 
6257  Player* playerCaster = m_caster->ToPlayer();
6258  if (!playerCaster->GetTarget())
6259  return SPELL_FAILED_BAD_TARGETS;
6260 
6261  Player* target = playerCaster->GetSelectedPlayer();
6262  if (!target ||
6263  !(target->GetSession()->GetRecruiterId() == playerCaster->GetSession()->GetAccountId() || target->GetSession()->GetAccountId() == playerCaster->GetSession()->GetRecruiterId()))
6264  return SPELL_FAILED_BAD_TARGETS;
6265  break;
6266  }
6267  case SPELL_EFFECT_LEAP:
6269  {
6270  //Do not allow to cast it before BG starts.
6271  if (m_caster->GetTypeId() == TYPEID_PLAYER)
6272  if (Battleground const* bg = m_caster->ToPlayer()->GetBattleground())
6273  if (bg->GetStatus() != STATUS_IN_PROGRESS)
6274  return SPELL_FAILED_TRY_AGAIN;
6275  break;
6276  }
6278  {
6280  return SPELL_FAILED_BAD_TARGETS;
6281  break;
6282  }
6284  {
6285  Unit* unitCaster = m_caster->ToUnit();
6286  if (!unitCaster)
6287  return SPELL_FAILED_BAD_TARGETS;
6288 
6289  if (unitCaster->HasUnitState(UNIT_STATE_ROOT))
6290  {
6291  if (unitCaster->GetTypeId() == TYPEID_PLAYER)
6292  return SPELL_FAILED_ROOTED;
6293  else
6294  return SPELL_FAILED_DONT_REPORT;
6295  }
6296  break;
6297  }
6298  case SPELL_EFFECT_JUMP:
6300  {
6301  Unit* unitCaster = m_caster->ToUnit();
6302  if (!unitCaster)
6303  return SPELL_FAILED_BAD_TARGETS;
6304 
6305  if (unitCaster->HasUnitState(UNIT_STATE_ROOT))
6306  return SPELL_FAILED_ROOTED;
6307  break;
6308  }
6310  {
6311  ChrSpecializationEntry const* spec = sChrSpecializationStore.LookupEntry(m_misc.SpecializationId);
6312  Player* player = m_caster->ToPlayer();
6313  if (!player)
6315 
6316  if (!spec || (spec->ClassID != player->GetClass() && !spec->IsPetSpecialization()))
6317  return SPELL_FAILED_NO_SPEC;
6318 
6319  if (spec->IsPetSpecialization())
6320  {
6321  Pet* pet = player->GetPet();
6322  if (!pet || pet->getPetType() != HUNTER_PET || !pet->GetCharmInfo())
6323  return SPELL_FAILED_NO_PET;
6324  }
6325 
6326  // can't change during already started arena/battleground
6327  if (Battleground const* bg = player->GetBattleground())
6328  if (bg->GetStatus() == STATUS_IN_PROGRESS)
6330  break;
6331  }
6333  {
6334  Player* playerCaster = m_caster->ToPlayer();
6335  if (!playerCaster)
6336  return SPELL_FAILED_BAD_TARGETS;
6337 
6338  TalentEntry const* talent = sTalentStore.LookupEntry(m_misc.TalentId);
6339  if (!talent)
6340  return SPELL_FAILED_DONT_REPORT;
6341 
6342  if (playerCaster->GetSpellHistory()->HasCooldown(talent->SpellID))
6343  {
6344  if (param1)
6345  *param1 = talent->SpellID;
6347  }
6348  break;
6349  }
6352  {
6353  Player* playerCaster = m_caster->ToPlayer();
6354  if (!playerCaster)
6355  return SPELL_FAILED_BAD_TARGETS;
6356 
6358  if (!artifactAura)
6360 
6361  Item* artifact = playerCaster->GetItemByGuid(artifactAura->GetCastItemGUID());
6362  if (!artifact)
6364 
6365  if (spellEffectInfo.Effect == SPELL_EFFECT_GIVE_ARTIFACT_POWER)
6366  {
6367  ArtifactEntry const* artifactEntry = sArtifactStore.LookupEntry(artifact->GetTemplate()->GetArtifactID());
6368  if (!artifactEntry || artifactEntry->ArtifactCategoryID != spellEffectInfo.MiscValue)
6370  }
6371  break;
6372  }
6376  {
6377  Player* playerCaster = m_caster->ToPlayer();
6378  if (!playerCaster || !m_targets.GetUnitTarget() || !m_targets.GetUnitTarget()->IsCreature())
6379  return SPELL_FAILED_BAD_TARGETS;
6380 
6381  BattlePets::BattlePetMgr* battlePetMgr = playerCaster->GetSession()->GetBattlePetMgr();
6382  if (!battlePetMgr->HasJournalLock())
6384 
6385  Creature* creature = m_targets.GetUnitTarget()->ToCreature();
6386  if (creature)
6387  {
6388  if (playerCaster->GetSummonedBattlePetGUID().IsEmpty() || creature->GetBattlePetCompanionGUID().IsEmpty())
6389  return SPELL_FAILED_NO_PET;
6390 
6391  if (playerCaster->GetSummonedBattlePetGUID() != creature->GetBattlePetCompanionGUID())
6392  return SPELL_FAILED_BAD_TARGETS;
6393 
6394  if (BattlePets::BattlePet* battlePet = battlePetMgr->GetPet(creature->GetBattlePetCompanionGUID()))
6395  {
6396  if (BattlePetSpeciesEntry const* battlePetSpecies = sBattlePetSpeciesStore.LookupEntry(battlePet->PacketInfo.Species))
6397  {
6398  if (uint32 battlePetType = spellEffectInfo.MiscValue)
6399  if (!(battlePetType & (1 << battlePetSpecies->PetTypeEnum)))
6401 
6402  if (spellEffectInfo.Effect == SPELL_EFFECT_CHANGE_BATTLEPET_QUALITY)
6403  {
6405  switch (spellEffectInfo.BasePoints)
6406  {
6407  case 85:
6409  break;
6410  case 75:
6412  break;
6413  default:
6414  // Ignore Epic Battle-Stones
6415  break;
6416  }
6417  if (battlePet->PacketInfo.Quality >= AsUnderlyingType(quality))
6419  }
6420 
6421  if (spellEffectInfo.Effect == SPELL_EFFECT_GRANT_BATTLEPET_LEVEL || spellEffectInfo.Effect == SPELL_EFFECT_GRANT_BATTLEPET_EXPERIENCE)
6422  if (battlePet->PacketInfo.Level >= BattlePets::MAX_BATTLE_PET_LEVEL)
6423  return GRANT_PET_LEVEL_FAIL;
6424 
6425  if (battlePetSpecies->GetFlags().HasFlag(BattlePetSpeciesFlags::CantBattle))
6426  return SPELL_FAILED_BAD_TARGETS;
6427  }
6428  }
6429  }
6430  break;
6431  }
6432  default:
6433  break;
6434  }
6435 
6436  if (spellEffectInfo.IsAura())
6437  approximateAuraEffectMask |= 1 << spellEffectInfo.EffectIndex;
6438  else if (spellEffectInfo.IsEffect())
6439  nonAuraEffectMask |= 1 << spellEffectInfo.EffectIndex;
6440  }
6441 
6442  for (SpellEffectInfo const& spellEffectInfo : m_spellInfo->GetEffects())
6443  {
6444  switch (spellEffectInfo.ApplyAuraName)
6445  {
6447  {
6448  if (m_caster->GetTypeId() != TYPEID_PLAYER)
6449  return SPELL_FAILED_NO_PET;
6450 
6451  Pet* pet = m_caster->ToPlayer()->GetPet();
6452  if (!pet)
6453  return SPELL_FAILED_NO_PET;
6454 
6455  if (!pet->GetCharmerGUID().IsEmpty())
6457  break;
6458  }
6460  case SPELL_AURA_MOD_CHARM:
6461  case SPELL_AURA_AOE_CHARM:
6462  {
6463  Unit* unitCaster = (m_originalCaster ? m_originalCaster : m_caster->ToUnit());
6464  if (!unitCaster)
6465  return SPELL_FAILED_BAD_TARGETS;
6466 
6467  if (!unitCaster->GetCharmerGUID().IsEmpty())
6468  return SPELL_FAILED_CHARMED;
6469 
6470  if (spellEffectInfo.ApplyAuraName == SPELL_AURA_MOD_CHARM
6471  || spellEffectInfo.ApplyAuraName == SPELL_AURA_MOD_POSSESS)
6472  {
6475 
6476  if (!unitCaster->GetCharmedGUID().IsEmpty())
6478  }
6479 
6480  if (Unit* target = m_targets.GetUnitTarget())
6481  {
6482  if (target->GetTypeId() == TYPEID_UNIT && target->IsVehicle())
6484 
6485  if (target->IsMounted())
6487 
6488  if (!target->GetCharmerGUID().IsEmpty())
6490 
6491  if (target->GetOwner() && target->GetOwner()->GetTypeId() == TYPEID_PLAYER)
6493 
6494  int32 value = CalculateDamage(spellEffectInfo, target);
6495  if (value && int32(target->GetLevelForTarget(m_caster)) > value)
6496  return SPELL_FAILED_HIGHLEVEL;
6497  }
6498 
6499  break;
6500  }
6501  case SPELL_AURA_MOUNTED:
6502  {
6503  Unit* unitCaster = m_caster->ToUnit();
6504  if (!unitCaster)
6505  return SPELL_FAILED_BAD_TARGETS;
6506 
6509 
6510  if (unitCaster->IsInDisallowedMountForm())
6511  {
6512  SendMountResult(MountResult::Shapeshifted); // mount result gets sent before the cast result
6513  return SPELL_FAILED_DONT_REPORT;
6514  }
6515  break;
6516  }
6518  {
6519  if (!m_targets.GetUnitTarget())
6521 
6522  // can be cast at non-friendly unit or own pet/charm
6525  break;
6526  }
6527  case SPELL_AURA_FLY:
6529  {
6530  // not allow cast fly spells if not have req. skills (all spells is self target)
6531  // allow always ghost flight spells
6533  {
6534  Battlefield* Bf = sBattlefieldMgr->GetBattlefieldToZoneId(m_originalCaster->GetZoneId());
6535  if (AreaTableEntry const* area = sAreaTableStore.LookupEntry(m_originalCaster->GetAreaId()))
6536  if (area->Flags[0] & AREA_FLAG_NO_FLY_ZONE || (Bf && !Bf->CanFlyIn()))
6537  return SPELL_FAILED_NOT_HERE;
6538  }
6539  break;
6540  }
6542  {
6543  if (spellEffectInfo.IsTargetingArea())
6544  break;
6545 
6546  if (!m_targets.GetUnitTarget())
6548 
6550  break;
6551 
6553  return SPELL_FAILED_BAD_TARGETS;
6554  break;
6555  }
6556  default:
6557  break;
6558  }
6559 
6560  // check if target already has the same type, but more powerful aura
6562  && (!nonAuraEffectMask || m_spellInfo->HasAttribute(SPELL_ATTR4_AURA_BOUNCE_FAILS_SPELL))
6563  && (approximateAuraEffectMask & (1 << spellEffectInfo.EffectIndex))
6565  if (Unit* target = m_targets.GetUnitTarget())
6566  if (!target->IsHighestExclusiveAuraEffect(m_spellInfo, spellEffectInfo.ApplyAuraName,
6567  spellEffectInfo.CalcValue(m_caster, &m_spellValue->EffectBasePoints[spellEffectInfo.EffectIndex], nullptr, nullptr, m_castItemEntry, m_castItemLevel),
6568  approximateAuraEffectMask, false))
6570  }
6571 
6572  // check trade slot case (last, for allow catch any another cast problems)
6574  {
6575  if (m_CastItem)
6577 
6580 
6581  if (m_caster->GetTypeId() != TYPEID_PLAYER)
6582  return SPELL_FAILED_NOT_TRADING;
6583 
6584  TradeData* my_trade = m_caster->ToPlayer()->GetTradeData();
6585  if (!my_trade)
6586  return SPELL_FAILED_NOT_TRADING;
6587 
6589  return SPELL_FAILED_BAD_TARGETS;
6590 
6591  if (!IsTriggered())
6592  if (my_trade->GetSpell())
6594  }
6595 
6596  // check if caster has at least 1 combo point for spells that require combo points
6597  if (m_needComboPoints)
6598  if (Player* plrCaster = m_caster->ToPlayer())
6599  if (!plrCaster->GetComboPoints())
6601 
6602  // all ok
6603  return SPELL_CAST_OK;
6604 }
GameObject * focusObject
Definition: Spell.h:708
Definition: SharedDefines.h:1243
GameObject * SearchSpellFocus()
Definition: Spell.cpp:2193
bool CanTameExoticPets() const
Definition: Player.h:2284
Definition: SpellAuraEffects.h:28
Definition: DB2Structure.h:468
float GetCombatReach() const override
Definition: Unit.h:812
Definition: Battleground.h:172
Definition: DB2Structure.h:125
Definition: SharedDefines.h:432
Definition: DBCEnums.h:666
Item * GetItemTarget() const
Definition: SpellDefines.h:351
constexpr std::underlying_type< E >::type AsUnderlyingType(E enumValue)
Definition: Util.h:473
bool IsOutdoors() const
Definition: Object.h:483
static Player * ToPlayer(Object *o)
Definition: Object.h:198
Definition: SharedDefines.h:1573
SpellInfo const *const m_spellInfo
Definition: Spell.h:532
BattlePetBreedQuality
Definition: BattlePetMgr.h:44
#define sDB2Manager
Definition: DB2Stores.h:479
Definition: SharedDefines.h:529
Definition: SharedDefines.h:2554
Difficulty
Definition: DBCEnums.h:664
ItemTemplate const * GetTemplate() const
Definition: Item.cpp:1137
SpellCastResult CallScriptCheckCastHandlers()
Definition: Spell.cpp:8419
Definition: SharedDefines.h:1670
SpellCastResult CheckRange(bool strict) const
Definition: Spell.cpp:6967
DB2Storage< ArtifactEntry > sArtifactStore("Artifact.db2", ArtifactLoadInfo::Instance())
Definition: SharedDefines.h:1586
Definition: DB2Structure.h:201
Definition: SharedDefines.h:1244
Definition: SharedDefines.h:1656
bool IsInWater() const
Definition: Unit.cpp:3055
bool CanFlyIn()
Return if we can use mount in battlefield.
Definition: Battlefield.h:343
Definition: SharedDefines.h:606
bool HasAura(AuraType aura) const
Definition: SpellInfo.cpp:1327
Definition: SharedDefines.h:1579
Definition: SharedDefines.h:1503
Difficulty GetDifficultyID() const
Definition: Map.h:401
Definition: SharedDefines.h:1555
Definition: ObjectMgr.h:156
Definition: PathGenerator.h:47
Definition: SharedDefines.h:2538
Definition: SharedDefines.h:2551
SpellCastResult CheckItems(int32 *param1, int32 *param2) const
Definition: Spell.cpp:7116
SpellCastResult CheckArenaAndRatedBattlegroundCastRules()
Definition: Spell.cpp:6836
Definition: SpellDefines.h:283
TypeID GetTypeId() const
Definition: Object.h:170
DB2Storage< ChrClassesEntry > sChrClassesStore("ChrClasses.db2", ChrClassesLoadInfo::Instance())
Definition: SharedDefines.h:1532
Definition: SharedDefines.h:1373
uint8 GetClass() const
Definition: Unit.h:869
std::vector< uint32 > const & GetGlyphs(uint8 spec) const
Definition: Player.h:1875
Definition: SharedDefines.h:1690
bool IsMounted() const
Definition: Unit.h:1012
DB2Storage< BattlePetSpeciesEntry > sBattlePetSpeciesStore("BattlePetSpecies.db2", BattlePetSpeciesLoadInfo::Instance())
ObjectGuid GetCharmerGUID() const
Definition: Unit.h:1272
uint32 DmgClass
Definition: SpellInfo.h:427
Definition: SharedDefines.h:1472
DB2Storage< ChrSpecializationEntry > sChrSpecializationStore("ChrSpecialization.db2", ChrSpecializationLoadInfo::Instance())
SpellCustomErrors
Definition: SharedDefines.h:1763
uint32 SpellLevel
Definition: SpellInfo.h:401
Definition: SharedDefines.h:5209
union Spell::@328 m_misc
Definition: SpellInfo.h:342
Definition: SharedDefines.h:483
Definition: SharedDefines.h:1451
Definition: SharedDefines.h:1191
ObjectGuid GetCastItemGUID() const
Definition: SpellAuras.h:143
Definition: SharedDefines.h:1559
Definition: SharedDefines.h:1177
bool HasEffect(SpellEffectName effect) const
Definition: SpellInfo.cpp:1318
SpellCastTargets m_targets
Definition: Spell.h:575
bool isLooted() const
Definition: Loot.h:242
PetStable * GetPetStable()
Definition: Player.h:1246
Definition: SharedDefines.h:1222
Pet * ToPet()
Definition: Unit.h:1841
WorldSession * GetSession() const
Definition: Player.h:2082
bool HasSummonPending() const
Definition: Player.cpp:25416
Definition: SpellAuraDefines.h:172
bool InBattleground() const
Definition: Player.h:2373
bool HasAura(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemCasterGUID=ObjectGuid::Empty, uint32 reqEffMask=0) const
Definition: Unit.cpp:4520
static ObjectGuid GetGUID(Object const *o)
Definition: Object.h:156
Definition: SharedDefines.h:1454
Definition: SharedDefines.h:1830
AuraStateType
Definition: SharedDefines.h:2412
flag128 SpellFamilyFlags
Definition: SpellInfo.h:426
uint32 ExcludeCasterAuraSpell
Definition: SpellInfo.h:381
Definition: SharedDefines.h:1286
SpellCastResult CheckPower() const
Definition: Spell.cpp:7074
bool IsInCombat() const
Definition: Unit.h:1149
Definition: SharedDefines.h:424
static VMapManager2 * createOrGetVMapManager()
Definition: VMapFactory.cpp:27
Definition: SharedDefines.h:1445
SpellInfo const * m_triggeredByAuraSpell
Definition: Spell.h:875
ObjectGuid GetItemTargetGUID() const
Definition: SpellDefines.h:350
WorldObject *const m_caster
Definition: Spell.h:649
bool IsInDisallowedMountForm() const
Definition: Unit.cpp:8604
GameObject * GetGOTarget() const
Definition: Spell.cpp:236
Definition: SpellAuraDefines.h:96
int32 Control
Definition: DB2Structure.h:3665
Loot loot
Definition: Creature.h:226
static GameObject * ToGameObject(Object *o)
Definition: Object.h:216
uint32 RequiresSpellFocus
Definition: SpellInfo.h:373
std::list< AuraEffect * > AuraEffectList
Definition: Unit.h:764
Definition: SpellAuraDefines.h:369
Definition: DB2Structure.h:2488
Definition: ObjectGuid.h:39
Definition: DisableMgr.h:48
Definition: SharedDefines.h:1352
Definition: SharedDefines.h:1274
Definition: SharedDefines.h:1176
bool NeedsExplicitUnitTarget() const
Definition: SpellInfo.cpp:1478
CreatureTemplate const * GetCreatureTemplate() const
Definition: Creature.h:207
Definition: SharedDefines.h:1649
Definition: SharedDefines.h:1655
bool IsTameable(bool canTameExotic) const
Definition: CreatureData.h:494
uint32 m_castItemEntry
Definition: Spell.h:535
bool IsLocked() const
Definition: Item.h:250
Definition: SharedDefines.h:1567
bool HasSpell(uint32 spell) const override
Definition: Player.cpp:3720
DynamicObject * GetDynObject(uint32 spellId) const
Definition: Unit.cpp:5020
bool IsPassive() const
Definition: SpellInfo.cpp:1519
Definition: Object.h:430
Definition: Creature.h:69
PetSaveMode
Definition: PetDefines.h:40
bool IsPotion() const
Definition: Item.h:331
SpellCastResult CheckShapeshift(uint32 form) const
Definition: SpellInfo.cpp:1877
Definition: SharedDefines.h:1601
Battleground * GetBattleground() const
Definition: Player.cpp:25124
bool IsInSameRaidWith(Player const *p) const
Definition: Player.cpp:2204
bool HasCooldown(SpellInfo const *spellInfo, uint32 itemId=0) const
Definition: SpellHistory.cpp:664
#define M_PI
Definition: Common.h:157
Item * m_CastItem
Definition: Spell.h:533
Definition: SharedDefines.h:5858
SpellValue *const m_spellValue
Definition: Spell.h:651
Definition: SpellAuraDefines.h:158
Definition: SharedDefines.h:1531
bool HasUnitFlag2(UnitFlags2 flags) const
Definition: Unit.h:953
Definition: Unit.h:252
Definition: SharedDefines.h:1554
Definition: SharedDefines.h:1184
#define sObjectMgr
Definition: ObjectMgr.h:1967
uint32 ErrorTextId
Definition: ConditionMgr.h:232
std::unique_ptr< PathGenerator > m_preGeneratedPath
Definition: Spell.h:877
Definition: SharedDefines.h:1591
bool CanUseBattlegroundObject(GameObject *gameobject) const
Definition: Player.cpp:26317
CharmInfo * GetCharmInfo()
Definition: Unit.h:1306
Definition: SpellAuraDefines.h:221
bool HasUnitFlag(UnitFlags flags) const
Definition: Unit.h:948
uint32 GetId() const
Definition: Map.cpp:4410
uint32 GetZoneId() const
Definition: Object.h:479
Definition: SharedDefines.h:1557
uint32 CategoryId
Definition: SpellInfo.h:349
uint8 GetArtifactID() const
Definition: ItemTemplate.h:788
Definition: SharedDefines.h:1524
bool IsIgnoringCooldowns() const
Definition: Spell.cpp:7966
Definition: DBCEnums.h:139
Definition: SharedDefines.h:1550
Definition: SharedDefines.h:1165
Definition: SharedDefines.h:1662
int8 ClassID
Definition: DB2Structure.h:815
Definition: SharedDefines.h:1583
bool IsPetSpecialization() const
Definition: DB2Structure.h:825
Definition: SharedDefines.h:584
bool IsBattleground() const
Definition: Map.cpp:4452
Definition: SharedDefines.h:494
float GetPositionY() const
Definition: Position.h:78
Map * GetMap() const
Definition: Object.h:555
uint8 ArtifactCategoryID
Definition: DB2Structure.h:211
Definition: SharedDefines.h:1692
std::array< Optional< PetInfo >, MAX_ACTIVE_PETS > ActivePets
Definition: PetDefines.h:140