AzerothCore 3.3.5a
OpenSource WoW Emulator
Loading...
Searching...
No Matches
Spell Class Reference

#include "Spell.h"

Classes

struct  GOTargetInfo
 
struct  HitTriggerSpell
 
struct  ItemTargetInfo
 

Public Types

typedef std::set< Aura * > UsedSpellMods
 

Public Member Functions

 Spell (Unit *caster, SpellInfo const *info, TriggerCastFlags triggerFlags, ObjectGuid originalCasterGUID=ObjectGuid::Empty, bool skipCheck=false)
 
 ~Spell ()
 
void EffectNULL (SpellEffIndex effIndex)
 
void EffectUnused (SpellEffIndex effIndex)
 
void EffectDistract (SpellEffIndex effIndex)
 
void EffectPull (SpellEffIndex effIndex)
 
void EffectSchoolDMG (SpellEffIndex effIndex)
 
void EffectEnvironmentalDMG (SpellEffIndex effIndex)
 
void EffectInstaKill (SpellEffIndex effIndex)
 
void EffectDummy (SpellEffIndex effIndex)
 
void EffectTeleportUnits (SpellEffIndex effIndex)
 
void EffectApplyAura (SpellEffIndex effIndex)
 
void EffectSendEvent (SpellEffIndex effIndex)
 
void EffectPowerBurn (SpellEffIndex effIndex)
 
void EffectPowerDrain (SpellEffIndex effIndex)
 
void EffectHeal (SpellEffIndex effIndex)
 
void EffectBind (SpellEffIndex effIndex)
 
void EffectHealthLeech (SpellEffIndex effIndex)
 
void EffectQuestComplete (SpellEffIndex effIndex)
 
void EffectCreateItem (SpellEffIndex effIndex)
 
void EffectCreateItem2 (SpellEffIndex effIndex)
 
void EffectCreateRandomItem (SpellEffIndex effIndex)
 
void EffectPersistentAA (SpellEffIndex effIndex)
 
void EffectEnergize (SpellEffIndex effIndex)
 
void EffectOpenLock (SpellEffIndex effIndex)
 
void EffectSummonChangeItem (SpellEffIndex effIndex)
 
void EffectProficiency (SpellEffIndex effIndex)
 
void EffectApplyAreaAura (SpellEffIndex effIndex)
 
void EffectSummonType (SpellEffIndex effIndex)
 
void EffectLearnSpell (SpellEffIndex effIndex)
 
void EffectDispel (SpellEffIndex effIndex)
 
void EffectDualWield (SpellEffIndex effIndex)
 
void EffectPickPocket (SpellEffIndex effIndex)
 
void EffectAddFarsight (SpellEffIndex effIndex)
 
void EffectUntrainTalents (SpellEffIndex effIndex)
 
void EffectHealMechanical (SpellEffIndex effIndex)
 
void EffectJump (SpellEffIndex effIndex)
 
void EffectJumpDest (SpellEffIndex effIndex)
 
void EffectLeapBack (SpellEffIndex effIndex)
 
void EffectQuestClear (SpellEffIndex effIndex)
 
void EffectTeleUnitsFaceCaster (SpellEffIndex effIndex)
 
void EffectLearnSkill (SpellEffIndex effIndex)
 
void EffectAddHonor (SpellEffIndex effIndex)
 
void EffectTradeSkill (SpellEffIndex effIndex)
 
void EffectEnchantItemPerm (SpellEffIndex effIndex)
 
void EffectEnchantItemTmp (SpellEffIndex effIndex)
 
void EffectTameCreature (SpellEffIndex effIndex)
 
void EffectSummonPet (SpellEffIndex effIndex)
 
void EffectLearnPetSpell (SpellEffIndex effIndex)
 
void EffectWeaponDmg (SpellEffIndex effIndex)
 
void EffectForceCast (SpellEffIndex effIndex)
 
void EffectTriggerSpell (SpellEffIndex effIndex)
 
void EffectTriggerMissileSpell (SpellEffIndex effIndex)
 
void EffectThreat (SpellEffIndex effIndex)
 
void EffectHealMaxHealth (SpellEffIndex effIndex)
 
void EffectInterruptCast (SpellEffIndex effIndex)
 
void EffectSummonObjectWild (SpellEffIndex effIndex)
 
void EffectScriptEffect (SpellEffIndex effIndex)
 
void EffectSanctuary (SpellEffIndex effIndex)
 
void EffectAddComboPoints (SpellEffIndex effIndex)
 
void EffectDuel (SpellEffIndex effIndex)
 
void EffectStuck (SpellEffIndex effIndex)
 
void EffectSummonPlayer (SpellEffIndex effIndex)
 
void EffectActivateObject (SpellEffIndex effIndex)
 
void EffectApplyGlyph (SpellEffIndex effIndex)
 
void EffectEnchantHeldItem (SpellEffIndex effIndex)
 
void EffectSummonObject (SpellEffIndex effIndex)
 
void EffectResurrect (SpellEffIndex effIndex)
 
void EffectParry (SpellEffIndex effIndex)
 
void EffectBlock (SpellEffIndex effIndex)
 
void EffectLeap (SpellEffIndex effIndex)
 
void EffectTransmitted (SpellEffIndex effIndex)
 
void EffectDisEnchant (SpellEffIndex effIndex)
 
void EffectInebriate (SpellEffIndex effIndex)
 
void EffectFeedPet (SpellEffIndex effIndex)
 
void EffectDismissPet (SpellEffIndex effIndex)
 
void EffectReputation (SpellEffIndex effIndex)
 
void EffectForceDeselect (SpellEffIndex effIndex)
 
void EffectSelfResurrect (SpellEffIndex effIndex)
 
void EffectSkinning (SpellEffIndex effIndex)
 
void EffectCharge (SpellEffIndex effIndex)
 
void EffectChargeDest (SpellEffIndex effIndex)
 
void EffectProspecting (SpellEffIndex effIndex)
 
void EffectMilling (SpellEffIndex effIndex)
 
void EffectRenamePet (SpellEffIndex effIndex)
 
void EffectSendTaxi (SpellEffIndex effIndex)
 
void EffectSummonCritter (SpellEffIndex effIndex)
 
void EffectKnockBack (SpellEffIndex effIndex)
 
void EffectPullTowards (SpellEffIndex effIndex)
 
void EffectDispelMechanic (SpellEffIndex effIndex)
 
void EffectResurrectPet (SpellEffIndex effIndex)
 
void EffectDestroyAllTotems (SpellEffIndex effIndex)
 
void EffectDurabilityDamage (SpellEffIndex effIndex)
 
void EffectSkill (SpellEffIndex effIndex)
 
void EffectTaunt (SpellEffIndex effIndex)
 
void EffectDurabilityDamagePCT (SpellEffIndex effIndex)
 
void EffectModifyThreatPercent (SpellEffIndex effIndex)
 
void EffectResurrectNew (SpellEffIndex effIndex)
 
void EffectAddExtraAttacks (SpellEffIndex effIndex)
 
void EffectSpiritHeal (SpellEffIndex effIndex)
 
void EffectSkinPlayerCorpse (SpellEffIndex effIndex)
 
void EffectStealBeneficialBuff (SpellEffIndex effIndex)
 
void EffectUnlearnSpecialization (SpellEffIndex effIndex)
 
void EffectHealPct (SpellEffIndex effIndex)
 
void EffectEnergizePct (SpellEffIndex effIndex)
 
void EffectTriggerRitualOfSummoning (SpellEffIndex effIndex)
 
void EffectSummonRaFFriend (SpellEffIndex effIndex)
 
void EffectKillCreditPersonal (SpellEffIndex effIndex)
 
void EffectKillCredit (SpellEffIndex effIndex)
 
void EffectQuestFail (SpellEffIndex effIndex)
 
void EffectQuestStart (SpellEffIndex effIndex)
 
void EffectRedirectThreat (SpellEffIndex effIndex)
 
void EffectGameObjectDamage (SpellEffIndex effIndex)
 
void EffectGameObjectRepair (SpellEffIndex effIndex)
 
void EffectGameObjectSetDestructionState (SpellEffIndex effIndex)
 
void EffectActivateRune (SpellEffIndex effIndex)
 
void EffectCreateTamedPet (SpellEffIndex effIndex)
 
void EffectDiscoverTaxi (SpellEffIndex effIndex)
 
void EffectTitanGrip (SpellEffIndex effIndex)
 
void EffectEnchantItemPrismatic (SpellEffIndex effIndex)
 
void EffectPlayMusic (SpellEffIndex effIndex)
 
void EffectSpecCount (SpellEffIndex effIndex)
 
void EffectActivateSpec (SpellEffIndex effIndex)
 
void EffectPlaySound (SpellEffIndex effIndex)
 
void EffectRemoveAura (SpellEffIndex effIndex)
 
void EffectCastButtons (SpellEffIndex effIndex)
 
void EffectRechargeManaGem (SpellEffIndex effIndex)
 
void InitExplicitTargets (SpellCastTargets const &targets)
 
void SelectExplicitTargets ()
 
void SelectSpellTargets ()
 
void SelectEffectImplicitTargets (SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType, uint32 &processedEffectMask)
 
void SelectImplicitChannelTargets (SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
 
void SelectImplicitNearbyTargets (SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType, uint32 effMask)
 
void SelectImplicitConeTargets (SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType, uint32 effMask)
 
void SelectImplicitAreaTargets (SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType, uint32 effMask)
 
void SelectImplicitCasterDestTargets (SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
 
void SelectImplicitTargetDestTargets (SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
 
void SelectImplicitDestDestTargets (SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
 
void SelectImplicitCasterObjectTargets (SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
 
void SelectImplicitTargetObjectTargets (SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
 
void SelectImplicitChainTargets (SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType, WorldObject *target, uint32 effMask)
 
void SelectImplicitTrajTargets (SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
 
void SelectEffectTypeImplicitTargets (uint8 effIndex)
 
uint32 GetSearcherTypeMask (SpellTargetObjectTypes objType, ConditionList *condList)
 
template<class SEARCHER >
void SearchTargets (SEARCHER &searcher, uint32 containerMask, Unit *referer, Position const *pos, float radius)
 
WorldObjectSearchNearbyTarget (float range, SpellTargetObjectTypes objectType, SpellTargetCheckTypes selectionType, ConditionList *condList=nullptr)
 
void SearchAreaTargets (std::list< WorldObject * > &targets, float range, Position const *position, Unit *referer, SpellTargetObjectTypes objectType, SpellTargetCheckTypes selectionType, ConditionList *condList)
 
void SearchChainTargets (std::list< WorldObject * > &targets, uint32 chainTargets, WorldObject *target, SpellTargetObjectTypes objectType, SpellTargetCheckTypes selectType, SpellTargetSelectionCategories selectCategory, ConditionList *condList, bool isChainHeal)
 
SpellCastResult prepare (SpellCastTargets const *targets, AuraEffect const *triggeredByAura=nullptr)
 
void cancel (bool bySelf=false)
 
void update (uint32 difftime)
 
void cast (bool skipCheck=false)
 
void _cast (bool skipCheck)
 
void finish (bool ok=true)
 
void TakePower ()
 
void TakeAmmo ()
 
void TakeRunePower (bool didHit)
 
void TakeReagents ()
 
void TakeCastItem ()
 
SpellCastResult CheckCast (bool strict)
 
SpellCastResult CheckPetCast (Unit *target)
 
void handle_immediate ()
 
uint64 handle_delayed (uint64 t_offset)
 
void _handle_immediate_phase ()
 
void _handle_finish_phase ()
 
void OnSpellLaunch ()
 
SpellCastResult CheckItems ()
 
SpellCastResult CheckSpellFocus ()
 
SpellCastResult CheckRange (bool strict)
 
SpellCastResult CheckPower ()
 
SpellCastResult CheckRuneCost (uint32 RuneCostID)
 
SpellCastResult CheckCasterAuras (bool preventionOnly) const
 
int32 CalculateSpellDamage (uint8 i, Unit const *target) const
 
bool HaveTargetsForEffect (uint8 effect) const
 
void Delayed ()
 
void DelayedChannel ()
 
uint32 getState () const
 
void setState (uint32 state)
 
void DoCreateItem (uint8 effIndex, uint32 itemId)
 
void WriteSpellGoTargets (WorldPacket *data)
 Writes miss and hit targets for a SMSG_SPELL_GO packet. More...
 
void WriteAmmoToPacket (WorldPacket *data)
 
bool CheckEffectTarget (Unit const *target, uint32 eff) const
 
bool CanAutoCast (Unit *target)
 
void CheckSrc ()
 
void CheckDst ()
 
void SendCastResult (SpellCastResult result)
 
void SendPetCastResult (SpellCastResult result)
 
void SendSpellStart ()
 
void SendSpellGo ()
 
void SendSpellCooldown ()
 
void SendLogExecute ()
 
void ExecuteLogEffectTakeTargetPower (uint8 effIndex, Unit *target, uint32 PowerType, uint32 powerTaken, float gainMultiplier)
 
void ExecuteLogEffectExtraAttacks (uint8 effIndex, Unit *victim, uint32 attCount)
 
void ExecuteLogEffectInterruptCast (uint8 effIndex, Unit *victim, uint32 spellId)
 
void ExecuteLogEffectDurabilityDamage (uint8 effIndex, Unit *victim, int32 itemId, int32 slot)
 
void ExecuteLogEffectOpenLock (uint8 effIndex, Object *obj)
 
void ExecuteLogEffectCreateItem (uint8 effIndex, uint32 entry)
 
void ExecuteLogEffectDestroyItem (uint8 effIndex, uint32 entry)
 
void ExecuteLogEffectSummonObject (uint8 effIndex, WorldObject *obj)
 
void ExecuteLogEffectUnsummonObject (uint8 effIndex, WorldObject *obj)
 
void ExecuteLogEffectResurrect (uint8 effIndex, Unit *target)
 
void SendInterrupted (uint8 result)
 
void SendChannelUpdate (uint32 time)
 
void SendChannelStart (uint32 duration)
 
void SendResurrectRequest (Player *target)
 
void HandleEffects (Unit *pUnitTarget, Item *pItemTarget, GameObject *pGOTarget, uint32 i, SpellEffectHandleMode mode)
 
void HandleThreatSpells ()
 
void AddComboPointGain (Unit *target, int8 amount)
 
int32 GetCastTime () const
 
bool IsAutoRepeat () const
 
void SetAutoRepeat (bool rep)
 
void ReSetTimer ()
 
int32 GetCastTimeRemaining ()
 
bool IsNextMeleeSwingSpell () const
 
bool IsTriggered () const
 
bool HasTriggeredCastFlag (TriggerCastFlags flag) const
 
bool IsChannelActive () const
 
bool IsAutoActionResetSpell () const
 
bool IsIgnoringCooldowns () 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 GetDelayTrajectory () const
 
uint64 CalculateDelayMomentForDst () const
 
void RecalculateDelayMomentForDst ()
 
bool IsNeedSendToClient (bool go) const
 
CurrentSpellTypes GetCurrentContainer () const
 
UnitGetCaster () const
 
UnitGetOriginalCaster () const
 
SpellInfo const * GetSpellInfo () const
 
int32 GetPowerCost () const
 
bool UpdatePointers ()
 
void CleanupTargetList ()
 
void SetSpellValue (SpellValueMod mod, int32 value)
 
SpellValue const * GetSpellValue ()
 
void LoadScripts ()
 
std::list< TargetInfo > * GetUniqueTargetInfo ()
 
uint32 GetTriggeredByAuraTickNumber () const
 
TriggerCastFlags GetTriggeredCastFlags () const
 
SpellSchoolMask GetSpellSchoolMask () const
 

Static Public Member Functions

static void WriteCastResultInfo (WorldPacket &data, Player *caster, SpellInfo const *spellInfo, uint8 castCount, SpellCastResult result, SpellCustomErrors customError)
 
static void SendCastResult (Player *caster, SpellInfo const *spellInfo, uint8 castCount, SpellCastResult result, SpellCustomErrors customError=SPELL_CUSTOM_ERROR_NONE)
 

Public Attributes

SpellInfo const *const m_spellInfo
 
Itemm_CastItem
 
Itemm_weaponItem
 
ObjectGuid m_castItemGUID
 
uint8 m_cast_count
 
uint32 m_glyphIndex
 
uint32 m_preCastSpell
 
SpellCastTargets m_targets
 
SpellCustomErrors m_customError
 
Unitm_comboTarget
 
int8 m_comboPointGain
 
UsedSpellMods m_appliedMods
 

Protected Types

typedef std::list< HitTriggerSpellHitTriggerSpellList
 

Protected Member Functions

bool HasGlobalCooldown () const
 
void TriggerGlobalCooldown ()
 
void CancelGlobalCooldown ()
 
void SendLoot (ObjectGuid guid, LootType loottype)
 
std::string GetDebugInfo () const
 
bool isDelayableNoMore ()
 
void prepareDataForTriggerSystem (AuraEffect const *triggeredByAura)
 
void AddUnitTarget (Unit *target, uint32 effectMask, bool checkIfValid=true, bool implicit=true)
 
void AddGOTarget (GameObject *target, uint32 effectMask)
 
void AddItemTarget (Item *item, uint32 effectMask)
 
void AddDestTarget (SpellDestination const &dest, uint32 effIndex)
 
void DoAllEffectOnTarget (TargetInfo *target)
 
SpellMissInfo DoSpellHitOnUnit (Unit *unit, uint32 effectMask, bool scaleAura)
 
void DoTriggersOnSpellHit (Unit *unit, uint8 effMask)
 
void DoAllEffectOnTarget (GOTargetInfo *target)
 
void DoAllEffectOnTarget (ItemTargetInfo *target)
 
bool UpdateChanneledTargetList ()
 
bool IsValidDeadOrAliveTarget (Unit const *target) const
 
void HandleLaunchPhase ()
 
void DoAllEffectOnLaunchTarget (TargetInfo &targetInfo, float *multiplier)
 
void PrepareTargetProcessing ()
 
void FinishTargetProcessing ()
 
void InitEffectExecuteData (uint8 effIndex)
 
void CheckEffectExecuteData ()
 
void CallScriptBeforeCastHandlers ()
 
void CallScriptOnCastHandlers ()
 
void CallScriptAfterCastHandlers ()
 
SpellCastResult CallScriptCheckCastHandlers ()
 
void PrepareScriptHitHandlers ()
 
bool CallScriptEffectHandlers (SpellEffIndex effIndex, SpellEffectHandleMode mode)
 
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 (uint8 effMask, SpellInfo const *triggeredByAura=nullptr) const
 
void PrepareTriggersExecutedOnHit ()
 
void SummonGuardian (uint32 i, uint32 entry, SummonPropertiesEntry const *properties, uint32 numSummons, bool personalSpawn)
 
void CalculateJumpSpeeds (uint8 i, float dist, float &speedxy, float &speedz)
 
SpellCastResult CanOpenLock (uint32 effIndex, uint32 lockid, SkillType &skillid, int32 &reqSkillValue, int32 &skillValue)
 

Protected Attributes

Unit *const m_caster
 
SpellValue *const m_spellValue
 
ObjectGuid m_originalCasterGUID
 
Unitm_originalCaster
 
Spell ** m_selfContainer
 
SpellSchoolMask m_spellSchoolMask
 
WeaponAttackType m_attackType
 
int32 m_powerCost
 
int32 m_casttime
 
int32 m_channeledDuration
 
bool m_canReflect
 
uint8 m_spellFlags
 
bool m_autoRepeat
 
uint8 m_runesState
 
uint8 m_delayAtDamageCount
 
uint64 m_delayStart
 
uint64 m_delayMoment
 
uint64 m_delayTrajectory
 
bool m_immediateHandled
 
bool m_referencedFromCurrentSpell
 
bool m_executedCurrently
 
bool m_needComboPoints
 
uint8 m_applyMultiplierMask
 
float m_damageMultipliers [3]
 
UnitunitTarget
 
ItemitemTarget
 
GameObjectgameObjTarget
 
WorldLocationdestTarget
 
int32 damage
 
SpellEffectHandleMode effectHandleMode
 
Auram_spellAura
 
DiminishingLevels m_diminishLevel
 
DiminishingGroup m_diminishGroup
 
GameObjectfocusObject
 
int32 m_damage
 
int32 m_healing
 
uint32 m_procAttacker
 
uint32 m_procVictim
 
uint32 m_procEx
 
std::list< TargetInfom_UniqueTargetInfo
 
uint8 m_channelTargetEffectMask
 
std::list< GOTargetInfom_UniqueGOTargetInfo
 
std::list< ItemTargetInfom_UniqueItemInfo
 
SpellDestination m_destTargets [MAX_SPELL_EFFECTS]
 
bool _scriptsLoaded
 
std::list< SpellScript * > m_loadedScripts
 
HitTriggerSpellList m_hitTriggerSpells
 
uint32 m_spellState
 
int32 m_timer
 
SpellEvent_spellEvent
 
TriggerCastFlags _triggeredCastFlags
 
TriggeredByAuraSpellData m_triggeredByAuraSpell
 
bool m_skipCheck
 
uint8 m_auraScaleMask
 
std::unique_ptr< PathGeneratorm_preGeneratedPath
 
bool _spellTargetsSelected
 
ByteBufferm_effectExecuteData [MAX_SPELL_EFFECTS]
 

Friends

class SpellScript
 
void Unit::SetCurrentCastedSpell (Spell *pSpell)
 

Detailed Description

Member Typedef Documentation

◆ HitTriggerSpellList

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

◆ UsedSpellMods

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

Constructor & Destructor Documentation

◆ Spell()

Spell::Spell ( Unit caster,
SpellInfo const *  info,
TriggerCastFlags  triggerFlags,
ObjectGuid  originalCasterGUID = ObjectGuid::Empty,
bool  skipCheck = false 
)
571 :
572 m_spellInfo(sSpellMgr->GetSpellForDifficultyFromSpell(info, caster)),
573 m_caster((info->HasAttribute(SPELL_ATTR6_ORIGINATE_FROM_CONTROLLER) && caster->GetCharmerOrOwner()) ? caster->GetCharmerOrOwner() : caster)
575{
577 m_skipCheck = skipCheck;
578 m_selfContainer = nullptr;
580 m_executedCurrently = false;
583 m_comboTarget = nullptr;
584 m_delayStart = 0;
586
588 m_auraScaleMask = 0;
589 memset(m_damageMultipliers, 0, sizeof(m_damageMultipliers));
590
591 // Get data for type of attack
592 switch (m_spellInfo->DmgClass)
593 {
597 else
599 break;
602 break;
603 default:
604 // Wands
607 else
609 break;
610 }
611
612 m_spellSchoolMask = info->GetSchoolMask(); // Can be override for some spell (wand shoot for example)
613
615 // wand case
618 m_spellSchoolMask = SpellSchoolMask(1 << pItem->GetTemplate()->Damage[0].DamageType);
619
620 if (originalCasterGUID)
621 m_originalCasterGUID = originalCasterGUID;
622 else
624
627 else
628 {
631 m_originalCaster = nullptr;
632 }
633
635 _triggeredCastFlags = triggerFlags;
636 if (info->HasAttribute(SPELL_ATTR4_ALLOW_CAST_WHILE_CASTING))
638
639 m_CastItem = nullptr;
640
641 unitTarget = nullptr;
642 itemTarget = nullptr;
643 gameObjTarget = nullptr;
644 destTarget = nullptr;
645 damage = 0;
649 m_damage = 0;
650 m_healing = 0;
651 m_procAttacker = 0;
652 m_procVictim = 0;
653 m_procEx = 0;
654 focusObject = nullptr;
655 m_cast_count = 0;
656 m_glyphIndex = 0;
657 m_preCastSpell = 0;
658 m_spellAura = nullptr;
659 _scriptsLoaded = false;
660
661 //Auto Shot & Shoot (wand)
663
664 m_runesState = 0;
665 m_powerCost = 0; // setup to correct value in Spell::prepare, must not be used before.
666 m_casttime = 0; // setup to correct value in Spell::prepare, must not be used before.
667 m_timer = 0; // will set to castime in prepare
668 m_channeledDuration = 0; // will be setup in Spell::handle_immediate
669 m_immediateHandled = false;
670
672
674
675 // Determine if spell can be reflected back to the caster
676 // Patch 1.2 notes: Spell Reflection no longer reflects abilities
680
682 memset(m_effectExecuteData, 0, MAX_SPELL_EFFECTS * sizeof(ByteBuffer*));
683
684 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
686
687 // xinef:
688 _spellTargetsSelected = false;
689
690 m_weaponItem = nullptr;
691}
std::uint8_t uint8
Definition: Define.h:109
std::uint32_t uint32
Definition: Define.h:107
#define MAX_SPELL_EFFECTS
Definition: DBCStructure.h:1636
@ DIMINISHING_NONE
Definition: SharedDefines.h:3258
@ SPELL_EFFECT_DISPEL
Definition: SharedDefines.h:816
#define CLASSMASK_WAND_USERS
Definition: SharedDefines.h:174
@ SPELL_ATTR2_AUTO_REPEAT
Definition: SharedDefines.h:461
@ SPELL_ATTR1_NO_REFLECTION
Definition: SharedDefines.h:426
@ SPELL_ATTR3_REQUIRES_OFF_HAND_WEAPON
Definition: SharedDefines.h:517
@ SPELL_DAMAGE_CLASS_RANGED
Definition: SharedDefines.h:1548
@ SPELL_DAMAGE_CLASS_MAGIC
Definition: SharedDefines.h:1546
@ SPELL_DAMAGE_CLASS_MELEE
Definition: SharedDefines.h:1547
@ SPELL_CUSTOM_ERROR_NONE
Definition: SharedDefines.h:1143
@ SPELL_ATTR0_IS_ABILITY
Definition: SharedDefines.h:386
@ SPELL_ATTR0_NO_IMMUNITIES
Definition: SharedDefines.h:411
@ SPELL_ATTR4_ALLOW_CAST_WHILE_CASTING
Definition: SharedDefines.h:537
@ SPELL_ATTR6_ORIGINATE_FROM_CONTROLLER
Definition: SharedDefines.h:622
SpellSchoolMask
Definition: SharedDefines.h:295
@ SPELL_EFFECT_HANDLE_LAUNCH
Definition: Spell.h:236
@ SPELL_FLAG_NORMAL
Definition: Spell.h:83
@ SPELL_STATE_NULL
Definition: Spell.h:226
TriggerCastFlags
Definition: SpellDefines.h:132
@ TRIGGERED_CAST_DIRECTLY
Will ignore combo point requirement.
Definition: SpellDefines.h:141
@ TRIGGERED_IGNORE_CAST_IN_PROGRESS
Will ignore aura scaling.
Definition: SpellDefines.h:139
#define sSpellMgr
Definition: SpellMgr.h:825
@ OFF_ATTACK
Definition: Unit.h:210
@ BASE_ATTACK
Definition: Unit.h:209
@ RANGED_ATTACK
Definition: Unit.h:211
@ DIMINISHING_LEVEL_1
Definition: Unit.h:263
Unit * GetUnit(WorldObject const &, ObjectGuid const guid)
Definition: ObjectAccessor.cpp:199
Definition: Item.h:220
bool IsPlayer() const
Definition: Object.h:200
Player * ToPlayer()
Definition: Object.h:201
bool IsInWorld() const
Definition: Object.h:107
static ObjectGuid GetGUID(Object const *o)
Definition: Object.h:112
Item * GetWeaponForAttack(WeaponAttackType attackType, bool useable=false) const
Definition: PlayerStorage.cpp:488
Unit * GetCharmerOrOwner() const
Definition: Unit.h:1211
uint32 getClassMask() const
Definition: Unit.h:802
Definition: Spell.h:96
Definition: Spell.h:213
Unit * m_comboTarget
Definition: Spell.h:545
int8 m_comboPointGain
Definition: Spell.h:546
GameObject * gameObjTarget
Definition: Spell.h:657
bool m_referencedFromCurrentSpell
Definition: Spell.h:648
bool m_canReflect
Definition: Spell.h:624
uint32 m_procVictim
Definition: Spell.h:679
Unit * m_originalCaster
Definition: Spell.h:612
bool m_needComboPoints
Definition: Spell.h:650
uint64 m_delayStart
Definition: Spell.h:642
bool _scriptsLoaded
Definition: Spell.h:730
TriggerCastFlags _triggeredCastFlags
Definition: Spell.h:771
int32 damage
Definition: Spell.h:659
SpellEffectHandleMode effectHandleMode
Definition: Spell.h:660
int32 m_channeledDuration
Definition: Spell.h:623
Aura * m_spellAura
Definition: Spell.h:662
SpellDestination m_destTargets[MAX_SPELL_EFFECTS]
Definition: Spell.h:705
Unit *const m_caster
Definition: Spell.h:606
uint8 m_delayAtDamageCount
Definition: Spell.h:631
WeaponAttackType m_attackType
Definition: Spell.h:620
bool m_immediateHandled
Definition: Spell.h:645
uint32 m_spellState
Definition: Spell.h:767
ObjectGuid m_originalCasterGUID
Definition: Spell.h:610
void CleanupTargetList()
Definition: Spell.cpp:2375
int32 m_timer
Definition: Spell.h:768
int32 m_casttime
Definition: Spell.h:622
Item * itemTarget
Definition: Spell.h:656
uint8 m_cast_count
Definition: Spell.h:527
int32 m_damage
Definition: Spell.h:672
bool m_executedCurrently
Definition: Spell.h:649
DiminishingLevels m_diminishLevel
Definition: Spell.h:665
float m_damageMultipliers[3]
Definition: Spell.h:652
ByteBuffer * m_effectExecuteData[MAX_SPELL_EFFECTS]
Definition: Spell.h:785
uint8 m_auraScaleMask
Definition: Spell.h:779
SpellCustomErrors m_customError
Definition: Spell.h:531
uint8 m_spellFlags
Definition: Spell.h:626
bool m_skipCheck
Definition: Spell.h:778
int32 m_healing
Definition: Spell.h:673
uint32 m_glyphIndex
Definition: Spell.h:528
uint8 m_channelTargetEffectMask
Definition: Spell.h:687
Item * m_weaponItem
Definition: Spell.h:525
Unit * unitTarget
Definition: Spell.h:655
SpellSchoolMask m_spellSchoolMask
Definition: Spell.h:619
SpellEvent * _spellEvent
Definition: Spell.h:770
bool _spellTargetsSelected
Definition: Spell.h:783
uint32 m_preCastSpell
Definition: Spell.h:529
WorldLocation * destTarget
Definition: Spell.h:658
Spell ** m_selfContainer
Definition: Spell.h:614
uint8 m_applyMultiplierMask
Definition: Spell.h:651
DiminishingGroup m_diminishGroup
Definition: Spell.h:666
uint32 m_procEx
Definition: Spell.h:680
Item * m_CastItem
Definition: Spell.h:524
SpellValue *const m_spellValue
Definition: Spell.h:608
int32 m_powerCost
Definition: Spell.h:621
uint32 m_procAttacker
Definition: Spell.h:678
GameObject * focusObject
Definition: Spell.h:669
SpellInfo const *const m_spellInfo
Definition: Spell.h:523
uint8 m_runesState
Definition: Spell.h:629
bool m_autoRepeat
Definition: Spell.h:628
bool IsPassive() const
Definition: SpellInfo.cpp:1098
bool NeedsComboPoints() const
Definition: SpellInfo.cpp:1266
bool HasAttribute(SpellAttr0 attribute) const
Definition: SpellInfo.h:415
bool HasEffect(SpellEffects effect) const
Definition: SpellInfo.cpp:876
bool IsPositive() const
Definition: SpellInfo.cpp:1237
bool IsAutoRepeatRangedSpell() const
Definition: SpellInfo.cpp:1283
uint32 DmgClass
Definition: SpellInfo.h:389
bool IsRangedWeaponSpell() const
Definition: SpellInfo.cpp:1276
Definition: ByteBuffer.h:70

References _scriptsLoaded, _spellTargetsSelected, _triggeredCastFlags, BASE_ATTACK, CLASSMASK_WAND_USERS, CleanupTargetList(), damage, destTarget, DIMINISHING_LEVEL_1, DIMINISHING_NONE, SpellInfo::DmgClass, effectHandleMode, focusObject, gameObjTarget, Unit::getClassMask(), Object::GetGUID(), SpellInfo::GetSchoolMask(), ObjectAccessor::GetUnit(), Player::GetWeaponForAttack(), SpellInfo::HasAttribute(), SpellInfo::HasEffect(), SpellInfo::IsAutoRepeatRangedSpell(), Object::IsInWorld(), SpellInfo::IsPassive(), Object::IsPlayer(), SpellInfo::IsPositive(), SpellInfo::IsRangedWeaponSpell(), itemTarget, m_applyMultiplierMask, m_attackType, m_auraScaleMask, m_autoRepeat, m_canReflect, m_cast_count, m_caster, m_CastItem, m_casttime, m_channeledDuration, m_channelTargetEffectMask, m_comboPointGain, m_comboTarget, m_customError, m_damage, m_damageMultipliers, m_delayAtDamageCount, m_delayStart, m_destTargets, m_diminishGroup, m_diminishLevel, m_effectExecuteData, m_executedCurrently, m_glyphIndex, m_healing, m_immediateHandled, m_needComboPoints, m_originalCaster, m_originalCasterGUID, m_powerCost, m_preCastSpell, m_procAttacker, m_procEx, m_procVictim, m_referencedFromCurrentSpell, m_runesState, m_selfContainer, m_skipCheck, m_spellAura, m_spellFlags, m_spellInfo, m_spellSchoolMask, m_spellState, m_timer, m_weaponItem, MAX_SPELL_EFFECTS, SpellInfo::NeedsComboPoints(), OFF_ATTACK, RANGED_ATTACK, SPELL_ATTR0_IS_ABILITY, SPELL_ATTR0_NO_IMMUNITIES, SPELL_ATTR1_NO_REFLECTION, SPELL_ATTR2_AUTO_REPEAT, SPELL_ATTR3_REQUIRES_OFF_HAND_WEAPON, SPELL_ATTR4_ALLOW_CAST_WHILE_CASTING, SPELL_CUSTOM_ERROR_NONE, SPELL_DAMAGE_CLASS_MAGIC, SPELL_DAMAGE_CLASS_MELEE, SPELL_DAMAGE_CLASS_RANGED, SPELL_EFFECT_DISPEL, SPELL_EFFECT_HANDLE_LAUNCH, SPELL_FLAG_NORMAL, SPELL_STATE_NULL, Object::ToPlayer(), TRIGGERED_CAST_DIRECTLY, TRIGGERED_IGNORE_CAST_IN_PROGRESS, and unitTarget.

◆ ~Spell()

Spell::~Spell ( )
694{
695 // unload scripts
696 while (!m_loadedScripts.empty())
697 {
698 std::list<SpellScript*>::iterator itr = m_loadedScripts.begin();
699 (*itr)->_Unload();
700 delete (*itr);
701 m_loadedScripts.erase(itr);
702 }
703
705 {
706 // Clean the reference to avoid later crash.
707 // If this error is repeating, we may have to add an ASSERT to better track down how we get into this case.
708 LOG_ERROR("spells", "Spell::~Spell: deleting spell for spell ID {}. However, spell still referenced.", m_spellInfo->Id);
709 *m_selfContainer = nullptr;
710 }
711
712 delete m_spellValue;
713
715}
#define LOG_ERROR(filterType__,...)
Definition: Log.h:157
void CheckEffectExecuteData()
Definition: Spell.cpp:8504
std::list< SpellScript * > m_loadedScripts
Definition: Spell.h:745
uint32 Id
Definition: SpellInfo.h:320

References CheckEffectExecuteData(), SpellInfo::Id, LOG_ERROR, m_loadedScripts, m_referencedFromCurrentSpell, m_selfContainer, m_spellInfo, and m_spellValue.

Member Function Documentation

◆ _cast()

void Spell::_cast ( bool  skipCheck)

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

3812{
3813 // update pointers base at GUIDs to prevent access to non-existed already object
3814 if (!UpdatePointers())
3815 {
3816 // cancel the spell if UpdatePointers() returned false, something wrong happened there
3817 cancel();
3818 return;
3819 }
3820
3821 // cancel at lost explicit target during cast
3823 {
3824 cancel();
3825 return;
3826 }
3827
3828 // Xinef: implement attribute SPELL_ATTR1_DISMISS_PET_FIRST, on spell cast current pet is dismissed and charms are removed
3830 {
3832 if (Pet* pet = m_caster->ToPlayer()->GetPet())
3834
3835 if (Unit* charm = m_caster->GetCharm())
3836 charm->RemoveAurasByType(SPELL_AURA_MOD_CHARM, m_caster->GetGUID());
3837 }
3838
3839 if (Player* playerCaster = m_caster->ToPlayer())
3840 {
3841 // now that we've done the basic check, now run the scripts
3842 // should be done before the spell is actually executed
3843 sScriptMgr->OnPlayerSpellCast(playerCaster, this, skipCheck);
3844
3845 // As of 3.0.2 pets begin attacking their owner's target immediately
3846 // Let any pets know we've attacked something. Check DmgClass for harmful spells only
3847 // This prevents spells such as Hunter's Mark from triggering pet attack
3848 // xinef: take into account SPELL_ATTR3_SUPPRESS_TARGET_PROCS
3850 if (!playerCaster->m_Controlled.empty())
3851 for (Unit::ControlSet::iterator itr = playerCaster->m_Controlled.begin(); itr != playerCaster->m_Controlled.end(); ++itr)
3852 if (Unit* pet = *itr)
3853 if (pet->IsAlive() && pet->IsCreature())
3854 pet->ToCreature()->AI()->OwnerAttacked(m_targets.GetUnitTarget());
3855 }
3856
3858
3862
3864
3865 Player* modOwner = m_caster->GetSpellModOwner();
3866 // skip check if done already (for instant cast spells for example)
3867 if (!skipCheck)
3868 {
3869 SpellCastResult castResult = CheckCast(false);
3870 if (castResult != SPELL_CAST_OK)
3871 {
3872 SendCastResult(castResult);
3873 SendInterrupted(0);
3874
3875 finish(false);
3876 SetExecutedCurrently(false);
3877 return;
3878 }
3879
3880 // additional check after cast bar completes (must not be in CheckCast)
3881 // if trade not complete then remember it in trade data
3883 {
3884 if (m_caster->IsPlayer())
3885 {
3886 if (TradeData* my_trade = m_caster->ToPlayer()->GetTradeData())
3887 {
3888 if (!my_trade->IsInAcceptProcess())
3889 {
3890 // Spell will be casted at completing the trade. Silently ignore at this place
3891 my_trade->SetSpell(m_spellInfo->Id, m_CastItem);
3893 SendInterrupted(0);
3894
3895 finish(false);
3896 SetExecutedCurrently(false);
3897 return;
3898 }
3899 }
3900 }
3901 }
3902 }
3903
3904 if (modOwner)
3905 modOwner->SetSpellModTakingSpell(this, true);
3906
3909
3910 if (modOwner)
3911 modOwner->SetSpellModTakingSpell(this, false);
3912
3913 // Spell may be finished after target map check
3915 {
3916 SendInterrupted(0);
3917 finish(false);
3918 SetExecutedCurrently(false);
3919 return;
3920 }
3921
3922 if (modOwner)
3923 modOwner->SetSpellModTakingSpell(this, true);
3924
3926
3928
3929 if (modOwner)
3930 modOwner->SetSpellModTakingSpell(this, false);
3931
3932 // traded items have trade slot instead of guid in m_itemTargetGUID
3933 // set to real guid to be sent later to the client
3935
3936 if (m_caster->IsPlayer())
3937 {
3939 {
3942 }
3943
3945 }
3946
3948 {
3949 // Powers have to be taken before SendSpellGo
3950 TakePower();
3951 TakeReagents(); // we must remove reagents before HandleEffects to allow place crafted item in same slot
3952 }
3953 else if (Item* targetItem = m_targets.GetItemTarget())
3954 {
3956 if (targetItem->GetOwnerGUID() != m_caster->GetGUID())
3957 TakeReagents();
3958 }
3959
3961
3962 // CAST SPELL
3963 if (modOwner)
3964 modOwner->SetSpellModTakingSpell(this, true);
3965
3967
3969
3970 // we must send smsg_spell_go packet before m_castItem delete in TakeCastItem()...
3971 SendSpellGo();
3972
3973 if (modOwner)
3974 modOwner->SetSpellModTakingSpell(this, false);
3975
3976 if (m_originalCaster)
3977 {
3978 // Handle procs on cast
3979 uint32 procAttacker = m_procAttacker;
3980 if (!procAttacker)
3981 {
3982 bool IsPositive = m_spellInfo->IsPositive();
3984 {
3986 }
3987 else
3988 {
3990 }
3991 }
3992
3993 uint32 procEx = PROC_EX_NORMAL_HIT;
3994
3995 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
3996 {
3997 if (ihit->missCondition != SPELL_MISS_NONE)
3998 {
3999 continue;
4000 }
4001
4002 if (!ihit->crit)
4003 {
4004 continue;
4005 }
4006
4007 procEx |= PROC_EX_CRITICAL_HIT;
4008 break;
4009 }
4010
4013 }
4014
4015 if (modOwner)
4016 modOwner->SetSpellModTakingSpell(this, true);
4017
4019 if (resetAttackTimers)
4020 {
4022 for (Unit::AuraEffectList::const_iterator i = vIgnoreReset.begin(); i != vIgnoreReset.end(); ++i)
4023 {
4024 if ((*i)->IsAffectedOnSpell(m_spellInfo))
4025 {
4026 resetAttackTimers = false;
4027 break;
4028 }
4029 }
4030 }
4031
4032 // Okay, everything is prepared. Now we need to distinguish between immediate and evented delayed spells
4033 if ((m_spellInfo->Speed > 0.0f && !m_spellInfo->IsChanneled())/* xinef: we dont need this || m_spellInfo->Id == 14157*/)
4034 {
4035 // Remove used for cast item if need (it can be already nullptr after TakeReagents call
4036 // in case delayed spell remove item at cast delay start
4037 TakeCastItem();
4038
4039 // Okay, maps created, now prepare flags
4040 m_immediateHandled = false;
4042 SetDelayStart(0);
4043
4046
4047 // remove all applied mods at this point
4048 // dont allow user to use them twice in case spell did not reach current target
4049 if (modOwner)
4050 modOwner->RemoveSpellMods(this);
4051
4052 // Xinef: why do we keep focus after spell is sent to air?
4053 // Xinef: Because of this, in the middle of some animation after setting targetguid to 0 etc
4054 // Xinef: we get focused to it out of nowhere...
4055 if (Creature* creatureCaster = m_caster->ToCreature())
4056 creatureCaster->ReleaseFocus(this);
4057 }
4058 else
4059 {
4060 // Immediate spell, no big deal
4062 }
4063
4064 if (resetAttackTimers)
4065 {
4066 if (m_casttime == 0 && m_spellInfo->CalcCastTime())
4067 {
4068 resetAttackTimers = false;
4069 }
4070
4071 if (resetAttackTimers)
4072 {
4074
4076 {
4078 }
4079
4081 }
4082 }
4083
4085
4086 if (modOwner)
4087 modOwner->SetSpellModTakingSpell(this, false);
4088
4089 if (std::vector<int32> const* spell_triggered = sSpellMgr->GetSpellLinked(m_spellInfo->Id))
4090 {
4091 for (int32 id : *spell_triggered)
4092 {
4093 if (id < 0)
4095 else
4097 }
4098 }
4099
4100 // Interrupt Spell casting
4101 // handle this here, in other places SpellHitTarget can be set to nullptr, if there is an error in this function
4103 if (Unit* target = m_targets.GetUnitTarget())
4104 if (target->IsCreature())
4105 m_caster->CastSpell(target, 32747, true);
4106
4107 // xinef: start combat at cast for delayed spells, only for explicit target
4108 if (Unit* target = m_targets.GetUnitTarget())
4111 m_caster->CombatStartOnCast(target, !m_spellInfo->HasAttribute(SPELL_ATTR3_SUPPRESS_TARGET_PROCS), GetDelayMoment() + 500); // xinef: increase this time so we dont leave and enter combat in a moment
4112
4113 if (m_caster->IsPlayer())
4116
4117 SetExecutedCurrently(false);
4118}
std::int32_t int32
Definition: Define.h:103
@ ACHIEVEMENT_TIMED_TYPE_ITEM
Definition: DBCEnums.h:115
@ ACHIEVEMENT_CRITERIA_TYPE_USE_ITEM
Definition: DBCEnums.h:155
@ ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL
Definition: DBCEnums.h:143
@ SPELL_ATTR7_CAN_CAUSE_INTERRUPT
Definition: SharedDefines.h:652
@ SPELL_EFFECT_SUMMON_PET
Definition: SharedDefines.h:834
@ SPELL_ATTR2_DO_NOT_RESET_COMBAT_TIMERS
Definition: SharedDefines.h:473
@ SPELL_ATTR1_DISMISS_PET_FIRST
Definition: SharedDefines.h:419
@ SPELL_ATTR3_SUPPRESS_TARGET_PROCS
Definition: SharedDefines.h:510
@ SPELL_DAMAGE_CLASS_NONE
Definition: SharedDefines.h:1545
@ SPELL_MISS_NONE
Definition: SharedDefines.h:1519
SpellCastResult
Definition: SharedDefines.h:948
@ SPELL_FAILED_DONT_REPORT
Definition: SharedDefines.h:976
@ SPELL_CAST_OK
Definition: SharedDefines.h:1138
@ TARGET_FLAG_TRADE_ITEM
Definition: SpellInfo.h:58
@ TARGET_FLAG_UNIT
Definition: SpellInfo.h:47
@ SPELL_STATE_DELAYED
Definition: Spell.h:231
@ SPELL_STATE_FINISHED
Definition: Spell.h:229
@ TRIGGERED_IGNORE_POWER_AND_REAGENT_COST
Will ignore Spell and Category cooldowns.
Definition: SpellDefines.h:136
@ TRIGGERED_IGNORE_CAST_ITEM
Will ignore power and reagent cost.
Definition: SpellDefines.h:137
@ TRIGGERED_IGNORE_SET_FACING
Will ignore interruptible aura's at cast.
Definition: SpellDefines.h:143
@ SPELL_AURA_MOD_CHARM
Definition: SpellAuraDefines.h:69
@ SPELL_AURA_IGNORE_MELEE_RESET
Definition: SpellAuraDefines.h:335
@ SPELL_AURA_BIND_SIGHT
Definition: SpellAuraDefines.h:64
@ PROC_EX_CRITICAL_HIT
Definition: SpellMgr.h:195
@ PROC_EX_NORMAL_HIT
Definition: SpellMgr.h:194
@ PROC_SPELL_PHASE_CAST
Definition: SpellMgr.h:243
@ PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_POS
Definition: SpellMgr.h:128
@ PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_POS
Definition: SpellMgr.h:122
@ PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_NEG
Definition: SpellMgr.h:125
@ PROC_FLAG_NONE
Definition: SpellMgr.h:105
@ PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG
Definition: SpellMgr.h:131
@ CHEAT_COOLDOWN
Definition: Player.h:1006
@ UNIT_STATE_CASTING
Definition: UnitDefines.h:164
@ PET_SAVE_AS_CURRENT
Definition: PetDefines.h:42
#define sScriptMgr
Definition: ScriptMgr.h:709
Definition: Creature.h:43
uint32 GetEntry() const
Definition: Object.h:115
bool IsCreature() const
Definition: Object.h:204
Creature * ToCreature()
Definition: Object.h:205
Definition: Pet.h:41
Definition: Player.h:1081
void UpdateAchievementCriteria(AchievementCriteriaTypes type, uint32 miscValue1=0, uint32 miscValue2=0, Unit *unit=nullptr)
Definition: PlayerUpdates.cpp:2131
void SetSpellModTakingSpell(Spell *spell, bool apply)
Definition: Player.cpp:10109
void StartTimedAchievement(AchievementCriteriaTimedTypes type, uint32 entry, uint32 timeLost=0)
Definition: Player.cpp:13956
void RemoveSpellMods(Spell *spell)
Definition: Player.cpp:10041
Pet * GetPet() const
Definition: Player.cpp:8939
bool GetCommandStatus(uint32 command) const
Definition: Player.h:1195
void RemovePet(Pet *pet, PetSaveMode mode, bool returnreagent=false)
Definition: Player.cpp:9089
TradeData * GetTradeData() const
Definition: Player.h:1387
void RemoveSpellCooldown(uint32 spell_id, bool update=false)
Definition: Player.cpp:3536
Definition: TradeData.h:36
Definition: Unit.h:630
bool HasOffhandWeaponForAttack() const
Definition: Unit.h:934
void ClearUnitState(uint32 f)
Definition: Unit.h:702
AuraEffectList const & GetAuraEffectsByType(AuraType type) const
Definition: Unit.h:1349
Unit * GetCharm() const
Definition: Unit.cpp:10671
Player * GetSpellModOwner() const
Definition: Unit.cpp:16577
void CombatStartOnCast(Unit *target, bool initialAggro=true, uint32 duration=0)
Definition: Unit.cpp:13705
bool IsPet() const
Definition: Unit.h:754
bool IsNonMeleeSpellCast(bool withDelayed, bool skipChanneled=false, bool skipAutorepeat=false, bool isAutoshoot=false, bool skipInstant=true) const
Definition: Unit.cpp:4099
SpellCastResult CastSpell(SpellCastTargets const &targets, SpellInfo const *spellInfo, CustomSpellValues const *value, TriggerCastFlags triggerFlags=TRIGGERED_NONE, Item *castItem=nullptr, AuraEffect const *triggeredByAura=nullptr, ObjectGuid originalCaster=ObjectGuid::Empty)
Definition: Unit.cpp:1167
void RemoveAurasDueToSpell(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, uint8 reqEffMask=0, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition: Unit.cpp:4909
static void ProcDamageAndSpell(Unit *actor, Unit *victim, uint32 procAttacker, uint32 procVictim, uint32 procEx, uint32 amount, WeaponAttackType attType=BASE_ATTACK, SpellInfo const *procSpellInfo=nullptr, SpellInfo const *procAura=nullptr, int8 procAuraEffectIndex=-1, Spell const *procSpell=nullptr, DamageInfo *damageInfo=nullptr, HealInfo *healInfo=nullptr, uint32 procPhase=2)
Definition: Unit.cpp:6378
bool HasUnitState(const uint32 f) const
Definition: Unit.h:701
bool IsFriendlyTo(Unit const *unit) const
Definition: Unit.cpp:10241
bool IsControlledByPlayer() const
Definition: Unit.h:1232
std::list< AuraEffect * > AuraEffectList
Definition: Unit.h:646
void SetInFront(WorldObject const *target)
Definition: Unit.cpp:20521
void resetAttackTimer(WeaponAttackType type=BASE_ATTACK)
Definition: Unit.cpp:642
WorldObject * GetObjectTarget() const
Definition: Spell.cpp:311
void UpdateTradeSlotItem()
Definition: Spell.cpp:348
ObjectGuid GetObjectTargetGUID() const
Definition: Spell.cpp:316
Item * GetItemTarget() const
Definition: Spell.h:141
uint32 GetTargetMask() const
Definition: Spell.h:119
Unit * GetUnitTarget() const
Definition: Spell.cpp:232
int8 effectIndex
Definition: Spell.h:282
SpellInfo const * spellInfo
Definition: Spell.h:281
SpellInfo const * GetSpellInfo() const
Definition: Spell.h:579
void CallScriptAfterCastHandlers()
Definition: Spell.cpp:8558
void PrepareTriggersExecutedOnHit()
Definition: Spell.cpp:8764
bool HasTriggeredCastFlag(TriggerCastFlags flag) const
Definition: Spell.h:557
SpellCastTargets m_targets
Definition: Spell.h:530
TriggeredByAuraSpellData m_triggeredByAuraSpell
Definition: Spell.h:776
void handle_immediate()
Definition: Spell.cpp:4120
void SendSpellGo()
Definition: Spell.cpp:4802
void TakeReagents()
Definition: Spell.cpp:5536
void SetExecutedCurrently(bool yes)
Definition: Spell.h:565
void SendInterrupted(uint8 result)
Definition: Spell.cpp:5179
void PrepareScriptHitHandlers()
Definition: Spell.cpp:8590
void CallScriptOnCastHandlers()
Definition: Spell.cpp:8545
void cancel(bool bySelf=false)
Definition: Spell.cpp:3723
void SendSpellCooldown()
Definition: Spell.cpp:4360
void CallScriptBeforeCastHandlers()
Definition: Spell.cpp:8532
void HandleLaunchPhase()
Definition: Spell.cpp:8236
bool UpdatePointers()
Definition: Spell.cpp:7866
void SetDelayStart(uint64 m_time)
Definition: Spell.h:567
std::list< TargetInfo > m_UniqueTargetInfo
Definition: Spell.h:686
void SelectSpellTargets()
Definition: Spell.cpp:819
void TakePower()
Definition: Spell.cpp:5320
SpellCastResult CheckCast(bool strict)
Definition: Spell.cpp:5658
static void SendCastResult(Player *caster, SpellInfo const *spellInfo, uint8 castCount, SpellCastResult result, SpellCustomErrors customError=SPELL_CUSTOM_ERROR_NONE)
Definition: Spell.cpp:4674
uint64 GetDelayMoment() const
Definition: Spell.h:568
void TakeCastItem()
Definition: Spell.cpp:5257
bool IsAutoActionResetSpell() const
Definition: Spell.cpp:8080
void finish(bool ok=true)
Definition: Spell.cpp:4487
float Speed
Definition: SpellInfo.h:370
bool IsChanneled() const
Definition: SpellInfo.cpp:1256
uint32 CalcCastTime(Unit *caster=nullptr, Spell *spell=nullptr) const
Definition: SpellInfo.cpp:2352
bool HasAura(AuraType aura) const
Definition: SpellInfo.cpp:893

References _spellTargetsSelected, ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL, ACHIEVEMENT_CRITERIA_TYPE_USE_ITEM, ACHIEVEMENT_TIMED_TYPE_ITEM, BASE_ATTACK, SpellInfo::CalcCastTime(), CallScriptAfterCastHandlers(), CallScriptBeforeCastHandlers(), CallScriptOnCastHandlers(), cancel(), Unit::CastSpell(), CHEAT_COOLDOWN, CheckCast(), Unit::ClearUnitState(), Unit::CombatStartOnCast(), SpellInfo::DmgClass, TriggeredByAuraSpellData::effectIndex, finish(), Unit::GetAuraEffectsByType(), Unit::GetCharm(), Player::GetCommandStatus(), GetDelayMoment(), Object::GetEntry(), Object::GetGUID(), SpellCastTargets::GetItemTarget(), SpellCastTargets::GetObjectTarget(), SpellCastTargets::GetObjectTargetGUID(), Player::GetPet(), GetSpellInfo(), Unit::GetSpellModOwner(), SpellCastTargets::GetTargetMask(), Player::GetTradeData(), SpellCastTargets::GetUnitTarget(), handle_immediate(), HandleLaunchPhase(), SpellInfo::HasAttribute(), SpellInfo::HasAura(), SpellInfo::HasEffect(), Unit::HasOffhandWeaponForAttack(), HasTriggeredCastFlag(), Unit::HasUnitState(), SpellInfo::Id, IsAutoActionResetSpell(), SpellInfo::IsChanneled(), Unit::IsControlledByPlayer(), Object::IsCreature(), Unit::IsFriendlyTo(), Unit::IsNonMeleeSpellCast(), Unit::IsPet(), Object::IsPlayer(), SpellInfo::IsPositive(), m_caster, m_CastItem, m_casttime, m_immediateHandled, m_originalCaster, m_procAttacker, m_spellInfo, m_spellState, m_targets, m_triggeredByAuraSpell, m_UniqueTargetInfo, OFF_ATTACK, PET_SAVE_AS_CURRENT, PrepareScriptHitHandlers(), PrepareTriggersExecutedOnHit(), PROC_EX_CRITICAL_HIT, PROC_EX_NORMAL_HIT, PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG, PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_POS, PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_NEG, PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_POS, PROC_FLAG_NONE, PROC_SPELL_PHASE_CAST, Unit::ProcDamageAndSpell(), RANGED_ATTACK, Unit::RemoveAurasDueToSpell(), Player::RemovePet(), Player::RemoveSpellCooldown(), Player::RemoveSpellMods(), Unit::resetAttackTimer(), SelectSpellTargets(), SendCastResult(), SendInterrupted(), SendSpellCooldown(), SendSpellGo(), SetDelayStart(), SetExecutedCurrently(), Unit::SetInFront(), Player::SetSpellModTakingSpell(), SpellInfo::Speed, SPELL_ATTR1_DISMISS_PET_FIRST, SPELL_ATTR2_DO_NOT_RESET_COMBAT_TIMERS, SPELL_ATTR3_SUPPRESS_TARGET_PROCS, SPELL_ATTR7_CAN_CAUSE_INTERRUPT, SPELL_AURA_BIND_SIGHT, SPELL_AURA_IGNORE_MELEE_RESET, SPELL_AURA_MOD_CHARM, SPELL_CAST_OK, SPELL_DAMAGE_CLASS_MAGIC, SPELL_DAMAGE_CLASS_NONE, SPELL_EFFECT_DISPEL, SPELL_EFFECT_SUMMON_PET, SPELL_FAILED_DONT_REPORT, SPELL_MISS_NONE, SPELL_STATE_DELAYED, SPELL_STATE_FINISHED, TriggeredByAuraSpellData::spellInfo, sScriptMgr, sSpellMgr, Player::StartTimedAchievement(), TakeCastItem(), TakePower(), TakeReagents(), TARGET_FLAG_TRADE_ITEM, TARGET_FLAG_UNIT, Object::ToCreature(), Object::ToPlayer(), TRIGGERED_IGNORE_CAST_ITEM, TRIGGERED_IGNORE_POWER_AND_REAGENT_COST, TRIGGERED_IGNORE_SET_FACING, UNIT_STATE_CASTING, Player::UpdateAchievementCriteria(), UpdatePointers(), and SpellCastTargets::UpdateTradeSlotItem().

Referenced by cast().

◆ _handle_finish_phase()

void Spell::_handle_finish_phase ( )
4286{
4287 // Take for real after all targets are processed
4289 {
4291 }
4292
4293 // Real add combo points from effects
4295 {
4296 // remove Premed-like effects unless they were caused by ourselves
4297 // (this Aura removes the already-added CP when it expires from duration - now that we've added CP, this shouldn't happen anymore!)
4299 {
4301 }
4302
4304 }
4305
4307 {
4309 }
4310
4313 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
4314 {
4315 // Xinef: Properly clear infinite cooldowns in some cases
4316 if (ihit->targetGUID == m_caster->GetGUID() && ihit->missCondition != SPELL_MISS_NONE)
4319 }
4320
4321 // Handle procs on finish
4322 if (m_originalCaster)
4323 {
4324 uint32 procAttacker = m_procAttacker;
4325 if (!procAttacker)
4326 {
4327 bool IsPositive = m_spellInfo->IsPositive();
4329 {
4331 }
4332 else
4333 {
4335 }
4336 }
4337
4338 uint32 procEx = PROC_EX_NORMAL_HIT;
4339 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
4340 {
4341 if (ihit->missCondition != SPELL_MISS_NONE)
4342 {
4343 continue;
4344 }
4345
4346 if (!ihit->crit)
4347 {
4348 continue;
4349 }
4350
4351 procEx |= PROC_EX_CRITICAL_HIT;
4352 break;
4353 }
4354
4357 }
4358}
@ SPELL_EFFECT_ADD_EXTRA_ATTACKS
Definition: SharedDefines.h:797
@ SPELL_AURA_RETAIN_COMBO_POINTS
Definition: SpellAuraDefines.h:211
@ PROC_SPELL_PHASE_FINISH
Definition: SpellMgr.h:245
void SendCooldownEvent(SpellInfo const *spellInfo, uint32 itemId=0, Spell *spell=nullptr, bool setCooldown=true)
Definition: Player.cpp:11140
void SetLastExtraAttackSpell(uint32 spellId)
Definition: Unit.h:953
Player * GetCharmerOrOwnerPlayerOrPlayerItself() const
Definition: Unit.cpp:10616
void ClearComboPoints()
Definition: Unit.cpp:16864
void AddComboPoints(Unit *target, int8 count)
Definition: Unit.cpp:16838
void RemoveAurasByType(AuraType auraType, ObjectGuid casterGUID=ObjectGuid::Empty, Aura *except=nullptr, bool negative=true, bool positive=true)
Definition: Unit.cpp:5110
bool IsAutoRepeat() const
Definition: Spell.h:551
bool IsNextMeleeSwingSpell() const
Definition: Spell.cpp:8070
bool IsCooldownStartedOnEvent() const
Definition: SpellInfo.cpp:1212

References Unit::AddComboPoints(), BASE_ATTACK, Unit::ClearComboPoints(), SpellInfo::DmgClass, TriggeredByAuraSpellData::effectIndex, Unit::GetCharmerOrOwnerPlayerOrPlayerItself(), Object::GetGUID(), SpellInfo::HasAura(), SpellInfo::HasEffect(), SpellInfo::Id, IsAutoRepeat(), SpellInfo::IsCooldownStartedOnEvent(), IsNextMeleeSwingSpell(), Object::IsPlayer(), SpellInfo::IsPositive(), m_caster, m_comboPointGain, m_comboTarget, m_needComboPoints, m_originalCaster, m_procAttacker, m_spellInfo, m_triggeredByAuraSpell, m_UniqueTargetInfo, PROC_EX_CRITICAL_HIT, PROC_EX_NORMAL_HIT, PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG, PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_POS, PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_NEG, PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_POS, PROC_FLAG_NONE, PROC_SPELL_PHASE_FINISH, Unit::ProcDamageAndSpell(), Unit::RemoveAurasByType(), Player::SendCooldownEvent(), Unit::SetLastExtraAttackSpell(), SPELL_AURA_RETAIN_COMBO_POINTS, SPELL_DAMAGE_CLASS_MAGIC, SPELL_EFFECT_ADD_EXTRA_ATTACKS, SPELL_MISS_NONE, TriggeredByAuraSpellData::spellInfo, and Object::ToPlayer().

Referenced by handle_delayed(), and handle_immediate().

◆ _handle_immediate_phase()

void Spell::_handle_immediate_phase ( )
4258{
4259 m_spellAura = nullptr;
4260 // initialize Diminishing Returns Data
4263
4264 // handle some immediate features of the spell here
4266
4268
4269 // handle effects with SPELL_EFFECT_HANDLE_HIT mode
4270 for (uint32 j = 0; j < MAX_SPELL_EFFECTS; ++j)
4271 {
4272 // don't do anything for empty effect
4273 if (!m_spellInfo->Effects[j].IsEffect())
4274 continue;
4275
4276 // call effect handlers to handle destination hit
4277 HandleEffects(nullptr, nullptr, nullptr, j, SPELL_EFFECT_HANDLE_HIT);
4278 }
4279
4280 // process items
4281 for (std::list<ItemTargetInfo>::iterator ihit = m_UniqueItemInfo.begin(); ihit != m_UniqueItemInfo.end(); ++ihit)
4282 DoAllEffectOnTarget(&(*ihit));
4283}
@ SPELL_EFFECT_HANDLE_HIT
Definition: Spell.h:238
void HandleThreatSpells()
Definition: Spell.cpp:5585
void HandleEffects(Unit *pUnitTarget, Item *pItemTarget, GameObject *pGOTarget, uint32 i, SpellEffectHandleMode mode)
Definition: Spell.cpp:5632
std::list< ItemTargetInfo > m_UniqueItemInfo
Definition: Spell.h:703
void DoAllEffectOnTarget(TargetInfo *target)
Definition: Spell.cpp:2613
std::array< SpellEffectInfo, MAX_SPELL_EFFECTS > Effects
Definition: SpellInfo.h:393

References DIMINISHING_LEVEL_1, DIMINISHING_NONE, DoAllEffectOnTarget(), SpellInfo::Effects, HandleEffects(), HandleThreatSpells(), m_diminishGroup, m_diminishLevel, m_spellAura, m_spellInfo, m_UniqueItemInfo, MAX_SPELL_EFFECTS, PrepareScriptHitHandlers(), and SPELL_EFFECT_HANDLE_HIT.

Referenced by handle_delayed(), and handle_immediate().

◆ AddComboPointGain()

void Spell::AddComboPointGain ( Unit target,
int8  amount 
)
inline
534 {
535 if (target != m_comboTarget)
536 {
537 m_comboTarget = target;
538 m_comboPointGain = amount;
539 }
540 else
541 {
542 m_comboPointGain += amount;
543 }
544 }

References m_comboPointGain, and m_comboTarget.

Referenced by EffectAddComboPoints(), and EffectWeaponDmg().

◆ AddDestTarget()

void Spell::AddDestTarget ( SpellDestination const &  dest,
uint32  effIndex 
)
protected
2609{
2610 m_destTargets[effIndex] = dest;
2611}

References m_destTargets.

Referenced by SelectSpellTargets().

◆ AddGOTarget()

void Spell::AddGOTarget ( GameObject target,
uint32  effectMask 
)
protected
2518{
2519 for (uint32 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
2520 {
2521 if (!m_spellInfo->Effects[effIndex].IsEffect())
2522 effectMask &= ~(1 << effIndex);
2523 else
2524 {
2525 switch (m_spellInfo->Effects[effIndex].Effect)
2526 {
2530 if (go->GetGoType() != GAMEOBJECT_TYPE_DESTRUCTIBLE_BUILDING)
2531 effectMask &= ~(1 << effIndex);
2532 break;
2533 default:
2534 break;
2535 }
2536 }
2537 }
2538
2539 if (!effectMask)
2540 return;
2541
2542 ObjectGuid targetGUID = go->GetGUID();
2543
2544 // Lookup target in already in list
2545 for (std::list<GOTargetInfo>::iterator ihit = m_UniqueGOTargetInfo.begin(); ihit != m_UniqueGOTargetInfo.end(); ++ihit)
2546 {
2547 if (targetGUID == ihit->targetGUID) // Found in list
2548 {
2549 ihit->effectMask |= effectMask; // Add only effect mask
2550 return;
2551 }
2552 }
2553
2554 // This is new target calculate data for him
2555
2556 GOTargetInfo target;
2557 target.targetGUID = targetGUID;
2558 target.effectMask = effectMask;
2559 target.processed = false; // Effects not apply on target
2560
2561 // Spell have speed - need calculate incoming time
2562 if (m_spellInfo->Speed > 0.0f)
2563 {
2564 // calculate spell incoming interval
2565 float dist = m_caster->GetDistance(go->GetPositionX(), go->GetPositionY(), go->GetPositionZ());
2566 if (dist < 5.0f)
2567 dist = 5.0f;
2568 target.timeDelay = uint64(std::floor(dist / m_spellInfo->Speed * 1000.0f));
2569 if (m_delayMoment == 0 || m_delayMoment > target.timeDelay)
2570 m_delayMoment = target.timeDelay;
2571 }
2572 else
2573 target.timeDelay = 0LL;
2574
2575 // Add target to list
2576 m_UniqueGOTargetInfo.push_back(target);
2577}
std::uint64_t uint64
Definition: Define.h:106
@ GAMEOBJECT_TYPE_DESTRUCTIBLE_BUILDING
Definition: SharedDefines.h:1593
@ SPELL_EFFECT_GAMEOBJECT_REPAIR
Definition: SharedDefines.h:866
@ SPELL_EFFECT_GAMEOBJECT_SET_DESTRUCTION_STATE
Definition: SharedDefines.h:867
@ SPELL_EFFECT_GAMEOBJECT_DAMAGE
Definition: SharedDefines.h:865
float GetDistance(WorldObject const *obj) const
Definition: Object.cpp:1256
Definition: ObjectGuid.h:118
uint64 m_delayMoment
Definition: Spell.h:643
std::list< GOTargetInfo > m_UniqueGOTargetInfo
Definition: Spell.h:696

References Spell::GOTargetInfo::effectMask, SpellInfo::Effects, GAMEOBJECT_TYPE_DESTRUCTIBLE_BUILDING, WorldObject::GetDistance(), GameObject::GetGoType(), Object::GetGUID(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), m_caster, m_delayMoment, m_spellInfo, m_UniqueGOTargetInfo, MAX_SPELL_EFFECTS, Spell::GOTargetInfo::processed, SpellInfo::Speed, SPELL_EFFECT_GAMEOBJECT_DAMAGE, SPELL_EFFECT_GAMEOBJECT_REPAIR, SPELL_EFFECT_GAMEOBJECT_SET_DESTRUCTION_STATE, Spell::GOTargetInfo::targetGUID, and Spell::GOTargetInfo::timeDelay.

Referenced by SelectEffectTypeImplicitTargets(), SelectImplicitAreaTargets(), SelectImplicitConeTargets(), SelectImplicitNearbyTargets(), and SelectImplicitTargetObjectTargets().

◆ AddItemTarget()

void Spell::AddItemTarget ( Item item,
uint32  effectMask 
)
protected
2580{
2581 for (uint32 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
2582 if (!m_spellInfo->Effects[effIndex].IsEffect())
2583 effectMask &= ~(1 << effIndex);
2584
2585 // no effects left
2586 if (!effectMask)
2587 return;
2588
2589 // Lookup target in already in list
2590 for (std::list<ItemTargetInfo>::iterator ihit = m_UniqueItemInfo.begin(); ihit != m_UniqueItemInfo.end(); ++ihit)
2591 {
2592 if (item == ihit->item) // Found in list
2593 {
2594 ihit->effectMask |= effectMask; // Add only effect mask
2595 return;
2596 }
2597 }
2598
2599 // This is new target add data
2600
2601 ItemTargetInfo target;
2602 target.item = item;
2603 target.effectMask = effectMask;
2604
2605 m_UniqueItemInfo.push_back(target);
2606}

References Spell::ItemTargetInfo::effectMask, SpellInfo::Effects, Spell::ItemTargetInfo::item, m_spellInfo, m_UniqueItemInfo, and MAX_SPELL_EFFECTS.

Referenced by SelectEffectTypeImplicitTargets(), and SelectImplicitTargetObjectTargets().

◆ AddUnitTarget()

void Spell::AddUnitTarget ( Unit target,
uint32  effectMask,
bool  checkIfValid = true,
bool  implicit = true 
)
protected
Todo:
: this is a hack
Todo:
: seduction should be casted only on humanoids (not demons)
2385{
2386 for (uint32 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
2387 if (!m_spellInfo->Effects[effIndex].IsEffect() || !CheckEffectTarget(target, effIndex))
2388 effectMask &= ~(1 << effIndex);
2389
2390 // no effects left
2391 if (!effectMask)
2392 return;
2393
2394 if (checkIfValid)
2395 {
2396 SpellCastResult res = m_spellInfo->CheckTarget(m_caster, target, implicit);
2397 if (res != SPELL_CAST_OK)
2398 return;
2399 }
2400
2401 // Check for effect immune skip if immuned
2402 for (uint32 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
2403 if (target->IsImmunedToSpellEffect(m_spellInfo, effIndex))
2404 effectMask &= ~(1 << effIndex);
2405
2406 ObjectGuid targetGUID = target->GetGUID();
2407
2408 // Lookup target in already in list
2409 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
2410 {
2411 if (targetGUID == ihit->targetGUID) // Found in list
2412 {
2413 ihit->effectMask |= effectMask; // Immune effects removed from mask
2414 ihit->scaleAura = false;
2415 if (m_auraScaleMask && ihit->effectMask == m_auraScaleMask && m_caster != target)
2416 {
2417 SpellInfo const* auraSpell = m_spellInfo->GetFirstRankSpell();
2418 if (uint32(target->GetLevel() + 10) >= auraSpell->SpellLevel)
2419 ihit->scaleAura = true;
2420 }
2421
2422 sScriptMgr->OnScaleAuraUnitAdd(this, target, effectMask, checkIfValid, implicit, m_auraScaleMask, *ihit);
2423 return;
2424 }
2425 }
2426
2427 // This is new target calculate data for him
2428
2429 // Get spell hit result on target
2430 TargetInfo targetInfo;
2431 targetInfo.targetGUID = targetGUID; // Store target GUID
2432 targetInfo.effectMask = effectMask; // Store all effects not immune
2433 targetInfo.processed = false; // Effects not apply on target
2434 targetInfo.alive = target->IsAlive();
2435 targetInfo.damage = 0;
2436 targetInfo.crit = false;
2437 targetInfo.scaleAura = false;
2438 if (m_auraScaleMask && targetInfo.effectMask == m_auraScaleMask && m_caster != target)
2439 {
2440 SpellInfo const* auraSpell = m_spellInfo->GetFirstRankSpell();
2441 if (uint32(target->GetLevel() + 10) >= auraSpell->SpellLevel)
2442 targetInfo.scaleAura = true;
2443 }
2444
2445 sScriptMgr->OnScaleAuraUnitAdd(this, target, effectMask, checkIfValid, implicit, m_auraScaleMask, targetInfo);
2446
2447 // Calculate hit result
2448 if (m_originalCaster)
2449 {
2450 targetInfo.missCondition = m_originalCaster->SpellHitResult(target, this, m_canReflect);
2451 if (m_skipCheck && targetInfo.missCondition != SPELL_MISS_IMMUNE)
2452 {
2453 targetInfo.missCondition = SPELL_MISS_NONE;
2454 }
2455 }
2456 else
2457 targetInfo.missCondition = SPELL_MISS_EVADE; //SPELL_MISS_NONE;
2458
2459 // Spell have speed - need calculate incoming time
2460 // Incoming time is zero for self casts. At least I think so.
2461 if (m_spellInfo->Speed > 0.0f && m_caster != target)
2462 {
2463 // calculate spell incoming interval
2465 float dist = m_caster->GetDistance(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ());
2466
2467 if (dist < 5.0f)
2468 dist = 5.0f;
2469 targetInfo.timeDelay = (uint64) std::floor(dist / m_spellInfo->Speed * 1000.0f);
2470
2471 // Calculate minimum incoming time
2472 if (m_delayMoment == 0 || m_delayMoment > targetInfo.timeDelay)
2473 m_delayMoment = targetInfo.timeDelay;
2474 }
2475 else
2476 targetInfo.timeDelay = 0LL;
2477
2478 // If target reflect spell back to caster
2479 if (targetInfo.missCondition == SPELL_MISS_REFLECT)
2480 {
2481 // Calculate reflected spell result on caster
2483
2484 if (targetInfo.reflectResult == SPELL_MISS_REFLECT) // Impossible reflect again, so simply deflect spell
2485 targetInfo.reflectResult = SPELL_MISS_PARRY;
2486
2487 // Increase time interval for reflected spells by 1.5
2489 targetInfo.timeDelay += targetInfo.timeDelay >> 1;
2490
2492
2493 // HACK: workaround check for succubus seduction case
2495 if (m_caster->IsPet())
2496 {
2497 CreatureTemplate const* ci = sObjectMgr->GetCreatureTemplate(m_caster->GetEntry());
2498 switch (ci->family)
2499 {
2501 {
2502 if (m_spellInfo->SpellIconID != 694) // Soothing Kiss
2503 cancel();
2504 }
2505 break;
2506 return;
2507 }
2508 }
2509 }
2510 else
2511 targetInfo.reflectResult = SPELL_MISS_NONE;
2512
2513 // Add target to list
2514 m_UniqueTargetInfo.push_back(targetInfo);
2515}
@ CREATURE_FAMILY_SUCCUBUS
Definition: SharedDefines.h:2664
@ SPELL_MISS_PARRY
Definition: SharedDefines.h:1523
@ SPELL_MISS_IMMUNE
Definition: SharedDefines.h:1526
@ SPELL_MISS_EVADE
Definition: SharedDefines.h:1525
@ SPELL_MISS_REFLECT
Definition: SharedDefines.h:1530
#define sObjectMgr
Definition: ObjectMgr.h:1635
@ SPELL_FLAG_REFLECTED
Definition: Spell.h:84
void AddEvent(BasicEvent *Event, uint64 e_time, bool set_addtime=true)
Definition: EventProcessor.h:103
uint64 CalculateTime(uint64 t_offset) const
Definition: EventProcessor.cpp:159
Definition: CreatureData.h:186
uint32 family
Definition: CreatureData.h:217
EventProcessor m_Events
Definition: Object.h:642
float GetPositionZ() const
Definition: Position.h:118
float GetPositionX() const
Definition: Position.h:116
float GetPositionY() const
Definition: Position.h:117
bool IsAlive() const
Definition: Unit.h:1654
SpellMissInfo SpellHitResult(Unit *victim, SpellInfo const *spell, bool canReflect=false)
Definition: Unit.cpp:3470
virtual bool IsImmunedToSpellEffect(SpellInfo const *spellInfo, uint32 index) const
Definition: Unit.cpp:13006
uint8 GetLevel() const
Definition: Unit.h:1024
Definition: Spell.h:257
bool processed
Definition: Spell.h:263
int32 damage
Definition: Spell.h:267
SpellMissInfo missCondition
Definition: Spell.h:260
bool scaleAura
Definition: Spell.h:266
bool crit
Definition: Spell.h:265
uint64 timeDelay
Definition: Spell.h:259
ObjectGuid targetGUID
Definition: Spell.h:258
SpellMissInfo reflectResult
Definition: Spell.h:261
bool alive
Definition: Spell.h:264
uint8 effectMask
Definition: Spell.h:262
bool CheckEffectTarget(Unit const *target, uint32 eff) const
Definition: Spell.cpp:7928
Definition: Spell.h:850
Definition: SpellInfo.h:316
uint32 SpellLevel
Definition: SpellInfo.h:360
SpellInfo const * GetFirstRankSpell() const
Definition: SpellInfo.cpp:2501
uint32 SpellIconID
Definition: SpellInfo.h:380
SpellCastResult CheckTarget(Unit const *caster, WorldObject const *target, bool implicit=true) const
Definition: SpellInfo.cpp:1759

References EventProcessor::AddEvent(), TargetInfo::alive, EventProcessor::CalculateTime(), cancel(), CheckEffectTarget(), SpellInfo::CheckTarget(), CREATURE_FAMILY_SUCCUBUS, TargetInfo::crit, TargetInfo::damage, TargetInfo::effectMask, SpellInfo::Effects, CreatureTemplate::family, WorldObject::GetDistance(), Object::GetEntry(), SpellInfo::GetFirstRankSpell(), Object::GetGUID(), Unit::GetLevel(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), Unit::IsAlive(), Unit::IsImmunedToSpellEffect(), Unit::IsPet(), m_auraScaleMask, m_canReflect, m_caster, m_delayMoment, WorldObject::m_Events, m_originalCaster, m_skipCheck, m_spellFlags, m_spellInfo, m_UniqueTargetInfo, MAX_SPELL_EFFECTS, TargetInfo::missCondition, TargetInfo::processed, TargetInfo::reflectResult, TargetInfo::scaleAura, sObjectMgr, SpellInfo::Speed, SPELL_CAST_OK, SPELL_FLAG_REFLECTED, SPELL_MISS_EVADE, SPELL_MISS_IMMUNE, SPELL_MISS_NONE, SPELL_MISS_PARRY, SPELL_MISS_REFLECT, Unit::SpellHitResult(), SpellInfo::SpellIconID, SpellInfo::SpellLevel, sScriptMgr, TargetInfo::targetGUID, and TargetInfo::timeDelay.

Referenced by SelectEffectTypeImplicitTargets(), SelectImplicitAreaTargets(), SelectImplicitCasterObjectTargets(), SelectImplicitChainTargets(), SelectImplicitChannelTargets(), SelectImplicitConeTargets(), SelectImplicitNearbyTargets(), and SelectImplicitTargetObjectTargets().

◆ CalculateDelayMomentForDst()

uint64 Spell::CalculateDelayMomentForDst ( ) const
900{
901 if (m_targets.HasDst())
902 {
903 if (m_targets.HasTraj())
904 {
905 float speed = m_targets.GetSpeedXY();
906 if (speed > 0.0f)
907 return (uint64)std::floor(m_targets.GetDist2d() / speed * 1000.0f);
908 }
909 else if (m_spellInfo->Speed > 0.0f)
910 {
911 // We should not subtract caster size from dist calculation (fixes execution time desync with animation on client, eg. Malleable Goo cast by PP)
912 float dist = m_caster->GetExactDist(*m_targets.GetDstPos());
913 return (uint64)std::floor(dist / m_spellInfo->Speed * 1000.0f);
914 }
915 }
916
917 return 0;
918}
float GetExactDist(float x, float y, float z) const
Definition: Position.h:177
bool HasTraj() const
Definition: Spell.h:168
bool HasDst() const
Definition: Spell.h:167
float GetSpeedXY() const
Definition: Spell.h:176
float GetDist2d() const
Definition: Spell.h:175
WorldLocation const * GetDstPos() const
Definition: Spell.cpp:401

References SpellCastTargets::GetDist2d(), SpellCastTargets::GetDstPos(), Position::GetExactDist(), SpellCastTargets::GetSpeedXY(), SpellCastTargets::HasDst(), SpellCastTargets::HasTraj(), m_caster, m_spellInfo, m_targets, and SpellInfo::Speed.

Referenced by RecalculateDelayMomentForDst(), and SelectSpellTargets().

◆ CalculateJumpSpeeds()

void Spell::CalculateJumpSpeeds ( uint8  i,
float  dist,
float &  speedxy,
float &  speedz 
)
protected
1154{
1156 if (Creature* creature = m_caster->ToCreature())
1157 runSpeed *= creature->GetCreatureTemplate()->speed_run;
1158
1159 float multiplier = m_spellInfo->Effects[i].ValueMultiplier;
1160 if (multiplier <= 0.0f)
1161 multiplier = 1.0f;
1162
1163 speedXY = std::min(runSpeed * 3.0f * multiplier, std::max(28.0f, m_caster->GetSpeed(MOVE_RUN) * 4.0f));
1164
1165 float duration = dist / speedXY;
1166 float durationSqr = duration * duration;
1167 float minHeight = m_spellInfo->Effects[i].MiscValue ? m_spellInfo->Effects[i].MiscValue / 10.0f : 0.5f; // Lower bound is blizzlike
1168 float maxHeight = m_spellInfo->Effects[i].MiscValueB ? m_spellInfo->Effects[i].MiscValueB / 10.0f : 1000.0f; // Upper bound is unknown
1169 float height;
1170 if (durationSqr < minHeight * 8 / Movement::gravity)
1171 height = minHeight;
1172 else if (durationSqr > maxHeight * 8 / Movement::gravity)
1173 height = maxHeight;
1174 else
1175 height = Movement::gravity * durationSqr / 8;
1176
1177 speedZ = std::sqrt(2 * Movement::gravity * height);
1178}
float baseMoveSpeed[MAX_MOVE_TYPE]
Definition: Unit.cpp:73
float playerBaseMoveSpeed[MAX_MOVE_TYPE]
Definition: Unit.cpp:86
@ MOVE_RUN
Definition: UnitDefines.h:329
double gravity
Definition: MovementUtil.cpp:24
float GetSpeed(UnitMoveType mtype) const
Definition: Unit.cpp:14424

References baseMoveSpeed, SpellInfo::Effects, Unit::GetSpeed(), Movement::gravity, Unit::IsControlledByPlayer(), m_caster, m_spellInfo, MOVE_RUN, playerBaseMoveSpeed, and Object::ToCreature().

Referenced by EffectJump(), and EffectJumpDest().

◆ CalculateSpellDamage()

int32 Spell::CalculateSpellDamage ( uint8  i,
Unit const *  target 
) const
inline
int32 CalculateSpellDamage(Unit const *target, SpellInfo const *spellProto, uint8 effect_index, int32 const *basePoints=nullptr) const
Definition: Unit.cpp:14851
int32 EffectBasePoints[MAX_SPELL_EFFECTS]
Definition: Spell.h:215

References Unit::CalculateSpellDamage(), SpellValue::EffectBasePoints, m_caster, m_spellInfo, and m_spellValue.

Referenced by CheckCast(), CheckEffectTarget(), EffectWeaponDmg(), and HandleEffects().

◆ CallScriptAfterCastHandlers()

void Spell::CallScriptAfterCastHandlers ( )
protected
8559{
8560 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8561 {
8562 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_AFTER_CAST);
8563 std::list<SpellScript::CastHandler>::iterator hookItrEnd = (*scritr)->AfterCast.end(), hookItr = (*scritr)->AfterCast.begin();
8564 for (; hookItr != hookItrEnd; ++hookItr)
8565 (*hookItr).Call(*scritr);
8566
8567 (*scritr)->_FinishScriptCall();
8568 }
8569}
@ SPELL_SCRIPT_HOOK_AFTER_CAST
Definition: SpellScript.h:172

References m_loadedScripts, and SPELL_SCRIPT_HOOK_AFTER_CAST.

Referenced by _cast().

◆ CallScriptAfterHitHandlers()

void Spell::CallScriptAfterHitHandlers ( )
protected
8671{
8672 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8673 {
8674 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_AFTER_HIT);
8675 std::list<SpellScript::HitHandler>::iterator hookItrEnd = (*scritr)->AfterHit.end(), hookItr = (*scritr)->AfterHit.begin();
8676 for (; hookItr != hookItrEnd; ++hookItr)
8677 (*hookItr).Call(*scritr);
8678
8679 (*scritr)->_FinishScriptCall();
8680 }
8681}
@ SPELL_SCRIPT_HOOK_AFTER_HIT
Definition: SpellScript.h:165

References m_loadedScripts, and SPELL_SCRIPT_HOOK_AFTER_HIT.

Referenced by DoAllEffectOnTarget().

◆ CallScriptBeforeCastHandlers()

void Spell::CallScriptBeforeCastHandlers ( )
protected
8533{
8534 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8535 {
8536 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_BEFORE_CAST);
8537 std::list<SpellScript::CastHandler>::iterator hookItrEnd = (*scritr)->BeforeCast.end(), hookItr = (*scritr)->BeforeCast.begin();
8538 for (; hookItr != hookItrEnd; ++hookItr)
8539 (*hookItr).Call(*scritr);
8540
8541 (*scritr)->_FinishScriptCall();
8542 }
8543}
@ SPELL_SCRIPT_HOOK_BEFORE_CAST
Definition: SpellScript.h:170

References m_loadedScripts, and SPELL_SCRIPT_HOOK_BEFORE_CAST.

Referenced by _cast().

◆ CallScriptBeforeHitHandlers()

void Spell::CallScriptBeforeHitHandlers ( SpellMissInfo  missInfo)
protected
8645{
8646 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8647 {
8648 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_BEFORE_HIT);
8649 std::list<SpellScript::BeforeHitHandler>::iterator hookItrEnd = (*scritr)->BeforeHit.end(), hookItr = (*scritr)->BeforeHit.begin();
8650 for (; hookItr != hookItrEnd; ++hookItr)
8651 (*hookItr).Call(*scritr, missInfo);
8652
8653 (*scritr)->_FinishScriptCall();
8654 }
8655}
@ SPELL_SCRIPT_HOOK_BEFORE_HIT
Definition: SpellScript.h:163

References m_loadedScripts, and SPELL_SCRIPT_HOOK_BEFORE_HIT.

Referenced by DoAllEffectOnTarget().

◆ CallScriptCheckCastHandlers()

SpellCastResult Spell::CallScriptCheckCastHandlers ( )
protected
8572{
8574 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8575 {
8576 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_CHECK_CAST);
8577 std::list<SpellScript::CheckCastHandler>::iterator hookItrEnd = (*scritr)->OnCheckCast.end(), hookItr = (*scritr)->OnCheckCast.begin();
8578 for (; hookItr != hookItrEnd; ++hookItr)
8579 {
8580 SpellCastResult tempResult = (*hookItr).Call(*scritr);
8581 if (retVal == SPELL_CAST_OK)
8582 retVal = tempResult;
8583 }
8584
8585 (*scritr)->_FinishScriptCall();
8586 }
8587 return retVal;
8588}
@ SPELL_SCRIPT_HOOK_CHECK_CAST
Definition: SpellScript.h:169

References m_loadedScripts, SPELL_CAST_OK, and SPELL_SCRIPT_HOOK_CHECK_CAST.

Referenced by CheckCast().

◆ CallScriptDestinationTargetSelectHandlers()

void Spell::CallScriptDestinationTargetSelectHandlers ( SpellDestination target,
SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType 
)
protected
8712{
8713 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8714 {
8715 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_DESTINATION_TARGET_SELECT);
8716 std::list<SpellScript::DestinationTargetSelectHandler>::iterator hookItrEnd = (*scritr)->OnDestinationTargetSelect.end(), hookItr = (*scritr)->OnDestinationTargetSelect.begin();
8717 for (; hookItr != hookItrEnd; ++hookItr)
8718 if (hookItr->IsEffectAffected(m_spellInfo, effIndex) && targetType.GetTarget() == hookItr->GetTarget())
8719 hookItr->Call(*scritr, target);
8720
8721 (*scritr)->_FinishScriptCall();
8722 }
8723}
@ SPELL_SCRIPT_HOOK_DESTINATION_TARGET_SELECT
Definition: SpellScript.h:168

References SpellImplicitTargetInfo::GetTarget(), m_loadedScripts, m_spellInfo, and SPELL_SCRIPT_HOOK_DESTINATION_TARGET_SELECT.

Referenced by SelectImplicitCasterDestTargets(), SelectImplicitDestDestTargets(), SelectImplicitTargetDestTargets(), and SelectImplicitTrajTargets().

◆ CallScriptEffectHandlers()

bool Spell::CallScriptEffectHandlers ( SpellEffIndex  effIndex,
SpellEffectHandleMode  mode 
)
protected
8597{
8598 // execute script effect handler hooks and check if effects was prevented
8599 bool preventDefault = false;
8600 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8601 {
8602 std::list<SpellScript::EffectHandler>::iterator effItr, effEndItr;
8603 SpellScriptHookType hookType;
8604 switch (mode)
8605 {
8607 effItr = (*scritr)->OnEffectLaunch.begin();
8608 effEndItr = (*scritr)->OnEffectLaunch.end();
8610 break;
8612 effItr = (*scritr)->OnEffectLaunchTarget.begin();
8613 effEndItr = (*scritr)->OnEffectLaunchTarget.end();
8615 break;
8617 effItr = (*scritr)->OnEffectHit.begin();
8618 effEndItr = (*scritr)->OnEffectHit.end();
8620 break;
8622 effItr = (*scritr)->OnEffectHitTarget.begin();
8623 effEndItr = (*scritr)->OnEffectHitTarget.end();
8625 break;
8626 default:
8627 ABORT();
8628 return false;
8629 }
8630 (*scritr)->_PrepareScriptCall(hookType);
8631 for (; effItr != effEndItr; ++effItr)
8632 // effect execution can be prevented
8633 if (!(*scritr)->_IsEffectPrevented(effIndex) && (*effItr).IsEffectAffected(m_spellInfo, effIndex))
8634 (*effItr).Call(*scritr, effIndex);
8635
8636 if (!preventDefault)
8637 preventDefault = (*scritr)->_IsDefaultEffectPrevented(effIndex);
8638
8639 (*scritr)->_FinishScriptCall();
8640 }
8641 return preventDefault;
8642}
#define ABORT
Definition: Errors.h:76
@ SPELL_EFFECT_HANDLE_LAUNCH_TARGET
Definition: Spell.h:237
@ SPELL_EFFECT_HANDLE_HIT_TARGET
Definition: Spell.h:239
SpellScriptHookType
Definition: SpellScript.h:158
@ SPELL_SCRIPT_HOOK_EFFECT_HIT
Definition: SpellScript.h:161
@ SPELL_SCRIPT_HOOK_EFFECT_LAUNCH
Definition: SpellScript.h:159
@ SPELL_SCRIPT_HOOK_EFFECT_LAUNCH_TARGET
Definition: SpellScript.h:160
@ SPELL_SCRIPT_HOOK_EFFECT_HIT_TARGET
Definition: SpellScript.h:162

References ABORT, m_loadedScripts, m_spellInfo, SPELL_EFFECT_HANDLE_HIT, SPELL_EFFECT_HANDLE_HIT_TARGET, SPELL_EFFECT_HANDLE_LAUNCH, SPELL_EFFECT_HANDLE_LAUNCH_TARGET, SPELL_SCRIPT_HOOK_EFFECT_HIT, SPELL_SCRIPT_HOOK_EFFECT_HIT_TARGET, SPELL_SCRIPT_HOOK_EFFECT_LAUNCH, and SPELL_SCRIPT_HOOK_EFFECT_LAUNCH_TARGET.

Referenced by HandleEffects().

◆ CallScriptObjectAreaTargetSelectHandlers()

void Spell::CallScriptObjectAreaTargetSelectHandlers ( std::list< WorldObject * > &  targets,
SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType 
)
protected
8684{
8685 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8686 {
8687 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_OBJECT_AREA_TARGET_SELECT);
8688 std::list<SpellScript::ObjectAreaTargetSelectHandler>::iterator hookItrEnd = (*scritr)->OnObjectAreaTargetSelect.end(), hookItr = (*scritr)->OnObjectAreaTargetSelect.begin();
8689 for (; hookItr != hookItrEnd; ++hookItr)
8690 if (hookItr->IsEffectAffected(m_spellInfo, effIndex) && targetType.GetTarget() == hookItr->GetTarget())
8691 hookItr->Call(*scritr, targets);
8692
8693 (*scritr)->_FinishScriptCall();
8694 }
8695}
@ SPELL_SCRIPT_HOOK_OBJECT_AREA_TARGET_SELECT
Definition: SpellScript.h:166

References SpellImplicitTargetInfo::GetTarget(), m_loadedScripts, m_spellInfo, and SPELL_SCRIPT_HOOK_OBJECT_AREA_TARGET_SELECT.

Referenced by SelectImplicitAreaTargets(), SelectImplicitChainTargets(), and SelectImplicitConeTargets().

◆ CallScriptObjectTargetSelectHandlers()

void Spell::CallScriptObjectTargetSelectHandlers ( WorldObject *&  target,
SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType 
)
protected
8698{
8699 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8700 {
8701 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_OBJECT_TARGET_SELECT);
8702 std::list<SpellScript::ObjectTargetSelectHandler>::iterator hookItrEnd = (*scritr)->OnObjectTargetSelect.end(), hookItr = (*scritr)->OnObjectTargetSelect.begin();
8703 for (; hookItr != hookItrEnd; ++hookItr)
8704 if (hookItr->IsEffectAffected(m_spellInfo, effIndex) && targetType.GetTarget() == hookItr->GetTarget())
8705 hookItr->Call(*scritr, target);
8706
8707 (*scritr)->_FinishScriptCall();
8708 }
8709}
@ SPELL_SCRIPT_HOOK_OBJECT_TARGET_SELECT
Definition: SpellScript.h:167

References SpellImplicitTargetInfo::GetTarget(), m_loadedScripts, m_spellInfo, and SPELL_SCRIPT_HOOK_OBJECT_TARGET_SELECT.

Referenced by SelectEffectTypeImplicitTargets(), SelectImplicitCasterObjectTargets(), SelectImplicitChannelTargets(), SelectImplicitNearbyTargets(), and SelectImplicitTargetObjectTargets().

◆ CallScriptOnCastHandlers()

void Spell::CallScriptOnCastHandlers ( )
protected
8546{
8547 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8548 {
8549 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_ON_CAST);
8550 std::list<SpellScript::CastHandler>::iterator hookItrEnd = (*scritr)->OnCast.end(), hookItr = (*scritr)->OnCast.begin();
8551 for (; hookItr != hookItrEnd; ++hookItr)
8552 (*hookItr).Call(*scritr);
8553
8554 (*scritr)->_FinishScriptCall();
8555 }
8556}
@ SPELL_SCRIPT_HOOK_ON_CAST
Definition: SpellScript.h:171

References m_loadedScripts, and SPELL_SCRIPT_HOOK_ON_CAST.

Referenced by _cast().

◆ CallScriptOnHitHandlers()

void Spell::CallScriptOnHitHandlers ( )
protected
8658{
8659 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8660 {
8661 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_HIT);
8662 std::list<SpellScript::HitHandler>::iterator hookItrEnd = (*scritr)->OnHit.end(), hookItr = (*scritr)->OnHit.begin();
8663 for (; hookItr != hookItrEnd; ++hookItr)
8664 (*hookItr).Call(*scritr);
8665
8666 (*scritr)->_FinishScriptCall();
8667 }
8668}
@ SPELL_SCRIPT_HOOK_HIT
Definition: SpellScript.h:164

References m_loadedScripts, and SPELL_SCRIPT_HOOK_HIT.

Referenced by DoAllEffectOnTarget().

◆ CanAutoCast()

bool Spell::CanAutoCast ( Unit target)
7013{
7014 ObjectGuid targetguid = target->GetGUID();
7015
7016 for (uint32 j = 0; j < MAX_SPELL_EFFECTS; ++j)
7017 {
7019 {
7020 if (m_spellInfo->StackAmount <= 1)
7021 {
7022 if (target->HasAuraEffect(m_spellInfo->Id, j))
7023 return false;
7024 }
7025 else
7026 {
7027 if (AuraEffect* aureff = target->GetAuraEffect(m_spellInfo->Id, j))
7028 if (aureff->GetBase()->GetStackAmount() >= m_spellInfo->StackAmount)
7029 return false;
7030 }
7031 }
7032 else if (m_spellInfo->Effects[j].IsAreaAuraEffect())
7033 {
7034 if (target->HasAuraEffect(m_spellInfo->Id, j))
7035 return false;
7036 }
7037 }
7038
7039 SpellCastResult result = CheckPetCast(target);
7040
7041 if (result == SPELL_CAST_OK || result == SPELL_FAILED_UNIT_NOT_INFRONT)
7042 {
7044 //check if among target units, our WANTED target is as well (->only self cast spells return false)
7045 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
7046 if (ihit->targetGUID == targetguid)
7047 return true;
7048 }
7049 return false; //target invalid
7050}
@ SPELL_EFFECT_APPLY_AURA
Definition: SharedDefines.h:784
@ SPELL_FAILED_UNIT_NOT_INFRONT
Definition: SharedDefines.h:1083
AuraEffect * GetAuraEffect(uint32 spellId, uint8 effIndex, ObjectGuid casterGUID=ObjectGuid::Empty) const
Definition: Unit.cpp:5494
bool HasAuraEffect(uint32 spellId, uint8 effIndex, ObjectGuid caster=ObjectGuid::Empty) const
Definition: Unit.cpp:5668
Definition: SpellAuraEffects.h:39
SpellCastResult CheckPetCast(Unit *target)
Definition: Spell.cpp:6819
uint32 StackAmount
Definition: SpellInfo.h:371

References CheckPetCast(), SpellInfo::Effects, Unit::GetAuraEffect(), Object::GetGUID(), Unit::HasAuraEffect(), SpellInfo::Id, m_spellInfo, m_UniqueTargetInfo, MAX_SPELL_EFFECTS, SelectSpellTargets(), SPELL_CAST_OK, SPELL_EFFECT_APPLY_AURA, SPELL_FAILED_UNIT_NOT_INFRONT, and SpellInfo::StackAmount.

Referenced by PetAI::UpdateAI().

◆ cancel()

void Spell::cancel ( bool  bySelf = false)
3724{
3726 return;
3727
3728 uint32 oldState = m_spellState;
3730
3731 m_autoRepeat = false;
3732 switch (oldState)
3733 {
3737
3738 if (m_caster->IsPlayer())
3739 {
3741 ArenaSpectator::SendCommand_Spell(m_caster->FindMap(), m_caster->GetGUID(), "SPE", m_spellInfo->Id, bySelf ? 99998 : 99999);
3742 }
3743 [[fallthrough]];
3746 break;
3748 if (!bySelf)
3749 {
3750 for (std::list<TargetInfo>::const_iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
3751 if ((*ihit).missCondition == SPELL_MISS_NONE)
3752 if (Unit* unit = m_caster->GetGUID() == ihit->targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID))
3753 unit->RemoveOwnedAura(m_spellInfo->Id, m_originalCasterGUID, 0, AURA_REMOVE_BY_CANCEL);
3754
3757
3760 }
3761
3763 ArenaSpectator::SendCommand_Spell(m_caster->FindMap(), m_caster->GetGUID(), "SPE", m_spellInfo->Id, bySelf ? 99998 : 99999);
3764
3765 // spell is canceled-take mods and clear list
3766 if (Player* player = m_caster->GetSpellModOwner())
3767 player->RemoveSpellMods(this);
3768
3769 m_appliedMods.clear();
3770 break;
3771 default:
3772 break;
3773 }
3774
3776 if (m_selfContainer && *m_selfContainer == this)
3777 *m_selfContainer = nullptr;
3778
3779 // Do not remove current far sight object (already done in Spell::EffectAddFarsight) to prevent from reset viewpoint to player
3781 {
3783 }
3784
3785 if (m_spellInfo->IsChanneled()) // if not channeled then the object for the current cast wasn't summoned yet
3787
3788 //set state back so finish will be processed
3789 m_spellState = oldState;
3790
3791 finish(false);
3792}
@ SPELL_EFFECT_ADD_FARSIGHT
Definition: SharedDefines.h:850
@ SPELL_FAILED_INTERRUPTED
Definition: SharedDefines.h:989
@ SPELL_STATE_PREPARING
Definition: Spell.h:227
@ SPELL_STATE_CASTING
Definition: Spell.h:228
@ AURA_REMOVE_BY_CANCEL
Definition: SpellAuraDefines.h:393
void SendCommand_Spell(T *o, ObjectGuid targetGUID, const char *prefix, uint32 id, int32 casttime)
Definition: ArenaSpectator.h:80
Map * FindMap() const
Definition: Object.h:537
bool NeedSendSpectatorData() const
Definition: Player.cpp:15432
void RemoveGameObject(GameObject *gameObj, bool del)
Definition: Unit.cpp:6197
bool RemoveDynObject(uint32 spellId)
Definition: Unit.cpp:6141
void SendChannelUpdate(uint32 time)
Definition: Spell.cpp:5196
void CancelGlobalCooldown()
Definition: Spell.cpp:8899
void SetReferencedFromCurrent(bool yes)
Definition: Spell.h:563
UsedSpellMods m_appliedMods
Definition: Spell.h:548

References AURA_REMOVE_BY_CANCEL, CancelGlobalCooldown(), WorldObject::FindMap(), finish(), Object::GetGUID(), Unit::GetSpellModOwner(), ObjectAccessor::GetUnit(), SpellInfo::HasEffect(), SpellInfo::Id, SpellInfo::IsChanneled(), SpellInfo::IsCooldownStartedOnEvent(), Object::IsPlayer(), m_appliedMods, m_autoRepeat, m_caster, m_originalCasterGUID, m_selfContainer, m_spellInfo, m_spellState, m_UniqueTargetInfo, Player::NeedSendSpectatorData(), Unit::RemoveDynObject(), Unit::RemoveGameObject(), Player::RemoveSpellCooldown(), SendCastResult(), SendChannelUpdate(), ArenaSpectator::SendCommand_Spell(), SendInterrupted(), SetReferencedFromCurrent(), SPELL_EFFECT_ADD_FARSIGHT, SPELL_FAILED_INTERRUPTED, SPELL_MISS_NONE, SPELL_STATE_CASTING, SPELL_STATE_DELAYED, SPELL_STATE_FINISHED, SPELL_STATE_PREPARING, and Object::ToPlayer().

Referenced by _cast(), SpellEvent::Abort(), AddUnitTarget(), SpellScript::Cancel(), Unit::InterruptSpell(), update(), and SpellEvent::~SpellEvent().

◆ CancelGlobalCooldown()

void Spell::CancelGlobalCooldown ( )
protected
8900{
8902 return;
8903
8904 // Cancel global cooldown when interrupting current cast
8906 return;
8907
8908 // Only players or controlled units have global cooldown
8909 if (m_caster->GetCharmInfo())
8911 else if (m_caster->IsPlayer())
8913}
@ CURRENT_GENERIC_SPELL
Definition: Unit.h:538
GlobalCooldownMgr & GetGlobalCooldownMgr()
Definition: Player.h:1805
void CancelGlobalCooldown(SpellInfo const *spellInfo)
Definition: CharmInfo.cpp:424
GlobalCooldownMgr & GetGlobalCooldownMgr()
Definition: CharmInfo.h:160
CharmInfo * GetCharmInfo()
Definition: Unit.h:1206
Spell * GetCurrentSpell(CurrentSpellTypes spellType) const
Definition: Unit.h:1449
uint32 StartRecoveryTime
Definition: SpellInfo.h:351

References GlobalCooldownMgr::CancelGlobalCooldown(), CURRENT_GENERIC_SPELL, Unit::GetCharmInfo(), Unit::GetCurrentSpell(), Player::GetGlobalCooldownMgr(), CharmInfo::GetGlobalCooldownMgr(), Object::IsPlayer(), m_caster, m_spellInfo, SpellInfo::StartRecoveryTime, and Object::ToPlayer().

Referenced by cancel().

◆ CanExecuteTriggersOnHit()

bool Spell::CanExecuteTriggersOnHit ( uint8  effMask,
SpellInfo const *  triggeredByAura = nullptr 
) const
protected
8749{
8750 // Relentless strikes, proc only from first effect
8751 if (triggeredByAura && triggeredByAura->SpellIconID == 559)
8752 return effMask & (1 << EFFECT_0);
8753
8754 bool only_on_caster = (triggeredByAura && triggeredByAura->HasAttribute(SPELL_ATTR4_CLASS_TRIGGER_ONLY_ON_TARGET));
8755 // If triggeredByAura has SPELL_ATTR4_CLASS_TRIGGER_ONLY_ON_TARGET then it can only proc on a casted spell with TARGET_UNIT_CASTER
8756 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
8757 {
8758 if ((effMask & (1 << i)) && (!only_on_caster || (m_spellInfo->Effects[i].TargetA.GetTarget() == TARGET_UNIT_CASTER)))
8759 return true;
8760 }
8761 return effMask;
8762}
@ EFFECT_0
Definition: SharedDefines.h:31
@ TARGET_UNIT_CASTER
Definition: SharedDefines.h:1410
@ SPELL_ATTR4_CLASS_TRIGGER_ONLY_ON_TARGET
Definition: SharedDefines.h:531

References EFFECT_0, SpellInfo::Effects, SpellInfo::HasAttribute(), m_spellInfo, MAX_SPELL_EFFECTS, SPELL_ATTR4_CLASS_TRIGGER_ONLY_ON_TARGET, SpellInfo::SpellIconID, and TARGET_UNIT_CASTER.

Referenced by DoAllEffectOnTarget(), and DoTriggersOnSpellHit().

◆ CanOpenLock()

SpellCastResult Spell::CanOpenLock ( uint32  effIndex,
uint32  lockid,
SkillType skillid,
int32 reqSkillValue,
int32 skillValue 
)
protected
8364{
8365 if (!lockId) // possible case for GO and maybe for items.
8366 return SPELL_CAST_OK;
8367
8368 // Get LockInfo
8369 LockEntry const* lockInfo = sLockStore.LookupEntry(lockId);
8370
8371 if (!lockInfo)
8373
8374 bool reqKey = false; // some locks not have reqs
8375
8376 for (int j = 0; j < MAX_LOCK_CASE; ++j)
8377 {
8378 switch (lockInfo->Type[j])
8379 {
8380 // check key item (many fit cases can be)
8381 case LOCK_KEY_ITEM:
8382 if (lockInfo->Index[j] && m_CastItem && m_CastItem->GetEntry() == lockInfo->Index[j])
8383 return SPELL_CAST_OK;
8384 reqKey = true;
8385 break;
8386 // check key skill (only single first fit case can be)
8387 case LOCK_KEY_SKILL:
8388 {
8389 reqKey = true;
8390
8391 // wrong locktype, skip
8392 if (uint32(m_spellInfo->Effects[effIndex].MiscValue) != lockInfo->Index[j])
8393 continue;
8394
8395 skillId = SkillByLockType(LockType(lockInfo->Index[j]));
8396
8397 if (skillId != SKILL_NONE)
8398 {
8399 reqSkillValue = lockInfo->Skill[j];
8400
8401 // castitem check: rogue using skeleton keys. the skill values should not be added in this case.
8402 skillValue = m_CastItem || !m_caster->IsPlayer() ?
8403 0 : m_caster->ToPlayer()->GetSkillValue(skillId);
8404
8405 // skill bonus provided by casting spell (mostly item spells)
8406 // add the effect base points modifier from the spell casted (cheat lock / skeleton key etc.)
8407 if ((m_spellInfo->Effects[effIndex].TargetA.GetTarget() == TARGET_GAMEOBJECT_ITEM_TARGET || m_spellInfo->Effects[effIndex].TargetB.GetTarget() == TARGET_GAMEOBJECT_ITEM_TARGET)
8409 {
8410 skillValue += m_spellInfo->Effects[effIndex].CalcValue();
8411 }
8412
8413 if (skillValue < reqSkillValue)
8415 }
8416
8417 return SPELL_CAST_OK;
8418 }
8419 case LOCK_KEY_SPELL:
8420 {
8421 if (m_spellInfo->Id == lockInfo->Index[j])
8422 {
8423 return SPELL_CAST_OK;
8424 }
8425 reqKey = true;
8426 break;
8427 }
8428 }
8429 }
8430
8431 if (reqKey)
8433
8434 return SPELL_CAST_OK;
8435}
#define MAX_LOCK_CASE
Definition: DBCStructure.h:1304
@ TARGET_GAMEOBJECT_ITEM_TARGET
Definition: SharedDefines.h:1430
LockType
Definition: SharedDefines.h:2591
@ LOCK_KEY_ITEM
Definition: SharedDefines.h:2585
@ LOCK_KEY_SKILL
Definition: SharedDefines.h:2586
@ LOCK_KEY_SPELL
Definition: SharedDefines.h:2587
@ SPELL_FAILED_BAD_TARGETS
Definition: SharedDefines.h:961
@ SPELL_FAILED_LOW_CASTLEVEL
Definition: SharedDefines.h:998
SkillType SkillByLockType(LockType locktype)
Definition: SharedDefines.h:3020
@ SKILL_NONE
Definition: SharedDefines.h:2864
@ SKILL_LOCKPICKING
Definition: SharedDefines.h:2975
DBCStorage< LockEntry > sLockStore(LockEntryfmt)
uint16 GetSkillValue(uint32 skill) const
Definition: Player.cpp:5468
bool IsAbilityOfSkillType(uint32 skillType) const
Definition: SpellInfo.cpp:1005
Definition: DBCStructure.h:1307
uint32 Type[MAX_LOCK_CASE]
Definition: DBCStructure.h:1309
uint32 Index[MAX_LOCK_CASE]
Definition: DBCStructure.h:1310
uint32 Skill[MAX_LOCK_CASE]
Definition: DBCStructure.h:1311

References SpellInfo::Effects, Object::GetEntry(), Player::GetSkillValue(), SpellInfo::Id, LockEntry::Index, SpellInfo::IsAbilityOfSkillType(), Object::IsPlayer(), LOCK_KEY_ITEM, LOCK_KEY_SKILL, LOCK_KEY_SPELL, m_caster, m_CastItem, m_spellInfo, MAX_LOCK_CASE, LockEntry::Skill, SKILL_LOCKPICKING, SKILL_NONE, SkillByLockType(), sLockStore, SPELL_CAST_OK, SPELL_FAILED_BAD_TARGETS, SPELL_FAILED_LOW_CASTLEVEL, TARGET_GAMEOBJECT_ITEM_TARGET, Object::ToPlayer(), and LockEntry::Type.

Referenced by CheckCast(), and EffectOpenLock().

◆ cast()

void Spell::cast ( bool  skipCheck = false)
3795{
3796 Player* modOwner = m_caster->GetSpellModOwner();
3797 Spell* lastMod = nullptr;
3798 if (modOwner)
3799 {
3800 lastMod = modOwner->m_spellModTakingSpell;
3801 if (lastMod)
3802 modOwner->SetSpellModTakingSpell(lastMod, false);
3803 }
3804
3805 _cast(skipCheck);
3806
3807 if (lastMod)
3808 modOwner->SetSpellModTakingSpell(lastMod, true);
3809}
Spell * m_spellModTakingSpell
Definition: Player.h:2552
Definition: Spell.h:287
void _cast(bool skipCheck)
Definition: Spell.cpp:3811

References _cast(), Unit::GetSpellModOwner(), m_caster, Player::m_spellModTakingSpell, and Player::SetSpellModTakingSpell().

Referenced by Unit::AttackerStateUpdate(), prepare(), and update().

◆ CheckCast()

SpellCastResult Spell::CheckCast ( bool  strict)
Todo:
: determine if there is some flag to enable/disable the check
5659{
5660 // check death state
5663
5664 // Spectator check
5665 if (m_caster->IsPlayer())
5666 if (((Player const*)m_caster)->IsSpectator() && m_spellInfo->Id != SPECTATOR_SPELL_BINDSIGHT)
5667 return SPELL_FAILED_NOT_HERE;
5668
5670
5671 sScriptMgr->OnSpellCheckCast(this, strict, res);
5672
5673 if (res != SPELL_CAST_OK)
5674 return res;
5675
5676 // check cooldowns to prevent cheating
5678 {
5679 if (m_caster->IsPlayer())
5680 {
5681 //can cast triggered (by aura only?) spells while have this flag
5684
5686 {
5689 else
5691 }
5692
5693 // check if we are using a potion in combat for the 2nd+ time. Cooldown is added only after caster gets out of combat
5696 }
5699 }
5700
5702 {
5705 }
5706
5707 // Check global cooldown
5710
5711 // only triggered spells can be processed an ended battleground
5712 if (!IsTriggered() && m_caster->IsPlayer())
5714 if (bg->GetStatus() == STATUS_WAIT_LEAVE)
5716
5717 if (m_caster->IsPlayer() /*&& VMAP::VMapFactory::createOrGetVMapMgr()->isLineOfSightCalcEnabled()*/) // pussywizard: optimization (commented)
5718 {
5720 !m_caster->IsOutdoors())
5722
5726 }
5727
5728 // only check at first call, Stealth auras are already removed at second call
5729 // for now, ignore triggered spells
5731 {
5732 bool checkForm = true;
5733 // Ignore form req aura
5735 for (Unit::AuraEffectList::const_iterator i = ignore.begin(); i != ignore.end(); ++i)
5736 {
5737 if (!(*i)->IsAffectedOnSpell(m_spellInfo))
5738 continue;
5739 checkForm = false;
5740 break;
5741 }
5742 if (checkForm)
5743 {
5744 // Cannot be used in this stance/form
5746 if (shapeError != SPELL_CAST_OK)
5747 return shapeError;
5748
5751 }
5752 }
5753
5755 for (Unit::AuraEffectList::const_iterator blockItr = blockSpells.begin(); blockItr != blockSpells.end(); ++blockItr)
5756 if (uint32((*blockItr)->GetMiscValue()) == m_spellInfo->SpellFamilyName)
5758
5759 bool reqCombat = true;
5761 for (Unit::AuraEffectList::const_iterator j = stateAuras.begin(); j != stateAuras.end(); ++j)
5762 {
5763 if ((*j)->IsAffectedOnSpell(m_spellInfo))
5764 {
5765 m_needComboPoints = false;
5766 if ((*j)->GetMiscValue() == 1)
5767 {
5768 reqCombat = false;
5769 break;
5770 }
5771 }
5772 }
5773
5774 // caster state requirements
5775 // not for triggered spells (needed by execute)
5777 {
5782
5783 // Note: spell 62473 requres CasterAuraSpell = triggering spell
5788
5789 if (reqCombat && m_caster->IsInCombat() && !m_spellInfo->CanBeUsedInCombat())
5791 }
5792
5793 // Xinef: exploit protection
5795 {
5796 if (m_caster->IsPlayer() && m_caster->GetMap()->IsDungeon())
5797 if (InstanceScript* instanceScript = m_caster->GetInstanceScript())
5798 if (instanceScript->IsEncounterInProgress())
5799 {
5800 if (Group* group = m_caster->ToPlayer()->GetGroup())
5801 for (GroupReference* itr = group->GetFirstMember(); itr != nullptr; itr = itr->next())
5802 if (Player* member = itr->GetSource())
5803 if (member->IsInMap(m_caster))
5804 if (Unit* victim = member->GetVictim())
5805 if (victim->IsInCombat() && m_caster->GetDistance(victim) < m_caster->GetVisibilityRange())
5806 {
5807 m_caster->CombatStart(victim);
5808 victim->AddThreat(m_caster, 1.0f);
5809 break;
5810 }
5812 }
5813 }
5814
5815 // cancel autorepeat spells if cast start when moving
5816 // (not wand currently autorepeat cast delayed to moving stop anyway in spell update code)
5817 if (m_caster->IsPlayer() && m_caster->ToPlayer()->isMoving() && !IsTriggered())
5818 {
5819 // skip stuck spell to allow use it in falling case and apply spell limitations at movement
5822 return SPELL_FAILED_MOVING;
5823 }
5824
5825 Vehicle* vehicle = m_caster->GetVehicle();
5827 {
5828 uint16 checkMask = 0;
5829 for (uint8 effIndex = EFFECT_0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
5830 {
5831 SpellEffectInfo const* effInfo = &m_spellInfo->Effects[effIndex];
5833 {
5834 SpellShapeshiftFormEntry const* shapeShiftEntry = sSpellShapeshiftFormStore.LookupEntry(effInfo->MiscValue);
5835 if (shapeShiftEntry && (shapeShiftEntry->flags1 & 1) == 0) // unk flag
5836 checkMask |= VEHICLE_SEAT_FLAG_UNCONTROLLED;
5837 break;
5838 }
5839 }
5840
5843
5844 if (!checkMask)
5845 checkMask = VEHICLE_SEAT_FLAG_CAN_ATTACK;
5846
5847 // All creatures should be able to cast as passengers freely, restriction and attribute are only for players
5848 VehicleSeatEntry const* vehicleSeat = vehicle->GetSeatForPassenger(m_caster);
5850 && (vehicleSeat->m_flags & checkMask) != checkMask && m_caster->IsPlayer())
5852 }
5853
5854 // check spell cast conditions from database
5855 {
5858 ConditionList conditions = sConditionMgr->GetConditionsForNotGroupedEntry(CONDITION_SOURCE_TYPE_SPELL, m_spellInfo->Id);
5859 if (!conditions.empty() && !sConditionMgr->IsObjectMeetToConditions(condInfo, conditions))
5860 {
5861 // mLastFailedCondition can be nullptr if there was an error processing the condition in Condition::Meets (i.e. wrong data for ConditionTarget or others)
5862 if (condInfo.mLastFailedCondition && condInfo.mLastFailedCondition->ErrorType)
5863 {
5867 }
5868 if (!condInfo.mLastFailedCondition || !condInfo.mLastFailedCondition->ConditionTarget)
5871 }
5872 }
5873
5874 // Don't check explicit target for passive spells (workaround) (check should be skipped only for learn case)
5875 // those spells may have incorrect target entries or not filled at all (for example 15332)
5876 // such spells when learned are not targeting anyone using targeting system, they should apply directly to caster instead
5877 // also, such casts shouldn't be sent to client
5878 // Xinef: do not check explicit casts for self cast of triggered spells (eg. reflect case)
5880 {
5881 // Check explicit target for m_originalCaster - todo: get rid of such workarounds
5882 // Xinef: do not check explicit target for triggered spell casted on self with targetflag enemy
5884 {
5886 if (castResult != SPELL_CAST_OK)
5887 return castResult;
5888 }
5889 }
5890
5891 if (Unit* target = m_targets.GetUnitTarget())
5892 {
5893 SpellCastResult castResult = m_spellInfo->CheckTarget(m_caster, target, false);
5894 if (castResult != SPELL_CAST_OK)
5895 return castResult;
5896
5897 if (target != m_caster)
5898 {
5899 // Must be behind the target
5900 if (m_spellInfo->HasAttribute(SPELL_ATTR0_CU_REQ_CASTER_BEHIND_TARGET) && target->HasInArc(static_cast<float>(M_PI), m_caster))
5902
5903 // Target must be facing you
5904 if (m_spellInfo->HasAttribute(SPELL_ATTR0_CU_REQ_TARGET_FACING_CASTER) && !target->HasInArc(static_cast<float>(M_PI), m_caster))
5906
5909 {
5910 bool castedByGameobject = false;
5911 uint32 losChecks = LINEOFSIGHT_ALL_CHECKS;
5913 {
5914 castedByGameobject = m_caster->GetMap()->GetGameObject(m_originalCasterGUID) != nullptr;
5915 }
5916 else if (m_caster->GetEntry() == WORLD_TRIGGER)
5917 {
5918 if (TempSummon* tempSummon = m_caster->ToTempSummon())
5919 {
5920 castedByGameobject = tempSummon->GetSummonerGameObject() != nullptr;
5921 }
5922 }
5923
5924 if (castedByGameobject)
5925 {
5926 // If spell casted by gameobject then ignore M2 models
5927 losChecks &= ~LINEOFSIGHT_CHECK_GOBJECT_M2;
5928 }
5929
5931 {
5933 }
5934 }
5935 }
5936 }
5937
5938 // Check for line of sight for spells with dest
5939 if (m_targets.HasDst())
5940 {
5941 float x, y, z;
5942 m_targets.GetDstPos()->GetPosition(x, y, z);
5943
5946 {
5947 bool castedByGameobject = false;
5948 uint32 losChecks = LINEOFSIGHT_ALL_CHECKS;
5950 {
5951 castedByGameobject = m_caster->GetMap()->GetGameObject(m_originalCasterGUID) != nullptr;
5952 }
5953 else if (m_caster->GetEntry() == WORLD_TRIGGER)
5954 {
5955 if (TempSummon* tempSummon = m_caster->ToTempSummon())
5956 {
5957 castedByGameobject = tempSummon->GetSummonerGameObject() != nullptr;
5958 }
5959 }
5960
5961 if (castedByGameobject)
5962 {
5963 // If spell casted by gameobject then ignore M2 models
5964 losChecks &= ~LINEOFSIGHT_CHECK_GOBJECT_M2;
5965 }
5966
5968 {
5970 }
5971 }
5972 }
5973
5974 // check pet presence
5975 for (int j = 0; j < MAX_SPELL_EFFECTS; ++j)
5976 {
5977 if (m_spellInfo->Effects[j].TargetA.GetTarget() == TARGET_UNIT_PET)
5978 {
5980 {
5981 if (m_triggeredByAuraSpell.spellInfo) // not report pet not existence for triggered spells
5983 else
5984 return SPELL_FAILED_NO_PET;
5985 }
5986 break;
5987 }
5988 }
5989 // Spell casted only on battleground
5991 if (!m_caster->ToPlayer()->InBattleground())
5993
5994 // do not allow spells to be cast in arenas
5995 // - with greater than 10 min CD without SPELL_ATTR4_IGNORE_DEFAULT_ARENA_RESTRICTIONS flag
5996 // - with SPELL_ATTR4_NOT_IN_ARENA_OR_RATED_BATTLEGROUND flag
5999 if (MapEntry const* mapEntry = sMapStore.LookupEntry(m_caster->GetMapId()))
6000 if (mapEntry->IsBattleArena())
6002
6003 // zone check
6005 {
6006 uint32 zone, area;
6007 m_caster->GetZoneAndAreaId(zone, area);
6008
6010 m_caster->IsPlayer() ? m_caster->ToPlayer() : nullptr);
6011 if (locRes != SPELL_CAST_OK)
6012 return locRes;
6013 }
6014
6015 // not let players cast spells at mount (and let do it to creatures)
6018 {
6019 if (m_caster->IsInFlight())
6021 else
6023 }
6024
6025 SpellCastResult castResult = SPELL_CAST_OK;
6026
6027 // always (except passive spells) check items (focus object can be required for any type casts)
6028 if (!m_spellInfo->IsPassive())
6029 {
6030 // spell focus needs to be checked not only for players! there are vehicle spells that require spell focus
6031 castResult = CheckSpellFocus();
6032 if (castResult != SPELL_CAST_OK)
6033 return castResult;
6034
6035 castResult = CheckItems();
6036 if (castResult != SPELL_CAST_OK)
6037 return castResult;
6038 }
6039
6040 // Triggered spells also have range check
6042 castResult = CheckRange(strict);
6043 if (castResult != SPELL_CAST_OK)
6044 return castResult;
6045
6047 {
6048 castResult = CheckPower();
6049 if (castResult != SPELL_CAST_OK)
6050 return castResult;
6051 }
6052
6054 {
6055 return SPELL_CAST_OK;
6056 }
6057
6058 // xinef: do not skip triggered spells if they posses prevention type (eg. Bladestorm vs Hand of Protection)
6060 {
6062 if (castResult != SPELL_CAST_OK)
6063 return castResult;
6064
6065 // xinef: Enraged Regeneration: While this is active, the warrior is blocked from using abilities that trigger being enraged (which would do nothing and waste the cooldowns).
6067 {
6069 for (SpellImmuneList::const_iterator itr = mechanicList.begin(); itr != mechanicList.end(); ++itr)
6070 if (itr->type == m_spellInfo->Mechanic)
6072 }
6073 }
6074
6075 // script hook
6076 castResult = CallScriptCheckCastHandlers();
6077 if (castResult != SPELL_CAST_OK)
6078 return castResult;
6079
6080 bool hasDispellableAura = false;
6081 bool hasNonDispelEffect = false;
6082 uint32 dispelMask = 0;
6083 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
6084 if (m_spellInfo->Effects[i].Effect == SPELL_EFFECT_DISPEL)
6085 {
6087 {
6088 hasDispellableAura = true;
6089 break;
6090 }
6091
6092 dispelMask |= SpellInfo::GetDispelMask(DispelType(m_spellInfo->Effects[i].MiscValue));
6093 }
6094 else if (m_spellInfo->Effects[i].IsEffect())
6095 {
6096 hasNonDispelEffect = true;
6097 break;
6098 }
6099
6100 if (!hasNonDispelEffect && !hasDispellableAura && dispelMask && !IsTriggered())
6101 {
6102 if (Unit* target = m_targets.GetUnitTarget())
6103 {
6104 // Xinef: do not allow to cast on hostile targets in sanctuary
6105 if (!m_caster->IsFriendlyTo(target))
6106 {
6107 if (m_caster->IsInSanctuary() || target->IsInSanctuary())
6108 {
6109 // Xinef: fix for duels
6110 Player* player = m_caster->ToPlayer();
6111 if (!player || !player->duel || target != player->duel->Opponent)
6113 }
6114 }
6115
6116 DispelChargesList dispelList;
6117 target->GetDispellableAuraList(m_caster, dispelMask, dispelList, m_spellInfo);
6118
6119 if (dispelList.empty())
6121 }
6122 }
6123
6124 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
6125 {
6126 // for effects of spells that have only one target
6127 switch (m_spellInfo->Effects[i].Effect)
6128 {
6130 {
6131 if (!m_caster->IsPlayer())
6133
6134 if (m_spellInfo->Effects[i].TargetA.GetTarget() != TARGET_UNIT_PET)
6135 break;
6136
6137 Pet* pet = m_caster->ToPlayer()->GetPet();
6138
6139 if (!pet)
6140 return SPELL_FAILED_NO_PET;
6141
6142 SpellInfo const* learn_spellproto = sSpellMgr->GetSpellInfo(m_spellInfo->Effects[i].TriggerSpell);
6143
6144 if (!learn_spellproto)
6146
6147 if (m_spellInfo->SpellLevel > pet->GetLevel())
6148 return SPELL_FAILED_LOWLEVEL;
6149
6150 break;
6151 }
6153 {
6154 // check target only for unit target case
6156 {
6157 if (!m_caster->IsPlayer())
6159
6160 Pet* pet = unitTarget->ToPet();
6161 if (!pet || pet->GetOwner() != m_caster)
6163
6164 SpellInfo const* learn_spellproto = sSpellMgr->GetSpellInfo(m_spellInfo->Effects[i].TriggerSpell);
6165
6166 if (!learn_spellproto)
6168
6169 if (m_spellInfo->SpellLevel > pet->GetLevel())
6170 return SPELL_FAILED_LOWLEVEL;
6171 }
6172 break;
6173 }
6175 {
6176 uint32 glyphId = m_spellInfo->Effects[i].MiscValue;
6177 if (GlyphPropertiesEntry const* gp = sGlyphPropertiesStore.LookupEntry(glyphId))
6178 if (m_caster->HasAura(gp->SpellId))
6180 break;
6181 }
6183 {
6184 if (!m_caster->IsPlayer())
6186
6187 Item* foodItem = m_targets.GetItemTarget();
6188 if (!foodItem)
6190
6191 Pet* pet = m_caster->ToPlayer()->GetPet();
6192
6193 if (!pet)
6194 return SPELL_FAILED_NO_PET;
6195
6196 if (!pet->HaveInDiet(foodItem->GetTemplate()))
6198
6199 if (!pet->GetCurrentFoodBenefitLevel(foodItem->GetTemplate()->ItemLevel))
6201
6202 if (m_caster->IsInCombat() || pet->IsInCombat())
6204
6205 break;
6206 }
6209 {
6210 // Can be area effect, Check only for players and not check if target - caster (spell can have multiply drain/burn effects)
6211 if (m_caster->IsPlayer())
6212 if (Unit* target = m_targets.GetUnitTarget())
6213 if (target != m_caster && !target->HasActivePowerType(Powers(m_spellInfo->Effects[i].MiscValue)))
6215 break;
6216 }
6218 {
6220 {
6222 }
6223
6225 {
6226 // Warbringer - can't be handled in proc system - should be done before checkcast root check and charge effect process
6227 if (strict && m_caster->IsScriptOverriden(m_spellInfo, 6953))
6229 }
6231 {
6232 // Exception for Master's Call
6233 if (m_spellInfo->Id != 54216)
6234 {
6235 return SPELL_FAILED_ROOTED;
6236 }
6237 }
6238 if (m_caster->IsPlayer())
6239 if (Unit* target = m_targets.GetUnitTarget())
6240 if (!target->IsAlive())
6242 // Xinef: Pass only explicit unit target spells
6243 // pussywizard:
6245 {
6246 Unit* target = m_targets.GetUnitTarget();
6247 if (!target)
6249
6250 // first we must check to see if the target is in LoS. A path can usually be built but LoS matters for charge spells
6251 if (!target->IsWithinLOSInMap(m_caster)) //Do full LoS/Path check. Don't exclude m2
6253
6254 float objSize = target->GetCombatReach();
6255 float range = m_spellInfo->GetMaxRange(true, m_caster, this) * 1.5f + objSize; // can't be overly strict
6256
6257 m_preGeneratedPath = std::make_unique<PathGenerator>(m_caster);
6258 m_preGeneratedPath->SetPathLengthLimit(range);
6259
6260 // first try with raycast, if it fails fall back to normal path
6261 bool result = m_preGeneratedPath->CalculatePath(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), false);
6262 if (m_preGeneratedPath->GetPathType() & PATHFIND_SHORT)
6263 return SPELL_FAILED_NOPATH;
6264 else if (!result || m_preGeneratedPath->GetPathType() & (PATHFIND_NOPATH | PATHFIND_INCOMPLETE))
6265 return SPELL_FAILED_NOPATH;
6266 else if (m_preGeneratedPath->IsInvalidDestinationZ(target)) // Check position z, if not in a straight line
6267 return SPELL_FAILED_NOPATH;
6268
6269 m_preGeneratedPath->ShortenPathUntilDist(G3D::Vector3(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ()), objSize); // move back
6270 }
6271 if (Player* player = m_caster->ToPlayer())
6272 player->SetCanTeleport(true);
6273 break;
6274 }
6276 {
6279
6282
6283 Creature* creature = m_targets.GetUnitTarget()->ToCreature();
6284 if (!creature->IsCritter() && !creature->loot.isLooted())
6286
6287 uint32 skill = creature->GetCreatureTemplate()->GetRequiredLootSkill();
6288
6289 int32 skillValue = m_caster->ToPlayer()->GetSkillValue(skill);
6290 int32 TargetLevel = m_targets.GetUnitTarget()->GetLevel();
6291 int32 ReqValue = (skillValue < 100 ? (TargetLevel - 10) * 10 : TargetLevel * 5);
6292 if (ReqValue > skillValue)
6294
6295 break;
6296 }
6298 {
6299 if (m_spellInfo->Effects[i].TargetA.GetTarget() != TARGET_GAMEOBJECT_TARGET &&
6300 m_spellInfo->Effects[i].TargetA.GetTarget() != TARGET_GAMEOBJECT_ITEM_TARGET)
6301 break;
6302
6303 if (!m_caster->IsPlayer() // only players can open locks, gather etc.
6304 // we need a go target in case of TARGET_GAMEOBJECT_TARGET
6305 || (m_spellInfo->Effects[i].TargetA.GetTarget() == TARGET_GAMEOBJECT_TARGET && !m_targets.GetGOTarget()))
6307
6308 Item* pTempItem = nullptr;
6310 {
6311 if (TradeData* pTrade = m_caster->ToPlayer()->GetTradeData())
6312 pTempItem = pTrade->GetTraderData()->GetItem(TradeSlots(m_targets.GetItemTargetGUID().GetRawValue()));
6313 }
6316
6317 // we need a go target, or an openable item target in case of TARGET_GAMEOBJECT_ITEM_TARGET
6318 if (m_spellInfo->Effects[i].TargetA.GetTarget() == TARGET_GAMEOBJECT_ITEM_TARGET &&
6320 (!pTempItem || !pTempItem->GetTemplate()->LockID || !pTempItem->IsLocked()))
6322
6323 // We must also ensure the gameobject we are opening is still closed by the time the spell finishes.
6324 if (GameObject* go = m_targets.GetGOTarget())
6325 {
6326 if (go->GetGoType() == GAMEOBJECT_TYPE_DOOR && go->GetGoState() != GO_STATE_READY)
6327 {
6329 }
6330 }
6331 if (m_spellInfo->Id != 1842 || (m_targets.GetGOTarget() &&
6333 {
6334 if (m_targets.GetGOTarget() && m_targets.GetGOTarget()->GetEntry() == 179697)
6335 {
6336 if (!m_caster->ToPlayer()->CanUseBattlegroundObject(nullptr))
6338 }
6339 else if (m_caster->ToPlayer()->InBattleground() && // In Battleground players can use only flags and banners, or Gurubashi chest
6342 }
6343
6344 // get the lock entry
6345 uint32 lockId = 0;
6346 if (GameObject* go = m_targets.GetGOTarget())
6347 {
6348 lockId = go->GetGOInfo()->GetLockId();
6349 if (!lockId)
6351 }
6352 else if (Item* itm = m_targets.GetItemTarget())
6353 lockId = itm->GetTemplate()->LockID;
6354
6355 SkillType skillId = SKILL_NONE;
6356 int32 reqSkillValue = 0;
6357 int32 skillValue = 0;
6358
6359 // check lock compatibility
6360 SpellCastResult res = CanOpenLock(i, lockId, skillId, reqSkillValue, skillValue);
6361 if (res != SPELL_CAST_OK)
6362 return res;
6363
6364 // chance for fail at lockpicking attempt
6365 // second check prevent fail at rechecks
6366 // herbalism and mining cannot fail as of patch 3.1.0
6367 if (skillId != SKILL_NONE && skillId != SKILL_HERBALISM && skillId != SKILL_MINING && (!m_selfContainer || ((*m_selfContainer) != this)))
6368 {
6369 // chance for failure in orange lockpick
6370 if (skillId == SKILL_LOCKPICKING && reqSkillValue > irand(skillValue - 25, skillValue + 37))
6371 {
6373 }
6374 }
6375 break;
6376 }
6378 {
6379 Unit* unitCaster = m_caster->ToUnit();
6380 if (!unitCaster)
6381 {
6383 }
6384
6385 Creature* pet = unitCaster->GetGuardianPet();
6386 if (pet)
6387 {
6388 if (pet->IsAlive())
6389 {
6391 }
6392 }
6393 else if (Player* playerCaster = m_caster->ToPlayer())
6394 {
6395 PetStable& petStable = playerCaster->GetOrInitPetStable();
6396 if (!petStable.CurrentPet && petStable.UnslottedPets.empty())
6397 {
6398 return SPELL_FAILED_NO_PET;
6399 }
6400 }
6401
6402 break;
6403 }
6404 // This is generic summon effect
6406 {
6407 SummonPropertiesEntry const* SummonProperties = sSummonPropertiesStore.LookupEntry(m_spellInfo->Effects[i].MiscValueB);
6408 if (!SummonProperties || m_spellInfo->HasAttribute(SPELL_ATTR1_DISMISS_PET_FIRST))
6409 break;
6410 switch (SummonProperties->Category)
6411 {
6413 if (m_caster->GetPetGUID())
6415 [[fallthrough]];
6417 if (m_caster->GetCharmGUID())
6419 break;
6420 }
6421 break;
6422 }
6424 {
6426 {
6431 }
6432 break;
6433 }
6435 {
6436 Unit* unitCaster = m_caster->ToUnit();
6437 if (!unitCaster)
6439
6441 {
6442 if (m_caster->GetPetGUID())
6444 if (m_caster->GetCharmGUID())
6446 }
6447
6449 if (Pet* pet = m_caster->ToPlayer()->GetPet())
6450 pet->CastSpell(pet, 32752, true, nullptr, nullptr, pet->GetGUID()); //starting cast, trigger pet stun (cast by pet so it doesn't attack player)
6451
6452 Player* playerCaster = unitCaster->ToPlayer();
6453 if (playerCaster && playerCaster->GetPetStable())
6454 {
6455 std::pair<PetStable::PetInfo const*, PetSaveMode> info = Pet::GetLoadPetInfo(*playerCaster->GetPetStable(), m_spellInfo->Effects[i].MiscValue, 0, false);
6456 if (info.first)
6457 {
6458 if (info.first->Type == HUNTER_PET)
6459 {
6460 if (!info.first->Health)
6461 {
6462 playerCaster->SendTameFailure(PET_TAME_DEAD);
6464 }
6465
6466 CreatureTemplate const* creatureInfo = sObjectMgr->GetCreatureTemplate(info.first->CreatureId);
6467 if (!creatureInfo || !creatureInfo->IsTameable(playerCaster->CanTameExoticPets()))
6468 {
6469 // if problem in exotic pet
6470 if (creatureInfo && creatureInfo->IsTameable(true))
6472 else
6474
6476 }
6477 }
6478 }
6479 else if (!m_spellInfo->Effects[i].MiscValue) // when miscvalue is present it is allowed to create new pets
6480 {
6483 }
6484 }
6485 break;
6486 }
6488 {
6489 if (!m_caster->IsPlayer())
6491 if (!m_caster->GetTarget())
6493
6495 if (!target || (!target->IsInSameRaidWith(m_caster->ToPlayer()) && m_spellInfo->Id != 48955)) // refer-a-friend spell
6497
6498 // Xinef: Implement summon pending error
6499 if (target->GetSummonExpireTimer() > GameTime::GetGameTime().count())
6501
6502 // check if our map is dungeon
6503 MapEntry const* map = sMapStore.LookupEntry(m_caster->GetMapId());
6504 if (map->IsDungeon())
6505 {
6506 uint32 mapId = m_caster->GetMap()->GetId();
6507 Difficulty difficulty = m_caster->GetMap()->GetDifficulty();
6508 /*if (map->IsRaid())
6509 if (InstancePlayerBind* targetBind = target->GetBoundInstance(mapId, difficulty))
6510 if (targetBind->perm && targetBind != m_caster->ToPlayer()->GetBoundInstance(mapId, difficulty))
6511 return SPELL_FAILED_TARGET_LOCKED_TO_RAID_INSTANCE;*/
6512
6513 InstanceTemplate const* instance = sObjectMgr->GetInstanceTemplate(mapId);
6514 if (!instance)
6516 if (!target->Satisfy(sObjectMgr->GetAccessRequirement(mapId, difficulty), mapId))
6518 }
6519 break;
6520 }
6521 // RETURN HERE
6523 {
6524 if (!m_caster->IsPlayer())
6526
6527 Player* playerCaster = m_caster->ToPlayer();
6528 //
6529 if (!(playerCaster->GetTarget()))
6531
6533
6534 if (!target ||
6535 !(target->GetSession()->GetRecruiterId() == playerCaster->GetSession()->GetAccountId() || target->GetSession()->GetAccountId() == playerCaster->GetSession()->GetRecruiterId()))
6537
6538 // Xinef: Implement summon pending error
6539 if (target->GetSummonExpireTimer() > GameTime::GetGameTime().count())
6541
6542 break;
6543 }
6544 case SPELL_EFFECT_LEAP:
6546 {
6547 //Do not allow to cast it before BG starts.
6548 if (m_caster->IsPlayer())
6549 if (Battleground const* bg = m_caster->ToPlayer()->GetBattleground())
6550 if (bg->GetStatus() != STATUS_IN_PROGRESS)
6552 break;
6553 }
6555 {
6558
6559 bool found = false;
6561 for(Unit::VisibleAuraMap::const_iterator itr = visibleAuras->begin(); itr != visibleAuras->end(); ++itr)
6562 {
6563 if (itr->second->GetBase()->IsPassive())
6564 continue;
6565
6566 if (!itr->second->IsPositive())
6567 continue;
6568
6569 found = true;
6570 break;
6571 }
6572
6573 if (!found)
6575
6576 break;
6577 }
6579 {
6581 {
6582 if (m_caster->IsPlayer())
6583 return SPELL_FAILED_ROOTED;
6584 else
6586 }
6587 break;
6588 }
6589 // xinef: do not allow to use leaps while rooted
6590 case SPELL_EFFECT_JUMP:
6592 {
6594 return SPELL_FAILED_ROOTED;
6595 break;
6596 }
6598 if (!sScriptMgr->CanSelectSpecTalent(this))
6600 // can't change during already started arena/battleground
6601 if (m_caster->IsPlayer())
6602 if (Battleground const* bg = m_caster->ToPlayer()->GetBattleground())
6603 if (bg->GetStatus() == STATUS_IN_PROGRESS)
6605 break;
6606 default:
6607 break;
6608 }
6609 }
6610
6611 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
6612 {
6613 switch (m_spellInfo->Effects[i].ApplyAuraName)
6614 {
6615 case SPELL_AURA_DUMMY:
6616 break;
6618 {
6619 if (!m_caster->IsPlayer())
6620 return SPELL_FAILED_NO_PET;
6621
6622 Pet* pet = m_caster->ToPlayer()->GetPet();
6623 if (!pet)
6624 return SPELL_FAILED_NO_PET;
6625
6626 if (pet->GetCharmerGUID())
6627 return SPELL_FAILED_CHARMED;
6628 break;
6629 }
6633 {
6634 if (m_caster->GetCharmerGUID())
6635 return SPELL_FAILED_CHARMED;
6636
6637 // Xinef: allow SPELL_AURA_MOD_POSSESS to posses target if caster has some pet
6639 {
6640 if (m_caster->GetPetGUID())
6642
6643 if (m_caster->GetCharmGUID())
6645 }
6646 else if (m_spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_MOD_POSSESS)
6647 {
6648 if (m_caster->GetCharmGUID())
6650 }
6651
6652 if (Unit* target = m_targets.GetUnitTarget())
6653 {
6654 if (target->IsCreature() && target->ToCreature()->IsVehicle())
6656
6657 if (target->IsMounted())
6659
6660 if (target->GetCharmerGUID())
6661 return SPELL_FAILED_CHARMED;
6662
6663 if (target->GetOwnerGUID() && target->GetOwnerGUID().IsPlayer())
6665
6666 if (target->IsPet() && (!target->GetOwner() || target->GetOwner()->ToPlayer()))
6668
6669 int32 damage = CalculateSpellDamage(i, target);
6670 if (damage && int32(target->GetLevel()) > damage)
6672 }
6673
6674 break;
6675 }
6676 case SPELL_AURA_MOUNTED:
6677 {
6678 // Disallow casting flying mounts in water
6681
6682 // Ignore map check if spell have AreaId. AreaId already checked and this prevent special mount spells
6683 bool allowMount = !m_caster->GetMap()->IsDungeon() || m_caster->GetMap()->IsBattlegroundOrArena();
6684 InstanceTemplate const* it = sObjectMgr->GetInstanceTemplate(m_caster->GetMapId());
6685 if (it)
6686 allowMount = it->AllowMount;
6687 if (m_caster->IsPlayer() && !allowMount && !m_spellInfo->AreaGroupId)
6689
6692
6693 // xinef: dont allow to cast mounts in specific transforms
6694 if (m_caster->getTransForm())
6695 if (SpellInfo const* transformSpellInfo = sSpellMgr->GetSpellInfo(m_caster->getTransForm()))
6696 if (transformSpellInfo->HasAttribute(SPELL_ATTR0_NO_IMMUNITIES) &&
6697 !transformSpellInfo->HasAttribute(SpellAttr0(SPELL_ATTR0_ALLOW_WHILE_MOUNTED | SPELL_ATTR0_AURA_IS_DEBUFF)))
6699
6700 break;
6701 }
6703 {
6704 if (!m_targets.GetUnitTarget())
6706
6707 // can be casted at non-friendly unit or own pet/charm
6710
6711 break;
6712 }
6713 case SPELL_AURA_FLY:
6715 {
6716 // Xinef: added water check
6717 if (m_caster->IsInWater())
6719
6720 // not allow cast fly spells if not have req. skills (all spells is self target)
6721 // allow always ghost flight spells
6723 {
6724 Battlefield* Bf = sBattlefieldMgr->GetBattlefieldToZoneId(m_originalCaster->GetZoneId());
6725 if (AreaTableEntry const* pArea = sAreaTableStore.LookupEntry(m_originalCaster->GetAreaId()))
6726 if ((pArea->flags & AREA_FLAG_NO_FLY_ZONE) || (Bf && !Bf->CanFlyIn()))
6727 return SPELL_FAILED_NOT_HERE;
6728 }
6729 break;
6730 }
6732 {
6733 if (m_spellInfo->Effects[i].IsTargetingArea())
6734 break;
6735
6736 if (!m_caster->IsPlayer() || m_CastItem)
6737 break;
6738
6739 if (!m_targets.GetUnitTarget())
6741
6744
6745 break;
6746 }
6747 case SPELL_AURA_HOVER:
6748 {
6750 {
6752 }
6753 break;
6754 }
6756 {
6757 if (m_caster && m_caster->HasAura(23397)) // Nefarian Class Call (Warrior): Berserk -- Nefertum: I don't really like this but I didn't find another way.
6758 {
6760 }
6761 break;
6762 }
6763 default:
6764 break;
6765 }
6766 }
6767
6768 // check trade slot case (last, for allow catch any another cast problems)
6770 {
6771 if (m_CastItem)
6773
6774 if (!m_caster->IsPlayer())
6776
6777 TradeData* my_trade = m_caster->ToPlayer()->GetTradeData();
6778
6779 if (!my_trade)
6781
6783 if (slot != TRADE_SLOT_NONTRADED)
6785
6786 if (!IsTriggered())
6787 if (my_trade->GetSpell())
6789 }
6790
6791 // check if caster has at least 1 combo point on target for spells that require combo points
6793 {
6795 {
6797 {
6799 }
6800 }
6801 else
6802 {
6803 if (!m_caster->GetComboPoints())
6804 {
6806 }
6807 }
6808 }
6809
6810 // xinef: check relic cooldown
6814
6815 // all ok
6816 return SPELL_CAST_OK;
6817}
constexpr auto IN_MILLISECONDS
Definition: Common.h:53
constexpr auto MINUTE
Definition: Common.h:47
int32 irand(int32 min, int32 max)
Definition: Random.cpp:37
std::uint16_t uint16
Definition: Define.h:108
@ VEHICLE_SEAT_FLAG_CAN_CAST_MOUNT_SPELL
Definition: DBCEnums.h:456
@ VEHICLE_SEAT_FLAG_UNCONTROLLED
Definition: DBCEnums.h:457
@ VEHICLE_SEAT_FLAG_CAN_ATTACK
Definition: DBCEnums.h:458
Difficulty
Definition: DBCEnums.h:266
@ AREA_FLAG_NO_FLY_ZONE
Definition: DBCEnums.h:262
@ GAMEOBJECT_TYPE_TRAP
Definition: SharedDefines.h:1566
@ GAMEOBJECT_TYPE_DOOR
Definition: SharedDefines.h:1560
Powers
Definition: SharedDefines.h:268
@ POWER_MANA
Definition: SharedDefines.h:269
@ SPELL_ATTR7_DEBUG_SPELL
Definition: SharedDefines.h:644
@ SPELL_EFFECT_LEAP
Definition: SharedDefines.h:807
@ SPELL_EFFECT_POWER_BURN
Definition: SharedDefines.h:840
@ SPELL_EFFECT_STUCK
Definition: SharedDefines.h:862
@ SPELL_EFFECT_SUMMON_RAF_FRIEND
Definition: SharedDefines.h:930
@ SPELL_EFFECT_APPLY_GLYPH
Definition: SharedDefines.h:852
@ SPELL_EFFECT_FEED_PET
Definition: SharedDefines.h:879
@ SPELL_EFFECT_SUMMON_PLAYER
Definition: SharedDefines.h:863
@ SPELL_EFFECT_JUMP_DEST
Definition: SharedDefines.h:820
@ SPELL_EFFECT_TELEPORT_UNITS_FACE_CASTER
Definition: SharedDefines.h:821
@ SPELL_EFFECT_RESURRECT_PET
Definition: SharedDefines.h:887
@ SPELL_EFFECT_LEAP_BACK
Definition: SharedDefines.h:916
@ SPELL_EFFECT_SUMMON
Definition: SharedDefines.h:806
@ SPELL_EFFECT_POWER_DRAIN
Definition: SharedDefines.h:786
@ SPELL_EFFECT_RESURRECT
Definition: SharedDefines.h:796
@ SPELL_EFFECT_CHARGE
Definition: SharedDefines.h:874
@ SPELL_EFFECT_RESURRECT_NEW
Definition: SharedDefines.h:891
@ SPELL_EFFECT_TALENT_SPEC_SELECT
Definition: SharedDefines.h:940
@ SPELL_EFFECT_LEARN_SPELL
Definition: SharedDefines.h:814
@ SPELL_EFFECT_JUMP
Definition: SharedDefines.h:819
@ SPELL_EFFECT_SKINNING
Definition: SharedDefines.h:873
@ SPELL_EFFECT_CREATE_TAMED_PET
Definition: SharedDefines.h:931
@ SPELL_EFFECT_OPEN_LOCK
Definition: SharedDefines.h:811
@ SPELL_EFFECT_STEAL_BENEFICIAL_BUFF
Definition: SharedDefines.h:904
@ SPELL_EFFECT_LEARN_PET_SPELL
Definition: SharedDefines.h:835
@ SPELL_PREVENTION_TYPE_NONE
Definition: SharedDefines.h:1553
@ SPELL_ATTR5_ALWAYS_AOE_LINE_OF_SIGHT
Definition: SharedDefines.h:593
@ TARGET_UNIT_PET
Definition: SharedDefines.h:1414
@ TARGET_GAMEOBJECT_TARGET
Definition: SharedDefines.h:1427
@ SPELL_ATTR2_IGNORE_LINE_OF_SIGHT
Definition: SharedDefines.h:458
@ SPELL_ATTR1_INITIATE_COMBAT
Definition: SharedDefines.h:428
@ SPELL_ATTR3_ONLY_BATTLEGROUNDS
Definition: SharedDefines.h:504
@ PET_TAME_NOPET_AVAILABLE
Definition: SharedDefines.h:3683
@ PET_TAME_DEAD
Definition: SharedDefines.h:3686
@ PET_TAME_CANT_CONTROL_EXOTIC
Definition: SharedDefines.h:3688
@ CLASS_WARLOCK
Definition: SharedDefines.h:149
@ IMMUNITY_MECHANIC
Definition: SharedDefines.h:1399
@ SPELLFAMILY_WARRIOR
Definition: SharedDefines.h:3532
SpellCustomErrors
Definition: SharedDefines.h:1142
@ SPELL_CUSTOM_ERROR_GM_ONLY
Definition: SharedDefines.h:1208
SpellAttr0
Definition: SharedDefines.h:381
@ SPELL_ATTR0_ONLY_INDOORS
Definition: SharedDefines.h:396
@ SPELL_ATTR0_AURA_IS_DEBUFF
Definition: SharedDefines.h:408
@ SPELL_ATTR0_ONLY_OUTDOORS
Definition: SharedDefines.h:397
@ SPELL_ATTR0_ALLOW_WHILE_MOUNTED
Definition: SharedDefines.h:406
@ SPELL_ATTR0_PASSIVE
Definition: SharedDefines.h:388
@ SPELL_ATTR0_ALLOW_CAST_WHILE_DEAD
Definition: SharedDefines.h:405
@ SPELL_ATTR0_ONLY_STEALTHED
Definition: SharedDefines.h:399
AuraStateType
Definition: SharedDefines.h:1288
DispelType
Definition: SharedDefines.h:1371
@ SPELL_FAILED_TARGET_NOT_LOOTED
Definition: SharedDefines.h:1070
@ SPELL_FAILED_NOT_INFRONT
Definition: SharedDefines.h:1010
@ SPELL_FAILED_MOVING
Definition: SharedDefines.h:1000
@ SPELL_FAILED_NOT_MOUNTED
Definition: SharedDefines.h:1013
@ SPELL_FAILED_AFFECTING_COMBAT
Definition: SharedDefines.h:950
@ SPELL_FAILED_CASTER_AURASTATE
Definition: SharedDefines.h:971
@ SPELL_FAILED_NOTHING_TO_DISPEL
Definition: SharedDefines.h:1035
@ SPELL_FAILED_NOT_KNOWN
Definition: SharedDefines.h:1012
@ SPELL_FAILED_FOOD_LOWLEVEL
Definition: SharedDefines.h:984
@ SPELL_FAILED_NOT_HERE
Definition: SharedDefines.h:1009
@ SPELL_FAILED_ROOTED
Definition: SharedDefines.h:1052
@ SPELL_FAILED_WRONG_PET_FOOD
Definition: SharedDefines.h:1084
@ SPELL_FAILED_CUSTOM_ERROR
Definition: SharedDefines.h:1121
@ SPELL_FAILED_SUMMON_PENDING
Definition: SharedDefines.h:1132
@ SPELL_FAILED_DAMAGE_IMMUNE
Definition: SharedDefines.h:1095
@ SPELL_FAILED_BAD_IMPLICIT_TARGETS
Definition: SharedDefines.h:960
@ SPELL_FAILED_TRY_AGAIN
Definition: SharedDefines.h:1081
@ SPELL_FAILED_NO_COMBO_POINTS
Definition: SharedDefines.h:1027
@ SPELL_FAILED_ALREADY_HAVE_SUMMON
Definition: SharedDefines.h:956
@ SPELL_FAILED_ALREADY_OPEN
Definition: SharedDefines.h:957
@ SPELL_FAILED_NOT_TRADING
Definition: SharedDefines.h:1020
@ SPELL_FAILED_NOTHING_TO_STEAL
Definition: SharedDefines.h:1036
@ SPELL_FAILED_NO_MOUNTS_ALLOWED
Definition: SharedDefines.h:1032
@ SPELL_FAILED_NOT_IN_BATTLEGROUND
Definition: SharedDefines.h:1115
@ SPELL_FAILED_NOT_BEHIND
Definition: SharedDefines.h:1006
@ SPELL_FAILED_ALREADY_HAVE_CHARM
Definition: SharedDefines.h:955
@ SPELL_FAILED_TARGET_NOT_IN_INSTANCE
Definition: SharedDefines.h:1086
@ SPELL_FAILED_HIGHLEVEL
Definition: SharedDefines.h:985
@ SPELL_FAILED_LOWLEVEL
Definition: SharedDefines.h:997
@ SPELL_FAILED_NOT_READY
Definition: SharedDefines.h:1016
@ SPELL_FAILED_ONLY_BATTLEGROUNDS
Definition: SharedDefines.h:1091
@ SPELL_FAILED_NOT_IN_ARENA
Definition: SharedDefines.h:1100
@ SPELL_FAILED_ITEM_ALREADY_ENCHANTED
Definition: SharedDefines.h:991
@ SPELL_FAILED_ONLY_STEALTHED
Definition: SharedDefines.h:1044
@ SPELL_FAILED_TARGET_IS_PLAYER_CONTROLLED
Definition: SharedDefines.h:1067
@ SPELL_FAILED_ONLY_ABOVEWATER
Definition: SharedDefines.h:1037
@ SPELL_FAILED_CANT_BE_CHARMED
Definition: SharedDefines.h:962
@ SPELL_FAILED_CASTER_DEAD
Definition: SharedDefines.h:972
@ SPELL_FAILED_NOT_ON_MOUNTED
Definition: SharedDefines.h:1104
@ SPELL_FAILED_ITEM_ENCHANT_TRADE_WINDOW
Definition: SharedDefines.h:1131
@ SPELL_FAILED_TARGET_CANNOT_BE_RESURRECTED
Definition: SharedDefines.h:1135
@ SPELL_FAILED_TARGET_UNSKINNABLE
Definition: SharedDefines.h:1075
@ SPELL_FAILED_NOT_SHAPESHIFT
Definition: SharedDefines.h:1017
@ SPELL_FAILED_UNIQUE_GLYPH
Definition: SharedDefines.h:1125
@ SPELL_FAILED_ONLY_OUTDOORS
Definition: SharedDefines.h:1042
@ SPELL_FAILED_CHARMED
Definition: SharedDefines.h:973
@ SPELL_FAILED_LINE_OF_SIGHT
Definition: SharedDefines.h:996
@ SPELL_FAILED_SPELL_IN_PROGRESS
Definition: SharedDefines.h:1054
@ SPELL_FAILED_NO_PET
Definition: SharedDefines.h:1033
@ SPELL_FAILED_NOPATH
Definition: SharedDefines.h:1005
@ SPELL_FAILED_SPELL_UNAVAILABLE
Definition: SharedDefines.h:1056
@ SPELL_FAILED_ONLY_INDOORS
Definition: SharedDefines.h:1039
@ SPELL_FAILED_NOT_ON_TAXI
Definition: SharedDefines.h:1014
@ SPELL_FAILED_TARGET_FRIENDLY
Definition: SharedDefines.h:1064
@ SPELL_ATTR4_IGNORE_DEFAULT_ARENA_RESTRICTIONS
Definition: SharedDefines.h:547
@ SPELL_ATTR4_NOT_IN_ARENA_OR_RATED_BATTLEGROUND
Definition: SharedDefines.h:546
@ SUMMON_CATEGORY_PET
Definition: SharedDefines.h:3285
@ SUMMON_CATEGORY_PUPPET
Definition: SharedDefines.h:3286
SkillType
Definition: SharedDefines.h:2863
@ SKILL_MINING
Definition: SharedDefines.h:2919
@ SKILL_HERBALISM
Definition: SharedDefines.h:2915
@ SPELL_ATTR6_ALLOW_WHILE_RIDING_VEHICLE
Definition: SharedDefines.h:616
#define sBattlefieldMgr
Definition: BattlefieldMgr.h:77
LineOfSightChecks
Definition: Map.h:189
@ LINEOFSIGHT_ALL_CHECKS
Definition: Map.h:196
@ TARGET_FLAG_UNIT_ENEMY
Definition: SpellInfo.h:53
@ TARGET_FLAG_ITEM
Definition: SpellInfo.h:50
@ SPELL_ATTR0_CU_REQ_TARGET_FACING_CASTER
Definition: SpellInfo.h:192
@ SPELL_ATTR0_CU_REQ_CASTER_BEHIND_TARGET
Definition: SpellInfo.h:193
@ SPELL_FLAG_REDIRECTED
Definition: Spell.h:85
@ AURA_INTERRUPT_FLAG_NOT_SEATED
Definition: SpellDefines.h:61
@ AURA_INTERRUPT_FLAG_MOUNT
Definition: SpellDefines.h:60
@ TRIGGERED_IGNORE_SPELL_AND_CATEGORY_CD
Will ignore GCD.
Definition: SpellDefines.h:135
@ TRIGGERED_IGNORE_CASTER_AURASTATE
Will ignore shapeshift checks.
Definition: SpellDefines.h:145
@ TRIGGERED_IGNORE_CASTER_MOUNTED_OR_ON_VEHICLE
Will ignore caster aura states including combat requirements and death state.
Definition: SpellDefines.h:146
@ TRIGGERED_IGNORE_SHAPESHIFT
Will not adjust facing to target (if any)
Definition: SpellDefines.h:144
@ TRIGGERED_IGNORE_GCD
Not triggered.
Definition: SpellDefines.h:134
@ TRIGGERED_IGNORE_EFFECTS
Periodic aura tick wont be reset on override.
Definition: SpellDefines.h:153
@ TRIGGERED_IGNORE_CASTER_AURAS
Will ignore mounted/on vehicle restrictions.
Definition: SpellDefines.h:147
std::vector< SpellImmune > SpellImmuneList
Definition: SpellDefines.h:182
@ SPELL_AURA_ABILITY_IGNORE_AURASTATE
Definition: SpellAuraDefines.h:325
@ SPELL_AURA_MOD_SHAPESHIFT
Definition: SpellAuraDefines.h:99
@ SPELL_AURA_MOD_IGNORE_SHAPESHIFT
Definition: SpellAuraDefines.h:338
@ SPELL_AURA_PERIODIC_MANA_LEECH
Definition: SpellAuraDefines.h:127
@ SPELL_AURA_MOD_POSSESS_PET
Definition: SpellAuraDefines.h:191
@ SPELL_AURA_RANGED_ATTACK_POWER_ATTACKER_BONUS
Definition: SpellAuraDefines.h:190
@ SPELL_AURA_DUMMY
Definition: SpellAuraDefines.h:67
@ SPELL_AURA_FLY
Definition: SpellAuraDefines.h:264
@ SPELL_AURA_HOVER
Definition: SpellAuraDefines.h:169
@ SPELL_AURA_MOUNTED
Definition: SpellAuraDefines.h:141
@ SPELL_AURA_AOE_CHARM
Definition: SpellAuraDefines.h:240
@ SPELL_AURA_MOD_POSSESS
Definition: SpellAuraDefines.h:65
@ SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED
Definition: SpellAuraDefines.h:270
@ SPELL_AURA_BLOCK_SPELL_FAMILY
Definition: SpellAuraDefines.h:360
#define SPELL_RELIC_COOLDOWN
Definition: SpellMgr.h:34
TradeSlots
Definition: TradeData.h:28
@ TRADE_SLOT_NONTRADED
Definition: TradeData.h:31
@ PLAYER_ALLOW_ONLY_ABILITY
Definition: Player.h:502
@ INVTYPE_RELIC
Definition: ItemTemplate.h:284
@ GO_STATE_READY
Definition: GameObjectData.h:690
#define WORLD_TRIGGER
Definition: Unit.h:37
std::list< std::pair< Aura *, uint8 > > DispelChargesList
Definition: Unit.h:77
@ MOVEMENTFLAG_FALLING_FAR
Definition: UnitDefines.h:357
@ CLASS_CONTEXT_PET
Definition: UnitDefines.h:215
@ UNIT_FLAG2_ALLOW_CHEAT_SPELLS
Definition: UnitDefines.h:285
@ UNIT_STATE_ROOT
Definition: UnitDefines.h:159
@ UNIT_STATE_CHARGING
Definition: UnitDefines.h:166
@ UNIT_FLAG_SKINNABLE
Definition: UnitDefines.h:255
@ HUNTER_PET
Definition: PetDefines.h:32
#define SPECTATOR_SPELL_BINDSIGHT
Definition: ArenaSpectator.h:38
DBCStorage< SummonPropertiesEntry > sSummonPropertiesStore(SummonPropertiesfmt)
DBCStorage< SpellShapeshiftFormEntry > sSpellShapeshiftFormStore(SpellShapeshiftFormEntryfmt)
DBCStorage< MapEntry > sMapStore(MapEntryfmt)
DBCStorage< GlyphPropertiesEntry > sGlyphPropertiesStore(GlyphPropertiesfmt)
DBCStorage< AreaTableEntry > sAreaTableStore(AreaTableEntryfmt)
@ STATUS_WAIT_LEAVE
Definition: Battleground.h:203
@ STATUS_IN_PROGRESS
Definition: Battleground.h:202
#define sConditionMgr
Definition: ConditionMgr.h:290
@ CONDITION_SOURCE_TYPE_SPELL
Definition: ConditionMgr.h:140
std::list< Condition * > ConditionList
Definition: ConditionMgr.h:237
@ PATHFIND_NOPATH
Definition: PathGenerator.h:50
@ PATHFIND_SHORT
Definition: PathGenerator.h:52
@ PATHFIND_INCOMPLETE
Definition: PathGenerator.h:49
bool IsPathfindingEnabled(const Map *map)
Definition: DisableMgr.cpp:412
Player * FindPlayer(ObjectGuid const guid)
Definition: ObjectAccessor.cpp:245
Seconds GetGameTime()
Definition: GameTime.cpp:38
Definition: Battlefield.h:204
bool CanFlyIn()
Return if we can use mount in battlefield.
Definition: Battlefield.h:340
Definition: Battleground.h:303
Definition: ConditionMgr.h:182
Condition * mLastFailedCondition
Definition: ConditionMgr.h:184
WorldObject * mConditionTargets[MAX_CONDITION_TARGETS]
Definition: ConditionMgr.h:183
uint32 ErrorType
Definition: ConditionMgr.h:205
uint8 ConditionTarget
Definition: ConditionMgr.h:209
uint32 ErrorTextId
Definition: ConditionMgr.h:206
Loot loot
Definition: Creature.h:226
CreatureTemplate const * GetCreatureTemplate() const
Definition: Creature.h:205
bool IsSpellProhibited(SpellSchoolMask idSchoolMask) const
Definition: Creature.cpp:2828
SkillType GetRequiredLootSkill() const
Definition: CreatureData.h:257
bool IsTameable(bool exotic) const
Definition: CreatureData.h:274
Definition: TemporarySummon.h:40
Definition: GameObject.h:120
GameObjectTemplate const * GetGOInfo() const
Definition: GameObject.h:136
uint32 type
Definition: GameObjectData.h:33
bool IsLocked() const
Definition: Item.h:253
ItemTemplate const * GetTemplate() const
Definition: Item.cpp:544
bool IsPotion() const
Definition: Item.h:337
uint32 ItemLevel
Definition: ItemTemplate.h:635
uint32 LockID
Definition: ItemTemplate.h:669
uint32 InventoryType
Definition: ItemTemplate.h:632
Unit * ToUnit()
Definition: Object.h:209
Map * GetMap() const
Definition: Object.h:536
InstanceScript * GetInstanceScript() const
Definition: Object.cpp:1203
bool IsWithinLOSInMap(WorldObject const *obj, VMAP::ModelIgnoreFlags ignoreFlags=VMAP::ModelIgnoreFlags::Nothing, LineOfSightChecks checks=LINEOFSIGHT_ALL_CHECKS, Optional< float > collisionHeight={ }, Optional< float > combatReach={ }) const
Definition: Object.cpp:1358
bool IsOutdoors() const
Definition: Object.cpp:3182
bool IsWithinLOS(float x, float y, float z, VMAP::ModelIgnoreFlags ignoreFlags=VMAP::ModelIgnoreFlags::Nothing, LineOfSightChecks checks=LINEOFSIGHT_ALL_CHECKS) const
Definition: Object.cpp:1337
float GetVisibilityRange() const
Definition: Object.cpp:1656
uint32 GetAreaId() const
Definition: Object.cpp:3165
uint32 GetZoneId() const
Definition: Object.cpp:3157
void GetZoneAndAreaId(uint32 &zoneid, uint32 &areaid) const
Definition: Object.cpp:3173
uint64 GetRawValue() const
Definition: ObjectGuid.h:142
bool IsPlayer() const
Definition: ObjectGuid.h:168
bool IsGameObject() const
Definition: ObjectGuid.h:171
void GetPosition(float &x, float &y) const
Definition: Position.h:121
uint32 GetMapId() const
Definition: Position.h:275
Player * GetOwner() const
Definition: Pet.cpp:2487
bool HaveInDiet(ItemTemplate const *item) const
Definition: Pet.cpp:1433
uint32 GetCurrentFoodBenefitLevel(uint32 itemlevel) const
Definition: Pet.cpp:1451
static std::pair< PetStable::PetInfo const *, PetSaveMode > GetLoadPetInfo(PetStable const &stable, uint32 petEntry, uint32 petnumber, bool current)
Definition: Pet.cpp:170
Definition: PetDefines.h:202
Optional< PetInfo > CurrentPet
Definition: PetDefines.h:225
std::vector< PetInfo > UnslottedPets
Definition: PetDefines.h:228
void SetCanTeleport(bool value)
Definition: Player.h:2498
bool IsInSameRaidWith(Player const *p) const
Definition: Player.h:1886
bool CanTameExoticPets() const
Definition: Player.h:2189
bool CanUseBattlegroundObject(GameObject *gameobject) const
Definition: Player.cpp:13254
bool InBattleground() const
Definition: Player.h:2252
PetStable * GetPetStable()
Definition: Player.h:1219
Battleground * GetBattleground(bool create=false) const
Definition: Player.cpp:12228
WorldSession * GetSession() const
Definition: Player.h:1998
bool HasSpellCooldown(uint32 spell_id) const override
Definition: Player.cpp:16364
uint32 GetLastPotionId()
Definition: Player.h:1812
Group * GetGroup()
Definition: Player.h:2468
bool IsGameMaster() const
Definition: Player.h:1175
time_t GetSummonExpireTimer() const
Definition: Player.h:1118
bool Satisfy(DungeonProgressionRequirements const *ar, uint32 target_map, bool report=false)
Definition: PlayerStorage.cpp:6706
bool HasPlayerFlag(PlayerFlags flags) const
Definition: Player.h:1125
std::unique_ptr< DuelInfo > duel
Definition: Player.h:1878
Item * GetItemByGuid(ObjectGuid guid) const
Definition: PlayerStorage.cpp:407
uint32 GetSpell() const
Definition: TradeData.h:49
bool IsVehicle() const
Definition: Unit.h:757
Vehicle * GetVehicle() const
Definition: Unit.h:1786
Unit * GetOwner() const
Definition: Unit.cpp:10600
Pet * ToPet()
Definition: Unit.h:694
virtual bool HasSpellCooldown(uint32) const
Definition: Unit.h:1260
ShapeshiftForm GetShapeshiftForm() const
Definition: Unit.h:1817
virtual bool HasSpellItemCooldown(uint32, uint32) const
Definition: Unit.h:1261
bool IsInDisallowedMountForm() const
Definition: Unit.cpp:21261
void CombatStart(Unit *target, bool initialAggro=true)
Definition: Unit.cpp:13629
bool HasUnitFlag2(UnitFlags2 flags) const
Definition: Unit.h:718
bool IsInSanctuary() const
Definition: Unit.h:980
virtual bool IsClass(Classes unitClass, ClassContext context=CLASS_CONTEXT_NONE) const
Definition: Unit.h:801
AuraEffect * IsScriptOverriden(SpellInfo const *spell, int32 script) const
Definition: Unit.cpp:5809
float GetCombatReach() const override
Definition: Unit.h:828
UnitFlags GetUnitFlags() const
Definition: Unit.h:711
TempSummon * ToTempSummon()
Definition: Unit.h:696
bool HasStealthAura() const
Definition: Unit.h:1702
bool HasAura(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemCasterGUID=ObjectGuid::Empty, uint8 reqEffMask=0) const
Definition: Unit.cpp:5698
std::map< uint8, AuraApplication * > VisibleAuraMap
Definition: Unit.h:652
bool IsInFlight() const
Definition: Unit.h:1572
SpellImmuneList m_spellImmune[MAX_SPELL_IMMUNITY]
Definition: Unit.h:1955
void SendTameFailure(uint8 result)
Definition: Unit.cpp:19999
bool HasUnitMovementFlag(uint32 f) const
Definition: Unit.h:736
virtual bool IsInWater() const
Definition: Unit.cpp:4339
bool HasAuraState(AuraStateType flag, SpellInfo const *spellProto=nullptr, Unit const *Caster=nullptr) const
Definition: Unit.cpp:10547
bool isMoving() const
Definition: Unit.h:1575
ObjectGuid GetCharmGUID() const
Definition: Unit.h:686
VisibleAuraMap const * GetVisibleAuras()
Definition: Unit.h:1412
bool IsMounted() const
Definition: Unit.h:1747
Unit * GetVictim() const
Definition: Unit.h:853
bool IsCritter() const
Definition: Unit.h:790
ObjectGuid GetOwnerGUID() const
Definition: Unit.h:678
uint8 GetComboPoints(Unit const *who=nullptr) const
Definition: Unit.h:958
ObjectGuid GetCharmerGUID() const
Definition: Unit.h:684
uint32 getTransForm() const
Definition: Unit.h:1831
virtual bool HasActivePowerType(Powers power)
Definition: Unit.h:1053
void RemoveMovementImpairingAuras(bool withRoot)
Definition: Unit.cpp:5234
bool IsTotem() const
Definition: Unit.h:756
Guardian * GetGuardianPet() const
Definition: Unit.cpp:10651
ObjectGuid GetTarget() const
Definition: Unit.h:818
bool IsInCombat() const
Definition: Unit.h:884
ObjectGuid GetPetGUID() const
Definition: Unit.h:688
Definition: Vehicle.h:28
VehicleSeatEntry const * GetSeatForPassenger(Unit const *passenger)
Definition: Vehicle.cpp:597
Definition: Group.h:169
Definition: GroupReference.h:27
GroupReference * next()
Definition: GroupReference.h:36
Definition: InstanceScript.h:142
bool isLooted() const
Definition: LootMgr.h:368
Definition: Map.h:272
bool AllowMount
Definition: Map.h:275
bool IsDungeon() const
Definition: Map.h:446
bool IsBattlegroundOrArena() const
Definition: Map.h:454
GameObject * GetGameObject(ObjectGuid const guid)
Definition: Map.cpp:3322
uint32 GetId() const
Definition: Map.h:377
Difficulty GetDifficulty() const
Definition: Map.h:441
uint32 GetRecruiterId() const
Definition: WorldSession.h:526
uint32 GetAccountId() const
Definition: WorldSession.h:361
GameObject * GetGOTarget() const
Definition: Spell.cpp:264
ObjectGuid GetItemTargetGUID() const
Definition: Spell.h:140
std::unique_ptr< PathGenerator > m_preGeneratedPath
Definition: Spell.h:780
SpellCastResult CheckSpellFocus()
Definition: Spell.cpp:7751
SpellCastResult CanOpenLock(uint32 effIndex, uint32 lockid, SkillType &skillid, int32 &reqSkillValue, int32 &skillValue)
Definition: Spell.cpp:8363
SpellCastResult CheckItems()
Definition: Spell.cpp:7183
int32 CalculateSpellDamage(uint8 i, Unit const *target) const
Definition: Spell.h:480
SpellCastResult CheckPower()
Definition: Spell.cpp:7138
SpellCastResult CheckCasterAuras(bool preventionOnly) const
Definition: Spell.cpp:6855
SpellCastResult CallScriptCheckCastHandlers()
Definition: Spell.cpp:8571
bool IsTriggered() const
Definition: Spell.h:556
SpellCastResult CheckRange(bool strict)
Definition: Spell.cpp:7052
bool HasGlobalCooldown() const
Definition: Spell.cpp:8843
Definition: SpellInfo.h:249
int32 MiscValue
Definition: SpellInfo.h:263
uint32 ApplyAuraName
Definition: SpellInfo.h:254
uint32 PreventionType
Definition: SpellInfo.h:390
uint32 CasterAuraSpell
Definition: SpellInfo.h:343
SpellCastResult CheckShapeshift(uint32 form) const
Definition: SpellInfo.cpp:1434
uint32 Mechanic
Definition: SpellInfo.h:323
uint32 GetDispelMask() const
Definition: SpellInfo.cpp:2041
uint32 GetRecoveryTime() const
Definition: SpellInfo.cpp:2396
bool IsSelfCast() const
Definition: SpellInfo.cpp:1090
uint32 CasterAuraState
Definition: SpellInfo.h:339
bool CanBeUsedInCombat() const
Definition: SpellInfo.cpp:1232
uint32 CasterAuraStateNot
Definition: SpellInfo.h:341
SpellCastResult CheckLocation(uint32 map_id, uint32 zone_id, uint32 area_id, Player *player=nullptr, bool strict=true) const
Definition: SpellInfo.cpp:1489
SpellSchoolMask GetSchoolMask() const
Definition: SpellInfo.cpp:1987
int32 AreaGroupId
Definition: SpellInfo.h:391
float GetMaxRange(bool positive=false, Unit *caster=nullptr, Spell *spell=nullptr) const
Definition: SpellInfo.cpp:2323
uint32 GetExplicitTargetMask() const
Definition: SpellInfo.cpp:2055
bool NeedsExplicitUnitTarget() const
Definition: SpellInfo.cpp:1033
uint32 ExcludeCasterAuraSpell
Definition: SpellInfo.h:345
uint32 SpellFamilyName
Definition: SpellInfo.h:387
uint32 AuraInterruptFlags
Definition: SpellInfo.h:353
SpellCastResult CheckExplicitTarget(Unit const *caster, WorldObject const *target, Item const *itemTarget=nullptr) const
Definition: SpellInfo.cpp:1937
Definition: DBCStructure.h:518
Definition: DBCStructure.h:1020
Definition: DBCStructure.h:1324
bool IsDungeon() const
Definition: DBCStructure.h:1350
Definition: DBCStructure.h:1816
uint32 flags1
Definition: DBCStructure.h:1821
Definition: DBCStructure.h:1908
uint32 Category
Definition: DBCStructure.h:1910
Definition: DBCStructure.h:2063
uint32 m_flags
Definition: DBCStructure.h:2065

References InstanceTemplate::AllowMount, SpellEffectInfo::ApplyAuraName, AREA_FLAG_NO_FLY_ZONE, SpellInfo::AreaGroupId, AURA_INTERRUPT_FLAG_MOUNT, AURA_INTERRUPT_FLAG_NOT_SEATED, SpellInfo::AuraInterruptFlags, CalculateSpellDamage(), CallScriptCheckCastHandlers(), SpellInfo::CanBeUsedInCombat(), Battlefield::CanFlyIn(), CanOpenLock(), Player::CanTameExoticPets(), Player::CanUseBattlegroundObject(), SpellInfo::CasterAuraSpell, SpellInfo::CasterAuraState, SpellInfo::CasterAuraStateNot, SummonPropertiesEntry::Category, CheckCasterAuras(), SpellInfo::CheckExplicitTarget(), CheckItems(), SpellInfo::CheckLocation(), CheckPower(), CheckRange(), SpellInfo::CheckShapeshift(), CheckSpellFocus(), SpellInfo::CheckTarget(), CLASS_CONTEXT_PET, CLASS_WARLOCK, Unit::CombatStart(), CONDITION_SOURCE_TYPE_SPELL, Condition::ConditionTarget, PetStable::CurrentPet, damage, Player::duel, EFFECT_0, SpellInfo::Effects, Condition::ErrorTextId, Condition::ErrorType, SpellInfo::ExcludeCasterAuraSpell, WorldObject::FindMap(), ObjectAccessor::FindPlayer(), SpellShapeshiftFormEntry::flags1, GAMEOBJECT_TYPE_DOOR, GAMEOBJECT_TYPE_TRAP, WorldSession::GetAccountId(), WorldObject::GetAreaId(), Unit::GetAuraEffectsByType(), Player::GetBattleground(), Unit::GetCharm(), Unit::GetCharmerGUID(), Unit::GetCharmGUID(), Unit::GetCombatReach(), Unit::GetComboPoints(), Creature::GetCreatureTemplate(), Pet::GetCurrentFoodBenefitLevel(), Map::GetDifficulty(), SpellInfo::GetDispelMask(), WorldObject::GetDistance(), SpellCastTargets::GetDstPos(), Object::GetEntry(), SpellInfo::GetExplicitTargetMask(), Map::GetGameObject(), GameTime::GetGameTime(), GameObject::GetGOInfo(), SpellCastTargets::GetGOTarget(), Player::GetGroup(), Unit::GetGuardianPet(), Map::GetId(), WorldObject::GetInstanceScript(), Player::GetItemByGuid(), SpellCastTargets::GetItemTarget(), SpellCastTargets::GetItemTargetGUID(), Player::GetLastPotionId(), Unit::GetLevel(), Pet::GetLoadPetInfo(), WorldObject::GetMap(), WorldLocation::GetMapId(), SpellInfo::GetMaxRange(), SpellCastTargets::GetObjectTarget(), Pet::GetOwner(), Player::GetPet(), Unit::GetPetGUID(), Player::GetPetStable(), Position::GetPosition(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), ObjectGuid::GetRawValue(), SpellInfo::GetRecoveryTime(), WorldSession::GetRecruiterId(), CreatureTemplate::GetRequiredLootSkill(), SpellInfo::GetSchoolMask(), Vehicle::GetSeatForPassenger(), Player::GetSession(), Unit::GetShapeshiftForm(), Player::GetSkillValue(), TradeData::GetSpell(), Player::GetSummonExpireTimer(), Unit::GetTarget(), SpellCastTargets::GetTargetMask(), Item::GetTemplate(), Player::GetTradeData(), Unit::getTransForm(), Unit::GetUnitFlags(), SpellCastTargets::GetUnitTarget(), Unit::GetVehicle(), Unit::GetVictim(), WorldObject::GetVisibilityRange(), Unit::GetVisibleAuras(), WorldObject::GetZoneAndAreaId(), WorldObject::GetZoneId(), GO_STATE_READY, Unit::HasActivePowerType(), SpellInfo::HasAttribute(), SpellInfo::HasAura(), Unit::HasAura(), Unit::HasAuraState(), SpellCastTargets::HasDst(), SpellInfo::HasEffect(), HasGlobalCooldown(), Player::HasPlayerFlag(), Player::HasSpellCooldown(), Unit::HasSpellCooldown(), Unit::HasSpellItemCooldown(), Unit::HasStealthAura(), HasTriggeredCastFlag(), Unit::HasUnitFlag2(), Unit::HasUnitMovementFlag(), Unit::HasUnitState(), Pet::HaveInDiet(), HUNTER_PET, SpellInfo::Id, IMMUNITY_MECHANIC, IN_MILLISECONDS, Player::InBattleground(), ItemTemplate::InventoryType, INVTYPE_RELIC, irand(), Unit::IsAlive(), IsAutoRepeat(), Map::IsBattlegroundOrArena(), Unit::IsClass(), SpellInfo::IsCooldownStartedOnEvent(), Object::IsCreature(), Unit::IsCritter(), Map::IsDungeon(), MapEntry::IsDungeon(), Unit::IsFriendlyTo(), Player::IsGameMaster(), ObjectGuid::IsGameObject(), Unit::IsInCombat(), Unit::IsInDisallowedMountForm(), Unit::IsInFlight(), Player::IsInSameRaidWith(), Unit::IsInSanctuary(), Unit::IsInWater(), Item::IsLocked(), Loot::isLooted(), Unit::IsMounted(), Unit::isMoving(), IsNextMeleeSwingSpell(), WorldObject::IsOutdoors(), SpellInfo::IsPassive(), DisableMgr::IsPathfindingEnabled(), Object::IsPlayer(), SpellInfo::IsPositive(), Item::IsPotion(), Unit::IsScriptOverriden(), SpellInfo::IsSelfCast(), Creature::IsSpellProhibited(), CreatureTemplate::IsTameable(), Unit::IsTotem(), IsTriggered(), WorldObject::IsWithinLOS(), WorldObject::IsWithinLOSInMap(), ItemTemplate::ItemLevel, LINEOFSIGHT_ALL_CHECKS, ItemTemplate::LockID, Creature::loot, VMAP::M2, m_caster, m_CastItem, m_customError, VehicleSeatEntry::m_flags, m_needComboPoints, m_originalCaster, m_originalCasterGUID, m_preGeneratedPath, m_selfContainer, m_spellFlags, Unit::m_spellImmune, m_spellInfo, m_targets, m_triggeredByAuraSpell, MAX_SPELL_EFFECTS, ConditionSourceInfo::mConditionTargets, SpellInfo::Mechanic, MINUTE, SpellEffectInfo::MiscValue, ConditionSourceInfo::mLastFailedCondition, MOVEMENTFLAG_FALLING_FAR, SpellInfo::NeedsExplicitUnitTarget(), GroupReference::next(), PATHFIND_INCOMPLETE, PATHFIND_NOPATH, PATHFIND_SHORT, PET_TAME_CANT_CONTROL_EXOTIC, PET_TAME_DEAD, PET_TAME_NOPET_AVAILABLE, PLAYER_ALLOW_ONLY_ABILITY, POWER_MANA, SpellInfo::PreventionType, Unit::RemoveMovementImpairingAuras(), sAreaTableStore, Player::Satisfy(), sBattlefieldMgr, sConditionMgr, Unit::SendTameFailure(), sGlyphPropertiesStore, SKILL_HERBALISM, SKILL_LOCKPICKING, SKILL_MINING, SKILL_NONE, sMapStore, sObjectMgr, SPECTATOR_SPELL_BINDSIGHT, SPELL_ATTR0_ALLOW_CAST_WHILE_DEAD, SPELL_ATTR0_ALLOW_WHILE_MOUNTED, SPELL_ATTR0_AURA_IS_DEBUFF, SPELL_ATTR0_CU_REQ_CASTER_BEHIND_TARGET, SPELL_ATTR0_CU_REQ_TARGET_FACING_CASTER, SPELL_ATTR0_NO_IMMUNITIES, SPELL_ATTR0_ONLY_INDOORS, SPELL_ATTR0_ONLY_OUTDOORS, SPELL_ATTR0_ONLY_STEALTHED, SPELL_ATTR0_PASSIVE, SPELL_ATTR1_DISMISS_PET_FIRST, SPELL_ATTR1_INITIATE_COMBAT, SPELL_ATTR2_IGNORE_LINE_OF_SIGHT, SPELL_ATTR3_ONLY_BATTLEGROUNDS, SPELL_ATTR4_IGNORE_DEFAULT_ARENA_RESTRICTIONS, SPELL_ATTR4_NOT_IN_ARENA_OR_RATED_BATTLEGROUND, SPELL_ATTR5_ALWAYS_AOE_LINE_OF_SIGHT, SPELL_ATTR6_ALLOW_WHILE_RIDING_VEHICLE, SPELL_ATTR7_DEBUG_SPELL, SPELL_AURA_ABILITY_IGNORE_AURASTATE, SPELL_AURA_AOE_CHARM, SPELL_AURA_BLOCK_SPELL_FAMILY, SPELL_AURA_DUMMY, SPELL_AURA_FLY, SPELL_AURA_HOVER, SPELL_AURA_MOD_CHARM, SPELL_AURA_MOD_IGNORE_SHAPESHIFT, SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED, SPELL_AURA_MOD_POSSESS, SPELL_AURA_MOD_POSSESS_PET, SPELL_AURA_MOD_SHAPESHIFT, SPELL_AURA_MOUNTED, SPELL_AURA_PERIODIC_MANA_LEECH, SPELL_AURA_RANGED_ATTACK_POWER_ATTACKER_BONUS, SPELL_CAST_OK, SPELL_CUSTOM_ERROR_GM_ONLY, SPELL_EFFECT_APPLY_GLYPH, SPELL_EFFECT_CHARGE, SPELL_EFFECT_CREATE_TAMED_PET, SPELL_EFFECT_DISPEL, SPELL_EFFECT_FEED_PET, SPELL_EFFECT_JUMP, SPELL_EFFECT_JUMP_DEST, SPELL_EFFECT_LEAP, SPELL_EFFECT_LEAP_BACK, SPELL_EFFECT_LEARN_PET_SPELL, SPELL_EFFECT_LEARN_SPELL, SPELL_EFFECT_OPEN_LOCK, SPELL_EFFECT_POWER_BURN, SPELL_EFFECT_POWER_DRAIN, SPELL_EFFECT_RESURRECT, SPELL_EFFECT_RESURRECT_NEW, SPELL_EFFECT_RESURRECT_PET, SPELL_EFFECT_SKINNING, SPELL_EFFECT_STEAL_BENEFICIAL_BUFF, SPELL_EFFECT_STUCK, SPELL_EFFECT_SUMMON, SPELL_EFFECT_SUMMON_PET, SPELL_EFFECT_SUMMON_PLAYER, SPELL_EFFECT_SUMMON_RAF_FRIEND, SPELL_EFFECT_TALENT_SPEC_SELECT, SPELL_EFFECT_TELEPORT_UNITS_FACE_CASTER, SPELL_FAILED_AFFECTING_COMBAT, SPELL_FAILED_ALREADY_HAVE_CHARM, SPELL_FAILED_ALREADY_HAVE_SUMMON, SPELL_FAILED_ALREADY_OPEN, SPELL_FAILED_BAD_IMPLICIT_TARGETS, SPELL_FAILED_BAD_TARGETS, SPELL_FAILED_CANT_BE_CHARMED, SPELL_FAILED_CASTER_AURASTATE, SPELL_FAILED_CASTER_DEAD, SPELL_FAILED_CHARMED, SPELL_FAILED_CUSTOM_ERROR, SPELL_FAILED_DAMAGE_IMMUNE, SPELL_FAILED_DONT_REPORT, SPELL_FAILED_FOOD_LOWLEVEL, SPELL_FAILED_HIGHLEVEL, SPELL_FAILED_ITEM_ALREADY_ENCHANTED, SPELL_FAILED_ITEM_ENCHANT_TRADE_WINDOW, SPELL_FAILED_LINE_OF_SIGHT, SPELL_FAILED_LOW_CASTLEVEL, SPELL_FAILED_LOWLEVEL, SPELL_FAILED_MOVING, SPELL_FAILED_NO_COMBO_POINTS, SPELL_FAILED_NO_MOUNTS_ALLOWED, SPELL_FAILED_NO_PET, SPELL_FAILED_NOPATH, SPELL_FAILED_NOT_BEHIND, SPELL_FAILED_NOT_HERE, SPELL_FAILED_NOT_IN_ARENA, SPELL_FAILED_NOT_IN_BATTLEGROUND, SPELL_FAILED_NOT_INFRONT, SPELL_FAILED_NOT_KNOWN, SPELL_FAILED_NOT_MOUNTED, SPELL_FAILED_NOT_ON_MOUNTED, SPELL_FAILED_NOT_ON_TAXI, SPELL_FAILED_NOT_READY, SPELL_FAILED_NOT_SHAPESHIFT, SPELL_FAILED_NOT_TRADING, SPELL_FAILED_NOTHING_TO_DISPEL, SPELL_FAILED_NOTHING_TO_STEAL, SPELL_FAILED_ONLY_ABOVEWATER, SPELL_FAILED_ONLY_BATTLEGROUNDS, SPELL_FAILED_ONLY_INDOORS, SPELL_FAILED_ONLY_OUTDOORS, SPELL_FAILED_ONLY_STEALTHED, SPELL_FAILED_ROOTED, SPELL_FAILED_SPELL_IN_PROGRESS, SPELL_FAILED_SPELL_UNAVAILABLE, SPELL_FAILED_SUMMON_PENDING, SPELL_FAILED_TARGET_CANNOT_BE_RESURRECTED, SPELL_FAILED_TARGET_FRIENDLY, SPELL_FAILED_TARGET_IS_PLAYER_CONTROLLED, SPELL_FAILED_TARGET_NOT_IN_INSTANCE, SPELL_FAILED_TARGET_NOT_LOOTED, SPELL_FAILED_TARGET_UNSKINNABLE, SPELL_FAILED_TRY_AGAIN, SPELL_FAILED_UNIQUE_GLYPH, SPELL_FAILED_WRONG_PET_FOOD, SPELL_FLAG_REDIRECTED, SPELL_PREVENTION_TYPE_NONE, SPELL_RELIC_COOLDOWN, SPELLFAMILY_WARRIOR, SpellInfo::SpellFamilyName, TriggeredByAuraSpellData::spellInfo, SpellInfo::SpellLevel, sScriptMgr, sSpellMgr, sSpellShapeshiftFormStore, sSummonPropertiesStore, STATUS_IN_PROGRESS, STATUS_WAIT_LEAVE, SUMMON_CATEGORY_PET, SUMMON_CATEGORY_PUPPET, TARGET_FLAG_ITEM, TARGET_FLAG_TRADE_ITEM, TARGET_FLAG_UNIT_ENEMY, TARGET_GAMEOBJECT_ITEM_TARGET, TARGET_GAMEOBJECT_TARGET, TARGET_UNIT_PET, Object::ToCreature(), Unit::ToPet(), Object::ToPlayer(), Unit::ToTempSummon(), Object::ToUnit(), TRADE_SLOT_NONTRADED, TRIGGERED_IGNORE_CASTER_AURAS, TRIGGERED_IGNORE_CASTER_AURASTATE, TRIGGERED_IGNORE_CASTER_MOUNTED_OR_ON_VEHICLE, TRIGGERED_IGNORE_EFFECTS, TRIGGERED_IGNORE_GCD, TRIGGERED_IGNORE_POWER_AND_REAGENT_COST, TRIGGERED_IGNORE_SHAPESHIFT, TRIGGERED_IGNORE_SPELL_AND_CATEGORY_CD, GameObjectTemplate::type, UNIT_FLAG2_ALLOW_CHEAT_SPELLS, UNIT_FLAG_SKINNABLE, UNIT_STATE_CHARGING, UNIT_STATE_ROOT, unitTarget, PetStable::UnslottedPets, VEHICLE_SEAT_FLAG_CAN_ATTACK, VEHICLE_SEAT_FLAG_CAN_CAST_MOUNT_SPELL, VEHICLE_SEAT_FLAG_UNCONTROLLED, and WORLD_TRIGGER.

Referenced by _cast(), Unit::_UpdateAutoRepeatSpell(), Unit::AttackerStateUpdate(), Player::CastItemUseSpell(), CheckPetCast(), WorldSession::HandleAcceptTradeOpcode(), prepare(), and go_wind_stone::go_wind_stoneAI::SummonNPC().

◆ CheckCasterAuras()

SpellCastResult Spell::CheckCasterAuras ( bool  preventionOnly) const
6856{
6857 // spells totally immuned to caster auras (wsg flag drop, give marks etc)
6859 return SPELL_CAST_OK;
6860
6861 uint8 school_immune = 0;
6862 uint32 mechanic_immune = 0;
6863 uint32 dispel_immune = 0;
6864
6865 // Check if the spell grants school or mechanic immunity.
6866 // We use bitmasks so the loop is done only once and not on every aura check below.
6868 {
6869 for (int i = 0; i < MAX_SPELL_EFFECTS; ++i)
6870 {
6871 if (m_spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_SCHOOL_IMMUNITY)
6872 school_immune |= uint32(m_spellInfo->Effects[i].MiscValue);
6873 else if (m_spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_MECHANIC_IMMUNITY)
6874 mechanic_immune |= 1 << uint32(m_spellInfo->Effects[i].MiscValue);
6875 else if (m_spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_DISPEL_IMMUNITY)
6876 dispel_immune |= SpellInfo::GetDispelMask(DispelType(m_spellInfo->Effects[i].MiscValue));
6877 }
6878 // immune movement impairment and loss of control
6879 // PVP trinket EMFH TOC PVP trinket Bullheaded Bestial Wrath // Beath Within // Medalion of Immunity
6880 if (m_spellInfo->Id == 42292 || m_spellInfo->Id == 59752 || m_spellInfo->Id == 65547 || m_spellInfo->Id == 53490 || m_spellInfo->Id == 19574 || m_spellInfo->Id == 34471 || m_spellInfo->Id == 46227)
6882 }
6883
6885
6886 // Glyph of Pain Suppression
6887 // there is no other way to handle it
6888 if (m_spellInfo->Id == 33206 && !m_caster->HasAura(63248))
6889 usableInStun = false;
6890
6891 // Check whether the cast should be prevented by any state you might have.
6892 SpellCastResult prevented_reason = SPELL_CAST_OK;
6893 // Have to check if there is a stun aura. Otherwise will have problems with ghost aura apply while logging out
6894 uint32 unitflag = m_caster->GetUnitFlags(); // Get unit state
6895
6896 // Xinef: if spell is triggered check preventionType only
6897 if (!preventionOnly)
6898 {
6899 if (unitflag & UNIT_FLAG_STUNNED)
6900 {
6901 // spell is usable while stunned, check if caster has only mechanic stun auras, another stun types must prevent cast spell
6902 if (usableInStun)
6903 {
6904 bool foundNotStun = false;
6905 uint32 mask = (1 << MECHANIC_STUN) | (1 << MECHANIC_FREEZE) | (1 << MECHANIC_HORROR);
6906 // Barkskin should skip sleep effects, sap and fears
6907 if (m_spellInfo->Id == 22812)
6908 mask |= 1 << MECHANIC_SAPPED | 1 << MECHANIC_HORROR | 1 << MECHANIC_SLEEP;
6909 // Hand of Freedom, can be used while sapped
6910 if (m_spellInfo->Id == 1044)
6911 mask |= 1 << MECHANIC_SAPPED;
6913 for (Unit::AuraEffectList::const_iterator i = stunAuras.begin(); i != stunAuras.end(); ++i)
6914 {
6915 if ((*i)->GetSpellInfo()->GetAllEffectsMechanicMask() && !((*i)->GetSpellInfo()->GetAllEffectsMechanicMask() & mask))
6916 {
6917 foundNotStun = true;
6918 break;
6919 }
6920 }
6921 if (foundNotStun)
6922 prevented_reason = SPELL_FAILED_STUNNED;
6923 }
6924 else
6925 prevented_reason = SPELL_FAILED_STUNNED;
6926 }
6928 prevented_reason = SPELL_FAILED_CONFUSED;
6930 prevented_reason = SPELL_FAILED_FLEEING;
6931 }
6932
6933 // Xinef: if there is no prevented_reason, check prevention types
6934 if (prevented_reason == SPELL_CAST_OK)
6935 {
6937 prevented_reason = SPELL_FAILED_SILENCED;
6939 prevented_reason = SPELL_FAILED_PACIFIED;
6940 }
6941
6942 // Attr must make flag drop spell totally immune from all effects
6943 if (prevented_reason != SPELL_CAST_OK)
6944 {
6945 if (school_immune || mechanic_immune || dispel_immune)
6946 {
6947 //Checking auras is needed now, because you are prevented by some state but the spell grants immunity.
6949 for (Unit::AuraApplicationMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
6950 {
6951 Aura const* aura = itr->second->GetBase();
6952 SpellInfo const* auraInfo = aura->GetSpellInfo();
6953 if (auraInfo->GetAllEffectsMechanicMask() & mechanic_immune)
6954 continue;
6955 if (auraInfo->GetSchoolMask() & school_immune && !auraInfo->HasAttribute(SPELL_ATTR1_IMMUNITY_TO_HOSTILE_AND_FRIENDLY_EFFECTS))
6956 continue;
6957 if (auraInfo->GetDispelMask() & dispel_immune)
6958 continue;
6959
6960 //Make a second check for spell failed so the right SPELL_FAILED message is returned.
6961 //That is needed when your casting is prevented by multiple states and you are only immune to some of them.
6962 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
6963 {
6964 if (AuraEffect* part = aura->GetEffect(i))
6965 {
6966 switch (part->GetAuraType())
6967 {
6969 {
6970 uint32 mask = 1 << MECHANIC_STUN;
6971 // Barkskin should skip sleep effects, sap and fears
6972 if (m_spellInfo->Id == 22812)
6973 mask |= 1 << MECHANIC_SAPPED | 1 << MECHANIC_HORROR | 1 << MECHANIC_SLEEP;
6974 // Hand of Freedom, can be used while sapped
6975 if (m_spellInfo->Id == 1044)
6976 mask |= 1 << MECHANIC_SAPPED;
6977
6978 if (!usableInStun || !(auraInfo->GetAllEffectsMechanicMask() & mask))
6979 return SPELL_FAILED_STUNNED;
6980 break;
6981 }
6984 return SPELL_FAILED_CONFUSED;
6985 break;
6988 return SPELL_FAILED_FLEEING;
6989 break;
6994 return SPELL_FAILED_PACIFIED;
6996 return SPELL_FAILED_SILENCED;
6997 break;
6998 default:
6999 break;
7000 }
7001 }
7002 }
7003 }
7004 }
7005 // You are prevented from casting and the spell casted does not grant immunity. Return a failed error.
7006 else
7007 return prevented_reason;
7008 }
7009 return SPELL_CAST_OK;
7010}
@ SPELL_PREVENTION_TYPE_SILENCE
Definition: SharedDefines.h:1554
@ SPELL_PREVENTION_TYPE_PACIFY
Definition: SharedDefines.h:1555
@ SPELL_ATTR5_ALLOW_WHILE_STUNNED
Definition: SharedDefines.h:570
@ SPELL_ATTR5_ALLOW_WHILE_FLEEING
Definition: SharedDefines.h:584
@ SPELL_ATTR5_ALLOW_WHILE_CONFUSED
Definition: SharedDefines.h:585
@ SPELL_ATTR1_IMMUNITY_PURGES_EFFECT
Definition: SharedDefines.h:434
@ SPELL_ATTR1_IMMUNITY_TO_HOSTILE_AND_FRIENDLY_EFFECTS
Definition: SharedDefines.h:435
@ MECHANIC_STUN
Definition: SharedDefines.h:1337
@ MECHANIC_FREEZE
Definition: SharedDefines.h:1338
@ MECHANIC_SLEEP
Definition: SharedDefines.h:1335
@ MECHANIC_SAPPED
Definition: SharedDefines.h:1355
@ MECHANIC_HORROR
Definition: SharedDefines.h:1349
#define IMMUNE_TO_MOVEMENT_IMPAIRMENT_AND_LOSS_CONTROL_MASK
Definition: SharedDefines.h:1361
@ SPELL_FAILED_STUNNED
Definition: SharedDefines.h:1057
@ SPELL_FAILED_CONFUSED
Definition: SharedDefines.h:975
@ SPELL_FAILED_SILENCED
Definition: SharedDefines.h:1053
@ SPELL_FAILED_FLEEING
Definition: SharedDefines.h:983
@ SPELL_FAILED_PACIFIED
Definition: SharedDefines.h:1047
@ SPELL_ATTR6_NOT_AN_ATTACK
Definition: SharedDefines.h:606
@ SPELL_AURA_DISPEL_IMMUNITY
Definition: SpellAuraDefines.h:104
@ SPELL_AURA_MOD_FEAR
Definition: SpellAuraDefines.h:70
@ SPELL_AURA_MOD_PACIFY
Definition: SpellAuraDefines.h:88
@ SPELL_AURA_MOD_SILENCE
Definition: SpellAuraDefines.h:90
@ SPELL_AURA_SCHOOL_IMMUNITY
Definition: SpellAuraDefines.h:102
@ SPELL_AURA_MECHANIC_IMMUNITY
Definition: SpellAuraDefines.h:140
@ SPELL_AURA_MOD_PACIFY_SILENCE
Definition: SpellAuraDefines.h:123
@ SPELL_AURA_MOD_CONFUSE
Definition: SpellAuraDefines.h:68
@ SPELL_AURA_MOD_STUN
Definition: SpellAuraDefines.h:75
@ UNIT_FLAG_STUNNED
Definition: UnitDefines.h:247
@ UNIT_FLAG_PACIFIED
Definition: UnitDefines.h:246
@ UNIT_FLAG_CONFUSED
Definition: UnitDefines.h:251
@ UNIT_FLAG_FLEEING
Definition: UnitDefines.h:252
@ UNIT_FLAG_SILENCED
Definition: UnitDefines.h:242
std::multimap< uint32, AuraApplication * > AuraApplicationMap
Definition: Unit.h:639
AuraApplicationMap & GetAppliedAuras()
Definition: Unit.h:1304
Definition: SpellAuras.h:87
AuraEffect * GetEffect(uint8 effIndex) const
Definition: SpellAuras.h:175
SpellInfo const * GetSpellInfo() const
Definition: SpellAuras.h:100
uint32 GetAllEffectsMechanicMask() const
Definition: SpellInfo.cpp:1992

References SpellInfo::Effects, SpellInfo::GetAllEffectsMechanicMask(), Unit::GetAppliedAuras(), Unit::GetAuraEffectsByType(), SpellInfo::GetDispelMask(), Aura::GetEffect(), SpellInfo::GetSchoolMask(), Aura::GetSpellInfo(), Unit::GetUnitFlags(), SpellInfo::HasAttribute(), Unit::HasAura(), SpellInfo::Id, IMMUNE_TO_MOVEMENT_IMPAIRMENT_AND_LOSS_CONTROL_MASK, m_caster, m_spellInfo, MAX_SPELL_EFFECTS, MECHANIC_FREEZE, MECHANIC_HORROR, MECHANIC_SAPPED, MECHANIC_SLEEP, MECHANIC_STUN, SpellInfo::PreventionType, SPELL_ATTR1_IMMUNITY_PURGES_EFFECT, SPELL_ATTR1_IMMUNITY_TO_HOSTILE_AND_FRIENDLY_EFFECTS, SPELL_ATTR5_ALLOW_WHILE_CONFUSED, SPELL_ATTR5_ALLOW_WHILE_FLEEING, SPELL_ATTR5_ALLOW_WHILE_STUNNED, SPELL_ATTR6_NOT_AN_ATTACK, SPELL_AURA_DISPEL_IMMUNITY, SPELL_AURA_MECHANIC_IMMUNITY, SPELL_AURA_MOD_CONFUSE, SPELL_AURA_MOD_FEAR, SPELL_AURA_MOD_PACIFY, SPELL_AURA_MOD_PACIFY_SILENCE, SPELL_AURA_MOD_SILENCE, SPELL_AURA_MOD_STUN, SPELL_AURA_SCHOOL_IMMUNITY, SPELL_CAST_OK, SPELL_FAILED_CONFUSED, SPELL_FAILED_FLEEING, SPELL_FAILED_PACIFIED, SPELL_FAILED_SILENCED, SPELL_FAILED_STUNNED, SPELL_PREVENTION_TYPE_PACIFY, SPELL_PREVENTION_TYPE_SILENCE, UNIT_FLAG_CONFUSED, UNIT_FLAG_FLEEING, UNIT_FLAG_PACIFIED, UNIT_FLAG_SILENCED, and UNIT_FLAG_STUNNED.

Referenced by CheckCast().

◆ CheckDst()

void Spell::CheckDst ( )
inline
void SetDst(float x, float y, float z, float orientation, uint32 mapId=MAPID_INVALID)
Definition: Spell.cpp:406

References SpellCastTargets::HasDst(), m_caster, m_targets, and SpellCastTargets::SetDst().

Referenced by SelectEffectImplicitTargets(), and SelectImplicitDestDestTargets().

◆ CheckEffectExecuteData()

void Spell::CheckEffectExecuteData ( )
protected
8505{
8506 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
8508}
#define ASSERT
Definition: Errors.h:68

References ASSERT, m_effectExecuteData, and MAX_SPELL_EFFECTS.

Referenced by PrepareTargetProcessing(), and ~Spell().

◆ CheckEffectTarget()

bool Spell::CheckEffectTarget ( Unit const *  target,
uint32  eff 
) const
Todo:
: below shouldn't be here, but it's temporary
7929{
7930 switch (m_spellInfo->Effects[eff].ApplyAuraName)
7931 {
7936 if (target->IsCreature() && target->IsVehicle())
7937 return false;
7938 if (target->IsMounted())
7939 return false;
7940 if (target->GetCharmerGUID())
7941 return false;
7942 if (int32 damage = CalculateSpellDamage(eff, target))
7943 if ((int32)target->GetLevel() > damage)
7944 return false;
7945 break;
7946 default:
7947 break;
7948 }
7949
7950 // xinef: skip los checking if spell has appropriate attribute, or target requires specific entry
7951 // this is only for target addition and target has to have unselectable flag, this is valid for FLAG_EXTRA_TRIGGER and quest triggers however there are some without this flag, used not_selectable
7952 if (m_spellInfo->HasAttribute(SPELL_ATTR2_IGNORE_LINE_OF_SIGHT) || (target->IsCreature() && target->HasUnitFlag(UNIT_FLAG_NOT_SELECTABLE) && (m_spellInfo->Effects[eff].TargetA.GetCheckType() == TARGET_CHECK_ENTRY || m_spellInfo->Effects[eff].TargetB.GetCheckType() == TARGET_CHECK_ENTRY)))
7953 return true;
7954
7955 // if spell is triggered, need to check for LOS disable on the aura triggering it and inherit that behaviour
7958 {
7959 return true;
7960 }
7961
7963 //Check targets for LOS visibility (except spells without range limitations)
7964 switch (m_spellInfo->Effects[eff].Effect)
7965 {
7967 // player far away, maybe his corpse near?
7968 if (target != m_caster && !target->IsWithinLOSInMap(m_caster))
7969 {
7971 return false;
7972
7974 if (!corpse)
7975 return false;
7976
7977 if (target->GetGUID() != corpse->GetOwnerGUID())
7978 return false;
7979
7981 return false;
7982 }
7983 break;
7985 {
7987 {
7988 if (target->IsWithinLOSInMap(m_caster, VMAP::ModelIgnoreFlags::M2) && target->HasUnitFlag(UNIT_FLAG_SKINNABLE))
7989 return true;
7990
7991 return false;
7992 }
7993
7995 if (!corpse)
7996 return false;
7997
7998 if (target->GetGUID() != corpse->GetOwnerGUID())
7999 return false;
8000
8002 return false;
8003
8005 return false;
8006 }
8007 break;
8009 if (!m_caster->IsPlayer() || !target->IsPlayer())
8010 return false;
8011 if (m_caster->ToPlayer()->GetSession()->IsARecruiter() && target->ToPlayer()->GetSession()->GetRecruiterId() != m_caster->ToPlayer()->GetSession()->GetAccountId())
8012 return false;
8013 if (m_caster->ToPlayer()->GetSession()->GetRecruiterId() != target->ToPlayer()->GetSession()->GetAccountId() && target->ToPlayer()->GetSession()->IsARecruiter())
8014 return false;
8015 if (target->ToPlayer()->GetLevel() >= sWorld->getIntConfig(CONFIG_MAX_RECRUIT_A_FRIEND_BONUS_PLAYER_LEVEL))
8016 return false;
8017 break;
8018 default: // normal case
8019 {
8020 uint32 losChecks = LINEOFSIGHT_ALL_CHECKS;
8021 GameObject* gobCaster = nullptr;
8023 {
8025 }
8026 else if (m_caster->GetEntry() == WORLD_TRIGGER)
8027 {
8028 if (TempSummon* tempSummon = m_caster->ToTempSummon())
8029 {
8030 gobCaster = tempSummon->GetSummonerGameObject();
8031 }
8032 }
8033
8034 if (gobCaster)
8035 {
8036 if (gobCaster->GetGOInfo()->IsIgnoringLOSChecks())
8037 {
8038 return true;
8039 }
8040
8041 // If spell casted by gameobject then ignore M2 models
8042 losChecks &= ~LINEOFSIGHT_CHECK_GOBJECT_M2;
8043 }
8044
8045 if (target != m_caster)
8046 {
8047 if (m_targets.HasDst())
8048 {
8049 float x = m_targets.GetDstPos()->GetPositionX();
8050 float y = m_targets.GetDstPos()->GetPositionY();
8051 float z = m_targets.GetDstPos()->GetPositionZ();
8052
8053 if (!target->IsWithinLOS(x, y, z, VMAP::ModelIgnoreFlags::M2, LineOfSightChecks(losChecks)))
8054 {
8055 return false;
8056 }
8057 }
8059 {
8060 return false;
8061 }
8062 }
8063 break;
8064 }
8065 }
8066
8067 return true;
8068}
@ SPELL_EFFECT_SKIN_PLAYER_CORPSE
Definition: SharedDefines.h:894
@ TARGET_CHECK_ENTRY
Definition: SpellInfo.h:115
@ CONFIG_MAX_RECRUIT_A_FRIEND_BONUS_PLAYER_LEVEL
Definition: IWorld.h:247
@ CORPSE_FLAG_LOOTABLE
Definition: Corpse.h:45
@ CORPSE_FIELD_FLAGS
Definition: UpdateFields.h:427
@ UNIT_FLAG_NOT_SELECTABLE
Definition: UnitDefines.h:254
@ SPELL_DISABLE_LOS
Definition: DisableMgr.h:48
@ DISABLE_TYPE_SPELL
Definition: DisableMgr.h:27
#define sWorld
Definition: World.h:443
bool IsDisabledFor(DisableType type, uint32 entry, Unit const *unit, uint8 flags)
Definition: DisableMgr.cpp:307
Corpse * GetCorpse(WorldObject const &u, ObjectGuid const guid)
Definition: ObjectAccessor.cpp:179
Definition: Corpse.h:49
ObjectGuid GetOwnerGUID() const
Definition: Corpse.h:68
bool IsIgnoringLOSChecks() const
Definition: GameObjectData.h:642
bool HasFlag(uint16 index, uint32 flag) const
Definition: Object.cpp:889
bool IsARecruiter() const
Definition: WorldSession.h:527
ObjectGuid GetCorpseTargetGUID() const
Definition: Spell.cpp:281

References CalculateSpellDamage(), CONFIG_MAX_RECRUIT_A_FRIEND_BONUS_PLAYER_LEVEL, CORPSE_FIELD_FLAGS, CORPSE_FLAG_LOOTABLE, damage, DISABLE_TYPE_SPELL, SpellInfo::Effects, WorldSession::GetAccountId(), Unit::GetCharmerGUID(), ObjectAccessor::GetCorpse(), SpellCastTargets::GetCorpseTargetGUID(), SpellCastTargets::GetDstPos(), Object::GetEntry(), Map::GetGameObject(), GameObject::GetGOInfo(), Object::GetGUID(), Unit::GetLevel(), WorldObject::GetMap(), Corpse::GetOwnerGUID(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), WorldSession::GetRecruiterId(), Player::GetSession(), SpellInfo::HasAttribute(), SpellCastTargets::HasDst(), Object::HasFlag(), Unit::HasUnitFlag(), SpellInfo::Id, WorldSession::IsARecruiter(), Object::IsCreature(), DisableMgr::IsDisabledFor(), ObjectGuid::IsGameObject(), GameObjectTemplate::IsIgnoringLOSChecks(), Unit::IsMounted(), Object::IsPlayer(), IsTriggered(), Unit::IsVehicle(), WorldObject::IsWithinLOS(), WorldObject::IsWithinLOSInMap(), LINEOFSIGHT_ALL_CHECKS, VMAP::M2, m_caster, m_originalCasterGUID, m_spellFlags, m_spellInfo, m_targets, m_triggeredByAuraSpell, SPELL_ATTR2_IGNORE_LINE_OF_SIGHT, SPELL_AURA_AOE_CHARM, SPELL_AURA_MOD_CHARM, SPELL_AURA_MOD_POSSESS, SPELL_AURA_MOD_POSSESS_PET, SPELL_DISABLE_LOS, SPELL_EFFECT_RESURRECT_NEW, SPELL_EFFECT_SKIN_PLAYER_CORPSE, SPELL_EFFECT_SUMMON_RAF_FRIEND, SPELL_FLAG_REDIRECTED, TriggeredByAuraSpellData::spellInfo, sWorld, TARGET_CHECK_ENTRY, Object::ToPlayer(), Unit::ToTempSummon(), UNIT_FLAG_NOT_SELECTABLE, UNIT_FLAG_SKINNABLE, and WORLD_TRIGGER.

Referenced by AddUnitTarget().

◆ CheckItems()

SpellCastResult Spell::CheckItems ( )
Todo:
Needs review
Todo:
: Not sure whether the fallthrough was a mistake (forgetting a break) or intended. This should be double-checked.
7184{
7185 Player* player = m_caster->ToPlayer();
7186 if (!player)
7187 {
7188 // Non-player case: Check if creature is disarmed
7190 {
7192 }
7193
7194 return SPELL_CAST_OK;
7195 }
7196
7197 if (!m_CastItem)
7198 {
7199 if (m_castItemGUID)
7201 }
7202 else
7203 {
7204 uint32 itemid = m_CastItem->GetEntry();
7205 if (!player->HasItemCount(itemid))
7207
7208 ItemTemplate const* proto = m_CastItem->GetTemplate();
7209 if (!proto)
7211
7212 for (int i = 0; i < MAX_ITEM_SPELLS; ++i)
7213 if (proto->Spells[i].SpellCharges)
7214 if (m_CastItem->GetSpellCharges(i) == 0)
7216
7217 // consumable cast item checks
7219 {
7220 // such items should only fail if there is no suitable effect at all - see Rejuvenation Potions for example
7221 SpellCastResult failReason = SPELL_CAST_OK;
7222 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; i++)
7223 {
7224 // skip check, pet not required like checks, and for TARGET_UNIT_PET m_targets.GetUnitTarget() is not the real target but the caster
7225 if (m_spellInfo->Effects[i].TargetA.GetTarget() == TARGET_UNIT_PET)
7226 continue;
7227
7228 if (m_spellInfo->Effects[i].Effect == SPELL_EFFECT_HEAL)
7229 {
7231 {
7233 continue;
7234 }
7235 else
7236 {
7237 failReason = SPELL_CAST_OK;
7238 break;
7239 }
7240 }
7241
7242 // Mana Potion, Rage Potion, Thistle Tea(Rogue), ...
7243 if (m_spellInfo->Effects[i].Effect == SPELL_EFFECT_ENERGIZE)
7244 {
7245 if (m_spellInfo->Effects[i].MiscValue < 0 || m_spellInfo->Effects[i].MiscValue >= int8(MAX_POWERS))
7246 {
7248 continue;
7249 }
7250
7251 Powers power = Powers(m_spellInfo->Effects[i].MiscValue);
7253 {
7255 continue;
7256 }
7257 else
7258 {
7259 failReason = SPELL_CAST_OK;
7260 break;
7261 }
7262 }
7263 }
7264 if (failReason != SPELL_CAST_OK)
7265 return failReason;
7266 }
7267 }
7268
7269 // check target item
7271 {
7272 if (!m_caster->IsPlayer())
7274
7275 if (!m_targets.GetItemTarget())
7277
7280 }
7281 // if not item target then required item must be equipped
7282 else
7283 {
7284 // Xinef: this is not true in my opinion, in eg bladestorm will not be canceled after disarm
7285 //if (!HasTriggeredCastFlag(TRIGGERED_IGNORE_EQUIPPED_ITEM_REQUIREMENT))
7288 }
7289
7290 // do not take reagents for these item casts
7292 {
7294 // Not own traded item (in trader trade slot) requires reagents even if triggered spell
7295 if (!checkReagents)
7296 if (Item* targetItem = m_targets.GetItemTarget())
7297 if (targetItem->GetOwnerGUID() != m_caster->GetGUID())
7298 checkReagents = true;
7299
7300 // check reagents (ignore triggered spells with reagents processed by original spell) and special reagent ignore case.
7301 if (checkReagents)
7302 {
7303 for (uint32 i = 0; i < MAX_SPELL_REAGENTS; i++)
7304 {
7305 if (m_spellInfo->Reagent[i] <= 0)
7306 continue;
7307
7308 uint32 itemid = m_spellInfo->Reagent[i];
7309 uint32 itemcount = m_spellInfo->ReagentCount[i];
7310
7311 // if CastItem is also spell reagent
7312 if (m_CastItem && m_CastItem->GetEntry() == itemid)
7313 {
7314 ItemTemplate const* proto = m_CastItem->GetTemplate();
7315 if (!proto)
7317 for (int s = 0; s < MAX_ITEM_PROTO_SPELLS; ++s)
7318 {
7319 // CastItem will be used up and does not count as reagent
7320 int32 charges = m_CastItem->GetSpellCharges(s);
7321 if (proto->Spells[s].SpellCharges < 0 && std::abs(charges) < 2)
7322 {
7323 ++itemcount;
7324 break;
7325 }
7326 }
7327 }
7328 if (!player->HasItemCount(itemid, itemcount))
7329 return SPELL_FAILED_REAGENTS;
7330 }
7331 }
7332
7333 // check totem-item requirements (items presence in inventory)
7334 uint32 totems = 2;
7335 for (int i = 0; i < 2; ++i)
7336 {
7337 if (m_spellInfo->Totem[i] != 0)
7338 {
7339 if (player->HasItemCount(m_spellInfo->Totem[i]))
7340 {
7341 totems -= 1;
7342 continue;
7343 }
7344 }
7345 else
7346 totems -= 1;
7347 }
7348 if (totems != 0)
7349 return SPELL_FAILED_TOTEMS; //0x7C
7350
7351 // Check items for TotemCategory (items presence in inventory)
7353 for (int i = 0; i < 2; ++i)
7354 {
7355 if (m_spellInfo->TotemCategory[i] != 0)
7356 {
7358 {
7359 TotemCategory -= 1;
7360 continue;
7361 }
7362 }
7363 else
7364 TotemCategory -= 1;
7365 }
7366 if (TotemCategory != 0)
7367 return SPELL_FAILED_TOTEM_CATEGORY; //0x7B
7368 }
7369
7370 // special checks for spell effects
7371 for (int i = 0; i < MAX_SPELL_EFFECTS; i++)
7372 {
7373 switch (m_spellInfo->Effects[i].Effect)
7374 {
7377 {
7378 // m_targets.GetUnitTarget() means explicit cast, otherwise we dont check for possible equip error
7379 Unit* target = m_targets.GetUnitTarget() ? m_targets.GetUnitTarget() : player;
7380 if (target->IsPlayer() && !IsTriggered())
7381 {
7382 // SPELL_EFFECT_CREATE_ITEM_2 differs from SPELL_EFFECT_CREATE_ITEM in that it picks the random item to create from a pool of potential items,
7383 // so we need to make sure there is at least one free space in the player's inventory
7385 if (target->ToPlayer()->GetFreeInventorySpace() == 0)
7386 {
7387 player->SendEquipError(EQUIP_ERR_INVENTORY_FULL, nullptr, nullptr, m_spellInfo->Effects[i].ItemType);
7389 }
7390
7391 if (m_spellInfo->Effects[i].ItemType)
7392 {
7393 ItemTemplate const* itemTemplate = sObjectMgr->GetItemTemplate(m_spellInfo->Effects[i].ItemType);
7394 if (!itemTemplate)
7396
7397 uint32 createCount = std::clamp<uint32>(m_spellInfo->Effects[i].CalcValue(), 1u, itemTemplate->GetMaxStackSize());
7398 ItemPosCountVec dest;
7399 InventoryResult msg = target->ToPlayer()->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, m_spellInfo->Effects[i].ItemType, createCount);
7400 if (msg != EQUIP_ERR_OK)
7401 {
7403 if (!itemTemplate->ItemLimitCategory)
7404 {
7405 player->SendEquipError(msg, nullptr, nullptr, m_spellInfo->Effects[i].ItemType);
7407 }
7408 else
7409 {
7410 // Conjure Food/Water/Refreshment spells
7413 else if (!(target->ToPlayer()->HasItemCount(m_spellInfo->Effects[i].ItemType)))
7414 {
7415 player->SendEquipError(msg, nullptr, nullptr, m_spellInfo->Effects[i].ItemType);
7417 }
7418 else
7419 player->CastSpell(player, m_spellInfo->Effects[EFFECT_1].CalcValue(), false); // move this to anywhere
7420
7422 }
7423 }
7424 }
7425 }
7426 break;
7427 }
7429 {
7430 if (player->GetFreeInventorySpace() == 0)
7431 {
7432 player->SendEquipError(EQUIP_ERR_INVENTORY_FULL, nullptr, nullptr, m_spellInfo->Effects[i].ItemType);
7434 }
7435 break;
7436 }
7438 if (m_spellInfo->Effects[i].ItemType && m_targets.GetItemTarget()
7440 {
7441 // cannot enchant vellum for other player
7444 // do not allow to enchant vellum from scroll made by vellum-prevent exploit
7447 ItemPosCountVec dest;
7448 InventoryResult msg = player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, m_spellInfo->Effects[i].ItemType, 1);
7449 if (msg != EQUIP_ERR_OK)
7450 {
7451 player->SendEquipError(msg, nullptr, nullptr, m_spellInfo->Effects[i].ItemType);
7453 }
7454 }
7455 [[fallthrough]];
7457 {
7458 Item* targetItem = m_targets.GetItemTarget();
7459 if (!targetItem)
7461
7462 // xinef: required level has to be checked also! Exploit fix
7463 if (targetItem->GetTemplate()->ItemLevel < m_spellInfo->BaseLevel || (targetItem->GetTemplate()->RequiredLevel && targetItem->GetTemplate()->RequiredLevel < m_spellInfo->BaseLevel))
7464 return SPELL_FAILED_LOWLEVEL;
7465
7466 bool isItemUsable = false;
7467 for (uint8 e = 0; e < MAX_ITEM_PROTO_SPELLS; ++e)
7468 {
7469 ItemTemplate const* proto = targetItem->GetTemplate();
7470 if (proto->Spells[e].SpellId && (
7473 {
7474 isItemUsable = true;
7475 break;
7476 }
7477 }
7478
7479 SpellItemEnchantmentEntry const* enchantEntry = sSpellItemEnchantmentStore.LookupEntry(m_spellInfo->Effects[i].MiscValue);
7480 // do not allow adding usable enchantments to items that have use effect already
7481 if (enchantEntry)
7482 {
7483 for (uint8 s = 0; s < MAX_SPELL_ITEM_ENCHANTMENT_EFFECTS; ++s)
7484 {
7485 switch (enchantEntry->type[s])
7486 {
7488 if (isItemUsable)
7490 break;
7492 {
7493 uint32 numSockets = 0;
7494 for (uint32 socket = 0; socket < MAX_ITEM_PROTO_SOCKETS; ++socket)
7495 if (targetItem->GetTemplate()->Socket[socket].Color)
7496 ++numSockets;
7497
7498 if (numSockets == MAX_ITEM_PROTO_SOCKETS || targetItem->GetEnchantmentId(PRISMATIC_ENCHANTMENT_SLOT))
7500 break;
7501 }
7502 }
7503 }
7504 }
7505
7506 // Not allow enchant in trade slot for some enchant type
7507 if (targetItem->GetOwner() != m_caster)
7508 {
7509 if (!enchantEntry)
7510 return SPELL_FAILED_ERROR;
7511 if (enchantEntry->slot & ENCHANTMENT_CAN_SOULBOUND)
7513 }
7514 break;
7515 }
7517 {
7518 Item* item = m_targets.GetItemTarget();
7519 if (!item)
7521 // Not allow enchant in trade slot for some enchant type
7522 if (item->GetOwner() != m_caster)
7523 {
7524 uint32 enchant_id = m_spellInfo->Effects[i].MiscValue;
7525 SpellItemEnchantmentEntry const* pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id);
7526 if (!pEnchant)
7527 return SPELL_FAILED_ERROR;
7528 if (pEnchant->slot & ENCHANTMENT_CAN_SOULBOUND)
7530 }
7531
7532 // Xinef: Apply item level restriction if the enchanting spell has max level restrition set
7533 if (m_CastItem && m_spellInfo->MaxLevel > 0)
7534 {
7536 return SPELL_FAILED_LOWLEVEL;
7537 if (item->GetTemplate()->ItemLevel > m_spellInfo->MaxLevel)
7539 }
7540
7541 break;
7542 }
7544 // check item existence in effect code (not output errors at offhand hold item effect to main hand for example
7545 break;
7547 {
7548 if (!m_targets.GetItemTarget())
7550
7551 // prevent disenchanting in trade slot
7554
7555 ItemTemplate const* itemProto = m_targets.GetItemTarget()->GetTemplate();
7556 if (!itemProto)
7558
7559 uint32 item_quality = itemProto->Quality;
7560 // 2.0.x addon: Check player enchanting level against the item disenchanting requirements
7561 uint32 item_disenchantskilllevel = itemProto->RequiredDisenchantSkill;
7562 if (item_disenchantskilllevel == uint32(-1))
7564 if (item_disenchantskilllevel > player->GetSkillValue(SKILL_ENCHANTING))
7566 if (item_quality > 4 || item_quality < 2)
7568 if (itemProto->Class != ITEM_CLASS_WEAPON && itemProto->Class != ITEM_CLASS_ARMOR)
7570 if (!itemProto->DisenchantID)
7572 break;
7573 }
7575 {
7576 if (!m_targets.GetItemTarget())
7578 //ensure item is a prospectable ore
7581 //prevent prospecting in trade slot
7584 //Check for enough skill in jewelcrafting
7585 uint32 item_prospectingskilllevel = m_targets.GetItemTarget()->GetTemplate()->RequiredSkillRank;
7586 if (item_prospectingskilllevel > player->GetSkillValue(SKILL_JEWELCRAFTING))
7588 //make sure the player has the required ores in inventory
7589 if (m_targets.GetItemTarget()->GetCount() < 5)
7591
7594
7595 break;
7596 }
7598 {
7599 if (!m_targets.GetItemTarget())
7601 //ensure item is a millable herb
7604 //prevent milling in trade slot
7607 //Check for enough skill in inscription
7608 uint32 item_millingskilllevel = m_targets.GetItemTarget()->GetTemplate()->RequiredSkillRank;
7609 if (item_millingskilllevel > player->GetSkillValue(SKILL_INSCRIPTION))
7611 //make sure the player has the required herbs in inventory
7612 if (m_targets.GetItemTarget()->GetCount() < 5)
7614
7617
7618 break;
7619 }
7622 {
7623 if (!m_caster->IsPlayer())
7625
7627 break;
7628
7630 if (!pItem || pItem->IsBroken())
7632
7633 switch (pItem->GetTemplate()->SubClass)
7634 {
7636 {
7637 uint32 ammo = pItem->GetEntry();
7638 if (!m_caster->ToPlayer()->HasItemCount(ammo))
7639 return SPELL_FAILED_NO_AMMO;
7640 };
7641 break;
7645 {
7647 if (!ammo)
7648 {
7649 // Requires No Ammo
7650 if (m_caster->HasAura(46699))
7651 break; // skip other checks
7652
7653 return SPELL_FAILED_NO_AMMO;
7654 }
7655
7656 ItemTemplate const* ammoProto = sObjectMgr->GetItemTemplate(ammo);
7657 if (!ammoProto)
7658 return SPELL_FAILED_NO_AMMO;
7659
7660 if (ammoProto->Class != ITEM_CLASS_PROJECTILE)
7661 return SPELL_FAILED_NO_AMMO;
7662
7663 // check ammo ws. weapon compatibility
7664 switch (pItem->GetTemplate()->SubClass)
7665 {
7668 if (ammoProto->SubClass != ITEM_SUBCLASS_ARROW)
7669 return SPELL_FAILED_NO_AMMO;
7670 break;
7672 if (ammoProto->SubClass != ITEM_SUBCLASS_BULLET)
7673 return SPELL_FAILED_NO_AMMO;
7674 break;
7675 default:
7676 return SPELL_FAILED_NO_AMMO;
7677 }
7678
7679 if (!m_caster->ToPlayer()->HasItemCount(ammo))
7680 {
7682 return SPELL_FAILED_NO_AMMO;
7683 }
7684 };
7685 break;
7687 break;
7688 default:
7689 break;
7690 }
7691 break;
7692 }
7694 {
7695 uint32 item_id = m_spellInfo->Effects[i].ItemType;
7696 ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(item_id);
7697
7698 if (!pProto)
7700
7701 if (Item* pitem = player->GetItemByEntry(item_id))
7702 {
7703 for (int x = 0; x < MAX_ITEM_PROTO_SPELLS; ++x)
7704 if (pProto->Spells[x].SpellCharges != 0 && pitem->GetSpellCharges(x) == pProto->Spells[x].SpellCharges)
7706 }
7707 break;
7708 }
7709 default:
7710 break;
7711 }
7712 }
7713
7714 // check weapon presence in slots for main/offhand weapons
7715 if (/*never skip those checks !HasTriggeredCastFlag(TRIGGERED_IGNORE_EQUIPPED_ITEM_REQUIREMENT) &&*/ m_spellInfo->EquippedItemClass >= 0)
7716 {
7717 // main hand weapon required
7719 {
7721
7722 // skip spell if no weapon in slot or broken
7723 if (!item || item->IsBroken())
7725
7726 // skip spell if weapon not fit to triggered spell
7729 }
7730
7731 // offhand hand weapon required
7733 {
7735
7736 // skip spell if no weapon in slot or broken
7737 if (!item || item->IsBroken())
7739
7740 // skip spell if weapon not fit to triggered spell
7743 }
7744
7746 }
7747
7748 return SPELL_CAST_OK;
7749}
std::int8_t int8
Definition: Define.h:105
#define MAX_SPELL_REAGENTS
Definition: DBCStructure.h:1638
#define MAX_SPELL_ITEM_ENCHANTMENT_EFFECTS
Definition: DBCStructure.h:1837
@ ITEM_ENCHANTMENT_TYPE_USE_SPELL
Definition: DBCEnums.h:373
@ ITEM_ENCHANTMENT_TYPE_PRISMATIC_SOCKET
Definition: DBCEnums.h:374
@ EFFECT_1
Definition: SharedDefines.h:32
@ MAX_POWERS
Definition: SharedDefines.h:276
@ SPELL_EFFECT_DISENCHANT
Definition: SharedDefines.h:877
@ SPELL_EFFECT_PROSPECTING
Definition: SharedDefines.h:905
@ SPELL_EFFECT_ENCHANT_HELD_ITEM
Definition: SharedDefines.h:870
@ SPELL_EFFECT_ENCHANT_ITEM
Definition: SharedDefines.h:831
@ SPELL_EFFECT_WEAPON_DAMAGE
Definition: SharedDefines.h:836
@ SPELL_EFFECT_HEAL
Definition: SharedDefines.h:788
@ SPELL_EFFECT_MILLING
Definition: SharedDefines.h:936
@ SPELL_EFFECT_CREATE_MANA_GEM
Definition: SharedDefines.h:844
@ SPELL_EFFECT_CREATE_ITEM_2
Definition: SharedDefines.h:935
@ SPELL_EFFECT_WEAPON_DAMAGE_NOSCHOOL
Definition: SharedDefines.h:795
@ SPELL_EFFECT_ENERGIZE
Definition: SharedDefines.h:808
@ SPELL_EFFECT_CREATE_RANDOM_ITEM
Definition: SharedDefines.h:837
@ SPELL_EFFECT_ENCHANT_ITEM_PRISMATIC
Definition: SharedDefines.h:934
@ SPELL_EFFECT_ENCHANT_ITEM_TEMPORARY
Definition: SharedDefines.h:832
@ SPELL_EFFECT_CREATE_ITEM
Definition: SharedDefines.h:802
@ SPELL_ATTR3_REQUIRES_MAIN_HAND_WEAPON
Definition: SharedDefines.h:503
@ SPELLFAMILY_MAGE
Definition: SharedDefines.h:3531
TotemCategory
Definition: SharedDefines.h:3083
@ SPELL_FAILED_CANT_BE_MILLED
Definition: SharedDefines.h:965
@ SPELL_FAILED_EQUIPPED_ITEM_CLASS_OFFHAND
Definition: SharedDefines.h:980
@ SPELL_FAILED_EQUIPPED_ITEM_CLASS
Definition: SharedDefines.h:978
@ SPELL_FAILED_ITEM_AT_MAX_CHARGES
Definition: SharedDefines.h:1128
@ SPELL_FAILED_TARGET_NOT_PLAYER
Definition: SharedDefines.h:1071
@ SPELL_FAILED_ALREADY_AT_FULL_POWER
Definition: SharedDefines.h:953
@ SPELL_FAILED_NOT_TRADEABLE
Definition: SharedDefines.h:1019
@ SPELL_FAILED_ITEM_NOT_READY
Definition: SharedDefines.h:994
@ SPELL_FAILED_NO_CHARGES_REMAIN
Definition: SharedDefines.h:1025
@ SPELL_FAILED_ITEM_GONE
Definition: SharedDefines.h:992
@ SPELL_FAILED_NO_AMMO
Definition: SharedDefines.h:1024
@ SPELL_FAILED_ITEM_NOT_FOUND
Definition: SharedDefines.h:993
@ SPELL_FAILED_EQUIPPED_ITEM
Definition: SharedDefines.h:977
@ SPELL_FAILED_ALREADY_AT_FULL_HEALTH
Definition: SharedDefines.h:951
@ SPELL_FAILED_ON_USE_ENCHANT
Definition: SharedDefines.h:1119
@ SPELL_FAILED_TOTEMS
Definition: SharedDefines.h:1080
@ SPELL_FAILED_ERROR
Definition: SharedDefines.h:981
@ SPELL_FAILED_REAGENTS
Definition: SharedDefines.h:1049
@ SPELL_FAILED_MAX_SOCKETS
Definition: SharedDefines.h:1133
@ SPELL_FAILED_CANT_BE_DISENCHANTED
Definition: SharedDefines.h:963
@ SPELL_FAILED_TOO_MANY_OF_ITEM
Definition: SharedDefines.h:1078
@ SPELL_FAILED_NEED_MORE_ITEMS
Definition: SharedDefines.h:1004
@ SPELL_FAILED_CANT_BE_PROSPECTED
Definition: SharedDefines.h:966
@ SPELL_FAILED_EQUIPPED_ITEM_CLASS_MAINHAND
Definition: SharedDefines.h:979
@ SPELL_FAILED_TOTEM_CATEGORY
Definition: SharedDefines.h:1079
@ SKILL_INSCRIPTION
Definition: SharedDefines.h:3002
@ SKILL_ENCHANTING
Definition: SharedDefines.h:2954
@ SKILL_JEWELCRAFTING
Definition: SharedDefines.h:2985
std::vector< ItemPosCount > ItemPosCountVec
Definition: Player.h:776
InventoryResult
Definition: Item.h:46
@ EQUIP_ERR_OK
Definition: Item.h:47
@ EQUIP_ERR_INVENTORY_FULL
Definition: Item.h:97
#define MAX_ITEM_SPELLS
Definition: Item.h:215
@ ENCHANTMENT_CAN_SOULBOUND
Definition: Item.h:201
@ NULL_BAG
Definition: Item.h:40
@ NULL_SLOT
Definition: Item.h:41
@ PRISMATIC_ENCHANTMENT_SLOT
Definition: Item.h:175
@ ITEM_SUBCLASS_WEAPON_CROSSBOW
Definition: ItemTemplate.h:362
@ ITEM_SUBCLASS_WEAPON_GUN
Definition: ItemTemplate.h:347
@ ITEM_SUBCLASS_WEAPON_BOW
Definition: ItemTemplate.h:346
@ ITEM_SUBCLASS_WEAPON_WAND
Definition: ItemTemplate.h:363
@ ITEM_SUBCLASS_WEAPON_THROWN
Definition: ItemTemplate.h:360
@ ITEM_SPELLTRIGGER_ON_USE
Definition: ItemTemplate.h:77
@ ITEM_SPELLTRIGGER_ON_NO_DELAY_USE
Definition: ItemTemplate.h:87
@ ITEM_FLAG_IS_MILLABLE
Definition: ItemTemplate.h:176
@ ITEM_FLAG_NO_REAGENT_COST
Definition: ItemTemplate.h:175
@ ITEM_FLAG_IS_PROSPECTABLE
Definition: ItemTemplate.h:165
@ ITEM_SUBCLASS_ARROW
Definition: ItemTemplate.h:416
@ ITEM_SUBCLASS_BULLET
Definition: ItemTemplate.h:417
#define MAX_ITEM_PROTO_SOCKETS
Definition: ItemTemplate.h:614
#define MAX_ITEM_PROTO_SPELLS
Definition: ItemTemplate.h:615
@ ITEM_CLASS_PROJECTILE
Definition: ItemTemplate.h:297
@ ITEM_CLASS_ARMOR
Definition: ItemTemplate.h:295
@ ITEM_CLASS_WEAPON
Definition: ItemTemplate.h:293
@ ITEM_CLASS_CONSUMABLE
Definition: ItemTemplate.h:291
@ PLAYER_AMMO_ID
Definition: UpdateFields.h:369
LootStore LootTemplates_Milling("milling_loot_template", "item entry (herb)", true)
LootStore LootTemplates_Prospecting("prospecting_loot_template", "item entry (ore)", true)
DBCStorage< SpellItemEnchantmentEntry > sSpellItemEnchantmentStore(SpellItemEnchantmentfmt)
uint32 GetEnchantmentId(EnchantmentSlot slot) const
Definition: Item.h:304
int32 GetSpellCharges(uint8 index=0) const
Definition: Item.h:317
bool IsBroken() const
Definition: Item.h:257
bool IsWeaponVellum() const
Definition: Item.h:338
bool IsArmorVellum() const
Definition: Item.h:339
Player * GetOwner() const
Definition: Item.cpp:549
ObjectGuid GetOwnerGUID() const
Definition: Item.h:231
uint32 GetCount() const
Definition: Item.h:272
bool IsFitToSpellRequirements(SpellInfo const *spellInfo) const
Definition: Item.cpp:884
int32 SpellCharges
Definition: ItemTemplate.h:593
uint32 SpellTrigger
Definition: ItemTemplate.h:592
int32 SpellId
Definition: ItemTemplate.h:591
uint32 Color
Definition: ItemTemplate.h:602
Definition: ItemTemplate.h:619
uint32 DisenchantID
Definition: ItemTemplate.h:690
uint32 Quality
Definition: ItemTemplate.h:626
uint32 RequiredSkillRank
Definition: ItemTemplate.h:638
uint32 GetMaxStackSize() const
Definition: ItemTemplate.h:729
_Spell Spells[MAX_ITEM_PROTO_SPELLS]
Definition: ItemTemplate.h:662
uint32 RequiredDisenchantSkill
Definition: ItemTemplate.h:684
uint32 RequiredLevel
Definition: ItemTemplate.h:636
bool HasFlag(ItemFlags flag) const
Definition: ItemTemplate.h:827
uint32 Class
Definition: ItemTemplate.h:621
uint32 ItemLimitCategory
Definition: ItemTemplate.h:687
uint32 SubClass
Definition: ItemTemplate.h:622
_Socket Socket[MAX_ITEM_PROTO_SOCKETS]
Definition: ItemTemplate.h:681
uint32 GetUInt32Value(uint16 index) const
Definition: Object.cpp:305
bool HasItemFitToSpellRequirements(SpellInfo const *spellInfo, Item const *ignoreItem=nullptr) const
Definition: Player.cpp:12550
uint32 GetFreeInventorySpace() const
Definition: PlayerStorage.cpp:466
Item * GetItemByEntry(uint32 entry) const
Definition: PlayerStorage.cpp:3369
bool HasItemCount(uint32 item, uint32 count=1, bool inBankAlso=false) const
Definition: PlayerStorage.cpp:655
bool HasItemTotemCategory(uint32 TotemCategory) const
Definition: PlayerStorage.cpp:851
bool CanNoReagentCast(SpellInfo const *spellInfo) const
Definition: Player.cpp:12595
void SendEquipError(InventoryResult msg, Item *pItem, Item *pItem2=nullptr, uint32 itemid=0)
Definition: PlayerStorage.cpp:4021
InventoryResult CanStoreNewItem(uint8 bag, uint8 slot, ItemPosCountVec &dest, uint32 item, uint32 count, uint32 *no_space_count=nullptr) const
Definition: Player.h:1291
bool CanUseAttackType(uint8 attacktype) const
Definition: Unit.h:936
bool IsFullHealth() const
Definition: Unit.h:1035
uint32 GetMaxPower(Powers power) const
Definition: Unit.h:1057
void SetUInt32Value(uint16 index, uint32 value)
Definition: Unit.cpp:21316
uint32 GetPower(Powers power) const
Definition: Unit.h:1056
bool HaveLootFor(uint32 loot_id) const
Definition: LootMgr.h:224
uint32 GetItemTargetEntry() const
Definition: Spell.h:142
ObjectGuid m_castItemGUID
Definition: Spell.h:526
uint32 BaseLevel
Definition: SpellInfo.h:359
uint32 MaxLevel
Definition: SpellInfo.h:358
std::array< int32, MAX_SPELL_REAGENTS > Reagent
Definition: SpellInfo.h:373
flag96 SpellFamilyFlags
Definition: SpellInfo.h:388
std::array< uint32, 2 > TotemCategory
Definition: SpellInfo.h:378
int32 EquippedItemClass
Definition: SpellInfo.h:375
std::array< uint32, 2 > Totem
Definition: SpellInfo.h:372
std::array< uint32, MAX_SPELL_REAGENTS > ReagentCount
Definition: SpellInfo.h:374
Definition: DBCStructure.h:1840
uint32 type[MAX_SPELL_ITEM_ENCHANTMENT_EFFECTS]
Definition: DBCStructure.h:1843
uint32 slot
Definition: DBCStructure.h:1850

References BASE_ATTACK, SpellInfo::BaseLevel, Player::CanNoReagentCast(), Player::CanStoreNewItem(), Unit::CanUseAttackType(), Unit::CastSpell(), ItemTemplate::Class, _Socket::Color, ItemTemplate::DisenchantID, SpellInfo::DmgClass, EFFECT_1, SpellInfo::Effects, ENCHANTMENT_CAN_SOULBOUND, EQUIP_ERR_INVENTORY_FULL, EQUIP_ERR_OK, SpellInfo::EquippedItemClass, Item::GetCount(), Item::GetEnchantmentId(), Object::GetEntry(), Player::GetFreeInventorySpace(), Object::GetGUID(), Player::GetItemByEntry(), SpellCastTargets::GetItemTarget(), SpellCastTargets::GetItemTargetEntry(), SpellCastTargets::GetItemTargetGUID(), Unit::GetMaxPower(), ItemTemplate::GetMaxStackSize(), Item::GetOwner(), Item::GetOwnerGUID(), Unit::GetPower(), Player::GetSkillValue(), Item::GetSpellCharges(), Item::GetTemplate(), Object::GetUInt32Value(), SpellCastTargets::GetUnitTarget(), Player::GetWeaponForAttack(), SpellInfo::HasAttribute(), Unit::HasAura(), ItemTemplate::HasFlag(), Player::HasItemCount(), Player::HasItemFitToSpellRequirements(), Player::HasItemTotemCategory(), HasTriggeredCastFlag(), LootStore::HaveLootFor(), Item::IsArmorVellum(), Item::IsBroken(), Item::IsFitToSpellRequirements(), Unit::IsFullHealth(), Object::IsPlayer(), IsTriggered(), Item::IsWeaponVellum(), ITEM_CLASS_ARMOR, ITEM_CLASS_CONSUMABLE, ITEM_CLASS_PROJECTILE, ITEM_CLASS_WEAPON, ITEM_ENCHANTMENT_TYPE_PRISMATIC_SOCKET, ITEM_ENCHANTMENT_TYPE_USE_SPELL, ITEM_FLAG_IS_MILLABLE, ITEM_FLAG_IS_PROSPECTABLE, ITEM_FLAG_NO_REAGENT_COST, ITEM_SPELLTRIGGER_ON_NO_DELAY_USE, ITEM_SPELLTRIGGER_ON_USE, ITEM_SUBCLASS_ARROW, ITEM_SUBCLASS_BULLET, ITEM_SUBCLASS_WEAPON_BOW, ITEM_SUBCLASS_WEAPON_CROSSBOW, ITEM_SUBCLASS_WEAPON_GUN, ITEM_SUBCLASS_WEAPON_THROWN, ITEM_SUBCLASS_WEAPON_WAND, ItemTemplate::ItemLevel, ItemTemplate::ItemLimitCategory, LootTemplates_Milling, LootTemplates_Prospecting, m_attackType, m_caster, m_CastItem, m_castItemGUID, m_spellInfo, m_targets, m_weaponItem, MAX_ITEM_PROTO_SOCKETS, MAX_ITEM_PROTO_SPELLS, MAX_ITEM_SPELLS, MAX_POWERS, MAX_SPELL_EFFECTS, MAX_SPELL_ITEM_ENCHANTMENT_EFFECTS, MAX_SPELL_REAGENTS, SpellInfo::MaxLevel, NULL_BAG, NULL_SLOT, OFF_ATTACK, PLAYER_AMMO_ID, PRISMATIC_ENCHANTMENT_SLOT, ItemTemplate::Quality, RANGED_ATTACK, SpellInfo::Reagent, SpellInfo::ReagentCount, ItemTemplate::RequiredDisenchantSkill, ItemTemplate::RequiredLevel, ItemTemplate::RequiredSkillRank, Player::SendEquipError(), Unit::SetUInt32Value(), SKILL_ENCHANTING, SKILL_INSCRIPTION, SKILL_JEWELCRAFTING, SpellItemEnchantmentEntry::slot, sObjectMgr, ItemTemplate::Socket, SPELL_ATTR3_REQUIRES_MAIN_HAND_WEAPON, SPELL_ATTR3_REQUIRES_OFF_HAND_WEAPON, SPELL_CAST_OK, SPELL_DAMAGE_CLASS_MELEE, SPELL_DAMAGE_CLASS_RANGED, SPELL_EFFECT_CREATE_ITEM, SPELL_EFFECT_CREATE_ITEM_2, SPELL_EFFECT_CREATE_MANA_GEM, SPELL_EFFECT_CREATE_RANDOM_ITEM, SPELL_EFFECT_DISENCHANT, SPELL_EFFECT_ENCHANT_HELD_ITEM, SPELL_EFFECT_ENCHANT_ITEM, SPELL_EFFECT_ENCHANT_ITEM_PRISMATIC, SPELL_EFFECT_ENCHANT_ITEM_TEMPORARY, SPELL_EFFECT_ENERGIZE, SPELL_EFFECT_HEAL, SPELL_EFFECT_MILLING, SPELL_EFFECT_PROSPECTING, SPELL_EFFECT_WEAPON_DAMAGE, SPELL_EFFECT_WEAPON_DAMAGE_NOSCHOOL, SPELL_FAILED_ALREADY_AT_FULL_HEALTH, SPELL_FAILED_ALREADY_AT_FULL_POWER, SPELL_FAILED_BAD_TARGETS, SPELL_FAILED_CANT_BE_DISENCHANTED, SPELL_FAILED_CANT_BE_MILLED, SPELL_FAILED_CANT_BE_PROSPECTED, SPELL_FAILED_DONT_REPORT, SPELL_FAILED_EQUIPPED_ITEM, SPELL_FAILED_EQUIPPED_ITEM_CLASS, SPELL_FAILED_EQUIPPED_ITEM_CLASS_MAINHAND, SPELL_FAILED_EQUIPPED_ITEM_CLASS_OFFHAND, SPELL_FAILED_ERROR, SPELL_FAILED_HIGHLEVEL, SPELL_FAILED_ITEM_AT_MAX_CHARGES, SPELL_FAILED_ITEM_GONE, SPELL_FAILED_ITEM_NOT_FOUND, SPELL_FAILED_ITEM_NOT_READY, SPELL_FAILED_LOW_CASTLEVEL, SPELL_FAILED_LOWLEVEL, SPELL_FAILED_MAX_SOCKETS, SPELL_FAILED_NEED_MORE_ITEMS, SPELL_FAILED_NO_AMMO, SPELL_FAILED_NO_CHARGES_REMAIN, SPELL_FAILED_NOT_TRADEABLE, SPELL_FAILED_ON_USE_ENCHANT, SPELL_FAILED_REAGENTS, SPELL_FAILED_TARGET_NOT_PLAYER, SPELL_FAILED_TOO_MANY_OF_ITEM, SPELL_FAILED_TOTEM_CATEGORY, SPELL_FAILED_TOTEMS, _Spell::SpellCharges, SPELLFAMILY_MAGE, SpellInfo::SpellFamilyFlags, SpellInfo::SpellFamilyName, _Spell::SpellId, ItemTemplate::Spells, _Spell::SpellTrigger, sSpellItemEnchantmentStore, ItemTemplate::SubClass, TARGET_UNIT_PET, Object::ToPlayer(), SpellInfo::Totem, SpellInfo::TotemCategory, TRIGGERED_IGNORE_POWER_AND_REAGENT_COST, and SpellItemEnchantmentEntry::type.

Referenced by CheckCast().

◆ CheckPetCast()

SpellCastResult Spell::CheckPetCast ( Unit target)
6820{
6821 if (m_caster->HasUnitState(UNIT_STATE_CASTING) && !HasTriggeredCastFlag(TRIGGERED_IGNORE_CAST_IN_PROGRESS)) //prevent spellcast interruption by another spellcast
6823
6824 // dead owner (pets still alive when owners ressed?)
6825 if (Unit* owner = m_caster->GetCharmerOrOwner())
6826 if (!owner->IsAlive() && m_caster->GetEntry() != 30230) // Rise Ally
6828
6829 if (!target && m_targets.GetUnitTarget())
6830 target = m_targets.GetUnitTarget();
6831
6833 {
6834 if (!target)
6836 m_targets.SetUnitTarget(target);
6837 }
6838
6839 // xinef: Calculate power cost here, so funciton checking power can work properly and dont return bad results
6841
6842 // cooldown
6843 if (Creature const* creatureCaster = m_caster->ToCreature())
6844 if (creatureCaster->HasSpellCooldown(m_spellInfo->Id))
6846
6847 // Check if spell is affected by GCD
6851
6852 return CheckCast(true);
6853}
bool HasGlobalCooldown(SpellInfo const *spellInfo) const
Definition: CharmInfo.cpp:397
void SetUnitTarget(Unit *target)
Definition: Spell.cpp:239
int32 CalcPowerCost(Unit const *caster, SpellSchoolMask schoolMask, Spell *spell=nullptr) const
Definition: SpellInfo.cpp:2401
uint32 StartRecoveryCategory
Definition: SpellInfo.h:350

References SpellInfo::CalcPowerCost(), CheckCast(), Unit::GetCharmerOrOwner(), Unit::GetCharmInfo(), Object::GetEntry(), CharmInfo::GetGlobalCooldownMgr(), SpellCastTargets::GetUnitTarget(), GlobalCooldownMgr::HasGlobalCooldown(), HasTriggeredCastFlag(), Unit::HasUnitState(), SpellInfo::Id, m_caster, m_powerCost, m_spellInfo, m_spellSchoolMask, m_targets, SpellInfo::NeedsExplicitUnitTarget(), SpellCastTargets::SetUnitTarget(), SPELL_FAILED_BAD_IMPLICIT_TARGETS, SPELL_FAILED_CASTER_DEAD, SPELL_FAILED_NOT_READY, SPELL_FAILED_SPELL_IN_PROGRESS, SpellInfo::StartRecoveryCategory, Object::ToCreature(), TRIGGERED_IGNORE_CAST_IN_PROGRESS, and UNIT_STATE_CASTING.

Referenced by CanAutoCast(), WorldSession::HandlePetActionHelper(), and WorldSession::HandlePetCastSpellOpcode().

◆ CheckPower()

SpellCastResult Spell::CheckPower ( )
7139{
7140 // item cast not used power
7141 if (m_CastItem)
7142 return SPELL_CAST_OK;
7143
7144 //While .cheat power is enabled dont check if we need power to cast the spell
7145 if (m_caster->IsPlayer())
7146 {
7148 {
7149 return SPELL_CAST_OK;
7150 }
7151 }
7152
7153 // health as power used - need check health amount
7155 {
7158 return SPELL_CAST_OK;
7159 }
7160 // Check valid power type
7162 {
7163 LOG_ERROR("spells", "Spell::CheckPower: Unknown power type '{}'", m_spellInfo->PowerType);
7164 return SPELL_FAILED_UNKNOWN;
7165 }
7166
7167 //check rune cost only if a spell has PowerType == POWER_RUNE
7169 {
7171 if (failReason != SPELL_CAST_OK)
7172 return failReason;
7173 }
7174
7175 // Check power amount
7178 return SPELL_FAILED_NO_POWER;
7179 else
7180 return SPELL_CAST_OK;
7181}
@ POWER_HEALTH
Definition: SharedDefines.h:278
@ POWER_RUNE
Definition: SharedDefines.h:274
@ SPELL_FAILED_NO_POWER
Definition: SharedDefines.h:1034
@ SPELL_FAILED_UNKNOWN
Definition: SharedDefines.h:1136
@ CHEAT_POWER
Definition: Player.h:1007
PowerType
Definition: VehicleDefines.h:29
uint32 GetHealth() const
Definition: Unit.h:1029
SpellCastResult CheckRuneCost(uint32 RuneCostID)
Definition: Spell.cpp:5413
uint32 RuneCostID
Definition: SpellInfo.h:368
uint32 PowerType
Definition: SpellInfo.h:362

References CHEAT_POWER, CheckRuneCost(), Player::GetCommandStatus(), Unit::GetHealth(), Unit::GetPower(), Object::IsPlayer(), LOG_ERROR, m_caster, m_CastItem, m_powerCost, m_spellInfo, MAX_POWERS, POWER_HEALTH, POWER_RUNE, SpellInfo::PowerType, SpellInfo::RuneCostID, SPELL_CAST_OK, SPELL_FAILED_CASTER_AURASTATE, SPELL_FAILED_NO_POWER, SPELL_FAILED_UNKNOWN, and Object::ToPlayer().

Referenced by CheckCast().

◆ CheckRange()

SpellCastResult Spell::CheckRange ( bool  strict)
7053{
7054 // Don't check for instant cast spells
7055 if (!strict && m_casttime == 0)
7056 return SPELL_CAST_OK;
7057
7058 uint32 range_type = 0;
7059
7061 {
7062 // check needed by 68766 51693 - both spells are cast on enemies and have 0 max range
7063 // these are triggered by other spells - possibly we should omit range check in that case?
7064 if (m_spellInfo->RangeEntry->ID == 1)
7065 return SPELL_CAST_OK;
7066
7067 range_type = m_spellInfo->RangeEntry->Flags;
7068 }
7069
7070 Unit* target = m_targets.GetUnitTarget();
7071 float max_range = m_caster->GetSpellMaxRangeForTarget(target, m_spellInfo);
7072 float min_range = m_caster->GetSpellMinRangeForTarget(target, m_spellInfo);
7073
7074 // xinef: hack for npc shooters
7075 if (min_range && GetCaster()->IsCreature() && !GetCaster()->GetOwnerGUID().IsPlayer() && min_range <= 6.0f)
7076 range_type = SPELL_RANGE_RANGED;
7077
7078 if (Player* modOwner = m_caster->GetSpellModOwner())
7079 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_RANGE, max_range, this);
7080
7081 // xinef: dont check max_range to strictly after cast
7082 if (range_type != SPELL_RANGE_MELEE && !strict)
7083 max_range += std::min(3.0f, max_range * 0.1f); // 10% but no more than 3yd
7084
7085 if (target)
7086 {
7087 if (target != m_caster)
7088 {
7089 // Xinef: Spells with 5yd range can hit target 9yd away?
7090 if (range_type == SPELL_RANGE_MELEE)
7091 {
7092 float real_max_range = max_range;
7093 if (!m_caster->IsCreature() && m_caster->isMoving() && target->isMoving() && !m_caster->IsWalking() && !target->IsWalking())
7094 real_max_range -= MIN_MELEE_REACH; // Because of lag, we can not check too strictly here (is only used if both caster and target are moving)
7095 else
7096 real_max_range -= 2 * MIN_MELEE_REACH;
7097
7098 if (!m_caster->IsWithinMeleeRange(target, std::max(real_max_range, 0.0f)))
7100 }
7101 else if (!m_caster->IsWithinCombatRange(target, max_range))
7102 return SPELL_FAILED_OUT_OF_RANGE; //0x5A;
7103
7105 {
7106 if (m_caster->IsWithinMeleeRange(target))
7108 }
7109
7110 if (m_caster->IsPlayer() && (m_spellInfo->FacingCasterFlags & SPELL_FACING_FLAG_INFRONT) && !m_caster->HasInArc(static_cast<float>(M_PI), target))
7112 }
7113
7114 // Xinef: check min range for self casts
7115 if (min_range && range_type != SPELL_RANGE_RANGED && m_caster->IsWithinCombatRange(target, min_range)) // skip this check if min_range = 0
7117 }
7118
7119 if (GameObject* goTarget = m_targets.GetGOTarget())
7120 {
7121 if (!goTarget->IsAtInteractDistance(m_caster->ToPlayer(), m_spellInfo))
7122 {
7124 }
7125 }
7126
7127 if (m_targets.HasDst() && !m_targets.HasTraj())
7128 {
7129 if (!m_caster->IsWithinDist3d(m_targets.GetDstPos(), max_range))
7131 if (min_range && m_caster->IsWithinDist3d(m_targets.GetDstPos(), min_range))
7133 }
7134
7135 return SPELL_CAST_OK;
7136}
@ SPELL_FAILED_TOO_CLOSE
Definition: SharedDefines.h:1077
@ SPELL_FAILED_OUT_OF_RANGE
Definition: SharedDefines.h:1046
@ SPELL_RANGE_MELEE
Definition: Spell.h:91
@ SPELL_RANGE_RANGED
Definition: Spell.h:92
@ SPELLMOD_RANGE
Definition: SpellDefines.h:81
@ SPELL_FACING_FLAG_INFRONT
Definition: SpellDefines.h:128
#define MIN_MELEE_REACH
Definition: ObjectDefines.h:47
bool IsWithinDist3d(float x, float y, float z, float dist) const
Definition: Object.cpp:1306
bool HasInArc(float arcangle, const Position *pos, float targetRadius=0.0f) const
Definition: Position.cpp:141
bool IsWithinCombatRange(Unit const *obj, float dist2compare) const
Definition: Unit.cpp:648
float GetSpellMinRangeForTarget(Unit const *target, SpellInfo const *spellInfo) const
Definition: Unit.cpp:15167
bool IsWithinMeleeRange(Unit const *obj, float dist=0.f) const
Definition: Unit.cpp:664
float GetSpellMaxRangeForTarget(Unit const *target, SpellInfo const *spellInfo) const
Definition: Unit.cpp:15147
bool IsWalking() const
Definition: Unit.h:1574
Unit * GetCaster() const
Definition: Spell.h:577
SpellRangeEntry const * RangeEntry
Definition: SpellInfo.h:369
uint32 FacingCasterFlags
Definition: SpellInfo.h:338
uint32 Flags
Definition: DBCStructure.h:1796
uint32 ID
Definition: DBCStructure.h:1793

References SpellInfo::DmgClass, SpellInfo::FacingCasterFlags, SpellRangeEntry::Flags, GetCaster(), SpellCastTargets::GetDstPos(), SpellCastTargets::GetGOTarget(), Unit::GetSpellMaxRangeForTarget(), Unit::GetSpellMinRangeForTarget(), Unit::GetSpellModOwner(), SpellCastTargets::GetUnitTarget(), SpellCastTargets::HasDst(), Position::HasInArc(), SpellCastTargets::HasTraj(), SpellInfo::Id, SpellRangeEntry::ID, Object::IsCreature(), Unit::isMoving(), Object::IsPlayer(), Unit::IsWalking(), Unit::IsWithinCombatRange(), WorldObject::IsWithinDist3d(), Unit::IsWithinMeleeRange(), m_caster, m_casttime, m_spellInfo, m_targets, MIN_MELEE_REACH, SpellInfo::RangeEntry, SPELL_CAST_OK, SPELL_DAMAGE_CLASS_RANGED, SPELL_FACING_FLAG_INFRONT, SPELL_FAILED_OUT_OF_RANGE, SPELL_FAILED_TOO_CLOSE, SPELL_FAILED_UNIT_NOT_INFRONT, SPELL_RANGE_MELEE, SPELL_RANGE_RANGED, SPELLMOD_RANGE, and Object::ToPlayer().

Referenced by CheckCast().

◆ CheckRuneCost()

SpellCastResult Spell::CheckRuneCost ( uint32  RuneCostID)
5414{
5415 if (m_spellInfo->PowerType != POWER_RUNE || !RuneCostID)
5416 return SPELL_CAST_OK;
5417
5418 if (!m_caster->IsPlayer())
5419 return SPELL_CAST_OK;
5420
5421 Player* player = m_caster->ToPlayer();
5422 //If we are in .cheat power mode we dont need to check the cost as we are expected to be able to use it anyways (infinite power)
5423 if (player->GetCommandStatus(CHEAT_POWER))
5424 {
5425 return SPELL_CAST_OK;
5426 }
5427
5429 return SPELL_CAST_OK;
5430
5431 SpellRuneCostEntry const* src = sSpellRuneCostStore.LookupEntry(RuneCostID);
5432
5433 if (!src)
5434 return SPELL_CAST_OK;
5435
5436 if (src->NoRuneCost())
5437 return SPELL_CAST_OK;
5438
5439 int32 runeCost[NUM_RUNE_TYPES]; // blood, frost, unholy, death
5440
5441 for (uint32 i = 0; i < RUNE_DEATH; ++i)
5442 {
5443 runeCost[i] = src->RuneCost[i];
5444 if (Player* modOwner = m_caster->GetSpellModOwner())
5445 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_COST, runeCost[i], this);
5446 }
5447
5448 runeCost[RUNE_DEATH] = MAX_RUNES; // calculated later
5449
5450 for (uint32 i = 0; i < MAX_RUNES; ++i)
5451 {
5452 RuneType rune = player->GetCurrentRune(i);
5453 if ((player->GetRuneCooldown(i) == 0) && (runeCost[rune] > 0))
5454 runeCost[rune]--;
5455 }
5456
5457 for (uint32 i = 0; i < RUNE_DEATH; ++i)
5458 if (runeCost[i] > 0)
5459 runeCost[RUNE_DEATH] += runeCost[i];
5460
5461 if (runeCost[RUNE_DEATH] > MAX_RUNES)
5462 return SPELL_FAILED_NO_POWER; // not sure if result code is correct
5463
5464 return SPELL_CAST_OK;
5465}
@ CLASS_DEATH_KNIGHT
Definition: SharedDefines.h:146
@ SPELLMOD_COST
Definition: SpellDefines.h:90
RuneType
Definition: Player.h:413
@ RUNE_DEATH
Definition: Player.h:417
@ NUM_RUNE_TYPES
Definition: Player.h:418
#define MAX_RUNES
Definition: Player.h:403
@ CLASS_CONTEXT_ABILITY
Definition: UnitDefines.h:213
DBCStorage< SpellRuneCostEntry > sSpellRuneCostStore(SpellRuneCostfmt)
uint32 GetRuneCooldown(uint8 index) const
Definition: Player.h:2508
bool IsClass(Classes playerClass, ClassContext context=CLASS_CONTEXT_NONE) const override
Definition: Player.cpp:1284
RuneType GetCurrentRune(uint8 index) const
Definition: Player.h:2507
Definition: DBCStructure.h:1804
uint32 RuneCost[3]
Definition: DBCStructure.h:1806
bool NoRuneCost() const
Definition: DBCStructure.h:1809

References CHEAT_POWER, CLASS_CONTEXT_ABILITY, CLASS_DEATH_KNIGHT, Player::GetCommandStatus(), Player::GetCurrentRune(), Player::GetRuneCooldown(), Unit::GetSpellModOwner(), SpellInfo::Id, Player::IsClass(), Object::IsPlayer(), m_caster, m_spellInfo, MAX_RUNES, SpellRuneCostEntry::NoRuneCost(), NUM_RUNE_TYPES, POWER_RUNE, SpellInfo::PowerType, RUNE_DEATH, SpellRuneCostEntry::RuneCost, SPELL_CAST_OK, SPELL_FAILED_NO_POWER, SPELLMOD_COST, sSpellRuneCostStore, and Object::ToPlayer().

Referenced by CheckPower().

◆ CheckScriptEffectImplicitTargets()

bool Spell::CheckScriptEffectImplicitTargets ( uint32  effIndex,
uint32  effIndexToCheck 
)
protected
8726{
8727 // Skip if there are not any script
8728 if (!m_loadedScripts.size())
8729 return true;
8730
8731 for (std::list<SpellScript*>::iterator itr = m_loadedScripts.begin(); itr != m_loadedScripts.end(); ++itr)
8732 {
8733 std::list<SpellScript::ObjectTargetSelectHandler>::iterator targetSelectHookEnd = (*itr)->OnObjectTargetSelect.end(), targetSelectHookItr = (*itr)->OnObjectTargetSelect.begin();
8734 for (; targetSelectHookItr != targetSelectHookEnd; ++targetSelectHookItr)
8735 if (((*targetSelectHookItr).IsEffectAffected(m_spellInfo, effIndex) && !(*targetSelectHookItr).IsEffectAffected(m_spellInfo, effIndexToCheck)) ||
8736 (!(*targetSelectHookItr).IsEffectAffected(m_spellInfo, effIndex) && (*targetSelectHookItr).IsEffectAffected(m_spellInfo, effIndexToCheck)))
8737 return false;
8738
8739 std::list<SpellScript::ObjectAreaTargetSelectHandler>::iterator areaTargetSelectHookEnd = (*itr)->OnObjectAreaTargetSelect.end(), areaTargetSelectHookItr = (*itr)->OnObjectAreaTargetSelect.begin();
8740 for (; areaTargetSelectHookItr != areaTargetSelectHookEnd; ++areaTargetSelectHookItr)
8741 if (((*areaTargetSelectHookItr).IsEffectAffected(m_spellInfo, effIndex) && !(*areaTargetSelectHookItr).IsEffectAffected(m_spellInfo, effIndexToCheck)) ||
8742 (!(*areaTargetSelectHookItr).IsEffectAffected(m_spellInfo, effIndex) && (*areaTargetSelectHookItr).IsEffectAffected(m_spellInfo, effIndexToCheck)))
8743 return false;
8744 }
8745 return true;
8746}

References m_loadedScripts, and m_spellInfo.

Referenced by SelectEffectImplicitTargets().

◆ CheckSpellFocus()

SpellCastResult Spell::CheckSpellFocus ( )
7752{
7753 // check spell focus object
7755 {
7757 Cell cell(p);
7758
7759 GameObject* ok = nullptr;
7762
7764 Map& map = *m_caster->GetMap();
7765 cell.Visit(p, object_checker, map, *m_caster, m_caster->GetVisibilityRange());
7766
7767 if (!ok)
7769
7770 focusObject = ok; // game object found in range
7771 }
7772 return SPELL_CAST_OK;
7773}
@ SPELL_FAILED_REQUIRES_SPELL_FOCUS
Definition: SharedDefines.h:1051
CellCoord ComputeCellCoord(float x, float y)
Definition: GridDefines.h:190
Definition: TypeContainer.h:100
Definition: TypeContainerVisitor.h:84
Definition: Cell.h:45
Definition: GridNotifiers.h:319
Definition: GridNotifiers.h:657
Definition: Map.h:311
void Visit(const Cell &cell, TypeContainerVisitor< T, CONTAINER > &visitor)
Definition: Map.h:871
uint32 RequiresSpellFocus
Definition: SpellInfo.h:337

References Acore::ComputeCellCoord(), focusObject, WorldObject::GetMap(), Position::GetPositionX(), Position::GetPositionY(), WorldObject::GetVisibilityRange(), m_caster, m_spellInfo, SpellInfo::RequiresSpellFocus, SPELL_CAST_OK, SPELL_FAILED_REQUIRES_SPELL_FOCUS, and Cell::Visit().

Referenced by CheckCast().

◆ CheckSrc()

void Spell::CheckSrc ( )
inline
bool HasSrc() const
Definition: Spell.h:166
void SetSrc(float x, float y, float z)
Definition: Spell.cpp:367

References SpellCastTargets::HasSrc(), m_caster, m_targets, and SpellCastTargets::SetSrc().

◆ CleanupTargetList()

void Spell::CleanupTargetList ( )
2376{
2377 m_UniqueTargetInfo.clear();
2378 m_UniqueGOTargetInfo.clear();
2379 m_UniqueItemInfo.clear();
2380 m_delayMoment = 0;
2382}
uint64 m_delayTrajectory
Definition: Spell.h:644

References m_delayMoment, m_delayTrajectory, m_UniqueGOTargetInfo, m_UniqueItemInfo, and m_UniqueTargetInfo.

Referenced by spell_dk_raise_dead::CheckCast(), and Spell().

◆ Delayed()

void Spell::Delayed ( )
7776{
7777 if (!m_caster)// || !m_caster->IsPlayer())
7778 return;
7779
7780 //if (m_spellState == SPELL_STATE_DELAYED)
7781 // return; // spell is active and can't be time-backed
7782
7783 if (isDelayableNoMore()) // Spells may only be delayed twice
7784 return;
7785
7787 return;
7788
7789 // spells not loosing casting time (slam, dynamites, bombs..)
7790 //if (!(m_spellInfo->InterruptFlags & SPELL_INTERRUPT_FLAG_DAMAGE))
7791 // return;
7792
7793 //check pushback reduce
7794 int32 delaytime = 500; // spellcasting delay is normally 500ms
7795 int32 delayReduce = 100; // must be initialized to 100 for percent modifiers
7798 if (delayReduce >= 100)
7799 return;
7800
7801 AddPct(delaytime, -delayReduce);
7802
7803 if (m_timer + delaytime > m_casttime)
7804 {
7805 delaytime = m_casttime - m_timer;
7807 }
7808 else
7809 m_timer += delaytime;
7810
7811 LOG_DEBUG("spells", "Spell {} partially interrupted for ({}) ms at damage", m_spellInfo->Id, delaytime);
7812
7813 WorldPacket data(SMSG_SPELL_DELAYED, 8 + 4);
7814 data << m_caster->GetPackGUID();
7815 data << uint32(delaytime);
7816
7817 m_caster->SendMessageToSet(&data, true);
7818}
#define LOG_DEBUG(filterType__,...)
Definition: Log.h:169
T AddPct(T &base, U pct)
Definition: Util.h:67
@ SPELL_ATTR6_NO_PUSHBACK
Definition: SharedDefines.h:619
@ SPELLMOD_NOT_LOSE_CASTING_TIME
Definition: SpellDefines.h:85
@ SPELL_AURA_REDUCE_PUSHBACK
Definition: SpellAuraDefines.h:212
@ SMSG_SPELL_DELAYED
Definition: Opcodes.h:512
PackedGuid const & GetPackGUID() const
Definition: Object.h:114
virtual void SendMessageToSet(WorldPacket const *data, bool self) const
Definition: Object.cpp:2091
void ApplySpellMod(uint32 spellId, SpellModOp op, T &basevalue, Spell *spell=nullptr, bool temporaryPet=false)
Definition: Player.cpp:9761
int32 GetTotalAuraModifier(AuraType auratype) const
Definition: Unit.cpp:5910
Definition: WorldPacket.h:26
bool isDelayableNoMore()
Definition: Spell.h:632

References AddPct(), Player::ApplySpellMod(), Object::GetPackGUID(), Unit::GetTotalAuraModifier(), SpellInfo::HasAttribute(), SpellInfo::Id, isDelayableNoMore(), LOG_DEBUG, m_caster, m_casttime, m_spellInfo, m_timer, WorldObject::SendMessageToSet(), SMSG_SPELL_DELAYED, SPELL_ATTR6_NO_PUSHBACK, SPELL_AURA_REDUCE_PUSHBACK, SPELLMOD_NOT_LOSE_CASTING_TIME, and Object::ToPlayer().

◆ DelayedChannel()

void Spell::DelayedChannel ( )
7821{
7823 return;
7824
7825 if (isDelayableNoMore()) // Spells may only be delayed twice
7826 return;
7827
7829 return;
7830
7831 //check pushback reduce
7832 // should be affected by modifiers, not take the dbc duration.
7834
7835 int32 delaytime = CalculatePct(duration, 25); // channeling delay is normally 25% of its time per hit
7836 int32 delayReduce = 100; // must be initialized to 100 for percent modifiers
7839 if (delayReduce >= 100)
7840 return;
7841
7842 AddPct(delaytime, -delayReduce);
7843
7844 if (m_timer <= delaytime)
7845 {
7846 delaytime = m_timer;
7847 m_timer = 0;
7848 }
7849 else
7850 m_timer -= delaytime;
7851
7852 LOG_DEBUG("spells.aura", "Spell {} partially interrupted for {} ms, new duration: {} ms", m_spellInfo->Id, delaytime, m_timer);
7853
7854 for (std::list<TargetInfo>::const_iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
7855 if ((*ihit).missCondition == SPELL_MISS_NONE)
7856 if (Unit* unit = (m_caster->GetGUID() == ihit->targetGUID) ? m_caster : ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID))
7857 unit->DelayOwnedAuras(m_spellInfo->Id, m_originalCasterGUID, delaytime);
7858
7859 // partially interrupt persistent area auras
7861 dynObj->Delay(delaytime);
7862
7864}
T CalculatePct(T base, U pct)
Definition: Util.h:61
Definition: DynamicObject.h:35
DynamicObject * GetDynObject(uint32 spellId)
Definition: Unit.cpp:6128
uint32 getState() const
Definition: Spell.h:485
int32 GetDuration() const
Definition: SpellInfo.cpp:2338

References AddPct(), Player::ApplySpellMod(), CalculatePct(), SpellInfo::GetDuration(), Unit::GetDynObject(), Object::GetGUID(), getState(), Unit::GetTotalAuraModifier(), ObjectAccessor::GetUnit(), SpellInfo::HasAttribute(), SpellInfo::Id, isDelayableNoMore(), Object::IsPlayer(), LOG_DEBUG, m_caster, m_channeledDuration, m_originalCasterGUID, m_spellInfo, m_timer, m_UniqueTargetInfo, SendChannelUpdate(), SPELL_ATTR6_NO_PUSHBACK, SPELL_AURA_REDUCE_PUSHBACK, SPELL_MISS_NONE, SPELL_STATE_CASTING, SPELLMOD_NOT_LOSE_CASTING_TIME, and Object::ToPlayer().

◆ DoAllEffectOnLaunchTarget()

void Spell::DoAllEffectOnLaunchTarget ( TargetInfo targetInfo,
float *  multiplier 
)
protected
8304{
8305 Unit* unit = nullptr;
8306 // In case spell hit target, do all effect on that target
8307 if (targetInfo.missCondition == SPELL_MISS_NONE)
8308 unit = m_caster->GetGUID() == targetInfo.targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, targetInfo.targetGUID);
8309 // In case spell reflect from target, do all effect on caster (if hit)
8310 else if (targetInfo.missCondition == SPELL_MISS_REFLECT && targetInfo.reflectResult == SPELL_MISS_NONE)
8311 unit = m_caster;
8312 if (!unit)
8313 return;
8314
8315 for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i)
8316 {
8317 if (targetInfo.effectMask & (1 << i))
8318 {
8319 m_damage = 0;
8320 m_healing = 0;
8321
8322 HandleEffects(unit, nullptr, nullptr, i, SPELL_EFFECT_HANDLE_LAUNCH_TARGET);
8323
8324 if (m_damage > 0)
8325 {
8326 // Xinef: Area Auras, AoE Targetting spells AND Chain Target spells (cleave etc.)
8327 if (m_spellInfo->Effects[i].IsAreaAuraEffect() || m_spellInfo->Effects[i].IsTargetingArea() || (m_spellInfo->Effects[i].ChainTarget > 1 && m_spellInfo->DmgClass != SPELL_DAMAGE_CLASS_MAGIC))
8328 {
8330 if (m_caster->IsPlayer())
8331 {
8332 uint32 targetAmount = m_UniqueTargetInfo.size();
8333 if (targetAmount > 10)
8334 m_damage = m_damage * 10 / targetAmount;
8335 }
8336 }
8337 }
8338
8339 if (m_applyMultiplierMask & (1 << i))
8340 {
8342 m_damageMultipliers[i] *= multiplier[i];
8343 }
8344 targetInfo.damage += m_damage;
8345 }
8346 }
8347
8348 // xinef: totem's inherit owner crit chance and dancing rune weapon
8349 Unit* caster = m_caster;
8350 if (m_caster->IsTotem() || m_caster->GetEntry() == 27893)
8351 {
8352 if (Unit* owner = m_caster->GetOwner())
8353 caster = owner;
8354 }
8355 else if (m_originalCaster)
8356 caster = m_originalCaster;
8357
8358 float critChance = caster->SpellDoneCritChance(unit, m_spellInfo, m_spellSchoolMask, m_attackType, false);
8359 critChance = unit->SpellTakenCritChance(caster, m_spellInfo, m_spellSchoolMask, critChance, m_attackType, false);
8360 targetInfo.crit = roll_chance_f(std::max(0.0f, critChance));
8361}
bool roll_chance_f(float chance)
Definition: Random.h:53
float SpellTakenCritChance(Unit const *caster, SpellInfo const *spellProto, SpellSchoolMask schoolMask, float doneChance, WeaponAttackType attackType, bool skipEffectCheck) const
Definition: Unit.cpp:12069
float SpellDoneCritChance(Unit const *, SpellInfo const *spellProto, SpellSchoolMask schoolMask, WeaponAttackType attackType, bool skipEffectCheck) const
Definition: Unit.cpp:11994
int32 CalculateAOEDamageReduction(int32 damage, uint32 schoolMask, Unit *caster) const
Definition: Unit.cpp:20394
uint32 SchoolMask
Definition: SpellInfo.h:392

References Unit::CalculateAOEDamageReduction(), TargetInfo::crit, TargetInfo::damage, SpellInfo::DmgClass, TargetInfo::effectMask, SpellInfo::Effects, Object::GetEntry(), Object::GetGUID(), Unit::GetOwner(), ObjectAccessor::GetUnit(), HandleEffects(), Object::IsPlayer(), Unit::IsTotem(), m_applyMultiplierMask, m_attackType, m_caster, m_damage, m_damageMultipliers, m_healing, m_originalCaster, m_spellInfo, m_spellSchoolMask, m_UniqueTargetInfo, MAX_SPELL_EFFECTS, TargetInfo::missCondition, TargetInfo::reflectResult, roll_chance_f(), SpellInfo::SchoolMask, SPELL_DAMAGE_CLASS_MAGIC, SPELL_EFFECT_HANDLE_LAUNCH_TARGET, SPELL_MISS_NONE, SPELL_MISS_REFLECT, Unit::SpellDoneCritChance(), Unit::SpellTakenCritChance(), and TargetInfo::targetGUID.

Referenced by HandleLaunchPhase().

◆ DoAllEffectOnTarget() [1/3]

void Spell::DoAllEffectOnTarget ( GOTargetInfo target)
protected
3346{
3347 if (target->processed) // Check target
3348 return;
3349 target->processed = true; // Target checked in apply effects procedure
3350
3351 uint32 effectMask = target->effectMask;
3352 if (!effectMask)
3353 return;
3354
3355 GameObject* go = m_caster->GetMap()->GetGameObject(target->targetGUID);
3356 if (!go)
3357 return;
3358
3361
3362 for (uint32 effectNumber = 0; effectNumber < MAX_SPELL_EFFECTS; ++effectNumber)
3363 if (effectMask & (1 << effectNumber))
3364 HandleEffects(nullptr, nullptr, go, effectNumber, SPELL_EFFECT_HANDLE_HIT_TARGET);
3365
3366 // xinef: inform ai about spellhit
3368
3370
3372}
virtual void SpellHit(Unit *, SpellInfo const *)
Definition: GameObjectAI.h:66
GameObjectAI * AI() const
Definition: GameObject.h:306
void CallScriptBeforeHitHandlers(SpellMissInfo missInfo)
Definition: Spell.cpp:8644
void CallScriptOnHitHandlers()
Definition: Spell.cpp:8657
void CallScriptAfterHitHandlers()
Definition: Spell.cpp:8670

References GameObject::AI(), CallScriptAfterHitHandlers(), CallScriptBeforeHitHandlers(), CallScriptOnHitHandlers(), Spell::GOTargetInfo::effectMask, Map::GetGameObject(), WorldObject::GetMap(), HandleEffects(), m_caster, m_spellInfo, MAX_SPELL_EFFECTS, PrepareScriptHitHandlers(), Spell::GOTargetInfo::processed, SPELL_EFFECT_HANDLE_HIT_TARGET, SPELL_MISS_NONE, GameObjectAI::SpellHit(), and Spell::GOTargetInfo::targetGUID.

◆ DoAllEffectOnTarget() [2/3]

void Spell::DoAllEffectOnTarget ( ItemTargetInfo target)
protected
3375{
3376 uint32 effectMask = target->effectMask;
3377 if (!target->item || !effectMask)
3378 return;
3379
3382
3383 for (uint32 effectNumber = 0; effectNumber < MAX_SPELL_EFFECTS; ++effectNumber)
3384 if (effectMask & (1 << effectNumber))
3385 HandleEffects(nullptr, target->item, nullptr, effectNumber, SPELL_EFFECT_HANDLE_HIT_TARGET);
3386
3388
3390}

References CallScriptAfterHitHandlers(), CallScriptBeforeHitHandlers(), CallScriptOnHitHandlers(), Spell::ItemTargetInfo::effectMask, HandleEffects(), Spell::ItemTargetInfo::item, MAX_SPELL_EFFECTS, PrepareScriptHitHandlers(), SPELL_EFFECT_HANDLE_HIT_TARGET, and SPELL_MISS_NONE.

◆ DoAllEffectOnTarget() [3/3]

void Spell::DoAllEffectOnTarget ( TargetInfo target)
protected
Todo:
: check how broad this rule should be
2614{
2615 if (!target || target->processed)
2616 return;
2617
2618 target->processed = true; // Target checked in apply effects procedure
2619
2620 // Get mask of effects for target
2621 uint8 mask = target->effectMask;
2622
2623 Unit* effectUnit = m_caster->GetGUID() == target->targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, target->targetGUID);
2624 if (!effectUnit && !target->targetGUID.IsPlayer()) // only players may be targeted across maps
2625 return;
2626
2627 if (!effectUnit || m_spellInfo->Id == 45927)
2628 {
2629 uint8 farMask = 0;
2630 // create far target mask
2631 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
2632 if (m_spellInfo->Effects[i].IsFarUnitTargetEffect())
2633 if ((1 << i) & mask)
2634 farMask |= (1 << i);
2635
2636 if (!farMask)
2637 return;
2638 // find unit in world
2639 // Xinef: FindUnit Access without Map check!!! Intended
2640 effectUnit = ObjectAccessor::FindPlayer(target->targetGUID);
2641 if (!effectUnit)
2642 return;
2643
2644 // do far effects on the unit
2645 // can't use default call because of threading, do stuff as fast as possible
2646 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
2647 if (farMask & (1 << i))
2648 HandleEffects(effectUnit, nullptr, nullptr, i, SPELL_EFFECT_HANDLE_HIT_TARGET);
2649 return;
2650 }
2651
2652 if (effectUnit->IsAlive() != target->alive)
2653 return;
2654
2655 // Xinef: absorb delayed projectiles for 500ms
2657 (GameTime::GetGameTimeMS().count() - target->timeDelay) <= effectUnit->m_lastSanctuaryTime && GameTime::GetGameTimeMS().count() < (effectUnit->m_lastSanctuaryTime + 500) &&
2658 effectUnit->FindMap() && !effectUnit->FindMap()->IsDungeon()
2659 )
2660 return; // No missinfo in that case
2661
2662 // Get original caster (if exist) and calculate damage/healing from him data
2664
2665 // Skip if m_originalCaster not avaiable
2666 if (!caster)
2667 return;
2668
2669 SpellMissInfo missInfo = target->missCondition;
2670
2671 // Need init unitTarget by default unit (can changed in code on reflect)
2672 // Or on missInfo != SPELL_MISS_NONE unitTarget undefined (but need in trigger subsystem)
2673 unitTarget = effectUnit;
2674
2675 // Reset damage/healing counter
2676 m_damage = target->damage;
2677 m_healing = -target->damage;
2678
2679 m_spellAura = nullptr; // Set aura to null for every target-make sure that pointer is not used for unit without aura applied
2680
2683
2684 //Spells with this flag cannot trigger if effect is casted on self
2686 bool reflectedSpell = missInfo == SPELL_MISS_REFLECT;
2687 Unit* spellHitTarget = nullptr;
2688
2689 if (missInfo == SPELL_MISS_NONE) // In case spell hit target, do all effect on that target
2690 spellHitTarget = unitTarget;
2691 else if (missInfo == SPELL_MISS_REFLECT) // In case spell reflect from target, do all effect on caster (if hit)
2692 {
2693 missInfo = target->reflectResult;
2694 if (missInfo == SPELL_MISS_NONE) // If reflected spell hit caster -> do all effect on him
2695 {
2696 spellHitTarget = m_caster;
2698 if (m_caster->IsCreature())
2700 }
2701 }
2702
2703 if (spellHitTarget)
2704 {
2705 SpellMissInfo missInfo2 = DoSpellHitOnUnit(spellHitTarget, mask, target->scaleAura);
2706 if (missInfo2 != SPELL_MISS_NONE)
2707 {
2708 if (missInfo2 != SPELL_MISS_MISS)
2709 m_caster->SendSpellMiss(spellHitTarget, m_spellInfo->Id, missInfo2);
2710 m_damage = 0;
2711 spellHitTarget = nullptr;
2712
2713 // Xinef: if missInfo2 is MISS_EVADE, override base missinfo data
2714 if (missInfo2 == SPELL_MISS_EVADE)
2715 missInfo = SPELL_MISS_EVADE;
2716 }
2717 }
2718
2719 // Do not take combo points on dodge and miss
2720 if (missInfo != SPELL_MISS_NONE && m_needComboPoints && m_targets.GetUnitTargetGUID() == target->targetGUID)
2721 {
2722 m_needComboPoints = false;
2723 // Restore spell mods for a miss/dodge/parry Cold Blood
2725 if (m_caster->IsPlayer() && (missInfo == SPELL_MISS_MISS || missInfo == SPELL_MISS_DODGE || missInfo == SPELL_MISS_PARRY))
2726 m_caster->ToPlayer()->RestoreSpellMods(this, 14177);
2727 }
2728
2729 // Fill base trigger info
2730 uint32 procAttacker = m_procAttacker;
2731 uint32 procVictim = m_procVictim;
2732 uint32 procEx = m_procEx;
2733
2734 // Trigger info was not filled in spell::preparedatafortriggersystem - we do it now
2735 if (canEffectTrigger && !procAttacker && !procVictim)
2736 {
2737 bool positive = true;
2738 if (m_damage > 0)
2739 positive = false;
2740 else if (!m_healing)
2741 {
2742 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
2743 // If at least one effect negative spell is negative hit
2744 // Xinef: if missInfo is immune state check all effects to properly determine positiveness of spell
2745 if ((missInfo == SPELL_MISS_IMMUNE2 || (mask & (1 << i))) && !m_spellInfo->IsPositiveEffect(i))
2746 {
2747 positive = false;
2748 break;
2749 }
2750 }
2751 switch (m_spellInfo->DmgClass)
2752 {
2754 if (positive)
2755 {
2758 }
2759 else
2760 {
2763 }
2764 break;
2766 if (positive)
2767 {
2770 }
2771 else
2772 {
2775 }
2776 break;
2777 }
2778 }
2780
2781 // All calculated do it!
2782 // Do healing and triggers
2783 if (m_healing > 0)
2784 {
2785 bool crit = target->crit;
2786 uint32 addhealth = m_healing;
2787
2788 if (crit)
2789 {
2790 procEx |= PROC_EX_CRITICAL_HIT;
2791 addhealth = Unit::SpellCriticalHealingBonus(caster, m_spellInfo, addhealth, nullptr);
2792 }
2793 else
2794 procEx |= PROC_EX_NORMAL_HIT;
2795
2796 HealInfo healInfo(caster, unitTarget, addhealth, m_spellInfo, m_spellInfo->GetSchoolMask());
2797
2798 // Xinef: override with forced crit, only visual result
2799 if (GetSpellValue()->ForcedCritResult)
2800 {
2801 crit = true;
2802 procEx |= PROC_EX_CRITICAL_HIT;
2803 }
2804
2805 int32 gain = caster->HealBySpell(healInfo, crit);
2806 unitTarget->getHostileRefMgr().threatAssist(caster, float(gain) * 0.5f, m_spellInfo);
2807 m_healing = gain;
2808
2809 // Xinef: if heal acutally healed something, add no overheal flag
2810 if (m_healing)
2811 procEx |= PROC_EX_NO_OVERHEAL;
2812
2813 // Do triggers for unit (reflect triggers passed on hit phase for correct drop charge)
2814 if (canEffectTrigger)
2815 Unit::ProcDamageAndSpell(caster, unitTarget, procAttacker, procVictim, procEx, addhealth, m_attackType, m_spellInfo, m_triggeredByAuraSpell.spellInfo,
2816 m_triggeredByAuraSpell.effectIndex, this, nullptr, &healInfo);
2817 }
2818 // Do damage and triggers
2819 else if (m_damage > 0)
2820 {
2822
2823 // Fill base damage struct (unitTarget - is real spell target)
2825
2826 // Add bonuses and fill damageInfo struct
2827 // Dancing Rune Weapon...
2828 if (m_caster->GetEntry() == 27893)
2829 {
2830 if (Unit* owner = m_caster->GetOwner())
2831 owner->CalculateSpellDamageTaken(&damageInfo, m_damage, m_spellInfo, m_attackType, target->crit);
2832 }
2833 else
2834 caster->CalculateSpellDamageTaken(&damageInfo, m_damage, m_spellInfo, m_attackType, target->crit);
2835
2836 // xinef: override miss info after absorb / block calculations
2837 if (missInfo == SPELL_MISS_NONE && damageInfo.damage == 0)
2838 {
2839 //if (damageInfo.absorb > 0)
2840 // missInfo = SPELL_MISS_ABSORB;
2841 if (damageInfo.blocked)
2842 missInfo = SPELL_MISS_BLOCK;
2843 }
2844
2845 // Xinef: override with forced crit, only visual result
2846 if (GetSpellValue()->ForcedCritResult)
2847 {
2848 damageInfo.HitInfo |= SPELL_HIT_TYPE_CRIT;
2849 }
2850
2851 Unit::DealDamageMods(damageInfo.target, damageInfo.damage, &damageInfo.absorb);
2852
2853 // xinef: health leech handling
2855 {
2856 uint8 effIndex = EFFECT_0;
2857 for (; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
2858 if (m_spellInfo->Effects[effIndex].Effect == SPELL_EFFECT_HEALTH_LEECH)
2859 break;
2860
2861 float healMultiplier = m_spellInfo->Effects[effIndex].CalcValueMultiplier(m_originalCaster, this);
2862
2863 // get max possible damage, don't count overkill for heal
2864 uint32 healthGain = uint32(-unitTarget->GetHealthGain(-int32(damageInfo.damage)) * healMultiplier);
2865
2866 if (m_caster->IsAlive())
2867 {
2868 healthGain = m_caster->SpellHealingBonusDone(m_caster, m_spellInfo, healthGain, HEAL, effIndex);
2869 healthGain = m_caster->SpellHealingBonusTaken(m_caster, m_spellInfo, healthGain, HEAL);
2870
2871 HealInfo healInfo(m_caster, m_caster, healthGain, m_spellInfo, m_spellInfo->GetSchoolMask());
2872 m_caster->HealBySpell(healInfo);
2873 }
2874 }
2875
2876 // Send log damage message to client
2877 caster->SendSpellNonMeleeDamageLog(&damageInfo);
2878 // Xinef: send info to target about reflect
2879 if (reflectedSpell)
2880 effectUnit->SendSpellNonMeleeReflectLog(&damageInfo, effectUnit);
2881
2882 procEx |= createProcExtendMask(&damageInfo, missInfo);
2883 procVictim |= PROC_FLAG_TAKEN_DAMAGE;
2884
2885 caster->DealSpellDamage(&damageInfo, true, this);
2886
2887 // do procs after damage, eg healing effects
2888 // no need to check if target is alive, done in procdamageandspell
2889
2890 // Do triggers for unit (reflect triggers passed on hit phase for correct drop charge)
2891 if (canEffectTrigger)
2892 {
2893 DamageInfo dmgInfo(damageInfo, SPELL_DIRECT_DAMAGE);
2894 Unit::ProcDamageAndSpell(caster, unitTarget, procAttacker, procVictim, procEx, damageInfo.damage, m_attackType, m_spellInfo, m_triggeredByAuraSpell.spellInfo,
2895 m_triggeredByAuraSpell.effectIndex, this, &dmgInfo);
2896
2899 caster->ToPlayer()->CastItemCombatSpell(unitTarget, m_attackType, procVictim, procEx);
2900 }
2901
2902 m_damage = damageInfo.damage;
2903 }
2904 // Passive spell hits/misses or active spells only misses (only triggers)
2905 else
2906 {
2907 // Fill base damage struct (unitTarget - is real spell target)
2909 procEx |= createProcExtendMask(&damageInfo, missInfo);
2910 // Do triggers for unit (reflect triggers passed on hit phase for correct drop charge)
2911 if (canEffectTrigger)
2912 {
2913 DamageInfo dmgInfo(damageInfo, NODAMAGE);
2914 Unit::ProcDamageAndSpell(caster, unitTarget, procAttacker, procVictim, procEx, 0, m_attackType, m_spellInfo, m_triggeredByAuraSpell.spellInfo,
2915 m_triggeredByAuraSpell.effectIndex, this, &dmgInfo);
2916
2917 // Xinef: eg. rogue poisons can proc off cheap shot, etc. so this block should be here also
2918 // Xinef: ofc count only spells that HIT the target, little hack used to fool the system
2922 }
2923
2924 // Failed Pickpocket, reveal rogue
2926 {
2930 }
2931 }
2932
2933 if (m_caster)
2934 {
2936 {
2939
2940 // Patch 3.0.8: All player spells which cause a creature to become aggressive to you will now also immediately cause the creature to be tapped.
2941 if (effectUnit->IsInCombatWith(m_caster))
2942 {
2943 if (Creature* creature = effectUnit->ToCreature())
2944 {
2945 if (!creature->hasLootRecipient() && m_caster->IsPlayer())
2946 {
2947 creature->SetLootRecipient(m_caster);
2948 }
2949 }
2950 }
2951
2952 // Unsure if there are more spells that are not supposed to stop enemy from
2953 // regenerating HP from food, so for now it stays as an ID.
2954 const uint32 SPELL_PREMEDITATION = 14183;
2955 if (m_spellInfo->Id != SPELL_PREMEDITATION)
2956 {
2957 if (!effectUnit->IsStandState())
2958 {
2960 }
2961 }
2962 }
2963 }
2964
2965 if (missInfo != SPELL_MISS_EVADE && effectUnit != m_caster && m_caster->IsFriendlyTo(effectUnit) && m_spellInfo->IsPositive() &&
2967 {
2968 m_caster->SetInCombatWith(effectUnit);
2969 }
2970
2971 // Check for SPELL_ATTR7_CAN_CAUSE_INTERRUPT
2973 caster->CastSpell(effectUnit, SPELL_INTERRUPT_NONPLAYER, true);
2974
2975 if (spellHitTarget)
2976 {
2977 //AI functions
2978 if (spellHitTarget->IsCreature())
2979 {
2980 if (spellHitTarget->ToCreature()->IsAIEnabled)
2981 spellHitTarget->ToCreature()->AI()->SpellHit(m_caster, m_spellInfo);
2982 }
2983
2985 m_caster->ToCreature()->AI()->SpellHitTarget(spellHitTarget, m_spellInfo);
2986
2987 // Needs to be called after dealing damage/healing to not remove breaking on damage auras
2988 DoTriggersOnSpellHit(spellHitTarget, mask);
2989
2990 // if target is fallged for pvp also flag caster if a player
2991 // xinef: do not flag spells with aura bind sight (no special attribute)
2992 if (effectUnit->IsPvP() && effectUnit != m_caster && effectUnit->GetOwnerGUID() != m_caster->GetGUID() &&
2994 {
2995 m_caster->ToPlayer()->UpdatePvP(true);
2996 }
2997
2999 }
3000}
@ SPELL_EFFECT_HEALTH_LEECH
Definition: SharedDefines.h:787
@ SPELL_ATTR1_NO_THREAT
Definition: SharedDefines.h:429
@ SPELL_ATTR3_SUPPRESS_CASTER_PROCS
Definition: SharedDefines.h:509
@ SPELL_ATTR0_CANCELS_AUTO_ATTACK_COMBAT
Definition: SharedDefines.h:402
@ SPELL_HIT_TYPE_CRIT
Definition: SharedDefines.h:1536
SpellMissInfo
Definition: SharedDefines.h:1518
@ SPELL_MISS_DODGE
Definition: SharedDefines.h:1522
@ SPELL_MISS_IMMUNE2
Definition: SharedDefines.h:1527
@ SPELL_MISS_RESIST
Definition: SharedDefines.h:1521
@ SPELL_MISS_MISS
Definition: SharedDefines.h:1520
@ SPELL_MISS_BLOCK
Definition: SharedDefines.h:1524
@ SPELL_ATTR4_SUPPRESS_WEAPON_PROCS
Definition: SharedDefines.h:553
@ SPELL_ATTR0_CU_NO_PVP_FLAG
Definition: SpellInfo.h:183
@ SPELL_ATTR0_CU_PICKPOCKET
Definition: SpellInfo.h:186
static const uint32 SPELL_INTERRUPT_NONPLAYER
Definition: Spell.h:270
@ AURA_INTERRUPT_FLAG_TALK
Definition: SpellDefines.h:53
@ PROC_EX_NO_OVERHEAL
Definition: SpellMgr.h:213
@ PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_NEG
Definition: SpellMgr.h:132
@ PROC_FLAG_TAKEN_SPELL_NONE_DMG_CLASS_NEG
Definition: SpellMgr.h:126
@ PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_POS
Definition: SpellMgr.h:129
@ PROC_FLAG_TAKEN_DAMAGE
Definition: SpellMgr.h:137
@ PROC_FLAG_TAKEN_SPELL_NONE_DMG_CLASS_POS
Definition: SpellMgr.h:123
@ NODAMAGE
Definition: Unit.h:252
@ SPELL_DIRECT_DAMAGE
Definition: Unit.h:249
@ HEAL
Definition: Unit.h:251
uint32 createProcExtendMask(SpellNonMeleeDamage *damageInfo, SpellMissInfo missCondition)
Definition: Unit.cpp:15994
@ UNIT_STAND_STATE_STAND
Definition: UnitDefines.h:32
Milliseconds GetGameTimeMS()
Definition: GameTime.cpp:43
virtual void AttackStart(Unit *)
Definition: UnitAI.cpp:27
virtual void SpellHitTarget(Unit *, SpellInfo const *)
Definition: CreatureAI.h:147
virtual void SpellHit(Unit *, SpellInfo const *)
Definition: CreatureAI.h:144
void threatAssist(Unit *victim, float baseThreat, SpellInfo const *threatSpell=nullptr)
Definition: HostileRefMgr.cpp:35
void LowerPlayerDamageReq(uint32 unDamage, bool damagedByPlayer=true)
Definition: Creature.cpp:3806
CreatureAI * AI() const
Definition: Creature.h:140
void RestoreSpellMods(Spell *spell, uint32 ownerAuraId=0, Aura *aura=nullptr)
Definition: Player.cpp:9967
void CastItemCombatSpell(Unit *target, WeaponAttackType attType, uint32 procVictim, uint32 procEx)
Definition: Player.cpp:7232
void UpdatePvP(bool state, bool _override=false)
Definition: PlayerUpdates.cpp:1484
Definition: Unit.h:330
Definition: Unit.h:373
Definition: Unit.h:489
uint32 m_lastSanctuaryTime
Definition: Unit.h:1956
void DealSpellDamage(SpellNonMeleeDamage *damageInfo, bool durabilityLoss, Spell const *spell=nullptr)
Definition: Unit.cpp:1438
void SendSpellMiss(Unit *target, uint32 spellID, SpellMissInfo missInfo)
Definition: Unit.cpp:6445
void SendSpellNonMeleeReflectLog(SpellNonMeleeDamage *log, Unit *attacker)
Definition: Unit.cpp:6278
bool CanProc()
Definition: Unit.h:1430
bool IsPvP() const
Definition: Unit.h:981
uint32 SpellHealingBonusDone(Unit *victim, SpellInfo const *spellProto, uint32 healamount, DamageEffectType damagetype, uint8 effIndex, float TotalMod=0.0f, uint32 stack=1)
Definition: Unit.cpp:12452
void SetInCombatWith(Unit *enemy, uint32 duration=0)
Definition: Unit.cpp:13581
int32 HealBySpell(HealInfo &healInfo, bool critical=false)
Definition: Unit.cpp:11244
bool IsStandState() const
Definition: Unit.cpp:16720
bool IsInCombatWith(Unit const *who) const
Definition: Unit.cpp:21038
HostileRefMgr & getHostileRefMgr()
Definition: Unit.h:907
int32 GetHealthGain(int32 dVal)
Definition: Unit.cpp:14123
static uint32 SpellCriticalHealingBonus(Unit const *caster, SpellInfo const *spellProto, uint32 damage, Unit const *victim)
Definition: Unit.cpp:12321
void SendSpellNonMeleeDamageLog(SpellNonMeleeDamage *log)
Definition: Unit.cpp:6310
bool IsAIEnabled
Definition: Unit.h:1962
void SetLastDamagedTargetGuid(ObjectGuid const &guid)
Definition: Unit.h:916
uint32 SpellHealingBonusTaken(Unit *caster, SpellInfo const *spellProto, uint32 healamount, DamageEffectType damagetype, uint32 stack=1)
Definition: Unit.cpp:12570
void SetStandState(uint8 state)
Definition: Unit.cpp:16726
void RemoveAurasWithInterruptFlags(uint32 flag, uint32 except=0, bool isAutoshot=false)
Definition: Unit.cpp:5181
static void DealDamageMods(Unit const *victim, uint32 &damage, uint32 *absorb)
Definition: Unit.cpp:800
void CalculateSpellDamageTaken(SpellNonMeleeDamage *damageInfo, int32 damage, SpellInfo const *spellInfo, WeaponAttackType attackType=BASE_ATTACK, bool crit=false)
Definition: Unit.cpp:1295
ObjectGuid GetUnitTargetGUID() const
Definition: Spell.cpp:216
bool CanExecuteTriggersOnHit(uint8 effMask, SpellInfo const *triggeredByAura=nullptr) const
Definition: Spell.cpp:8748
SpellValue const * GetSpellValue()
Definition: Spell.h:587
SpellMissInfo DoSpellHitOnUnit(Unit *unit, uint32 effectMask, bool scaleAura)
Definition: Spell.cpp:3002
void DoTriggersOnSpellHit(Unit *unit, uint8 effMask)
Definition: Spell.cpp:3268
uint32 AttributesEx3
Definition: SpellInfo.h:327
bool IsAuraEffectEqual(SpellInfo const *otherSpellInfo) const
Definition: SpellInfo.cpp:1698
bool IsTargetingArea() const
Definition: SpellInfo.cpp:1025
bool IsPositiveEffect(uint8 effIndex) const
Definition: SpellInfo.cpp:1242

References SpellNonMeleeDamage::absorb, Creature::AI(), TargetInfo::alive, UnitAI::AttackStart(), SpellInfo::AttributesEx3, AURA_INTERRUPT_FLAG_TALK, SpellNonMeleeDamage::blocked, Unit::CalculateSpellDamageTaken(), CallScriptAfterHitHandlers(), CallScriptBeforeHitHandlers(), CallScriptOnHitHandlers(), CanExecuteTriggersOnHit(), Unit::CanProc(), Player::CastItemCombatSpell(), Unit::CastSpell(), Unit::CombatStart(), createProcExtendMask(), TargetInfo::crit, SpellNonMeleeDamage::damage, TargetInfo::damage, Unit::DealDamageMods(), Unit::DealSpellDamage(), SpellInfo::DmgClass, DoSpellHitOnUnit(), DoTriggersOnSpellHit(), EFFECT_0, TriggeredByAuraSpellData::effectIndex, TargetInfo::effectMask, SpellInfo::Effects, WorldObject::FindMap(), ObjectAccessor::FindPlayer(), Object::GetEntry(), GameTime::GetGameTimeMS(), Object::GetGUID(), Unit::GetHealthGain(), Unit::getHostileRefMgr(), Unit::GetOwner(), Unit::GetOwnerGUID(), SpellInfo::GetSchoolMask(), GetSpellValue(), getState(), ObjectAccessor::GetUnit(), SpellCastTargets::GetUnitTargetGUID(), HandleEffects(), SpellInfo::HasAttribute(), SpellInfo::HasEffect(), HEAL, Unit::HealBySpell(), SpellNonMeleeDamage::HitInfo, SpellInfo::Id, Unit::IsAIEnabled, Unit::IsAlive(), SpellInfo::IsAuraEffectEqual(), Object::IsCreature(), Map::IsDungeon(), Unit::IsFriendlyTo(), Unit::IsInCombat(), Unit::IsInCombatWith(), Object::IsPlayer(), ObjectGuid::IsPlayer(), SpellInfo::IsPositive(), SpellInfo::IsPositiveEffect(), Unit::IsPvP(), Unit::IsStandState(), SpellInfo::IsTargetingArea(), Creature::LowerPlayerDamageReq(), m_attackType, m_caster, m_damage, m_healing, Unit::m_lastSanctuaryTime, m_needComboPoints, m_originalCaster, m_procAttacker, m_procEx, m_procVictim, m_spellAura, m_spellInfo, m_spellSchoolMask, m_targets, m_triggeredByAuraSpell, MAX_SPELL_EFFECTS, TargetInfo::missCondition, NODAMAGE, PrepareScriptHitHandlers(), PROC_EX_CRITICAL_HIT, PROC_EX_NO_OVERHEAL, PROC_EX_NORMAL_HIT, PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG, PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_POS, PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_NEG, PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_POS, PROC_FLAG_TAKEN_DAMAGE, PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_NEG, PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_POS, PROC_FLAG_TAKEN_SPELL_NONE_DMG_CLASS_NEG, PROC_FLAG_TAKEN_SPELL_NONE_DMG_CLASS_POS, Unit::ProcDamageAndSpell(), TargetInfo::processed, TargetInfo::reflectResult, Unit::RemoveAurasWithInterruptFlags(), Player::RestoreSpellMods(), TargetInfo::scaleAura, Unit::SendSpellMiss(), Unit::SendSpellNonMeleeDamageLog(), Unit::SendSpellNonMeleeReflectLog(), Unit::SetInCombatWith(), Unit::SetLastDamagedTargetGuid(), Unit::SetStandState(), SPELL_ATTR0_CANCELS_AUTO_ATTACK_COMBAT, SPELL_ATTR0_CU_NO_PVP_FLAG, SPELL_ATTR0_CU_PICKPOCKET, SPELL_ATTR1_NO_THREAT, SPELL_ATTR3_SUPPRESS_CASTER_PROCS, SPELL_ATTR3_SUPPRESS_TARGET_PROCS, SPELL_ATTR4_SUPPRESS_WEAPON_PROCS, SPELL_ATTR7_CAN_CAUSE_INTERRUPT, SPELL_DAMAGE_CLASS_MAGIC, SPELL_DAMAGE_CLASS_MELEE, SPELL_DAMAGE_CLASS_NONE, SPELL_DAMAGE_CLASS_RANGED, SPELL_DIRECT_DAMAGE, SPELL_EFFECT_DISPEL, SPELL_EFFECT_HANDLE_HIT_TARGET, SPELL_EFFECT_HEALTH_LEECH, SPELL_HIT_TYPE_CRIT, SPELL_INTERRUPT_NONPLAYER, SPELL_MISS_BLOCK, SPELL_MISS_DODGE, SPELL_MISS_EVADE, SPELL_MISS_IMMUNE2, SPELL_MISS_MISS, SPELL_MISS_NONE, SPELL_MISS_PARRY, SPELL_MISS_REFLECT, SPELL_MISS_RESIST, SPELL_STATE_DELAYED, Unit::SpellCriticalHealingBonus(), Unit::SpellHealingBonusDone(), Unit::SpellHealingBonusTaken(), CreatureAI::SpellHit(), CreatureAI::SpellHitTarget(), TriggeredByAuraSpellData::spellInfo, SpellNonMeleeDamage::target, TargetInfo::targetGUID, HostileRefMgr::threatAssist(), TargetInfo::timeDelay, Object::ToCreature(), Object::ToPlayer(), UNIT_STAND_STATE_STAND, unitTarget, and Player::UpdatePvP().

Referenced by _handle_immediate_phase(), handle_delayed(), and handle_immediate().

◆ DoCreateItem()

void Spell::DoCreateItem ( uint8  effIndex,
uint32  itemId 
)
1648{
1649 if (!unitTarget)
1650 return;
1651
1652 Player* player = unitTarget->ToPlayer();
1653 if (!player)
1654 {
1655 return;
1656 }
1657
1658 uint32 newitemid = itemId;
1659
1660 ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(newitemid);
1661 if (!pProto)
1662 {
1663 player->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, nullptr, nullptr);
1664 return;
1665 }
1666
1667 uint32 addNumber = damage;
1668
1669 // bg reward have some special in code work
1670 bool SelfCast = true;
1671 switch (m_spellInfo->Id)
1672 {
1677 case SPELL_WS_MARK_TIE:
1680 SelfCast = true;
1681 break;
1683 if (player->HasAura(55629 /*SPELL_LIEUTENANT*/))
1684 addNumber = 3;
1685 else if (player->HasAura(33280 /*SPELL_CORPORAL*/))
1686 addNumber = 2;
1687 else
1688 addNumber = 1;
1689 SelfCast = true;
1690 break;
1691 }
1692
1693 if (addNumber < 1)
1694 addNumber = 1;
1695 if (addNumber > pProto->GetMaxStackSize())
1696 addNumber = pProto->GetMaxStackSize();
1697
1698 /* == gem perfection handling == */
1699
1700 // the chance of getting a perfect result
1701 float perfectCreateChance = 0.0f;
1702
1703 // the resulting perfect item if successful
1704 uint32 perfectItemType = itemId;
1705
1706 // get perfection capability and chance
1707 if (CanCreatePerfectItem(player, m_spellInfo->Id, perfectCreateChance, perfectItemType))
1708 if (roll_chance_f(perfectCreateChance)) // if the roll succeeds...
1709 newitemid = perfectItemType; // the perfect item replaces the regular one
1710
1711 /* == gem perfection handling over == */
1712
1713 /* == profession specialization handling == */
1714
1715 // init items_count to 1, since 1 item will be created regardless of specialization
1716 int32 itemsCount = 1;
1717 float additionalCreateChance = 0.0f;
1718 int32 additionalMaxNum = 0;
1719 // get the chance and maximum number for creating extra items
1720 if (canCreateExtraItems(player, m_spellInfo->Id, additionalCreateChance, additionalMaxNum))
1721 {
1722 // roll with this chance till we roll not to create or we create the max num
1723 while (roll_chance_f(additionalCreateChance) && itemsCount <= additionalMaxNum)
1724 ++itemsCount;
1725 }
1726
1727 // really will be created more items
1728 addNumber *= itemsCount;
1729
1730 /* == profession specialization handling over == */
1731
1732 // can the player store the new item?
1733 ItemPosCountVec dest;
1734 uint32 no_space = 0;
1735 InventoryResult msg = player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, newitemid, addNumber, &no_space);
1736 if (msg != EQUIP_ERR_OK)
1737 {
1738 // convert to possible store amount
1740 addNumber -= no_space;
1741 else
1742 {
1743 // if not created by another reason from full inventory or unique items amount limitation
1744 player->SendEquipError(msg, nullptr, nullptr, newitemid);
1745 return;
1746 }
1747 }
1748
1749 if (addNumber)
1750 {
1751 // create the new item and store it
1752 Item* pItem = player->StoreNewItem(dest, newitemid, true);
1753
1754 // was it successful? return error if not
1755 if (!pItem)
1756 {
1757 player->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, nullptr, nullptr);
1758 return;
1759 }
1760
1761 // set the "Crafted by ..." property of the item
1762 if (pItem->GetTemplate()->HasSignature())
1763 pItem->SetGuidValue(ITEM_FIELD_CREATOR, player->GetGUID());
1764
1765 // send info to the client
1766 player->SendNewItem(pItem, addNumber, true, SelfCast);
1767
1768 sScriptMgr->OnCreateItem(player, pItem, addNumber);
1769
1770 // we succeeded in creating at least one item, so a levelup is possible
1771 if (SelfCast)
1773 }
1774}
bool canCreateExtraItems(Player *player, uint32 spellId, float &additionalChance, int32 &newMaxOrEntry)
Definition: SkillExtraItems.cpp:226
bool CanCreatePerfectItem(Player *player, uint32 spellId, float &perfectCreateChance, uint32 &perfectItemType)
Definition: SkillExtraItems.cpp:202
@ EQUIP_ERR_ITEM_NOT_FOUND
Definition: Item.h:70
@ EQUIP_ERR_CANT_CARRY_MORE_OF_THIS
Definition: Item.h:64
@ ITEM_FIELD_CREATOR
Definition: UpdateFields.h:37
@ SPELL_WS_MARK_WINNER
Definition: Battleground.h:106
@ SPELL_AV_MARK_LOSER
Definition: Battleground.h:110
@ SPELL_WS_MARK_TIE
Definition: Battleground.h:107
@ SPELL_WS_MARK_LOSER
Definition: Battleground.h:105
@ SPELL_AB_MARK_LOSER
Definition: Battleground.h:108
@ SPELL_WG_MARK_WINNER
Definition: Battleground.h:114
@ SPELL_AB_MARK_WINNER
Definition: Battleground.h:109
@ SPELL_AV_MARK_WINNER
Definition: Battleground.h:111
bool HasSignature() const
Definition: ItemTemplate.h:698
void SetGuidValue(uint16 index, ObjectGuid value)
Definition: Object.cpp:723
bool UpdateCraftSkill(uint32 spellid)
Definition: PlayerUpdates.cpp:783
void SendNewItem(Item *item, uint32 count, bool received, bool created, bool broadcast=false, bool sendChatMessage=true)
Definition: PlayerStorage.cpp:4751
Item * StoreNewItem(ItemPosCountVec const &pos, uint32 item, bool update, int32 randomPropertyId=0)
Definition: PlayerStorage.cpp:2524

References canCreateExtraItems(), CanCreatePerfectItem(), Player::CanStoreNewItem(), damage, EQUIP_ERR_CANT_CARRY_MORE_OF_THIS, EQUIP_ERR_INVENTORY_FULL, EQUIP_ERR_ITEM_NOT_FOUND, EQUIP_ERR_OK, Object::GetGUID(), ItemTemplate::GetMaxStackSize(), Item::GetTemplate(), Unit::HasAura(), ItemTemplate::HasSignature(), SpellInfo::Id, ITEM_FIELD_CREATOR, m_spellInfo, NULL_BAG, NULL_SLOT, roll_chance_f(), Player::SendEquipError(), Player::SendNewItem(), Object::SetGuidValue(), sObjectMgr, SPELL_AB_MARK_LOSER, SPELL_AB_MARK_WINNER, SPELL_AV_MARK_LOSER, SPELL_AV_MARK_WINNER, SPELL_WG_MARK_WINNER, SPELL_WS_MARK_LOSER, SPELL_WS_MARK_TIE, SPELL_WS_MARK_WINNER, sScriptMgr, Player::StoreNewItem(), Object::ToPlayer(), unitTarget, and Player::UpdateCraftSkill().

Referenced by SpellScript::CreateItem(), EffectCreateItem(), EffectCreateItem2(), and EffectEnchantItemPerm().

◆ DoSpellHitOnUnit()

SpellMissInfo Spell::DoSpellHitOnUnit ( Unit unit,
uint32  effectMask,
bool  scaleAura 
)
protected
Todo:
: this cause soul transfer bugged
3003{
3004 if (!unit || !effectMask)
3005 return SPELL_MISS_EVADE;
3006
3007 // For delayed spells immunity may be applied between missile launch and hit - check immunity for that case
3008 if (m_spellInfo->Speed && ((m_damage > 0 && unit->IsImmunedToDamage(this)) || unit->IsImmunedToSchool(this) || unit->IsImmunedToSpell(m_spellInfo, this)))
3009 {
3010 return SPELL_MISS_IMMUNE;
3011 }
3012
3013 // disable effects to which unit is immune
3014 SpellMissInfo returnVal = SPELL_MISS_IMMUNE;
3015 for (uint32 effectNumber = 0; effectNumber < MAX_SPELL_EFFECTS; ++effectNumber)
3016 {
3017 if (effectMask & (1 << effectNumber))
3018 {
3019 if (unit->IsImmunedToSpellEffect(m_spellInfo, effectNumber))
3020 effectMask &= ~(1 << effectNumber);
3021 // Xinef: Buggs out polymorph
3022 // Xinef: And this is checked in MagicSpellHitResult, why we check resistance twice?
3023 // Xinef: And why we check every spell effect basing on rand and generic dispel info? some effects will be appliend and some wont?
3024 /*else if (m_spellInfo->Effects[effectNumber].IsAura() && !m_spellInfo->IsPositiveEffect(effectNumber))
3025 {
3026 int32 debuff_resist_chance = unit->GetMaxPositiveAuraModifierByMiscValue(SPELL_AURA_MOD_DEBUFF_RESISTANCE, int32(m_spellInfo->Dispel));
3027 debuff_resist_chance += unit->GetMaxNegativeAuraModifierByMiscValue(SPELL_AURA_MOD_DEBUFF_RESISTANCE, int32(m_spellInfo->Dispel));
3028
3029 if (debuff_resist_chance > 0)
3030 if (irand(0,10000) <= (debuff_resist_chance * 100))
3031 {
3032 effectMask &= ~(1 << effectNumber);
3033 returnVal = SPELL_MISS_RESIST;
3034 }
3035 }*/
3036 }
3037 }
3038 if (!effectMask)
3039 return returnVal;
3040
3041 if (unit->IsPlayer())
3042 {
3046 }
3047
3048 if (m_caster->IsPlayer())
3049 {
3052 }
3053
3054 if (m_caster != unit)
3055 {
3056 // Recheck UNIT_FLAG_NON_ATTACKABLE for delayed spells
3057 // Xinef: Also check evade state
3058 if (m_spellInfo->Speed > 0.0f)
3059 {
3060 if (unit->IsCreature() && unit->ToCreature()->IsInEvadeMode())
3061 return SPELL_MISS_EVADE;
3062
3064 return SPELL_MISS_EVADE;
3065 }
3066
3067 if (m_caster->_IsValidAttackTarget(unit, m_spellInfo) && /*Intervene Trigger*/ m_spellInfo->Id != 59667)
3068 {
3070 }
3071 else if (m_caster->IsFriendlyTo(unit))
3072 {
3073 // for delayed spells ignore negative spells (after duel end) for friendly targets
3075 if (!IsTriggered() && m_spellInfo->Speed > 0.0f && unit->IsPlayer() && !m_spellInfo->IsPositive())
3076 return SPELL_MISS_EVADE;
3077
3078 // assisting case, healing and resurrection
3080 {
3083 m_caster->ToPlayer()->UpdatePvP(true);
3084 }
3085
3086 // xinef: triggered spells should not prolong combat
3088 {
3089 m_caster->SetInCombatState(unit->GetCombatTimer() > 0, unit);
3090 unit->getHostileRefMgr().threatAssist(m_caster, 0.0f);
3091 }
3092 }
3093 }
3094
3095 uint8 aura_effmask = 0;
3096 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
3097 if (effectMask & (1 << i) && m_spellInfo->Effects[i].IsUnitOwnedAuraEffect())
3098 aura_effmask |= 1 << i;
3099
3100 Unit* originalCaster = GetOriginalCaster();
3101 if (!originalCaster)
3102 originalCaster = m_caster;
3103
3104 // Get Data Needed for Diminishing Returns, some effects may have multiple auras, so this must be done on spell hit, not aura add
3105 // Xinef: Do not increase diminishing level for self cast
3107 // xinef: do not increase diminish level for bosses (eg. Void Reaver silence is never diminished)
3108 if (((m_spellFlags & SPELL_FLAG_REFLECTED) && !(unit->HasReflectSpellsAura())) || (aura_effmask && m_diminishGroup && unit != m_caster && (!m_caster->IsCreature() || !m_caster->ToCreature()->isWorldBoss())))
3109 {
3112
3113 uint32 flagsExtra = unit->IsCreature() ? unit->ToCreature()->GetCreatureTemplate()->flags_extra : 0;
3114
3115 // Increase Diminishing on unit, current informations for actually casts will use values above
3116 if ((type == DRTYPE_PLAYER && (unit->IsCharmedOwnedByPlayerOrPlayer() || flagsExtra & CREATURE_FLAG_EXTRA_ALL_DIMINISH ||
3118 {
3119 // Do not apply diminish return if caster is NPC
3121 {
3123 }
3124 }
3125 }
3126
3128 {
3130 }
3131
3132 if (aura_effmask)
3133 {
3134 // Select rank for aura with level requirements only in specific cases
3135 // Unit has to be target only of aura effect, both caster and target have to be players, target has to be other than unit target
3136 SpellInfo const* aurSpellInfo = m_spellInfo;
3137 int32 basePoints[3];
3138 if (scaleAura)
3139 {
3141 ASSERT(aurSpellInfo);
3142 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
3143 {
3144 basePoints[i] = aurSpellInfo->Effects[i].BasePoints;
3145 if (m_spellInfo->Effects[i].Effect != aurSpellInfo->Effects[i].Effect)
3146 {
3147 aurSpellInfo = m_spellInfo;
3148 break;
3149 }
3150 }
3151 }
3152
3153 if (m_originalCaster)
3154 {
3155 bool refresh = false;
3157 m_spellAura = Aura::TryRefreshStackOrCreate(aurSpellInfo, effectMask, unit, m_originalCaster,
3158 (aurSpellInfo == m_spellInfo) ? &m_spellValue->EffectBasePoints[0] : &basePoints[0], m_CastItem, ObjectGuid::Empty, &refresh, refreshPeriodic);
3159
3160 // xinef: if aura was not refreshed, add proc ex
3161 if (!refresh)
3163
3164 if (m_spellAura)
3165 {
3166 // Prevent aura application if target is banished and immuned
3169 {
3171 return SPELL_MISS_IMMUNE;
3172 }
3173
3174 // Set aura stack amount to desired value
3176 {
3177 if (!refresh)
3179 else
3181 }
3182
3183 // Now Reduce spell duration using data received at spell hit
3184 int32 duration = m_spellAura->GetMaxDuration();
3185 int32 limitduration = GetDiminishingReturnsLimitDuration(m_diminishGroup, aurSpellInfo);
3186
3187 // Xinef: if unit == caster - test versus original unit if available
3188 float diminishMod = 1.0f;
3189 if (unit == m_caster && m_targets.GetUnitTarget())
3191 else
3192 diminishMod = unit->ApplyDiminishingToDuration(m_diminishGroup, duration, m_originalCaster, m_diminishLevel, limitduration);
3193
3194 // unit is immune to aura if it was diminished to 0 duration
3195 if (diminishMod == 0.0f)
3196 {
3199 return SPELL_MISS_IMMUNE;
3200 bool found = false;
3201 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
3202 if (effectMask & (1 << i) && m_spellInfo->Effects[i].Effect != SPELL_EFFECT_APPLY_AURA)
3203 found = true;
3204 if (!found)
3205 return SPELL_MISS_IMMUNE;
3206 }
3207 else
3208 {
3209 ((UnitAura*)m_spellAura)->SetDiminishGroup(m_diminishGroup);
3210
3211 bool positive = m_spellAura->GetSpellInfo()->IsPositive();
3213 positive = aurApp->IsPositive();
3214
3215 duration = m_originalCaster->ModSpellDuration(aurSpellInfo, unit, duration, positive, effectMask);
3216
3217 // xinef: haste affects duration of those spells twice
3220
3221 if (m_spellValue->AuraDuration != 0)
3222 {
3223 if (m_spellAura->GetMaxDuration() != -1)
3224 {
3226 }
3227
3229 }
3230 else if (duration != m_spellAura->GetMaxDuration())
3231 {
3232 m_spellAura->SetMaxDuration(duration);
3233 m_spellAura->SetDuration(duration);
3234 }
3235
3236 // xinef: apply relic cooldown, imo best place to add this
3239
3242 }
3243 }
3244 }
3245 }
3246
3247 int8 sanct_effect = -1;
3248
3249 for (uint32 effectNumber = 0; effectNumber < MAX_SPELL_EFFECTS; ++effectNumber)
3250 {
3251 // handle sanctuary effects after aura apply!
3252 if (m_spellInfo->Effects[effectNumber].Effect == SPELL_EFFECT_SANCTUARY)
3253 {
3254 sanct_effect = effectNumber;
3255 continue;
3256 }
3257
3258 if (effectMask & (1 << effectNumber))
3259 HandleEffects(unit, nullptr, nullptr, effectNumber, SPELL_EFFECT_HANDLE_HIT_TARGET);
3260 }
3261
3262 if (sanct_effect >= 0 && (effectMask & (1 << sanct_effect)))
3263 HandleEffects(unit, nullptr, nullptr, sanct_effect, SPELL_EFFECT_HANDLE_HIT_TARGET);
3264
3265 return SPELL_MISS_NONE;
3266}
@ ACHIEVEMENT_TIMED_TYPE_SPELL_CASTER
Definition: DBCEnums.h:112
@ ACHIEVEMENT_TIMED_TYPE_SPELL_TARGET
Definition: DBCEnums.h:113
@ ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET2
Definition: DBCEnums.h:181
@ ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET
Definition: DBCEnums.h:142
@ ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL2
Definition: DBCEnums.h:217
@ DIMINISHING_TAUNT
Definition: SharedDefines.h:3276
@ SPELL_EFFECT_SANCTUARY
Definition: SharedDefines.h:857
@ SPELL_ATTR5_SPELL_HASTE_AFFECTS_PERIODIC
Definition: SharedDefines.h:580
DiminishingReturnsType
Definition: SharedDefines.h:3249
@ DRTYPE_PLAYER
Definition: SharedDefines.h:3251
@ DRTYPE_ALL
Definition: SharedDefines.h:3252
@ SPELL_ATTR0_CU_DONT_BREAK_STEALTH
Definition: SpellInfo.h:182
int32 GetDiminishingReturnsLimitDuration(DiminishingGroup group, SpellInfo const *spellproto)
Definition: SpellMgr.cpp:275
DiminishingGroup GetDiminishingReturnsGroupForSpell(SpellInfo const *spellproto, bool triggered)
Definition: SpellMgr.cpp:58
DiminishingReturnsType GetDiminishingReturnsGroupType(DiminishingGroup group)
Definition: SpellMgr.cpp:245
@ AURA_INTERRUPT_FLAG_HITBYSPELL
Definition: SpellDefines.h:43
@ TRIGGERED_NO_PERIODIC_RESET
Will ignore equipped item requirements.
Definition: SpellDefines.h:152
@ SPELL_AURA_PERIODIC_HASTE
Definition: SpellAuraDefines.h:379
@ SPELL_AURA_MOD_STEALTH
Definition: SpellAuraDefines.h:79
@ PROC_EX_NO_AURA_REFRESH
Definition: SpellMgr.h:214
@ UNIT_MOD_CAST_SPEED
Definition: UpdateFields.h:137
@ UNIT_STATE_ATTACK_PLAYER
Definition: UnitDefines.h:163
@ UNIT_STATE_ISOLATED
Definition: UnitDefines.h:162
@ UNIT_FLAG_NON_ATTACKABLE
Definition: UnitDefines.h:230
@ CREATURE_FLAG_EXTRA_OBEYS_TAUNT_DIMINISHING_RETURNS
Definition: CreatureData.h:64
@ CREATURE_FLAG_EXTRA_ALL_DIMINISH
Definition: CreatureData.h:65
bool isWorldBoss() const
Definition: Creature.h:120
bool IsInEvadeMode() const
Definition: Creature.h:134
uint32 flags_extra
Definition: CreatureData.h:246
float GetFloatValue(uint16 index) const
Definition: Object.cpp:317
static ObjectGuid const Empty
Definition: ObjectGuid.h:120
bool HasAuraTypeWithAffectMask(AuraType auratype, SpellInfo const *affectedSpell) const
Definition: Unit.cpp:5738
DiminishingLevels GetDiminishing(DiminishingGroup group)
Definition: Unit.cpp:15007
void IncrDiminishing(DiminishingGroup group)
Definition: Unit.cpp:15033
uint32 GetCombatTimer() const
Definition: Unit.h:894
bool IsImmunedToSchool(SpellSchoolMask meleeSchoolMask) const
Definition: Unit.cpp:12832
void SetContestedPvP(Player *attackedPlayer=nullptr, bool lookForNearContestedGuards=true)
Definition: Unit.cpp:17248
bool HasUnitFlag(UnitFlags flags) const
Definition: Unit.h:712
float ApplyDiminishingToDuration(DiminishingGroup group, int32 &duration, Unit *caster, DiminishingLevels Level, int32 limitduration)
Definition: Unit.cpp:15047
int32 ModSpellDuration(SpellInfo const *spellProto, Unit const *target, int32 duration, bool positive, uint32 effectMask)
Definition: Unit.cpp:14873
virtual void AddSpellCooldown(uint32, uint32, uint32, bool needSendToClient=false, bool forceSendToSpectator=false)
Definition: Unit.h:1262
void SetInCombatState(bool PvP, Unit *enemy=nullptr, uint32 duration=0)
Definition: Unit.cpp:13732
bool HasReflectSpellsAura() const
Definition: Unit.h:1677
bool IsCharmedOwnedByPlayerOrPlayer() const
Definition: Unit.h:1234
bool IsImmunedToDamage(SpellSchoolMask meleeSchoolMask) const
Definition: Unit.cpp:12747
virtual bool IsImmunedToSpell(SpellInfo const *spellInfo, Spell const *spell=nullptr)
Definition: Unit.cpp:12916
bool IsImmunedToDamageOrSchool(SpellSchoolMask meleeSchoolMask) const
Definition: Unit.cpp:12901
bool IsHostileTo(Unit const *unit) const
Definition: Unit.cpp:10236
bool _IsValidAttackTarget(Unit const *target, SpellInfo const *bySpell, WorldObject const *obj=nullptr) const
Definition: Unit.cpp:13877
ObjectGuid GetCharmerOrOwnerGUID() const
Definition: Unit.h:1220
Definition: SpellAuras.h:37
int32 GetMaxDuration() const
Definition: SpellAuras.h:129
void SetStackAmount(uint8 num)
Definition: SpellAuras.cpp:995
void SetTriggeredByAuraSpellInfo(SpellInfo const *triggeredByAuraSpellInfo)
Definition: SpellAuras.cpp:2747
void _RegisterForTargets()
Definition: SpellAuras.h:121
bool ModStackAmount(int32 num, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT, bool periodicReset=false)
Definition: SpellAuras.cpp:1021
static Aura * TryRefreshStackOrCreate(SpellInfo const *spellproto, uint8 tryEffMask, WorldObject *owner, Unit *caster, int32 *baseAmount=nullptr, Item *castItem=nullptr, ObjectGuid casterGUID=ObjectGuid::Empty, bool *refresh=nullptr, bool periodicReset=false)
Definition: SpellAuras.cpp:326
void SetDuration(int32 duration, bool withMods=false)
Definition: SpellAuras.cpp:868
const AuraApplication * GetApplicationOfTarget(ObjectGuid guid) const
Definition: SpellAuras.h:183
void SetMaxDuration(int32 duration)
Definition: SpellAuras.h:130
virtual void Remove(AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)=0
Definition: SpellAuras.h:279
int32 AuraDuration
Definition: Spell.h:219
uint8 AuraStackAmount
Definition: Spell.h:218
Unit * GetOriginalCaster() const
Definition: Spell.h:578
SpellInfo const * GetAuraRankForLevel(uint8 level) const
Definition: SpellInfo.cpp:2526

References Unit::_IsValidAttackTarget(), Aura::_RegisterForTargets(), ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET, ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET2, ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL2, ACHIEVEMENT_TIMED_TYPE_SPELL_CASTER, ACHIEVEMENT_TIMED_TYPE_SPELL_TARGET, Unit::AddSpellCooldown(), Unit::ApplyDiminishingToDuration(), ASSERT, AURA_INTERRUPT_FLAG_HITBYSPELL, SpellValue::AuraDuration, SpellValue::AuraStackAmount, CREATURE_FLAG_EXTRA_ALL_DIMINISH, CREATURE_FLAG_EXTRA_OBEYS_TAUNT_DIMINISHING_RETURNS, DIMINISHING_TAUNT, DRTYPE_ALL, DRTYPE_PLAYER, SpellValue::EffectBasePoints, SpellInfo::Effects, ObjectGuid::Empty, CreatureTemplate::flags_extra, Aura::GetApplicationOfTarget(), SpellInfo::GetAuraRankForLevel(), Unit::GetCharmerOrOwnerGUID(), Unit::GetCombatTimer(), Creature::GetCreatureTemplate(), Unit::GetDiminishing(), GetDiminishingReturnsGroupForSpell(), GetDiminishingReturnsGroupType(), GetDiminishingReturnsLimitDuration(), Object::GetEntry(), Object::GetFloatValue(), Object::GetGUID(), Unit::getHostileRefMgr(), Unit::GetLevel(), Aura::GetMaxDuration(), GetOriginalCaster(), Aura::GetSpellInfo(), Item::GetTemplate(), SpellCastTargets::GetUnitTarget(), HandleEffects(), SpellInfo::HasAttribute(), Unit::HasAuraTypeWithAffectMask(), Unit::HasReflectSpellsAura(), HasTriggeredCastFlag(), Unit::HasUnitFlag(), Unit::HasUnitState(), SpellInfo::Id, Unit::IncrDiminishing(), ItemTemplate::InventoryType, INVTYPE_RELIC, Unit::IsCharmedOwnedByPlayerOrPlayer(), Object::IsCreature(), Unit::IsFriendlyTo(), Unit::IsHostileTo(), Unit::IsImmunedToDamage(), Unit::IsImmunedToDamageOrSchool(), Unit::IsImmunedToSchool(), Unit::IsImmunedToSpell(), Unit::IsImmunedToSpellEffect(), Unit::IsInCombat(), Creature::IsInEvadeMode(), Object::IsPlayer(), SpellInfo::IsPositive(), IsTriggered(), Creature::isWorldBoss(), m_caster, m_CastItem, m_damage, m_diminishGroup, m_diminishLevel, m_originalCaster, m_procEx, m_spellAura, m_spellFlags, m_spellInfo, m_spellValue, m_targets, m_triggeredByAuraSpell, MAX_SPELL_EFFECTS, Unit::ModSpellDuration(), Aura::ModStackAmount(), PROC_EX_NO_AURA_REFRESH, Aura::Remove(), Unit::RemoveAurasByType(), Unit::RemoveAurasWithInterruptFlags(), Unit::SetContestedPvP(), Aura::SetDuration(), Unit::SetInCombatState(), Aura::SetMaxDuration(), Aura::SetStackAmount(), Aura::SetTriggeredByAuraSpellInfo(), SpellInfo::Speed, SPELL_ATTR0_CU_DONT_BREAK_STEALTH, SPELL_ATTR0_CU_NO_PVP_FLAG, SPELL_ATTR3_SUPPRESS_TARGET_PROCS, SPELL_ATTR5_SPELL_HASTE_AFFECTS_PERIODIC, SPELL_AURA_MOD_STEALTH, SPELL_AURA_PERIODIC_HASTE, SPELL_EFFECT_APPLY_AURA, SPELL_EFFECT_HANDLE_HIT_TARGET, SPELL_EFFECT_SANCTUARY, SPELL_FLAG_REFLECTED, SPELL_MISS_EVADE, SPELL_MISS_IMMUNE, SPELL_MISS_NONE, SPELL_RELIC_COOLDOWN, TriggeredByAuraSpellData::spellInfo, SpellInfo::StackAmount, Player::StartTimedAchievement(), HostileRefMgr::threatAssist(), Object::ToCreature(), Object::ToPlayer(), TRIGGERED_NO_PERIODIC_RESET, Aura::TryRefreshStackOrCreate(), UNIT_FLAG_NON_ATTACKABLE, UNIT_MOD_CAST_SPEED, UNIT_STATE_ATTACK_PLAYER, UNIT_STATE_ISOLATED, unitTarget, Player::UpdateAchievementCriteria(), and Player::UpdatePvP().

Referenced by DoAllEffectOnTarget().

◆ DoTriggersOnSpellHit()

void Spell::DoTriggersOnSpellHit ( Unit unit,
uint8  effMask 
)
protected
Todo:
: move this code to scripts
Todo:
: remove/cleanup this, as this table is not documented and people are doing stupid things with it
3269{
3270 // Apply additional spell effects to target
3272 if (m_preCastSpell)
3273 {
3274 // Paladin immunity shields
3275 if (m_preCastSpell == 61988)
3276 {
3277 // Cast Forbearance
3278 m_caster->CastSpell(unit, 25771, true);
3279 // Cast Avenging Wrath Marker
3280 unit->CastSpell(unit, 61987, true);
3281 }
3282
3283 // Avenging Wrath
3284 if (m_preCastSpell == 61987)
3285 // Cast the serverside immunity shield marker
3286 m_caster->CastSpell(unit, 61988, true);
3287
3288 // Fearie Fire (Feral) - damage
3289 if (m_preCastSpell == 60089)
3290 m_caster->CastSpell(unit, m_preCastSpell, true);
3291 else if (sSpellMgr->GetSpellInfo(m_preCastSpell))
3292 // Blizz seems to just apply aura without bothering to cast
3294 }
3295
3296 // handle SPELL_AURA_ADD_TARGET_TRIGGER auras
3297 // this is executed after spell proc spells on target hit
3298 // spells are triggered for each hit spell target
3299 // info confirmed with retail sniffs of permafrost and shadow weaving
3300 if (!m_hitTriggerSpells.empty())
3301 {
3302 int _duration = 0;
3303 for (HitTriggerSpellList::const_iterator i = m_hitTriggerSpells.begin(); i != m_hitTriggerSpells.end(); ++i)
3304 {
3305 if (CanExecuteTriggersOnHit(effMask, i->triggeredByAura) && roll_chance_i(i->chance))
3306 {
3307 m_caster->CastSpell(unit, i->triggeredSpell->Id, true);
3308 LOG_DEBUG("spells.aura", "Spell {} triggered spell {} by SPELL_AURA_ADD_TARGET_TRIGGER aura", m_spellInfo->Id, i->triggeredSpell->Id);
3309
3310 // SPELL_AURA_ADD_TARGET_TRIGGER auras shouldn't trigger auras without duration
3311 // set duration of current aura to the triggered spell
3312 if (i->triggeredSpell->GetDuration() == -1)
3313 {
3314 if (Aura* triggeredAur = unit->GetAura(i->triggeredSpell->Id, m_caster->GetGUID()))
3315 {
3316 // get duration from aura-only once
3317 if (!_duration)
3318 {
3319 Aura* aur = unit->GetAura(m_spellInfo->Id, m_caster->GetGUID());
3320 _duration = aur ? aur->GetDuration() : -1;
3321 }
3322 triggeredAur->SetDuration(_duration);
3323 }
3324 }
3325 }
3326 }
3327 }
3328
3329 // trigger linked auras remove/apply
3331 if (std::vector<int32> const* spellTriggered = sSpellMgr->GetSpellLinked(m_spellInfo->Id + SPELL_LINK_HIT))
3332 {
3333 for (std::vector<int32>::const_iterator i = spellTriggered->begin(); i != spellTriggered->end(); ++i)
3334 if (*i < 0)
3335 {
3336 unit->RemoveAurasDueToSpell(-(*i));
3337 }
3338 else
3339 {
3340 unit->CastSpell(unit, *i, true, 0, 0, m_caster->GetGUID());
3341 }
3342 }
3343}
bool roll_chance_i(int chance)
Definition: Random.h:59
@ SPELL_LINK_HIT
Definition: SpellMgr.h:97
Aura * GetAura(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemCasterGUID=ObjectGuid::Empty, uint8 reqEffMask=0) const
Definition: Unit.cpp:5581
Aura * AddAura(uint32 spellId, Unit *target)
Definition: Unit.cpp:18863
int32 GetDuration() const
Definition: SpellAuras.h:133
HitTriggerSpellList m_hitTriggerSpells
Definition: Spell.h:758

References Unit::AddAura(), CanExecuteTriggersOnHit(), Unit::CastSpell(), Unit::GetAura(), Aura::GetDuration(), Object::GetGUID(), SpellInfo::Id, LOG_DEBUG, m_caster, m_hitTriggerSpells, m_preCastSpell, m_spellInfo, Unit::RemoveAurasDueToSpell(), roll_chance_i(), SPELL_LINK_HIT, and sSpellMgr.

Referenced by DoAllEffectOnTarget().

◆ EffectActivateObject()

void Spell::EffectActivateObject ( SpellEffIndex  effIndex)
4260{
4262 return;
4263
4264 if (!gameObjTarget)
4265 return;
4266
4267 GameObjectActions action = GameObjectActions(m_spellInfo->Effects[effIndex].MiscValue);
4268 switch (action)
4269 {
4270 case GameObjectActions::AnimateCustom0:
4271 case GameObjectActions::AnimateCustom1:
4272 case GameObjectActions::AnimateCustom2:
4273 case GameObjectActions::AnimateCustom3:
4274 gameObjTarget->SendCustomAnim(uint32(action) - uint32(GameObjectActions::AnimateCustom0));
4275 break;
4276 case GameObjectActions::Disturb: // What's the difference with Open?
4277 case GameObjectActions::Open:
4278 if (Unit* unitCaster = m_caster->ToUnit())
4279 gameObjTarget->Use(unitCaster);
4280 break;
4281 case GameObjectActions::OpenAndUnlock:
4282 if (Unit* unitCaster = m_caster->ToUnit())
4283 gameObjTarget->UseDoorOrButton(0, false, unitCaster);
4284 [[fallthrough]];
4285 case GameObjectActions::Unlock:
4286 case GameObjectActions::Lock:
4287 gameObjTarget->ApplyModFlag(GAMEOBJECT_FLAGS, GO_FLAG_LOCKED, action == GameObjectActions::Lock);
4288 break;
4289 case GameObjectActions::Close:
4290 case GameObjectActions::Rebuild:
4292 break;
4293 case GameObjectActions::Despawn:
4295 break;
4296 case GameObjectActions::MakeInert:
4297 case GameObjectActions::MakeActive:
4298 gameObjTarget->ApplyModFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE, action == GameObjectActions::MakeInert);
4299 break;
4300 case GameObjectActions::CloseAndLock:
4303 break;
4304 case GameObjectActions::Destroy:
4305 if (Unit* unitCaster = m_caster->ToUnit())
4306 gameObjTarget->UseDoorOrButton(0, true, unitCaster);
4307 break;
4308 case GameObjectActions::UseArtKit0:
4309 case GameObjectActions::UseArtKit1:
4310 case GameObjectActions::UseArtKit2:
4311 case GameObjectActions::UseArtKit3:
4312 {
4313 GameObjectTemplateAddon const* templateAddon = gameObjTarget->GetTemplateAddon();
4314
4315 uint32 artKitIndex = uint32(action) - uint32(GameObjectActions::UseArtKit0);
4316
4317 uint32 artKitValue = 0;
4318 if (templateAddon)
4319 artKitValue = templateAddon->artKits[artKitIndex];
4320
4321 if (artKitValue == 0)
4322 LOG_ERROR("sql.sql", "GameObject {} hit by spell {} needs `artkit{}` in `gameobject_template_addon`", gameObjTarget->GetEntry(), m_spellInfo->Id, artKitIndex);
4323 else
4324 gameObjTarget->SetGoArtKit(artKitValue);
4325
4326 break;
4327 }
4328 case GameObjectActions::None:
4329 LOG_FATAL("spell", "Spell {} has action type NONE in effect {}", m_spellInfo->Id, int32(effIndex));
4330 break;
4331 default:
4332 LOG_ERROR("spell", "Spell {} has unhandled action {} in effect {}", m_spellInfo->Id, int32(action), int32(effIndex));
4333 break;
4334 }
4335}
#define LOG_FATAL(filterType__,...)
Definition: Log.h:153
@ GO_FLAG_NOT_SELECTABLE
Definition: SharedDefines.h:1607
@ GO_FLAG_LOCKED
Definition: SharedDefines.h:1604
GameObjectActions
Definition: GameObject.h:76
@ GAMEOBJECT_FLAGS
Definition: UpdateFields.h:399
void UseDoorOrButton(uint32 time_to_restore=0, bool alternative=false, Unit *user=nullptr)
Definition: GameObject.cpp:1431
void SetGoArtKit(uint8 artkit)
Definition: GameObject.cpp:1445
void SendCustomAnim(uint32 anim)
Definition: GameObject.cpp:2152
void ResetDoorOrButton()
Definition: GameObject.cpp:1421
void DespawnOrUnsummon(Milliseconds delay=0ms, Seconds forcedRespawnTime=0s)
Definition: GameObject.cpp:935
GameObjectTemplateAddon const * GetTemplateAddon() const
Definition: GameObject.cpp:914
void Use(Unit *user)
Definition: GameObject.cpp:1481
Definition: GameObjectData.h:664
std::array< uint32, 4 > artKits
Definition: GameObjectData.h:670
void SetFlag(uint16 index, uint32 newFlag)
Definition: Object.cpp:845
void ApplyModFlag(uint16 index, uint32 flag, bool apply)
Definition: Object.cpp:899

References Object::ApplyModFlag(), GameObjectTemplateAddon::artKits, GameObject::DespawnOrUnsummon(), effectHandleMode, SpellInfo::Effects, GAMEOBJECT_FLAGS, gameObjTarget, Object::GetEntry(), GameObject::GetTemplateAddon(), GO_FLAG_LOCKED, GO_FLAG_NOT_SELECTABLE, SpellInfo::Id, LOG_ERROR, LOG_FATAL, m_caster, m_spellInfo, GameObject::ResetDoorOrButton(), GameObject::SendCustomAnim(), Object::SetFlag(), GameObject::SetGoArtKit(), SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToUnit(), GameObject::Use(), and GameObject::UseDoorOrButton().

◆ EffectActivateRune()

void Spell::EffectActivateRune ( SpellEffIndex  effIndex)
5774{
5776 return;
5777
5778 if (!m_caster->IsPlayer())
5779 return;
5780
5781 Player* player = m_caster->ToPlayer();
5782
5784 return;
5785
5786 // needed later
5788
5789 uint32 count = damage;
5790 if (count == 0) count = 1;
5791 for (uint32 j = 0; j < MAX_RUNES && count > 0; ++j)
5792 {
5793 if (player->GetRuneCooldown(j) && player->GetCurrentRune(j) == RuneType(m_spellInfo->Effects[effIndex].MiscValue))
5794 {
5795 if (m_spellInfo->Id == 45529)
5796 if (player->GetBaseRune(j) != RuneType(m_spellInfo->Effects[effIndex].MiscValueB))
5797 continue;
5798 player->SetRuneCooldown(j, 0);
5799 player->SetGracePeriod(j, player->IsInCombat()); // xinef: reset grace period
5800 --count;
5801 }
5802 }
5803
5804 // Blood Tap
5805 if (m_spellInfo->Id == 45529 && count > 0)
5806 {
5807 for (uint32 l = 0; l < MAX_RUNES && count > 0; ++l)
5808 {
5809 // Check if both runes are on cd as that is the only time when this needs to come into effect
5810 if ((player->GetRuneCooldown(l) && player->GetCurrentRune(l) == RuneType(m_spellInfo->Effects[effIndex].MiscValueB)) && (player->GetRuneCooldown(l + 1) && player->GetCurrentRune(l + 1) == RuneType(m_spellInfo->Effects[effIndex].MiscValueB)))
5811 {
5812 // Should always update the rune with the lowest cd
5813 if (player->GetRuneCooldown(l) >= player->GetRuneCooldown(l + 1))
5814 l++;
5815 player->SetRuneCooldown(l, 0);
5816 player->SetGracePeriod(l, player->IsInCombat()); // xinef: reset grace period
5817 --count;
5818 }
5819 else
5820 break;
5821 }
5822 }
5823
5824 // Empower rune weapon
5825 if (m_spellInfo->Id == 47568)
5826 {
5827 // Need to do this just once
5828 if (effIndex != 0)
5829 return;
5830
5831 for (uint32 i = 0; i < MAX_RUNES; ++i)
5832 {
5833 if (player->GetRuneCooldown(i) && (player->GetCurrentRune(i) == RUNE_FROST || player->GetCurrentRune(i) == RUNE_DEATH))
5834 {
5835 player->SetRuneCooldown(i, 0);
5836 player->SetGracePeriod(i, player->IsInCombat()); // xinef: reset grace period
5837 }
5838 }
5839 }
5840
5841 // is needed to push through to the client that the rune is active
5842 //player->ResyncRunes(MAX_RUNES);
5843 m_caster->CastSpell(m_caster, 47804, true);
5844}
@ RUNE_FROST
Definition: Player.h:416
void SetRuneCooldown(uint8 index, uint32 cooldown)
Definition: Player.h:2516
uint8 GetRunesState() const
Definition: Player.h:2505
void SetGracePeriod(uint8 index, uint32 period)
Definition: Player.h:2517
RuneType GetBaseRune(uint8 index) const
Definition: Player.h:2506

References Unit::CastSpell(), CLASS_CONTEXT_ABILITY, CLASS_DEATH_KNIGHT, damage, effectHandleMode, SpellInfo::Effects, Player::GetBaseRune(), Player::GetCurrentRune(), Player::GetRuneCooldown(), Player::GetRunesState(), SpellInfo::Id, Player::IsClass(), Unit::IsInCombat(), Object::IsPlayer(), m_caster, m_runesState, m_spellInfo, MAX_RUNES, RUNE_DEATH, RUNE_FROST, Player::SetGracePeriod(), Player::SetRuneCooldown(), SPELL_EFFECT_HANDLE_LAUNCH, and Object::ToPlayer().

◆ EffectActivateSpec()

void Spell::EffectActivateSpec ( SpellEffIndex  effIndex)
6149{
6151 return;
6152
6153 if (!unitTarget)
6154 return;
6155
6156 if (Player* player = unitTarget->ToPlayer())
6157 {
6158 player->ActivateSpec(damage - 1); // damage is 1 or 2, spec is 0 or 1
6159 }
6160}

References damage, effectHandleMode, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectAddComboPoints()

void Spell::EffectAddComboPoints ( SpellEffIndex  effIndex)
4097{
4099 {
4100 return;
4101 }
4102
4103 if (!unitTarget || damage <= 0)
4104 {
4105 return;
4106 }
4107
4109}
void AddComboPointGain(Unit *target, int8 amount)
Definition: Spell.h:533

References AddComboPointGain(), damage, effectHandleMode, SPELL_EFFECT_HANDLE_HIT_TARGET, and unitTarget.

◆ EffectAddExtraAttacks()

void Spell::EffectAddExtraAttacks ( SpellEffIndex  effIndex)
4679{
4681 {
4682 return;
4683 }
4684
4685 if (!unitTarget || !unitTarget->IsAlive())
4686 {
4687 return;
4688 }
4689
4691
4693}
void AddExtraAttacks(uint32 count)
Definition: Unit.cpp:2765
void ExecuteLogEffectExtraAttacks(uint8 effIndex, Unit *victim, uint32 attCount)
Definition: Spell.cpp:5121

References Unit::AddExtraAttacks(), damage, effectHandleMode, ExecuteLogEffectExtraAttacks(), Unit::IsAlive(), SPELL_EFFECT_HANDLE_HIT_TARGET, and unitTarget.

◆ EffectAddFarsight()

void Spell::EffectAddFarsight ( SpellEffIndex  effIndex)
2718{
2720 return;
2721
2722 if (!m_caster->IsPlayer())
2723 return;
2724
2725 float radius = m_spellInfo->Effects[effIndex].CalcRadius();
2726 int32 duration = m_spellInfo->GetDuration();
2727 // Caster not in world, might be spell triggered from aura removal
2728 if (!m_caster->IsInWorld())
2729 return;
2730
2731 // Remove old farsight if exist
2732 bool updateViewerVisibility = m_caster->RemoveDynObject(m_spellInfo->Id);
2733
2734 DynamicObject* dynObj = new DynamicObject(true);
2735 if (!dynObj->CreateDynamicObject(m_caster->GetMap()->GenerateLowGuid<HighGuid::DynamicObject>(), m_caster, m_spellInfo->Id, *destTarget, radius, DYNAMIC_OBJECT_FARSIGHT_FOCUS))
2736 {
2737 delete dynObj;
2738 return;
2739 }
2740
2741 dynObj->SetDuration(duration);
2742 dynObj->SetCasterViewpoint(updateViewerVisibility);
2743}
@ DYNAMIC_OBJECT_FARSIGHT_FOCUS
Definition: DynamicObject.h:31
void SetDuration(int32 newDuration)
Definition: DynamicObject.cpp:203
void SetCasterViewpoint(bool updateViewerVisibility)
Definition: DynamicObject.cpp:231
bool CreateDynamicObject(ObjectGuid::LowType guidlow, Unit *caster, uint32 spellId, Position const &pos, float radius, DynamicObjectType type)
Definition: DynamicObject.cpp:97
ObjectGuid::LowType GenerateLowGuid()
Definition: Map.h:636

References DynamicObject::CreateDynamicObject(), destTarget, DYNAMIC_OBJECT_FARSIGHT_FOCUS, effectHandleMode, SpellInfo::Effects, Map::GenerateLowGuid(), SpellInfo::GetDuration(), WorldObject::GetMap(), SpellInfo::Id, Object::IsInWorld(), Object::IsPlayer(), m_caster, m_spellInfo, Unit::RemoveDynObject(), DynamicObject::SetCasterViewpoint(), DynamicObject::SetDuration(), and SPELL_EFFECT_HANDLE_HIT.

◆ EffectAddHonor()

void Spell::EffectAddHonor ( SpellEffIndex  effIndex)
2788{
2790 return;
2791
2792 if (!unitTarget->IsPlayer())
2793 return;
2794
2795 // not scale value for item based reward (/10 value expected)
2796 if (m_CastItem)
2797 {
2798 unitTarget->ToPlayer()->RewardHonor(nullptr, 1, damage / 10, false);
2799 LOG_DEBUG("spells.aura", "SpellEffect::AddHonor (spell_id {}) rewards {} honor points (item {}) for player: {}",
2801 return;
2802 }
2803
2804 // do not allow to add too many honor for player (50 * 21) = 1040 at level 70, or (50 * 31) = 1550 at level 80
2805 if (damage <= 50)
2806 {
2808 unitTarget->ToPlayer()->RewardHonor(nullptr, 1, honor_reward, false);
2809 LOG_DEBUG("spells.aura", "SpellEffect::AddHonor (spell_id {}) rewards {} honor points (scale) to player: {}",
2810 m_spellInfo->Id, honor_reward, unitTarget->ToPlayer()->GetGUID().ToString());
2811 }
2812 else
2813 {
2814 //maybe we have correct honor_gain in damage already
2815 unitTarget->ToPlayer()->RewardHonor(nullptr, 1, damage, false);
2816 LOG_DEBUG("spells.aura", "SpellEffect::AddHonor (spell_id {}) rewards {} honor points (non scale) for player: {}",
2818 }
2819}
uint32 hk_honor_at_level(uint8 level, float multiplier=1.0f)
Definition: Formulas.h:38
std::string ToString() const
Definition: ObjectGuid.cpp:47
bool RewardHonor(Unit *victim, uint32 groupsize, int32 honor=-1, bool awardXP=true)
Definition: Player.cpp:6095

References damage, effectHandleMode, Object::GetEntry(), Object::GetGUID(), Unit::GetLevel(), Acore::Honor::hk_honor_at_level(), SpellInfo::Id, Object::IsPlayer(), LOG_DEBUG, m_CastItem, m_spellInfo, Player::RewardHonor(), SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), ObjectGuid::ToString(), and unitTarget.

◆ EffectApplyAreaAura()

void Spell::EffectApplyAreaAura ( SpellEffIndex  effIndex)
1320{
1322 return;
1323
1324 if (!m_spellAura || !unitTarget)
1325 return;
1328}
WorldObject * GetOwner() const
Definition: SpellAuras.h:107
void _ApplyEffectForTargets(uint8 effIndex)
Definition: SpellAuras.cpp:735

References Aura::_ApplyEffectForTargets(), ASSERT, effectHandleMode, Aura::GetOwner(), m_spellAura, SPELL_EFFECT_HANDLE_HIT_TARGET, and unitTarget.

◆ EffectApplyAura()

void Spell::EffectApplyAura ( SpellEffIndex  effIndex)

◆ EffectApplyGlyph()

void Spell::EffectApplyGlyph ( SpellEffIndex  effIndex)
4338{
4340 return;
4341
4343 return;
4344
4345 Player* player = m_caster->ToPlayer();
4346
4347 // glyph sockets level requirement
4348 uint8 minLevel = 0;
4349 switch (m_glyphIndex)
4350 {
4351 case 0:
4352 case 1:
4353 minLevel = 15;
4354 break;
4355 case 2:
4356 minLevel = 50;
4357 break;
4358 case 3:
4359 minLevel = 30;
4360 break;
4361 case 4:
4362 minLevel = 70;
4363 break;
4364 case 5:
4365 minLevel = 80;
4366 break;
4367 }
4368 if (minLevel && m_caster->GetLevel() < minLevel)
4369 {
4371 return;
4372 }
4373
4374 // apply new one
4375 if (uint32 glyph = m_spellInfo->Effects[effIndex].MiscValue)
4376 {
4377 if (GlyphPropertiesEntry const* glyphEntry = sGlyphPropertiesStore.LookupEntry(glyph))
4378 {
4379 if (GlyphSlotEntry const* glyphSlotEntry = sGlyphSlotStore.LookupEntry(player->GetGlyphSlot(m_glyphIndex)))
4380 {
4381 if (glyphEntry->TypeFlags != glyphSlotEntry->TypeFlags)
4382 {
4384 return; // glyph slot mismatch
4385 }
4386 }
4387
4388 // remove old glyph aura
4389 if (uint32 oldGlyph = player->GetGlyph(m_glyphIndex))
4390 if (GlyphPropertiesEntry const* oldGlyphEntry = sGlyphPropertiesStore.LookupEntry(oldGlyph))
4391 {
4392 player->RemoveAurasDueToSpell(oldGlyphEntry->SpellId);
4393
4394 // Removed any triggered auras
4395 Unit::AuraMap& ownedAuras = player->GetOwnedAuras();
4396 for (Unit::AuraMap::iterator iter = ownedAuras.begin(); iter != ownedAuras.end();)
4397 {
4398 Aura* aura = iter->second;
4399 if (SpellInfo const* triggeredByAuraSpellInfo = aura->GetTriggeredByAuraSpellInfo())
4400 {
4401 if (triggeredByAuraSpellInfo->Id == oldGlyphEntry->SpellId)
4402 {
4403 player->RemoveOwnedAura(iter);
4404 continue;
4405 }
4406 }
4407 ++iter;
4408 }
4409
4410 player->SendLearnPacket(oldGlyphEntry->SpellId, false); // Send packet to properly handle client-side spell tooltips
4411 }
4412
4413 player->SendLearnPacket(glyphEntry->SpellId, true); // Send packet to properly handle client-side spell tooltips
4415 player->SetGlyph(m_glyphIndex, glyph, !player->GetSession()->PlayerLoading());
4416 player->SendTalentsInfoData(false);
4417 }
4418 }
4419}
#define MAX_GLYPH_SLOT_INDEX
Definition: SharedDefines.h:676
@ SPELL_FAILED_GLYPH_SOCKET_LOCKED
Definition: SharedDefines.h:1126
@ SPELL_FAILED_INVALID_GLYPH
Definition: SharedDefines.h:1124
@ TRIGGERED_FULL_MASK
Will return SPELL_FAILED_DONT_REPORT in CheckCast functions.
Definition: SpellDefines.h:150
DBCStorage< GlyphSlotEntry > sGlyphSlotStore(GlyphSlotfmt)
void SendTalentsInfoData(bool pet)
Definition: Player.cpp:14454
void SendLearnPacket(uint32 spellId, bool learn)
Definition: Player.cpp:3052
uint32 GetGlyph(uint8 slot) const
Definition: Player.h:1770
uint32 GetGlyphSlot(uint8 slot) const
Definition: Player.h:1761
void SetGlyph(uint8 slot, uint32 glyph, bool save)
Definition: Player.h:1762
void RemoveOwnedAura(AuraMap::iterator &i, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition: Unit.cpp:4705
std::multimap< uint32, Aura * > AuraMap
Definition: Unit.h:635
AuraMap & GetOwnedAuras()
Definition: Unit.h:1294
bool PlayerLoading() const
Definition: WorldSession.h:337
SpellInfo const * GetTriggeredByAuraSpellInfo() const
Definition: SpellAuras.cpp:2761
Definition: DBCStructure.h:1028

References Unit::CastSpell(), effectHandleMode, SpellInfo::Effects, Player::GetGlyph(), Player::GetGlyphSlot(), Unit::GetLevel(), Unit::GetOwnedAuras(), Player::GetSession(), Aura::GetTriggeredByAuraSpellInfo(), Object::IsPlayer(), m_caster, m_glyphIndex, m_spellInfo, MAX_GLYPH_SLOT_INDEX, WorldSession::PlayerLoading(), Unit::RemoveAurasDueToSpell(), Unit::RemoveOwnedAura(), SendCastResult(), Player::SendLearnPacket(), Player::SendTalentsInfoData(), Player::SetGlyph(), sGlyphPropertiesStore, sGlyphSlotStore, SPELL_EFFECT_HANDLE_HIT, SPELL_FAILED_GLYPH_SOCKET_LOCKED, SPELL_FAILED_INVALID_GLYPH, Object::ToPlayer(), TRIGGERED_FULL_MASK, TRIGGERED_IGNORE_CASTER_AURASTATE, and TRIGGERED_IGNORE_SHAPESHIFT.

◆ EffectBind()

void Spell::EffectBind ( SpellEffIndex  effIndex)
6282{
6284 return;
6285
6286 if (!unitTarget)
6287 return;
6288
6289 Player* player = unitTarget->ToPlayer();
6290 if (!player)
6291 {
6292 return;
6293 }
6294
6295 WorldLocation homeLoc;
6296 uint32 areaId = player->GetAreaId();
6297
6298 if (m_spellInfo->Effects[effIndex].MiscValue)
6299 areaId = m_spellInfo->Effects[effIndex].MiscValue;
6300
6301 if (m_targets.HasDst())
6302 homeLoc.WorldRelocate(*destTarget);
6303 else
6304 {
6305 homeLoc = player->GetWorldLocation();
6306 }
6307
6308 player->SetHomebind(homeLoc, areaId);
6309
6310 // binding
6311 WorldPacket data(SMSG_BINDPOINTUPDATE, 4 + 4 + 4 + 4 + 4);
6312 data << float(homeLoc.GetPositionX());
6313 data << float(homeLoc.GetPositionY());
6314 data << float(homeLoc.GetPositionZ());
6315 data << uint32(homeLoc.GetMapId());
6316 data << uint32(areaId);
6317 player->SendDirectMessage(&data);
6318
6319 LOG_DEBUG("spells.aura", "EffectBind: New homebind X: {}, Y: {}, Z: {}, MapId: {}, AreaId: {}",
6320 homeLoc.GetPositionX(), homeLoc.GetPositionY(), homeLoc.GetPositionZ(), homeLoc.GetMapId(), areaId);
6321 // zone update
6322 data.Initialize(SMSG_PLAYERBOUND, 8 + 4);
6323 data << m_caster->GetGUID();
6324 data << uint32(areaId);
6325 player->SendDirectMessage(&data);
6326}
@ SMSG_BINDPOINTUPDATE
Definition: Opcodes.h:371
@ SMSG_PLAYERBOUND
Definition: Opcodes.h:374
Definition: Position.h:250
void WorldRelocate(const WorldLocation &loc)
Definition: Position.h:258
void GetWorldLocation(uint32 &mapId, float &x, float &y) const
Definition: Position.h:280
void SendDirectMessage(WorldPacket const *data) const
Definition: Player.cpp:5723
void SetHomebind(WorldLocation const &loc, uint32 areaId)
Definition: PlayerStorage.cpp:4897

References destTarget, effectHandleMode, SpellInfo::Effects, WorldObject::GetAreaId(), Object::GetGUID(), WorldLocation::GetMapId(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), WorldLocation::GetWorldLocation(), SpellCastTargets::HasDst(), WorldPacket::Initialize(), LOG_DEBUG, m_caster, m_spellInfo, m_targets, Player::SendDirectMessage(), Player::SetHomebind(), SMSG_BINDPOINTUPDATE, SMSG_PLAYERBOUND, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), unitTarget, and WorldLocation::WorldRelocate().

◆ EffectBlock()

void Spell::EffectBlock ( SpellEffIndex  effIndex)
4705{
4707 return;
4708
4709 if (m_caster->IsPlayer())
4710 m_caster->ToPlayer()->SetCanBlock(true);
4711}
void SetCanBlock(bool value)
Definition: Player.cpp:13169

References effectHandleMode, Object::IsPlayer(), m_caster, Player::SetCanBlock(), SPELL_EFFECT_HANDLE_HIT, and Object::ToPlayer().

◆ EffectCastButtons()

void Spell::EffectCastButtons ( SpellEffIndex  effIndex)

Action button data is unverified when it's set so it can be "hacked" to contain invalid spells, so filter here.

6209{
6211 return;
6212
6213 if (!m_caster->IsPlayer())
6214 return;
6215
6216 Player* p_caster = m_caster->ToPlayer();
6217 uint32 button_id = m_spellInfo->Effects[effIndex].MiscValue + 132;
6218 uint32 n_buttons = m_spellInfo->Effects[effIndex].MiscValueB;
6219
6220 for (; n_buttons; --n_buttons, ++button_id)
6221 {
6222 ActionButton const* ab = p_caster->GetActionButton(button_id);
6223 if (!ab || ab->GetType() != ACTION_BUTTON_SPELL)
6224 continue;
6225
6228 uint32 spell_id = ab->GetAction();
6229 if (!spell_id)
6230 continue;
6231
6232 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spell_id);
6233 if (!spellInfo)
6234 continue;
6235
6236 if (!p_caster->HasSpell(spell_id) || p_caster->HasSpellCooldown(spell_id))
6237 continue;
6238
6240 continue;
6241
6242 uint32 cost = spellInfo->CalcPowerCost(m_caster, spellInfo->GetSchoolMask(), this);
6243 if (m_caster->GetPower(POWER_MANA) < cost)
6244 continue;
6245
6247 m_caster->CastSpell(m_caster, spell_id, triggerFlags);
6248 }
6249}
@ SPELL_ATTR7_CAN_BE_MULTI_CAST
Definition: SharedDefines.h:646
@ ACTION_BUTTON_SPELL
Definition: Player.h:229
Definition: Player.h:258
uint32 GetAction() const
Definition: Player.h:266
ActionButtonType GetType() const
Definition: Player.h:265
ActionButton const * GetActionButton(uint8 button)
Definition: Player.cpp:5669
bool HasSpell(uint32 spell) const override
Definition: Player.cpp:3892

References ACTION_BUTTON_SPELL, SpellInfo::CalcPowerCost(), Unit::CastSpell(), effectHandleMode, SpellInfo::Effects, ActionButton::GetAction(), Player::GetActionButton(), Unit::GetPower(), SpellInfo::GetSchoolMask(), ActionButton::GetType(), SpellInfo::HasAttribute(), Player::HasSpell(), Player::HasSpellCooldown(), Object::IsPlayer(), m_caster, m_spellInfo, POWER_MANA, SPELL_ATTR7_CAN_BE_MULTI_CAST, SPELL_EFFECT_HANDLE_HIT, sSpellMgr, Object::ToPlayer(), TRIGGERED_CAST_DIRECTLY, TRIGGERED_IGNORE_CAST_IN_PROGRESS, and TRIGGERED_IGNORE_GCD.

◆ EffectCharge()

void Spell::EffectCharge ( SpellEffIndex  effIndex)
4924{
4926 {
4927 if (!unitTarget)
4928 return;
4929
4930 ObjectGuid targetGUID = ObjectGuid::Empty;
4931 Player* player = m_caster->ToPlayer();
4932 if (player)
4933 {
4934 // charge changes fall time
4936
4938 {
4939 targetGUID = unitTarget->GetGUID();
4940 }
4941 }
4942
4943 float speed = G3D::fuzzyGt(m_spellInfo->Speed, 0.0f) ? m_spellInfo->Speed : SPEED_CHARGE;
4944 // Spell is not using explicit target - no generated path
4945 if (!m_preGeneratedPath)
4946 {
4948 m_caster->GetMotionMaster()->MoveCharge(pos.m_positionX, pos.m_positionY, pos.m_positionZ, speed, EVENT_CHARGE, nullptr, false, 0.0f, targetGUID);
4949 }
4950 else
4951 {
4952 m_caster->GetMotionMaster()->MoveCharge(*m_preGeneratedPath, speed, targetGUID);
4953 }
4954
4955 if (player)
4956 {
4957 sScriptMgr->AnticheatSetUnderACKmount(player);
4958 }
4959 }
4960}
@ EVENT_CHARGE
Definition: SharedDefines.h:3311
#define SPEED_CHARGE
Definition: MotionMaster.h:109
Position GetFirstCollisionPosition(float startX, float startY, float startZ, float destX, float destY)
Definition: Object.cpp:2834
Definition: Position.h:27
float m_positionZ
Definition: Position.h:57
float GetRelativeAngle(const Position *pos) const
Definition: Position.h:196
float m_positionX
Definition: Position.h:55
float m_positionY
Definition: Position.h:56
void SetFallInformation(uint32 time, float z)
Definition: Player.h:2336
MotionMaster * GetMotionMaster()
Definition: Unit.h:1620
void MoveCharge(float x, float y, float z, float speed=SPEED_CHARGE, uint32 id=EVENT_CHARGE, const Movement::PointsArray *path=nullptr, bool generatePath=false, float orientation=0.0f, ObjectGuid targetGUID=ObjectGuid::Empty)
The unit will charge the target. Doesn't work with UNIT_FLAG_DISABLE_MOVE.
Definition: MotionMaster.cpp:670

References effectHandleMode, ObjectGuid::Empty, EVENT_CHARGE, Unit::GetCombatReach(), WorldObject::GetFirstCollisionPosition(), GameTime::GetGameTime(), Object::GetGUID(), Unit::GetMotionMaster(), Position::GetPositionZ(), Position::GetRelativeAngle(), Unit::GetTarget(), SpellInfo::HasAttribute(), SpellInfo::IsPositive(), m_caster, Position::m_positionX, Position::m_positionY, Position::m_positionZ, m_preGeneratedPath, m_spellInfo, MotionMaster::MoveCharge(), Player::SetFallInformation(), SpellInfo::Speed, SPEED_CHARGE, SPELL_ATTR0_CANCELS_AUTO_ATTACK_COMBAT, SPELL_EFFECT_HANDLE_LAUNCH_TARGET, sScriptMgr, Object::ToPlayer(), and unitTarget.

◆ EffectChargeDest()

◆ EffectCreateItem()

void Spell::EffectCreateItem ( SpellEffIndex  effIndex)
1777{
1779 return;
1780
1781 DoCreateItem(effIndex, m_spellInfo->Effects[effIndex].ItemType);
1782 ExecuteLogEffectCreateItem(effIndex, m_spellInfo->Effects[effIndex].ItemType);
1783}
void ExecuteLogEffectCreateItem(uint8 effIndex, uint32 entry)
Definition: Spell.cpp:5149
void DoCreateItem(uint8 effIndex, uint32 itemId)
Definition: SpellEffects.cpp:1647

References DoCreateItem(), effectHandleMode, SpellInfo::Effects, ExecuteLogEffectCreateItem(), m_spellInfo, and SPELL_EFFECT_HANDLE_HIT_TARGET.

◆ EffectCreateItem2()

void Spell::EffectCreateItem2 ( SpellEffIndex  effIndex)
Todo:
: ExecuteLogEffectCreateItem(i, m_spellInfo->Effects[i].ItemType);
1786{
1788 return;
1789
1790 if (!unitTarget)
1791 return;
1792
1793 Player* player = unitTarget->ToPlayer();
1794 if (!player)
1795 {
1796 return;
1797 }
1798
1799 uint32 itemId = m_spellInfo->Effects[effIndex].ItemType;
1800
1801 if (itemId)
1802 DoCreateItem(effIndex, itemId);
1803
1804 // special case: fake item replaced by generate using spell_loot_template
1806 {
1807 if (itemId)
1808 {
1809 if (!player->HasItemCount(itemId))
1810 return;
1811
1812 // remove reagent
1813 uint32 count = 1;
1814 player->DestroyItemCount(itemId, count, true);
1815
1816 // create some random items
1818 }
1819 else
1820 player->AutoStoreLoot(m_spellInfo->Id, LootTemplates_Spell); // create some random items
1821 }
1823}
LootStore LootTemplates_Spell("spell_loot_template", "spell id (random item creating)", false)
void AutoStoreLoot(uint8 bag, uint8 slot, uint32 loot_id, LootStore const &store, bool broadcast=false)
Definition: Player.cpp:13524
void DestroyItemCount(uint32 item, uint32 count, bool update, bool unequip_check=false)
Definition: PlayerStorage.cpp:3121
bool IsLootCrafting() const
Definition: SpellInfo.cpp:925

References Player::AutoStoreLoot(), Player::DestroyItemCount(), DoCreateItem(), effectHandleMode, SpellInfo::Effects, Player::HasItemCount(), SpellInfo::Id, SpellInfo::IsLootCrafting(), LootTemplates_Spell, m_spellInfo, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectCreateRandomItem()

void Spell::EffectCreateRandomItem ( SpellEffIndex  effIndex)
Todo:
: ExecuteLogEffectCreateItem(i, m_spellInfo->Effects[i].ItemType);
1826{
1828 return;
1829
1830 if (!unitTarget)
1831 return;
1832
1833 Player* player = unitTarget->ToPlayer();
1834 if (!player)
1835 {
1836 return;
1837 }
1838
1839 // create some random items
1842}

References Player::AutoStoreLoot(), effectHandleMode, SpellInfo::Id, LootTemplates_Spell, m_spellInfo, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectCreateTamedPet()

void Spell::EffectCreateTamedPet ( SpellEffIndex  effIndex)
5847{
5849 return;
5850
5852 return;
5853
5854 uint32 creatureEntry = m_spellInfo->Effects[effIndex].MiscValue;
5855 Pet* pet = unitTarget->CreateTamedPetFrom(creatureEntry, m_spellInfo->Id);
5856 if (!pet)
5857 return;
5858
5859 // add to world
5860 pet->GetMap()->AddToMap(pet->ToCreature(), true);
5861
5862 // unitTarget has pet now
5863 unitTarget->SetMinion(pet, true);
5864
5865 pet->InitTalentForLevel();
5866
5867 if (unitTarget->IsPlayer())
5868 {
5871 }
5872}
@ CLASS_HUNTER
Definition: SharedDefines.h:143
void InitTalentForLevel()
Definition: Pet.cpp:2219
void SavePetToDB(PetSaveMode mode)
Definition: Pet.cpp:501
void PetSpellInitialize()
Definition: Player.cpp:9500
void SetMinion(Minion *minion, bool apply)
Definition: Unit.cpp:10685
Pet * CreateTamedPetFrom(Creature *creatureTarget, uint32 spell_id=0)
Definition: Unit.cpp:17351
bool AddToMap(T *, bool checkTransport=false)
Definition: Map.cpp:558

References Map::AddToMap(), CLASS_CONTEXT_PET, CLASS_HUNTER, Unit::CreateTamedPetFrom(), effectHandleMode, SpellInfo::Effects, WorldObject::GetMap(), Unit::GetPetGUID(), SpellInfo::Id, Pet::InitTalentForLevel(), Unit::IsClass(), Object::IsPlayer(), m_spellInfo, PET_SAVE_AS_CURRENT, Player::PetSpellInitialize(), Pet::SavePetToDB(), Unit::SetMinion(), SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToCreature(), Object::ToPlayer(), and unitTarget.

◆ EffectDestroyAllTotems()

void Spell::EffectDestroyAllTotems ( SpellEffIndex  effIndex)
5258{
5260 return;
5261
5262 int32 mana = 0;
5263 for (uint8 slot = SUMMON_SLOT_TOTEM; slot < MAX_TOTEM_SLOT; ++slot)
5264 {
5265 if (!m_caster->m_SummonSlot[slot])
5266 continue;
5267
5269 if (totem && totem->IsTotem())
5270 {
5271 uint32 spell_id = totem->GetUInt32Value(UNIT_CREATED_BY_SPELL);
5272 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spell_id);
5273 if (spellInfo)
5274 {
5275 mana += spellInfo->ManaCost;
5277 }
5278 totem->ToTotem()->UnSummon();
5279 }
5280 }
5281 ApplyPct(mana, damage);
5282 if (mana)
5283 m_caster->CastCustomSpell(m_caster, 39104, &mana, nullptr, nullptr, true);
5284}
T ApplyPct(T &base, U pct)
Definition: Util.h:73
@ UNIT_CREATED_BY_SPELL
Definition: UpdateFields.h:138
#define SUMMON_SLOT_TOTEM
Definition: Unit.h:597
#define MAX_TOTEM_SLOT
Definition: Unit.h:598
void UnSummon(uint32 msTime=0) override
Definition: Totem.cpp:122
Totem * ToTotem()
Definition: Unit.h:695
SpellCastResult CastCustomSpell(Unit *victim, uint32 spellId, int32 const *bp0, int32 const *bp1, int32 const *bp2, bool triggered, Item *castItem=nullptr, AuraEffect const *triggeredByAura=nullptr, ObjectGuid originalCaster=ObjectGuid::Empty)
Definition: Unit.cpp:1224
uint32 GetCreateMana() const
Definition: Unit.h:1070
ObjectGuid m_SummonSlot[MAX_SUMMON_SLOT]
Definition: Unit.h:1944
Creature * GetCreature(ObjectGuid const guid)
Definition: Map.cpp:3317
uint32 ManaCostPercentage
Definition: SpellInfo.h:367
uint32 ManaCost
Definition: SpellInfo.h:363

References ApplyPct(), CalculatePct(), Unit::CastCustomSpell(), damage, effectHandleMode, Unit::GetCreateMana(), Map::GetCreature(), WorldObject::GetMap(), Object::GetUInt32Value(), Unit::IsTotem(), m_caster, Unit::m_SummonSlot, SpellInfo::ManaCost, SpellInfo::ManaCostPercentage, MAX_TOTEM_SLOT, SPELL_EFFECT_HANDLE_HIT, sSpellMgr, SUMMON_SLOT_TOTEM, Unit::ToTotem(), UNIT_CREATED_BY_SPELL, and Totem::UnSummon().

◆ EffectDiscoverTaxi()

void Spell::EffectDiscoverTaxi ( SpellEffIndex  effIndex)
5875{
5877 return;
5878
5879 if (!unitTarget)
5880 return;
5881
5882 Player* player = unitTarget->ToPlayer();
5883 if (!player)
5884 {
5885 return;
5886 }
5887
5888 uint32 nodeid = m_spellInfo->Effects[effIndex].MiscValue;
5889 if (sTaxiNodesStore.LookupEntry(nodeid))
5890 player->GetSession()->SendDiscoverNewTaxiNode(nodeid);
5891}
DBCStorage< TaxiNodesEntry > sTaxiNodesStore(TaxiNodesEntryfmt)
void SendDiscoverNewTaxiNode(uint32 nodeid)
Definition: TaxiHandler.cpp:151

References effectHandleMode, SpellInfo::Effects, Player::GetSession(), m_spellInfo, WorldSession::SendDiscoverNewTaxiNode(), SPELL_EFFECT_HANDLE_HIT_TARGET, sTaxiNodesStore, Object::ToPlayer(), and unitTarget.

◆ EffectDisEnchant()

void Spell::EffectDisEnchant ( SpellEffIndex  effIndex)
4475{
4477 return;
4478
4480 return;
4481
4482 if (Player* caster = m_caster->ToPlayer())
4483 {
4484 caster->UpdateCraftSkill(m_spellInfo->Id);
4485 caster->SendLoot(itemTarget->GetGUID(), LOOT_DISENCHANTING);
4486 }
4487
4488 // item will be removed at disenchanting end
4489}
@ LOOT_DISENCHANTING
Definition: LootMgr.h:83

References ItemTemplate::DisenchantID, effectHandleMode, Object::GetGUID(), Item::GetTemplate(), SpellInfo::Id, itemTarget, LOOT_DISENCHANTING, m_caster, m_spellInfo, SPELL_EFFECT_HANDLE_HIT_TARGET, and Object::ToPlayer().

◆ EffectDismissPet()

void Spell::EffectDismissPet ( SpellEffIndex  effIndex)
4561{
4563 return;
4564
4565 if (!unitTarget || !unitTarget->IsPet())
4566 return;
4567
4568 Pet* pet = unitTarget->ToPet();
4569
4570 ExecuteLogEffectUnsummonObject(effIndex, pet);
4572}
@ PET_SAVE_NOT_IN_SLOT
Definition: PetDefines.h:45
void Remove(PetSaveMode mode, bool returnreagent=false)
Definition: Pet.cpp:878
void ExecuteLogEffectUnsummonObject(uint8 effIndex, WorldObject *obj)
Definition: Spell.cpp:5167

References effectHandleMode, ExecuteLogEffectUnsummonObject(), Unit::IsPet(), PET_SAVE_NOT_IN_SLOT, Pet::Remove(), SPELL_EFFECT_HANDLE_HIT_TARGET, Unit::ToPet(), and unitTarget.

◆ EffectDispel()

void Spell::EffectDispel ( SpellEffIndex  effIndex)
2567{
2569 return;
2570
2571 if (!unitTarget)
2572 return;
2573
2574 // Create dispel mask by dispel type
2575 uint32 dispel_type = m_spellInfo->Effects[effIndex].MiscValue;
2576 uint32 dispelMask = SpellInfo::GetDispelMask(DispelType(dispel_type));
2577
2578 DispelChargesList dispel_list;
2579 unitTarget->GetDispellableAuraList(m_caster, dispelMask, dispel_list, m_spellInfo);
2580 if (dispel_list.empty())
2581 return;
2582
2583 // Ok if exist some buffs for dispel try dispel it
2584 uint32 failCount = 0;
2585 DispelChargesList success_list;
2586 WorldPacket dataFail(SMSG_DISPEL_FAILED, 8 + 8 + 4 + 4 + damage * 4);
2587 // dispel N = damage buffs (or while exist buffs for dispel)
2588 for (int32 count = 0; count < damage && !dispel_list.empty();)
2589 {
2590 // Random select buff for dispel
2591 DispelChargesList::iterator itr = dispel_list.begin();
2592 std::advance(itr, urand(0, dispel_list.size() - 1));
2593
2594 int32 chance = itr->first->CalcDispelChance(unitTarget, !unitTarget->IsFriendlyTo(m_caster));
2595 // 2.4.3 Patch Notes: "Dispel effects will no longer attempt to remove effects that have 100% dispel resistance."
2596 if (!chance)
2597 {
2598 dispel_list.erase(itr);
2599 continue;
2600 }
2601 else
2602 {
2603 if (roll_chance_i(chance))
2604 {
2605 bool alreadyListed = false;
2606 for (DispelChargesList::iterator successItr = success_list.begin(); successItr != success_list.end(); ++successItr)
2607 {
2608 if (successItr->first->GetId() == itr->first->GetId())
2609 {
2610 ++successItr->second;
2611 alreadyListed = true;
2612 }
2613 }
2614 if (!alreadyListed)
2615 success_list.push_back(std::make_pair(itr->first, 1));
2616 --itr->second;
2617 if (itr->second <= 0)
2618 dispel_list.erase(itr);
2619 }
2620 else
2621 {
2622 if (!failCount)
2623 {
2624 // Failed to dispell
2625 dataFail << m_caster->GetGUID(); // Caster GUID
2626 dataFail << unitTarget->GetGUID(); // Victim GUID
2627 dataFail << uint32(m_spellInfo->Id); // dispel spell id
2628 }
2629 ++failCount;
2630 dataFail << uint32(itr->first->GetId()); // Spell Id
2631 }
2632 ++count;
2633 }
2634 }
2635
2636 if (failCount)
2637 m_caster->SendMessageToSet(&dataFail, true);
2638
2639 // put in combat
2642
2643 if (success_list.empty())
2644 return;
2645
2646 WorldPacket dataSuccess(SMSG_SPELLDISPELLOG, 8 + 8 + 4 + 1 + 4 + success_list.size() * 5);
2647 // Send packet header
2648 dataSuccess << unitTarget->GetPackGUID(); // Victim GUID
2649 dataSuccess << m_caster->GetPackGUID(); // Caster GUID
2650 dataSuccess << uint32(m_spellInfo->Id); // dispel spell id
2651 dataSuccess << uint8(0); // not used
2652 dataSuccess << uint32(success_list.size()); // count
2653 for (DispelChargesList::iterator itr = success_list.begin(); itr != success_list.end(); ++itr)
2654 {
2655 // Send dispelled spell info
2656 dataSuccess << uint32(itr->first->GetId()); // Spell Id
2657 dataSuccess << uint8(0); // 0 - dispelled !=0 cleansed
2658 unitTarget->RemoveAurasDueToSpellByDispel(itr->first->GetId(), m_spellInfo->Id, itr->first->GetCasterGUID(), m_caster, itr->second);
2659 }
2660 m_caster->SendMessageToSet(&dataSuccess, true);
2661
2662 // On success dispel
2663 // Devour Magic
2665 {
2666 int32 heal_amount = m_spellInfo->Effects[EFFECT_1].CalcValue();
2667 m_caster->CastCustomSpell(m_caster, 19658, &heal_amount, nullptr, nullptr, true);
2668 // Glyph of Felhunter
2669 if (Unit* owner = m_caster->GetOwner())
2670 if (owner->GetAura(56249))
2671 owner->CastCustomSpell(owner, 19658, &heal_amount, nullptr, nullptr, true);
2672 }
2673}
uint32 urand(uint32 min, uint32 max)
Definition: Random.cpp:44
@ SPELLFAMILY_WARLOCK
Definition: SharedDefines.h:3533
@ SPELLCATEGORY_DEVOUR_MAGIC
Definition: SpellMgr.h:40
@ SMSG_DISPEL_FAILED
Definition: Opcodes.h:640
@ SMSG_SPELLDISPELLOG
Definition: Opcodes.h:665
void GetDispellableAuraList(Unit *caster, uint32 dispelMask, DispelChargesList &dispelList, SpellInfo const *dispelSpell)
Definition: Unit.cpp:5605
void RemoveAurasDueToSpellByDispel(uint32 spellId, uint32 dispellerSpellId, ObjectGuid casterGUID, Unit *dispeller, uint8 chargesRemoved=1)
Definition: Unit.cpp:4942
uint32 GetCategory() const
Definition: SpellInfo.cpp:871

References Unit::CastCustomSpell(), damage, EFFECT_1, effectHandleMode, SpellInfo::Effects, SpellInfo::GetCategory(), Unit::GetDispellableAuraList(), SpellInfo::GetDispelMask(), Object::GetGUID(), Unit::getHostileRefMgr(), Unit::GetOwner(), Object::GetPackGUID(), SpellInfo::Id, Unit::IsFriendlyTo(), m_caster, m_spellInfo, Unit::RemoveAurasDueToSpellByDispel(), roll_chance_i(), WorldObject::SendMessageToSet(), SMSG_DISPEL_FAILED, SMSG_SPELLDISPELLOG, SPELL_EFFECT_HANDLE_HIT_TARGET, SPELLCATEGORY_DEVOUR_MAGIC, SPELLFAMILY_WARLOCK, SpellInfo::SpellFamilyName, HostileRefMgr::threatAssist(), unitTarget, and urand().

◆ EffectDispelMechanic()

void Spell::EffectDispelMechanic ( SpellEffIndex  effIndex)
5163{
5165 return;
5166
5167 if (!unitTarget)
5168 return;
5169
5170 uint32 mechanic = m_spellInfo->Effects[effIndex].MiscValue;
5171
5172 std::queue<std::pair<uint32, ObjectGuid>> dispel_list;
5173
5174 Unit::AuraMap const& auras = unitTarget->GetOwnedAuras();
5175 for (Unit::AuraMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
5176 {
5177 Aura* aura = itr->second;
5179 continue;
5181 {
5182 if ((aura->GetSpellInfo()->GetAllEffectsMechanicMask() & (1 << mechanic)))
5183 {
5184 dispel_list.push(std::make_pair(aura->GetId(), aura->GetCasterGUID()));
5185
5186 // spell only removes 1 bleed effect do not continue
5187 if (m_spellInfo->Effects[effIndex].BasePoints == 1)
5188 {
5189 break;
5190 }
5191 }
5192 }
5193 }
5194
5195 for (; dispel_list.size(); dispel_list.pop())
5196 {
5197 unitTarget->RemoveAura(dispel_list.front().first, dispel_list.front().second, 0, AURA_REMOVE_BY_ENEMY_SPELL);
5198 }
5199
5200 // put in combat
5203}
@ AURA_REMOVE_BY_ENEMY_SPELL
Definition: SpellAuraDefines.h:394
void RemoveAura(AuraApplicationMap::iterator &i, AuraRemoveMode mode=AURA_REMOVE_BY_DEFAULT)
Definition: Unit.cpp:4776
ObjectGuid GetCasterGUID() const
Definition: SpellAuras.h:105
uint32 GetId() const
Definition: SpellAuras.cpp:466
int32 CalcDispelChance(Unit *auraTarget, bool offensive) const
Definition: SpellAuras.cpp:1182

References AURA_REMOVE_BY_ENEMY_SPELL, Aura::CalcDispelChance(), effectHandleMode, SpellInfo::Effects, SpellInfo::GetAllEffectsMechanicMask(), Aura::GetApplicationOfTarget(), Aura::GetCasterGUID(), Object::GetGUID(), Unit::getHostileRefMgr(), Aura::GetId(), Unit::GetOwnedAuras(), Aura::GetSpellInfo(), Unit::IsFriendlyTo(), m_caster, m_spellInfo, Unit::RemoveAura(), roll_chance_i(), SPELL_EFFECT_HANDLE_HIT_TARGET, HostileRefMgr::threatAssist(), and unitTarget.

◆ EffectDistract()

void Spell::EffectDistract ( SpellEffIndex  effIndex)

@BUG Causes the player to stop moving.

2690{
2692 return;
2693
2694 // Check for possible target
2695 if (!unitTarget || unitTarget->IsEngaged())
2696 return;
2697
2698 // target must be OK to do this
2700 return;
2701
2704}
@ UNIT_STATE_CONFUSED
Definition: UnitDefines.h:160
@ UNIT_STATE_FLEEING
Definition: UnitDefines.h:156
@ UNIT_STATE_STUNNED
Definition: UnitDefines.h:152
float GetAngle(const Position *pos) const
Definition: Position.cpp:78
void SetFacingTo(float ori)
Definition: Unit.cpp:20527
bool IsEngaged() const
Definition: Unit.h:881
void MoveDistract(uint32 time)
Enable the target's distract movement. Doesn't work with UNIT_FLAG_DISABLE_MOVE and if the unit has M...
Definition: MotionMaster.cpp:798

References damage, destTarget, effectHandleMode, Position::GetAngle(), Unit::GetMotionMaster(), Unit::HasUnitState(), IN_MILLISECONDS, Unit::IsEngaged(), MotionMaster::MoveDistract(), Unit::SetFacingTo(), SPELL_EFFECT_HANDLE_HIT_TARGET, UNIT_STATE_CONFUSED, UNIT_STATE_FLEEING, UNIT_STATE_STUNNED, and unitTarget.

◆ EffectDualWield()

void Spell::EffectDualWield ( SpellEffIndex  effIndex)
2676{
2678 return;
2679
2681}
virtual void SetCanDualWield(bool value)
Definition: Unit.h:924

References effectHandleMode, Unit::SetCanDualWield(), SPELL_EFFECT_HANDLE_HIT_TARGET, and unitTarget.

◆ EffectDuel()

void Spell::EffectDuel ( SpellEffIndex  effIndex)
4112{
4114 return;
4115
4116 if (!unitTarget || !m_caster->IsPlayer() || !unitTarget->IsPlayer())
4117 return;
4118
4119 Player* caster = m_caster->ToPlayer();
4120 Player* target = unitTarget->ToPlayer();
4121
4122 // caster or target already have requested duel
4123 if (caster->duel || target->duel || !target->GetSocial() || target->GetSocial()->HasIgnore(caster->GetGUID()))
4124 return;
4125
4126 // Players can only fight a duel in zones with this flag
4127 AreaTableEntry const* casterAreaEntry = sAreaTableStore.LookupEntry(caster->GetAreaId());
4128 if (casterAreaEntry && !(casterAreaEntry->flags & AREA_FLAG_ALLOW_DUELS))
4129 {
4130 SendCastResult(SPELL_FAILED_NO_DUELING); // Dueling isn't allowed here
4131 return;
4132 }
4133
4134 AreaTableEntry const* targetAreaEntry = sAreaTableStore.LookupEntry(target->GetAreaId());
4135 if (targetAreaEntry && !(targetAreaEntry->flags & AREA_FLAG_ALLOW_DUELS))
4136 {
4137 SendCastResult(SPELL_FAILED_NO_DUELING); // Dueling isn't allowed here
4138 return;
4139 }
4140
4141 //CREATE DUEL FLAG OBJECT
4142 uint32 gameobject_id = m_spellInfo->Effects[effIndex].MiscValue;
4143 GameObject* pGameObj = sObjectMgr->IsGameObjectStaticTransport(gameobject_id) ? new StaticTransport() : new GameObject();
4144
4145 Map* map = m_caster->GetMap();
4146 if (!pGameObj->Create(map->GenerateLowGuid<HighGuid::GameObject>(), gameobject_id,
4147 map, m_caster->GetPhaseMask(),
4151 m_caster->GetOrientation(), G3D::Quat(), 0, GO_STATE_READY))
4152 {
4153 delete pGameObj;
4154 return;
4155 }
4156
4159 int32 duration = m_spellInfo->GetDuration();
4160 pGameObj->SetRespawnTime(duration > 0 ? duration / IN_MILLISECONDS : 0);
4161 pGameObj->SetSpellId(m_spellInfo->Id);
4162
4163 ExecuteLogEffectSummonObject(effIndex, pGameObj);
4164
4165 m_caster->AddGameObject(pGameObj);
4166 map->AddToMap(pGameObj, true);
4167 //END
4168
4169 // Send request
4170 WorldPacket data(SMSG_DUEL_REQUESTED, 8 + 8);
4171 data << pGameObj->GetGUID();
4172 data << caster->GetGUID();
4173 caster->GetSession()->SendPacket(&data);
4174 target->GetSession()->SendPacket(&data);
4175
4176 // create duel-info
4177 bool isMounted = (GetSpellInfo()->Id == 62875);
4178 caster->duel = std::make_unique<DuelInfo>(target, caster, isMounted);
4179 target->duel = std::make_unique<DuelInfo>(caster, caster, isMounted);
4180
4181 caster->SetGuidValue(PLAYER_DUEL_ARBITER, pGameObj->GetGUID());
4182 target->SetGuidValue(PLAYER_DUEL_ARBITER, pGameObj->GetGUID());
4183
4184 sScriptMgr->OnPlayerDuelRequest(target, caster);
4185}
@ AREA_FLAG_ALLOW_DUELS
Definition: DBCEnums.h:240
@ SPELL_FAILED_NO_DUELING
Definition: SharedDefines.h:1028
@ PLAYER_DUEL_ARBITER
Definition: UpdateFields.h:177
@ GAMEOBJECT_LEVEL
Definition: UpdateFields.h:403
@ GAMEOBJECT_FACTION
Definition: UpdateFields.h:402
@ SMSG_DUEL_REQUESTED
Definition: Opcodes.h:389
virtual bool Create(ObjectGuid::LowType guidlow, uint32 name_id, Map *map, uint32 phaseMask, float x, float y, float z, float ang, G3D::Quat const &rotation, uint32 animprogress, GOState go_state, uint32 artKit=0)
Definition: GameObject.cpp:254
void SetRespawnTime(int32 respawn)
Definition: GameObject.cpp:1305
void SetSpellId(uint32 id)
Definition: GameObject.h:176
void SetUInt32Value(uint16 index, uint32 value)
Definition: Object.cpp:650
uint32 GetPhaseMask() const
Definition: Object.h:451
float GetOrientation() const
Definition: Position.h:119
PlayerSocial * GetSocial()
Definition: Player.h:1158
bool HasIgnore(ObjectGuid ignore_guid) const
Definition: SocialMgr.cpp:193
Definition: Transport.h:112
uint32 GetFaction() const
Definition: Unit.h:808
void AddGameObject(GameObject *gameObj)
Definition: Unit.cpp:6179
void SendPacket(WorldPacket const *packet)
Send a packet to the client.
Definition: WorldSession.cpp:214
void ExecuteLogEffectSummonObject(uint8 effIndex, WorldObject *obj)
Definition: Spell.cpp:5161
uint32 flags
Definition: DBCStructure.h:523

References Unit::AddGameObject(), Map::AddToMap(), AREA_FLAG_ALLOW_DUELS, GameObject::Create(), Player::duel, effectHandleMode, SpellInfo::Effects, ExecuteLogEffectSummonObject(), AreaTableEntry::flags, GAMEOBJECT_FACTION, GAMEOBJECT_LEVEL, Map::GenerateLowGuid(), WorldObject::GetAreaId(), SpellInfo::GetDuration(), Unit::GetFaction(), Object::GetGUID(), Unit::GetLevel(), WorldObject::GetMap(), Position::GetOrientation(), WorldObject::GetPhaseMask(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), Player::GetSession(), Player::GetSocial(), GetSpellInfo(), GO_STATE_READY, PlayerSocial::HasIgnore(), SpellInfo::Id, IN_MILLISECONDS, Object::IsPlayer(), m_caster, m_spellInfo, PLAYER_DUEL_ARBITER, sAreaTableStore, SendCastResult(), WorldSession::SendPacket(), Object::SetGuidValue(), GameObject::SetRespawnTime(), GameObject::SetSpellId(), Object::SetUInt32Value(), SMSG_DUEL_REQUESTED, sObjectMgr, SPELL_EFFECT_HANDLE_HIT_TARGET, SPELL_FAILED_NO_DUELING, sScriptMgr, Object::ToPlayer(), and unitTarget.

◆ EffectDummy()

void Spell::EffectDummy ( SpellEffIndex  effIndex)
663{
665 return;
666
668 return;
669
670 // selection by spell family
672 {
674 {
675 switch (m_spellInfo->Id)
676 {
677 // Trial of the Champion, Trample
678 case 67866:
679 {
681 unitTarget->CastSpell(unitTarget, 67867, false);
682 return;
683 }
684 // Trial of the Champion, Hammer of the Righteous
685 case 66867:
686 {
687 if (!unitTarget)
688 return;
689 if (unitTarget->HasAura(66940))
690 m_caster->CastSpell(unitTarget, 66903, true);
691 else
692 m_caster->CastSpell(unitTarget, 66904, true);
693 return;
694 }
695 case 17731:
696 case 69294:
697 {
699 return;
700
704 trigger->CastSpell(trigger, 17731, false);
705
706 return;
707 }
708 // HoL, Arc Weld
709 case 59086:
710 {
712 m_caster->CastSpell(m_caster, 59097, true);
713
714 return;
715 }
716 }
717 break;
718 }
720 switch (m_spellInfo->Id)
721 {
722 case 31789: // Righteous Defense (step 1)
723 {
724 if (!unitTarget)
725 return;
726 // not empty (checked), copy
728
729 // remove invalid attackers
730 for (Unit::AttackerSet::iterator aItr = attackers.begin(); aItr != attackers.end();)
731 if (!(*aItr)->IsValidAttackTarget(m_caster))
732 aItr = attackers.erase(aItr);
733 else
734 ++aItr;
735
736 // selected from list 3
737 uint32 maxTargets = std::min<uint32>(3, attackers.size());
738 for (uint32 i = 0; i < maxTargets; ++i)
739 {
740 Unit::AttackerSet::iterator aItr = attackers.begin();
741 std::advance(aItr, urand(0, attackers.size() - 1));
742 m_caster->CastSpell((*aItr), 31790, true);
743 attackers.erase(aItr);
744 }
745
746 return;
747 }
748 }
749 break;
751 // Hunger for Blood
752 if (m_spellInfo->Id == 51662)
753 {
754 m_caster->CastSpell(m_caster, 63848, true);
755 return;
756 }
757 break;
758 }
759
760 // pet auras
761 if (PetAura const* petSpell = sSpellMgr->GetPetAura(m_spellInfo->Id, effIndex))
762 {
763 m_caster->AddPetAura(petSpell);
764 return;
765 }
766
767 // normal DB scripted effect
768 LOG_DEBUG("spells.aura", "Spell ScriptStart spellid {} in EffectDummy({})", m_spellInfo->Id, effIndex);
770
771 if (gameObjTarget)
772 {
773 sScriptMgr->OnDummyEffect(m_caster, m_spellInfo->Id, effIndex, gameObjTarget);
774 }
775 else if (unitTarget && unitTarget->IsCreature())
776 {
777 sScriptMgr->OnDummyEffect(m_caster, m_spellInfo->Id, effIndex, unitTarget->ToCreature());
778 }
779 else if (itemTarget)
780 {
781 sScriptMgr->OnDummyEffect(m_caster, m_spellInfo->Id, effIndex, itemTarget);
782 }
783}
@ SPELLFAMILY_GENERIC
Definition: SharedDefines.h:3528
@ SPELLFAMILY_PALADIN
Definition: SharedDefines.h:3538
@ SPELLFAMILY_ROGUE
Definition: SharedDefines.h:3536
ScriptMapMap sSpellScripts
Definition: ObjectMgr.cpp:59
@ TEMPSUMMON_TIMED_DESPAWN
Definition: Object.h:48
@ UNIT_FIELD_MOUNTDISPLAYID
Definition: UpdateFields.h:126
uint8 GetGoAnimProgress() const
Definition: GameObject.h:209
time_t GetRespawnTime() const
Definition: GameObject.h:183
TempSummon * SummonCreature(uint32 id, const Position &pos, TempSummonType spwtype=TEMPSUMMON_MANUAL_DESPAWN, uint32 despwtime=0, uint32 vehId=0, SummonPropertiesEntry const *properties=nullptr, bool visibleBySummonerOnly=false) const
Definition: Object.cpp:2366
void AddPetAura(PetAura const *petSpell)
Definition: Unit.cpp:17297
std::unordered_set< Unit * > AttackerSet
Definition: Unit.h:632
AttackerSet const & getAttackers() const
Definition: Unit.h:850
void ScriptsStart(std::map< uint32, std::multimap< uint32, ScriptInfo > > const &scripts, uint32 id, Object *source, Object *target)
Put scripts in the execution queue.
Definition: MapScripts.cpp:31
Definition: SpellMgr.h:470

References Unit::AddPetAura(), Unit::CastSpell(), effectHandleMode, gameObjTarget, Unit::getAttackers(), GameTime::GetGameTime(), GameObject::GetGoAnimProgress(), WorldObject::GetMap(), GameObject::GetRespawnTime(), Object::GetUInt32Value(), Unit::HasAura(), SpellInfo::Id, Object::IsCreature(), Unit::isMoving(), Object::IsPlayer(), Unit::IsVehicle(), itemTarget, LOG_DEBUG, m_caster, m_spellInfo, Map::ScriptsStart(), GameObject::SendCustomAnim(), GameObject::SetRespawnTime(), SPELL_EFFECT_HANDLE_HIT_TARGET, SPELLFAMILY_GENERIC, SPELLFAMILY_PALADIN, SPELLFAMILY_ROGUE, SpellInfo::SpellFamilyName, sScriptMgr, sSpellMgr, sSpellScripts, WorldObject::SummonCreature(), TEMPSUMMON_TIMED_DESPAWN, Object::ToCreature(), Object::ToPlayer(), UNIT_FIELD_MOUNTDISPLAYID, unitTarget, and urand().

◆ EffectDurabilityDamage()

void Spell::EffectDurabilityDamage ( SpellEffIndex  effIndex)
5287{
5289 return;
5290
5291 if (!unitTarget)
5292 return;
5293
5294 Player* player = unitTarget->ToPlayer();
5295 if (!player)
5296 {
5297 return;
5298 }
5299
5300 int32 slot = m_spellInfo->Effects[effIndex].MiscValue;
5301
5302 // -1 means all player equipped items and -2 all items
5303 if (slot < 0)
5304 {
5305 player->DurabilityPointsLossAll(damage, (slot < -1));
5307 return;
5308 }
5309
5310 // invalid slot value
5311 if (slot >= INVENTORY_SLOT_BAG_END)
5312 return;
5313
5314 if (Item* item = player->GetItemByPos(INVENTORY_SLOT_BAG_0, slot))
5315 {
5316 player->DurabilityPointsLoss(item, damage);
5317 ExecuteLogEffectDurabilityDamage(effIndex, unitTarget, item->GetEntry(), slot);
5318 }
5319}
@ INVENTORY_SLOT_BAG_END
Definition: Player.h:705
#define INVENTORY_SLOT_BAG_0
Definition: Player.h:675
Item * GetItemByPos(uint16 pos) const
Definition: PlayerStorage.cpp:441
void DurabilityPointsLossAll(int32 points, bool inventory)
Definition: Player.cpp:4779
void DurabilityPointsLoss(Item *item, int32 points)
Definition: Player.cpp:4805
void ExecuteLogEffectDurabilityDamage(uint8 effIndex, Unit *victim, int32 itemId, int32 slot)
Definition: Spell.cpp:5135

References damage, Player::DurabilityPointsLoss(), Player::DurabilityPointsLossAll(), effectHandleMode, SpellInfo::Effects, ExecuteLogEffectDurabilityDamage(), Object::GetEntry(), Player::GetItemByPos(), INVENTORY_SLOT_BAG_0, INVENTORY_SLOT_BAG_END, m_spellInfo, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectDurabilityDamagePCT()

void Spell::EffectDurabilityDamagePCT ( SpellEffIndex  effIndex)
5322{
5324 return;
5325
5326 if (!unitTarget)
5327 return;
5328
5329 Player* player = unitTarget->ToPlayer();
5330 if (!player)
5331 {
5332 return;
5333 }
5334
5335 int32 slot = m_spellInfo->Effects[effIndex].MiscValue;
5336
5337 // FIXME: some spells effects have value -1/-2
5338 // Possibly its mean -1 all player equipped items and -2 all items
5339 if (slot < 0)
5340 {
5341 player->DurabilityLossAll(float(damage) / 100.0f, (slot < -1));
5342 return;
5343 }
5344
5345 // invalid slot value
5346 if (slot >= INVENTORY_SLOT_BAG_END)
5347 return;
5348
5349 if (damage <= 0)
5350 return;
5351
5352 if (Item* item = player->GetItemByPos(INVENTORY_SLOT_BAG_0, slot))
5353 player->DurabilityLoss(item, float(damage) / 100.0f);
5354}
void DurabilityLossAll(double percent, bool inventory)
Definition: Player.cpp:4735
void DurabilityLoss(Item *item, double percent)
Definition: Player.cpp:4761

References damage, Player::DurabilityLoss(), Player::DurabilityLossAll(), effectHandleMode, SpellInfo::Effects, Player::GetItemByPos(), INVENTORY_SLOT_BAG_0, INVENTORY_SLOT_BAG_END, m_spellInfo, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectEnchantHeldItem()

void Spell::EffectEnchantHeldItem ( SpellEffIndex  effIndex)
4422{
4424 return;
4425
4426 // this is only item spell effect applied to main-hand weapon of target player (players in area)
4427 if (!unitTarget)
4428 return;
4429
4430 Player* item_owner = unitTarget->ToPlayer();
4431 if (!item_owner)
4432 {
4433 return;
4434 }
4435
4437 if (!item)
4438 return;
4439
4440 // must be equipped
4441 if (!item->IsEquipped())
4442 return;
4443
4444 if (m_spellInfo->Effects[effIndex].MiscValue)
4445 {
4446 uint32 enchant_id = m_spellInfo->Effects[effIndex].MiscValue;
4447 int32 duration = m_spellInfo->GetDuration(); //Try duration index first ..
4448 if (!duration)
4449 duration = damage * IN_MILLISECONDS; //+1; //Base points after ..
4450 if (!duration)
4451 duration = 10 * IN_MILLISECONDS; //10 seconds for enchants which don't have listed duration
4452
4453 // Xinef: Venomhide poison, no other spell uses this effect...
4454 if (m_spellInfo->Id == 14792)
4455 duration = 5 * MINUTE * IN_MILLISECONDS;
4456
4457 SpellItemEnchantmentEntry const* pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id);
4458 if (!pEnchant)
4459 return;
4460
4461 // Always go to temp enchantment slot
4463
4464 // Enchantment will not be applied if a different one already exists
4465 if (item->GetEnchantmentId(slot) && item->GetEnchantmentId(slot) != enchant_id)
4466 return;
4467
4468 // Apply the temporary enchantment
4469 item->SetEnchantment(slot, enchant_id, duration, pEnchant->charges, m_caster->GetGUID());
4470 item_owner->ApplyEnchantment(item, slot, true);
4471 }
4472}
@ EQUIPMENT_SLOT_MAINHAND
Definition: Player.h:695
EnchantmentSlot
Definition: Item.h:168
@ TEMP_ENCHANTMENT_SLOT
Definition: Item.h:170
bool IsEquipped() const
Definition: Item.cpp:789
void SetEnchantment(EnchantmentSlot slot, uint32 id, uint32 duration, uint32 charges, ObjectGuid caster=ObjectGuid::Empty)
Definition: Item.cpp:920
void ApplyEnchantment(Item *item, EnchantmentSlot slot, bool apply, bool apply_dur=true, bool ignore_condition=false)
Definition: PlayerStorage.cpp:4305
uint32 charges
Definition: DBCStructure.h:1842

References Player::ApplyEnchantment(), SpellItemEnchantmentEntry::charges, damage, effectHandleMode, SpellInfo::Effects, EQUIPMENT_SLOT_MAINHAND, SpellInfo::GetDuration(), Item::GetEnchantmentId(), Object::GetGUID(), Player::GetItemByPos(), SpellInfo::Id, IN_MILLISECONDS, INVENTORY_SLOT_BAG_0, Item::IsEquipped(), m_caster, m_spellInfo, MINUTE, Item::SetEnchantment(), SPELL_EFFECT_HANDLE_HIT_TARGET, sSpellItemEnchantmentStore, TEMP_ENCHANTMENT_SLOT, Object::ToPlayer(), and unitTarget.

◆ EffectEnchantItemPerm()

void Spell::EffectEnchantItemPerm ( SpellEffIndex  effIndex)
2834{
2836 return;
2837
2838 if (!m_caster->IsPlayer())
2839 return;
2840 if (!itemTarget)
2841 return;
2842
2843 Player* p_caster = m_caster->ToPlayer();
2844
2845 // Handle vellums
2847 {
2848 // destroy one vellum from stack
2849 uint32 count = 1;
2850 p_caster->DestroyItemCount(itemTarget, count, true);
2851 unitTarget = p_caster;
2852 // and add a scroll
2853 DoCreateItem(effIndex, m_spellInfo->Effects[effIndex].ItemType);
2854 itemTarget = nullptr;
2855 m_targets.SetItemTarget(nullptr);
2856 }
2857 else
2858 {
2859 // do not increase skill if vellum used
2861 p_caster->UpdateCraftSkill(m_spellInfo->Id);
2862
2863 uint32 enchant_id = m_spellInfo->Effects[effIndex].MiscValue;
2864 if (!enchant_id)
2865 return;
2866
2867 SpellItemEnchantmentEntry const* pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id);
2868 if (!pEnchant)
2869 return;
2870
2871 // item can be in trade slot and have owner diff. from caster
2872 Player* item_owner = itemTarget->GetOwner();
2873 if (!item_owner)
2874 return;
2875
2876 // remove old enchanting before applying new if equipped
2878
2880
2881 // add new enchanting if equipped
2883
2884 item_owner->RemoveTradeableItem(itemTarget);
2886 }
2887}
@ PERM_ENCHANTMENT_SLOT
Definition: Item.h:169
void ClearSoulboundTradeable(Player *currentOwner)
Definition: Item.cpp:1264
void RemoveTradeableItem(Item *item)
Definition: PlayerStorage.cpp:4140
void SetItemTarget(Item *item)
Definition: Spell.cpp:328

References Player::ApplyEnchantment(), Item::ClearSoulboundTradeable(), Player::DestroyItemCount(), DoCreateItem(), effectHandleMode, SpellInfo::Effects, Object::GetGUID(), Item::GetOwner(), Item::GetTemplate(), ItemTemplate::HasFlag(), SpellInfo::Id, Item::IsArmorVellum(), Object::IsPlayer(), Item::IsWeaponVellum(), ITEM_FLAG_NO_REAGENT_COST, itemTarget, m_caster, m_CastItem, m_spellInfo, m_targets, PERM_ENCHANTMENT_SLOT, Player::RemoveTradeableItem(), Item::SetEnchantment(), SpellCastTargets::SetItemTarget(), SPELL_EFFECT_HANDLE_HIT_TARGET, sSpellItemEnchantmentStore, Object::ToPlayer(), unitTarget, and Player::UpdateCraftSkill().

◆ EffectEnchantItemPrismatic()

void Spell::EffectEnchantItemPrismatic ( SpellEffIndex  effIndex)
2890{
2892 return;
2893
2894 if (!m_caster->IsPlayer())
2895 return;
2896 if (!itemTarget)
2897 return;
2898
2899 uint32 enchant_id = m_spellInfo->Effects[effIndex].MiscValue;
2900 if (!enchant_id)
2901 return;
2902
2903 SpellItemEnchantmentEntry const* pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id);
2904 if (!pEnchant)
2905 return;
2906
2907 // support only enchantings with add socket in this slot
2908 {
2909 bool add_socket = false;
2910 for (uint8 i = 0; i < MAX_SPELL_ITEM_ENCHANTMENT_EFFECTS; ++i)
2911 {
2912 if (pEnchant->type[i] == ITEM_ENCHANTMENT_TYPE_PRISMATIC_SOCKET)
2913 {
2914 add_socket = true;
2915 break;
2916 }
2917 }
2918 if (!add_socket)
2919 {
2920 LOG_ERROR("spells.effect", "Spell::EffectEnchantItemPrismatic: attempt apply enchant spell {} with SPELL_EFFECT_ENCHANT_ITEM_PRISMATIC ({}) but without ITEM_ENCHANTMENT_TYPE_PRISMATIC_SOCKET ({}), not suppoted yet.",
2922 return;
2923 }
2924 }
2925
2926 // item can be in trade slot and have owner diff. from caster
2927 Player* item_owner = itemTarget->GetOwner();
2928 if (!item_owner)
2929 return;
2930
2931 // remove old enchanting before applying new if equipped
2933
2935
2936 // add new enchanting if equipped
2938
2939 item_owner->RemoveTradeableItem(itemTarget);
2941}

References Player::ApplyEnchantment(), Item::ClearSoulboundTradeable(), effectHandleMode, SpellInfo::Effects, Object::GetGUID(), Item::GetOwner(), SpellInfo::Id, Object::IsPlayer(), ITEM_ENCHANTMENT_TYPE_PRISMATIC_SOCKET, itemTarget, LOG_ERROR, m_caster, m_spellInfo, MAX_SPELL_ITEM_ENCHANTMENT_EFFECTS, PRISMATIC_ENCHANTMENT_SLOT, Player::RemoveTradeableItem(), Item::SetEnchantment(), SPELL_EFFECT_ENCHANT_ITEM_PRISMATIC, SPELL_EFFECT_HANDLE_HIT_TARGET, sSpellItemEnchantmentStore, and SpellItemEnchantmentEntry::type.

◆ EffectEnchantItemTmp()

void Spell::EffectEnchantItemTmp ( SpellEffIndex  effIndex)
2944{
2946 return;
2947
2948 if (!m_caster->IsPlayer())
2949 return;
2950
2951 Player* p_caster = m_caster->ToPlayer();
2952
2953 // Rockbiter Weapon apply to both weapon
2954 if (!itemTarget)
2955 return;
2957 {
2958 uint32 spell_id = 0;
2959
2960 // enchanting spell selected by calculated damage-per-sec stored in Effect[1] base value
2961 // Note: damage calculated (correctly) with rounding int32(float(v)) but
2962 // RW enchantments applied damage int32(float(v)+0.5), this create 0..1 difference sometime
2963 switch (damage)
2964 {
2965 // Rank 1
2966 case 2:
2967 spell_id = 36744;
2968 break; // 0% [ 7% == 2, 14% == 2, 20% == 2]
2969 // Rank 2
2970 case 4:
2971 spell_id = 36753;
2972 break; // 0% [ 7% == 4, 14% == 4]
2973 case 5:
2974 spell_id = 36751;
2975 break; // 20%
2976 // Rank 3
2977 case 6:
2978 spell_id = 36754;
2979 break; // 0% [ 7% == 6, 14% == 6]
2980 case 7:
2981 spell_id = 36755;
2982 break; // 20%
2983 // Rank 4
2984 case 9:
2985 spell_id = 36761;
2986 break; // 0% [ 7% == 6]
2987 case 10:
2988 spell_id = 36758;
2989 break; // 14%
2990 case 11:
2991 spell_id = 36760;
2992 break; // 20%
2993 default:
2994 LOG_ERROR("spells.effect", "Spell::EffectEnchantItemTmp: Damage {} not handled in S'RW", damage);
2995 return;
2996 }
2997
2998 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spell_id);
2999 if (!spellInfo)
3000 {
3001 LOG_ERROR("spells.effect", "Spell::EffectEnchantItemTmp: unknown spell id {}", spell_id);
3002 return;
3003 }
3004
3005 for (int j = BASE_ATTACK; j <= OFF_ATTACK; ++j)
3006 {
3007 if (Item* item = p_caster->GetWeaponForAttack(WeaponAttackType(j)))
3008 {
3009 if (item->IsFitToSpellRequirements(m_spellInfo))
3010 {
3011 Spell* spell = new Spell(m_caster, spellInfo, TRIGGERED_FULL_MASK);
3012 SpellCastTargets targets;
3013 targets.SetItemTarget(item);
3014 spell->prepare(&targets);
3015 }
3016 }
3017 }
3018 return;
3019 }
3020 if (!itemTarget)
3021 return;
3022
3023 uint32 enchant_id = m_spellInfo->Effects[effIndex].MiscValue;
3024
3025 if (!enchant_id)
3026 {
3027 LOG_ERROR("spells.effect", "Spell {} Effect {} (SPELL_EFFECT_ENCHANT_ITEM_TEMPORARY) have 0 as enchanting id", m_spellInfo->Id, effIndex);
3028 return;
3029 }
3030
3031 SpellItemEnchantmentEntry const* pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id);
3032 if (!pEnchant)
3033 {
3034 LOG_ERROR("spells.effect", "Spell {} Effect {} (SPELL_EFFECT_ENCHANT_ITEM_TEMPORARY) have not existed enchanting id {} ", m_spellInfo->Id, effIndex, enchant_id);
3035 return;
3036 }
3037
3038 // select enchantment duration
3039 uint32 duration;
3040
3041 // rogue family enchantments exception by duration
3042 if (m_spellInfo->Id == 38615)
3043 duration = 1800; // 30 mins
3044 // other rogue family enchantments always 1 hour (some have spell damage=0, but some have wrong data in EffBasePoints)
3046 duration = 3600; // 1 hour
3047 // shaman family enchantments
3049 duration = 1800; // 30 mins
3050 // other cases with this SpellVisual already selected
3051 else if (m_spellInfo->SpellVisual[0] == 215)
3052 duration = 1800; // 30 mins
3053 // some fishing pole bonuses except Glow Worm which lasts full hour
3054 else if (m_spellInfo->SpellVisual[0] == 563 && m_spellInfo->Id != 64401)
3055 duration = 600; // 10 mins
3056 // shaman rockbiter enchantments
3057 else if (m_spellInfo->SpellVisual[0] == 0)
3058 duration = 1800; // 30 mins
3059 else if (m_spellInfo->Id == 29702)
3060 duration = 300; // 5 mins
3061 else if (m_spellInfo->Id == 37360)
3062 duration = 300; // 5 mins
3063 // default case
3064 else
3065 duration = 3600; // 1 hour
3066
3067 // item can be in trade slot and have owner diff. from caster
3068 Player* item_owner = itemTarget->GetOwner();
3069 if (!item_owner)
3070 return;
3071
3072 // remove old enchanting before applying new if equipped
3074
3075 itemTarget->SetEnchantment(TEMP_ENCHANTMENT_SLOT, enchant_id, duration * 1000, pEnchant->charges, m_caster->GetGUID());
3076
3077 // add new enchanting if equipped
3079
3080 item_owner->RemoveTradeableItem(itemTarget);
3082}
@ SPELLFAMILY_SHAMAN
Definition: SharedDefines.h:3539
WeaponAttackType
Definition: Unit.h:208
Definition: Spell.h:111
SpellCastResult prepare(SpellCastTargets const *targets, AuraEffect const *triggeredByAura=nullptr)
Definition: Spell.cpp:3480
std::array< uint32, 2 > SpellVisual
Definition: SpellInfo.h:379

References Player::ApplyEnchantment(), BASE_ATTACK, SpellItemEnchantmentEntry::charges, Item::ClearSoulboundTradeable(), damage, effectHandleMode, SpellInfo::Effects, Object::GetGUID(), Item::GetOwner(), Player::GetWeaponForAttack(), SpellInfo::Id, Object::IsPlayer(), itemTarget, LOG_ERROR, m_caster, m_spellInfo, OFF_ATTACK, prepare(), Player::RemoveTradeableItem(), Item::SetEnchantment(), SpellCastTargets::SetItemTarget(), SPELL_EFFECT_HANDLE_HIT_TARGET, SPELLFAMILY_ROGUE, SPELLFAMILY_SHAMAN, SpellInfo::SpellFamilyFlags, SpellInfo::SpellFamilyName, SpellInfo::SpellVisual, sSpellItemEnchantmentStore, sSpellMgr, TEMP_ENCHANTMENT_SLOT, Object::ToPlayer(), and TRIGGERED_FULL_MASK.

◆ EffectEnergize()

void Spell::EffectEnergize ( SpellEffIndex  effIndex)
1879{
1881 return;
1882
1883 if (!unitTarget)
1884 return;
1885 if (!unitTarget->IsAlive())
1886 return;
1887
1889 {
1891 return;
1892 }
1893
1894 if (m_spellInfo->Effects[effIndex].MiscValue < 0 || m_spellInfo->Effects[effIndex].MiscValue >= int8(MAX_POWERS))
1895 return;
1896
1897 Powers power = Powers(m_spellInfo->Effects[effIndex].MiscValue);
1898
1901 return;
1902
1903 if (unitTarget->GetMaxPower(power) == 0)
1904 return;
1905
1906 // Some level depends spells
1907 int level_multiplier = 0;
1908 int level_diff = 0;
1909 switch (m_spellInfo->Id)
1910 {
1911 case 9512: // Restore Energy
1912 level_diff = m_caster->GetLevel() - 40;
1913 level_multiplier = 2;
1914 break;
1915 case 24571: // Blood Fury
1916 level_diff = m_caster->GetLevel() - 60;
1917 level_multiplier = 10;
1918 break;
1919 case 24532: // Burst of Energy
1920 level_diff = m_caster->GetLevel() - 60;
1921 level_multiplier = 4;
1922 break;
1923 case 31930: // Judgements of the Wise
1924 case 63375: // Improved Stormstrike
1925 case 68082: // Glyph of Seal of Command
1927 break;
1928 case 48542: // Revitalize
1930 break;
1931 case 71132: // Glyph of Shadow Word: Pain
1932 damage = int32(CalculatePct(unitTarget->GetCreateMana(), 1)); // set 1 as value, missing in dbc
1933 break;
1934 default:
1935 break;
1936 }
1937
1938 if (level_diff > 0)
1939 damage -= level_multiplier * level_diff;
1940
1941 if (damage < 0)
1942 return;
1943
1945
1946 // Mad Alchemist's Potion
1947 if (m_spellInfo->Id == 45051)
1948 {
1949 // find elixirs on target
1950 bool guardianFound = false;
1951 bool battleFound = false;
1953 for (Unit::AuraApplicationMap::iterator itr = Auras.begin(); itr != Auras.end(); ++itr)
1954 {
1955 SpellGroupSpecialFlags sFlag = sSpellMgr->GetSpellGroupSpecialFlags(itr->second->GetBase()->GetId());
1956 if (!guardianFound)
1958 guardianFound = true;
1959 if (!battleFound)
1961 battleFound = true;
1962 if (battleFound && guardianFound)
1963 break;
1964 }
1965
1966 // get all available elixirs by mask and spell level
1967 std::set<uint32> availableElixirs;
1968 if (!guardianFound)
1969 sSpellMgr->GetSetOfSpellsInSpellGroupWithFlag(1, SPELL_GROUP_SPECIAL_FLAG_ELIXIR_GUARDIAN, availableElixirs);
1970 if (!battleFound)
1971 sSpellMgr->GetSetOfSpellsInSpellGroupWithFlag(1, SPELL_GROUP_SPECIAL_FLAG_ELIXIR_BATTLE, availableElixirs);
1972 for (std::set<uint32>::iterator itr = availableElixirs.begin(); itr != availableElixirs.end();)
1973 {
1974 SpellInfo const* spellInfo = sSpellMgr->AssertSpellInfo(*itr);
1975 if (spellInfo->SpellLevel < m_spellInfo->SpellLevel || spellInfo->SpellLevel > unitTarget->GetLevel())
1976 availableElixirs.erase(itr++);
1977 else
1978 ++itr;
1979 }
1980
1981 if (!availableElixirs.empty())
1982 {
1983 // cast random elixir on target
1985 }
1986 }
1987}
@ SPELL_ATTR7_ONLY_IN_SPELLBOOK_UNTIL_LEARNED
Definition: SharedDefines.h:657
@ SPELLFAMILY_POTION
Definition: SharedDefines.h:3541
SpellGroupSpecialFlags
Definition: SpellMgr.h:334
@ SPELL_GROUP_SPECIAL_FLAG_ELIXIR_BATTLE
Definition: SpellMgr.h:336
@ SPELL_GROUP_SPECIAL_FLAG_ELIXIR_GUARDIAN
Definition: SpellMgr.h:337
auto SelectRandomContainerElement(C const &container) -> typename std::add_const< decltype(*std::begin(container))>::type &
Definition: Containers.h:133
void EnergizeBySpell(Unit *victim, uint32 SpellID, uint32 Damage, Powers powertype)
Definition: Unit.cpp:11271
void SendSpellDamageImmune(Unit *target, uint32 spellId)
Definition: Unit.cpp:6469

References CalculatePct(), Unit::CastSpell(), damage, effectHandleMode, SpellInfo::Effects, Unit::EnergizeBySpell(), Unit::GetAppliedAuras(), Unit::GetCreateMana(), Unit::GetLevel(), Unit::GetMaxPower(), GetSpellInfo(), Unit::HasActivePowerType(), SpellInfo::HasAttribute(), Unit::HasUnitState(), SpellInfo::Id, Unit::IsAlive(), Object::IsPlayer(), m_caster, m_CastItem, m_spellInfo, MAX_POWERS, Acore::Containers::SelectRandomContainerElement(), Unit::SendSpellDamageImmune(), SPELL_ATTR7_ONLY_IN_SPELLBOOK_UNTIL_LEARNED, SPELL_EFFECT_HANDLE_HIT_TARGET, SPELL_GROUP_SPECIAL_FLAG_ELIXIR_BATTLE, SPELL_GROUP_SPECIAL_FLAG_ELIXIR_GUARDIAN, SPELLFAMILY_POTION, SpellInfo::SpellFamilyName, SpellInfo::SpellLevel, sSpellMgr, UNIT_STATE_ISOLATED, and unitTarget.

◆ EffectEnergizePct()

void Spell::EffectEnergizePct ( SpellEffIndex  effIndex)
1990{
1992 return;
1993
1994 if (!unitTarget)
1995 return;
1996 if (!unitTarget->IsAlive())
1997 return;
1998
1999 if (m_spellInfo->Effects[effIndex].MiscValue < 0 || m_spellInfo->Effects[effIndex].MiscValue >= int8(MAX_POWERS))
2000 return;
2001
2002 Powers power = Powers(m_spellInfo->Effects[effIndex].MiscValue);
2003
2005 return;
2006
2007 uint32 maxPower = unitTarget->GetMaxPower(power);
2008 if (maxPower == 0)
2009 return;
2010
2011 uint32 gain = CalculatePct(maxPower, damage);
2013}

References CalculatePct(), damage, effectHandleMode, SpellInfo::Effects, Unit::EnergizeBySpell(), Unit::GetMaxPower(), Unit::HasActivePowerType(), SpellInfo::HasAttribute(), SpellInfo::Id, Unit::IsAlive(), Object::IsPlayer(), m_caster, m_spellInfo, MAX_POWERS, SPELL_ATTR7_ONLY_IN_SPELLBOOK_UNTIL_LEARNED, SPELL_EFFECT_HANDLE_HIT_TARGET, and unitTarget.

◆ EffectEnvironmentalDMG()

void Spell::EffectEnvironmentalDMG ( SpellEffIndex  effIndex)
299{
301 return;
302
303 if (!unitTarget || !unitTarget->IsAlive())
304 return;
305
306 if (unitTarget->IsPlayer())
308 else
309 {
311
312 uint32 absorb = dmgInfo.GetAbsorb();
313 uint32 resist = dmgInfo.GetResist();
314 uint32 envDamage = dmgInfo.GetDamage();
315
316 Unit::DealDamageMods(unitTarget, envDamage, &absorb);
317 damage = envDamage;
318
320 }
321}
@ DAMAGE_FIRE
Definition: Player.h:844
uint32 EnvironmentalDamage(EnviromentalDamage type, uint32 damage)
Definition: Player.cpp:755

References damage, DAMAGE_FIRE, Unit::DealDamageMods(), effectHandleMode, Player::EnvironmentalDamage(), DamageInfo::GetAbsorb(), DamageInfo::GetDamage(), DamageInfo::GetResist(), SpellInfo::GetSchoolMask(), Unit::IsAlive(), Object::IsPlayer(), m_caster, m_spellInfo, Unit::SendSpellNonMeleeDamageLog(), SPELL_DIRECT_DAMAGE, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectFeedPet()

void Spell::EffectFeedPet ( SpellEffIndex  effIndex)
Todo:
: fix crash when a spell has two effects, both pointed at the same item target
4528{
4530 return;
4531
4532 Player* player = m_caster->ToPlayer();
4533 if (!player)
4534 return;
4535
4536 Item* foodItem = itemTarget;
4537 if (!foodItem)
4538 return;
4539
4540 Pet* pet = player->GetPet();
4541 if (!pet)
4542 return;
4543
4544 if (!pet->IsAlive())
4545 return;
4546
4547 int32 benefit = pet->GetCurrentFoodBenefitLevel(foodItem->GetTemplate()->ItemLevel);
4548 if (benefit <= 0)
4549 return;
4550
4551 ExecuteLogEffectDestroyItem(effIndex, foodItem->GetEntry());
4552
4553 uint32 count = 1;
4554 player->DestroyItemCount(foodItem, count, true);
4556
4557 m_caster->CastCustomSpell(pet, m_spellInfo->Effects[effIndex].TriggerSpell, &benefit, nullptr, nullptr, true);
4558}
void ExecuteLogEffectDestroyItem(uint8 effIndex, uint32 entry)
Definition: Spell.cpp:5155

References Unit::CastCustomSpell(), Player::DestroyItemCount(), effectHandleMode, SpellInfo::Effects, ExecuteLogEffectDestroyItem(), Pet::GetCurrentFoodBenefitLevel(), Object::GetEntry(), Player::GetPet(), Item::GetTemplate(), Unit::IsAlive(), ItemTemplate::ItemLevel, itemTarget, m_caster, m_spellInfo, SPELL_EFFECT_HANDLE_HIT_TARGET, and Object::ToPlayer().

◆ EffectForceCast()

void Spell::EffectForceCast ( SpellEffIndex  effIndex)
997{
999 return;
1000
1001 if (!unitTarget)
1002 return;
1003
1004 uint32 triggered_spell_id = m_spellInfo->Effects[effIndex].TriggerSpell;
1005
1006 // normal case
1007 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(triggered_spell_id);
1008
1009 if (!spellInfo)
1010 {
1011 LOG_ERROR("spells.effect", "Spell::EffectForceCast of spell {}: triggering unknown spell id {}", m_spellInfo->Id, triggered_spell_id);
1012 return;
1013 }
1014
1015 if (m_spellInfo->Effects[effIndex].Effect == SPELL_EFFECT_FORCE_CAST && damage)
1016 {
1017 switch (m_spellInfo->Id)
1018 {
1019 case 52588: // Skeletal Gryphon Escape
1020 case 48598: // Ride Flamebringer Cue
1022 break;
1023 case 52463: // Hide In Mine Car
1024 case 52349: // Overtake
1025 unitTarget->CastCustomSpell(unitTarget, spellInfo->Id, &damage, nullptr, nullptr, true, nullptr, nullptr, m_originalCasterGUID);
1026 return;
1027 case 72378: // Blood Nova
1028 case 73058: // Blood Nova
1029 m_caster->CastSpell(unitTarget, damage, true); // additional spell cast
1030 break;
1031 }
1032 }
1033
1034 CustomSpellValues values;
1035 // set basepoints for trigger with value effect
1037 {
1038 // maybe need to set value only when basepoints == 0?
1042 }
1043
1044 SpellCastTargets targets;
1045 targets.SetUnitTarget(m_caster);
1046
1047 unitTarget->CastSpell(targets, spellInfo, &values, TRIGGERED_FULL_MASK);
1048}
@ SPELL_EFFECT_FORCE_CAST
Definition: SharedDefines.h:918
@ SPELL_EFFECT_FORCE_CAST_WITH_VALUE
Definition: SharedDefines.h:919
@ SPELLVALUE_BASE_POINT1
Definition: SpellDefines.h:114
@ SPELLVALUE_BASE_POINT2
Definition: SpellDefines.h:115
@ SPELLVALUE_BASE_POINT0
Definition: SpellDefines.h:113
Definition: SpellDefines.h:165
void AddSpellMod(SpellValueMod mod, int32 value)
Definition: SpellDefines.h:167

References CustomSpellValues::AddSpellMod(), Unit::CastCustomSpell(), Unit::CastSpell(), damage, effectHandleMode, SpellInfo::Effects, SpellInfo::Id, LOG_ERROR, m_caster, m_originalCasterGUID, m_spellInfo, Unit::RemoveAura(), SpellCastTargets::SetUnitTarget(), SPELL_EFFECT_FORCE_CAST, SPELL_EFFECT_FORCE_CAST_WITH_VALUE, SPELL_EFFECT_HANDLE_HIT_TARGET, SPELLVALUE_BASE_POINT0, SPELLVALUE_BASE_POINT1, SPELLVALUE_BASE_POINT2, sSpellMgr, TRIGGERED_FULL_MASK, and unitTarget.

◆ EffectForceDeselect()

void Spell::EffectForceDeselect ( SpellEffIndex  effIndex)
4784{
4786 return;
4787
4788 // xinef: clear focus
4790
4792 data << m_caster->GetGUID();
4793
4795 Acore::MessageDistDelivererToHostile notifier(m_caster, &data, dist);
4796 Cell::VisitWorldObjects(m_caster, notifier, dist);
4797
4798 // xinef: we should also force pets to remove us from current target
4799 Unit::AttackerSet attackerSet;
4800 for (Unit::AttackerSet::const_iterator itr = m_caster->getAttackers().begin(); itr != m_caster->getAttackers().end(); ++itr)
4801 if ((*itr)->IsCreature() && !(*itr)->CanHaveThreatList())
4802 attackerSet.insert(*itr);
4803
4804 for (Unit::AttackerSet::const_iterator itr = attackerSet.begin(); itr != attackerSet.end(); ++itr)
4805 (*itr)->AttackStop();
4806
4807 // Xinef: Mirror images code Initialize Images
4808 if (m_spellInfo->Id == 58836)
4809 {
4810 std::vector<Unit*> images;
4811 for (Unit::ControlSet::const_iterator itr = m_caster->m_Controlled.begin(); itr != m_caster->m_Controlled.end(); ++itr)
4812 if ((*itr)->GetEntry() == 31216 /*NPC_MIRROR_IMAGE*/)
4813 images.push_back(*itr);
4814
4815 if (images.empty())
4816 return;
4817
4818 UnitList targets;
4819 Acore::AnyUnfriendlyUnitInObjectRangeCheck u_check(m_caster, m_caster, m_caster->GetVisibilityRange()); // no VISIBILITY_COMPENSATION, distance is enough
4822 for (UnitList::iterator iter = targets.begin(); iter != targets.end(); ++iter)
4823 {
4824 if (!(*iter)->HasUnitState(UNIT_STATE_CASTING))
4825 continue;
4826
4827 if (Spell* spell = (*iter)->GetCurrentSpell(CURRENT_GENERIC_SPELL))
4828 {
4829 if (spell->m_targets.GetUnitTargetGUID() == m_caster->GetGUID())
4830 {
4831 SpellInfo const* si = spell->GetSpellInfo();
4832 if (si->HasAttribute(SPELL_ATTR6_IGNORE_PHASE_SHIFT) && (*iter)->IsCreature())
4833 {
4834 Creature* c = (*iter)->ToCreature();
4835 if ((!c->IsPet() && c->GetCreatureTemplate()->rank == CREATURE_ELITE_WORLDBOSS) || c->isWorldBoss() || c->IsDungeonBoss())
4836 continue;
4837 }
4838
4839 bool interrupt = false; // pussywizard: skip spells that don't target units, but casted on unit (eg. TARGET_DEST_TARGET_ENEMY)
4840 for (uint8 j = 0; j < MAX_SPELL_EFFECTS; ++j)
4841 if (si->Effects[j].Effect && (si->Effects[j].GetUsedTargetObjectType() == TARGET_OBJECT_TYPE_UNIT || si->Effects[j].GetUsedTargetObjectType() == TARGET_OBJECT_TYPE_UNIT_AND_DEST))
4842 {
4843 // at least one effect truly targets an unit, interrupt the spell
4844 interrupt = true;
4845 break;
4846 }
4847
4848 if (interrupt)
4849 spell->m_targets.SetUnitTarget(images.at(urand(0, images.size() - 1)));
4850 }
4851 }
4852 }
4853 }
4854}
@ CREATURE_ELITE_WORLDBOSS
Definition: SharedDefines.h:2734
@ SPELL_ATTR6_IGNORE_PHASE_SHIFT
Definition: SharedDefines.h:617
@ TARGET_OBJECT_TYPE_UNIT
Definition: SpellInfo.h:101
@ TARGET_OBJECT_TYPE_UNIT_AND_DEST
Definition: SpellInfo.h:102
#define VISIBILITY_COMPENSATION
Definition: ObjectDefines.h:26
std::list< Unit * > UnitList
Definition: Unit.h:76
@ SMSG_CLEAR_TARGET
Definition: Opcodes.h:989
bool IsDungeonBoss() const
Definition: Creature.cpp:3162
uint32 rank
Definition: CreatureData.h:206
ControlSet m_Controlled
Definition: Unit.h:1940
void SendClearTarget()
Definition: Unit.cpp:20326
static void VisitAllObjects(WorldObject const *obj, T &visitor, float radius, bool dont_load=true)
Definition: CellImpl.h:206
static void VisitWorldObjects(WorldObject const *obj, T &visitor, float radius, bool dont_load=true)
Definition: CellImpl.h:192
Definition: GridNotifiers.h:133
Definition: GridNotifiers.h:423
Definition: GridNotifiers.h:861

References CREATURE_ELITE_WORLDBOSS, CURRENT_GENERIC_SPELL, effectHandleMode, SpellInfo::Effects, Unit::getAttackers(), Creature::GetCreatureTemplate(), Object::GetGUID(), WorldObject::GetVisibilityRange(), SpellInfo::HasAttribute(), SpellInfo::Id, Creature::IsDungeonBoss(), Unit::IsPet(), Creature::isWorldBoss(), m_caster, Unit::m_Controlled, m_spellInfo, MAX_SPELL_EFFECTS, CreatureTemplate::rank, Unit::SendClearTarget(), SMSG_CLEAR_TARGET, SPELL_ATTR6_IGNORE_PHASE_SHIFT, SPELL_EFFECT_HANDLE_HIT, TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT_AND_DEST, Object::ToCreature(), UNIT_STATE_CASTING, urand(), VISIBILITY_COMPENSATION, Cell::VisitAllObjects(), and Cell::VisitWorldObjects().

◆ EffectGameObjectDamage()

void Spell::EffectGameObjectDamage ( SpellEffIndex  effIndex)
5919{
5921 return;
5922
5923 if (!gameObjTarget)
5924 return;
5925
5926 Unit* caster = m_originalCaster;
5927 if (!caster)
5928 return;
5929
5930 FactionTemplateEntry const* casterFaction = caster->GetFactionTemplateEntry();
5932 // Do not allow to damage GO's of friendly factions (ie: Wintergrasp Walls/Ulduar Storm Beacons)
5933 if ((casterFaction && targetFaction && !casterFaction->IsFriendlyTo(*targetFaction)) || !targetFaction)
5935}
DBCStorage< FactionTemplateEntry > sFactionTemplateStore(FactionTemplateEntryfmt)
void ModifyHealth(int32 change, Unit *attackerOrHealer=nullptr, uint32 spellId=0)
Definition: GameObject.cpp:2279
FactionTemplateEntry const * GetFactionTemplateEntry() const
Definition: Unit.cpp:10034
Definition: DBCStructure.h:938
bool IsFriendlyTo(FactionTemplateEntry const &entry) const
Definition: DBCStructure.h:950

References damage, effectHandleMode, GAMEOBJECT_FACTION, gameObjTarget, Unit::GetFactionTemplateEntry(), GetSpellInfo(), Object::GetUInt32Value(), FactionTemplateEntry::IsFriendlyTo(), m_originalCaster, GameObject::ModifyHealth(), sFactionTemplateStore, and SPELL_EFFECT_HANDLE_HIT_TARGET.

◆ EffectGameObjectRepair()

void Spell::EffectGameObjectRepair ( SpellEffIndex  effIndex)

◆ EffectGameObjectSetDestructionState()

void Spell::EffectGameObjectSetDestructionState ( SpellEffIndex  effIndex)
5949{
5951 return;
5952
5954 return;
5955
5958}
GameObjectDestructibleState
Definition: SharedDefines.h:1626
void SetDestructibleState(GameObjectDestructibleState state, Player *eventInvoker=nullptr, bool setHealth=false)
Definition: GameObject.cpp:2342

References effectHandleMode, SpellInfo::Effects, gameObjTarget, Unit::GetCharmerOrOwnerPlayerOrPlayerItself(), m_originalCaster, m_spellInfo, GameObject::SetDestructibleState(), and SPELL_EFFECT_HANDLE_HIT_TARGET.

◆ EffectHeal()

void Spell::EffectHeal ( SpellEffIndex  effIndex)
1473{
1475 return;
1476
1477 if (unitTarget && unitTarget->IsAlive() && damage >= 0)
1478 {
1479 // Try to get original caster
1481
1482 // Skip if m_originalCaster not available
1483 if (!caster)
1484 return;
1485
1486 int32 addhealth = damage;
1487
1488 // Vessel of the Naaru (Vial of the Sunwell trinket)
1489 if (m_spellInfo->Id == 45064)
1490 {
1491 // Amount of heal - depends from stacked Holy Energy
1492 int damageAmount = 0;
1493 if (AuraEffect const* aurEff = m_caster->GetAuraEffect(45062, 0))
1494 {
1495 damageAmount += aurEff->GetAmount();
1497 }
1498
1499 addhealth += damageAmount;
1500 }
1501 // Swiftmend - consumes Regrowth or Rejuvenation
1503 {
1505 // find most short by duration
1506 AuraEffect* forcedTargetAura = nullptr;
1507 AuraEffect* targetAura = nullptr;
1508 for (Unit::AuraEffectList::const_iterator i = RejorRegr.begin(); i != RejorRegr.end(); ++i)
1509 {
1510 if ((*i)->GetSpellInfo()->SpellFamilyName == SPELLFAMILY_DRUID
1511 && (*i)->GetSpellInfo()->SpellFamilyFlags[0] & 0x50)
1512 {
1513 if (m_caster->GetGUID() == (*i)->GetCasterGUID())
1514 {
1515 if (!forcedTargetAura || (*i)->GetBase()->GetDuration() < forcedTargetAura->GetBase()->GetDuration())
1516 forcedTargetAura = *i;
1517 }
1518 else if (!targetAura || (*i)->GetBase()->GetDuration() < targetAura->GetBase()->GetDuration())
1519 targetAura = *i;
1520 }
1521 }
1522
1523 if (forcedTargetAura)
1524 targetAura = forcedTargetAura;
1525
1526 if (!targetAura)
1527 {
1528 LOG_ERROR("spells.effect", "Target({}) has aurastate AURA_STATE_SWIFTMEND but no matching aura.", unitTarget->GetGUID().ToString());
1529 return;
1530 }
1531
1532 int32 tickheal = targetAura->GetAmount();
1533 if (Unit* auraCaster = targetAura->GetCaster())
1534 tickheal = unitTarget->SpellHealingBonusTaken(auraCaster, targetAura->GetSpellInfo(), tickheal, DOT);
1535
1536 //int32 tickheal = targetAura->GetSpellInfo()->EffectBasePoints[idx] + 1;
1537 //It is said that talent bonus should not be included
1538
1539 int32 tickcount = 0;
1540 // Rejuvenation
1541 if (targetAura->GetSpellInfo()->SpellFamilyFlags[0] & 0x10)
1542 tickcount = 4;
1543 // Regrowth
1544 else // if (targetAura->GetSpellInfo()->SpellFamilyFlags[0] & 0x40)
1545 tickcount = 6;
1546
1547 addhealth += tickheal * tickcount;
1548
1549 // Glyph of Swiftmend
1550 if (!caster->HasAura(54824))
1551 unitTarget->RemoveAura(targetAura->GetId(), targetAura->GetCasterGUID());
1552
1553 //addhealth += tickheal * tickcount;
1554 //addhealth = caster->SpellHealingBonus(m_spellInfo, addhealth, HEAL, unitTarget);
1555 }
1556 // Death Pact - return pct of max health to caster
1558 {
1559 addhealth = caster->SpellHealingBonusDone(unitTarget, m_spellInfo, int32(caster->CountPctFromMaxHealth(damage)), HEAL, effIndex);
1560 addhealth = unitTarget->SpellHealingBonusTaken(caster, m_spellInfo, addhealth, HEAL);
1561 }
1562 else if (m_spellInfo->Id != 33778) // not lifebloom
1563 {
1564 addhealth = caster->SpellHealingBonusDone(unitTarget, m_spellInfo, addhealth, HEAL, effIndex);
1565 addhealth = unitTarget->SpellHealingBonusTaken(caster, m_spellInfo, addhealth, HEAL);
1566 }
1567
1568 // Implemented this way as there is no other way to do it currently (that I know :P)...
1569 if (caster->ToPlayer() && caster->HasAura(23401)) // Nefarian Corrupted Healing (priest)
1570 {
1572 {
1573 m_damage = 0;
1574 caster->CastSpell(unitTarget, 23402, false); // Nefarian Corrupted Healing Periodic Damage effect.
1575 return;
1576 }
1577 }
1578
1579 m_damage -= addhealth;
1580 }
1581}
@ SPELLFAMILY_DRUID
Definition: SharedDefines.h:3535
@ SPELLFAMILY_DEATHKNIGHT
Definition: SharedDefines.h:3543
@ AURA_STATE_SWIFTMEND
Definition: SharedDefines.h:1307
@ SPELL_SCHOOL_MASK_HOLY
Definition: SharedDefines.h:298
@ SPELL_AURA_PERIODIC_HEAL
Definition: SpellAuraDefines.h:71
@ DOT
Definition: Unit.h:250
uint32 CountPctFromMaxHealth(int32 pct) const
Definition: Unit.h:1042
SpellInfo const * GetSpellInfo() const
Definition: SpellAuraEffects.h:54
uint32 GetId() const
Definition: SpellAuraEffects.cpp:432
Unit * GetCaster() const
Definition: SpellAuraEffects.h:47
Aura * GetBase() const
Definition: SpellAuraEffects.h:49
ObjectGuid GetCasterGUID() const
Definition: SpellAuraEffects.h:48
int32 GetAmount() const
Definition: SpellAuraEffects.h:64
uint32 TargetAuraState
Definition: SpellInfo.h:340

References AURA_STATE_SWIFTMEND, Unit::CastSpell(), Unit::CountPctFromMaxHealth(), damage, DOT, effectHandleMode, AuraEffect::GetAmount(), Unit::GetAuraEffect(), Unit::GetAuraEffectsByType(), AuraEffect::GetBase(), AuraEffect::GetCaster(), AuraEffect::GetCasterGUID(), Aura::GetDuration(), Object::GetGUID(), AuraEffect::GetId(), SpellInfo::GetSchoolMask(), AuraEffect::GetSpellInfo(), SpellInfo::HasAura(), Unit::HasAura(), Unit::HasAuraState(), HEAL, SpellInfo::Id, Unit::IsAlive(), LOG_ERROR, m_caster, m_damage, m_originalCaster, m_originalCasterGUID, m_spellInfo, Unit::RemoveAura(), Unit::RemoveAurasDueToSpell(), SPELL_AURA_PERIODIC_HEAL, SPELL_EFFECT_HANDLE_LAUNCH_TARGET, SPELL_SCHOOL_MASK_HOLY, SPELLFAMILY_DEATHKNIGHT, SPELLFAMILY_DRUID, SpellInfo::SpellFamilyFlags, SpellInfo::SpellFamilyName, Unit::SpellHealingBonusDone(), Unit::SpellHealingBonusTaken(), SpellInfo::TargetAuraState, Object::ToPlayer(), ObjectGuid::ToString(), and unitTarget.

◆ EffectHealMaxHealth()

void Spell::EffectHealMaxHealth ( SpellEffIndex  effIndex)
3685{
3687 return;
3688
3689 if (!unitTarget || !unitTarget->IsAlive())
3690 return;
3691
3693 {
3695 return;
3696 }
3697
3698 int32 addhealth = 0;
3699
3700 // damage == 0 - heal for caster max health
3701 if (damage == 0)
3702 addhealth = m_caster->GetMaxHealth();
3703 else
3704 addhealth = unitTarget->GetMaxHealth() - unitTarget->GetHealth();
3705
3706 m_healing += addhealth;
3707}
uint32 GetMaxHealth() const
Definition: Unit.h:1030

References damage, effectHandleMode, Unit::GetHealth(), Unit::GetMaxHealth(), GetSpellInfo(), Unit::HasUnitState(), Unit::IsAlive(), m_caster, m_healing, Unit::SendSpellDamageImmune(), SPELL_EFFECT_HANDLE_HIT_TARGET, UNIT_STATE_ISOLATED, and unitTarget.

◆ EffectHealMechanical()

void Spell::EffectHealMechanical ( SpellEffIndex  effIndex)

◆ EffectHealPct()

void Spell::EffectHealPct ( SpellEffIndex  effIndex)

◆ EffectHealthLeech()

void Spell::EffectHealthLeech ( SpellEffIndex  effIndex)
1619{
1621 return;
1622
1623 if (!unitTarget || !unitTarget->IsAlive() || damage < 0)
1624 return;
1625
1628
1629 LOG_DEBUG("spells.aura", "HealthLeech :{}", damage);
1630
1631 // xinef: handled in spell.cpp
1632 //float healMultiplier = m_spellInfo->Effects[effIndex].CalcValueMultiplier(m_originalCaster, this);
1633
1634 m_damage += damage;
1635 // get max possible damage, don't count overkill for heal
1636 //uint32 healthGain = uint32(-unitTarget->GetHealthGain(-damage) * healMultiplier);
1637
1638 //if (m_caster->IsAlive())
1639 //{
1640 // healthGain = m_caster->SpellHealingBonusDone(m_caster, m_spellInfo, healthGain, HEAL);
1641 // healthGain = m_caster->SpellHealingBonusTaken(m_caster, m_spellInfo, healthGain, HEAL);
1642
1643 // m_caster->HealBySpell(m_caster, m_spellInfo, uint32(healthGain));
1644 //}
1645}
uint32 SpellDamageBonusTaken(Unit *caster, SpellInfo const *spellProto, uint32 pdamage, DamageEffectType damagetype, uint32 stack=1)
Definition: Unit.cpp:11791
uint32 SpellDamageBonusDone(Unit *victim, SpellInfo const *spellProto, uint32 pdamage, DamageEffectType damagetype, uint8 effIndex, float TotalMod=0.0f, uint32 stack=1)
Definition: Unit.cpp:11615

References damage, effectHandleMode, Unit::IsAlive(), LOG_DEBUG, m_caster, m_damage, m_spellInfo, SPELL_DIRECT_DAMAGE, SPELL_EFFECT_HANDLE_HIT_TARGET, Unit::SpellDamageBonusDone(), Unit::SpellDamageBonusTaken(), and unitTarget.

◆ EffectInebriate()

void Spell::EffectInebriate ( SpellEffIndex  effIndex)
4492{
4494 return;
4495
4496 if (!unitTarget)
4497 return;
4498
4499 Player* player = unitTarget->ToPlayer();
4500 if (!player)
4501 {
4502 return;
4503 }
4504
4505 uint8 currentDrunk = player->GetDrunkValue();
4506 int32 drunkMod = damage;
4507
4508 if (drunkMod == 0)
4509 return;
4510
4511 // drunkMod may contain values ​​that are guaranteed to cause uint8 overflow/underflow (examples: 29690, 46874)
4512 // In addition, we would not want currentDrunk to become more than 100.
4513 // So before adding the values, let's check that everything is fine.
4514 if (drunkMod > 0 && drunkMod > static_cast<int32>(100 - currentDrunk))
4515 currentDrunk = 100;
4516 else if (drunkMod < 0 && drunkMod < static_cast<int32>(0 - currentDrunk))
4517 currentDrunk = 0;
4518 else
4519 currentDrunk += drunkMod; // Due to previous checks we can be sure that currentDrunk will not go beyond [0-100] range.
4520
4521 player->SetDrunkValue(currentDrunk, m_CastItem ? m_CastItem->GetEntry() : 0);
4522
4523 if (currentDrunk == 100 && roll_chance_i(25))
4524 player->CastSpell(player, 67468, false); // Drunken Vomit
4525}
uint8 GetDrunkValue() const
Definition: Player.h:2171
void SetDrunkValue(uint8 newDrunkValue, uint32 itemId=0)
Definition: Player.cpp:972

References Unit::CastSpell(), damage, effectHandleMode, Player::GetDrunkValue(), Object::GetEntry(), m_CastItem, roll_chance_i(), Player::SetDrunkValue(), SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectInstaKill()

void Spell::EffectInstaKill ( SpellEffIndex  effIndex)
275{
277 return;
278
279 if (!unitTarget || !unitTarget->IsAlive() || unitTarget->HasAura(27827)) // Spirit of redemption doesn't make you death, but can cause infinite loops
280 return;
281
282 if (unitTarget->IsPlayer())
284 return;
285
286 if (m_caster == unitTarget) // prevent interrupt message
287 finish();
288
289 WorldPacket data(SMSG_SPELLINSTAKILLLOG, 8 + 8 + 4);
290 data << m_caster->GetGUID();
291 data << unitTarget->GetGUID();
292 data << uint32(m_spellInfo->Id);
293 m_caster->SendMessageToSet(&data, true);
294
296}
@ SPELL_SCHOOL_MASK_NORMAL
Definition: SharedDefines.h:297
@ CHEAT_GOD
Definition: Player.h:1004
@ SMSG_SPELLINSTAKILLLOG
Definition: Opcodes.h:845
static uint32 DealDamage(Unit *attacker, Unit *victim, uint32 damage, CleanDamage const *cleanDamage=nullptr, DamageEffectType damagetype=DIRECT_DAMAGE, SpellSchoolMask damageSchoolMask=SPELL_SCHOOL_MASK_NORMAL, SpellInfo const *spellProto=nullptr, bool durabilityLoss=true, bool allowGM=false, Spell const *spell=nullptr)
Definition: Unit.cpp:810

References CHEAT_GOD, Unit::DealDamage(), effectHandleMode, finish(), Player::GetCommandStatus(), Object::GetGUID(), Unit::GetHealth(), Unit::HasAura(), SpellInfo::Id, Unit::IsAlive(), Object::IsPlayer(), m_caster, m_spellInfo, NODAMAGE, WorldObject::SendMessageToSet(), SMSG_SPELLINSTAKILLLOG, SPELL_EFFECT_HANDLE_HIT_TARGET, SPELL_SCHOOL_MASK_NORMAL, Object::ToPlayer(), and unitTarget.

◆ EffectInterruptCast()

void Spell::EffectInterruptCast ( SpellEffIndex  effIndex)
Todo:
: not all spells that used this effect apply cooldown at school spells
3710{
3712 return;
3713
3714 if (!unitTarget || !unitTarget->IsAlive())
3715 return;
3716
3718 // also exist case: apply cooldown to interrupted cast only and to all spells
3719 // there is no CURRENT_AUTOREPEAT_SPELL spells that can be interrupted
3721 {
3723 {
3724 SpellInfo const* curSpellInfo = spell->m_spellInfo;
3725 // check if we can interrupt spell
3726 if ((spell->getState() == SPELL_STATE_CASTING
3727 || (spell->getState() == SPELL_STATE_PREPARING && spell->GetCastTime() > 0.0f))
3731 {
3732 if (m_originalCaster)
3733 {
3735 unitTarget->ProhibitSpellSchool(curSpellInfo->GetSchoolMask(), duration/*spellInfo->GetDuration()*/);
3736 }
3737 ExecuteLogEffectInterruptCast(effIndex, unitTarget, curSpellInfo->Id);
3739 }
3740 }
3741 }
3742}
@ CHANNEL_INTERRUPT_FLAG_INTERRUPT
Definition: SpellDefines.h:37
@ SPELL_INTERRUPT_FLAG_INTERRUPT
Definition: SpellDefines.h:29
#define CURRENT_FIRST_NON_MELEE_SPELL
Definition: Unit.h:543
CurrentSpellTypes
Definition: Unit.h:536
@ CURRENT_CHANNELED_SPELL
Definition: Unit.h:539
@ CURRENT_AUTOREPEAT_SPELL
Definition: Unit.h:540
void InterruptSpell(CurrentSpellTypes spellType, bool withDelayed=true, bool withInstant=true, bool bySelf=false)
Definition: Unit.cpp:4060
int32 CalcSpellDuration(SpellInfo const *spellProto)
Definition: Unit.cpp:14856
virtual void ProhibitSpellSchool(SpellSchoolMask, uint32)
Definition: Unit.h:1456
void ExecuteLogEffectInterruptCast(uint8 effIndex, Unit *victim, uint32 spellId)
Definition: Spell.cpp:5128
uint32 ChannelInterruptFlags
Definition: SpellInfo.h:354
uint32 InterruptFlags
Definition: SpellInfo.h:352

References Unit::CalcSpellDuration(), CHANNEL_INTERRUPT_FLAG_INTERRUPT, SpellInfo::ChannelInterruptFlags, CURRENT_AUTOREPEAT_SPELL, CURRENT_CHANNELED_SPELL, CURRENT_FIRST_NON_MELEE_SPELL, CURRENT_GENERIC_SPELL, effectHandleMode, ExecuteLogEffectInterruptCast(), Unit::GetCurrentSpell(), SpellInfo::GetSchoolMask(), SpellInfo::Id, SpellInfo::InterruptFlags, Unit::InterruptSpell(), Unit::IsAlive(), m_originalCaster, m_spellInfo, Unit::ModSpellDuration(), SpellInfo::PreventionType, Unit::ProhibitSpellSchool(), SPELL_EFFECT_HANDLE_LAUNCH_TARGET, SPELL_INTERRUPT_FLAG_INTERRUPT, SPELL_PREVENTION_TYPE_SILENCE, SPELL_STATE_CASTING, SPELL_STATE_PREPARING, and unitTarget.

◆ EffectJump()

void Spell::EffectJump ( SpellEffIndex  effIndex)
1070{
1072 return;
1073
1074 if (m_caster->IsInFlight())
1075 return;
1076
1077 if (!unitTarget)
1078 return;
1079
1080 float speedXY, speedZ;
1081 CalculateJumpSpeeds(effIndex, m_caster->GetExactDist2d(unitTarget), speedXY, speedZ);
1082 m_caster->GetMotionMaster()->MoveJump(*unitTarget, speedXY, speedZ);
1083
1084 if (m_caster->IsPlayer())
1085 {
1086 sScriptMgr->AnticheatSetUnderACKmount(m_caster->ToPlayer());
1087 }
1088}
float GetExactDist2d(const float x, const float y) const
Definition: Position.h:165
void MoveJump(Position const &pos, float speedXY, float speedZ, uint32 id=0)
Definition: MotionMaster.h:229
void CalculateJumpSpeeds(uint8 i, float dist, float &speedxy, float &speedz)
Definition: SpellEffects.cpp:1153

References CalculateJumpSpeeds(), effectHandleMode, Position::GetExactDist2d(), Unit::GetMotionMaster(), Unit::IsInFlight(), Object::IsPlayer(), m_caster, MotionMaster::MoveJump(), SPELL_EFFECT_HANDLE_LAUNCH_TARGET, sScriptMgr, Object::ToPlayer(), and unitTarget.

◆ EffectJumpDest()

void Spell::EffectJumpDest ( SpellEffIndex  effIndex)
1091{
1093 return;
1094
1095 if (m_caster->IsInFlight())
1096 return;
1097
1098 if (!m_targets.HasDst() || m_caster->GetVehicle())
1099 return;
1100
1101 // Init dest coordinates
1102 float x, y, z;
1103 destTarget->GetPosition(x, y, z);
1104 // xinef: this can happen if MovePositionToFirstCollision detects that X, Y cords are invalid and returns prematurely
1105 if (!Acore::IsValidMapCoord(x, y, z) || z <= INVALID_HEIGHT)
1106 return;
1107
1108 float speedXY, speedZ;
1109 float dist = m_caster->GetExactDist2d(x, y);
1110 CalculateJumpSpeeds(effIndex, dist, speedXY, speedZ);
1111
1112 // Override, calculations are incorrect
1113 if (m_spellInfo->Id == 49376) // feral charge
1114 {
1115 speedXY = pow(speedZ * 10, 8);
1117
1118 if (Player* player = m_caster->ToPlayer())
1119 {
1120 player->SetCanTeleport(true);
1121 }
1122
1123 if (m_caster->IsPlayer())
1124 {
1125 sScriptMgr->AnticheatSetUnderACKmount(m_caster->ToPlayer());
1126 }
1127
1128 return;
1129 }
1130
1131 if (m_spellInfo->Id == 57604) // death grip
1132 {
1133 speedZ = 3.0f;
1134 speedXY = 50.0f;
1135 }
1136
1137 // crash fix?
1138 if (speedXY < 1.0f)
1139 speedXY = 1.0f;
1140
1141 if (Player* player = m_caster->ToPlayer())
1142 {
1143 player->SetCanTeleport(true);
1144 }
1145 m_caster->GetMotionMaster()->MoveJump(x, y, z, speedXY, speedZ);
1146
1147 if (m_caster->IsPlayer())
1148 {
1149 sScriptMgr->AnticheatSetUnderACKmount(m_caster->ToPlayer());
1150 }
1151}
#define INVALID_HEIGHT
Definition: Map.h:163
@ UNIT_FIELD_TARGET
Definition: UpdateFields.h:92
bool IsValidMapCoord(float c)
Definition: GridDefines.h:215
ObjectGuid GetGuidValue(uint16 index) const
Definition: Object.cpp:337

References CalculateJumpSpeeds(), destTarget, effectHandleMode, Position::GetExactDist2d(), Object::GetGuidValue(), Unit::GetMotionMaster(), Position::GetPosition(), ObjectAccessor::GetUnit(), Unit::GetVehicle(), SpellCastTargets::HasDst(), SpellInfo::Id, INVALID_HEIGHT, Unit::IsInFlight(), Object::IsPlayer(), Acore::IsValidMapCoord(), m_caster, m_spellInfo, m_targets, MotionMaster::MoveJump(), SPELL_EFFECT_HANDLE_LAUNCH, sScriptMgr, Object::ToPlayer(), and UNIT_FIELD_TARGET.

◆ EffectKillCredit()

void Spell::EffectKillCredit ( SpellEffIndex  effIndex)
5711{
5713 return;
5714
5715 if (!unitTarget)
5716 return;
5717
5719 if (!player)
5720 {
5721 return;
5722 }
5723
5724 int32 creatureEntry = m_spellInfo->Effects[effIndex].MiscValue;
5725 if (!creatureEntry)
5726 {
5727 if (m_spellInfo->Id == 42793) // Burn Body
5728 creatureEntry = 24008; // Fallen Combatant
5729 }
5730
5731 if (creatureEntry)
5732 player->RewardPlayerAndGroupAtEvent(creatureEntry, unitTarget);
5733}
void RewardPlayerAndGroupAtEvent(uint32 creature_id, WorldObject *pRewardSource)
Definition: Player.cpp:12769

References effectHandleMode, SpellInfo::Effects, Unit::GetCharmerOrOwnerPlayerOrPlayerItself(), SpellInfo::Id, m_spellInfo, Player::RewardPlayerAndGroupAtEvent(), SPELL_EFFECT_HANDLE_HIT_TARGET, and unitTarget.

◆ EffectKillCreditPersonal()

void Spell::EffectKillCreditPersonal ( SpellEffIndex  effIndex)
5697{
5699 return;
5700
5701 if (!unitTarget)
5702 return;
5703
5705 {
5706 player->KilledMonsterCredit(m_spellInfo->Effects[effIndex].MiscValue);
5707 }
5708}

References effectHandleMode, SpellInfo::Effects, Unit::GetCharmerOrOwnerPlayerOrPlayerItself(), m_spellInfo, SPELL_EFFECT_HANDLE_HIT_TARGET, and unitTarget.

◆ EffectKnockBack()

void Spell::EffectKnockBack ( SpellEffIndex  effIndex)
4988{
4990 return;
4991
4992 if (!unitTarget)
4993 return;
4994
4995 // Xinef: allow entry specific spells to skip those checks
4996 if (m_spellInfo->Effects[effIndex].TargetA.GetCheckType() != TARGET_CHECK_ENTRY && m_spellInfo->Effects[effIndex].TargetB.GetCheckType() != TARGET_CHECK_ENTRY)
4997 {
4999 return;
5000
5001 if (unitTarget->GetVehicle())
5002 return;
5003
5004 if (Creature* creatureTarget = unitTarget->ToCreature())
5005 if (creatureTarget->isWorldBoss() || creatureTarget->IsDungeonBoss() || creatureTarget->IsImmuneToKnockback() || unitTarget->ToCreature()->GetCreatureType() == CREATURE_TYPE_GIANT)
5006 return;
5007 }
5008
5009 // Spells with SPELL_EFFECT_KNOCK_BACK(like Thunderstorm) can't knoback target if target has ROOT
5011 return;
5012
5013 // Instantly interrupt non melee spells being casted
5016
5017 float ratio = 0.1f;
5018 float speedxy = float(m_spellInfo->Effects[effIndex].MiscValue) * ratio;
5019 float speedz = float(damage) * ratio;
5020 if (speedxy <= 0.1f && speedz <= 0.1f)
5021 return;
5022
5023 float x, y;
5024 if (m_spellInfo->Effects[effIndex].Effect == SPELL_EFFECT_KNOCK_BACK_DEST)
5025 {
5026 if (m_targets.HasDst())
5027 destTarget->GetPosition(x, y);
5028 else
5029 return;
5030 }
5031 else //if (m_spellInfo->Effects[i].Effect == SPELL_EFFECT_KNOCK_BACK)
5032 {
5033 m_caster->GetPosition(x, y);
5034 }
5035
5036 unitTarget->KnockbackFrom(x, y, speedxy, speedz);
5037
5038 if (unitTarget->IsPlayer())
5039 {
5040 sScriptMgr->AnticheatSetUnderACKmount(unitTarget->ToPlayer());
5041 }
5042}
@ SPELL_EFFECT_KNOCK_BACK_DEST
Definition: SharedDefines.h:922
@ CREATURE_TYPE_GIANT
Definition: SharedDefines.h:2632
@ CREATURE_TYPE_BEAST
Definition: SharedDefines.h:2628
void InterruptNonMeleeSpells(bool withDelayed, uint32 spellid=0, bool withInstant=true, bool bySelf=false)
Definition: Unit.cpp:4129
uint32 GetCreatureType() const
Definition: Unit.cpp:15182
void KnockbackFrom(float x, float y, float speedXY, float speedZ)
Definition: Unit.cpp:19143

References CREATURE_TYPE_BEAST, CREATURE_TYPE_GIANT, damage, destTarget, effectHandleMode, SpellInfo::Effects, Unit::GetCreatureType(), Position::GetPosition(), Unit::GetVehicle(), SpellCastTargets::HasDst(), Unit::HasUnitState(), Unit::InterruptNonMeleeSpells(), Unit::IsNonMeleeSpellCast(), Object::IsPlayer(), Unit::IsVehicle(), Unit::KnockbackFrom(), m_caster, m_spellInfo, m_targets, SPELL_EFFECT_HANDLE_HIT_TARGET, SPELL_EFFECT_KNOCK_BACK_DEST, sScriptMgr, TARGET_CHECK_ENTRY, Object::ToCreature(), Object::ToPlayer(), UNIT_STATE_ROOT, and unitTarget.

◆ EffectLeap()

void Spell::EffectLeap ( SpellEffIndex  effIndex)
4714{
4716 return;
4717
4718 if (!unitTarget || unitTarget->IsInFlight())
4719 return;
4720
4721 if (!m_targets.HasDst())
4722 return;
4723
4724 Position dstpos = destTarget->GetPosition();
4726}
void NearTeleportTo(Position &pos, bool casting=false, bool vehicleTeleport=false, bool withPet=false, bool removeTransport=false)
Definition: Unit.cpp:19979

References destTarget, effectHandleMode, Position::GetOrientation(), Position::GetPosition(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), SpellCastTargets::HasDst(), Unit::IsInFlight(), m_caster, m_targets, Unit::NearTeleportTo(), SPELL_EFFECT_HANDLE_HIT_TARGET, and unitTarget.

◆ EffectLeapBack()

void Spell::EffectLeapBack ( SpellEffIndex  effIndex)
5045{
5047 return;
5048
5049 if (!unitTarget)
5050 return;
5051
5052 float speedxy = m_spellInfo->Effects[effIndex].MiscValue / 10.0f;
5053 float speedz = damage / 10.0f;
5054 //1891: Disengage
5056
5057 if (m_caster->IsPlayer())
5058 {
5059 sScriptMgr->AnticheatSetUnderACKmount(m_caster->ToPlayer());
5060 }
5061
5062 // xinef: changes fall time
5063 if (m_caster->IsPlayer())
5065}
@ SPELLFAMILY_HUNTER
Definition: SharedDefines.h:3537
void JumpTo(float speedXY, float speedZ, bool forward=true)
Definition: Unit.cpp:19524

References damage, effectHandleMode, SpellInfo::Effects, GameTime::GetGameTime(), Position::GetPositionZ(), Object::IsPlayer(), Unit::JumpTo(), m_caster, m_spellInfo, Player::SetFallInformation(), SPELL_EFFECT_HANDLE_LAUNCH_TARGET, SPELLFAMILY_HUNTER, SpellInfo::SpellFamilyName, sScriptMgr, Object::ToPlayer(), and unitTarget.

◆ EffectLearnPetSpell()

void Spell::EffectLearnPetSpell ( SpellEffIndex  effIndex)
3255{
3257 return;
3258
3259 if (!unitTarget)
3260 return;
3261
3262 if (unitTarget->ToPlayer())
3263 {
3264 EffectLearnSpell(effIndex);
3265 return;
3266 }
3267 Pet* pet = unitTarget->ToPet();
3268 if (!pet)
3269 return;
3270
3271 SpellInfo const* learn_spellproto = sSpellMgr->GetSpellInfo(m_spellInfo->Effects[effIndex].TriggerSpell);
3272 if (!learn_spellproto)
3273 return;
3274
3275 pet->learnSpell(learn_spellproto->Id);
3277 pet->GetOwner()->PetSpellInitialize();
3278}
bool learnSpell(uint32 spell_id)
Definition: Pet.cpp:1906
void EffectLearnSpell(SpellEffIndex effIndex)
Definition: SpellEffects.cpp:2541

References effectHandleMode, EffectLearnSpell(), SpellInfo::Effects, Pet::GetOwner(), SpellInfo::Id, Pet::learnSpell(), m_spellInfo, PET_SAVE_AS_CURRENT, Player::PetSpellInitialize(), Pet::SavePetToDB(), SPELL_EFFECT_HANDLE_HIT_TARGET, sSpellMgr, Unit::ToPet(), Object::ToPlayer(), and unitTarget.

Referenced by EffectLearnSpell().

◆ EffectLearnSkill()

void Spell::EffectLearnSkill ( SpellEffIndex  effIndex)
2772{
2774 return;
2775
2776 if (!unitTarget->IsPlayer())
2777 return;
2778
2779 if (damage < 0)
2780 return;
2781
2782 uint32 skillid = m_spellInfo->Effects[effIndex].MiscValue;
2783 uint16 skillval = unitTarget->ToPlayer()->GetPureSkillValue(skillid);
2784 unitTarget->ToPlayer()->SetSkill(skillid, m_spellInfo->Effects[effIndex].CalcValue(), skillval ? skillval : 1, damage * 75);
2785}
uint16 GetPureSkillValue(uint32 skill) const
Definition: Player.cpp:5533
void SetSkill(uint16 id, uint16 step, uint16 currVal, uint16 maxVal)
Definition: Player.cpp:5347

References damage, effectHandleMode, SpellInfo::Effects, Player::GetPureSkillValue(), Object::IsPlayer(), m_spellInfo, Player::SetSkill(), SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectLearnSpell()

void Spell::EffectLearnSpell ( SpellEffIndex  effIndex)
2542{
2544 return;
2545
2546 if (!unitTarget)
2547 return;
2548
2549 if (!unitTarget->IsPlayer())
2550 {
2551 if (unitTarget->ToPet())
2552 EffectLearnPetSpell(effIndex);
2553 return;
2554 }
2555
2556 Player* player = unitTarget->ToPlayer();
2557
2558 uint32 spellToLearn = (m_spellInfo->Id == 483 || m_spellInfo->Id == 55884) ? damage : m_spellInfo->Effects[effIndex].TriggerSpell;
2559 player->learnSpell(spellToLearn);
2560
2561 LOG_DEBUG("spells.aura", "Spell: Player {} has learned spell {} from Npc {}",
2562 player->GetGUID().ToString(), spellToLearn, m_caster->GetGUID().ToString());
2563}
void learnSpell(uint32 spellId, bool temporary=false, bool learnFromSkill=false)
Definition: Player.cpp:3304
void EffectLearnPetSpell(SpellEffIndex effIndex)
Definition: SpellEffects.cpp:3254

References damage, effectHandleMode, EffectLearnPetSpell(), SpellInfo::Effects, Object::GetGUID(), SpellInfo::Id, Object::IsPlayer(), Player::learnSpell(), LOG_DEBUG, m_caster, m_spellInfo, SPELL_EFFECT_HANDLE_HIT_TARGET, Unit::ToPet(), Object::ToPlayer(), ObjectGuid::ToString(), and unitTarget.

Referenced by EffectLearnPetSpell().

◆ EffectMilling()

void Spell::EffectMilling ( SpellEffIndex  effIndex)
5524{
5526 return;
5527
5528 if (!m_caster->IsPlayer())
5529 return;
5530
5531 Player* p_caster = m_caster->ToPlayer();
5533 return;
5534
5535 if (itemTarget->GetCount() < 5)
5536 return;
5537
5538 if (sWorld->getBoolConfig(CONFIG_SKILL_MILLING))
5539 {
5540 uint32 SkillValue = p_caster->GetPureSkillValue(SKILL_INSCRIPTION);
5541 uint32 reqSkillValue = itemTarget->GetTemplate()->RequiredSkillRank;
5542 p_caster->UpdateGatherSkill(SKILL_INSCRIPTION, SkillValue, reqSkillValue);
5543 }
5544
5546}
@ CONFIG_SKILL_MILLING
Definition: IWorld.h:92
@ LOOT_MILLING
Definition: LootMgr.h:87
void SendLoot(ObjectGuid guid, LootType loot_type)
Definition: Player.cpp:7806
bool UpdateGatherSkill(uint32 SkillId, uint32 SkillValue, uint32 RedLevel, uint32 Multiplicator=1)
Definition: PlayerUpdates.cpp:721

References CONFIG_SKILL_MILLING, effectHandleMode, Item::GetCount(), Object::GetGUID(), Player::GetPureSkillValue(), Item::GetTemplate(), ItemTemplate::HasFlag(), Object::IsPlayer(), ITEM_FLAG_IS_MILLABLE, itemTarget, LOOT_MILLING, m_caster, ItemTemplate::RequiredSkillRank, Player::SendLoot(), SKILL_INSCRIPTION, SPELL_EFFECT_HANDLE_HIT_TARGET, sWorld, Object::ToPlayer(), and Player::UpdateGatherSkill().

◆ EffectModifyThreatPercent()

void Spell::EffectModifyThreatPercent ( SpellEffIndex  effIndex)
5357{
5359 return;
5360
5361 if (!unitTarget)
5362 return;
5363
5365}
void ModifyThreatByPercent(Unit *victim, int32 percent)
Definition: ThreatMgr.cpp:508
ThreatMgr & GetThreatMgr()
Definition: Unit.h:903

References damage, effectHandleMode, Unit::GetThreatMgr(), m_caster, ThreatMgr::ModifyThreatByPercent(), SPELL_EFFECT_HANDLE_HIT_TARGET, and unitTarget.

◆ EffectNULL()

void Spell::EffectNULL ( SpellEffIndex  effIndex)
239{
240 LOG_DEBUG("spells.aura", "WORLD: Spell Effect DUMMY");
241}

References LOG_DEBUG.

Referenced by EffectPull().

◆ EffectOpenLock()

void Spell::EffectOpenLock ( SpellEffIndex  effIndex)
Todo:
: Add script for spell 41920 - Filling, becouse server it freze when use this spell
2082{
2084 return;
2085
2086 if (!m_caster->IsPlayer())
2087 {
2088 LOG_DEBUG("spells.aura", "WORLD: Open Lock - No Player Caster!");
2089 return;
2090 }
2091
2092 Player* player = m_caster->ToPlayer();
2093
2094 uint32 lockId = 0;
2095 ObjectGuid guid;
2096
2097 // Get lockId
2098 if (gameObjTarget)
2099 {
2100 GameObjectTemplate const* goInfo = gameObjTarget->GetGOInfo();
2101 // Arathi Basin banner opening. /// @todo: Verify correctness of this check
2102 if ((goInfo->type == GAMEOBJECT_TYPE_BUTTON && goInfo->button.noDamageImmune) ||
2103 (goInfo->type == GAMEOBJECT_TYPE_GOOBER && goInfo->goober.losOK))
2104 {
2105 //CanUseBattlegroundObject() already called in CheckCast()
2106 // in battleground check
2107 if (Battleground* bg = player->GetBattleground())
2108 {
2109 bg->EventPlayerClickedOnFlag(player, gameObjTarget);
2110 return;
2111 }
2112 }
2113 else if (goInfo->type == GAMEOBJECT_TYPE_FLAGSTAND)
2114 {
2115 //CanUseBattlegroundObject() already called in CheckCast()
2116 // in battleground check
2117 if (Battleground* bg = player->GetBattleground())
2118 {
2119 if (bg->GetBgTypeID(true) == BATTLEGROUND_EY)
2120 bg->EventPlayerClickedOnFlag(player, gameObjTarget);
2121 return;
2122 }
2123 }
2124 else if (m_spellInfo->Id == 1842 && gameObjTarget->GetGOInfo()->type == GAMEOBJECT_TYPE_TRAP)
2125 {
2128 {
2130 }
2131 return;
2132 }
2134 // handle outdoor pvp object opening, return true if go was registered for handling
2135 // these objects must have been spawned by outdoorpvp!
2136 else if (gameObjTarget->GetGOInfo()->type == GAMEOBJECT_TYPE_GOOBER && sOutdoorPvPMgr->HandleOpenGo(player, gameObjTarget))
2137 return;
2138 lockId = goInfo->GetLockId();
2139 guid = gameObjTarget->GetGUID();
2140 }
2141 else if (itemTarget)
2142 {
2143 lockId = itemTarget->GetTemplate()->LockID;
2144 guid = itemTarget->GetGUID();
2145 }
2146 else
2147 {
2148 LOG_DEBUG("spells.aura", "WORLD: Open Lock - No GameObject/Item Target!");
2149 return;
2150 }
2151
2152 SkillType skillId = SKILL_NONE;
2153 int32 reqSkillValue = 0;
2154 int32 skillValue;
2155
2156 SpellCastResult res = CanOpenLock(effIndex, lockId, skillId, reqSkillValue, skillValue);
2157 if (res != SPELL_CAST_OK)
2158 {
2159 SendCastResult(res);
2160 return;
2161 }
2162
2163 if (gameObjTarget)
2164 SendLoot(guid, LOOT_SKINNING);
2165 else if (itemTarget)
2166 {
2168 if (Player* itemOwner = itemTarget->GetOwner())
2169 itemTarget->SetState(ITEM_CHANGED, itemOwner);
2170 }
2171
2172 // not allow use skill grow at item base open
2173 if (!m_CastItem && skillId != SKILL_NONE)
2174 {
2175 // update skill if really known
2176 if (uint32 pureSkillValue = player->GetPureSkillValue(skillId))
2177 {
2178 if (gameObjTarget)
2179 {
2180 // Allow one skill-up until respawned
2181 if (!gameObjTarget->IsInSkillupList(player->GetGUID()))
2182 {
2184 player->UpdateGatherSkill(skillId, pureSkillValue, reqSkillValue);
2185 }
2186
2187 }
2188 else if (itemTarget)
2189 {
2190 // Do one skill-up
2191 player->UpdateGatherSkill(skillId, pureSkillValue, reqSkillValue);
2192 }
2193 }
2194 }
2196}
@ GAMEOBJECT_TYPE_BUTTON
Definition: SharedDefines.h:1561
@ GAMEOBJECT_TYPE_FLAGSTAND
Definition: SharedDefines.h:1584
@ GAMEOBJECT_TYPE_GOOBER
Definition: SharedDefines.h:1570
@ BATTLEGROUND_EY
Definition: SharedDefines.h:3487
@ ITEM_CHANGED
Definition: Item.h:210
@ ITEM_FIELD_FLAG_UNLOCKED
Definition: ItemTemplate.h:111
@ GO_JUST_DEACTIVATED
Definition: GameObject.h:113
@ ITEM_FIELD_FLAGS
Definition: UpdateFields.h:42
@ LOOT_SKINNING
Definition: LootMgr.h:85
#define sOutdoorPvPMgr
Definition: OutdoorPvPMgr.h:102
Unit * GetOwner() const
Definition: GameObject.cpp:1240
void AddToSkillupList(ObjectGuid playerGuid)
Definition: GameObject.cpp:3070
bool IsInSkillupList(ObjectGuid playerGuid) const
Definition: GameObject.cpp:3076
LootState getLootState() const
Definition: GameObject.h:224
void SetLootState(LootState s, Unit *unit=nullptr)
Definition: GameObject.cpp:2444
Definition: GameObjectData.h:31
uint32 GetAutoCloseTime() const
Definition: GameObjectData.h:510
uint32 noDamageImmune
Definition: GameObjectData.h:48
struct GameObjectTemplate::@230::@233 button
uint32 losOK
Definition: GameObjectData.h:64
struct GameObjectTemplate::@230::@241 goober
uint32 GetLockId() const
Definition: GameObjectData.h:427
void SetState(ItemUpdateState state, Player *forplayer=nullptr)
Definition: Item.cpp:714
Definition: Object.h:103
void ExecuteLogEffectOpenLock(uint8 effIndex, Object *obj)
Definition: Spell.cpp:5143
void SendLoot(ObjectGuid guid, LootType loottype)
Definition: SpellEffects.cpp:2015

References GameObject::AddToSkillupList(), BATTLEGROUND_EY, GameObjectTemplate::button, CanOpenLock(), effectHandleMode, ExecuteLogEffectOpenLock(), GAMEOBJECT_TYPE_BUTTON, GAMEOBJECT_TYPE_FLAGSTAND, GAMEOBJECT_TYPE_GOOBER, GAMEOBJECT_TYPE_TRAP, gameObjTarget, GameObjectTemplate::GetAutoCloseTime(), Player::GetBattleground(), GameObject::GetGOInfo(), Object::GetGUID(), GameObjectTemplate::GetLockId(), GameObject::getLootState(), GameObject::GetOwner(), Item::GetOwner(), Player::GetPureSkillValue(), Item::GetTemplate(), GO_JUST_DEACTIVATED, GameObjectTemplate::goober, SpellInfo::Id, IN_MILLISECONDS, GameObject::IsInSkillupList(), Object::IsPlayer(), ITEM_CHANGED, ITEM_FIELD_FLAG_UNLOCKED, ITEM_FIELD_FLAGS, itemTarget, ItemTemplate::LockID, LOG_DEBUG, LOOT_SKINNING, GameObjectTemplate::losOK, m_caster, m_CastItem, m_spellInfo, GameObjectTemplate::noDamageImmune, SendCastResult(), SendLoot(), Object::SetFlag(), GameObject::SetLootState(), GameObject::SetRespawnTime(), Item::SetState(), SKILL_NONE, sOutdoorPvPMgr, SPELL_CAST_OK, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), GameObjectTemplate::type, and Player::UpdateGatherSkill().

◆ EffectParry()

void Spell::EffectParry ( SpellEffIndex  effIndex)
4696{
4698 return;
4699
4700 if (m_caster->IsPlayer())
4701 m_caster->ToPlayer()->SetCanParry(true);
4702}
void SetCanParry(bool value)
Definition: Player.cpp:13160

References effectHandleMode, Object::IsPlayer(), m_caster, Player::SetCanParry(), SPELL_EFFECT_HANDLE_HIT, and Object::ToPlayer().

◆ EffectPersistentAA()

void Spell::EffectPersistentAA ( SpellEffIndex  effIndex)
1845{
1847 return;
1848
1849 if (!m_spellAura)
1850 {
1852 float radius = m_spellInfo->Effects[effIndex].CalcRadius(caster);
1853
1854 // Caster not in world, might be spell triggered from aura removal
1855 if (!caster->IsInWorld() || !caster->FindMap() || !ObjectAccessor::GetUnit(*caster, caster->GetGUID())) // pussywizard: temporary crash fix (FindMap and GetUnit are mine)
1856 return;
1857 DynamicObject* dynObj = new DynamicObject(false);
1858 if (!dynObj->CreateDynamicObject(caster->GetMap()->GenerateLowGuid<HighGuid::DynamicObject>(), caster, m_spellInfo->Id, *destTarget, radius, DYNAMIC_OBJECT_AREA_SPELL))
1859 {
1860 delete dynObj;
1861 return;
1862 }
1863
1865 {
1866 m_spellAura = aura;
1869 }
1870 else
1871 return;
1872 }
1873
1876}
#define MAX_EFFECT_MASK
Definition: DBCStructure.h:1637
@ DYNAMIC_OBJECT_AREA_SPELL
Definition: DynamicObject.h:30
DynamicObject * GetDynobjOwner() const
Definition: SpellAuras.h:109
static Aura * TryCreate(SpellInfo const *spellproto, uint8 effMask, WorldObject *owner, Unit *caster, int32 *baseAmount=nullptr, Item *castItem=nullptr, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemGUID=ObjectGuid::Empty)
Definition: SpellAuras.cpp:352

References Aura::_ApplyEffectForTargets(), Aura::_RegisterForTargets(), ASSERT, DynamicObject::CreateDynamicObject(), destTarget, DYNAMIC_OBJECT_AREA_SPELL, SpellValue::EffectBasePoints, effectHandleMode, SpellInfo::Effects, WorldObject::FindMap(), Map::GenerateLowGuid(), Aura::GetDynobjOwner(), Object::GetEntry(), Object::GetGUID(), WorldObject::GetMap(), ObjectAccessor::GetUnit(), SpellInfo::Id, Object::IsInWorld(), m_caster, m_originalCaster, m_spellAura, m_spellInfo, m_spellValue, m_triggeredByAuraSpell, MAX_EFFECT_MASK, Aura::SetTriggeredByAuraSpellInfo(), SPELL_EFFECT_HANDLE_HIT, TriggeredByAuraSpellData::spellInfo, Aura::TryCreate(), and WORLD_TRIGGER.

◆ EffectPickPocket()

void Spell::EffectPickPocket ( SpellEffIndex  effIndex)

◆ EffectPlayMusic()

void Spell::EffectPlayMusic ( SpellEffIndex  effIndex)
6110{
6112 return;
6113
6114 if (!unitTarget)
6115 return;
6116
6117 Player* player = unitTarget->ToPlayer();
6118 if (!player)
6119 {
6120 return;
6121 }
6122
6123 uint32 soundid = m_spellInfo->Effects[effIndex].MiscValue;
6124
6125 if (!sSoundEntriesStore.LookupEntry(soundid))
6126 {
6127 LOG_ERROR("spells.effect", "EffectPlayMusic: Sound (Id: {}) not exist in spell {}.", soundid, m_spellInfo->Id);
6128 return;
6129 }
6130
6132}
DBCStorage< SoundEntriesEntry > sSoundEntriesStore(SoundEntriesfmt)
Definition: MiscPackets.h:58

References effectHandleMode, SpellInfo::Effects, SpellInfo::Id, LOG_ERROR, m_spellInfo, Player::SendDirectMessage(), SPELL_EFFECT_HANDLE_HIT_TARGET, sSoundEntriesStore, Object::ToPlayer(), and unitTarget.

◆ EffectPlaySound()

void Spell::EffectPlaySound ( SpellEffIndex  effIndex)
6163{
6165 return;
6166
6167 if (!unitTarget)
6168 return;
6169
6170 Player* player = unitTarget->ToPlayer();
6171 if (!player)
6172 {
6173 return;
6174 }
6175
6176 switch (m_spellInfo->Id)
6177 {
6178 case 58730: // Restricted Flight Area
6179 case 58600: // Restricted Flight Area
6181 break;
6182 default:
6183 break;
6184 }
6185
6186 uint32 soundId = m_spellInfo->Effects[effIndex].MiscValue;
6187
6188 if (!sSoundEntriesStore.LookupEntry(soundId))
6189 {
6190 LOG_ERROR("spells.effect", "EffectPlayerSound: Sound (Id: {}) not exist in spell {}.", soundId, m_spellInfo->Id);
6191 return;
6192 }
6193
6194 player->PlayDirectSound(soundId, player);
6195}
@ LANG_ZONE_NOFLYZONE
Definition: Language.h:753
Definition: Chat.h:37
void SendNotification(std::string_view str)
Definition: Chat.cpp:104
void PlayDirectSound(uint32 sound_id, Player *target=nullptr)
Definition: Object.cpp:2903

References effectHandleMode, SpellInfo::Effects, Player::GetSession(), SpellInfo::Id, LANG_ZONE_NOFLYZONE, LOG_ERROR, m_spellInfo, WorldObject::PlayDirectSound(), ChatHandler::SendNotification(), SPELL_EFFECT_HANDLE_HIT_TARGET, sSoundEntriesStore, Object::ToPlayer(), and unitTarget.

◆ EffectPowerBurn()

void Spell::EffectPowerBurn ( SpellEffIndex  effIndex)
1431{
1433 return;
1434
1435 if (m_spellInfo->Effects[effIndex].MiscValue < 0 || m_spellInfo->Effects[effIndex].MiscValue >= int8(MAX_POWERS))
1436 return;
1437
1438 Powers PowerType = Powers(m_spellInfo->Effects[effIndex].MiscValue);
1439
1441 return;
1442
1443 // burn x% of target's mana, up to maximum of 2x% of caster's mana (Mana Burn)
1444 if (m_spellInfo->Id == 8129)
1445 {
1448 damage = std::min(damage, maxDamage);
1449
1450 // Remove fear
1452 }
1453
1454 int32 power = damage;
1455 // resilience reduce mana draining effect at spell crit damage reduction (added in 2.4)
1456 if (PowerType == POWER_MANA)
1457 power -= unitTarget->GetSpellCritDamageReduction(power);
1458
1459 int32 newDamage = -(unitTarget->ModifyPower(PowerType, -power));
1460
1461 // NO - Not a typo - EffectPowerBurn uses effect value multiplier - not effect damage multiplier
1462 float dmgMultiplier = m_spellInfo->Effects[effIndex].CalcValueMultiplier(m_originalCaster, this);
1463
1464 // add log data before multiplication (need power amount, not damage)
1465 ExecuteLogEffectTakeTargetPower(effIndex, unitTarget, PowerType, newDamage, 0.0f);
1466
1467 newDamage = int32(newDamage * dmgMultiplier);
1468
1469 m_damage += newDamage;
1470}
int32 ModifyPower(Powers power, int32 val, bool withPowerUpdate=true)
Definition: Unit.cpp:14149
uint32 GetSpellCritDamageReduction(uint32 damage) const
Definition: Unit.h:1201
void ExecuteLogEffectTakeTargetPower(uint8 effIndex, Unit *target, uint32 PowerType, uint32 powerTaken, float gainMultiplier)
Definition: Spell.cpp:5112

References CalculatePct(), damage, effectHandleMode, SpellInfo::Effects, ExecuteLogEffectTakeTargetPower(), Unit::GetMaxPower(), Unit::GetSpellCritDamageReduction(), Unit::HasActivePowerType(), SpellInfo::Id, Unit::IsAlive(), m_caster, m_damage, m_originalCaster, m_spellInfo, MAX_POWERS, Unit::ModifyPower(), POWER_MANA, Unit::RemoveAurasByType(), SPELL_AURA_MOD_FEAR, SPELL_EFFECT_HANDLE_HIT_TARGET, and unitTarget.

◆ EffectPowerDrain()

void Spell::EffectPowerDrain ( SpellEffIndex  effIndex)
1352{
1354 return;
1355
1356 if (m_spellInfo->Effects[effIndex].MiscValue < 0 || m_spellInfo->Effects[effIndex].MiscValue >= int8(MAX_POWERS))
1357 return;
1358
1359 Powers PowerType = Powers(m_spellInfo->Effects[effIndex].MiscValue);
1360
1362 return;
1363
1364 // add spell damage bonus
1367
1368 // resilience reduce mana draining effect at spell crit damage reduction (added in 2.4)
1369 int32 power = damage;
1370 if (PowerType == POWER_MANA)
1371 power -= unitTarget->GetSpellCritDamageReduction(power);
1372
1373 int32 newDamage = -(unitTarget->ModifyPower(PowerType, -int32(power)));
1374
1375 float gainMultiplier = 0.0f;
1376
1377 // Don`t restore from self drain
1378 if (m_caster != unitTarget)
1379 {
1380 gainMultiplier = m_spellInfo->Effects[effIndex].CalcValueMultiplier(m_originalCaster, this);
1381
1382 int32 gain = int32(newDamage * gainMultiplier);
1383
1385 }
1386 ExecuteLogEffectTakeTargetPower(effIndex, unitTarget, PowerType, newDamage, gainMultiplier);
1387}

References damage, effectHandleMode, SpellInfo::Effects, Unit::EnergizeBySpell(), ExecuteLogEffectTakeTargetPower(), Unit::GetSpellCritDamageReduction(), Unit::HasActivePowerType(), SpellInfo::Id, Unit::IsAlive(), m_caster, m_originalCaster, m_spellInfo, MAX_POWERS, Unit::ModifyPower(), POWER_MANA, SPELL_DIRECT_DAMAGE, SPELL_EFFECT_HANDLE_HIT_TARGET, Unit::SpellDamageBonusDone(), Unit::SpellDamageBonusTaken(), and unitTarget.

◆ EffectProficiency()

void Spell::EffectProficiency ( SpellEffIndex  effIndex)
2308{
2310 return;
2311
2312 if (!m_caster->IsPlayer())
2313 return;
2314 Player* p_target = m_caster->ToPlayer();
2315
2317 if (m_spellInfo->EquippedItemClass == ITEM_CLASS_WEAPON && !(p_target->GetWeaponProficiency() & subClassMask))
2318 {
2319 p_target->AddWeaponProficiency(subClassMask);
2321 }
2322 if (m_spellInfo->EquippedItemClass == ITEM_CLASS_ARMOR && !(p_target->GetArmorProficiency() & subClassMask))
2323 {
2324 p_target->AddArmorProficiency(subClassMask);
2326 }
2327}
uint32 GetArmorProficiency() const
Definition: Player.h:1372
void SendProficiency(ItemClass itemClass, uint32 itemSubclassMask)
Definition: Player.cpp:10133
uint32 GetWeaponProficiency() const
Definition: Player.h:1371
void AddArmorProficiency(uint32 newflag)
Definition: Player.h:1370
void AddWeaponProficiency(uint32 newflag)
Definition: Player.h:1369
int32 EquippedItemSubClassMask
Definition: SpellInfo.h:376

References Player::AddArmorProficiency(), Player::AddWeaponProficiency(), effectHandleMode, SpellInfo::EquippedItemClass, SpellInfo::EquippedItemSubClassMask, Player::GetArmorProficiency(), Player::GetWeaponProficiency(), Object::IsPlayer(), ITEM_CLASS_ARMOR, ITEM_CLASS_WEAPON, m_caster, m_spellInfo, Player::SendProficiency(), SPELL_EFFECT_HANDLE_HIT, and Object::ToPlayer().

◆ EffectProspecting()

void Spell::EffectProspecting ( SpellEffIndex  effIndex)

◆ EffectPull()

void Spell::EffectPull ( SpellEffIndex  effIndex)
Todo:
: create a proper pull towards distract spell center for distract
2684{
2686 EffectNULL(effIndex);
2687}
void EffectNULL(SpellEffIndex effIndex)
Definition: SpellEffects.cpp:238

References EffectNULL().

◆ EffectPullTowards()

void Spell::EffectPullTowards ( SpellEffIndex  effIndex)
5130{
5132 return;
5133
5134 if (!unitTarget)
5135 return;
5136
5137 Position pos;
5138 if (m_spellInfo->Effects[effIndex].Effect == SPELL_EFFECT_PULL_TOWARDS_DEST)
5139 {
5140 if (m_targets.HasDst())
5141 pos.Relocate(*destTarget);
5142 else
5143 return;
5144 }
5145 else //if (m_spellInfo->Effects[i].Effect == SPELL_EFFECT_PULL_TOWARDS)
5146 {
5147 // Xinef: Increase Z position a little bit, should protect from falling through textures
5149 }
5150
5151 float speedXY = float(m_spellInfo->Effects[effIndex].MiscValue) ? float(m_spellInfo->Effects[effIndex].MiscValue) * 0.1f : 30.f;
5152 float speedZ = unitTarget->GetDistance(pos) / speedXY * 0.5f * Movement::gravity;
5153
5154 unitTarget->GetMotionMaster()->MoveJump(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), speedXY, speedZ);
5155
5156 if (unitTarget->IsPlayer())
5157 {
5158 sScriptMgr->AnticheatSetUnderACKmount(unitTarget->ToPlayer());
5159 }
5160}
@ SPELL_EFFECT_PULL_TOWARDS_DEST
Definition: SharedDefines.h:923
void Relocate(float x, float y)
Definition: Position.h:72

References destTarget, effectHandleMode, SpellInfo::Effects, WorldObject::GetDistance(), Unit::GetMotionMaster(), Position::GetOrientation(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), Movement::gravity, SpellCastTargets::HasDst(), Object::IsPlayer(), m_caster, m_spellInfo, m_targets, MotionMaster::MoveJump(), Position::Relocate(), SPELL_EFFECT_HANDLE_HIT_TARGET, SPELL_EFFECT_PULL_TOWARDS_DEST, sScriptMgr, Object::ToPlayer(), and unitTarget.

◆ EffectQuestClear()

void Spell::EffectQuestClear ( SpellEffIndex  effIndex)
5068{
5070 return;
5071
5072 if (!unitTarget)
5073 return;
5074
5075 Player* player = unitTarget->ToPlayer();
5076 if (!player)
5077 {
5078 return;
5079 }
5080
5081 uint32 quest_id = m_spellInfo->Effects[effIndex].MiscValue;
5082
5083 Quest const* quest = sObjectMgr->GetQuestTemplate(quest_id);
5084
5085 if (!quest)
5086 return;
5087
5088 // Player has never done this quest
5089 if (player->GetQuestStatus(quest_id) == QUEST_STATUS_NONE)
5090 return;
5091
5092 // remove all quest entries for 'entry' from quest log
5093 for (uint8 slot = 0; slot < MAX_QUEST_LOG_SIZE; ++slot)
5094 {
5095 uint32 logQuest = player->GetQuestSlotQuestId(slot);
5096 if (logQuest == quest_id)
5097 {
5098 player->SetQuestSlot(slot, 0);
5099
5100 // we ignore unequippable quest items in this case, it's still be equipped
5101 player->TakeQuestSourceItem(logQuest, false);
5102
5103 if (quest->HasFlag(QUEST_FLAGS_FLAGS_PVP))
5104 {
5105 player->pvpInfo.IsHostile = player->pvpInfo.IsInHostileArea || player->HasPvPForcingQuest();
5106 player->UpdatePvPState();
5107 }
5108 }
5109 }
5110
5111 player->RemoveRewardedQuest(quest_id);
5112 player->RemoveActiveQuest(quest_id, false);
5113}
@ QUEST_FLAGS_FLAGS_PVP
Definition: QuestDef.h:145
#define MAX_QUEST_LOG_SIZE
Definition: QuestDef.h:33
@ QUEST_STATUS_NONE
Definition: QuestDef.h:100
bool IsHostile
Definition: Player.h:365
bool IsInHostileArea
Definition: Player.h:366
bool HasPvPForcingQuest() const
Definition: PlayerQuest.cpp:2494
void UpdatePvPState()
Definition: PlayerUpdates.cpp:1394
uint32 GetQuestSlotQuestId(uint16 slot) const
Definition: Player.h:1494
void SetQuestSlot(uint16 slot, uint32 quest_id, uint32 timer=0)
Definition: Player.h:1498
PvPInfo pvpInfo
Definition: Player.h:1847
bool TakeQuestSourceItem(uint32 questId, bool msg)
Definition: PlayerQuest.cpp:1362
void RemoveActiveQuest(uint32 questId, bool update=true)
Definition: PlayerQuest.cpp:1494
QuestStatus GetQuestStatus(uint32 quest_id) const
Definition: PlayerQuest.cpp:1429
void RemoveRewardedQuest(uint32 questId, bool update=true)
Definition: PlayerQuest.cpp:1512
Definition: QuestDef.h:210
bool HasFlag(uint32 flag) const
Definition: QuestDef.h:221

References effectHandleMode, SpellInfo::Effects, Player::GetQuestSlotQuestId(), Player::GetQuestStatus(), Quest::HasFlag(), Player::HasPvPForcingQuest(), PvPInfo::IsHostile, PvPInfo::IsInHostileArea, m_spellInfo, MAX_QUEST_LOG_SIZE, Player::pvpInfo, QUEST_FLAGS_FLAGS_PVP, QUEST_STATUS_NONE, Player::RemoveActiveQuest(), Player::RemoveRewardedQuest(), Player::SetQuestSlot(), sObjectMgr, SPELL_EFFECT_HANDLE_HIT_TARGET, Player::TakeQuestSourceItem(), Object::ToPlayer(), unitTarget, and Player::UpdatePvPState().

◆ EffectQuestComplete()

void Spell::EffectQuestComplete ( SpellEffIndex  effIndex)
4755{
4757 return;
4758
4759 if (!unitTarget)
4760 return;
4761
4762 Player* player = unitTarget->ToPlayer();
4763 if (!player)
4764 {
4765 return;
4766 }
4767
4768 uint32 questId = m_spellInfo->Effects[effIndex].MiscValue;
4769 if (questId)
4770 {
4771 Quest const* quest = sObjectMgr->GetQuestTemplate(questId);
4772 if (!quest)
4773 return;
4774
4775 uint16 logSlot = player->FindQuestSlot(questId);
4776 if (logSlot < MAX_QUEST_LOG_SIZE)
4777 player->AreaExploredOrEventHappens(questId);
4778 else if (player->CanTakeQuest(quest, false)) // Check if the quest has already been turned in.
4779 player->SetRewardedQuest(questId); // If not, set status to rewarded without broadcasting it to client.
4780 }
4781}
uint16 FindQuestSlot(uint32 quest_id) const
Definition: PlayerQuest.cpp:1781
bool CanTakeQuest(Quest const *quest, bool msg)
Definition: PlayerQuest.cpp:251
void SetRewardedQuest(uint32 quest_id)
Definition: PlayerQuest.cpp:879
void AreaExploredOrEventHappens(uint32 questId)
Definition: PlayerQuest.cpp:1790

References Player::AreaExploredOrEventHappens(), Player::CanTakeQuest(), effectHandleMode, SpellInfo::Effects, Player::FindQuestSlot(), m_spellInfo, MAX_QUEST_LOG_SIZE, Player::SetRewardedQuest(), sObjectMgr, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectQuestFail()

void Spell::EffectQuestFail ( SpellEffIndex  effIndex)
5736{
5738 return;
5739
5740 if (!unitTarget)
5741 return;
5742
5743 if (Player* player = unitTarget->ToPlayer())
5744 {
5745 player->FailQuest(m_spellInfo->Effects[effIndex].MiscValue);
5746 }
5747}

References effectHandleMode, SpellInfo::Effects, m_spellInfo, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectQuestStart()

void Spell::EffectQuestStart ( SpellEffIndex  effIndex)
5750{
5752 return;
5753
5754 if (!unitTarget)
5755 return;
5756
5757 Player* player = unitTarget->ToPlayer();
5758 if (!player)
5759 return;
5760
5761 if (Quest const* quest = sObjectMgr->GetQuestTemplate(m_spellInfo->Effects[effIndex].MiscValue))
5762 {
5763 if (!player->CanTakeQuest(quest, false))
5764 return;
5765
5766 if (quest->IsAutoAccept() && player->CanAddQuest(quest, false))
5767 player->AddQuestAndCheckCompletion(quest, player);
5768
5769 player->PlayerTalkClass->SendQuestGiverQuestDetails(quest, player->GetGUID(), true);
5770 }
5771}
void SendQuestGiverQuestDetails(Quest const *quest, ObjectGuid npcGUID, bool activateAccept) const
Definition: GossipDef.cpp:388
bool CanAddQuest(Quest const *quest, bool msg)
Definition: PlayerQuest.cpp:264
void AddQuestAndCheckCompletion(Quest const *quest, Object *questGiver)
Definition: PlayerQuest.cpp:420
PlayerMenu * PlayerTalkClass
Definition: Player.h:2239

References Player::AddQuestAndCheckCompletion(), Player::CanAddQuest(), Player::CanTakeQuest(), effectHandleMode, SpellInfo::Effects, Object::GetGUID(), m_spellInfo, Player::PlayerTalkClass, PlayerMenu::SendQuestGiverQuestDetails(), sObjectMgr, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectRechargeManaGem()

void Spell::EffectRechargeManaGem ( SpellEffIndex  effIndex)
6252{
6254 return;
6255
6256 if (!unitTarget || !unitTarget->IsPlayer())
6257 return;
6258
6259 Player* player = m_caster->ToPlayer();
6260
6261 if (!player)
6262 return;
6263
6264 uint32 item_id = m_spellInfo->Effects[EFFECT_0].ItemType;
6265
6266 ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(item_id);
6267 if (!pProto)
6268 {
6269 player->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, nullptr, nullptr);
6270 return;
6271 }
6272
6273 if (Item* pItem = player->GetItemByEntry(item_id))
6274 {
6275 for (int x = 0; x < MAX_ITEM_PROTO_SPELLS; ++x)
6276 pItem->SetSpellCharges(x, pProto->Spells[x].SpellCharges);
6277 pItem->SetState(ITEM_CHANGED, player);
6278 }
6279}

References EFFECT_0, effectHandleMode, SpellInfo::Effects, EQUIP_ERR_ITEM_NOT_FOUND, Player::GetItemByEntry(), Object::IsPlayer(), ITEM_CHANGED, m_caster, m_spellInfo, MAX_ITEM_PROTO_SPELLS, Player::SendEquipError(), sObjectMgr, SPELL_EFFECT_HANDLE_HIT_TARGET, _Spell::SpellCharges, ItemTemplate::Spells, Object::ToPlayer(), and unitTarget.

◆ EffectRedirectThreat()

void Spell::EffectRedirectThreat ( SpellEffIndex  effIndex)
5910{
5912 return;
5913
5914 if (unitTarget)
5916}
void SetRedirectThreat(ObjectGuid guid, uint32 pct)
Definition: Unit.h:910

References damage, effectHandleMode, Object::GetGUID(), m_caster, Unit::SetRedirectThreat(), SPELL_EFFECT_HANDLE_HIT_TARGET, and unitTarget.

◆ EffectRemoveAura()

void Spell::EffectRemoveAura ( SpellEffIndex  effIndex)
6198{
6200 return;
6201
6202 if (!unitTarget)
6203 return;
6204 // there may be need of specifying casterguid of removed auras
6205 unitTarget->RemoveAurasDueToSpell(m_spellInfo->Effects[effIndex].TriggerSpell);
6206}

References effectHandleMode, SpellInfo::Effects, m_spellInfo, Unit::RemoveAurasDueToSpell(), SPELL_EFFECT_HANDLE_HIT_TARGET, and unitTarget.

◆ EffectRenamePet()

void Spell::EffectRenamePet ( SpellEffIndex  effIndex)
6098{
6100 return;
6101
6102 if (!unitTarget || !unitTarget->IsCreature() ||
6104 return;
6105
6107}
@ UNIT_FIELD_BYTES_2
Definition: UpdateFields.h:161
@ UNIT_CAN_BE_RENAMED
Definition: UnitDefines.h:128
void SetByteFlag(uint16 index, uint8 offset, uint8 newFlag)
Definition: Object.cpp:911
PetType getPetType() const
Definition: Pet.h:52

References effectHandleMode, Pet::getPetType(), HUNTER_PET, Object::IsCreature(), Unit::IsPet(), Object::SetByteFlag(), SPELL_EFFECT_HANDLE_HIT_TARGET, Unit::ToPet(), UNIT_CAN_BE_RENAMED, UNIT_FIELD_BYTES_2, and unitTarget.

◆ EffectReputation()

void Spell::EffectReputation ( SpellEffIndex  effIndex)
4729{
4731 return;
4732
4733 if (!unitTarget)
4734 return;
4735
4736 Player* player = unitTarget->ToPlayer();
4737 if (!player)
4738 {
4739 return;
4740 }
4741
4742 float repChange = static_cast<float>(damage);
4743
4744 uint32 factionId = m_spellInfo->Effects[effIndex].MiscValue;
4745
4746 FactionEntry const* factionEntry = sFactionStore.LookupEntry(factionId);
4747 if (!factionEntry)
4748 return;
4749
4750 repChange = player->CalculateReputationGain(REPUTATION_SOURCE_SPELL, 0, repChange, factionId);
4751 player->GetReputationMgr().ModifyReputation(factionEntry, repChange);
4752}
@ REPUTATION_SOURCE_SPELL
Definition: Player.h:245
DBCStorage< FactionEntry > sFactionStore(FactionEntryfmt)
float CalculateReputationGain(ReputationSource source, uint32 creatureOrQuestLevel, float rep, int32 faction, bool noQuestBonus=false)
Definition: Player.cpp:5900
ReputationMgr & GetReputationMgr()
Definition: Player.h:2125
bool ModifyReputation(FactionEntry const *factionEntry, float standing, bool noSpillOver=false, Optional< ReputationRank > repMaxCap={})
Definition: ReputationMgr.h:117
Definition: DBCStructure.h:906

References Player::CalculateReputationGain(), damage, effectHandleMode, SpellInfo::Effects, Player::GetReputationMgr(), m_spellInfo, ReputationMgr::ModifyReputation(), REPUTATION_SOURCE_SPELL, sFactionStore, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectResurrect()

void Spell::EffectResurrect ( SpellEffIndex  effIndex)
4647{
4649 return;
4650
4651 if (!unitTarget)
4652 return;
4653
4654 if (!unitTarget)
4655 return;
4656
4657 Player* target = unitTarget->ToPlayer();
4658 if (!target)
4659 {
4660 return;
4661 }
4662
4663 if (unitTarget->IsAlive() || !unitTarget->IsInWorld())
4664 return;
4665
4666 if (target->isResurrectRequested()) // already have one active request
4667 return;
4668
4669 uint32 health = target->CountPctFromMaxHealth(damage);
4671
4672 ExecuteLogEffectResurrect(effIndex, target);
4673
4675 SendResurrectRequest(target);
4676}
void setResurrectRequestData(ObjectGuid guid, uint32 mapId, float X, float Y, float Z, uint32 health, uint32 mana)
Definition: Player.h:1816
bool isResurrectRequested() const
Definition: Player.h:1828
void ExecuteLogEffectResurrect(uint8 effIndex, Unit *target)
Definition: Spell.cpp:5173
void SendResurrectRequest(Player *target)
Definition: Spell.cpp:5235

References CalculatePct(), Unit::CountPctFromMaxHealth(), damage, effectHandleMode, ExecuteLogEffectResurrect(), Object::GetGUID(), WorldLocation::GetMapId(), Unit::GetMaxPower(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), Unit::IsAlive(), Object::IsInWorld(), Player::isResurrectRequested(), m_caster, POWER_MANA, SendResurrectRequest(), Player::setResurrectRequestData(), SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectResurrectNew()

◆ EffectResurrectPet()

void Spell::EffectResurrectPet ( SpellEffIndex  effIndex)
Todo:
: Better to fail Hunter's "Revive Pet" at cast instead of here when casting ends
5206{
5208 return;
5209
5210 if (damage < 0)
5211 return;
5212
5213 Player* player = m_caster->ToPlayer();
5214 if (!player)
5215 {
5216 return;
5217 }
5218
5219 Pet* pet = player->GetPet();
5220 if (!pet)
5221 {
5222 // Position passed to SummonPet is irrelevant with current implementation,
5223 // pet will be relocated without using these coords in Pet::LoadPetFromDB
5224 player->SummonPet(0, 0.0f, 0.0f, 0.0f, 0.0f, SUMMON_PET, 0s, damage);
5225 return;
5226 }
5227
5229 if (pet->IsAlive())
5230 {
5231 return;
5232 }
5233
5234 // Reposition the pet's corpse before reviving so as not to grab aggro
5235 // We can use a different, more accurate version of GetClosePoint() since we have a pet
5236 float x, y, z; // Will be used later to reposition the pet if we have one
5237 player->GetClosePoint(x, y, z, pet->GetCombatReach(), PET_FOLLOW_DIST, pet->GetFollowAngle());
5238 pet->NearTeleportTo(x, y, z, player->GetOrientation());
5239 pet->Relocate(x, y, z, player->GetOrientation()); // This is needed so SaveStayPosition() will get the proper coords.
5242 pet->setDeathState(DeathState::Alive);
5243 pet->ClearUnitState(uint32(UNIT_STATE_ALL_STATE & ~(UNIT_STATE_POSSESSED))); // xinef: just in case
5245 pet->SetDisplayId(pet->GetNativeDisplayId());
5246
5247 // xinef: restore movement
5248 if (auto ci = pet->GetCharmInfo())
5249 {
5250 ci->SetIsAtStay(false);
5251 ci->SetIsFollowing(false);
5252 }
5253
5255}
@ UNIT_DYNFLAG_NONE
Definition: SharedDefines.h:3120
@ UNIT_STATE_POSSESSED
Definition: UnitDefines.h:165
@ UNIT_STATE_ALL_STATE
Definition: UnitDefines.h:199
#define PET_FOLLOW_DIST
Definition: PetDefines.h:198
@ SUMMON_PET
Definition: PetDefines.h:31
float GetFollowAngle() const override
Definition: TemporarySummon.h:82
bool GetClosePoint(float &x, float &y, float &z, float size, float distance2d=0, float angle=0, WorldObject const *forWho=nullptr, bool force=false) const
Definition: Object.cpp:2710
void setDeathState(DeathState s, bool despawn=false) override
A creature can be in 4 different states: Alive, JustDied, Corpse, and JustRespawned....
Definition: Pet.cpp:625
void SetDisplayId(uint32 modelId, float displayScale=1.f) override
Definition: Pet.cpp:2415
Pet * SummonPet(uint32 entry, float x, float y, float z, float ang, PetType petType, Milliseconds duration=0s, uint32 healthPct=0)
Definition: Player.cpp:8962
void ReplaceAllDynamicFlags(uint32 flag) override
Definition: Unit.h:731
void SetHealth(uint32 val)
Definition: Unit.cpp:15478
uint32 GetNativeDisplayId() const
Definition: Unit.h:1839
void RemoveUnitFlag(UnitFlags flags)
UnitFlags available in UnitDefines.h.
Definition: Unit.h:714

References Unit::ClearUnitState(), Unit::CountPctFromMaxHealth(), damage, effectHandleMode, Unit::GetCharmInfo(), WorldObject::GetClosePoint(), Unit::GetCombatReach(), Minion::GetFollowAngle(), Unit::GetNativeDisplayId(), Position::GetOrientation(), Player::GetPet(), Unit::IsAlive(), m_caster, Unit::NearTeleportTo(), PET_FOLLOW_DIST, PET_SAVE_AS_CURRENT, Position::Relocate(), Unit::RemoveUnitFlag(), Unit::ReplaceAllDynamicFlags(), Pet::SavePetToDB(), Pet::setDeathState(), Pet::SetDisplayId(), Unit::SetHealth(), SPELL_EFFECT_HANDLE_HIT, SUMMON_PET, Player::SummonPet(), Object::ToPlayer(), UNIT_DYNFLAG_NONE, UNIT_FLAG_SKINNABLE, UNIT_STATE_ALL_STATE, and UNIT_STATE_POSSESSED.

◆ EffectSanctuary()

void Spell::EffectSanctuary ( SpellEffIndex  effIndex)
4031{
4033 return;
4034
4035 if (!unitTarget)
4036 return;
4037
4039 {
4041 // Xinef: replaced with CombatStop(false)
4044
4045 // Night Elf: Shadowmeld only resets threat temporarily
4046 if (m_spellInfo->Id != 59646)
4048
4049 if (unitTarget->IsPlayer())
4050 unitTarget->ToPlayer()->SendAttackSwingCancelAttack(); // melee and ranged forced attack cancel
4051 }
4052 else
4053 {
4054 unitTarget->getHostileRefMgr().UpdateVisibility(m_spellInfo->Id == 59646); // Night Elf: Shadowmeld
4055 unitTarget->CombatStop(true);
4056 }
4057
4058 UnitList targets;
4059 Acore::AnyUnfriendlyUnitInObjectRangeCheck u_check(unitTarget, unitTarget, unitTarget->GetVisibilityRange()); // no VISIBILITY_COMPENSATION, distance is enough
4062 for (UnitList::iterator iter = targets.begin(); iter != targets.end(); ++iter)
4063 {
4064 if (!(*iter)->HasUnitState(UNIT_STATE_CASTING))
4065 continue;
4066
4068 {
4069 if ((*iter)->GetCurrentSpell(i) && (*iter)->GetCurrentSpell(i)->m_targets.GetUnitTargetGUID() == unitTarget->GetGUID())
4070 {
4071 SpellInfo const* si = (*iter)->GetCurrentSpell(i)->GetSpellInfo();
4072 if (si->HasAttribute(SPELL_ATTR6_IGNORE_PHASE_SHIFT) && (*iter)->IsCreature())
4073 {
4074 Creature* c = (*iter)->ToCreature();
4075 if ((!c->IsPet() && c->GetCreatureTemplate()->rank == CREATURE_ELITE_WORLDBOSS) || c->isWorldBoss() || c->IsDungeonBoss())
4076 continue;
4077 }
4078 bool interrupt = false; // pussywizard: skip spells that don't target units, but casted on unit (eg. TARGET_DEST_TARGET_ENEMY)
4079 for (uint8 j = 0; j < MAX_SPELL_EFFECTS; ++j)
4080 if (si->Effects[j].Effect && (si->Effects[j].GetUsedTargetObjectType() == TARGET_OBJECT_TYPE_UNIT || si->Effects[j].GetUsedTargetObjectType() == TARGET_OBJECT_TYPE_UNIT_AND_DEST))
4081 {
4082 // at least one effect truly targets an unit, interrupt the spell
4083 interrupt = true;
4084 break;
4085 }
4086 if (interrupt)
4087 (*iter)->InterruptSpell(CurrentSpellTypes(i), false);
4088 }
4089 }
4090 }
4091
4092 // Xinef: Set last sanctuary time
4094}
#define CURRENT_MAX_SPELL
Definition: Unit.h:544
void UpdateVisibility(bool checkThreat)
Definition: HostileRefMgr.cpp:236
void addThreatPercent(int32 percent)
Definition: HostileRefMgr.cpp:85
void SendAttackSwingCancelAttack()
Definition: PlayerMisc.cpp:140
void CombatStop(bool includingCast=false)
Definition: Unit.cpp:10436
void RemoveAllAttackers()
Remove all units in m_attackers list and send them AttackStop()
Definition: Unit.cpp:10484
bool AttackStop()
Force the unit to stop attacking. This will clear UNIT_STATE_MELEE_ATTACKING, Interrupt current spell...
Definition: Unit.cpp:10403
virtual bool IsEncounterInProgress() const
Definition: InstanceScript.cpp:125

References HostileRefMgr::addThreatPercent(), Unit::AttackStop(), Unit::CombatStop(), CREATURE_ELITE_WORLDBOSS, CURRENT_FIRST_NON_MELEE_SPELL, CURRENT_MAX_SPELL, effectHandleMode, SpellInfo::Effects, Creature::GetCreatureTemplate(), GameTime::GetGameTimeMS(), Object::GetGUID(), Unit::getHostileRefMgr(), WorldObject::GetInstanceScript(), WorldObject::GetVisibilityRange(), SpellInfo::HasAttribute(), SpellInfo::Id, Unit::InterruptSpell(), Creature::IsDungeonBoss(), InstanceScript::IsEncounterInProgress(), Unit::IsPet(), Object::IsPlayer(), Creature::isWorldBoss(), Unit::m_lastSanctuaryTime, m_spellInfo, MAX_SPELL_EFFECTS, CreatureTemplate::rank, Unit::RemoveAllAttackers(), Player::SendAttackSwingCancelAttack(), SPELL_ATTR6_IGNORE_PHASE_SHIFT, SPELL_EFFECT_HANDLE_HIT_TARGET, TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT_AND_DEST, Object::ToCreature(), Object::ToPlayer(), UNIT_STATE_CASTING, unitTarget, HostileRefMgr::UpdateVisibility(), and Cell::VisitAllObjects().

◆ EffectSchoolDMG()

void Spell::EffectSchoolDMG ( SpellEffIndex  effIndex)
Todo:
: should this be put on taken but not done?
324{
326 return;
327
328 if (unitTarget && unitTarget->IsAlive())
329 {
330 bool apply_direct_bonus = true;
332 {
334 {
335 // Meteor like spells (divided damage to targets)
337 {
338 uint32 count = 0;
339 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
340 if (ihit->effectMask & (1 << effIndex))
341 ++count;
342
343 damage /= count; // divide to all targets
344 }
345 break;
346 }
348 {
349 // Shield Slam
350 if (m_spellInfo->SpellFamilyFlags[1] & 0x200 && m_spellInfo->GetCategory() == 1209)
351 {
352 uint8 level = m_caster->GetLevel();
353 // xinef: shield block should increase the limit
354 float limit = m_caster->HasAura(2565) ? 2.0f : 1.0f;
355 uint32 block_value = m_caster->GetShieldBlockValue(uint32(float(level) * 24.5f * limit), uint32(float(level) * 34.5f * limit));
356
357 damage += int32(m_caster->ApplyEffectModifiers(m_spellInfo, effIndex, float(block_value)));
358 }
359 // Victory Rush
360 else if (m_spellInfo->SpellFamilyFlags[1] & 0x100)
362 // Shockwave
363 else if (m_spellInfo->Id == 46968)
364 {
366 if (pct > 0)
368 break;
369 }
370 break;
371 }
373 {
374 // Incinerate Rank 1 & 2
375 if ((m_spellInfo->SpellFamilyFlags[1] & 0x000040) && m_spellInfo->SpellIconID == 2128)
376 {
377 // Incinerate does more dmg (dmg*0.25) if the target have Immolate debuff.
378 // Check aura state for speed but aura state set not only for Immolate spell
380 {
382 damage += damage / 4;
383 }
384 }
385 // Conflagrate - consumes Immolate or Shadowflame
387 {
388 AuraEffect const* aura = nullptr; // found req. aura for damage calculation
389
391 for (Unit::AuraEffectList::const_iterator i = mPeriodic.begin(); i != mPeriodic.end(); ++i)
392 {
393 // for caster applied auras only
394 if ((*i)->GetSpellInfo()->SpellFamilyName != SPELLFAMILY_WARLOCK ||
395 (*i)->GetCasterGUID() != m_caster->GetGUID())
396 continue;
397
398 // Immolate
399 if ((*i)->GetSpellInfo()->SpellFamilyFlags[0] & 0x4)
400 {
401 aura = *i; // it selected always if exist
402 break;
403 }
404
405 // Shadowflame
406 if ((*i)->GetSpellInfo()->SpellFamilyFlags[2] & 0x00000002)
407 aura = *i; // remember but wait possible Immolate as primary priority
408 }
409
410 // found Immolate or Shadowflame
411 if (aura)
412 {
413 uint32 pdamage = uint32(std::max(aura->GetAmount(), 0));
414 pdamage = unitTarget->SpellDamageBonusTaken(m_caster, aura->GetSpellInfo(), pdamage, DOT, aura->GetBase()->GetStackAmount());
415 uint32 pct_dir = m_caster->CalculateSpellDamage(unitTarget, m_spellInfo, (effIndex + 1));
416 uint8 baseTotalTicks = uint8(m_caster->CalcSpellDuration(aura->GetSpellInfo()) / aura->GetSpellInfo()->Effects[EFFECT_0].Amplitude);
417
418 damage += int32(CalculatePct(pdamage * baseTotalTicks, pct_dir));
419
420 uint32 pct_dot = m_caster->CalculateSpellDamage(unitTarget, m_spellInfo, (effIndex + 2)) / 3;
421 m_spellValue->EffectBasePoints[1] = m_spellInfo->Effects[EFFECT_1].CalcBaseValue(int32(CalculatePct(pdamage * baseTotalTicks, pct_dot)));
422
423 apply_direct_bonus = false;
424 // Glyph of Conflagrate
425 if (!m_caster->HasAura(56235))
427
428 break;
429 }
430 }
431 // Shadow Bite
432 else if (m_spellInfo->SpellFamilyFlags[1] & 0x400000)
433 {
434 if (m_caster->IsCreature() && m_caster->IsPet())
435 {
436 if (Player* owner = m_caster->GetOwner()->ToPlayer())
437 {
438 if (AuraEffect* aurEff = owner->GetAuraEffect(SPELL_AURA_ADD_FLAT_MODIFIER, SPELLFAMILY_WARLOCK, 214, 0))
439 {
440 int32 bp0 = aurEff->GetId() == 54037 ? 4 : 8;
441 m_caster->CastCustomSpell(m_caster, 54425, &bp0, nullptr, nullptr, true);
442 }
443 }
444 }
445 }
446 break;
447 }
449 {
450 // Improved Mind Blast (Mind Blast in shadow form bonus)
451 if (m_caster->GetShapeshiftForm() == FORM_SHADOW && (m_spellInfo->SpellFamilyFlags[0] & 0x00002000))
452 {
454 for (Unit::AuraEffectList::const_iterator i = ImprMindBlast.begin(); i != ImprMindBlast.end(); ++i)
455 {
456 if ((*i)->GetSpellInfo()->SpellFamilyName == SPELLFAMILY_PRIEST &&
457 ((*i)->GetSpellInfo()->SpellIconID == 95))
458 {
459 int chance = (*i)->GetSpellInfo()->Effects[EFFECT_1].CalcValue(m_caster);
460 if (roll_chance_i(chance))
461 // Mind Trauma
462 m_caster->CastSpell(unitTarget, 48301, true, 0);
463 break;
464 }
465 }
466 }
467 break;
468 }
470 {
471 // Ferocious Bite
472 if (m_caster->IsPlayer() && (m_spellInfo->SpellFamilyFlags[0] & 0x000800000) && m_spellInfo->SpellVisual[0] == 6587)
473 {
474 // converts each extra point of energy into ($f1+$AP/410) additional damage
476 float multiple = ap / 410 + m_spellInfo->Effects[effIndex].DamageMultiplier;
477 int32 energy = -(m_caster->ModifyPower(POWER_ENERGY, -30));
478 damage += int32(energy * multiple);
480 }
481 // Wrath
482 else if (m_spellInfo->SpellFamilyFlags[0] & 0x00000001)
483 {
484 // Improved Insect Swarm
485 if (AuraEffect const* aurEff = m_caster->GetDummyAuraEffect(SPELLFAMILY_DRUID, 1771, 0))
487 AddPct(damage, aurEff->GetAmount());
488 }
489 break;
490 }
492 {
493 // Envenom
494 if (m_spellInfo->SpellFamilyFlags[1] & 0x00000008)
495 {
496 if (Player* player = m_caster->ToPlayer())
497 {
498 // consume from stack dozes not more that have combo-points
499 if (uint32 combo = player->GetComboPoints())
500 {
501 // Lookup for Deadly poison (only attacker applied)
503 {
504 // count consumed deadly poison doses at target
505 bool needConsume = true;
506 uint32 spellId = aurEff->GetId();
507
508 uint32 doses = aurEff->GetBase()->GetStackAmount();
509 if (doses > combo)
510 doses = combo;
511
512 // Master Poisoner
513 Unit::AuraEffectList const& auraList = player->GetAuraEffectsByType(SPELL_AURA_MOD_AURA_DURATION_BY_DISPEL_NOT_STACK);
514 for (Unit::AuraEffectList::const_iterator iter = auraList.begin(); iter != auraList.end(); ++iter)
515 {
516 if ((*iter)->GetSpellInfo()->SpellFamilyName == SPELLFAMILY_ROGUE && (*iter)->GetSpellInfo()->SpellIconID == 1960)
517 {
518 uint32 chance = (*iter)->GetSpellInfo()->Effects[EFFECT_2].CalcValue(m_caster);
519
520 if (chance && roll_chance_i(chance))
521 needConsume = false;
522
523 break;
524 }
525 }
526
527 if (needConsume)
528 for (uint32 i = 0; i < doses; ++i)
530
531 damage *= doses;
532 damage += int32(player->GetTotalAttackPowerValue(BASE_ATTACK) * 0.09f * combo);
533 }
534
535 // Eviscerate and Envenom Bonus Damage (item set effect)
536 if (m_caster->HasAura(37169))
537 damage += combo * 40;
538 }
539 }
540 }
541 // Eviscerate
542 else if (m_spellInfo->SpellFamilyFlags[0] & 0x00020000)
543 {
544 if (m_caster->IsPlayer())
545 {
546 if (uint32 combo = m_caster->ToPlayer()->GetComboPoints())
547 {
549 damage += int32(ap * combo * 0.07f);
550
551 // Eviscerate and Envenom Bonus Damage (item set effect)
552 if (m_caster->HasAura(37169))
553 damage += combo * 40;
554 }
555 }
556 }
557 break;
558 }
560 {
561 //Gore
562 if (m_spellInfo->SpellIconID == 1578)
563 {
564 if (m_caster->HasAura(57627)) // Charge 6 sec post-affect
565 damage *= 2;
566 }
567 // Steady Shot
568 else if (m_spellInfo->SpellFamilyFlags[1] & 0x1)
569 {
570 bool found = false;
571 // check dazed affect
573 for (Unit::AuraEffectList::const_iterator iter = decSpeedList.begin(); iter != decSpeedList.end(); ++iter)
574 {
575 if ((*iter)->GetSpellInfo()->SpellIconID == 15 && (*iter)->GetSpellInfo()->Dispel == 0)
576 {
577 found = true;
578 break;
579 }
580 }
581
583 if (found)
584 damage += m_spellInfo->Effects[EFFECT_1].CalcValue();
585
586 if (Player* caster = m_caster->ToPlayer())
587 {
588 // Add Ammo and Weapon damage plus RAP * 0.1
589 float dmg_min = 0.f;
590 float dmg_max = 0.f;
591 for (uint8 i = 0; i < MAX_ITEM_PROTO_DAMAGES; ++i)
592 {
593 dmg_min += caster->GetWeaponDamageRange(RANGED_ATTACK, MINDAMAGE, i);
594 dmg_max += caster->GetWeaponDamageRange(RANGED_ATTACK, MAXDAMAGE, i);
595 }
596
597 if (dmg_max == 0.0f && dmg_min > dmg_max)
598 {
599 damage += int32(dmg_min);
600 }
601 else
602 {
603 damage += irand(int32(dmg_min), int32(dmg_max));
604 }
605 damage += int32(caster->GetAmmoDPS() * caster->GetAttackTime(RANGED_ATTACK) * 0.001f);
606 }
607 }
608 break;
609 }
611 {
612 // Hammer of the Righteous
613 if (m_spellInfo->SpellFamilyFlags[1] & 0x00040000)
614 {
615 // Add main hand dps * effect[2] amount
616 if (Player* player = m_caster->ToPlayer())
617 {
618 float minTotal = 0.f;
619 float maxTotal = 0.f;
620 for (uint8 i = 0; i < MAX_ITEM_PROTO_DAMAGES; ++i)
621 {
622 float tmpMin, tmpMax;
623 player->CalculateMinMaxDamage(BASE_ATTACK, false, false, tmpMin, tmpMax, i);
624 minTotal += tmpMin;
625 maxTotal += tmpMax;
626 }
627
628 float average = (minTotal + maxTotal) / 2;
631 }
632 break;
633 }
634 // Shield of Righteousness
635 if (m_spellInfo->SpellFamilyFlags[EFFECT_1] & 0x100000)
636 {
637 uint8 level = m_caster->GetLevel();
638 uint32 block_value = m_caster->GetShieldBlockValue(uint32(float(level) * 29.5f), uint32(float(level) * 34.5f));
639 if (m_caster->GetAuraEffect(64882, EFFECT_0))
640 block_value += 225;
641 damage += CalculatePct(block_value, m_spellInfo->Effects[EFFECT_1].CalcValue());
642 break;
643 }
644 break;
645 }
646 }
647
648 if (m_originalCaster /*&& damage > 0 Xinef: this can be increased from 0*/ && apply_direct_bonus)
649 {
650 // Xinef: protection
651 if (damage < 0)
652 damage = 0;
653
656 }
657
658 m_damage += damage;
659 }
660}
@ EFFECT_2
Definition: SharedDefines.h:33
@ POWER_ENERGY
Definition: SharedDefines.h:272
@ SPELLFAMILY_PRIEST
Definition: SharedDefines.h:3534
@ AURA_STATE_CONFLAGRATE
Definition: SharedDefines.h:1306
@ SPELL_ATTR0_CU_SHARE_DAMAGE
Definition: SpellInfo.h:179
@ SPELL_AURA_MOD_AURA_DURATION_BY_DISPEL_NOT_STACK
Definition: SpellAuraDefines.h:309
@ SPELL_AURA_PERIODIC_DAMAGE
Definition: SpellAuraDefines.h:66
@ SPELL_AURA_ADD_FLAT_MODIFIER
Definition: SpellAuraDefines.h:170
@ SPELL_AURA_MOD_DECREASE_SPEED
Definition: SpellAuraDefines.h:96
#define MAX_ITEM_PROTO_DAMAGES
Definition: ItemTemplate.h:613
@ MINDAMAGE
Definition: Unit.h:135
@ MAXDAMAGE
Definition: Unit.h:136
@ FORM_SHADOW
Definition: UnitDefines.h:95
float GetTotalAttackPowerValue(WeaponAttackType attType, Unit *pVictim=nullptr) const
Definition: Unit.cpp:15428
float ApplyEffectModifiers(SpellInfo const *spellProto, uint8 effect_index, float value) const
Definition: Unit.cpp:14829
virtual uint32 GetShieldBlockValue() const =0
void RemoveAuraFromStack(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition: Unit.cpp:4925
uint32 GetAttackTime(WeaponAttackType att) const
Definition: Unit.h:864
AuraEffect * GetDummyAuraEffect(SpellFamilyNames name, uint32 iconId, uint8 effIndex) const
Definition: Unit.h:1358
uint8 GetStackAmount() const
Definition: SpellAuras.h:148

References AddPct(), Unit::ApplyEffectModifiers(), ApplyPct(), AURA_STATE_CONFLAGRATE, BASE_ATTACK, Unit::CalcSpellDuration(), CalculatePct(), Unit::CalculateSpellDamage(), Unit::CastCustomSpell(), Unit::CastSpell(), damage, DOT, EFFECT_0, EFFECT_1, EFFECT_2, SpellValue::EffectBasePoints, effectHandleMode, SpellInfo::Effects, FORM_SHADOW, AuraEffect::GetAmount(), Unit::GetAttackTime(), Unit::GetAuraEffect(), Unit::GetAuraEffectsByType(), AuraEffect::GetBase(), SpellInfo::GetCategory(), Unit::GetComboPoints(), Unit::GetDummyAuraEffect(), Object::GetGUID(), AuraEffect::GetId(), Unit::GetLevel(), Unit::GetOwner(), Unit::GetShapeshiftForm(), Unit::GetShieldBlockValue(), AuraEffect::GetSpellInfo(), Aura::GetStackAmount(), Unit::GetTotalAttackPowerValue(), SpellInfo::HasAttribute(), Unit::HasAura(), Unit::HasAuraState(), SpellInfo::Id, IN_MILLISECONDS, irand(), Unit::IsAlive(), Object::IsCreature(), Unit::IsPet(), Object::IsPlayer(), m_caster, m_damage, m_originalCaster, m_spellInfo, m_spellValue, m_UniqueTargetInfo, MAX_ITEM_PROTO_DAMAGES, MAXDAMAGE, MINDAMAGE, Unit::ModifyPower(), POWER_ENERGY, RANGED_ATTACK, Unit::RemoveAuraFromStack(), Unit::RemoveAurasDueToSpell(), roll_chance_i(), SPELL_ATTR0_CU_SHARE_DAMAGE, SPELL_AURA_ADD_FLAT_MODIFIER, SPELL_AURA_MOD_AURA_DURATION_BY_DISPEL_NOT_STACK, SPELL_AURA_MOD_DECREASE_SPEED, SPELL_AURA_PERIODIC_DAMAGE, SPELL_DIRECT_DAMAGE, SPELL_EFFECT_HANDLE_LAUNCH_TARGET, Unit::SpellDamageBonusDone(), Unit::SpellDamageBonusTaken(), SPELLFAMILY_DRUID, SPELLFAMILY_GENERIC, SPELLFAMILY_HUNTER, SPELLFAMILY_PALADIN, SPELLFAMILY_PRIEST, SPELLFAMILY_ROGUE, SPELLFAMILY_WARLOCK, SPELLFAMILY_WARRIOR, SpellInfo::SpellFamilyFlags, SpellInfo::SpellFamilyName, SpellInfo::SpellIconID, SpellInfo::SpellVisual, SpellInfo::TargetAuraState, Object::ToPlayer(), and unitTarget.

◆ EffectScriptEffect()

void Spell::EffectScriptEffect ( SpellEffIndex  effIndex)
Todo:
: we must implement hunter pet summon at login there (spell 6962)
3795{
3797 return;
3798
3800
3802 {
3804 {
3805 switch (m_spellInfo->Id)
3806 {
3807 // Shadow Flame (All script effects, not just end ones to prevent player from dodging the last triggered spell)
3808 case 22539:
3809 case 22972:
3810 case 22975:
3811 case 22976:
3812 case 22977:
3813 case 22978:
3814 case 22979:
3815 case 22980:
3816 case 22981:
3817 case 22982:
3818 case 22983:
3819 case 22984:
3820 case 22985:
3821 {
3822 if (!unitTarget || !unitTarget->IsAlive())
3823 return;
3824
3825 // Onyxia Scale Cloak
3826 if (unitTarget->HasAura(22683))
3827 return;
3828
3829 // Shadow Flame
3830 m_caster->CastSpell(unitTarget, 22682, true);
3831 return;
3832 }
3833 // Plant Warmaul Ogre Banner
3834 case 32307:
3835 if (Player* caster = m_caster->ToPlayer())
3836 {
3837 caster->RewardPlayerAndGroupAtEvent(18388, unitTarget);
3838 if (Creature* target = unitTarget->ToCreature())
3839 {
3840 target->setDeathState(DeathState::Corpse);
3841 target->RemoveCorpse();
3842 }
3843 }
3844 break;
3845 // SOTA defender teleport
3846 case 54640:
3847 {
3848 if (Player* player = unitTarget->ToPlayer())
3849 if (player->GetBattleground() && player->GetBattleground()->GetBgTypeID(true) == BATTLEGROUND_SA)
3850 {
3851 if (GameObject* dportal = player->FindNearestGameObject(192819, 10.0f))
3852 {
3853 BattlegroundSA* bg = ((BattlegroundSA*)player->GetBattleground());
3854 bg->DefendersPortalTeleport(dportal, player);
3855 }
3856 }
3857 return;
3858 }
3859 /*// Mug Transformation
3860 case 41931:
3861 {
3862 if (!m_caster->IsPlayer())
3863 return;
3864
3865 uint8 bag = 19;
3866 uint8 slot = 0;
3867 Item* item = nullptr;
3868
3869 while (bag) // 256 = 0 due to var type
3870 {
3871 item = m_caster->ToPlayer()->GetItemByPos(bag, slot);
3872 if (item && item->GetEntry() == 38587)
3873 break;
3874
3875 ++slot;
3876 if (slot == 39)
3877 {
3878 slot = 0;
3879 ++bag;
3880 }
3881 }
3882 if (bag)
3883 {
3884 if (m_caster->ToPlayer()->GetItemByPos(bag, slot)->GetCount() == 1) m_caster->ToPlayer()->RemoveItem(bag, slot, true);
3885 else m_caster->ToPlayer()->GetItemByPos(bag, slot)->SetCount(m_caster->ToPlayer()->GetItemByPos(bag, slot)->GetCount()-1);
3886 // Spell 42518 (Braufest - Gratisprobe des Braufest herstellen)
3887 m_caster->CastSpell(m_caster, 42518, true);
3888 return;
3889 }
3890 break;
3891 }*/
3892 // Roll Dice - Decahedral Dwarven Dice
3893 case 47770:
3894 {
3895 char buf[128];
3896 const char* gender = "his";
3897 if (m_caster->getGender() > 0)
3898 gender = "her";
3899 snprintf(buf, sizeof(buf), "%s rubs %s [Decahedral Dwarven Dice] between %s hands and rolls. One %u and one %u.", m_caster->GetName().c_str(), gender, gender, urand(1, 10), urand(1, 10));
3900 m_caster->TextEmote(buf);
3901 break;
3902 }
3903 case 52173: // Coyote Spirit Despawn
3904 case 60243: // Blood Parrot Despawn
3907 return;
3908 case 57347: // Retrieving (Wintergrasp RP-GG pickup spell)
3909 {
3911 return;
3912
3914
3915 return;
3916 }
3917 case 57349: // Drop RP-GG (Wintergrasp RP-GG at death drop spell)
3918 {
3919 if (!m_caster->IsPlayer())
3920 return;
3921
3922 // Delete item from inventory at death
3924
3925 return;
3926 }
3927 case 58418: // Portal to Orgrimmar
3928 case 58420: // Portal to Stormwind
3929 {
3930 if (!unitTarget || !unitTarget->IsPlayer() || effIndex != 0)
3931 return;
3932
3933 uint32 spellID = m_spellInfo->Effects[EFFECT_0].CalcValue();
3934 uint32 questID = m_spellInfo->Effects[EFFECT_1].CalcValue();
3935
3937 unitTarget->CastSpell(unitTarget, spellID, true);
3938
3939 return;
3940 }
3941 // Stoneclaw Totem
3942 case 55328: // Rank 1
3943 case 55329: // Rank 2
3944 case 55330: // Rank 3
3945 case 55332: // Rank 4
3946 case 55333: // Rank 5
3947 case 55335: // Rank 6
3948 case 55278: // Rank 7
3949 case 58589: // Rank 8
3950 case 58590: // Rank 9
3951 case 58591: // Rank 10
3952 {
3953 int32 basepoints0 = damage;
3954 // Cast Absorb on totems
3955 for (uint8 slot = SUMMON_SLOT_TOTEM; slot < MAX_TOTEM_SLOT; ++slot)
3956 {
3957 if (!unitTarget->m_SummonSlot[slot])
3958 continue;
3959
3961 if (totem && totem->IsTotem())
3962 {
3963 m_caster->CastCustomSpell(totem, 55277, &basepoints0, nullptr, nullptr, true);
3964 }
3965 }
3966 // Glyph of Stoneclaw Totem
3967 if (AuraEffect* aur = unitTarget->GetAuraEffect(63298, 0))
3968 {
3969 basepoints0 *= aur->GetAmount();
3970 m_caster->CastCustomSpell(unitTarget, 55277, &basepoints0, nullptr, nullptr, true);
3971 }
3972 break;
3973 }
3974 case 61263: // for item Intravenous Healing Potion (44698)
3975 {
3976 if (!m_caster || !unitTarget)
3977 return;
3978
3979 m_caster->CastSpell(m_caster, 61267, true);
3980 m_caster->CastSpell(m_caster, 61268, true);
3981 return;
3982 }
3983 }
3984 break;
3985 }
3986 case SPELLFAMILY_ROGUE:
3987 {
3988 switch (m_spellInfo->Id)
3989 {
3990 // Master of Subtlety
3991 case 31666:
3992 {
3993 if (!unitTarget)
3994 return;
3995
3996 Aura* mos = unitTarget->GetAura(31665);
3997 if (mos)
3998 {
3999 mos->SetMaxDuration(6000);
4000 mos->SetDuration(6000, true);
4001 }
4002
4003 break;
4004 }
4005 // Overkill
4006 case 58428:
4007 {
4008 if (!unitTarget)
4009 return;
4010
4011 Aura* overkill = unitTarget->GetAura(58427);
4012 if (overkill)
4013 {
4014 overkill->SetMaxDuration(20000);
4015 overkill->SetDuration(20000, true);
4016 }
4017
4018 break;
4019 }
4020 }
4021 break;
4022 }
4023 }
4024
4025 // normal DB scripted effect
4026 LOG_DEBUG("spells.aura", "Spell ScriptStart spellid {} in EffectScriptEffect({})", m_spellInfo->Id, effIndex);
4028}
@ BATTLEGROUND_SA
Definition: SharedDefines.h:3489
@ QUEST_STATUS_COMPLETE
Definition: QuestDef.h:101
Class for manage Strand of Ancient battleground.
Definition: BattlegroundSA.h:456
void DefendersPortalTeleport(GameObject *portal, Player *plr)
Definition: BattlegroundSA.cpp:585
void DespawnOrUnsummon(Milliseconds msTimeToDespawn, Seconds forcedRespawnTimer)
Definition: Creature.cpp:2178
virtual void UnSummon(uint32 msTime=0)
Definition: TemporarySummon.cpp:282
GameObject * FindNearestGameObject(uint32 entry, float range, bool onlySpawned=false) const
Definition: Object.cpp:2466
std::string const & GetName() const
Definition: Object.h:463
uint8 getGender() const
Definition: Unit.h:805
bool IsSummon() const
Definition: Unit.h:751
virtual void TextEmote(std::string_view text, WorldObject const *target=nullptr, bool isBossEmote=false)
Definition: Unit.cpp:21149

References BATTLEGROUND_SA, Unit::CastCustomSpell(), Unit::CastSpell(), damage, BattlegroundSA::DefendersPortalTeleport(), Creature::DespawnOrUnsummon(), Player::DestroyItemCount(), EFFECT_0, EFFECT_1, effectHandleMode, SpellInfo::Effects, WorldObject::FindNearestGameObject(), Unit::GetAura(), Unit::GetAuraEffect(), Map::GetCreature(), Unit::getGender(), WorldObject::GetMap(), WorldObject::GetName(), Player::GetQuestStatus(), Unit::HasAura(), SpellInfo::Id, Unit::IsAlive(), Object::IsCreature(), Object::IsPlayer(), Unit::IsSummon(), Unit::IsTotem(), LOG_DEBUG, m_caster, m_spellInfo, Unit::m_SummonSlot, MAX_TOTEM_SLOT, QUEST_STATUS_COMPLETE, Map::ScriptsStart(), Aura::SetDuration(), Aura::SetMaxDuration(), SPELL_EFFECT_HANDLE_HIT_TARGET, SPELLFAMILY_GENERIC, SPELLFAMILY_ROGUE, SpellInfo::SpellFamilyName, sSpellScripts, SUMMON_SLOT_TOTEM, Unit::TextEmote(), Object::ToCreature(), Object::ToPlayer(), Unit::ToTempSummon(), unitTarget, TempSummon::UnSummon(), and urand().

◆ EffectSelfResurrect()

void Spell::EffectSelfResurrect ( SpellEffIndex  effIndex)
4857{
4859 return;
4860
4861 if (!m_caster || m_caster->IsAlive())
4862 return;
4863 if (!m_caster->IsPlayer())
4864 return;
4865 if (!m_caster->IsInWorld())
4866 return;
4867
4868 uint32 health = 0;
4869 uint32 mana = 0;
4870
4871 // flat case
4872 if (damage < 0)
4873 {
4874 health = uint32(-damage);
4875 mana = m_spellInfo->Effects[effIndex].MiscValue;
4876 }
4877 // percent case
4878 else
4879 {
4883 }
4884
4885 Player* player = m_caster->ToPlayer();
4886 player->ResurrectPlayer(0.0f);
4887
4888 player->SetHealth(health);
4889 player->SetPower(POWER_MANA, mana);
4890 player->SetPower(POWER_RAGE, 0);
4891 player->SetPower(POWER_ENERGY, player->GetMaxPower(POWER_ENERGY));
4892
4893 player->SpawnCorpseBones();
4894}
@ POWER_RAGE
Definition: SharedDefines.h:270
void SpawnCorpseBones(bool triggerSave=true)
Definition: Player.cpp:4705
void ResurrectPlayer(float restore_percent, bool applySickness=false)
Definition: Player.cpp:4492
void SetPower(Powers power, uint32 val, bool withPowerUpdate=true, bool fromRegenerate=false)
Definition: Unit.cpp:15566

References CalculatePct(), Unit::CountPctFromMaxHealth(), damage, effectHandleMode, SpellInfo::Effects, Unit::GetMaxPower(), Unit::IsAlive(), Object::IsInWorld(), Object::IsPlayer(), m_caster, m_spellInfo, POWER_ENERGY, POWER_MANA, POWER_RAGE, Player::ResurrectPlayer(), Unit::SetHealth(), Unit::SetPower(), Player::SpawnCorpseBones(), SPELL_EFFECT_HANDLE_HIT, and Object::ToPlayer().

◆ EffectSendEvent()

void Spell::EffectSendEvent ( SpellEffIndex  effIndex)
Todo:
: there should be a possibility to pass dest target to event script
1390{
1391 // we do not handle a flag dropping or clicking on flag in battleground by sendevent system
1394 return;
1395
1396 WorldObject* target = nullptr;
1397
1398 // call events for object target if present
1400 {
1401 if (unitTarget)
1402 target = unitTarget;
1403 else if (gameObjTarget)
1404 target = gameObjTarget;
1405 }
1406 else // if (effectHandleMode == SPELL_EFFECT_HANDLE_HIT)
1407 {
1408 // let's prevent executing effect handler twice in case when spell effect is capable of targeting an object
1409 // this check was requested by scripters, but it has some downsides:
1410 // now it's impossible to script (using sEventScripts) a cast which misses all targets
1411 // or to have an ability to script the moment spell hits dest (in a case when there are object targets present)
1412 if (m_spellInfo->Effects[effIndex].GetProvidedTargetMask() & (TARGET_FLAG_UNIT_MASK | TARGET_FLAG_GAMEOBJECT_MASK))
1413 return;
1414 // some spells have no target entries in dbc and they use focus target
1415 if (focusObject)
1416 target = focusObject;
1418 }
1419
1420 LOG_DEBUG("spells.aura", "Spell ScriptStart {} for spellid {} in EffectSendEvent ", m_spellInfo->Effects[effIndex].MiscValue, m_spellInfo->Id);
1421
1422 if (ZoneScript* zoneScript = m_caster->GetZoneScript())
1423 zoneScript->ProcessEvent(target, m_spellInfo->Effects[effIndex].MiscValue);
1424 else if (InstanceScript* instanceScript = m_caster->GetInstanceScript()) // needed in case Player is the caster
1425 instanceScript->ProcessEvent(target, m_spellInfo->Effects[effIndex].MiscValue);
1426
1427 m_caster->GetMap()->ScriptsStart(sEventScripts, m_spellInfo->Effects[effIndex].MiscValue, m_caster, target);
1428}
ScriptMapMap sEventScripts
Definition: ObjectMgr.cpp:60
@ TARGET_FLAG_UNIT_MASK
Definition: SpellInfo.h:68
@ TARGET_FLAG_GAMEOBJECT_MASK
Definition: SpellInfo.h:70
Definition: Object.h:410
ZoneScript * GetZoneScript() const
Definition: Object.h:542
Definition: ZoneScript.h:26

References effectHandleMode, SpellInfo::Effects, focusObject, gameObjTarget, WorldObject::GetInstanceScript(), WorldObject::GetMap(), WorldObject::GetZoneScript(), SpellInfo::Id, LOG_DEBUG, m_caster, m_spellInfo, Map::ScriptsStart(), sEventScripts, SPELL_EFFECT_HANDLE_HIT, SPELL_EFFECT_HANDLE_HIT_TARGET, TARGET_FLAG_GAMEOBJECT_MASK, TARGET_FLAG_UNIT_MASK, and unitTarget.

◆ EffectSendTaxi()

void Spell::EffectSendTaxi ( SpellEffIndex  effIndex)
5116{
5118 return;
5119
5120 if (!unitTarget)
5121 return;
5122
5123 if (Player* player = unitTarget->ToPlayer())
5124 {
5125 player->ActivateTaxiPathTo(m_spellInfo->Effects[effIndex].MiscValue, m_spellInfo->Id);
5126 }
5127}

References effectHandleMode, SpellInfo::Effects, SpellInfo::Id, m_spellInfo, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectSkill()

void Spell::EffectSkill ( SpellEffIndex  effIndex)
5549{
5551 return;
5552
5553 LOG_DEBUG("spells.aura", "WORLD: SkillEFFECT");
5554}

References effectHandleMode, LOG_DEBUG, and SPELL_EFFECT_HANDLE_HIT.

◆ EffectSkinning()

void Spell::EffectSkinning ( SpellEffIndex  effIndex)
4897{
4899 return;
4900
4901 if (!unitTarget->IsCreature())
4902 return;
4903 if (!m_caster->IsPlayer())
4904 return;
4905
4906 Creature* creature = unitTarget->ToCreature();
4907 int32 targetLevel = creature->GetLevel();
4908
4909 uint32 skill = creature->GetCreatureTemplate()->GetRequiredLootSkill();
4910
4914
4915 int32 reqValue = targetLevel < 10 ? 0 : targetLevel < 20 ? (targetLevel - 10) * 10 : targetLevel * 5;
4916
4917 int32 skillValue = m_caster->ToPlayer()->GetPureSkillValue(skill);
4918
4919 // Double chances for elites
4920 m_caster->ToPlayer()->UpdateGatherSkill(skill, skillValue, reqValue, creature->isElite() ? 2 : 1);
4921}
@ UNIT_DYNFLAG_LOOTABLE
Definition: SharedDefines.h:3121
bool isElite() const
Definition: Creature.h:111
virtual void SetDynamicFlag(uint32 flag)
Definition: Object.h:123

References effectHandleMode, Creature::GetCreatureTemplate(), Object::GetGUID(), Unit::GetLevel(), Player::GetPureSkillValue(), CreatureTemplate::GetRequiredLootSkill(), Object::IsCreature(), Creature::isElite(), Object::IsPlayer(), LOOT_SKINNING, m_caster, Unit::RemoveUnitFlag(), Player::SendLoot(), Object::SetDynamicFlag(), SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToCreature(), Object::ToPlayer(), UNIT_DYNFLAG_LOOTABLE, UNIT_FLAG_SKINNABLE, unitTarget, and Player::UpdateGatherSkill().

◆ EffectSkinPlayerCorpse()

void Spell::EffectSkinPlayerCorpse ( SpellEffIndex  effIndex)
5580{
5582 return;
5583
5584 LOG_DEBUG("spells.aura", "Effect: SkinPlayerCorpse");
5585 if ((!m_caster->IsPlayer()) || (!unitTarget->IsPlayer()) || (unitTarget->IsAlive()))
5586 return;
5587
5589}
void RemovedInsignia(Player *looterPlr)
Definition: Player.cpp:7767

References effectHandleMode, Unit::IsAlive(), Object::IsPlayer(), LOG_DEBUG, m_caster, Player::RemovedInsignia(), SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectSpecCount()

void Spell::EffectSpecCount ( SpellEffIndex  effIndex)
6135{
6137 return;
6138
6139 if (!unitTarget)
6140 return;
6141
6142 if (Player* player = unitTarget->ToPlayer())
6143 {
6144 player->UpdateSpecCount(damage);
6145 }
6146}

References damage, effectHandleMode, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectSpiritHeal()

void Spell::EffectSpiritHeal ( SpellEffIndex  effIndex)
5561{
5563 return;
5564
5565 /*
5566 if (!unitTarget->IsPlayer())
5567 return;
5568 if (!unitTarget->IsInWorld())
5569 return;
5570
5571 //m_spellInfo->Effects[i].BasePoints; == 99 (percent?)
5572 //unitTarget->ToPlayer()->setResurrect(m_caster->GetGUID(), unitTarget->GetPositionX(), unitTarget->GetPositionY(), unitTarget->GetPositionZ(), unitTarget->GetMaxHealth(), unitTarget->GetMaxPower(POWER_MANA));
5573 unitTarget->ToPlayer()->ResurrectPlayer(1.0f);
5574 unitTarget->ToPlayer()->SpawnCorpseBones();
5575 */
5576}

References effectHandleMode, and SPELL_EFFECT_HANDLE_HIT_TARGET.

◆ EffectStealBeneficialBuff()

void Spell::EffectStealBeneficialBuff ( SpellEffIndex  effIndex)
5592{
5594 return;
5595
5596 LOG_DEBUG("spells.aura", "Effect: StealBeneficialBuff");
5597
5598 if (!unitTarget || unitTarget == m_caster) // can't steal from self
5599 return;
5600
5601 DispelChargesList steal_list;
5602
5603 // Create dispel mask by dispel type
5604 uint32 dispelMask = SpellInfo::GetDispelMask(DispelType(m_spellInfo->Effects[effIndex].MiscValue));
5605 Unit::AuraMap const& auras = unitTarget->GetOwnedAuras();
5606 for (Unit::AuraMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
5607 {
5608 Aura* aura = itr->second;
5610 if (!aurApp)
5611 continue;
5612
5613 if ((aura->GetSpellInfo()->GetDispelMask()) & dispelMask)
5614 {
5615 // Need check for passive? this
5616 if (!aurApp->IsPositive() || aura->IsPassive() || aura->GetSpellInfo()->HasAttribute(SPELL_ATTR4_CANNOT_BE_STOLEN))
5617 continue;
5618
5619 // The charges / stack amounts don't count towards the total number of auras that can be dispelled.
5620 // Ie: A dispel on a target with 5 stacks of Winters Chill and a Polymorph has 1 / (1 + 1) -> 50% chance to dispell
5621 // Polymorph instead of 1 / (5 + 1) -> 16%.
5622 bool dispel_charges = aura->GetSpellInfo()->HasAttribute(SPELL_ATTR7_DISPEL_REMOVES_CHARGES);
5623 uint8 charges = dispel_charges ? aura->GetCharges() : aura->GetStackAmount();
5624 if (charges > 0)
5625 steal_list.push_back(std::make_pair(aura, charges));
5626 }
5627 }
5628
5629 if (steal_list.empty())
5630 return;
5631
5632 // Ok if exist some buffs for dispel try dispel it
5633 uint32 failCount = 0;
5634 DispelList success_list;
5635 WorldPacket dataFail(SMSG_DISPEL_FAILED, 8 + 8 + 4 + 4 + damage * 4);
5636 // dispel N = damage buffs (or while exist buffs for dispel)
5637 for (int32 count = 0; count < damage && !steal_list.empty();)
5638 {
5639 // Random select buff for dispel
5640 DispelChargesList::iterator itr = steal_list.begin();
5641 std::advance(itr, urand(0, steal_list.size() - 1));
5642
5643 int32 chance = itr->first->CalcDispelChance(unitTarget, !unitTarget->IsFriendlyTo(m_caster));
5644 // 2.4.3 Patch Notes: "Dispel effects will no longer attempt to remove effects that have 100% dispel resistance."
5645 if (!chance)
5646 {
5647 steal_list.erase(itr);
5648 continue;
5649 }
5650 else
5651 {
5652 if (roll_chance_i(chance))
5653 {
5654 success_list.push_back(std::make_pair(itr->first->GetId(), itr->first->GetCasterGUID()));
5655 --itr->second;
5656 if (itr->second <= 0)
5657 steal_list.erase(itr);
5658 }
5659 else
5660 {
5661 if (!failCount)
5662 {
5663 // Failed to dispell
5664 dataFail << m_caster->GetGUID(); // Caster GUID
5665 dataFail << unitTarget->GetGUID(); // Victim GUID
5666 dataFail << uint32(m_spellInfo->Id); // dispel spell id
5667 }
5668 ++failCount;
5669 dataFail << uint32(itr->first->GetId()); // Spell Id
5670 }
5671 ++count;
5672 }
5673 }
5674
5675 if (failCount)
5676 m_caster->SendMessageToSet(&dataFail, true);
5677
5678 if (success_list.empty())
5679 return;
5680
5681 WorldPacket dataSuccess(SMSG_SPELLSTEALLOG, 8 + 8 + 4 + 1 + 4 + damage * 5);
5682 dataSuccess << unitTarget->GetPackGUID(); // Victim GUID
5683 dataSuccess << m_caster->GetPackGUID(); // Caster GUID
5684 dataSuccess << uint32(m_spellInfo->Id); // dispel spell id
5685 dataSuccess << uint8(0); // not used
5686 dataSuccess << uint32(success_list.size()); // count
5687 for (DispelList::iterator itr = success_list.begin(); itr != success_list.end(); ++itr)
5688 {
5689 dataSuccess << uint32(itr->first); // Spell Id
5690 dataSuccess << uint8(0); // 0 - steals !=0 transfers
5691 unitTarget->RemoveAurasDueToSpellBySteal(itr->first, itr->second, m_caster);
5692 }
5693 m_caster->SendMessageToSet(&dataSuccess, true);
5694}
@ SPELL_ATTR7_DISPEL_REMOVES_CHARGES
Definition: SharedDefines.h:651
@ SPELL_ATTR4_CANNOT_BE_STOLEN
Definition: SharedDefines.h:536
std::list< std::pair< uint32, ObjectGuid > > DispelList
Definition: SpellEffects.cpp:2565
@ SMSG_SPELLSTEALLOG
Definition: Opcodes.h:849
void RemoveAurasDueToSpellBySteal(uint32 spellId, ObjectGuid casterGUID, Unit *stealer)
Definition: Unit.cpp:5006
bool IsPositive() const
Definition: SpellAuras.h:68
uint8 GetCharges() const
Definition: SpellAuras.h:141
bool IsPassive() const
Definition: SpellAuras.cpp:1082

References damage, effectHandleMode, SpellInfo::Effects, Aura::GetApplicationOfTarget(), Aura::GetCharges(), SpellInfo::GetDispelMask(), Object::GetGUID(), Unit::GetOwnedAuras(), Object::GetPackGUID(), Aura::GetSpellInfo(), Aura::GetStackAmount(), SpellInfo::HasAttribute(), SpellInfo::Id, Unit::IsFriendlyTo(), Aura::IsPassive(), AuraApplication::IsPositive(), LOG_DEBUG, m_caster, m_spellInfo, Unit::RemoveAurasDueToSpellBySteal(), roll_chance_i(), WorldObject::SendMessageToSet(), SMSG_DISPEL_FAILED, SMSG_SPELLSTEALLOG, SPELL_ATTR4_CANNOT_BE_STOLEN, SPELL_ATTR7_DISPEL_REMOVES_CHARGES, SPELL_EFFECT_HANDLE_HIT_TARGET, unitTarget, and urand().

◆ EffectStuck()

void Spell::EffectStuck ( SpellEffIndex  effIndex)
4188{
4190 return;
4191
4192 if (!m_caster->IsPlayer())
4193 return;
4194
4195 Player* target = m_caster->ToPlayer();
4196 if (target->IsInFlight())
4197 return;
4198
4199 // xinef: if player is dead - teleport to graveyard
4200 if (!target->IsAlive())
4201 {
4202 if (target->HasPreventResurectionAura())
4203 return;
4204
4205 // xinef: player is in corpse
4206 if (!target->HasPlayerFlag(PLAYER_FLAGS_GHOST))
4207 target->BuildPlayerRepop();
4208 target->RepopAtGraveyard();
4209 return;
4210 }
4211
4212 // xinef: no hearthstone in bag or on cooldown
4213 Item* hearthStone = target->GetItemByEntry(6948);
4214 if (!hearthStone || target->HasSpellCooldown(8690))
4215 {
4216 float o = rand_norm() * 2 * M_PI;
4217 Position pos = *target;
4218 target->MovePositionToFirstCollision(pos, 5.0f, o);
4219 target->NearTeleportTo(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), target->GetOrientation());
4220 return;
4221 }
4222
4223 // xinef: we have hearthstone not on cooldown, just use it
4225}
double rand_norm()
Definition: Random.cpp:77
@ PLAYER_FLAGS_GHOST
Definition: Player.h:483
void MovePositionToFirstCollision(Position &pos, float dist, float angle)
Definition: Object.cpp:2871
void RepopAtGraveyard()
Definition: Player.cpp:4937
void BuildPlayerRepop()
Definition: Player.cpp:4443
bool HasPreventResurectionAura() const
Definition: Unit.h:1668

References Player::BuildPlayerRepop(), Unit::CastSpell(), effectHandleMode, Player::GetItemByEntry(), Position::GetOrientation(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), Player::HasPlayerFlag(), Unit::HasPreventResurectionAura(), Player::HasSpellCooldown(), Unit::IsAlive(), Unit::IsInFlight(), Object::IsPlayer(), m_caster, WorldObject::MovePositionToFirstCollision(), Unit::NearTeleportTo(), PLAYER_FLAGS_GHOST, rand_norm(), Player::RepopAtGraveyard(), SPELL_EFFECT_HANDLE_HIT, Object::ToPlayer(), TRIGGERED_FULL_MASK, and TRIGGERED_IGNORE_SPELL_AND_CATEGORY_CD.

◆ EffectSummonChangeItem()

void Spell::EffectSummonChangeItem ( SpellEffIndex  effIndex)
2199{
2201 return;
2202
2203 if (!m_caster->IsPlayer())
2204 return;
2205
2206 Player* player = m_caster->ToPlayer();
2207
2208 // applied only to using item
2209 if (!m_CastItem)
2210 return;
2211
2212 // ... only to item in own inventory/bank/equip_slot
2213 if (m_CastItem->GetOwnerGUID() != player->GetGUID())
2214 return;
2215
2216 uint32 newitemid = m_spellInfo->Effects[effIndex].ItemType;
2217 if (!newitemid)
2218 return;
2219
2220 uint16 pos = m_CastItem->GetPos();
2221
2222 Item* pNewItem = Item::CreateItem(newitemid, 1, player);
2223 if (!pNewItem)
2224 return;
2225
2226 // Client-side enchantment durations update
2228
2232
2234 {
2236 player->DurabilityLoss(pNewItem, lossPercent);
2237 }
2238
2239 if (player->IsInventoryPos(pos))
2240 {
2241 ItemPosCountVec dest;
2242 InventoryResult msg = player->CanStoreItem(m_CastItem->GetBagSlot(), m_CastItem->GetSlot(), dest, pNewItem, true);
2243 if (msg == EQUIP_ERR_OK)
2244 {
2245 player->DestroyItem(m_CastItem->GetBagSlot(), m_CastItem->GetSlot(), true);
2246
2247 // prevent crash at access and unexpected charges counting with item update queue corrupt
2249 m_targets.SetItemTarget(nullptr);
2250
2251 m_CastItem = nullptr;
2253
2254 player->StoreItem(dest, pNewItem, true);
2255 player->ItemAddedQuestCheck(pNewItem->GetEntry(), 1);
2256 return;
2257 }
2258 }
2259 else if (player->IsBankPos(pos))
2260 {
2261 ItemPosCountVec dest;
2262 uint8 msg = player->CanBankItem(m_CastItem->GetBagSlot(), m_CastItem->GetSlot(), dest, pNewItem, true);
2263 if (msg == EQUIP_ERR_OK)
2264 {
2265 player->DestroyItem(m_CastItem->GetBagSlot(), m_CastItem->GetSlot(), true);
2266
2267 // prevent crash at access and unexpected charges counting with item update queue corrupt
2269 m_targets.SetItemTarget(nullptr);
2270
2271 m_CastItem = nullptr;
2273
2274 player->BankItem(dest, pNewItem, true);
2275 return;
2276 }
2277 }
2278 else if (player->IsEquipmentPos(pos))
2279 {
2280 uint16 dest;
2281
2282 player->DestroyItem(m_CastItem->GetBagSlot(), m_CastItem->GetSlot(), true);
2283
2284 uint8 msg = player->CanEquipItem(m_CastItem->GetSlot(), dest, pNewItem, true);
2285
2286 if (msg == EQUIP_ERR_OK || msg == EQUIP_ERR_CANT_DO_RIGHT_NOW)
2287 {
2289
2290 // prevent crash at access and unexpected charges counting with item update queue corrupt
2292 m_targets.SetItemTarget(nullptr);
2293
2294 m_CastItem = nullptr;
2296
2297 player->EquipItem(dest, pNewItem, true);
2298 player->AutoUnequipOffhandIfNeed();
2299 return;
2300 }
2301 }
2302
2303 // fail
2304 delete pNewItem;
2305}
@ EQUIP_ERR_CANT_DO_RIGHT_NOW
Definition: Item.h:86
@ ITEM_FIELD_DURABILITY
Definition: UpdateFields.h:69
@ ITEM_FIELD_MAXDURABILITY
Definition: UpdateFields.h:70
uint8 GetSlot() const
Definition: Item.h:281
static Item * CreateItem(uint32 item, uint32 count, Player const *player=nullptr, bool clone=false, uint32 randomPropertyId=0)
Definition: Item.cpp:1087
uint32 GetEnchantmentDuration(EnchantmentSlot slot) const
Definition: Item.h:305
uint16 GetPos() const
Definition: Item.h:285
uint32 GetEnchantmentCharges(EnchantmentSlot slot) const
Definition: Item.h:306
uint8 GetBagSlot() const
Definition: Item.cpp:784
void Clear()
Definition: ObjectGuid.h:138
static bool IsEquipmentPos(uint16 pos)
Definition: Player.h:1275
InventoryResult CanEquipItem(uint8 slot, uint16 &dest, Item *pItem, bool swap, bool not_loading=true) const
Definition: PlayerStorage.cpp:1805
Item * BankItem(ItemPosCountVec const &dest, Item *pItem, bool update)
Definition: Player.h:1344
InventoryResult CanStoreItem(uint8 bag, uint8 slot, ItemPosCountVec &dest, Item *pItem, bool swap=false) const
Definition: Player.h:1295
void UpdateEnchantmentDurations()
Definition: PlayerStorage.cpp:4735
Item * StoreItem(ItemPosCountVec const &pos, Item *pItem, bool update)
Definition: PlayerStorage.cpp:2574
void DestroyItem(uint8 bag, uint8 slot, bool update)
Definition: PlayerStorage.cpp:3023
static bool IsInventoryPos(uint16 pos)
Definition: Player.h:1273
void AutoUnequipOffhandIfNeed(bool force=false)
Definition: Player.cpp:12495
Item * EquipItem(uint16 pos, Item *pItem, bool update)
Definition: PlayerStorage.cpp:2727
InventoryResult CanBankItem(uint8 bag, uint8 slot, ItemPosCountVec &dest, Item *pItem, bool swap, bool not_loading=true) const
Definition: PlayerStorage.cpp:2032
void ItemAddedQuestCheck(uint32 entry, uint32 count)
Definition: PlayerQuest.cpp:1834
static bool IsBankPos(uint16 pos)
Definition: Player.h:1278

References Player::AutoUnequipOffhandIfNeed(), Player::BankItem(), Player::CanBankItem(), Player::CanEquipItem(), Player::CanStoreItem(), ObjectGuid::Clear(), Item::CreateItem(), Player::DestroyItem(), Player::DurabilityLoss(), effectHandleMode, SpellInfo::Effects, EQUIP_ERR_CANT_DO_RIGHT_NOW, EQUIP_ERR_OK, Player::EquipItem(), EQUIPMENT_SLOT_MAINHAND, Item::GetBagSlot(), Item::GetEnchantmentCharges(), Item::GetEnchantmentDuration(), Item::GetEnchantmentId(), Object::GetEntry(), Object::GetGUID(), SpellCastTargets::GetItemTarget(), Item::GetOwnerGUID(), Item::GetPos(), Item::GetSlot(), Object::GetUInt32Value(), Player::IsBankPos(), Player::IsEquipmentPos(), Player::IsInventoryPos(), Object::IsPlayer(), ITEM_FIELD_DURABILITY, ITEM_FIELD_MAXDURABILITY, Player::ItemAddedQuestCheck(), m_caster, m_CastItem, m_castItemGUID, m_spellInfo, m_targets, PERM_ENCHANTMENT_SLOT, Item::SetEnchantment(), SpellCastTargets::SetItemTarget(), SPELL_EFFECT_HANDLE_HIT, Player::StoreItem(), TEMP_ENCHANTMENT_SLOT, Object::ToPlayer(), and Player::UpdateEnchantmentDurations().

◆ EffectSummonCritter()

void Spell::EffectSummonCritter ( SpellEffIndex  effIndex)

◆ EffectSummonObject()

void Spell::EffectSummonObject ( SpellEffIndex  effIndex)
4575{
4577 return;
4578
4579 uint32 gameobjectId = m_spellInfo->Effects[effIndex].MiscValue;
4580
4581 uint8 slot = 0;
4582 switch (m_spellInfo->Effects[effIndex].Effect)
4583 {
4585 slot = 0;
4586 break;
4588 slot = 1;
4589 break;
4591 slot = 2;
4592 break;
4594 slot = 3;
4595 break;
4596 default:
4597 return;
4598 }
4599
4600 if (m_caster)
4601 {
4602 ObjectGuid guid = m_caster->m_ObjectSlot[slot];
4603 if (guid)
4604 {
4605 if (GameObject* gameObject = m_caster->GetMap()->GetGameObject(guid))
4606 {
4607 // Recast case - null spell id to make auras not be removed on object remove from world
4608 if (m_spellInfo->Id == gameObject->GetSpellId())
4609 gameObject->SetSpellId(0);
4610 m_caster->RemoveGameObject(gameObject, true);
4611 }
4612 m_caster->m_ObjectSlot[slot].Clear();
4613 }
4614 }
4615
4616 GameObject* pGameObj = sObjectMgr->IsGameObjectStaticTransport(gameobjectId) ? new StaticTransport() : new GameObject();
4617
4618 float x, y, z;
4619 // If dest location if present
4620 if (m_targets.HasDst())
4621 destTarget->GetPosition(x, y, z);
4622 // Summon in random point all other units if location present
4623 else
4625
4626 Map* map = m_caster->GetMap();
4627 if (!pGameObj->Create(map->GenerateLowGuid<HighGuid::GameObject>(), gameobjectId, map, m_caster->GetPhaseMask(), x, y, z, m_caster->GetOrientation(), G3D::Quat(), 0, GO_STATE_READY))
4628 {
4629 delete pGameObj;
4630 return;
4631 }
4632
4633 //pGameObj->SetUInt32Value(GAMEOBJECT_LEVEL, m_caster->GetLevel());
4634 int32 duration = m_spellInfo->GetDuration();
4635 pGameObj->SetRespawnTime(duration > 0 ? duration / IN_MILLISECONDS : 0);
4636 pGameObj->SetSpellId(m_spellInfo->Id);
4637 m_caster->AddGameObject(pGameObj);
4638
4639 ExecuteLogEffectSummonObject(effIndex, pGameObj);
4640
4641 map->AddToMap(pGameObj, true);
4642
4643 m_caster->m_ObjectSlot[slot] = pGameObj->GetGUID();
4644}
@ SPELL_EFFECT_SUMMON_OBJECT_SLOT4
Definition: SharedDefines.h:885
@ SPELL_EFFECT_SUMMON_OBJECT_SLOT1
Definition: SharedDefines.h:882
@ SPELL_EFFECT_SUMMON_OBJECT_SLOT3
Definition: SharedDefines.h:884
@ SPELL_EFFECT_SUMMON_OBJECT_SLOT2
Definition: SharedDefines.h:883
#define DEFAULT_WORLD_OBJECT_SIZE
Definition: ObjectDefines.h:45
ObjectGuid m_ObjectSlot[MAX_GAMEOBJECT_SLOT]
Definition: Unit.h:1945

References Unit::AddGameObject(), Map::AddToMap(), ObjectGuid::Clear(), GameObject::Create(), DEFAULT_WORLD_OBJECT_SIZE, destTarget, effectHandleMode, SpellInfo::Effects, ExecuteLogEffectSummonObject(), Map::GenerateLowGuid(), WorldObject::GetClosePoint(), SpellInfo::GetDuration(), Map::GetGameObject(), Object::GetGUID(), WorldObject::GetMap(), Position::GetOrientation(), WorldObject::GetPhaseMask(), Position::GetPosition(), GO_STATE_READY, SpellCastTargets::HasDst(), SpellInfo::Id, IN_MILLISECONDS, m_caster, Unit::m_ObjectSlot, m_spellInfo, m_targets, Unit::RemoveGameObject(), GameObject::SetRespawnTime(), GameObject::SetSpellId(), sObjectMgr, SPELL_EFFECT_HANDLE_HIT, SPELL_EFFECT_SUMMON_OBJECT_SLOT1, SPELL_EFFECT_SUMMON_OBJECT_SLOT2, SPELL_EFFECT_SUMMON_OBJECT_SLOT3, and SPELL_EFFECT_SUMMON_OBJECT_SLOT4.

◆ EffectSummonObjectWild()

void Spell::EffectSummonObjectWild ( SpellEffIndex  effIndex)
3745{
3747 return;
3748
3749 uint32 gameobject_id = m_spellInfo->Effects[effIndex].MiscValue;
3750
3751 GameObject* pGameObj = sObjectMgr->IsGameObjectStaticTransport(gameobject_id) ? new StaticTransport() : new GameObject();
3752
3753 WorldObject* target = focusObject;
3754 if (!target)
3755 target = m_caster;
3756
3757 float x, y, z;
3758 if (m_targets.HasDst())
3759 destTarget->GetPosition(x, y, z);
3760 else
3762
3763 Map* map = target->GetMap();
3764
3765 if (!pGameObj->Create(map->GenerateLowGuid<HighGuid::GameObject>(), gameobject_id, map, m_caster->GetPhaseMask(), x, y, z, target->GetOrientation(), G3D::Quat(), 100, GO_STATE_READY))
3766 {
3767 delete pGameObj;
3768 return;
3769 }
3770
3771 int32 duration = m_spellInfo->GetDuration();
3772
3773 pGameObj->SetRespawnTime(duration > 0 ? duration / IN_MILLISECONDS : 0);
3774 pGameObj->SetSpellId(m_spellInfo->Id);
3775
3776 ExecuteLogEffectSummonObject(effIndex, pGameObj);
3777
3778 // Wild object not have owner and check clickable by players
3779 map->AddToMap(pGameObj, true);
3780
3781 if (pGameObj->GetGoType() == GAMEOBJECT_TYPE_FLAGDROP)
3782 if (Player* player = m_caster->ToPlayer())
3783 if (Battleground* bg = player->GetBattleground())
3784 bg->SetDroppedFlagGUID(pGameObj->GetGUID(), player->GetTeamId() == TEAM_ALLIANCE ? TEAM_HORDE : TEAM_ALLIANCE);
3785
3786 if (GameObject* linkedTrap = pGameObj->GetLinkedTrap())
3787 {
3788 linkedTrap->SetRespawnTime(duration > 0 ? duration/IN_MILLISECONDS :0);
3789 linkedTrap->SetSpellId(m_spellInfo->Id);
3790 ExecuteLogEffectSummonObject(effIndex, linkedTrap);
3791 }
3792}
@ GAMEOBJECT_TYPE_FLAGDROP
Definition: SharedDefines.h:1586
@ TEAM_ALLIANCE
Definition: SharedDefines.h:760
@ TEAM_HORDE
Definition: SharedDefines.h:761
GameObject * GetLinkedTrap()
Definition: GameObject.cpp:2737
GameobjectTypes GetGoType() const
Definition: GameObject.h:203

References Map::AddToMap(), GameObject::Create(), DEFAULT_WORLD_OBJECT_SIZE, destTarget, effectHandleMode, SpellInfo::Effects, ExecuteLogEffectSummonObject(), focusObject, GAMEOBJECT_TYPE_FLAGDROP, Map::GenerateLowGuid(), WorldObject::GetClosePoint(), SpellInfo::GetDuration(), GameObject::GetGoType(), Object::GetGUID(), GameObject::GetLinkedTrap(), WorldObject::GetMap(), Position::GetOrientation(), WorldObject::GetPhaseMask(), Position::GetPosition(), GO_STATE_READY, SpellCastTargets::HasDst(), SpellInfo::Id, IN_MILLISECONDS, m_caster, m_spellInfo, m_targets, GameObject::SetRespawnTime(), GameObject::SetSpellId(), sObjectMgr, SPELL_EFFECT_HANDLE_HIT, TEAM_ALLIANCE, TEAM_HORDE, and Object::ToPlayer().

◆ EffectSummonPet()

void Spell::EffectSummonPet ( SpellEffIndex  effIndex)
3141{
3143 return;
3144
3145 if (!m_originalCaster)
3146 return;
3147
3148 uint32 petentry = m_spellInfo->Effects[effIndex].MiscValue;
3149 int32 duration = m_spellInfo->GetDuration();
3150
3151 if (Player* modOwner = m_originalCaster->GetSpellModOwner())
3152 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_DURATION, duration);
3153
3154 Player* owner = m_originalCaster->ToPlayer();
3155 if (!owner && m_originalCaster->ToCreature()->IsTotem())
3157
3158 if (!owner)
3159 {
3160 SummonPropertiesEntry const* properties = sSummonPropertiesStore.LookupEntry(67);
3161 if (properties)
3162 {
3163 // Xinef: unsummon old guardian
3164 if (Guardian* oldPet = m_originalCaster->GetGuardianPet())
3165 oldPet->UnSummon();
3166 SummonGuardian(effIndex, petentry, properties, 1, false);
3167 }
3168 return;
3169 }
3170
3171 Pet* OldSummon = owner->GetPet();
3172
3173 // if pet requested type already exist
3174 if (OldSummon)
3175 {
3176 if (petentry == 0 || OldSummon->GetEntry() == petentry)
3177 {
3178 // pet in corpse state can't be summoned
3179 if (OldSummon->isDead())
3180 return;
3181
3182 ASSERT(OldSummon->GetMap() == owner->GetMap());
3183
3184 //OldSummon->GetMap()->Remove(OldSummon->ToCreature(), false);
3185
3186 float px, py, pz;
3187 owner->GetClosePoint(px, py, pz, OldSummon->GetObjectSize());
3188
3189 OldSummon->NearTeleportTo(px, py, pz, OldSummon->GetOrientation());
3190 OldSummon->UpdateObjectVisibility();
3191
3192 OldSummon->SetHealth(OldSummon->GetMaxHealth());
3193 OldSummon->SetPower(OldSummon->getPowerType(), OldSummon->GetMaxPower(OldSummon->getPowerType()));
3194 // notify player
3195 for (CreatureSpellCooldowns::const_iterator itr = OldSummon->m_CreatureSpellCooldowns.begin(); itr != OldSummon->m_CreatureSpellCooldowns.end(); ++itr)
3196 owner->SendClearCooldown(itr->first, OldSummon);
3197
3198 // actually clear cooldowns
3199 OldSummon->m_CreatureSpellCooldowns.clear();
3200 Unit::AuraApplicationMap& myAuras = OldSummon->GetAppliedAuras();
3201 for (Unit::AuraApplicationMap::iterator i = myAuras.begin(); i != myAuras.end();)
3202 {
3203 Aura const* aura = i->second->GetBase();
3204 if (!aura->IsPassive() && !OldSummon->IsPetAura(aura) && aura->CanBeSentToClient())
3205 OldSummon->RemoveAura(i);
3206 else
3207 ++i;
3208 }
3209 return;
3210 }
3211
3212 if (owner->IsPlayer())
3213 owner->ToPlayer()->RemovePet(OldSummon, PET_SAVE_NOT_IN_SLOT, false);
3214 else
3215 return;
3216 }
3217
3218 float x, y, z;
3219 owner->GetClosePoint(x, y, z, owner->GetObjectSize());
3220 Pet* pet = owner->SummonPet(petentry, x, y, z, owner->GetOrientation(), SUMMON_PET);
3221 if (!pet)
3222 return;
3223
3224 if (m_caster->IsCreature())
3225 {
3226 if (m_caster->ToCreature()->IsTotem())
3228 else
3230 }
3231
3233
3234 // Reset cooldowns
3236 {
3237 pet->m_CreatureSpellCooldowns.clear();
3238 owner->PetSpellInitialize();
3239 }
3240
3241 // Set health to max if new pet is summoned
3242 // in this function old pet is saved with current health eg. 20% and new one is loaded from db with same amount
3243 // pet should have full health
3244 pet->SetHealth(pet->GetMaxHealth());
3245
3246 // generate new name for summon pet
3247 std::string new_name = sObjectMgr->GeneratePetName(petentry);
3248 if (!new_name.empty())
3249 pet->SetName(new_name);
3250
3251 // ExecuteLogEffectSummonObject(effectInfo->EffectIndex, pet);
3252}
@ SPELLMOD_DURATION
Definition: SpellDefines.h:77
@ REACT_DEFENSIVE
Definition: Unit.h:549
@ REACT_AGGRESSIVE
Definition: Unit.h:550
CreatureSpellCooldowns m_CreatureSpellCooldowns
Definition: Creature.h:251
void SetReactState(ReactStates state)
A creature can have 3 ReactStates : Agressive, Passive, Neutral.
Definition: Creature.h:94
Definition: TemporarySummon.h:95
void SetName(std::string const &newname)
Definition: Object.h:464
float GetObjectSize() const
Definition: Object.cpp:2782
void SendClearCooldown(uint32 spell_id, Unit *target)
Definition: Player.cpp:14684
bool IsPetAura(Aura const *aura)
Definition: Unit.cpp:17336
void UpdateObjectVisibility(bool forced=true, bool fromUpdate=false) override
Definition: Unit.cpp:19130
Powers getPowerType() const
Definition: Unit.h:1052
bool isDead() const
Definition: Unit.h:1656
bool CanBeSentToClient() const
Definition: SpellAuras.cpp:1137
void SummonGuardian(uint32 i, uint32 entry, SummonPropertiesEntry const *properties, uint32 numSummons, bool personalSpawn)
Definition: SpellEffects.cpp:5960

References ASSERT, Aura::CanBeSentToClient(), CLASS_CONTEXT_PET, CLASS_HUNTER, effectHandleMode, SpellInfo::Effects, Unit::GetAppliedAuras(), Unit::GetCharmerOrOwnerPlayerOrPlayerItself(), WorldObject::GetClosePoint(), SpellInfo::GetDuration(), Object::GetEntry(), Unit::GetGuardianPet(), WorldObject::GetMap(), Unit::GetMaxHealth(), Unit::GetMaxPower(), WorldObject::GetObjectSize(), Position::GetOrientation(), Player::GetPet(), Unit::getPowerType(), Unit::GetSpellModOwner(), SpellInfo::Id, Player::IsClass(), Object::IsCreature(), Unit::isDead(), Aura::IsPassive(), Unit::IsPetAura(), Object::IsPlayer(), Unit::IsTotem(), m_caster, Creature::m_CreatureSpellCooldowns, m_originalCaster, m_spellInfo, Unit::NearTeleportTo(), PET_SAVE_NOT_IN_SLOT, Player::PetSpellInitialize(), REACT_AGGRESSIVE, REACT_DEFENSIVE, Unit::RemoveAura(), Player::RemovePet(), Player::SendClearCooldown(), Unit::SetHealth(), WorldObject::SetName(), Unit::SetPower(), Creature::SetReactState(), Unit::SetUInt32Value(), sObjectMgr, SPELL_EFFECT_HANDLE_HIT, SPELLMOD_DURATION, sSummonPropertiesStore, SUMMON_PET, SummonGuardian(), Player::SummonPet(), Object::ToCreature(), Object::ToPlayer(), UNIT_CREATED_BY_SPELL, and Unit::UpdateObjectVisibility().

◆ EffectSummonPlayer()

void Spell::EffectSummonPlayer ( SpellEffIndex  effIndex)
4228{
4229 // workaround - this effect should not use target map
4231 return;
4232
4233 if (!unitTarget)
4234 return;
4235
4236 Player* player = unitTarget->ToPlayer();
4237 if (!player)
4238 {
4239 return;
4240 }
4241
4242 // Evil Twin (ignore player summon, but hide this for summoner)
4243 // Xinef: Unit Target may be on other map!!!, Need workaround
4244 if (unitTarget->HasAura(23445))
4245 return;
4246
4247 float x, y, z;
4248 m_caster->GetPosition(x, y, z);
4249
4250 player->SetSummonPoint(m_caster->GetMapId(), x, y, z);
4251
4252 WorldPacket data(SMSG_SUMMON_REQUEST, 8 + 4 + 4);
4253 data << m_caster->GetGUID(); // summoner guid
4254 data << uint32(m_caster->GetZoneId()); // summoner zone
4255 data << uint32(MAX_PLAYER_SUMMON_DELAY * IN_MILLISECONDS); // auto decline after msecs
4256 player->GetSession()->SendPacket(&data);
4257}
#define MAX_PLAYER_SUMMON_DELAY
Definition: Player.h:934
@ SMSG_SUMMON_REQUEST
Definition: Opcodes.h:713
void SetSummonPoint(uint32 mapid, float x, float y, float z, uint32 delay=0, bool asSpectator=false)
Definition: Player.cpp:16349

References effectHandleMode, Object::GetGUID(), WorldLocation::GetMapId(), Position::GetPosition(), Player::GetSession(), WorldObject::GetZoneId(), Unit::HasAura(), IN_MILLISECONDS, m_caster, MAX_PLAYER_SUMMON_DELAY, WorldSession::SendPacket(), Player::SetSummonPoint(), SMSG_SUMMON_REQUEST, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectSummonRaFFriend()

void Spell::EffectSummonRaFFriend ( SpellEffIndex  effIndex)
6329{
6331 return;
6332
6333 if (!m_caster->IsPlayer())
6334 return;
6335
6336 if (!unitTarget)
6337 return;
6338
6339 Player* player = unitTarget->ToPlayer();
6340 if (!player)
6341 {
6342 return;
6343 }
6344
6345 float x, y, z;
6346 m_caster->GetPosition(x, y, z);
6348 WorldPacket data(SMSG_SUMMON_REQUEST, 8 + 4 + 4);
6349 data << m_caster->GetGUID();
6350 data << uint32(m_caster->GetZoneId());
6351 data << uint32(MAX_PLAYER_SUMMON_DELAY * IN_MILLISECONDS); // auto decline after msecs
6352 player->GetSession()->SendPacket(&data);
6353}

References effectHandleMode, Object::GetGUID(), WorldLocation::GetMapId(), Position::GetPosition(), Player::GetSession(), WorldObject::GetZoneId(), IN_MILLISECONDS, Object::IsPlayer(), m_caster, MAX_PLAYER_SUMMON_DELAY, WorldSession::SendPacket(), Player::SetSummonPoint(), SMSG_SUMMON_REQUEST, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectSummonType()

void Spell::EffectSummonType ( SpellEffIndex  effIndex)
2330{
2332 return;
2333
2334 uint32 entry = m_spellInfo->Effects[effIndex].MiscValue;
2335
2336 if (m_spellValue->MiscVal[effIndex])
2337 entry = m_spellValue->MiscVal[effIndex];
2338
2339 if (!entry)
2340 return;
2341
2342 SummonPropertiesEntry const* properties = sSummonPropertiesStore.LookupEntry(m_spellInfo->Effects[effIndex].MiscValueB);
2343 if (!properties)
2344 {
2345 LOG_ERROR("spells.effect", "EffectSummonType: Unhandled summon type {}", m_spellInfo->Effects[effIndex].MiscValueB);
2346 return;
2347 }
2348
2349 if (!m_originalCaster)
2350 return;
2351
2352 bool personalSpawn = (properties->Flags & SUMMON_PROP_FLAG_ONLY_VISIBLE_TO_SUMMONER) != 0;
2353 int32 duration = m_spellInfo->GetDuration();
2354 if (Player* modOwner = m_originalCaster->GetSpellModOwner())
2355 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_DURATION, duration);
2356
2357 TempSummon* summon = nullptr;
2358
2359 // determine how many units should be summoned
2360 uint32 numSummons;
2361
2362 // some spells need to summon many units, for those spells number of summons is stored in effect value
2363 // however so far noone found a generic check to find all of those (there's no related data in summonproperties.dbc
2364 // and in spell attributes, possibly we need to add a table for those)
2365 // so here's a list of MiscValueB values, which is currently most generic check
2366 switch (properties->Id)
2367 {
2368 case 64:
2369 case 61:
2370 case 1101:
2371 case 66:
2372 case 648:
2373 case 2301:
2374 case 1061:
2375 case 1261:
2376 case 629:
2377 case 181:
2378 case 715:
2379 case 1562:
2380 case 833:
2381 case 1161:
2382 case 713: // xinef, bloodworms
2383 numSummons = (damage > 0) ? damage : 1;
2384 break;
2385 default:
2386 numSummons = 1;
2387 break;
2388 }
2389
2390 switch (properties->Category)
2391 {
2395 if (properties->Flags & 512)
2396 {
2397 SummonGuardian(effIndex, entry, properties, numSummons, personalSpawn);
2398 break;
2399 }
2400 switch (properties->Type)
2401 {
2402 case SUMMON_TYPE_PET:
2405 case SUMMON_TYPE_MINION:
2406 SummonGuardian(effIndex, entry, properties, numSummons, personalSpawn);
2407 break;
2408 // Summons a vehicle, but doesn't force anyone to enter it (see SUMMON_CATEGORY_VEHICLE)
2411 summon = m_caster->GetMap()->SummonCreature(entry, *destTarget, properties, duration, m_originalCaster, m_spellInfo->Id, 0, personalSpawn);
2412 break;
2414 case SUMMON_TYPE_TOTEM:
2415 {
2416 // protection code
2417 summon = m_caster->GetMap()->SummonCreature(entry, *destTarget, properties, duration, m_originalCaster, m_spellInfo->Id, 0, personalSpawn);
2418 if (!summon || !summon->IsTotem())
2419 return;
2420
2421 // Mana Tide Totem
2422 if (m_spellInfo->Id == 16190)
2424
2425 if (damage && properties->Type != SUMMON_TYPE_LIGHTWELL) // Health set in script for lightwell
2426 {
2427 summon->SetMaxHealth(damage);
2428 summon->SetHealth(damage);
2429 }
2430 break;
2431 }
2432 case SUMMON_TYPE_JEEVES:
2434 {
2435 summon = m_caster->GetMap()->SummonCreature(entry, *destTarget, properties, duration, m_originalCaster, m_spellInfo->Id, 0, personalSpawn);
2436 if (!summon || !summon->HasUnitTypeMask(UNIT_MASK_MINION))
2437 return;
2438
2439 summon->SelectLevel(); // some summoned creaters have different from 1 DB data for level/hp
2441
2442 summon->SetImmuneToAll(true);
2444
2445 // Xinef: Pet can have some auras in creature_addon or in scripts, do not remove them instantly
2446 //summon->AI()->EnterEvadeMode();
2447 if (properties->Type != SUMMON_TYPE_JEEVES)
2448 {
2449 summon->GetMotionMaster()->Clear(false);
2451 }
2452 break;
2453 }
2454 default:
2455 {
2456 float radius = m_spellInfo->Effects[effIndex].CalcRadius();
2457
2458 TempSummonType summonType = (duration <= 0) ? TEMPSUMMON_DEAD_DESPAWN : TEMPSUMMON_TIMED_DESPAWN;
2459
2460 for (uint32 count = 0; count < numSummons; ++count)
2461 {
2462 Position pos;
2463 if (count == 0)
2464 pos = *destTarget;
2465 else
2466 // randomize position for multiple summons
2467 pos = m_caster->GetRandomPoint(*destTarget, radius);
2468
2469 summon = m_originalCaster->SummonCreature(entry, pos, summonType, duration, 0, nullptr, personalSpawn);
2470 if (!summon)
2471 continue;
2472
2473 summon->SetTempSummonType(summonType);
2474
2475 if (properties->Category == SUMMON_CATEGORY_ALLY)
2476 {
2479 }
2480
2481 ExecuteLogEffectSummonObject(effIndex, summon);
2482 }
2483 return;
2484 }
2485 }//switch
2486 break;
2488 // Xinef: SummonGuardian function can summon a few npcs of same type, remove old summons with same entry here
2489 if (m_originalCaster)
2491 SummonGuardian(effIndex, entry, properties, numSummons, personalSpawn);
2492 break;
2494 summon = m_caster->GetMap()->SummonCreature(entry, *destTarget, properties, duration, m_originalCaster, m_spellInfo->Id, 0, personalSpawn);
2495 break;
2497 // Summoning spells (usually triggered by npc_spellclick) that spawn a vehicle and that cause the clicker
2498 // to cast a ride vehicle spell on the summoned unit.
2499 //float x, y, z;
2500 //m_caster->GetClosePoint(x, y, z, DEFAULT_WORLD_OBJECT_SIZE);
2501 // xinef: vehicles summoned in air, eg. Cold Hearted quest
2502 if (std::fabs(m_caster->GetPositionZ() - destTarget->GetPositionZ()) > 6.0f)
2504
2505 summon = m_originalCaster->GetMap()->SummonCreature(entry, *destTarget, properties, duration, m_caster, m_spellInfo->Id, 0, personalSpawn);
2506 if (!summon || !summon->IsVehicle())
2507 return;
2508
2509 // The spell that this effect will trigger. It has SPELL_AURA_CONTROL_VEHICLE
2511 int32 basePoints = m_spellInfo->Effects[effIndex].CalcValue();
2512 if (basePoints > 1) // xinef: some summoning spells have value 1 - indicates vehicle seat
2513 {
2514 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(basePoints);
2515 if (spellInfo && spellInfo->HasAura(SPELL_AURA_CONTROL_VEHICLE))
2516 spellId = spellInfo->Id;
2517 }
2518
2519 // xinef: if we have small value, it indicates seat position
2520 if (basePoints > 0 && basePoints < MAX_VEHICLE_SEATS)
2521 m_originalCaster->CastCustomSpell(spellId, SPELLVALUE_BASE_POINT0, basePoints, summon, true);
2522 else
2523 m_originalCaster->CastSpell(summon, spellId, true);
2524
2525 // xinef: i think this is wrong, found only 2 vehicles with faction override and one of them should inherit caster faction...
2526 //uint32 faction = properties->Faction;
2527 //if (!faction)
2528 uint32 faction = m_originalCaster->GetFaction();
2529
2530 summon->SetFaction(faction);
2531 break;
2532 }
2533
2534 if (summon)
2535 {
2537 ExecuteLogEffectSummonObject(effIndex, summon);
2538 }
2539}
#define MAX_VEHICLE_SEATS
Definition: DBCStructure.h:2023
@ SUMMON_PROP_FLAG_ONLY_VISIBLE_TO_SUMMONER
Definition: DBCEnums.h:428
@ SUMMON_TYPE_VEHICLE2
Definition: SharedDefines.h:3304
@ SUMMON_TYPE_LIGHTWELL
Definition: SharedDefines.h:3305
@ SUMMON_TYPE_MINION
Definition: SharedDefines.h:3297
@ SUMMON_TYPE_GUARDIAN
Definition: SharedDefines.h:3296
@ SUMMON_TYPE_JEEVES
Definition: SharedDefines.h:3306
@ SUMMON_TYPE_PET
Definition: SharedDefines.h:3295
@ SUMMON_TYPE_TOTEM
Definition: SharedDefines.h:3298
@ SUMMON_TYPE_VEHICLE
Definition: SharedDefines.h:3303
@ SUMMON_TYPE_MINIPET
Definition: SharedDefines.h:3299
@ SUMMON_TYPE_GUARDIAN2
Definition: SharedDefines.h:3300
@ SUMMON_CATEGORY_VEHICLE
Definition: SharedDefines.h:3287
@ SUMMON_CATEGORY_ALLY
Definition: SharedDefines.h:3284
@ SUMMON_CATEGORY_WILD
Definition: SharedDefines.h:3283
@ SUMMON_CATEGORY_UNK
Definition: SharedDefines.h:3288
@ SPELL_AURA_CONTROL_VEHICLE
Definition: SpellAuraDefines.h:299
@ VEHICLE_SPELL_RIDE_HARDCODED
Definition: VehicleDefines.h:52
TempSummonType
Definition: Object.h:45
@ TEMPSUMMON_DEAD_DESPAWN
Definition: Object.h:52
@ REACT_PASSIVE
Definition: Unit.h:548
@ UNIT_MASK_MINION
Definition: UnitDefines.h:136
NPCFlags
Non Player Character flags.
Definition: UnitDefines.h:292
@ MOTION_SLOT_ACTIVE
Definition: MotionMaster.h:64
void SelectLevel(bool changelevel=true)
Definition: Creature.cpp:1510
uint32 npcflag
Definition: CreatureData.h:199
void SetTempSummonType(TempSummonType type)
Definition: TemporarySummon.cpp:277
void GetRandomPoint(const Position &srcPos, float distance, float &rand_x, float &rand_y, float &rand_z) const
Definition: Object.cpp:1513
void SetFaction(uint32 faction)
Definition: Unit.cpp:10056
virtual float GetFollowAngle() const
Definition: Unit.h:1756
void SetOwnerGUID(ObjectGuid owner)
Definition: Unit.cpp:10573
uint32 HasUnitTypeMask(uint32 mask) const
Definition: Unit.h:706
void SetMaxHealth(uint32 val)
Definition: Unit.cpp:15528
void SetCreatorGUID(ObjectGuid creator)
Definition: Unit.h:681
void ReplaceAllNpcFlags(NPCFlags flags)
Definition: Unit.h:728
void RemoveAllMinionsByEntry(uint32 entry)
Definition: Unit.cpp:10863
void SetImmuneToAll(bool apply, bool keepCombat=false)
Definition: Unit.h:874
TempSummon * SummonCreature(uint32 entry, Position const &pos, SummonPropertiesEntry const *properties=nullptr, uint32 duration=0, WorldObject *summoner=nullptr, uint32 spellId=0, uint32 vehId=0, bool visibleBySummonerOnly=false)
Definition: Object.cpp:2174
void MoveFollow(Unit *target, float dist, float angle, MovementSlot slot=MOTION_SLOT_ACTIVE, bool inheritWalkState=true)
The unit will follow this target. Doesn't work with UNIT_FLAG_DISABLE_MOVE.
Definition: MotionMaster.cpp:409
void Clear(bool reset=true)
Definition: MotionMaster.h:167
uint32 MiscVal[MAX_SPELL_EFFECTS]
Definition: Spell.h:221
uint32 Flags
Definition: DBCStructure.h:1914
uint32 Type
Definition: DBCStructure.h:1912
uint32 Id
Definition: DBCStructure.h:1909

References Unit::CastCustomSpell(), Unit::CastSpell(), SummonPropertiesEntry::Category, MotionMaster::Clear(), Unit::CountPctFromMaxHealth(), damage, destTarget, effectHandleMode, SpellInfo::Effects, ExecuteLogEffectSummonObject(), SummonPropertiesEntry::Flags, Creature::GetCreatureTemplate(), SpellInfo::GetDuration(), Unit::GetFaction(), Unit::GetFollowAngle(), Object::GetGUID(), WorldObject::GetMap(), Unit::GetMotionMaster(), Position::GetPositionZ(), WorldObject::GetRandomPoint(), Unit::GetSpellModOwner(), SpellInfo::HasAura(), Unit::HasUnitTypeMask(), SpellInfo::Id, SummonPropertiesEntry::Id, Unit::IsTotem(), Unit::IsVehicle(), LOG_ERROR, m_caster, m_originalCaster, Position::m_positionZ, m_spellInfo, m_spellValue, MAX_VEHICLE_SEATS, SpellValue::MiscVal, MOTION_SLOT_ACTIVE, MotionMaster::MoveFollow(), CreatureTemplate::npcflag, PET_FOLLOW_DIST, REACT_PASSIVE, Unit::RemoveAllMinionsByEntry(), Unit::ReplaceAllNpcFlags(), Creature::SelectLevel(), Unit::SetCreatorGUID(), Unit::SetFaction(), Unit::SetHealth(), Unit::SetImmuneToAll(), Unit::SetMaxHealth(), Unit::SetOwnerGUID(), Creature::SetReactState(), TempSummon::SetTempSummonType(), SPELL_AURA_CONTROL_VEHICLE, SPELL_EFFECT_HANDLE_HIT, SPELLMOD_DURATION, SPELLVALUE_BASE_POINT0, sSpellMgr, sSummonPropertiesStore, SUMMON_CATEGORY_ALLY, SUMMON_CATEGORY_PET, SUMMON_CATEGORY_PUPPET, SUMMON_CATEGORY_UNK, SUMMON_CATEGORY_VEHICLE, SUMMON_CATEGORY_WILD, SUMMON_PROP_FLAG_ONLY_VISIBLE_TO_SUMMONER, SUMMON_TYPE_GUARDIAN, SUMMON_TYPE_GUARDIAN2, SUMMON_TYPE_JEEVES, SUMMON_TYPE_LIGHTWELL, SUMMON_TYPE_MINION, SUMMON_TYPE_MINIPET, SUMMON_TYPE_PET, SUMMON_TYPE_TOTEM, SUMMON_TYPE_VEHICLE, SUMMON_TYPE_VEHICLE2, Map::SummonCreature(), WorldObject::SummonCreature(), SummonGuardian(), TEMPSUMMON_DEAD_DESPAWN, TEMPSUMMON_TIMED_DESPAWN, SummonPropertiesEntry::Type, UNIT_MASK_MINION, and VEHICLE_SPELL_RIDE_HARDCODED.

◆ EffectTameCreature()

void Spell::EffectTameCreature ( SpellEffIndex  effIndex)
3085{
3087 return;
3088
3089 if (m_caster->GetPetGUID())
3090 return;
3091
3092 if (!unitTarget)
3093 return;
3094
3095 if (!unitTarget->IsCreature())
3096 return;
3097
3098 Creature* creatureTarget = unitTarget->ToCreature();
3099
3100 if (creatureTarget->IsPet())
3101 return;
3102
3104 return;
3105
3106 // cast finish successfully
3107 //SendChannelUpdate(0);
3108 finish();
3109
3110 Pet* pet = m_caster->CreateTamedPetFrom(creatureTarget, m_spellInfo->Id);
3111 if (!pet) // in very specific state like near world end/etc.
3112 return;
3113
3114 // "kill" original creature
3115 creatureTarget->DespawnOrUnsummon();
3116
3117 uint8 level = (creatureTarget->GetLevel() < (m_caster->GetLevel() - 5)) ? (m_caster->GetLevel() - 5) : creatureTarget->GetLevel();
3118
3119 // prepare visual effect for levelup
3120 pet->SetUInt32Value(UNIT_FIELD_LEVEL, level - 1);
3121
3122 // add to world
3123 pet->GetMap()->AddToMap(pet->ToCreature(), true);
3124
3125 // visual effect for levelup
3126 pet->SetUInt32Value(UNIT_FIELD_LEVEL, level);
3127
3128 // caster have pet now
3129 m_caster->SetMinion(pet, true);
3130
3131 pet->InitTalentForLevel();
3132
3133 if (m_caster->IsPlayer())
3134 {
3137 }
3138}
@ UNIT_FIELD_LEVEL
Definition: UpdateFields.h:114

References Map::AddToMap(), CLASS_CONTEXT_PET, CLASS_HUNTER, Unit::CreateTamedPetFrom(), Creature::DespawnOrUnsummon(), effectHandleMode, finish(), Unit::GetLevel(), WorldObject::GetMap(), Unit::GetPetGUID(), SpellInfo::Id, Pet::InitTalentForLevel(), Unit::IsClass(), Object::IsCreature(), Unit::IsPet(), Object::IsPlayer(), m_caster, m_spellInfo, PET_SAVE_AS_CURRENT, Player::PetSpellInitialize(), Pet::SavePetToDB(), Unit::SetMinion(), Unit::SetUInt32Value(), SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToCreature(), Object::ToPlayer(), UNIT_FIELD_LEVEL, and unitTarget.

◆ EffectTaunt()

void Spell::EffectTaunt ( SpellEffIndex  effIndex)
3281{
3283 return;
3284
3285 if (!unitTarget)
3286 return;
3287
3288 // xinef: Hand of Reckoning, cast before checing canhavethreatlist. fixes damage against pets
3289 if (m_spellInfo->Id == 62124 && unitTarget->GetVictim() != m_caster)
3290 {
3291 m_caster->CastSpell(unitTarget, 67485, true);
3293 }
3294
3295 // this effect use before aura Taunt apply for prevent taunt already attacking target
3296 // for spell as marked "non effective at already attacking target"
3298 {
3300 return;
3301 }
3302
3304 {
3305 // Also use this effect to set the taunter's threat to the taunted creature's highest value
3306 float myThreat = unitTarget->GetThreatMgr().GetThreat(m_caster);
3308 if (topThreat > myThreat)
3309 unitTarget->GetThreatMgr().DoAddThreat(m_caster, topThreat - myThreat);
3310
3311 //Set aggro victim to caster
3313 unitTarget->GetThreatMgr().setCurrentVictim(forcedVictim);
3314 }
3315}
@ SPELL_AURA_MOD_TAUNT
Definition: SpellAuraDefines.h:74
Definition: ThreatMgr.h:48
float GetThreat() const
Definition: ThreatMgr.h:62
HostileReference * getMostHated() const
Definition: ThreatMgr.h:168
HostileReference * getReferenceByTarget(Unit const *victim) const
Definition: ThreatMgr.cpp:261
bool empty() const
Definition: ThreatMgr.h:163
void setCurrentVictim(HostileReference *hostileRef)
Definition: ThreatMgr.cpp:572
void DoAddThreat(Unit *victim, float threat)
Definition: ThreatMgr.cpp:453
float GetThreat(Unit *victim, bool alsoSearchOfflineList=false)
Definition: ThreatMgr.cpp:525
ThreatContainer & GetOnlineContainer()
Definition: ThreatMgr.h:275
bool CanHaveThreatList(bool skipAliveCheck=false) const
Definition: Unit.cpp:14614

References Unit::CanHaveThreatList(), Unit::CastSpell(), Unit::CombatStart(), ThreatMgr::DoAddThreat(), effectHandleMode, ThreatContainer::empty(), ThreatContainer::getMostHated(), ThreatMgr::GetOnlineContainer(), ThreatContainer::getReferenceByTarget(), HostileReference::GetThreat(), ThreatMgr::GetThreat(), Unit::GetThreatMgr(), Unit::GetVictim(), SpellInfo::HasAura(), SpellInfo::Id, m_caster, m_spellInfo, SendCastResult(), ThreatMgr::setCurrentVictim(), SPELL_AURA_MOD_TAUNT, SPELL_EFFECT_HANDLE_HIT_TARGET, SPELL_FAILED_DONT_REPORT, and unitTarget.

◆ EffectTeleportUnits()

void Spell::EffectTeleportUnits ( SpellEffIndex  effIndex)
1181{
1183 return;
1184
1185 if (!unitTarget || unitTarget->IsInFlight())
1186 return;
1187
1188 if (unitTarget->IsPlayer())
1189 {
1190 sScriptMgr->AnticheatSetUnderACKmount(unitTarget->ToPlayer());
1191 }
1192
1193 // Pre effects
1194 switch (m_spellInfo->Id)
1195 {
1196 case 70746: // Teleport Into Sunwell (for Battered Hilt)
1197 if (Player* target = unitTarget->ToPlayer())
1198 {
1199 uint32 mapid = destTarget->GetMapId();
1200 float x, y, z, orientation;
1201 destTarget->GetPosition(x, y, z, orientation);
1202 target->TeleportTo(mapid, x, y, z, orientation, TELE_TO_GM_MODE); // skip PlayerCannotEnter check
1203 }
1204 return;
1205 }
1206
1207 // If not exist data for dest location - return
1208 if (!m_targets.HasDst())
1209 {
1210 LOG_ERROR("spells.effect", "Spell::EffectTeleportUnits - does not have destination for spell ID {}\n", m_spellInfo->Id);
1211 return;
1212 }
1213
1214 // Init dest coordinates
1215 uint32 mapid = destTarget->GetMapId();
1216 if (mapid == MAPID_INVALID)
1217 mapid = unitTarget->GetMapId();
1218 float x, y, z, orientation;
1219 destTarget->GetPosition(x, y, z, orientation);
1220 if (!orientation && m_targets.GetUnitTarget())
1221 orientation = m_targets.GetUnitTarget()->GetOrientation();
1222 LOG_DEBUG("spells.aura", "Spell::EffectTeleportUnits - teleport unit to {} {} {} {} {}\n", mapid, x, y, z, orientation);
1223
1224 if (mapid == unitTarget->GetMapId())
1225 {
1226 if (unitTarget->GetVehicleKit()) // we are vehicle!
1227 unitTarget->GetVehicleKit()->TeleportVehicle(x, y, z, orientation);
1228 else
1229 {
1231 unitTarget->NearTeleportTo(x, y, z, orientation, unitTarget == m_caster, false, withPet, true);
1232 if (unitTarget->IsPlayer()) // pussywizard: for units it's done inside NearTeleportTo
1234 }
1235 }
1236 else if (unitTarget->IsPlayer())
1237 unitTarget->ToPlayer()->TeleportTo(mapid, x, y, z, orientation, unitTarget == m_caster ? TELE_TO_SPELL : 0);
1238 else
1239 {
1240 LOG_ERROR("spells.effect", "Spell::EffectTeleportUnits - spellId {} attempted to teleport creature to a different map.", m_spellInfo->Id);
1241 return;
1242 }
1243
1244 // post effects for TARGET_DEST_DB
1245 switch (m_spellInfo->Id)
1246 {
1247 // Dimensional Ripper - Everlook
1248 case 23442:
1249 {
1250 int32 r = irand(0, 119);
1251 if (r >= 70) // 7/12 success
1252 {
1253 if (r < 100) // 4/12 evil twin
1254 m_caster->CastSpell(m_caster, 23445, true);
1255 else // 1/12 fire
1256 m_caster->CastSpell(m_caster, 23449, true);
1257 }
1258 return;
1259 }
1260 // Ultrasafe Transporter: Toshley's Station
1261 case 36941:
1262 {
1263 if (roll_chance_i(50)) // 50% success
1264 {
1265 int32 rand_eff = urand(1, 7);
1266 switch (rand_eff)
1267 {
1268 case 1:
1269 // soul split - evil
1270 m_caster->CastSpell(m_caster, 36900, true);
1271 break;
1272 case 2:
1273 // soul split - good
1274 m_caster->CastSpell(m_caster, 36901, true);
1275 break;
1276 case 3:
1277 // Increase the size
1278 m_caster->CastSpell(m_caster, 36895, true);
1279 break;
1280 case 4:
1281 // Decrease the size
1282 m_caster->CastSpell(m_caster, 36893, true);
1283 break;
1284 case 5:
1285 // Transform
1286 {
1288 m_caster->CastSpell(m_caster, 36897, true);
1289 else
1290 m_caster->CastSpell(m_caster, 36899, true);
1291 break;
1292 }
1293 case 6:
1294 // chicken
1295 m_caster->CastSpell(m_caster, 36940, true);
1296 break;
1297 case 7:
1298 // evil twin
1299 m_caster->CastSpell(m_caster, 23445, true);
1300 break;
1301 }
1302 }
1303 return;
1304 }
1305 }
1306}
@ TELE_TO_SPELL
Definition: Player.h:830
@ TELE_TO_GM_MODE
Definition: Player.h:826
#define MAPID_INVALID
Definition: Position.h:247
TeamId GetTeamId(bool original=false) const
Definition: Player.h:2108
bool TeleportTo(uint32 mapid, float x, float y, float z, float orientation, uint32 options=0, Unit *target=nullptr, bool newInstance=false)
Definition: Player.cpp:1334
Vehicle * GetVehicleKit() const
Definition: Unit.h:1785
void TeleportVehicle(float x, float y, float z, float ang)
Definition: Vehicle.cpp:562

References Unit::CastSpell(), destTarget, effectHandleMode, Position::GetExactDist(), WorldObject::GetMap(), WorldLocation::GetMapId(), Position::GetOrientation(), Position::GetPosition(), Player::GetTeamId(), SpellCastTargets::GetUnitTarget(), Unit::GetVehicleKit(), SpellCastTargets::HasDst(), SpellInfo::Id, irand(), Map::IsDungeon(), Unit::IsInFlight(), Object::IsPlayer(), LOG_DEBUG, LOG_ERROR, m_caster, m_spellInfo, m_targets, MAPID_INVALID, Unit::NearTeleportTo(), roll_chance_i(), SPELL_EFFECT_HANDLE_HIT_TARGET, SPELLFAMILY_GENERIC, SpellInfo::SpellFamilyName, sScriptMgr, TEAM_ALLIANCE, TELE_TO_GM_MODE, TELE_TO_SPELL, Player::TeleportTo(), Vehicle::TeleportVehicle(), Object::ToPlayer(), unitTarget, Unit::UpdateObjectVisibility(), and urand().

◆ EffectTeleUnitsFaceCaster()

◆ EffectThreat()

void Spell::EffectThreat ( SpellEffIndex  effIndex)
3670{
3672 return;
3673
3674 if (!unitTarget || !unitTarget->IsAlive() || !m_caster->IsAlive())
3675 return;
3676
3677 // xinef: skip if target cannot have threat list or caster is friendly (ghoul leap)
3679 return;
3680
3682}
void AddThreat(Unit *victim, float fThreat, SpellSchoolMask schoolMask=SPELL_SCHOOL_MASK_NORMAL, SpellInfo const *threatSpell=nullptr)
Definition: Unit.cpp:14653

References Unit::AddThreat(), Unit::CanHaveThreatList(), damage, effectHandleMode, Unit::IsAlive(), Unit::IsFriendlyTo(), m_caster, SPELL_EFFECT_HANDLE_HIT_TARGET, and unitTarget.

◆ EffectTitanGrip()

void Spell::EffectTitanGrip ( SpellEffIndex  effIndex)
5894{
5896 return;
5897
5898 if (m_caster->IsPlayer())
5899 {
5900 if (Aura* aur = m_caster->GetAura(49152))
5901 aur->RecalculateAmountOfEffects();
5902 else
5903 m_caster->CastSpell(unitTarget, 49152, true); // damage reduction
5904
5906 }
5907}
void SetCanTitanGrip(bool value)
Definition: Player.cpp:13178

References Unit::CastSpell(), effectHandleMode, Unit::GetAura(), Object::IsPlayer(), m_caster, Player::SetCanTitanGrip(), SPELL_EFFECT_HANDLE_HIT, Object::ToPlayer(), and unitTarget.

◆ EffectTradeSkill()

void Spell::EffectTradeSkill ( SpellEffIndex  effIndex)
2822{
2824 return;
2825
2826 if (!m_caster->IsPlayer())
2827 return;
2828 // uint32 skillid = m_spellInfo->Effects[i].MiscValue;
2829 // uint16 skillmax = unitTarget->ToPlayer()->(skillid);
2830 // m_caster->ToPlayer()->SetSkill(skillid, skillval?skillval:1, skillmax+75);
2831}

References effectHandleMode, Object::IsPlayer(), m_caster, and SPELL_EFFECT_HANDLE_HIT.

◆ EffectTransmitted()

void Spell::EffectTransmitted ( SpellEffIndex  effIndex)
5368{
5370 return;
5371
5372 uint32 name_id = m_spellInfo->Effects[effIndex].MiscValue;
5373
5374 GameObjectTemplate const* goinfo = sObjectMgr->GetGameObjectTemplate(name_id);
5375
5376 if (!goinfo)
5377 {
5378 LOG_ERROR("sql.sql", "Gameobject (Entry: {}) not exist and not created at spell (ID: {}) cast", name_id, m_spellInfo->Id);
5379 return;
5380 }
5381
5382 float fx, fy, fz;
5383
5384 if (m_targets.HasDst())
5385 destTarget->GetPosition(fx, fy, fz);
5386 //FIXME: this can be better check for most objects but still hack
5387 else if (m_spellInfo->Effects[effIndex].HasRadius() && m_spellInfo->Speed == 0)
5388 {
5389 float dis = m_spellInfo->Effects[effIndex].CalcRadius(m_originalCaster);
5391 }
5392 else
5393 {
5394 //GO is always friendly to it's creator, get range for friends
5395 float min_dis = m_spellInfo->GetMinRange(true);
5396 float max_dis = m_spellInfo->GetMaxRange(true);
5397 float dis = (float)rand_norm() * (max_dis - min_dis) + min_dis;
5398
5400 }
5401
5402 // Seaforium charge
5403 if (m_spellInfo->Id == 52410 || m_spellInfo->Id == 66268 || m_spellInfo->Id == 66674) // SotA / IoC / IoC Huge
5404 {
5405 fx = m_caster->GetPositionX();
5406 fy = m_caster->GetPositionY();
5407 fz = m_caster->GetPositionZ();
5408 }
5409
5410 Map* cMap = m_caster->GetMap();
5411
5412 GameObject* pGameObj = sObjectMgr->IsGameObjectStaticTransport(name_id) ? new StaticTransport() : new GameObject();
5413
5414 if (!pGameObj->Create(cMap->GenerateLowGuid<HighGuid::GameObject>(), name_id, cMap, m_caster->GetPhaseMask(), fx, fy, fz, m_caster->GetOrientation(), G3D::Quat(), 100, GO_STATE_READY))
5415 {
5416 delete pGameObj;
5417 return;
5418 }
5419
5420 int32 duration = m_spellInfo->GetDuration();
5421
5422 switch (goinfo->type)
5423 {
5425 {
5427 m_caster->AddGameObject(pGameObj); // will removed at spell cancel
5428
5429 // end time of range when possible catch fish (FISHING_BOBBER_READY_TIME..GetDuration(m_spellInfo))
5430 // start time == fish-FISHING_BOBBER_READY_TIME (0..GetDuration(m_spellInfo)-FISHING_BOBBER_READY_TIME)
5431 int32 lastSec = 0;
5432 switch (urand(0, 2))
5433 {
5434 case 0:
5435 lastSec = 3;
5436 break;
5437 case 1:
5438 lastSec = 7;
5439 break;
5440 case 2:
5441 lastSec = 13;
5442 break;
5443 }
5444
5445 // Duration of the fishing bobber can't be higher than the Fishing channeling duration
5446 duration = std::min(duration, duration - lastSec*IN_MILLISECONDS + FISHING_BOBBER_READY_TIME*IN_MILLISECONDS);
5447
5448 break;
5449 }
5451 {
5452 if (m_caster->IsPlayer())
5453 {
5454 pGameObj->AddUniqueUse(m_caster->ToPlayer());
5455 m_caster->AddGameObject(pGameObj); // will be removed at spell cancel
5456 }
5457 break;
5458 }
5459 case GAMEOBJECT_TYPE_DUEL_ARBITER: // 52991
5460 m_caster->AddGameObject(pGameObj);
5461 break;
5464 default:
5465 break;
5466 }
5467
5468 pGameObj->SetRespawnTime(duration > 0 ? duration / IN_MILLISECONDS : 0);
5469
5470 pGameObj->SetOwnerGUID(m_caster->GetGUID());
5471
5472 //pGameObj->SetUInt32Value(GAMEOBJECT_LEVEL, m_caster->GetLevel());
5473 pGameObj->SetSpellId(m_spellInfo->Id);
5474
5475 ExecuteLogEffectSummonObject(effIndex, pGameObj);
5476
5477 LOG_DEBUG("spells.effect", "AddObject at SpellEfects.cpp EffectTransmitted");
5478 //m_caster->AddGameObject(pGameObj);
5479 //m_ObjToDel.push_back(pGameObj);
5480
5481 cMap->AddToMap(pGameObj, true);
5482
5483 if (GameObject* linkedTrap = pGameObj->GetLinkedTrap())
5484 {
5485 linkedTrap->SetRespawnTime(duration > 0 ? duration / IN_MILLISECONDS : 0);
5486 linkedTrap->SetSpellId(m_spellInfo->Id);
5487 linkedTrap->SetOwnerGUID(m_caster->GetGUID());
5488
5489 ExecuteLogEffectSummonObject(effIndex, linkedTrap);
5490 }
5491
5492 if (Player* player = m_caster->ToPlayer())
5493 {
5494 player->SetCanTeleport(true);
5495 }
5496}
@ GAMEOBJECT_TYPE_DUEL_ARBITER
Definition: SharedDefines.h:1576
@ GAMEOBJECT_TYPE_SUMMONING_RITUAL
Definition: SharedDefines.h:1578
@ GAMEOBJECT_TYPE_CHEST
Definition: SharedDefines.h:1563
@ GAMEOBJECT_TYPE_FISHINGHOLE
Definition: SharedDefines.h:1585
@ GAMEOBJECT_TYPE_FISHINGNODE
Definition: SharedDefines.h:1577
#define FISHING_BOBBER_READY_TIME
Definition: GameObject.h:117
@ UNIT_FIELD_CHANNEL_OBJECT
Definition: UpdateFields.h:93
void SetOwnerGUID(ObjectGuid owner)
Definition: GameObject.h:163
void AddUniqueUse(Player *player)
Definition: GameObject.cpp:929
float GetMinRange(bool positive=false) const
Definition: SpellInfo.cpp:2314

References Unit::AddGameObject(), Map::AddToMap(), GameObject::AddUniqueUse(), GameObject::Create(), DEFAULT_WORLD_OBJECT_SIZE, destTarget, effectHandleMode, SpellInfo::Effects, ExecuteLogEffectSummonObject(), FISHING_BOBBER_READY_TIME, GAMEOBJECT_TYPE_CHEST, GAMEOBJECT_TYPE_DUEL_ARBITER, GAMEOBJECT_TYPE_FISHINGHOLE, GAMEOBJECT_TYPE_FISHINGNODE, GAMEOBJECT_TYPE_SUMMONING_RITUAL, Map::GenerateLowGuid(), WorldObject::GetClosePoint(), SpellInfo::GetDuration(), Object::GetGUID(), GameObject::GetLinkedTrap(), WorldObject::GetMap(), SpellInfo::GetMaxRange(), SpellInfo::GetMinRange(), Position::GetOrientation(), WorldObject::GetPhaseMask(), Position::GetPosition(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), GO_STATE_READY, SpellCastTargets::HasDst(), SpellInfo::Id, IN_MILLISECONDS, Object::IsPlayer(), LOG_DEBUG, LOG_ERROR, m_caster, m_originalCaster, m_spellInfo, m_targets, rand_norm(), Object::SetGuidValue(), GameObject::SetOwnerGUID(), GameObject::SetRespawnTime(), GameObject::SetSpellId(), sObjectMgr, SpellInfo::Speed, SPELL_EFFECT_HANDLE_HIT, Object::ToPlayer(), GameObjectTemplate::type, UNIT_FIELD_CHANNEL_OBJECT, and urand().

◆ EffectTriggerMissileSpell()

void Spell::EffectTriggerMissileSpell ( SpellEffIndex  effIndex)
943{
946 return;
947
948 uint32 triggered_spell_id = m_spellInfo->Effects[effIndex].TriggerSpell;
949
950 // normal case
951 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(triggered_spell_id);
952 if (!spellInfo)
953 {
954 LOG_DEBUG("spells.aura", "Spell::EffectTriggerMissileSpell spell {} tried to trigger unknown spell {}", m_spellInfo->Id, triggered_spell_id);
955 return;
956 }
957
958 SpellCastTargets targets;
960 {
961 if (!spellInfo->NeedsToBeTriggeredByCaster(m_spellInfo, effIndex))
962 return;
963 targets.SetUnitTarget(unitTarget);
964 }
965 else //if (effectHandleMode == SPELL_EFFECT_HANDLE_HIT)
966 {
967 if (spellInfo->NeedsToBeTriggeredByCaster(m_spellInfo, effIndex) && (m_spellInfo->Effects[effIndex].GetProvidedTargetMask() & TARGET_FLAG_UNIT_MASK))
968 return;
969
971 targets.SetDst(m_targets);
972
973 targets.SetUnitTarget(m_caster);
974 }
975
976 CustomSpellValues values;
977 // set basepoints for trigger with value effect
979 {
980 // maybe need to set value only when basepoints == 0?
984 }
985
986 // Remove spell cooldown (not category) if spell triggering spell with cooldown and same category
987 if (m_caster->IsPlayer() && spellInfo->CategoryRecoveryTime && m_spellInfo->GetCategory() == spellInfo->GetCategory())
988 {
989 m_caster->ToPlayer()->RemoveSpellCooldown(spellInfo->Id);
990 }
991
992 // original caster guid only for GO cast
993 m_caster->CastSpell(targets, spellInfo, &values, TRIGGERED_FULL_MASK, nullptr, nullptr, m_originalCasterGUID);
994}
@ SPELL_EFFECT_TRIGGER_MISSILE_SPELL_WITH_VALUE
Definition: SharedDefines.h:926
@ TARGET_FLAG_DEST_LOCATION
Definition: SpellInfo.h:52
bool NeedsToBeTriggeredByCaster(SpellInfo const *triggeringSpell, uint8 effIndex=MAX_SPELL_EFFECTS) const
Definition: SpellInfo.cpp:1038
uint32 CategoryRecoveryTime
Definition: SpellInfo.h:349

References CustomSpellValues::AddSpellMod(), Unit::CastSpell(), SpellInfo::CategoryRecoveryTime, damage, effectHandleMode, SpellInfo::Effects, SpellInfo::GetCategory(), SpellInfo::GetExplicitTargetMask(), SpellInfo::Id, Object::IsPlayer(), LOG_DEBUG, m_caster, m_originalCasterGUID, m_spellInfo, m_targets, SpellInfo::NeedsToBeTriggeredByCaster(), Player::RemoveSpellCooldown(), SpellCastTargets::SetDst(), SpellCastTargets::SetUnitTarget(), SPELL_EFFECT_HANDLE_HIT, SPELL_EFFECT_HANDLE_HIT_TARGET, SPELL_EFFECT_TRIGGER_MISSILE_SPELL_WITH_VALUE, SPELLVALUE_BASE_POINT0, SPELLVALUE_BASE_POINT1, SPELLVALUE_BASE_POINT2, sSpellMgr, TARGET_FLAG_DEST_LOCATION, TARGET_FLAG_UNIT_MASK, Object::ToPlayer(), TRIGGERED_FULL_MASK, and unitTarget.

◆ EffectTriggerRitualOfSummoning()

void Spell::EffectTriggerRitualOfSummoning ( SpellEffIndex  effIndex)
1051{
1053 return;
1054
1055 uint32 triggered_spell_id = m_spellInfo->Effects[effIndex].TriggerSpell;
1056 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(triggered_spell_id);
1057
1058 if (!spellInfo)
1059 {
1060 LOG_ERROR("spells.effect", "EffectTriggerRitualOfSummoning of spell {}: triggering unknown spell id {}", m_spellInfo->Id, triggered_spell_id);
1061 return;
1062 }
1063
1064 finish();
1065
1066 m_caster->CastSpell((Unit*)nullptr, spellInfo, true);
1067}

References Unit::CastSpell(), effectHandleMode, SpellInfo::Effects, finish(), SpellInfo::Id, LOG_ERROR, m_caster, m_spellInfo, SPELL_EFFECT_HANDLE_HIT, and sSpellMgr.

◆ EffectTriggerSpell()

void Spell::EffectTriggerSpell ( SpellEffIndex  effIndex)
Todo:
: move those to spell scripts
786{
789 return;
790
791 uint32 triggered_spell_id = m_spellInfo->Effects[effIndex].TriggerSpell;
792
794 if (m_spellInfo->Effects[effIndex].Effect == SPELL_EFFECT_TRIGGER_SPELL
796 {
797 // special cases
798 switch (triggered_spell_id)
799 {
800 // Mirror Image
801 case 58832:
802 {
803 // Glyph of Mirror Image
804 if (m_caster->HasAura(63093))
805 m_caster->CastSpell(m_caster, 65047, true); // Mirror Image
806
807 break;
808 }
809 // Demonic Empowerment -- succubus
810 case 54437:
811 {
815
816 // Cast Lesser Invisibility
817 unitTarget->CastSpell(unitTarget, 7870, true);
818 return;
819 }
820 // just skip
821 case 23770: // Sayge's Dark Fortune of *
822 // not exist, common cooldown can be implemented in scripts if need.
823 return;
824 // Brittle Armor - (need add max stack of 24575 Brittle Armor)
825 case 29284:
826 {
827 // Brittle Armor
828 SpellInfo const* spell = sSpellMgr->GetSpellInfo(24575);
829 if (!spell)
830 return;
831
832 for (uint32 j = 0; j < spell->StackAmount; ++j)
833 m_caster->CastSpell(unitTarget, spell->Id, true);
834 return;
835 }
836 // Mercurial Shield - (need add max stack of 26464 Mercurial Shield)
837 case 29286:
838 {
839 // Mercurial Shield
840 SpellInfo const* spell = sSpellMgr->GetSpellInfo(26464);
841 if (!spell)
842 return;
843
844 for (uint32 j = 0; j < spell->StackAmount; ++j)
845 m_caster->CastSpell(unitTarget, spell->Id, true);
846 return;
847 }
848 // Cloak of Shadows
849 case 35729:
850 {
853 for (Unit::AuraApplicationMap::iterator iter = Auras.begin(); iter != Auras.end();)
854 {
855 // remove all harmful spells on you...
856 SpellInfo const* spell = iter->second->GetBase()->GetSpellInfo();
857
858 // Pounce Bleed shouldn't be removed by Cloak of Shadows.
859 if (spell->GetAllEffectsMechanicMask() & 1 << MECHANIC_BLEED)
860 return;
861
862 bool dmgClassNone = false;
864 for (uint8 i = EFFECT_0; i < MAX_SPELL_EFFECTS; ++i)
865 {
866 if ((iter->second->GetEffectMask() & (1 << i)) &&
867 spell->Effects[i].ApplyAuraName != SPELL_AURA_PERIODIC_DAMAGE &&
868 spell->Effects[i].ApplyAuraName != SPELL_AURA_PERIODIC_TRIGGER_SPELL &&
869 spell->Effects[i].ApplyAuraName != SPELL_AURA_DUMMY)
870 {
871 dmgClassNone = false;
872 break;
873 }
874 dmgClassNone = true;
875 }
876
877 if ((spell->DmgClass == SPELL_DAMAGE_CLASS_MAGIC || (spell->GetDispelMask() & dispelMask) || dmgClassNone) &&
878 // ignore positive and passive auras
879 !iter->second->IsPositive() && !iter->second->GetBase()->IsPassive() &&
880 // Xinef: Ignore NPC spells having INVULNERABILITY attribute
882 {
883 m_caster->RemoveAura(iter);
884 }
885 else
886 ++iter;
887 }
888 return;
889 }
890 }
891 }
892
893 // normal case
894 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(triggered_spell_id);
895 if (!spellInfo)
896 {
897 LOG_DEBUG("spells.aura", "Spell::EffectTriggerSpell spell {} tried to trigger unknown spell {}", m_spellInfo->Id, triggered_spell_id);
898 return;
899 }
900
901 SpellCastTargets targets;
903 {
904 if (!spellInfo->NeedsToBeTriggeredByCaster(m_spellInfo, effIndex))
905 return;
906 targets.SetUnitTarget(unitTarget);
907 }
908 else //if (effectHandleMode == SPELL_EFFECT_HANDLE_LAUNCH)
909 {
910 if (spellInfo->NeedsToBeTriggeredByCaster(m_spellInfo, effIndex) && (m_spellInfo->Effects[effIndex].GetProvidedTargetMask() & TARGET_FLAG_UNIT_MASK))
911 return;
912
914 targets.SetDst(m_targets);
915
916 if (Unit* target = m_targets.GetUnitTarget())
917 targets.SetUnitTarget(target);
918 else
919 targets.SetUnitTarget(m_caster);
920 }
921
922 CustomSpellValues values;
923 // set basepoints for trigger with value effect
925 {
926 // maybe need to set value only when basepoints == 0?
930 }
931
932 // Remove spell cooldown (not category) if spell triggering spell with cooldown and same category
933 if (m_caster->IsPlayer() && spellInfo->CategoryRecoveryTime && m_spellInfo->GetCategory() == spellInfo->GetCategory())
934 {
935 m_caster->ToPlayer()->RemoveSpellCooldown(spellInfo->Id);
936 }
937
938 // original caster guid only for GO cast
940}
@ SPELL_EFFECT_TRIGGER_SPELL_WITH_VALUE
Definition: SharedDefines.h:920
@ SPELL_EFFECT_TRIGGER_SPELL
Definition: SharedDefines.h:842
@ MECHANIC_BLEED
Definition: SharedDefines.h:1340
@ DISPEL_ALL
Definition: SharedDefines.h:1379
@ SPELL_AURA_MOD_STALKED
Definition: SpellAuraDefines.h:131
@ SPELL_AURA_PERIODIC_TRIGGER_SPELL
Definition: SpellAuraDefines.h:86

References CustomSpellValues::AddSpellMod(), Unit::CastSpell(), SpellInfo::CategoryRecoveryTime, damage, DISPEL_ALL, SpellInfo::DmgClass, EFFECT_0, effectHandleMode, SpellInfo::Effects, SpellInfo::GetAllEffectsMechanicMask(), Unit::GetAppliedAuras(), SpellInfo::GetCategory(), SpellInfo::GetDispelMask(), SpellInfo::GetExplicitTargetMask(), SpellCastTargets::GetUnitTarget(), SpellInfo::HasAttribute(), Unit::HasAura(), SpellInfo::Id, Object::IsPlayer(), LOG_DEBUG, m_caster, m_originalCasterGUID, m_spellInfo, m_targets, MAX_SPELL_EFFECTS, MECHANIC_BLEED, SpellInfo::NeedsToBeTriggeredByCaster(), Unit::RemoveAura(), Unit::RemoveAurasByType(), Unit::RemoveMovementImpairingAuras(), Player::RemoveSpellCooldown(), SpellCastTargets::SetDst(), SpellCastTargets::SetUnitTarget(), SPELL_ATTR0_NO_IMMUNITIES, SPELL_AURA_DUMMY, SPELL_AURA_MOD_STALKED, SPELL_AURA_MOD_STUN, SPELL_AURA_PERIODIC_DAMAGE, SPELL_AURA_PERIODIC_TRIGGER_SPELL, SPELL_DAMAGE_CLASS_MAGIC, SPELL_DAMAGE_CLASS_NONE, SPELL_EFFECT_HANDLE_LAUNCH, SPELL_EFFECT_HANDLE_LAUNCH_TARGET, SPELL_EFFECT_TRIGGER_SPELL, SPELL_EFFECT_TRIGGER_SPELL_WITH_VALUE, SPELLFAMILY_GENERIC, SpellInfo::SpellFamilyName, SPELLVALUE_BASE_POINT0, SPELLVALUE_BASE_POINT1, SPELLVALUE_BASE_POINT2, sSpellMgr, SpellInfo::StackAmount, TARGET_FLAG_DEST_LOCATION, TARGET_FLAG_UNIT_MASK, Object::ToPlayer(), TRIGGERED_FULL_MASK, TRIGGERED_NO_PERIODIC_RESET, and unitTarget.

◆ EffectUnlearnSpecialization()

void Spell::EffectUnlearnSpecialization ( SpellEffIndex  effIndex)
1331{
1333 return;
1334
1335 if (!unitTarget)
1336 return;
1337
1338 Player* player = unitTarget->ToPlayer();
1339 if (!player)
1340 {
1341 return;
1342 }
1343
1344 uint32 spellToUnlearn = m_spellInfo->Effects[effIndex].TriggerSpell;
1345
1346 player->removeSpell(spellToUnlearn, SPEC_MASK_ALL, false);
1347 LOG_DEBUG("spells.aura", "Spell: Player {} has unlearned spell {} from Npc: {}",
1348 player->GetGUID().ToString(), spellToUnlearn, m_caster->GetGUID().ToString());
1349}
#define SPEC_MASK_ALL
Definition: Player.h:177
void removeSpell(uint32 spellId, uint8 removeSpecMask, bool onlyTemporary)
Definition: Player.cpp:3345

References effectHandleMode, SpellInfo::Effects, Object::GetGUID(), LOG_DEBUG, m_caster, m_spellInfo, Player::removeSpell(), SPEC_MASK_ALL, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), ObjectGuid::ToString(), and unitTarget.

◆ EffectUntrainTalents()

void Spell::EffectUntrainTalents ( SpellEffIndex  effIndex)
2746{
2748 return;
2749
2750 if (!unitTarget || m_caster->IsPlayer())
2751 return;
2752
2753 if (ObjectGuid guid = m_caster->GetGUID()) // the trainer is the caster
2755}
void SendTalentWipeConfirm(ObjectGuid guid)
Definition: Player.cpp:8911

References effectHandleMode, Object::GetGUID(), Object::IsPlayer(), m_caster, Player::SendTalentWipeConfirm(), SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectUnused()

void Spell::EffectUnused ( SpellEffIndex  effIndex)
244{
245 // NOT USED BY ANY SPELL OR USELESS OR IMPLEMENTED IN DIFFERENT WAY IN TRINITY
246}

◆ EffectWeaponDmg()

void Spell::EffectWeaponDmg ( SpellEffIndex  effIndex)
3318{
3320 return;
3321
3322 if (!unitTarget || !unitTarget->IsAlive())
3323 return;
3324
3325 // multiple weapon dmg effect workaround
3326 // execute only the last weapon damage
3327 // and handle all effects at once
3328 for (uint32 j = effIndex + 1; j < MAX_SPELL_EFFECTS; ++j)
3329 {
3330 switch (m_spellInfo->Effects[j].Effect)
3331 {
3336 return; // we must calculate only at last weapon effect
3337 break;
3338 }
3339 }
3340
3341 // some spell specific modifiers
3342 float totalDamagePercentMod = 100.0f; // applied to final bonus+weapon damage
3343 int32 spell_bonus = 0; // bonus specific for spell
3344 bool normalized = false;
3345
3347 {
3349 {
3350 switch (m_spellInfo->Id)
3351 {
3352 // Trial of the Champion, Black Knight, Obliterate
3353 case 67725:
3354 case 67883:
3355 {
3356 AddPct(totalDamagePercentMod, unitTarget->GetDiseasesByCaster(m_caster->GetGUID(), 1) * 30.0f);
3357 break;
3358 }
3359 }
3360 break;
3361 }
3363 {
3364 // Devastate (player ones)
3365 if (m_spellInfo->SpellFamilyFlags[1] & 0x40)
3366 {
3367 m_caster->CastSpell(unitTarget, 58567, true);
3368
3369 if (Aura* aur = unitTarget->GetAura(58567))
3370 {
3371 // 58388 - Glyph of Devastate dummy aura.
3372 if (m_caster->HasAura(58388))
3373 aur->ModStackAmount(1);
3374
3375 spell_bonus += (aur->GetStackAmount() - 1) * CalculateSpellDamage(2, unitTarget);
3376 }
3377 }
3378 break;
3379 }
3380 case SPELLFAMILY_ROGUE:
3381 {
3382 // Fan of Knives, Hemorrhage, Ghostly Strike
3383 if ((m_spellInfo->SpellFamilyFlags[1] & 0x40000)
3384 || (m_spellInfo->SpellFamilyFlags[0] & 0x6000000))
3385 {
3386 // Hemorrhage
3387 if (m_spellInfo->SpellFamilyFlags[0] & 0x2000000)
3388 {
3390 }
3391 // 50% more damage with daggers
3392 if (m_caster->IsPlayer())
3393 if (Item* item = m_caster->ToPlayer()->GetWeaponForAttack(m_attackType, true))
3394 if (item->GetTemplate()->SubClass == ITEM_SUBCLASS_WEAPON_DAGGER)
3395 AddPct(totalDamagePercentMod, 50.0f);
3396 }
3397 // Mutilate (for each hand)
3398 else if (m_spellInfo->SpellFamilyFlags[1] & 0x6)
3399 {
3400 bool found = false;
3401 // fast check
3403 found = true;
3404 // full aura scan
3405 else
3406 {
3408 for (Unit::AuraApplicationMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
3409 {
3410 if (itr->second->GetBase()->GetSpellInfo()->Dispel == DISPEL_POISON)
3411 {
3412 found = true;
3413 break;
3414 }
3415 }
3416 }
3417
3418 if (found)
3419 AddPct(totalDamagePercentMod, 20.0f); // 120% if poisoned
3420 }
3421 break;
3422 }
3424 {
3425 switch (m_spellInfo->Id)
3426 {
3427 case 20467: // Seal of Command Unleashed
3428 spell_bonus += int32(0.08f * m_caster->GetTotalAttackPowerValue(BASE_ATTACK));
3430 break;
3431 case 42463: // Seals of the Pure for Seal of Vengeance/Corruption
3432 case 53739:
3434 AddPct(totalDamagePercentMod, sealsOfPure->GetAmount());
3435 break;
3436 case 53385: // Divine Storm deals normalized damage
3437 normalized = true;
3438 break;
3439 default:
3440 break;
3441 }
3442 break;
3443 }
3444 case SPELLFAMILY_SHAMAN:
3445 {
3446 // Skyshatter Harness item set bonus
3447 // Stormstrike
3448 if (AuraEffect* aurEff = m_caster->IsScriptOverriden(m_spellInfo, 5634))
3449 m_caster->CastSpell(m_caster, 38430, true, nullptr, aurEff);
3450 // Lava lash damage increased by Flametongue weapon
3452 AddPct(totalDamagePercentMod, 25.0f);
3453 break;
3454 }
3455 case SPELLFAMILY_DRUID:
3456 {
3457 // Mangle (Cat): CP
3458 if (m_spellInfo->SpellFamilyFlags[1] & 0x400)
3459 {
3461 }
3462 // Shred, Maul - Rend and Tear
3464 {
3465 if (AuraEffect const* rendAndTear = m_caster->GetDummyAuraEffect(SPELLFAMILY_DRUID, 2859, 0))
3466 AddPct(totalDamagePercentMod, rendAndTear->GetAmount());
3467 }
3468 break;
3469 }
3470 case SPELLFAMILY_HUNTER:
3471 {
3472 // Kill Shot
3473 if (m_spellInfo->SpellFamilyFlags[1] & 0x800000)
3474 {
3475 spell_bonus += int32(m_caster->GetTotalAttackPowerValue(RANGED_ATTACK) * 0.4f);
3476 }
3477 break;
3478 }
3480 {
3481 // Plague Strike
3482 if (m_spellInfo->SpellFamilyFlags[0] & 0x1)
3483 {
3484 // Glyph of Plague Strike
3485 if (AuraEffect const* aurEff = m_caster->GetAuraEffect(58657, EFFECT_0))
3486 AddPct(totalDamagePercentMod, aurEff->GetAmount());
3487 break;
3488 }
3489 // Blood Strike
3490 if (m_spellInfo->SpellFamilyFlags[0] & 0x400000)
3491 {
3492 float disease_amt = m_spellInfo->Effects[EFFECT_2].CalcValue();
3493 //Death Knight T8 Melee 4P Bonus
3494 if (AuraEffect* aurEff = m_caster->GetAuraEffectDummy(64736))
3495 AddPct(disease_amt, aurEff->GetAmount());
3496
3497 AddPct(totalDamagePercentMod, disease_amt * unitTarget->GetDiseasesByCaster(m_caster->GetGUID()) / 2.0f);
3498
3499 // Glyph of Blood Strike
3500 if (m_caster->GetAuraEffect(59332, EFFECT_0))
3502 AddPct(totalDamagePercentMod, 20.0f);
3503 break;
3504 }
3505 // Death Strike
3506 if (m_spellInfo->SpellFamilyFlags[0] & 0x10)
3507 {
3508 // Glyph of Death Strike
3509 if (AuraEffect const* aurEff = m_caster->GetAuraEffect(59336, EFFECT_0))
3510 if (uint32 runic = std::min<uint32>(m_caster->GetPower(POWER_RUNIC_POWER), aurEff->GetSpellInfo()->Effects[EFFECT_1].CalcValue()))
3511 AddPct(totalDamagePercentMod, runic);
3512 break;
3513 }
3514 // Obliterate (12.5% more damage per disease)
3515 if (m_spellInfo->SpellFamilyFlags[1] & 0x20000)
3516 {
3517 bool consumeDiseases = true;
3518 // Annihilation
3520 // Do not consume diseases if roll sucesses
3521 if (roll_chance_i(aurEff->GetAmount()))
3522 consumeDiseases = false;
3523
3524 float disease_amt = m_spellInfo->Effects[EFFECT_2].CalcValue();
3525 //Death Knight T8 Melee 4P Bonus
3526 if (AuraEffect* aurEff = m_caster->GetAuraEffectDummy(64736))
3527 AddPct(disease_amt, aurEff->GetAmount());
3528
3529 AddPct(totalDamagePercentMod, disease_amt * unitTarget->GetDiseasesByCaster(m_caster->GetGUID(), consumeDiseases) / 2.0f);
3530 break;
3531 }
3532 // Blood-Caked Strike - Blood-Caked Blade
3533 if (m_spellInfo->SpellIconID == 1736)
3534 {
3535 int32 weaponDamage = m_caster->CalculateDamage(m_attackType, false, true);
3536 ApplyPct(weaponDamage, std::min(uint32(3), unitTarget->GetDiseasesByCaster(m_caster->GetGUID())) * 12.5f);
3537 spell_bonus = weaponDamage;
3538 break;
3539 }
3540 // Heart Strike
3541 if (m_spellInfo->SpellFamilyFlags[0] & 0x1000000)
3542 {
3543 float disease_amt = m_spellInfo->Effects[EFFECT_2].CalcValue();
3544 //Death Knight T8 Melee 4P Bonus
3545 if (AuraEffect* aurEff = m_caster->GetAuraEffectDummy(64736))
3546 AddPct(disease_amt, aurEff->GetAmount());
3547
3548 AddPct(totalDamagePercentMod, disease_amt * unitTarget->GetDiseasesByCaster(m_caster->GetGUID()));
3549 break;
3550 }
3551 // Rune Strike
3552 if (m_spellInfo->SpellFamilyFlags[1] & 0x20000000)
3553 {
3554 spell_bonus += int32(0.15f * m_caster->GetTotalAttackPowerValue(BASE_ATTACK));
3555 }
3556
3557 break;
3558 }
3559 }
3560
3561 float weaponDamagePercentMod = 100.0f;
3562 int32 fixed_bonus = 0;
3563
3564 for (int j = 0; j < MAX_SPELL_EFFECTS; ++j)
3565 {
3566 switch (m_spellInfo->Effects[j].Effect)
3567 {
3570 fixed_bonus += CalculateSpellDamage(j, unitTarget);
3571 break;
3573 fixed_bonus += CalculateSpellDamage(j, unitTarget);
3574 normalized = true;
3575 break;
3577 ApplyPct(weaponDamagePercentMod, CalculateSpellDamage(j, unitTarget));
3578 break;
3579 default:
3580 break; // not weapon damage effect, just skip
3581 }
3582 }
3583
3584 // apply to non-weapon bonus weapon total pct effect, weapon total flat effect included in weapon damage
3585 if (fixed_bonus || spell_bonus)
3586 {
3587 UnitMods unitMod;
3588 switch (m_attackType)
3589 {
3590 default:
3591 case BASE_ATTACK:
3592 unitMod = UNIT_MOD_DAMAGE_MAINHAND;
3593 break;
3594 case OFF_ATTACK:
3595 unitMod = UNIT_MOD_DAMAGE_OFFHAND;
3596 break;
3597 case RANGED_ATTACK:
3598 unitMod = UNIT_MOD_DAMAGE_RANGED;
3599 break;
3600 }
3601
3603 {
3604 float weapon_total_pct = m_caster->GetModifierValue(unitMod, TOTAL_PCT);
3605 fixed_bonus = int32(fixed_bonus * weapon_total_pct);
3606 spell_bonus = int32(spell_bonus * weapon_total_pct);
3607 }
3608 }
3609
3610 int32 weaponDamage = 0;
3611 // Dancing Rune Weapon
3612 if (m_caster->GetEntry() == 27893)
3613 {
3614 if (Unit* owner = m_caster->GetOwner())
3615 weaponDamage = owner->CalculateDamage(m_attackType, normalized, true);
3616 }
3617 else if (m_spellInfo->Id == 5019) // Wands
3618 {
3619 weaponDamage = m_caster->CalculateDamage(m_attackType, true, false);
3620 }
3621 else
3622 {
3623 weaponDamage = m_caster->CalculateDamage(m_attackType, normalized, true);
3624 }
3625
3626 // Sequence is important
3627 for (int j = 0; j < MAX_SPELL_EFFECTS; ++j)
3628 {
3629 // We assume that a spell have at most one fixed_bonus
3630 // and at most one weaponDamagePercentMod
3631 switch (m_spellInfo->Effects[j].Effect)
3632 {
3636 weaponDamage += fixed_bonus;
3637 break;
3639 ApplyPct(weaponDamage, weaponDamagePercentMod);
3640 default:
3641 break; // not weapon damage effect, just skip
3642 }
3643 }
3644
3645 weaponDamage += spell_bonus;
3646 ApplyPct(weaponDamage, totalDamagePercentMod);
3647
3648 // prevent negative damage
3649 uint32 eff_damage(std::max(weaponDamage, 0));
3650
3651 // Add melee damage bonuses (also check for negative)
3654
3655 // Meteor like spells (divided damage to targets)
3657 {
3658 uint32 count = 0;
3659 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
3660 if (ihit->effectMask & (1 << effIndex))
3661 ++count;
3662
3663 eff_damage /= count; // divide to all targets
3664 }
3665
3666 m_damage += eff_damage;
3667}
@ POWER_RUNIC_POWER
Definition: SharedDefines.h:275
@ SPELL_EFFECT_NORMALIZED_WEAPON_DMG
Definition: SharedDefines.h:899
@ SPELL_EFFECT_WEAPON_PERCENT_DAMAGE
Definition: SharedDefines.h:809
@ AURA_STATE_DEADLY_POISON
Definition: SharedDefines.h:1308
@ AURA_STATE_BLEEDING
Definition: SharedDefines.h:1310
@ DISPEL_POISON
Definition: SharedDefines.h:1376
@ SPELL_AURA_ADD_PCT_MODIFIER
Definition: SpellAuraDefines.h:171
@ ITEM_SUBCLASS_WEAPON_DAGGER
Definition: ItemTemplate.h:359
UnitMods
Definition: Unit.h:142
@ UNIT_MOD_DAMAGE_OFFHAND
Definition: Unit.h:166
@ UNIT_MOD_DAMAGE_RANGED
Definition: Unit.h:167
@ UNIT_MOD_DAMAGE_MAINHAND
Definition: Unit.h:165
@ TOTAL_PCT
Definition: Unit.h:129
uint32 MeleeDamageBonusTaken(Unit *attacker, uint32 pdamage, WeaponAttackType attType, SpellInfo const *spellProto=nullptr, SpellSchoolMask damageSchoolMask=SPELL_SCHOOL_MASK_NORMAL)
Definition: Unit.cpp:13276
uint32 GetDiseasesByCaster(ObjectGuid casterGUID, uint8 mode=0)
Definition: Unit.cpp:5821
bool HasDecreaseSpeedAura() const
Definition: Unit.h:1687
AuraEffect * GetAuraEffectDummy(uint32 spellid) const
Definition: Unit.cpp:5550
float GetModifierValue(UnitMods unitMod, UnitModifierType modifierType) const
Definition: Unit.cpp:15288
uint32 CalculateDamage(WeaponAttackType attType, bool normalized, bool addTotalPct, uint8 itemDamagesMask=0)
Definition: Unit.cpp:2984
int32 SpellBaseDamageBonusDone(SpellSchoolMask schoolMask)
Definition: Unit.cpp:11937
uint32 MeleeDamageBonusDone(Unit *pVictim, uint32 damage, WeaponAttackType attType, SpellInfo const *spellProto=nullptr, SpellSchoolMask damageSchoolMask=SPELL_SCHOOL_MASK_NORMAL)
Definition: Unit.cpp:13074

References AddComboPointGain(), AddPct(), ApplyPct(), AURA_STATE_BLEEDING, AURA_STATE_DEADLY_POISON, BASE_ATTACK, Unit::CalculateDamage(), CalculateSpellDamage(), Unit::CastSpell(), DISPEL_POISON, EFFECT_0, EFFECT_1, EFFECT_2, effectHandleMode, SpellInfo::Effects, Unit::GetAppliedAuras(), Unit::GetAura(), Unit::GetAuraEffect(), Unit::GetAuraEffectDummy(), Unit::GetDiseasesByCaster(), Unit::GetDummyAuraEffect(), Object::GetEntry(), Object::GetGUID(), Unit::GetModifierValue(), Unit::GetOwner(), Unit::GetPower(), SpellInfo::GetSchoolMask(), Unit::GetTotalAttackPowerValue(), Player::GetWeaponForAttack(), SpellInfo::HasAttribute(), Unit::HasAura(), Unit::HasAuraState(), Unit::HasDecreaseSpeedAura(), SpellInfo::Id, Unit::IsAlive(), Object::IsPlayer(), Unit::IsScriptOverriden(), ITEM_SUBCLASS_WEAPON_DAGGER, m_attackType, m_caster, m_damage, m_spellInfo, m_spellSchoolMask, m_UniqueTargetInfo, MAX_SPELL_EFFECTS, Unit::MeleeDamageBonusDone(), Unit::MeleeDamageBonusTaken(), OFF_ATTACK, POWER_RUNIC_POWER, RANGED_ATTACK, roll_chance_i(), SPELL_ATTR0_CU_SHARE_DAMAGE, SPELL_AURA_ADD_PCT_MODIFIER, SPELL_AURA_DUMMY, SPELL_EFFECT_HANDLE_LAUNCH_TARGET, SPELL_EFFECT_NORMALIZED_WEAPON_DMG, SPELL_EFFECT_WEAPON_DAMAGE, SPELL_EFFECT_WEAPON_DAMAGE_NOSCHOOL, SPELL_EFFECT_WEAPON_PERCENT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, Unit::SpellBaseDamageBonusDone(), SPELLFAMILY_DEATHKNIGHT, SPELLFAMILY_DRUID, SPELLFAMILY_GENERIC, SPELLFAMILY_HUNTER, SPELLFAMILY_PALADIN, SPELLFAMILY_ROGUE, SPELLFAMILY_SHAMAN, SPELLFAMILY_WARRIOR, SpellInfo::SpellFamilyFlags, SpellInfo::SpellFamilyName, SpellInfo::SpellIconID, Object::ToPlayer(), TOTAL_PCT, UNIT_MOD_DAMAGE_MAINHAND, UNIT_MOD_DAMAGE_OFFHAND, UNIT_MOD_DAMAGE_RANGED, and unitTarget.

◆ ExecuteLogEffectCreateItem()

void Spell::ExecuteLogEffectCreateItem ( uint8  effIndex,
uint32  entry 
)
5150{
5151 InitEffectExecuteData(effIndex);
5152 *m_effectExecuteData[effIndex] << uint32(entry);
5153}
void InitEffectExecuteData(uint8 effIndex)
Definition: Spell.cpp:8487

References InitEffectExecuteData(), and m_effectExecuteData.

Referenced by EffectCreateItem().

◆ ExecuteLogEffectDestroyItem()

void Spell::ExecuteLogEffectDestroyItem ( uint8  effIndex,
uint32  entry 
)
5156{
5157 InitEffectExecuteData(effIndex);
5158 *m_effectExecuteData[effIndex] << uint32(entry);
5159}

References InitEffectExecuteData(), and m_effectExecuteData.

Referenced by EffectFeedPet().

◆ ExecuteLogEffectDurabilityDamage()

void Spell::ExecuteLogEffectDurabilityDamage ( uint8  effIndex,
Unit victim,
int32  itemId,
int32  slot 
)
5136{
5137 InitEffectExecuteData(effIndex);
5138 *m_effectExecuteData[effIndex] << victim->GetPackGUID();
5139 *m_effectExecuteData[effIndex] << int32(itemId);
5140 *m_effectExecuteData[effIndex] << int32(slot);
5141}

References Object::GetPackGUID(), InitEffectExecuteData(), and m_effectExecuteData.

Referenced by EffectDurabilityDamage().

◆ ExecuteLogEffectExtraAttacks()

void Spell::ExecuteLogEffectExtraAttacks ( uint8  effIndex,
Unit victim,
uint32  attCount 
)
5122{
5123 InitEffectExecuteData(effIndex);
5124 *m_effectExecuteData[effIndex] << victim->GetPackGUID();
5125 *m_effectExecuteData[effIndex] << uint32(attCount);
5126}

References Object::GetPackGUID(), InitEffectExecuteData(), and m_effectExecuteData.

Referenced by EffectAddExtraAttacks().

◆ ExecuteLogEffectInterruptCast()

void Spell::ExecuteLogEffectInterruptCast ( uint8  effIndex,
Unit victim,
uint32  spellId 
)
5129{
5130 InitEffectExecuteData(effIndex);
5131 *m_effectExecuteData[effIndex] << victim->GetPackGUID();
5132 *m_effectExecuteData[effIndex] << uint32(spellId);
5133}

References Object::GetPackGUID(), InitEffectExecuteData(), and m_effectExecuteData.

Referenced by EffectInterruptCast().

◆ ExecuteLogEffectOpenLock()

void Spell::ExecuteLogEffectOpenLock ( uint8  effIndex,
Object obj 
)
5144{
5145 InitEffectExecuteData(effIndex);
5146 *m_effectExecuteData[effIndex] << obj->GetPackGUID();
5147}

References Object::GetPackGUID(), InitEffectExecuteData(), and m_effectExecuteData.

Referenced by EffectOpenLock().

◆ ExecuteLogEffectResurrect()

void Spell::ExecuteLogEffectResurrect ( uint8  effIndex,
Unit target 
)
5174{
5175 InitEffectExecuteData(effIndex);
5176 *m_effectExecuteData[effIndex] << target->GetPackGUID();
5177}

References Object::GetPackGUID(), InitEffectExecuteData(), and m_effectExecuteData.

Referenced by EffectResurrect(), and EffectResurrectNew().

◆ ExecuteLogEffectSummonObject()

◆ ExecuteLogEffectTakeTargetPower()

void Spell::ExecuteLogEffectTakeTargetPower ( uint8  effIndex,
Unit target,
uint32  PowerType,
uint32  powerTaken,
float  gainMultiplier 
)
5113{
5114 InitEffectExecuteData(effIndex);
5115 *m_effectExecuteData[effIndex] << target->GetPackGUID();
5116 *m_effectExecuteData[effIndex] << uint32(powerTaken);
5117 *m_effectExecuteData[effIndex] << uint32(PowerType);
5118 *m_effectExecuteData[effIndex] << float(gainMultiplier);
5119}

References Object::GetPackGUID(), InitEffectExecuteData(), and m_effectExecuteData.

Referenced by EffectPowerBurn(), EffectPowerDrain(), and spell_mage_burnout_trigger::HandleDummy().

◆ ExecuteLogEffectUnsummonObject()

void Spell::ExecuteLogEffectUnsummonObject ( uint8  effIndex,
WorldObject obj 
)
5168{
5169 InitEffectExecuteData(effIndex);
5170 *m_effectExecuteData[effIndex] << obj->GetPackGUID();
5171}

References Object::GetPackGUID(), InitEffectExecuteData(), and m_effectExecuteData.

Referenced by EffectDismissPet().

◆ finish()

void Spell::finish ( bool  ok = true)
4488{
4489 if (!m_caster)
4490 return;
4491
4493 return;
4495
4496 if (m_spellInfo->IsChanneled())
4498
4501
4502 // Unsummon summon as possessed creatures on spell cancel
4504 {
4505 if (Unit* charm = m_caster->GetCharm())
4506 if (charm->IsCreature()
4507 && charm->ToCreature()->HasUnitTypeMask(UNIT_MASK_PUPPET)
4508 && charm->GetUInt32Value(UNIT_CREATED_BY_SPELL) == m_spellInfo->Id)
4509 ((Puppet*)charm)->UnSummon();
4510 }
4511
4512 if (Creature* creatureCaster = m_caster->ToCreature())
4513 creatureCaster->ReleaseFocus(this);
4514
4515 if (ok)
4516 {
4519 }
4520 else
4521 {
4522 if (m_caster->IsPlayer())
4523 {
4524 // Xinef: Restore spell mods in case of fail cast
4526
4527 // Xinef: Reset cooldown event in case of fail cast
4530 }
4531 return;
4532 }
4533
4534 // pussywizard:
4537
4539 {
4540 // Unsummon statue
4542 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spell);
4543 if (spellInfo && spellInfo->SpellIconID == 2056)
4544 {
4545 LOG_DEBUG("spells.aura", "Statue {} is unsummoned in spell {} finish", m_caster->GetGUID().ToString(), m_spellInfo->Id);
4546 m_caster->setDeathState(DeathState::JustDied);
4547 return;
4548 }
4549 }
4550
4551 // potions disabled by client, send event "not in combat" if need
4554
4555 // Take mods after trigger spell (needed for 14177 to affect 48664)
4556 // mods are taken only on succesfull cast and independantly from targets of the spell
4557 if (Player* player = m_caster->GetSpellModOwner())
4558 player->RemoveSpellMods(this);
4559
4560 // xinef: clear reactive auras states after spell cast
4563
4564 // Stop Attack for some spells
4567}
@ AURA_STATE_DEFENSE
Definition: SharedDefines.h:1292
@ AURA_STATE_HUNTER_PARRY
Definition: SharedDefines.h:1298
@ ENCOUNTER_CREDIT_CAST_SPELL
Definition: Map.h:307
@ SPELL_ATTR0_CU_ENCOUNTER_REWARD
Definition: SpellInfo.h:207
@ UNIT_MASK_PUPPET
Definition: UnitDefines.h:141
Definition: TemporarySummon.h:114
void UpdatePotionCooldown(Spell *spell=nullptr)
Definition: PlayerUpdates.cpp:1501
virtual void setDeathState(DeathState s, bool despawn=false)
Definition: Unit.cpp:14553
void UpdateInterruptMask()
Definition: Unit.cpp:754
void ModifyAuraState(AuraStateType flag, bool apply)
Definition: Unit.cpp:10497
void UpdateEncounterState(EncounterCreditType type, uint32 creditEntry, Unit *source)
Definition: Map.cpp:3474

References Unit::AttackStop(), AURA_STATE_DEFENSE, AURA_STATE_HUNTER_PARRY, SpellInfo::CasterAuraState, Unit::ClearUnitState(), ENCOUNTER_CREDIT_CAST_SPELL, WorldObject::FindMap(), Unit::GetCharm(), Object::GetGUID(), Unit::GetSpellModOwner(), Object::GetUInt32Value(), SpellInfo::HasAttribute(), Unit::HasUnitState(), SpellInfo::Id, SpellInfo::IsChanneled(), SpellInfo::IsCooldownStartedOnEvent(), Object::IsCreature(), Unit::IsNonMeleeSpellCast(), Object::IsPlayer(), Unit::IsSummon(), LOG_DEBUG, m_caster, m_spellInfo, m_spellState, m_triggeredByAuraSpell, Unit::ModifyAuraState(), Player::RemoveSpellCooldown(), Player::RestoreSpellMods(), Player::SendCooldownEvent(), Unit::setDeathState(), SPELL_ATTR0_CANCELS_AUTO_ATTACK_COMBAT, SPELL_ATTR0_CU_ENCOUNTER_REWARD, SPELL_STATE_FINISHED, SpellInfo::SpellIconID, sSpellMgr, Object::ToCreature(), Object::ToPlayer(), ObjectGuid::ToString(), UNIT_CREATED_BY_SPELL, UNIT_MASK_PUPPET, UNIT_STATE_CASTING, Map::UpdateEncounterState(), Unit::UpdateInterruptMask(), and Player::UpdatePotionCooldown().

Referenced by _cast(), Unit::AttackerStateUpdate(), cancel(), EffectInstaKill(), EffectTameCreature(), EffectTriggerRitualOfSummoning(), SpellScript::FinishCast(), Unit::FinishSpell(), handle_delayed(), handle_immediate(), WorldSession::HandleCastSpellOpcode(), WorldSession::HandlePetActionHelper(), WorldSession::HandlePetCastSpellOpcode(), prepare(), SelectImplicitCasterDestTargets(), SelectSpellTargets(), and update().

◆ FinishTargetProcessing()

void Spell::FinishTargetProcessing ( )
protected
8483{
8485}
void SendLogExecute()
Definition: Spell.cpp:5078

References SendLogExecute().

Referenced by handle_delayed(), handle_immediate(), and HandleLaunchPhase().

◆ GetCaster()

Unit * Spell::GetCaster ( ) const
inline

◆ GetCastTime()

int32 Spell::GetCastTime ( ) const
inline
550{ return m_casttime; }

References m_casttime.

Referenced by Unit::InterruptSpell(), and Unit::SetCurrentCastedSpell().

◆ GetCastTimeRemaining()

int32 Spell::GetCastTimeRemaining ( )
inline
554{ return m_timer;}

References m_timer.

◆ GetCurrentContainer()

CurrentSpellTypes Spell::GetCurrentContainer ( ) const

◆ GetDebugInfo()

std::string Spell::GetDebugInfo ( ) const
protected
8946{
8947 std::stringstream sstr;
8948 sstr << std::boolalpha
8949 << "Id: " << GetSpellInfo()->Id << " OriginalCaster: " << m_originalCasterGUID.ToString()
8950 << " State: " << getState();
8951 return sstr.str();
8952}

References GetSpellInfo(), getState(), SpellInfo::Id, m_originalCasterGUID, and ObjectGuid::ToString().

◆ GetDelayMoment()

uint64 Spell::GetDelayMoment ( ) const
inline

◆ GetDelayStart()

uint64 Spell::GetDelayStart ( ) const
inline
566{ return m_delayStart; }

References m_delayStart.

Referenced by SpellEvent::Execute(), and RecalculateDelayMomentForDst().

◆ GetDelayTrajectory()

uint64 Spell::GetDelayTrajectory ( ) const
inline
569{ return m_delayTrajectory; }

References m_delayTrajectory.

◆ GetOriginalCaster()

Unit * Spell::GetOriginalCaster ( ) const
inline

◆ GetPowerCost()

int32 Spell::GetPowerCost ( ) const
inline
580{ return m_powerCost; }

References m_powerCost.

Referenced by Unit::HandleDummyAuraProc().

◆ GetSearcherTypeMask()

uint32 Spell::GetSearcherTypeMask ( SpellTargetObjectTypes  objType,
ConditionList condList 
)
2114{
2115 // this function selects which containers need to be searched for spell target
2117
2118 // filter searchers based on searched object type
2119 switch (objType)
2120 {
2127 break;
2131 break;
2132 default:
2133 break;
2134 }
2136 retMask &= ~GRID_MAP_TYPE_MASK_CORPSE;
2140 retMask &= GRID_MAP_TYPE_MASK_PLAYER;
2141
2142 if (condList)
2143 retMask &= sConditionMgr->GetSearcherTypeMaskForConditionList(*condList);
2144 return retMask;
2145}
@ SPELL_ATTR2_ALLOW_DEAD_TARGET
Definition: SharedDefines.h:456
@ SPELL_ATTR3_ONLY_ON_GHOSTS
Definition: SharedDefines.h:505
@ SPELL_ATTR3_ONLY_ON_PLAYER
Definition: SharedDefines.h:501
@ GRID_MAP_TYPE_MASK_PLAYER
Definition: GridDefines.h:72
@ GRID_MAP_TYPE_MASK_CREATURE
Definition: GridDefines.h:69
@ GRID_MAP_TYPE_MASK_ALL
Definition: GridDefines.h:73
@ GRID_MAP_TYPE_MASK_GAMEOBJECT
Definition: GridDefines.h:71
@ GRID_MAP_TYPE_MASK_CORPSE
Definition: GridDefines.h:68
@ TARGET_OBJECT_TYPE_CORPSE
Definition: SpellInfo.h:106
@ TARGET_OBJECT_TYPE_GOBJ
Definition: SpellInfo.h:103
@ TARGET_OBJECT_TYPE_CORPSE_ALLY
Definition: SpellInfo.h:109
@ TARGET_OBJECT_TYPE_CORPSE_ENEMY
Definition: SpellInfo.h:108
@ TARGET_OBJECT_TYPE_GOBJ_ITEM
Definition: SpellInfo.h:104

References GRID_MAP_TYPE_MASK_ALL, GRID_MAP_TYPE_MASK_CORPSE, GRID_MAP_TYPE_MASK_CREATURE, GRID_MAP_TYPE_MASK_GAMEOBJECT, GRID_MAP_TYPE_MASK_PLAYER, SpellInfo::HasAttribute(), m_spellInfo, sConditionMgr, SPELL_ATTR2_ALLOW_DEAD_TARGET, SPELL_ATTR3_ONLY_ON_GHOSTS, SPELL_ATTR3_ONLY_ON_PLAYER, TARGET_OBJECT_TYPE_CORPSE, TARGET_OBJECT_TYPE_CORPSE_ALLY, TARGET_OBJECT_TYPE_CORPSE_ENEMY, TARGET_OBJECT_TYPE_GOBJ, TARGET_OBJECT_TYPE_GOBJ_ITEM, TARGET_OBJECT_TYPE_UNIT, and TARGET_OBJECT_TYPE_UNIT_AND_DEST.

Referenced by SearchAreaTargets(), SearchNearbyTarget(), and SelectImplicitConeTargets().

◆ GetSpellInfo()

◆ GetSpellSchoolMask()

SpellSchoolMask Spell::GetSpellSchoolMask ( ) const
inline

◆ GetSpellValue()

SpellValue const * Spell::GetSpellValue ( )
inline
587{ return m_spellValue; }

References m_spellValue.

Referenced by DoAllEffectOnTarget().

◆ getState()

◆ GetTriggeredByAuraTickNumber()

uint32 Spell::GetTriggeredByAuraTickNumber ( ) const
inline

◆ GetTriggeredCastFlags()

TriggerCastFlags Spell::GetTriggeredCastFlags ( ) const
inline
595{ return _triggeredCastFlags; }

References _triggeredCastFlags.

◆ GetUniqueTargetInfo()

◆ handle_delayed()

uint64 Spell::handle_delayed ( uint64  t_offset)
4181{
4182 if (!UpdatePointers())
4183 {
4184 // finish the spell if UpdatePointers() returned false, something wrong happened there
4185 finish(false);
4186 return 0;
4187 }
4188
4189 Player* modOwner = m_caster->GetSpellModOwner();
4190 if (modOwner)
4191 modOwner->SetSpellModTakingSpell(this, true);
4192
4193 uint64 next_time = m_delayTrajectory;
4194
4196
4197 if (!m_immediateHandled && m_delayTrajectory <= t_offset)
4198 {
4200 m_immediateHandled = true;
4202 next_time = 0;
4203 }
4204
4205 bool single_missile = (m_targets.HasDst());
4206
4207 // now recheck units targeting correctness (need before any effects apply to prevent adding immunity at first effect not allow apply second spell effect and similar cases)
4208 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
4209 {
4210 if (ihit->processed == false)
4211 {
4212 if (single_missile || ihit->timeDelay <= t_offset)
4213 {
4214 ihit->timeDelay = t_offset;
4215 DoAllEffectOnTarget(&(*ihit));
4216 }
4217 else if (next_time == 0 || ihit->timeDelay < next_time)
4218 next_time = ihit->timeDelay;
4219 }
4220 }
4221
4222 // now recheck gameobject targeting correctness
4223 for (std::list<GOTargetInfo>::iterator ighit = m_UniqueGOTargetInfo.begin(); ighit != m_UniqueGOTargetInfo.end(); ++ighit)
4224 {
4225 if (ighit->processed == false)
4226 {
4227 if (single_missile || ighit->timeDelay <= t_offset)
4228 DoAllEffectOnTarget(&(*ighit));
4229 else if (next_time == 0 || ighit->timeDelay < next_time)
4230 next_time = ighit->timeDelay;
4231 }
4232 }
4233
4235
4236 if (modOwner)
4237 modOwner->SetSpellModTakingSpell(this, false);
4238
4239 // All targets passed - need finish phase
4240 if (next_time == 0)
4241 {
4242 // spell is finished, perform some last features of the spell here
4244
4245 finish(true); // successfully finish spell cast
4246
4247 // return zero, spell is finished now
4248 return 0;
4249 }
4250 else
4251 {
4252 // spell is unfinished, return next execution time
4253 return next_time;
4254 }
4255}
void _handle_finish_phase()
Definition: Spell.cpp:4285
void PrepareTargetProcessing()
Definition: Spell.cpp:8477
void _handle_immediate_phase()
Definition: Spell.cpp:4257
void FinishTargetProcessing()
Definition: Spell.cpp:8482

References _handle_finish_phase(), _handle_immediate_phase(), DoAllEffectOnTarget(), finish(), FinishTargetProcessing(), Unit::GetSpellModOwner(), SpellCastTargets::HasDst(), m_caster, m_delayTrajectory, m_immediateHandled, m_targets, m_UniqueGOTargetInfo, m_UniqueTargetInfo, PrepareTargetProcessing(), Player::SetSpellModTakingSpell(), and UpdatePointers().

Referenced by SpellEvent::Execute().

◆ handle_immediate()

void Spell::handle_immediate ( )
4121{
4122 // start channeling if applicable
4123 if (m_spellInfo->IsChanneled())
4124 {
4125 int32 duration = m_spellInfo->GetDuration();
4127 duration = -1;
4128
4129 if (duration > 0)
4130 {
4131 // First mod_duration then haste - see Missile Barrage
4132 // Apply duration mod
4133 if (Player* modOwner = m_caster->GetSpellModOwner())
4134 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_DURATION, duration);
4135
4136 // Apply haste mods
4138 duration = int32(duration * m_caster->GetFloatValue(UNIT_MOD_CAST_SPEED));
4139
4142 m_channeledDuration = duration;
4143 SendChannelStart(duration);
4144 }
4145 else if (duration == -1)
4146 {
4149 SendChannelStart(duration);
4150 }
4151 }
4152
4154
4155 // process immediate effects (items, ground, etc.) also initialize some variables
4157
4158 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
4159 DoAllEffectOnTarget(&(*ihit));
4160
4161 for (std::list<GOTargetInfo>::iterator ihit = m_UniqueGOTargetInfo.begin(); ihit != m_UniqueGOTargetInfo.end(); ++ihit)
4162 DoAllEffectOnTarget(&(*ihit));
4163
4165
4166 // spell is finished, perform some last features of the spell here
4168
4169 // Remove used for cast item if need (it can be already nullptr after TakeReagents call
4170 TakeCastItem();
4171
4172 // handle ammo consumption for Hunter's volley spell
4174 TakeAmmo();
4175
4177 finish(true); // successfully finish spell cast (not last in case autorepeat or channel spell)
4178}
void AddInterruptMask(uint32 mask)
Definition: Unit.h:1476
void SendChannelStart(uint32 duration)
Definition: Spell.cpp:5211
void TakeAmmo()
Definition: Spell.cpp:5384

References _handle_finish_phase(), _handle_immediate_phase(), Unit::AddInterruptMask(), SpellInfo::ChannelInterruptFlags, DoAllEffectOnTarget(), finish(), FinishTargetProcessing(), SpellInfo::GetDuration(), Object::GetFloatValue(), Unit::GetSpellModOwner(), SpellInfo::HasAttribute(), Unit::HasAuraTypeWithAffectMask(), HasTriggeredCastFlag(), SpellInfo::Id, SpellInfo::IsChanneled(), SpellInfo::IsRangedWeaponSpell(), m_caster, m_channeledDuration, m_spellInfo, m_spellState, m_UniqueGOTargetInfo, m_UniqueTargetInfo, PrepareTargetProcessing(), SendChannelStart(), SPELL_ATTR5_SPELL_HASTE_AFFECTS_PERIODIC, SPELL_AURA_PERIODIC_HASTE, SPELL_STATE_CASTING, SPELLMOD_DURATION, TakeAmmo(), TakeCastItem(), TRIGGERED_IGNORE_EFFECTS, and UNIT_MOD_CAST_SPEED.

Referenced by _cast().

◆ HandleEffects()

void Spell::HandleEffects ( Unit pUnitTarget,
Item pItemTarget,
GameObject pGOTarget,
uint32  i,
SpellEffectHandleMode  mode 
)
5633{
5635 return;
5636
5637 effectHandleMode = mode;
5638 unitTarget = pUnitTarget;
5639 itemTarget = pItemTarget;
5640 gameObjTarget = pGOTarget;
5642
5643 uint8 eff = m_spellInfo->Effects[i].Effect;
5644
5645 LOG_DEBUG("spells.aura", "Spell: {} Effect : {}", m_spellInfo->Id, eff);
5646
5647 // we do not need DamageMultiplier here.
5648 damage = CalculateSpellDamage(i, nullptr);
5649
5650 bool preventDefault = CallScriptEffectHandlers((SpellEffIndex)i, mode);
5651
5652 if (!preventDefault && eff < TOTAL_SPELL_EFFECTS)
5653 {
5654 (this->*SpellEffects[eff])((SpellEffIndex)i);
5655 }
5656}
SpellEffIndex
Definition: SharedDefines.h:30
SpellEffects
Definition: SharedDefines.h:778
@ TOTAL_SPELL_EFFECTS
Definition: SharedDefines.h:943
WorldLocation _position
Definition: Spell.h:105
bool CallScriptEffectHandlers(SpellEffIndex effIndex, SpellEffectHandleMode mode)
Definition: Spell.cpp:8596

References SpellDestination::_position, CalculateSpellDamage(), CallScriptEffectHandlers(), damage, destTarget, effectHandleMode, SpellInfo::Effects, gameObjTarget, HasTriggeredCastFlag(), SpellInfo::Id, itemTarget, LOG_DEBUG, m_destTargets, m_spellInfo, TOTAL_SPELL_EFFECTS, TRIGGERED_IGNORE_EFFECTS, and unitTarget.

Referenced by _handle_immediate_phase(), DoAllEffectOnLaunchTarget(), DoAllEffectOnTarget(), DoSpellHitOnUnit(), and HandleLaunchPhase().

◆ HandleLaunchPhase()

void Spell::HandleLaunchPhase ( )
protected
8237{
8238 // handle effects with SPELL_EFFECT_HANDLE_LAUNCH mode
8239 for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i)
8240 {
8241 // don't do anything for empty effect
8242 if (!m_spellInfo->Effects[i].IsEffect())
8243 continue;
8244
8245 HandleEffects(nullptr, nullptr, nullptr, i, SPELL_EFFECT_HANDLE_LAUNCH);
8246 }
8247
8248 float multiplier[MAX_SPELL_EFFECTS];
8249 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
8250 if (m_applyMultiplierMask & (1 << i))
8251 multiplier[i] = m_spellInfo->Effects[i].CalcDamageMultiplier(m_originalCaster, this);
8252
8255 for (Unit::AuraEffectList::const_iterator j = Auras.begin(); j != Auras.end(); ++j)
8256 {
8257 if ((*j)->IsAffectedOnSpell(m_spellInfo))
8258 usesAmmo = false;
8259 }
8260
8262
8263 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
8264 {
8265 TargetInfo& target = *ihit;
8266
8267 uint32 mask = target.effectMask;
8268 if (!mask)
8269 continue;
8270
8271 // do not consume ammo anymore for Hunter's volley spell
8273 usesAmmo = false;
8274
8275 if (usesAmmo)
8276 {
8277 bool ammoTaken = false;
8278 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; i++)
8279 {
8280 if (!(mask & 1 << i))
8281 continue;
8282 switch (m_spellInfo->Effects[i].Effect)
8283 {
8289 ammoTaken = true;
8290 TakeAmmo();
8291 }
8292 if (ammoTaken)
8293 break;
8294 }
8295 }
8296
8297 DoAllEffectOnLaunchTarget(target, multiplier);
8298 }
8299
8301}
@ SPELL_EFFECT_SCHOOL_DAMAGE
Definition: SharedDefines.h:780
@ SPELL_ATTR0_CU_DIRECT_DAMAGE
Definition: SpellInfo.h:184
@ SPELL_AURA_ABILITY_CONSUME_NO_AMMO
Definition: SpellAuraDefines.h:337
void DoAllEffectOnLaunchTarget(TargetInfo &targetInfo, float *multiplier)
Definition: Spell.cpp:8303

References DoAllEffectOnLaunchTarget(), TargetInfo::effectMask, SpellInfo::Effects, FinishTargetProcessing(), Unit::GetAuraEffectsByType(), HandleEffects(), SpellInfo::HasAttribute(), SpellInfo::IsTargetingArea(), IsTriggered(), m_applyMultiplierMask, m_caster, m_originalCaster, m_spellInfo, m_UniqueTargetInfo, MAX_SPELL_EFFECTS, PrepareTargetProcessing(), SPELL_ATTR0_CU_DIRECT_DAMAGE, SPELL_AURA_ABILITY_CONSUME_NO_AMMO, SPELL_EFFECT_HANDLE_LAUNCH, SPELL_EFFECT_NORMALIZED_WEAPON_DMG, SPELL_EFFECT_SCHOOL_DAMAGE, SPELL_EFFECT_WEAPON_DAMAGE, SPELL_EFFECT_WEAPON_DAMAGE_NOSCHOOL, SPELL_EFFECT_WEAPON_PERCENT_DAMAGE, SPELLFAMILY_HUNTER, SpellInfo::SpellFamilyName, and TakeAmmo().

Referenced by _cast().

◆ HandleThreatSpells()

void Spell::HandleThreatSpells ( )
5586{
5587 if (m_UniqueTargetInfo.empty())
5588 return;
5589
5591 return;
5592
5593 float threat = 0.0f;
5594 if (SpellThreatEntry const* threatEntry = sSpellMgr->GetSpellThreatEntry(m_spellInfo->Id))
5595 {
5596 if (threatEntry->apPctMod != 0.0f)
5597 threat += threatEntry->apPctMod * m_caster->GetTotalAttackPowerValue(BASE_ATTACK);
5598
5599 threat += threatEntry->flatMod;
5600 }
5602 threat += m_spellInfo->SpellLevel;
5603
5604 // past this point only multiplicative effects occur
5605 if (threat == 0.0f)
5606 return;
5607
5608 // since 2.0.1 threat from positive effects also is distributed among all targets, so the overall caused threat is at most the defined bonus
5609 threat /= m_UniqueTargetInfo.size();
5610
5611 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
5612 {
5613 float threatToAdd = threat;
5614 if (ihit->missCondition != SPELL_MISS_NONE)
5615 threatToAdd = 0.0f;
5616
5617 Unit* target = ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID);
5618 if (!target)
5619 continue;
5620
5621 bool IsFriendly = m_caster->IsFriendlyTo(target);
5622 // positive spells distribute threat among all units that are in combat with target, like healing
5624 target->getHostileRefMgr().threatAssist(m_caster, threatToAdd, m_spellInfo);
5625 // for negative spells threat gets distributed among affected targets
5626 else if (!m_spellInfo->_IsPositiveSpell() && !IsFriendly && target->CanHaveThreatList())
5627 target->AddThreat(m_caster, threatToAdd, m_spellInfo->GetSchoolMask(), m_spellInfo);
5628 }
5629 LOG_DEBUG("spells.aura", "Spell {}, added an additional {} threat for {} {} target(s)", m_spellInfo->Id, threat, m_spellInfo->_IsPositiveSpell() ? "assisting" : "harming", uint32(m_UniqueTargetInfo.size()));
5630}
static bool IsFriendly(Creature *piece, Creature *target)
Definition: boss_chess_event.cpp:180
@ SPELL_ATTR0_CU_NO_INITIAL_THREAT
Definition: SpellInfo.h:180
bool _IsPositiveSpell() const
Definition: SpellInfo.cpp:2840
Definition: SpellMgr.h:385

References SpellInfo::_IsPositiveSpell(), Unit::AddThreat(), BASE_ATTACK, Unit::CanHaveThreatList(), Unit::getHostileRefMgr(), SpellInfo::GetSchoolMask(), Unit::GetTotalAttackPowerValue(), ObjectAccessor::GetUnit(), SpellInfo::HasAttribute(), SpellInfo::Id, IsFriendly(), Unit::IsFriendlyTo(), LOG_DEBUG, m_caster, m_spellInfo, m_UniqueTargetInfo, SPELL_ATTR0_CU_NO_INITIAL_THREAT, SPELL_ATTR1_NO_THREAT, SPELL_ATTR3_SUPPRESS_TARGET_PROCS, SPELL_MISS_NONE, SpellInfo::SpellLevel, sSpellMgr, and HostileRefMgr::threatAssist().

Referenced by _handle_immediate_phase().

◆ HasGlobalCooldown()

bool Spell::HasGlobalCooldown ( ) const
protected

◆ HasTriggeredCastFlag()

◆ HaveTargetsForEffect()

bool Spell::HaveTargetsForEffect ( uint8  effect) const
8107{
8108 for (std::list<TargetInfo>::const_iterator itr = m_UniqueTargetInfo.begin(); itr != m_UniqueTargetInfo.end(); ++itr)
8109 if (itr->effectMask & (1 << effect))
8110 return true;
8111
8112 for (std::list<GOTargetInfo>::const_iterator itr = m_UniqueGOTargetInfo.begin(); itr != m_UniqueGOTargetInfo.end(); ++itr)
8113 if (itr->effectMask & (1 << effect))
8114 return true;
8115
8116 for (std::list<ItemTargetInfo>::const_iterator itr = m_UniqueItemInfo.begin(); itr != m_UniqueItemInfo.end(); ++itr)
8117 if (itr->effectMask & (1 << effect))
8118 return true;
8119
8120 return false;
8121}

References m_UniqueGOTargetInfo, m_UniqueItemInfo, and m_UniqueTargetInfo.

◆ InitEffectExecuteData()

void Spell::InitEffectExecuteData ( uint8  effIndex)
protected
8488{
8489 ASSERT(effIndex < MAX_SPELL_EFFECTS);
8490 if (!m_effectExecuteData[effIndex])
8491 {
8492 m_effectExecuteData[effIndex] = new ByteBuffer(0x20);
8493 // first dword - target counter
8494 *m_effectExecuteData[effIndex] << uint32(1);
8495 }
8496 else
8497 {
8498 // increase target counter by one
8499 uint32 count = (*m_effectExecuteData[effIndex]).read<uint32>(0);
8500 (*m_effectExecuteData[effIndex]).put<uint32>(0, ++count);
8501 }
8502}

References ASSERT, m_effectExecuteData, and MAX_SPELL_EFFECTS.

Referenced by ExecuteLogEffectCreateItem(), ExecuteLogEffectDestroyItem(), ExecuteLogEffectDurabilityDamage(), ExecuteLogEffectExtraAttacks(), ExecuteLogEffectInterruptCast(), ExecuteLogEffectOpenLock(), ExecuteLogEffectResurrect(), ExecuteLogEffectSummonObject(), ExecuteLogEffectTakeTargetPower(), and ExecuteLogEffectUnsummonObject().

◆ InitExplicitTargets()

void Spell::InitExplicitTargets ( SpellCastTargets const &  targets)
718{
719 m_targets = targets;
720 // this function tries to correct spell explicit targets for spell
721 // client doesn't send explicit targets correctly sometimes - we need to fix such spells serverside
722 // this also makes sure that we correctly send explicit targets to client (removes redundant data)
723 uint32 neededTargets = m_spellInfo->GetExplicitTargetMask();
724
725 if (WorldObject* target = m_targets.GetObjectTarget())
726 {
727 // check if object target is valid with needed target flags
728 // for unit case allow corpse target mask because player with not released corpse is a unit target
729 if ((target->ToUnit() && !(neededTargets & (TARGET_FLAG_UNIT_MASK | TARGET_FLAG_CORPSE_MASK)))
730 || (target->ToGameObject() && !(neededTargets & TARGET_FLAG_GAMEOBJECT_MASK))
731 || (target->ToCorpse() && !(neededTargets & TARGET_FLAG_CORPSE_MASK)))
733 }
734 else
735 {
736 // try to select correct unit target if not provided by client or by serverside cast
737 if (neededTargets & (TARGET_FLAG_UNIT_MASK))
738 {
739 Unit* unit = nullptr;
740 // try to use player selection as a target
741 if (Player* playerCaster = m_caster->ToPlayer())
742 {
743 // selection has to be found and to be valid target for the spell
744 if (Unit* selectedUnit = ObjectAccessor::GetUnit(*m_caster, playerCaster->GetTarget()))
746 unit = selectedUnit;
747 }
748 // try to use attacked unit as a target
749 else if ((m_caster->IsCreature()) && neededTargets & (TARGET_FLAG_UNIT_ENEMY | TARGET_FLAG_UNIT))
750 unit = m_caster->GetVictim();
751
752 // didn't find anything - let's use self as target
753 if (!unit && neededTargets & (TARGET_FLAG_UNIT_RAID | TARGET_FLAG_UNIT_PARTY | TARGET_FLAG_UNIT_ALLY))
754 unit = m_caster;
755
757 }
758 }
759
760 // check if spell needs dst target
761 if (neededTargets & TARGET_FLAG_DEST_LOCATION)
762 {
763 // and target isn't set
764 if (!m_targets.HasDst())
765 {
766 // try to use unit target if provided
767 if (WorldObject* target = targets.GetObjectTarget())
768 m_targets.SetDst(*target);
769 // or use self if not available
770 else
772 }
773 }
774 else
776
777 if (neededTargets & TARGET_FLAG_SOURCE_LOCATION)
778 {
779 if (!targets.HasSrc())
781 }
782 else
784}
@ TARGET_FLAG_UNIT_RAID
Definition: SpellInfo.h:48
@ TARGET_FLAG_UNIT_ALLY
Definition: SpellInfo.h:54
@ TARGET_FLAG_SOURCE_LOCATION
Definition: SpellInfo.h:51
@ TARGET_FLAG_CORPSE_MASK
Definition: SpellInfo.h:71
@ TARGET_FLAG_UNIT_PARTY
Definition: SpellInfo.h:49
void RemoveObjectTarget()
Definition: Spell.cpp:321
void RemoveDst()
Definition: Spell.cpp:448
void RemoveSrc()
Definition: Spell.cpp:391

References SpellInfo::CheckExplicitTarget(), SpellInfo::GetExplicitTargetMask(), SpellCastTargets::GetObjectTarget(), Unit::GetTarget(), ObjectAccessor::GetUnit(), Unit::GetVictim(), SpellCastTargets::HasDst(), SpellCastTargets::HasSrc(), Object::IsCreature(), m_caster, m_spellInfo, m_targets, SpellCastTargets::RemoveDst(), SpellCastTargets::RemoveObjectTarget(), SpellCastTargets::RemoveSrc(), SpellCastTargets::SetDst(), SpellCastTargets::SetSrc(), SpellCastTargets::SetUnitTarget(), SPELL_CAST_OK, TARGET_FLAG_CORPSE_MASK, TARGET_FLAG_DEST_LOCATION, TARGET_FLAG_GAMEOBJECT_MASK, TARGET_FLAG_SOURCE_LOCATION, TARGET_FLAG_UNIT, TARGET_FLAG_UNIT_ALLY, TARGET_FLAG_UNIT_ENEMY, TARGET_FLAG_UNIT_MASK, TARGET_FLAG_UNIT_PARTY, TARGET_FLAG_UNIT_RAID, and Object::ToPlayer().

Referenced by Player::CastItemUseSpell(), and prepare().

◆ IsAutoActionResetSpell()

bool Spell::IsAutoActionResetSpell ( ) const
Todo:
changed SPELL_INTERRUPT_FLAG_AUTOATTACK -> SPELL_INTERRUPT_FLAG_INTERRUPT to fix compile - is this check correct at all?
8081{
8084 {
8085 return false;
8086 }
8087
8089 {
8090 return false;
8091 }
8092
8093 return true;
8094}
@ SPELL_ATTR6_DOESNT_RESET_SWING_TIMER_IF_INSTANT
Definition: SharedDefines.h:629

References SpellInfo::HasAttribute(), SpellInfo::InterruptFlags, IsTriggered(), m_casttime, m_spellInfo, SPELL_ATTR6_DOESNT_RESET_SWING_TIMER_IF_INSTANT, and SPELL_INTERRUPT_FLAG_INTERRUPT.

Referenced by _cast().

◆ IsAutoRepeat()

bool Spell::IsAutoRepeat ( ) const
inline

◆ IsChannelActive()

bool Spell::IsChannelActive ( ) const
inline
@ UNIT_CHANNEL_SPELL
Definition: UpdateFields.h:94

References Object::GetUInt32Value(), m_caster, and UNIT_CHANNEL_SPELL.

Referenced by Creature::IsMovementPreventedByCasting().

◆ isDelayableNoMore()

bool Spell::isDelayableNoMore ( )
inlineprotected
633 {
634 if (m_delayAtDamageCount >= 2)
635 return true;
636
638 return false;
639 }

References m_delayAtDamageCount.

Referenced by Delayed(), and DelayedChannel().

◆ IsDeletable()

◆ IsIgnoringCooldowns()

bool Spell::IsIgnoringCooldowns ( ) const

◆ IsInterruptable()

bool Spell::IsInterruptable ( ) const
inline
564{ return !m_executedCurrently; }

References m_executedCurrently.

Referenced by Unit::InterruptSpell().

◆ IsNeedSendToClient()

◆ IsNextMeleeSwingSpell()

bool Spell::IsNextMeleeSwingSpell ( ) const

◆ IsTriggered()

◆ IsValidDeadOrAliveTarget()

bool Spell::IsValidDeadOrAliveTarget ( Unit const *  target) const
protected
8229{
8230 if (target->IsAlive())
8232
8234}
bool IsRequiringDeadTarget() const
Definition: SpellInfo.cpp:1222
bool IsAllowingDeadTarget() const
Definition: SpellInfo.cpp:1227

References Unit::IsAlive(), SpellInfo::IsAllowingDeadTarget(), SpellInfo::IsRequiringDeadTarget(), and m_spellInfo.

Referenced by UpdateChanneledTargetList().

◆ LoadScripts()

void Spell::LoadScripts ( )
8511{
8512 if (_scriptsLoaded)
8513 return;
8514 _scriptsLoaded = true;
8515 sScriptMgr->CreateSpellScripts(m_spellInfo->Id, m_loadedScripts);
8516 for (std::list<SpellScript*>::iterator itr = m_loadedScripts.begin(); itr != m_loadedScripts.end();)
8517 {
8518 if (!(*itr)->_Load(this))
8519 {
8520 std::list<SpellScript*>::iterator bitr = itr;
8521 ++itr;
8522 delete (*bitr);
8523 m_loadedScripts.erase(bitr);
8524 continue;
8525 }
8526 LOG_DEBUG("spells.aura", "Spell::LoadScripts: Script `{}` for spell `{}` is loaded now", (*itr)->_GetScriptName()->c_str(), m_spellInfo->Id);
8527 (*itr)->Register();
8528 ++itr;
8529 }
8530}

References _scriptsLoaded, SpellInfo::Id, LOG_DEBUG, m_loadedScripts, m_spellInfo, and sScriptMgr.

Referenced by WorldSession::HandlePetActionHelper(), WorldSession::HandlePetCastSpellOpcode(), prepare(), and PetAI::UpdateAI().

◆ OnSpellLaunch()

void Spell::OnSpellLaunch ( )
8916{
8917 if (!m_caster || !m_caster->IsInWorld())
8918 return;
8919
8920 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(24390);
8921
8922 // Make sure the player is sending a valid GO target and lock ID. SPELL_EFFECT_OPEN_LOCK
8923 // can succeed with a lockId of 0
8924 if (m_spellInfo->Id == 21651)
8925 {
8926 if (GameObject* go = m_targets.GetGOTarget())
8927 {
8928 LockEntry const* lockInfo = sLockStore.LookupEntry(go->GetGOInfo()->GetLockId());
8929 if (lockInfo && lockInfo->Index[1] == LOCKTYPE_SLOW_OPEN)
8930 {
8931 Spell* visual = new Spell(m_caster, spellInfo, TRIGGERED_NONE);
8932 visual->prepare(&m_targets);
8933 }
8934 }
8935 }
8936}
@ LOCKTYPE_SLOW_OPEN
Definition: SharedDefines.h:2608
@ TRIGGERED_NONE
Definition: SpellDefines.h:133

References SpellCastTargets::GetGOTarget(), SpellInfo::Id, LockEntry::Index, Object::IsInWorld(), LOCKTYPE_SLOW_OPEN, m_caster, m_spellInfo, m_targets, prepare(), sLockStore, sSpellMgr, and TRIGGERED_NONE.

Referenced by prepare().

◆ prepare()

SpellCastResult Spell::prepare ( SpellCastTargets const *  targets,
AuraEffect const *  triggeredByAura = nullptr 
)

m_castItemGUID &&

3481{
3482 if (m_CastItem)
3483 {
3485 }
3486 else
3487 {
3489 }
3490
3491 InitExplicitTargets(*targets);
3492
3493 if (!sScriptMgr->CanPrepare(this, targets, triggeredByAura))
3494 {
3495 finish(false);
3496 return SPELL_FAILED_UNKNOWN;
3497 }
3498
3499 // Fill aura scaling information
3501 {
3502 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
3503 {
3504 if (m_spellInfo->Effects[i].Effect == SPELL_EFFECT_APPLY_AURA ||
3507 {
3508 // Change aura with ranks only if basepoints are taken from spellInfo and aura is positive
3510 {
3511 m_auraScaleMask |= (1 << i);
3512 if (m_spellValue->EffectBasePoints[i] != m_spellInfo->Effects[i].BasePoints)
3513 {
3514 m_auraScaleMask = 0;
3515 break;
3516 }
3517 }
3518 }
3519 }
3520 }
3521
3523
3524 if (triggeredByAura)
3525 {
3526 m_triggeredByAuraSpell.Init(triggeredByAura);
3527 }
3528
3529 // create and add update event for this spell
3530 _spellEvent = new SpellEvent(this);
3532
3534 {
3536 finish(false);
3538 }
3539
3540 //Prevent casting at cast another spell (ServerSide check)
3542 {
3544 finish(false);
3546 }
3547
3548 LoadScripts();
3549
3550 OnSpellLaunch();
3551
3553
3554 // Set combo point requirement
3556 m_needComboPoints = false;
3557
3558 SpellCastResult result = CheckCast(true);
3559 if (result != SPELL_CAST_OK && !IsAutoRepeat()) //always cast autorepeat dummy for triggering
3560 {
3561 // Periodic auras should be interrupted when aura triggers a spell which can't be cast
3562 // for example bladestorm aura should be removed on disarm as of patch 3.3.5
3563 // channeled periodic spells should be affected by this (arcane missiles, penance, etc)
3564 // a possible alternative sollution for those would be validating aura target on unit state change
3565 if (m_caster->IsPlayer() && triggeredByAura && triggeredByAura->IsPeriodic() && !triggeredByAura->GetBase()->IsPassive())
3566 {
3568 triggeredByAura->GetBase()->SetDuration(0);
3569 }
3570
3571 // Allows to cast melee attack spell if result is SPELL_FAILED_OUT_OF_RANGE
3573 {
3574 SendCastResult(result);
3575
3576 finish(false);
3577 return result;
3578 }
3579 }
3580
3581 // Prepare data for triggers
3582 prepareDataForTriggerSystem(triggeredByAura);
3583
3584 // calculate cast time (calculated after first CheckCast check to prevent charge counting for first CheckCast fail)
3586
3587 if (m_caster->IsPlayer())
3589 m_casttime = 0;
3590
3591 // don't allow channeled spells / spells with cast time to be casted while moving
3592 // (even if they are interrupted on moving, spells with almost immediate effect get to have their effect processed before movement interrupter kicks in)
3594 {
3595 // 1. Has casttime, 2. Or doesn't have flag to allow action during channel
3597 {
3599 finish(false);
3600 return SPELL_FAILED_MOVING;
3601 }
3602 }
3603
3604 // xinef: if spell have nearby target entry only, do not allow to cast if no targets are found
3605 if (m_CastItem)
3606 {
3607 bool selectTargets = false;
3608 bool nearbyDest = false;
3609
3610 for (uint8 i = EFFECT_0; i < MAX_SPELL_EFFECTS; ++i)
3611 {
3612 if (!m_spellInfo->Effects[i].IsEffect())
3613 continue;
3614
3615 if (m_spellInfo->Effects[i].TargetA.GetSelectionCategory() != TARGET_SELECT_CATEGORY_NEARBY || m_spellInfo->Effects[i].TargetA.GetCheckType() != TARGET_CHECK_ENTRY)
3616 {
3617 selectTargets = false;
3618 break;
3619 }
3620
3621 if (m_spellInfo->Effects[i].TargetA.GetObjectType() == TARGET_OBJECT_TYPE_DEST)
3622 {
3623 nearbyDest = true;
3624 }
3625
3626 // xinef: by default set it to false, and to true if any valid target is found
3627 selectTargets = true;
3628 }
3629
3630 if (selectTargets)
3631 {
3633 _spellTargetsSelected = true;
3634 bool spellFailed = false;
3635
3636 if (m_UniqueTargetInfo.empty() && m_UniqueGOTargetInfo.empty())
3637 {
3638 // no valid nearby target unit or game object found; check if nearby destination type
3639 if (nearbyDest)
3640 {
3641 if (!m_targets.HasDst())
3642 {
3643 // no valid target destination
3644 spellFailed = true;
3645 }
3646 }
3647 else
3648 {
3649 spellFailed = true;
3650 }
3651 }
3652
3653 if (spellFailed)
3654 {
3656 finish(false);
3658 }
3659 }
3660 }
3661
3662 // set timer base at cast time
3663 ReSetTimer();
3664
3665 LOG_DEBUG("spells.aura", "Spell::prepare: spell id {} source {} caster {} customCastFlags {} mask {}", m_spellInfo->Id, m_caster->GetEntry(), m_originalCaster ? m_originalCaster->GetEntry() : -1, _triggeredCastFlags, m_targets.GetTargetMask());
3666
3668 {
3670 }
3671
3672 //Containers for channeled spells have to be set
3673 //TODO:Apply this to all casted spells if needed
3674 // Why check duration? 29350: channelled triggers channelled
3676 cast(true);
3677 else
3678 {
3679 // stealth must be removed at cast starting (at show channel bar)
3680 // skip triggered spell (item equip spell casting and other not explicit character casts/item uses)
3682 {
3683 // Farsight spells exception
3684 uint32 exceptSpellId = 0;
3686 {
3687 exceptSpellId = m_spellInfo->Id;
3688 }
3689
3692 }
3693
3696
3697 // set target for proper facing
3699 {
3702 {
3703 // Xinef: Creature should focus to cast target if there is explicit target or self if casting positive spell
3704 // Xinef: Creature should not rotate when casting spell... based on halion behavior
3706 }
3707 }
3708
3709 //item: first cast may destroy item and second cast causes crash
3710 // xinef: removed !m_spellInfo->StartRecoveryTime
3711 // second los check failed in events
3712 // xinef: removed itemguid check, currently there is no such item in database
3714 cast(true);
3715
3718 }
3719
3720 return SPELL_CAST_OK;
3721}
@ SPELL_EFFECT_APPLY_AREA_AURA_PARTY
Definition: SharedDefines.h:813
@ SPELL_EFFECT_APPLY_AREA_AURA_RAID
Definition: SharedDefines.h:843
@ SPELL_ATTR0_ALLOW_WHILE_SITTING
Definition: SharedDefines.h:409
@ TARGET_SELECT_CATEGORY_NEARBY
Definition: SpellInfo.h:80
@ TARGET_OBJECT_TYPE_DEST
Definition: SpellInfo.h:100
@ AURA_INTERRUPT_FLAG_SPELL_ATTACK
Definition: SpellDefines.h:56
@ AURA_INTERRUPT_FLAG_CAST
Definition: SpellDefines.h:45
@ TRIGGERED_IGNORE_AURA_SCALING
Will not take away cast item or update related achievement criteria.
Definition: SpellDefines.h:138
@ TRIGGERED_IGNORE_AURA_INTERRUPT_FLAGS
In Spell::prepare, will be cast directly without setting containers for executed spell.
Definition: SpellDefines.h:142
@ TRIGGERED_IGNORE_COMBO_POINTS
Will not check if a current cast is in progress.
Definition: SpellDefines.h:140
@ SPELL_INTERRUPT_FLAG_MOVEMENT
Definition: SpellDefines.h:26
@ CHEAT_CASTTIME
Definition: Player.h:1005
void FocusTarget(Spell const *focusSpell, WorldObject const *target)
Definition: Creature.cpp:3551
void SetCurrentCastedSpell(Spell *pSpell)
Definition: Unit.cpp:3957
bool IsSitState() const
Definition: Unit.cpp:16711
Definition: Spell.cpp:519
void Init(AuraEffect const *aurEff)
Definition: Spell.cpp:8938
void LoadScripts()
Definition: Spell.cpp:8510
void cast(bool skipCheck=false)
Definition: Spell.cpp:3794
void prepareDataForTriggerSystem(AuraEffect const *triggeredByAura)
Definition: Spell.cpp:2295
void SendSpellStart()
Definition: Spell.cpp:4722
void TriggerGlobalCooldown()
Definition: Spell.cpp:8854
void OnSpellLaunch()
Definition: Spell.cpp:8915
CurrentSpellTypes GetCurrentContainer() const
Definition: Spell.cpp:7916
void ReSetTimer()
Definition: Spell.h:553
void InitExplicitTargets(SpellCastTargets const &targets)
Definition: Spell.cpp:717
bool IsActionAllowedChannel() const
Definition: SpellInfo.cpp:1261
int32 GetMaxDuration() const
Definition: SpellInfo.cpp:2345
uint32 Attributes
Definition: SpellInfo.h:324
bool IsBreakingStealth() const
Definition: SpellInfo.cpp:1271

References _spellEvent, _spellTargetsSelected, _triggeredCastFlags, EventProcessor::AddEvent(), SpellInfo::Attributes, AURA_INTERRUPT_FLAG_CAST, AURA_INTERRUPT_FLAG_NOT_SEATED, AURA_INTERRUPT_FLAG_SPELL_ATTACK, SpellInfo::AuraInterruptFlags, SpellInfo::CalcCastTime(), SpellInfo::CalcPowerCost(), EventProcessor::CalculateTime(), cast(), CHEAT_CASTTIME, CheckCast(), CURRENT_GENERIC_SPELL, DISABLE_TYPE_SPELL, EFFECT_0, SpellValue::EffectBasePoints, SpellInfo::Effects, ObjectGuid::Empty, finish(), Creature::FocusTarget(), AuraEffect::GetBase(), Player::GetCommandStatus(), GetCurrentContainer(), Object::GetEntry(), Object::GetGUID(), SpellInfo::GetMaxDuration(), SpellCastTargets::GetObjectTarget(), SpellCastTargets::GetTargetMask(), SpellCastTargets::HasDst(), SpellInfo::HasEffect(), HasTriggeredCastFlag(), SpellInfo::Id, TriggeredByAuraSpellData::Init(), InitExplicitTargets(), SpellInfo::InterruptFlags, SpellInfo::IsActionAllowedChannel(), IsAutoRepeat(), SpellInfo::IsBreakingStealth(), SpellInfo::IsChanneled(), Unit::IsControlledByPlayer(), Object::IsCreature(), DisableMgr::IsDisabledFor(), Creature::IsInEvadeMode(), Unit::isMoving(), IsNextMeleeSwingSpell(), Unit::IsNonMeleeSpellCast(), Aura::IsPassive(), SpellInfo::IsPassive(), AuraEffect::IsPeriodic(), Object::IsPlayer(), SpellInfo::IsPositive(), SpellInfo::IsPositiveEffect(), Unit::IsSitState(), Unit::IsTotem(), IsTriggered(), LoadScripts(), LOG_DEBUG, m_auraScaleMask, m_cast_count, m_caster, m_CastItem, m_castItemGUID, m_casttime, WorldObject::m_Events, m_needComboPoints, m_originalCaster, m_powerCost, m_spellInfo, m_spellSchoolMask, m_spellState, m_spellValue, m_targets, m_triggeredByAuraSpell, m_UniqueGOTargetInfo, m_UniqueTargetInfo, MAX_SPELL_EFFECTS, OnSpellLaunch(), prepareDataForTriggerSystem(), Unit::RemoveAurasWithInterruptFlags(), ReSetTimer(), SelectSpellTargets(), SendCastResult(), SendChannelUpdate(), SendSpellStart(), Unit::SetCurrentCastedSpell(), Aura::SetDuration(), Unit::SetStandState(), SPELL_ATTR0_ALLOW_WHILE_SITTING, SPELL_CAST_OK, SPELL_EFFECT_ADD_FARSIGHT, SPELL_EFFECT_APPLY_AREA_AURA_PARTY, SPELL_EFFECT_APPLY_AREA_AURA_RAID, SPELL_EFFECT_APPLY_AURA, SPELL_FAILED_CASTER_AURASTATE, SPELL_FAILED_MOVING, SPELL_FAILED_OUT_OF_RANGE, SPELL_FAILED_SPELL_IN_PROGRESS, SPELL_FAILED_SPELL_UNAVAILABLE, SPELL_FAILED_UNKNOWN, SPELL_INTERRUPT_FLAG_MOVEMENT, SPELL_STATE_PREPARING, SpellInfo::SpellLevel, sScriptMgr, TARGET_CHECK_ENTRY, TARGET_OBJECT_TYPE_DEST, TARGET_SELECT_CATEGORY_NEARBY, Object::ToCreature(), Object::ToPlayer(), TRIGGERED_CAST_DIRECTLY, TRIGGERED_IGNORE_AURA_INTERRUPT_FLAGS, TRIGGERED_IGNORE_AURA_SCALING, TRIGGERED_IGNORE_CAST_IN_PROGRESS, TRIGGERED_IGNORE_COMBO_POINTS, TRIGGERED_IGNORE_GCD, TRIGGERED_IGNORE_SET_FACING, TriggerGlobalCooldown(), and UNIT_STAND_STATE_STAND.

Referenced by Unit::_UpdateAutoRepeatSpell(), Player::CastItemUseSpell(), Unit::CastSpell(), EffectEnchantItemTmp(), WorldSession::HandleAcceptTradeOpcode(), WorldSession::HandleCastSpellOpcode(), WorldSession::HandlePetActionHelper(), WorldSession::HandlePetCastSpellOpcode(), OnSpellLaunch(), and PetAI::UpdateAI().

◆ prepareDataForTriggerSystem()

void Spell::prepareDataForTriggerSystem ( AuraEffect const *  triggeredByAura)
protected
2296{
2297 //==========================================================================================
2298 // Now fill data for trigger system, need know:
2299 // can spell trigger another or not (m_canTrigger)
2300 // Create base triggers flags for Attacker and Victim (m_procAttacker, m_procVictim and m_procEx)
2301 //==========================================================================================
2302
2304 // Get data for type of attack and fill base info for trigger
2305 switch (m_spellInfo->DmgClass)
2306 {
2309 if (m_attackType == OFF_ATTACK)
2311 else
2314 break;
2316 // Auto attack
2318 {
2321 }
2322 else // Ranged spell attack
2323 {
2326 }
2327 break;
2328 default:
2331 && m_spellInfo->HasAttribute(SPELL_ATTR2_AUTO_REPEAT)) // Wands auto attack
2332 {
2335 }
2336 // For other spells trigger procflags are set in Spell::DoAllEffectOnTarget
2337 // Because spell positivity is dependant on target
2338 }
2340
2341 // Hunter trap spells - activation proc for Lock and Load, Entrapment and Misdirection
2343 (m_spellInfo->SpellFamilyFlags[0] & 0x18 || // Freezing and Frost Trap, Freezing Arrow
2344 m_spellInfo->Id == 57879 || m_spellInfo->Id == 45145 || // Snake Trap - done this way to avoid double proc
2345 m_spellInfo->SpellFamilyFlags[2] & 0x00064000)) // Explosive and Immolation Trap
2346 {
2348 }
2349
2350 /* Effects which are result of aura proc from triggered spell cannot proc
2351 to prevent chain proc of these spells */
2352
2353 // Hellfire Effect - trigger as DOT
2355 {
2358 }
2359
2360 // Ranged autorepeat attack is set as triggered spell - ignore it
2362 {
2369 }
2370 // Totem casts require spellfamilymask defined in spell_proc_event to proc
2373}
@ SPELL_ATTR2_ACTIVE_THREAT
Definition: SharedDefines.h:486
@ SPELL_ATTR3_NOT_A_PROC
Definition: SharedDefines.h:502
@ TRIGGERED_DISALLOW_PROC_EVENTS
Will ignore caster aura restrictions or requirements.
Definition: SpellDefines.h:148
@ PROC_EX_NONE
Definition: SpellMgr.h:193
@ PROC_EX_INTERNAL_CANT_PROC
Definition: SpellMgr.h:218
@ PROC_EX_INTERNAL_TRIGGERED
Definition: SpellMgr.h:221
@ PROC_EX_INTERNAL_REQ_FAMILY
Definition: SpellMgr.h:222
@ PROC_FLAG_DONE_SPELL_RANGED_DMG_CLASS
Definition: SpellMgr.h:119
@ PROC_FLAG_TAKEN_RANGED_AUTO_ATTACK
Definition: SpellMgr.h:117
@ PROC_FLAG_DONE_PERIODIC
Definition: SpellMgr.h:134
@ PROC_FLAG_DONE_SPELL_MELEE_DMG_CLASS
Definition: SpellMgr.h:113
@ PROC_FLAG_TAKEN_SPELL_RANGED_DMG_CLASS
Definition: SpellMgr.h:120
@ PROC_FLAG_TAKEN_PERIODIC
Definition: SpellMgr.h:135
@ PROC_FLAG_DONE_MAINHAND_ATTACK
Definition: SpellMgr.h:140
@ PROC_FLAG_DONE_RANGED_AUTO_ATTACK
Definition: SpellMgr.h:116
@ PROC_FLAG_TAKEN_SPELL_MELEE_DMG_CLASS
Definition: SpellMgr.h:114
@ PROC_FLAG_DONE_TRAP_ACTIVATION
Definition: SpellMgr.h:138
@ PROC_FLAG_DONE_OFFHAND_ATTACK
Definition: SpellMgr.h:141

References SpellInfo::DmgClass, SpellInfo::EquippedItemClass, SpellInfo::EquippedItemSubClassMask, SpellInfo::HasAttribute(), HasTriggeredCastFlag(), SpellInfo::Id, Unit::IsControlledByPlayer(), Object::IsCreature(), Unit::IsTotem(), ITEM_CLASS_WEAPON, ITEM_SUBCLASS_WEAPON_WAND, m_attackType, m_caster, m_originalCaster, m_procAttacker, m_procEx, m_procVictim, m_spellInfo, OFF_ATTACK, PROC_EX_INTERNAL_CANT_PROC, PROC_EX_INTERNAL_REQ_FAMILY, PROC_EX_INTERNAL_TRIGGERED, PROC_EX_NONE, PROC_FLAG_DONE_MAINHAND_ATTACK, PROC_FLAG_DONE_OFFHAND_ATTACK, PROC_FLAG_DONE_PERIODIC, PROC_FLAG_DONE_RANGED_AUTO_ATTACK, PROC_FLAG_DONE_SPELL_MELEE_DMG_CLASS, PROC_FLAG_DONE_SPELL_RANGED_DMG_CLASS, PROC_FLAG_DONE_TRAP_ACTIVATION, PROC_FLAG_TAKEN_PERIODIC, PROC_FLAG_TAKEN_RANGED_AUTO_ATTACK, PROC_FLAG_TAKEN_SPELL_MELEE_DMG_CLASS, PROC_FLAG_TAKEN_SPELL_RANGED_DMG_CLASS, SPELL_ATTR2_ACTIVE_THREAT, SPELL_ATTR2_AUTO_REPEAT, SPELL_ATTR3_NOT_A_PROC, SPELL_DAMAGE_CLASS_MELEE, SPELL_DAMAGE_CLASS_RANGED, SPELLFAMILY_HUNTER, SPELLFAMILY_WARLOCK, SpellInfo::SpellFamilyFlags, SpellInfo::SpellFamilyName, Object::ToCreature(), and TRIGGERED_DISALLOW_PROC_EVENTS.

Referenced by prepare().

◆ PrepareScriptHitHandlers()

void Spell::PrepareScriptHitHandlers ( )
protected
8591{
8592 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8593 (*scritr)->_InitHit();
8594}

References m_loadedScripts.

Referenced by _cast(), _handle_immediate_phase(), and DoAllEffectOnTarget().

◆ PrepareTargetProcessing()

void Spell::PrepareTargetProcessing ( )
protected

◆ PrepareTriggersExecutedOnHit()

void Spell::PrepareTriggersExecutedOnHit ( )
protected
Todo:
: move this to scripts
Todo:
: move this to scripts
8765{
8768 {
8769 SpellInfo const* excludeCasterSpellInfo = sSpellMgr->GetSpellInfo(m_spellInfo->ExcludeCasterAuraSpell);
8770 if (excludeCasterSpellInfo && !excludeCasterSpellInfo->IsPositive())
8772 SpellInfo const* excludeTargetSpellInfo = sSpellMgr->GetSpellInfo(m_spellInfo->ExcludeTargetAuraSpell);
8773 if (excludeTargetSpellInfo && !excludeTargetSpellInfo->IsPositive())
8775 }
8776
8779 {
8781 {
8782 if (m_spellInfo->SpellFamilyFlags[1] & 0x40000000)
8783 {
8785 for(Unit::AuraEffectList::const_iterator itr = mVindication.begin(); itr != mVindication.end(); ++itr)
8786 {
8787 if ((*itr)->GetSpellInfo()->Effects[EFFECT_0].TriggerSpell == 26017 )
8788 {
8789 m_preCastSpell = 26017;
8790 break;
8791 }
8792 else if ((*itr)->GetSpellInfo()->Effects[EFFECT_0].TriggerSpell == 67 )
8793 m_preCastSpell = 67;
8794 }
8795 }
8796 break;
8797 }
8798 case SPELLFAMILY_DRUID:
8799 {
8800 // Faerie Fire (Feral)
8802 m_preCastSpell = 60089;
8803
8804 break;
8805 }
8806 }
8807
8808 // handle SPELL_AURA_ADD_TARGET_TRIGGER auras:
8809 // save auras which were present on spell caster on cast, to prevent triggered auras from affecting caster
8810 // and to correctly calculate proc chance when combopoints are present
8812 for (Unit::AuraEffectList::const_iterator i = targetTriggers.begin(); i != targetTriggers.end(); ++i)
8813 {
8814 if (!(*i)->IsAffectedOnSpell(m_spellInfo))
8815 continue;
8816 SpellInfo const* auraSpellInfo = (*i)->GetSpellInfo();
8817 uint32 auraSpellIdx = (*i)->GetEffIndex();
8818 if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(auraSpellInfo->Effects[auraSpellIdx].TriggerSpell))
8819 {
8820 // calculate the chance using spell base amount, because aura amount is not updated on combo-points change
8821 // this possibly needs fixing
8822 int32 auraBaseAmount = (*i)->GetBaseAmount();
8823 // proc chance is stored in effect amount
8824 int32 chance = m_caster->CalculateSpellDamage(nullptr, auraSpellInfo, auraSpellIdx, &auraBaseAmount);
8825 // build trigger and add to the list
8826 HitTriggerSpell spellTriggerInfo;
8827 spellTriggerInfo.triggeredSpell = spellInfo;
8828 spellTriggerInfo.triggeredByAura = auraSpellInfo;
8829 spellTriggerInfo.triggeredByEffIdx = (*i)->GetEffIndex();
8830 spellTriggerInfo.chance = chance * (*i)->GetBase()->GetStackAmount();
8831 m_hitTriggerSpells.push_back(spellTriggerInfo);
8832 }
8833 }
8834}
@ SPELL_AURA_PROC_TRIGGER_SPELL
Definition: SpellAuraDefines.h:105
@ SPELL_AURA_ADD_TARGET_TRIGGER
Definition: SpellAuraDefines.h:172
@ FORM_DIREBEAR
Definition: UnitDefines.h:77
@ FORM_BEAR
Definition: UnitDefines.h:74
uint32 ExcludeTargetAuraSpell
Definition: SpellInfo.h:346

References Unit::CalculateSpellDamage(), Spell::HitTriggerSpell::chance, EFFECT_0, SpellInfo::Effects, SpellInfo::ExcludeCasterAuraSpell, SpellInfo::ExcludeTargetAuraSpell, FORM_BEAR, FORM_DIREBEAR, Unit::GetAuraEffectsByType(), Unit::GetShapeshiftForm(), SpellInfo::Id, SpellInfo::IsPositive(), m_caster, m_hitTriggerSpells, m_preCastSpell, m_spellInfo, SPELL_AURA_ADD_TARGET_TRIGGER, SPELL_AURA_PROC_TRIGGER_SPELL, SPELLFAMILY_DRUID, SPELLFAMILY_PALADIN, SpellInfo::SpellFamilyFlags, SpellInfo::SpellFamilyName, sSpellMgr, Spell::HitTriggerSpell::triggeredByAura, Spell::HitTriggerSpell::triggeredByEffIdx, and Spell::HitTriggerSpell::triggeredSpell.

Referenced by _cast().

◆ RecalculateDelayMomentForDst()

void Spell::RecalculateDelayMomentForDst ( )
921{
924}
std::chrono::milliseconds Milliseconds
Milliseconds shorthand typedef.
Definition: Duration.h:27
void ModifyEventTime(BasicEvent *event, Milliseconds newTime)
Definition: EventProcessor.cpp:145
uint64 CalculateDelayMomentForDst() const
Definition: Spell.cpp:899
uint64 GetDelayStart() const
Definition: Spell.h:566

References _spellEvent, CalculateDelayMomentForDst(), GetDelayStart(), m_caster, m_delayMoment, WorldObject::m_Events, and EventProcessor::ModifyEventTime().

◆ ReSetTimer()

void Spell::ReSetTimer ( )
inline
553{ m_timer = m_casttime > 0 ? m_casttime : 0; }

References m_casttime, and m_timer.

Referenced by prepare().

◆ SearchAreaTargets()

void Spell::SearchAreaTargets ( std::list< WorldObject * > &  targets,
float  range,
Position const *  position,
Unit referer,
SpellTargetObjectTypes  objectType,
SpellTargetCheckTypes  selectionType,
ConditionList condList 
)
2190{
2191 uint32 containerTypeMask = GetSearcherTypeMask(objectType, condList);
2192 if (!containerTypeMask)
2193 return;
2194 Acore::WorldObjectSpellAreaTargetCheck check(range, position, m_caster, referer, m_spellInfo, selectionType, condList);
2195 Acore::WorldObjectListSearcher<Acore::WorldObjectSpellAreaTargetCheck> searcher(m_caster, targets, check, containerTypeMask);
2196 SearchTargets<Acore::WorldObjectListSearcher<Acore::WorldObjectSpellAreaTargetCheck> > (searcher, containerTypeMask, m_caster, position, range);
2197}
Definition: GridNotifiers.h:239
uint32 GetSearcherTypeMask(SpellTargetObjectTypes objType, ConditionList *condList)
Definition: Spell.cpp:2113

References GetSearcherTypeMask(), m_caster, and m_spellInfo.

Referenced by SearchChainTargets(), and SelectImplicitAreaTargets().

◆ SearchChainTargets()

void Spell::SearchChainTargets ( std::list< WorldObject * > &  targets,
uint32  chainTargets,
WorldObject target,
SpellTargetObjectTypes  objectType,
SpellTargetCheckTypes  selectType,
SpellTargetSelectionCategories  selectCategory,
ConditionList condList,
bool  isChainHeal 
)
2200{
2201 // max dist for jump target selection
2202 float jumpRadius = 0.0f;
2203 switch (m_spellInfo->DmgClass)
2204 {
2206 // 7.5y for multi shot
2207 jumpRadius = 7.5f;
2208 break;
2210 // 5y for swipe, cleave and similar
2211 jumpRadius = 5.0f;
2212 break;
2215 // 12.5y for chain heal spell since 3.2 patch
2216 if (isChainHeal)
2217 jumpRadius = 12.5f;
2218 // 10y as default for magic chain spells
2219 else
2220 jumpRadius = 10.0f;
2221 break;
2222 }
2223
2224 // chain lightning/heal spells and similar - allow to jump at larger distance and go out of los
2228
2229 // max dist which spell can reach
2230 float searchRadius = jumpRadius;
2231 if (isBouncingFar)
2232 searchRadius *= chainTargets;
2233
2234 std::list<WorldObject*> tempTargets;
2235 SearchAreaTargets(tempTargets, searchRadius, target, m_caster, objectType, selectType, condList);
2236 tempTargets.remove(target);
2237
2238 // remove targets which are always invalid for chain spells
2239 // for some spells allow only chain targets in front of caster (swipe for example)
2240 if (!isBouncingFar)
2241 {
2242 for (std::list<WorldObject*>::iterator itr = tempTargets.begin(); itr != tempTargets.end();)
2243 {
2244 std::list<WorldObject*>::iterator checkItr = itr++;
2245 if (!m_caster->HasInArc(static_cast<float>(M_PI), *checkItr))
2246 tempTargets.erase(checkItr);
2247 }
2248 }
2249
2250 while (chainTargets)
2251 {
2252 // try to get unit for next chain jump
2253 std::list<WorldObject*>::iterator foundItr = tempTargets.end();
2254 // get unit with highest hp deficit in dist
2255 if (isChainHeal)
2256 {
2257 uint32 maxHPDeficit = 0;
2258 for (std::list<WorldObject*>::iterator itr = tempTargets.begin(); itr != tempTargets.end(); ++itr)
2259 {
2260 if (Unit* unit = (*itr)->ToUnit())
2261 {
2262 uint32 deficit = unit->GetMaxHealth() - unit->GetHealth();
2263 if ((deficit > maxHPDeficit || foundItr == tempTargets.end()) && target->IsWithinDist(unit, jumpRadius) && target->IsWithinLOSInMap(unit, VMAP::ModelIgnoreFlags::M2))
2264 {
2265 foundItr = itr;
2266 maxHPDeficit = deficit;
2267 }
2268 }
2269 }
2270 }
2271 // get closest object
2272 else
2273 {
2274 for (std::list<WorldObject*>::iterator itr = tempTargets.begin(); itr != tempTargets.end(); ++itr)
2275 {
2276 if (foundItr == tempTargets.end())
2277 {
2278 if ((!isBouncingFar || target->IsWithinDist(*itr, jumpRadius)) && target->IsWithinLOSInMap(*itr, VMAP::ModelIgnoreFlags::M2))
2279 foundItr = itr;
2280 }
2281 else if (target->GetDistanceOrder(*itr, *foundItr) && target->IsWithinLOSInMap(*itr, VMAP::ModelIgnoreFlags::M2))
2282 foundItr = itr;
2283 }
2284 }
2285 // not found any valid target - chain ends
2286 if (foundItr == tempTargets.end())
2287 break;
2288 target = *foundItr;
2289 tempTargets.erase(foundItr);
2290 targets.push_back(target);
2291 --chainTargets;
2292 }
2293}
@ SPELL_ATTR4_BOUNCY_CHAIN_MISSILES
Definition: SharedDefines.h:548
bool IsWithinDist(WorldObject const *obj, float dist2compare, bool is3D=true, bool useBoundingRadius=true) const
Definition: Object.cpp:1327
bool GetDistanceOrder(WorldObject const *obj1, WorldObject const *obj2, bool is3D=true) const
Definition: Object.cpp:1392
void SearchAreaTargets(std::list< WorldObject * > &targets, float range, Position const *position, Unit *referer, SpellTargetObjectTypes objectType, SpellTargetCheckTypes selectionType, ConditionList *condList)
Definition: Spell.cpp:2189

References SpellInfo::DmgClass, WorldObject::GetDistanceOrder(), SpellInfo::HasAttribute(), Position::HasInArc(), WorldObject::IsWithinDist(), WorldObject::IsWithinLOSInMap(), VMAP::M2, m_caster, m_spellInfo, SearchAreaTargets(), SPELL_ATTR4_BOUNCY_CHAIN_MISSILES, SPELL_DAMAGE_CLASS_MAGIC, SPELL_DAMAGE_CLASS_MELEE, SPELL_DAMAGE_CLASS_NONE, SPELL_DAMAGE_CLASS_RANGED, and Object::ToUnit().

Referenced by SelectImplicitChainTargets().

◆ SearchNearbyTarget()

WorldObject * Spell::SearchNearbyTarget ( float  range,
SpellTargetObjectTypes  objectType,
SpellTargetCheckTypes  selectionType,
ConditionList condList = nullptr 
)
2178{
2179 WorldObject* target = nullptr;
2180 uint32 containerTypeMask = GetSearcherTypeMask(objectType, condList);
2181 if (!containerTypeMask)
2182 return nullptr;
2183 Acore::WorldObjectSpellNearbyTargetCheck check(range, m_caster, m_spellInfo, selectionType, condList);
2185 SearchTargets<Acore::WorldObjectLastSearcher<Acore::WorldObjectSpellNearbyTargetCheck> > (searcher, containerTypeMask, m_caster, m_caster, range);
2186 return target;
2187}
Definition: GridNotifiers.h:219

References GetSearcherTypeMask(), m_caster, and m_spellInfo.

Referenced by SelectImplicitNearbyTargets().

◆ SearchTargets()

template<class SEARCHER >
void Spell::SearchTargets ( SEARCHER &  searcher,
uint32  containerMask,
Unit referer,
Position const *  pos,
float  radius 
)
2149{
2150 if (!containerMask)
2151 return;
2152
2153 // search world and grid for possible targets
2154 bool searchInGrid = containerMask & (GRID_MAP_TYPE_MASK_CREATURE | GRID_MAP_TYPE_MASK_GAMEOBJECT);
2155 bool searchInWorld = containerMask & (GRID_MAP_TYPE_MASK_CREATURE | GRID_MAP_TYPE_MASK_PLAYER | GRID_MAP_TYPE_MASK_CORPSE);
2156
2157 if (searchInGrid || searchInWorld)
2158 {
2159 float x, y;
2160 x = pos->GetPositionX();
2161 y = pos->GetPositionY();
2162
2164 Cell cell(p);
2165 cell.SetNoCreate();
2166
2167 Map* map = referer->GetMap();
2168
2169 if (searchInWorld)
2170 Cell::VisitWorldObjects(x, y, map, searcher, radius);
2171
2172 if (searchInGrid)
2173 Cell::VisitGridObjects(x, y, map, searcher, radius);
2174 }
2175}
static void VisitGridObjects(WorldObject const *obj, T &visitor, float radius, bool dont_load=true)
Definition: CellImpl.h:178

References Acore::ComputeCellCoord(), WorldObject::GetMap(), Position::GetPositionX(), Position::GetPositionY(), GRID_MAP_TYPE_MASK_CORPSE, GRID_MAP_TYPE_MASK_CREATURE, GRID_MAP_TYPE_MASK_GAMEOBJECT, GRID_MAP_TYPE_MASK_PLAYER, Cell::SetNoCreate(), Cell::VisitGridObjects(), and Cell::VisitWorldObjects().

◆ SelectEffectImplicitTargets()

void Spell::SelectEffectImplicitTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType,
uint32 processedEffectMask 
)
927{
928 if (!targetType.GetTarget())
929 return;
930
931 uint32 effectMask = 1 << effIndex;
932 // set the same target list for all effects
933 // some spells appear to need this, however this requires more research
934 switch (targetType.GetSelectionCategory())
935 {
939 {
940 // targets for effect already selected
941 if (effectMask & processedEffectMask)
942 {
943 return;
944 }
945
946 auto const& effects = GetSpellInfo()->Effects;
947
948 // choose which targets we can select at once
949 for (uint32 j = effIndex + 1; j < MAX_SPELL_EFFECTS; ++j)
950 {
951 if (effects[j].IsEffect() &&
952 effects[effIndex].TargetA.GetTarget() == effects[j].TargetA.GetTarget() &&
953 effects[effIndex].TargetB.GetTarget() == effects[j].TargetB.GetTarget() &&
954 effects[effIndex].ImplicitTargetConditions == effects[j].ImplicitTargetConditions &&
955 effects[effIndex].CalcRadius(m_caster) == effects[j].CalcRadius(m_caster) &&
957 {
958 effectMask |= 1 << j;
959 }
960 }
961 processedEffectMask |= effectMask;
962 break;
963 }
964 default:
965 break;
966 }
967
968 switch (targetType.GetSelectionCategory())
969 {
971 SelectImplicitChannelTargets(effIndex, targetType);
972 break;
974 SelectImplicitNearbyTargets(effIndex, targetType, effectMask);
975 break;
977 SelectImplicitConeTargets(effIndex, targetType, effectMask);
978 break;
980 SelectImplicitAreaTargets(effIndex, targetType, effectMask);
981 break;
983 // just in case there is no dest, explanation in SelectImplicitDestDestTargets
984 CheckDst();
985
986 SelectImplicitTrajTargets(effIndex, targetType);
987 break;
989 switch (targetType.GetObjectType())
990 {
992 switch (targetType.GetReferenceType())
993 {
996 break;
997 default:
998 ASSERT(false && "Spell::SelectEffectImplicitTargets: received not implemented select target reference type for TARGET_TYPE_OBJECT_SRC");
999 break;
1000 }
1001 break;
1003 switch (targetType.GetReferenceType())
1004 {
1006 SelectImplicitCasterDestTargets(effIndex, targetType);
1007 break;
1009 SelectImplicitTargetDestTargets(effIndex, targetType);
1010 break;
1012 SelectImplicitDestDestTargets(effIndex, targetType);
1013 break;
1014 default:
1015 ASSERT(false && "Spell::SelectEffectImplicitTargets: received not implemented select target reference type for TARGET_TYPE_OBJECT_DEST");
1016 break;
1017 }
1018 break;
1019 default:
1020 switch (targetType.GetReferenceType())
1021 {
1023 SelectImplicitCasterObjectTargets(effIndex, targetType);
1024 break;
1026 SelectImplicitTargetObjectTargets(effIndex, targetType);
1027 break;
1028 default:
1029 ASSERT(false && "Spell::SelectEffectImplicitTargets: received not implemented select target reference type for TARGET_TYPE_OBJECT");
1030 break;
1031 }
1032 break;
1033 }
1034 break;
1036 LOG_DEBUG("spells.aura", "SPELL: target type {}, found in spellID {}, effect {} is not implemented yet!", m_spellInfo->Id, effIndex, targetType.GetTarget());
1037 break;
1038 default:
1039 ASSERT(false && "Spell::SelectEffectImplicitTargets: received not implemented select target category");
1040 break;
1041 }
1042}
@ TARGET_SELECT_CATEGORY_CONE
Definition: SpellInfo.h:81
@ TARGET_SELECT_CATEGORY_AREA
Definition: SpellInfo.h:82
@ TARGET_SELECT_CATEGORY_DEFAULT
Definition: SpellInfo.h:78
@ TARGET_SELECT_CATEGORY_NYI
Definition: SpellInfo.h:77
@ TARGET_SELECT_CATEGORY_TRAJ
Definition: SpellInfo.h:83
@ TARGET_SELECT_CATEGORY_CHANNEL
Definition: SpellInfo.h:79
@ TARGET_OBJECT_TYPE_SRC
Definition: SpellInfo.h:99
@ TARGET_REFERENCE_TYPE_TARGET
Definition: SpellInfo.h:90
@ TARGET_REFERENCE_TYPE_CASTER
Definition: SpellInfo.h:89
@ TARGET_REFERENCE_TYPE_DEST
Definition: SpellInfo.h:93
void SelectImplicitDestDestTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition: Spell.cpp:1721
void CheckDst()
Definition: Spell.h:495
void SelectImplicitTrajTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition: Spell.cpp:1870
void SelectImplicitConeTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType, uint32 effMask)
Definition: Spell.cpp:1214
void SelectImplicitTargetDestTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition: Spell.cpp:1684
void SelectImplicitAreaTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType, uint32 effMask)
Definition: Spell.cpp:1264
void SelectImplicitChannelTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition: Spell.cpp:1044
void SelectImplicitTargetObjectTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition: Spell.cpp:1807
void SelectImplicitCasterObjectTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition: Spell.cpp:1760
void SelectImplicitNearbyTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType, uint32 effMask)
Definition: Spell.cpp:1100
bool CheckScriptEffectImplicitTargets(uint32 effIndex, uint32 effIndexToCheck)
Definition: Spell.cpp:8725
void SelectImplicitCasterDestTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition: Spell.cpp:1346

References ASSERT, CheckDst(), CheckScriptEffectImplicitTargets(), SpellInfo::Effects, SpellImplicitTargetInfo::GetObjectType(), SpellImplicitTargetInfo::GetReferenceType(), SpellImplicitTargetInfo::GetSelectionCategory(), GetSpellInfo(), SpellImplicitTargetInfo::GetTarget(), SpellInfo::Id, LOG_DEBUG, m_caster, m_spellInfo, m_targets, MAX_SPELL_EFFECTS, SelectImplicitAreaTargets(), SelectImplicitCasterDestTargets(), SelectImplicitCasterObjectTargets(), SelectImplicitChannelTargets(), SelectImplicitConeTargets(), SelectImplicitDestDestTargets(), SelectImplicitNearbyTargets(), SelectImplicitTargetDestTargets(), SelectImplicitTargetObjectTargets(), SelectImplicitTrajTargets(), SpellCastTargets::SetSrc(), TARGET_OBJECT_TYPE_DEST, TARGET_OBJECT_TYPE_SRC, TARGET_REFERENCE_TYPE_CASTER, TARGET_REFERENCE_TYPE_DEST, TARGET_REFERENCE_TYPE_TARGET, TARGET_SELECT_CATEGORY_AREA, TARGET_SELECT_CATEGORY_CHANNEL, TARGET_SELECT_CATEGORY_CONE, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_SELECT_CATEGORY_NEARBY, TARGET_SELECT_CATEGORY_NYI, and TARGET_SELECT_CATEGORY_TRAJ.

Referenced by SelectSpellTargets().

◆ SelectEffectTypeImplicitTargets()

void Spell::SelectEffectTypeImplicitTargets ( uint8  effIndex)
Todo:
: this is a workaround - target shouldn't be stored in target map for those spells
Todo:
: this is a workaround - corpses should be added to spell target map too, but we can't do that so we add owner instead
2031{
2032 // special case for SPELL_EFFECT_SUMMON_RAF_FRIEND and SPELL_EFFECT_SUMMON_PLAYER
2034 switch (m_spellInfo->Effects[effIndex].Effect)
2035 {
2039 {
2041
2043
2044 if (target && target->ToPlayer())
2045 AddUnitTarget(target->ToUnit(), 1 << effIndex, false);
2046 }
2047 return;
2048 default:
2049 break;
2050 }
2051
2052 // select spell implicit targets based on effect type
2053 if (!m_spellInfo->Effects[effIndex].GetImplicitTargetType())
2054 return;
2055
2056 uint32 targetMask = m_spellInfo->Effects[effIndex].GetMissingTargetMask();
2057
2058 if (!targetMask)
2059 return;
2060
2061 WorldObject* target = nullptr;
2062
2063 switch (m_spellInfo->Effects[effIndex].GetImplicitTargetType())
2064 {
2065 // add explicit object target or self to the target map
2067 // player which not released his spirit is Unit, but target flag for it is TARGET_FLAG_CORPSE_MASK
2069 {
2071 target = unitTarget;
2072 else if (targetMask & TARGET_FLAG_CORPSE_MASK)
2073 {
2074 if (Corpse* corpseTarget = m_targets.GetCorpseTarget())
2075 {
2077 if (Player* owner = ObjectAccessor::FindPlayer(corpseTarget->GetOwnerGUID()))
2078 target = owner;
2079 }
2080 }
2081 else //if (targetMask & TARGET_FLAG_UNIT_MASK)
2082 target = m_caster;
2083 }
2084 if (targetMask & TARGET_FLAG_ITEM_MASK)
2085 {
2087 AddItemTarget(itemTarget, 1 << effIndex);
2088 return;
2089 }
2090 if (targetMask & TARGET_FLAG_GAMEOBJECT_MASK)
2091 target = m_targets.GetGOTarget();
2092 break;
2093 // add self to the target map
2095 if (targetMask & TARGET_FLAG_UNIT_MASK)
2096 target = m_caster;
2097 break;
2098 default:
2099 break;
2100 }
2101
2103
2104 if (target)
2105 {
2106 if (target->ToUnit())
2107 AddUnitTarget(target->ToUnit(), 1 << effIndex, false);
2108 else if (target->ToGameObject())
2109 AddGOTarget(target->ToGameObject(), 1 << effIndex);
2110 }
2111}
@ EFFECT_IMPLICIT_TARGET_CASTER
Definition: SpellInfo.h:144
@ EFFECT_IMPLICIT_TARGET_EXPLICIT
Definition: SpellInfo.h:143
@ TARGET_FLAG_ITEM_MASK
Definition: SpellInfo.h:72
GameObject * ToGameObject()
Definition: Object.h:213
Corpse * GetCorpseTarget() const
Definition: Spell.cpp:294
void AddGOTarget(GameObject *target, uint32 effectMask)
Definition: Spell.cpp:2517
void AddUnitTarget(Unit *target, uint32 effectMask, bool checkIfValid=true, bool implicit=true)
Definition: Spell.cpp:2384
void AddItemTarget(Item *item, uint32 effectMask)
Definition: Spell.cpp:2579
void CallScriptObjectTargetSelectHandlers(WorldObject *&target, SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition: Spell.cpp:8697
Definition: SpellInfo.h:217

References AddGOTarget(), AddItemTarget(), AddUnitTarget(), CallScriptObjectTargetSelectHandlers(), EFFECT_IMPLICIT_TARGET_CASTER, EFFECT_IMPLICIT_TARGET_EXPLICIT, SpellInfo::Effects, ObjectAccessor::FindPlayer(), SpellCastTargets::GetCorpseTarget(), SpellCastTargets::GetGOTarget(), SpellCastTargets::GetItemTarget(), Unit::GetTarget(), SpellCastTargets::GetUnitTarget(), Object::IsPlayer(), itemTarget, m_caster, m_spellInfo, m_targets, SPELL_EFFECT_SUMMON_PLAYER, SPELL_EFFECT_SUMMON_RAF_FRIEND, TARGET_FLAG_CORPSE_MASK, TARGET_FLAG_GAMEOBJECT_MASK, TARGET_FLAG_ITEM_MASK, TARGET_FLAG_UNIT_MASK, Object::ToGameObject(), Object::ToPlayer(), Object::ToUnit(), and unitTarget.

Referenced by SelectSpellTargets().

◆ SelectExplicitTargets()

void Spell::SelectExplicitTargets ( )
787{
788 // here go all explicit target changes made to explicit targets after spell prepare phase is finished
789 if (Unit* target = m_targets.GetUnitTarget())
790 {
791 // check for explicit target redirection, for Grounding Totem for example
795 {
796 Unit* redirect;
797 switch (m_spellInfo->DmgClass)
798 {
801 break;
805 break;
806 default:
807 redirect = nullptr;
808 break;
809 }
810 if (redirect && (redirect != target))
811 {
812 m_targets.SetUnitTarget(redirect);
814 }
815 }
816 }
817}
Unit * GetMeleeHitRedirectTarget(Unit *victim, SpellInfo const *spellInfo=nullptr)
Definition: Unit.cpp:11057
Unit * GetMagicHitRedirectTarget(Unit *victim, SpellInfo const *spellInfo)
Definition: Unit.cpp:11019

References SpellInfo::DmgClass, SpellInfo::GetExplicitTargetMask(), Unit::GetMagicHitRedirectTarget(), Unit::GetMeleeHitRedirectTarget(), SpellCastTargets::GetUnitTarget(), SpellInfo::HasEffect(), Unit::IsFriendlyTo(), SpellInfo::IsPositive(), m_caster, m_spellFlags, m_spellInfo, m_targets, SpellCastTargets::SetUnitTarget(), SPELL_DAMAGE_CLASS_MAGIC, SPELL_DAMAGE_CLASS_MELEE, SPELL_DAMAGE_CLASS_RANGED, SPELL_EFFECT_DISPEL, SPELL_FLAG_REDIRECTED, TARGET_FLAG_UNIT, and TARGET_FLAG_UNIT_ENEMY.

Referenced by SelectSpellTargets().

◆ SelectImplicitAreaTargets()

void Spell::SelectImplicitAreaTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType,
uint32  effMask 
)
1265{
1266 Unit* referer = nullptr;
1267 switch (targetType.GetReferenceType())
1268 {
1272 referer = m_caster;
1273 break;
1275 referer = m_targets.GetUnitTarget();
1276 break;
1278 {
1279 // find last added target for this effect
1280 for (std::list<TargetInfo>::reverse_iterator ihit = m_UniqueTargetInfo.rbegin(); ihit != m_UniqueTargetInfo.rend(); ++ihit)
1281 {
1282 if (ihit->effectMask & (1 << effIndex))
1283 {
1284 referer = ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID);
1285 break;
1286 }
1287 }
1288 break;
1289 }
1290 default:
1291 ASSERT(false && "Spell::SelectImplicitAreaTargets: received not implemented target reference type");
1292 return;
1293 }
1294 if (!referer)
1295 return;
1296
1297 Position const* center = nullptr;
1298 switch (targetType.GetReferenceType())
1299 {
1301 center = m_targets.GetSrcPos();
1302 break;
1304 center = m_targets.GetDstPos();
1305 break;
1309 center = referer;
1310 break;
1311 default:
1312 ASSERT(false && "Spell::SelectImplicitAreaTargets: received not implemented target reference type");
1313 return;
1314 }
1315
1316 // Xinef: the distance should be increased by caster size, it is neglected in latter calculations
1317 std::list<WorldObject*> targets;
1318 float radius = m_spellInfo->Effects[effIndex].CalcRadius(m_caster) * m_spellValue->RadiusMod;
1319 SearchAreaTargets(targets, radius, center, referer, targetType.GetObjectType(), targetType.GetCheckType(), m_spellInfo->Effects[effIndex].ImplicitTargetConditions);
1320
1321 CallScriptObjectAreaTargetSelectHandlers(targets, effIndex, targetType);
1322
1323 if (!targets.empty())
1324 {
1325 // Other special target selection goes here
1326 if (uint32 maxTargets = m_spellValue->MaxAffectedTargets)
1327 {
1329 for (Unit::AuraEffectList::const_iterator j = Auras.begin(); j != Auras.end(); ++j)
1330 if ((*j)->IsAffectedOnSpell(m_spellInfo))
1331 maxTargets += (*j)->GetAmount();
1332
1333 Acore::Containers::RandomResize(targets, maxTargets);
1334 }
1335
1336 for (std::list<WorldObject*>::iterator itr = targets.begin(); itr != targets.end(); ++itr)
1337 {
1338 if (Unit* unitTarget = (*itr)->ToUnit())
1339 AddUnitTarget(unitTarget, effMask, false);
1340 else if (GameObject* gObjTarget = (*itr)->ToGameObject())
1341 AddGOTarget(gObjTarget, effMask);
1342 }
1343 }
1344}
@ TARGET_REFERENCE_TYPE_SRC
Definition: SpellInfo.h:92
@ TARGET_REFERENCE_TYPE_LAST
Definition: SpellInfo.h:91
@ SPELL_AURA_MOD_MAX_AFFECTED_TARGETS
Definition: SpellAuraDefines.h:340
void RandomResize(C &container, std::size_t requestedSize)
Definition: Containers.h:79
Position const * GetSrcPos() const
Definition: Spell.cpp:362
float RadiusMod
Definition: Spell.h:217
uint32 MaxAffectedTargets
Definition: Spell.h:216
void CallScriptObjectAreaTargetSelectHandlers(std::list< WorldObject * > &targets, SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition: Spell.cpp:8683

References AddGOTarget(), AddUnitTarget(), ASSERT, CallScriptObjectAreaTargetSelectHandlers(), SpellInfo::Effects, Unit::GetAuraEffectsByType(), SpellImplicitTargetInfo::GetCheckType(), SpellCastTargets::GetDstPos(), SpellImplicitTargetInfo::GetObjectType(), SpellImplicitTargetInfo::GetReferenceType(), SpellCastTargets::GetSrcPos(), ObjectAccessor::GetUnit(), SpellCastTargets::GetUnitTarget(), m_caster, m_spellInfo, m_spellValue, m_targets, m_UniqueTargetInfo, SpellValue::MaxAffectedTargets, SpellValue::RadiusMod, Acore::Containers::RandomResize(), SearchAreaTargets(), SPELL_AURA_MOD_MAX_AFFECTED_TARGETS, TARGET_REFERENCE_TYPE_CASTER, TARGET_REFERENCE_TYPE_DEST, TARGET_REFERENCE_TYPE_LAST, TARGET_REFERENCE_TYPE_SRC, TARGET_REFERENCE_TYPE_TARGET, Object::ToGameObject(), Object::ToUnit(), and unitTarget.

Referenced by SelectEffectImplicitTargets().

◆ SelectImplicitCasterDestTargets()

void Spell::SelectImplicitCasterDestTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType 
)
Todo:
fix this check
1347{
1349
1350 switch (targetType.GetTarget())
1351 {
1352 case TARGET_DEST_CASTER:
1354 break;
1355 case TARGET_DEST_HOME:
1356 if (Player* playerCaster = m_caster->ToPlayer())
1357 dest = SpellDestination(playerCaster->m_homebindX, playerCaster->m_homebindY, playerCaster->m_homebindZ, playerCaster->GetOrientation(), playerCaster->m_homebindMapId);
1358 break;
1359 case TARGET_DEST_DB:
1360 if (SpellTargetPosition const* st = sSpellMgr->GetSpellTargetPosition(m_spellInfo->Id, effIndex))
1361 {
1364 dest = SpellDestination(st->target_X, st->target_Y, st->target_Z, st->target_Orientation, (int32)st->target_mapId);
1365 else if (st->target_mapId == m_caster->GetMapId())
1366 dest = SpellDestination(st->target_X, st->target_Y, st->target_Z, st->target_Orientation);
1367 }
1368 else
1369 {
1370 LOG_DEBUG("spells.aura", "SPELL: unknown target coordinates for spell ID {}", m_spellInfo->Id);
1371 if (WorldObject* target = m_targets.GetObjectTarget())
1372 dest = SpellDestination(*target);
1373 }
1374 break;
1376 {
1377 float min_dis = m_spellInfo->GetMinRange(true);
1378 float max_dis = m_spellInfo->GetMaxRange(true);
1379 float dis = (float)rand_norm() * (max_dis - min_dis) + min_dis;
1380 float x, y, z, angle;
1381 angle = (float)rand_norm() * static_cast<float>(M_PI * 35.0f / 180.0f) - static_cast<float>(M_PI * 17.5f / 180.0f);
1382 //m_caster->GetClosePoint(x, y, z, DEFAULT_WORLD_OBJECT_SIZE, dis, angle); this contains extra code that breaks fishing
1384
1385 float ground = m_caster->GetMapHeight(x, y, z, true);
1386 float liquidLevel = VMAP_INVALID_HEIGHT_VALUE;
1388 if (liquidData.Status)
1389 liquidLevel = liquidData.Level;
1390
1391 if (liquidLevel <= ground) // When there is no liquid Map::GetWaterOrGroundLevel returns ground level
1392 {
1395 finish(false);
1396 return;
1397 }
1398
1399 if (ground + 0.75 > liquidLevel)
1400 {
1403 finish(false);
1404 return;
1405 }
1406
1407 if (!m_caster->IsWithinLOS(x, y, z))
1408 {
1411 finish(false);
1412 return;
1413 }
1414
1415 dest = SpellDestination(x, y, liquidLevel, m_caster->GetOrientation());
1416 break;
1417 }
1419 {
1420 float distance = m_spellInfo->Effects[effIndex].CalcRadius(m_caster);
1421 Map* map = m_caster->GetMap();
1422 uint32 mapid = m_caster->GetMapId();
1423 uint32 phasemask = m_caster->GetPhaseMask();
1424 float collisionHeight = m_caster->GetCollisionHeight();
1425 float destz = 0.0f, startx = 0.0f, starty = 0.0f, startz = 0.0f, starto = 0.0f;
1426
1427 Position pos;
1428 Position lastpos;
1429 m_caster->GetPosition(startx, starty, startz, starto);
1430 pos.Relocate(startx, starty, startz, starto);
1431 float destx = pos.GetPositionX() + distance * cos(pos.GetOrientation());
1432 float desty = pos.GetPositionY() + distance * sin(pos.GetOrientation());
1433
1434 float ground = map->GetHeight(phasemask, pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ());
1435
1436 bool isCasterInWater = m_caster->IsInWater();
1437 if (!m_caster->HasUnitMovementFlag(MOVEMENTFLAG_FALLING) || (pos.GetPositionZ() - ground < distance))
1438 {
1439 float tstX = 0.0f, tstY = 0.0f, tstZ = 0.0f, prevX = 0.0f, prevY = 0.0f, prevZ = 0.0f;
1440 float tstZ1 = 0.0f, tstZ2 = 0.0f, tstZ3 = 0.0f, destz1 = 0.0f, destz2 = 0.0f, destz3 = 0.0f, srange = 0.0f, srange1 = 0.0f, srange2 = 0.0f, srange3 = 0.0f;
1441 float maxtravelDistZ = 2.65f;
1442 float overdistance = 0.0f;
1443 float totalpath = 0.0f;
1444 float beforewaterz = 0.0f;
1445 bool inwater = false;
1446 bool wcol = false;
1447 const float step = 2.0f;
1448 const uint8 numChecks = std::ceil(std::fabs(distance / step));
1449 const float DELTA_X = (destx - pos.GetPositionX()) / numChecks;
1450 const float DELTA_Y = (desty - pos.GetPositionY()) / numChecks;
1451 int j = 1;
1452 for (; j < (numChecks + 1); j++)
1453 {
1454 prevX = pos.GetPositionX() + (float(j - 1) * DELTA_X);
1455 prevY = pos.GetPositionY() + (float(j - 1) * DELTA_Y);
1456 tstX = pos.GetPositionX() + (float(j) * DELTA_X);
1457 tstY = pos.GetPositionY() + (float(j) * DELTA_Y);
1458
1459 if (j < 2)
1460 {
1461 prevZ = pos.GetPositionZ();
1462 }
1463 else
1464 {
1465 prevZ = tstZ;
1466 }
1467
1468 tstZ = map->GetHeight(phasemask, tstX, tstY, prevZ + maxtravelDistZ, true);
1469 ground = tstZ;
1470
1471 if (!isCasterInWater)
1472 {
1473 if (map->IsInWater(phasemask, tstX, tstY, tstZ, collisionHeight))
1474 {
1475 if (!(beforewaterz != 0.0f))
1476 {
1477 beforewaterz = prevZ;
1478 }
1479 tstZ = beforewaterz;
1480 srange = sqrt((tstY - prevY) * (tstY - prevY) + (tstX - prevX) * (tstX - prevX));
1481 //LOG_ERROR("spells", "(start was from land) step in water , number of cycle = {} , distance of step = {}, total path = {}, Z = {}", j, srange, totalpath, tstZ);
1482 }
1483 }
1484 else if (map->IsInWater(phasemask, tstX, tstY, tstZ, collisionHeight))
1485 {
1486 prevZ = pos.GetPositionZ();
1487 tstZ = pos.GetPositionZ();
1488 srange = sqrt((tstY - prevY) * (tstY - prevY) + (tstX - prevX) * (tstX - prevX));
1489
1490 inwater = true;
1491 if (inwater && (fabs(tstZ - ground) < 2.0f))
1492 {
1493 wcol = true;
1494 //LOG_ERROR("spells", "step in water with collide and use standart check (for continue way after possible collide), number of cycle = {} ", j);
1495 }
1496
1497 // if (j < 2)
1498 // LOG_ERROR("spells", "(start in water) step in water, number of cycle = {} , distance of step = {}, total path = {}", j, srange, totalpath);
1499 // else
1500 // LOG_ERROR("spells", "step in water, number of cycle = {} , distance of step = {}, total path = {}", j, srange, totalpath);
1501 }
1502
1503 bool IsInWater = map->IsInWater(phasemask, tstX, tstY, tstZ, collisionHeight);
1504 if ((!IsInWater && tstZ != beforewaterz) || wcol) // second safety check z for blink way if on the ground
1505 {
1506 if (inwater && !IsInWater)
1507 inwater = false;
1508
1509 // highest available point
1510 tstZ1 = map->GetHeight(phasemask, tstX, tstY, prevZ + maxtravelDistZ, true, 25.0f);
1511 // upper or floor
1512 tstZ2 = map->GetHeight(phasemask, tstX, tstY, prevZ, true, 25.0f);
1513 //lower than floor
1514 tstZ3 = map->GetHeight(phasemask, tstX, tstY, prevZ - maxtravelDistZ / 2, true, 25.0f);
1515
1516 //distance of rays, will select the shortest in 3D
1517 srange1 = sqrt((tstY - prevY) * (tstY - prevY) + (tstX - prevX) * (tstX - prevX) + (tstZ1 - prevZ) * (tstZ1 - prevZ));
1518 //LOG_ERROR("spells", "step = {}, distance of ray1 = {}", j, srange1);
1519 srange2 = sqrt((tstY - prevY) * (tstY - prevY) + (tstX - prevX) * (tstX - prevX) + (tstZ2 - prevZ) * (tstZ2 - prevZ));
1520 //LOG_ERROR("spells", "step = {}, distance of ray2 = {}", j, srange2);
1521 srange3 = sqrt((tstY - prevY) * (tstY - prevY) + (tstX - prevX) * (tstX - prevX) + (tstZ3 - prevZ) * (tstZ3 - prevZ));
1522 //LOG_ERROR("spells", "step = {}, distance of ray3 = {}", j, srange3);
1523
1524 if (srange1 < srange2)
1525 {
1526 tstZ = tstZ1;
1527 srange = srange1;
1528 }
1529 else if (srange3 < srange2)
1530 {
1531 tstZ = tstZ3;
1532 srange = srange3;
1533 }
1534 else
1535 {
1536 tstZ = tstZ2;
1537 srange = srange2;
1538 }
1539
1540 //LOG_ERROR("spells", "step on ground, number of cycle = {} , distance of step = {}, total path = {}", j, srange, totalpath);
1541 }
1542
1543 destx = tstX;
1544 desty = tstY;
1545 destz = tstZ;
1546
1547 totalpath += srange;
1548
1549 if (totalpath > distance)
1550 {
1551 overdistance = totalpath - distance;
1552 //LOG_ERROR("spells", "total path > than distance in 3D , need to move back a bit for save distance, total path = {}, overdistance = {}", totalpath, overdistance);
1553 }
1554
1555 bool col = VMAP::VMapFactory::createOrGetVMapMgr()->GetObjectHitPos(mapid, prevX, prevY, prevZ + 0.5f, tstX, tstY, tstZ + 0.5f, tstX, tstY, tstZ, -0.5f);
1556 // check dynamic collision
1557 bool dcol = m_caster->GetMap()->GetObjectHitPos(phasemask, prevX, prevY, prevZ + 0.5f, tstX, tstY, tstZ + 0.5f, tstX, tstY, tstZ, -0.5f);
1558
1559 // collision occured
1560 if (col || dcol || (overdistance > 0.0f && !map->IsInWater(phasemask, tstX, tstY, ground, collisionHeight)) || (fabs(prevZ - tstZ) > maxtravelDistZ && (tstZ > prevZ)))
1561 {
1562 if ((overdistance > 0.0f) && (overdistance < 1.f))
1563 {
1564 destx = prevX + overdistance * cos(pos.GetOrientation());
1565 desty = prevY + overdistance * sin(pos.GetOrientation());
1566 //LOG_ERROR("spells", "(collision) collision occured 1");
1567 }
1568 else
1569 {
1570 // move back a bit
1571 destx = tstX - (0.6 * cos(pos.GetOrientation()));
1572 desty = tstY - (0.6 * sin(pos.GetOrientation()));
1573 //LOG_ERROR("spells", "(collision) collision occured 2");
1574 }
1575
1576 // highest available point
1577 destz1 = map->GetHeight(phasemask, destx, desty, prevZ + maxtravelDistZ, true, 25.0f);
1578 // upper or floor
1579 destz2 = map->GetHeight(phasemask, destx, desty, prevZ, true, 25.0f);
1580 //lower than floor
1581 destz3 = map->GetHeight(phasemask, destx, desty, prevZ - maxtravelDistZ / 2, true, 25.0f);
1582
1583 //distance of rays, will select the shortest in 3D
1584 srange1 = sqrt((desty - prevY) * (desty - prevY) + (destx - prevX) * (destx - prevX) + (destz1 - prevZ) * (destz1 - prevZ));
1585 srange2 = sqrt((desty - prevY) * (desty - prevY) + (destx - prevX) * (destx - prevX) + (destz2 - prevZ) * (destz2 - prevZ));
1586 srange3 = sqrt((desty - prevY) * (desty - prevY) + (destx - prevX) * (destx - prevX) + (destz3 - prevZ) * (destz3 - prevZ));
1587
1588 if (srange1 < srange2)
1589 destz = destz1;
1590 else if (srange3 < srange2)
1591 destz = destz3;
1592 else
1593 destz = destz2;
1594
1595 if (inwater && destz < prevZ && !wcol)
1596 destz = prevZ;
1597 //LOG_ERROR("spells", "(collision) destZ rewrited in prevZ");
1598
1599 // Don't make the player move backward from the xy adjustments by collisions.
1600 if ((DELTA_X > 0 && startx > destx) || (DELTA_X < 0 && startx < destx) ||
1601 (DELTA_Y > 0 && starty > desty) || (DELTA_Y < 0 && starty < desty))
1602 {
1603 destx = startx;
1604 desty = starty;
1605 destz = startz;
1606 }
1607
1608 break;
1609 }
1610 // we have correct destz now
1611 }
1612
1613 lastpos.Relocate(destx, desty, destz, pos.GetOrientation());
1614 dest = SpellDestination(lastpos);
1615 }
1616 else
1617 {
1618 float z = pos.GetPositionZ();
1619 bool col = VMAP::VMapFactory::createOrGetVMapMgr()->GetObjectHitPos(mapid, pos.GetPositionX(), pos.GetPositionY(), z, destx, desty, z, destx, desty, z, -0.5f);
1620 // check dynamic collision
1621 bool dcol = m_caster->GetMap()->GetObjectHitPos(phasemask, pos.GetPositionX(), pos.GetPositionY(), z, destx, desty, z, destx, desty, z, -0.5f);
1622
1623 // collision occured
1624 if (col || dcol)
1625 {
1626 // move back a bit
1627 destx = destx - (0.6 * cos(pos.GetOrientation()));
1628 desty = desty - (0.6 * sin(pos.GetOrientation()));
1629 }
1630
1631 lastpos.Relocate(destx, desty, z, pos.GetOrientation());
1632 dest = SpellDestination(lastpos);
1633 //float range = sqrt((desty - pos.GetPositionY())*(desty - pos.GetPositionY()) + (destx - pos.GetPositionX())*(destx - pos.GetPositionX()));
1634 //LOG_ERROR("spells", "Blink number 2, in falling but at a hight, distance of blink = {}", range);
1635 }
1636 break;
1637 }
1638 default:
1639 {
1640 float dist = m_spellInfo->Effects[effIndex].CalcRadius(m_caster);
1641 float angle = targetType.CalcDirectionAngle();
1642 float objSize = m_caster->GetCombatReach();
1643
1644 switch (targetType.GetTarget())
1645 {
1647 dist = PET_FOLLOW_DIST;
1648 break;
1650 if (dist > objSize)
1651 dist = objSize + (dist - objSize) * float(rand_norm());
1652 break;
1657 {
1658 static float const DefaultTotemDistance = 3.0f;
1659 if (!m_spellInfo->Effects[effIndex].HasRadius())
1660 dist = DefaultTotemDistance;
1661 break;
1662 }
1663 default:
1664 break;
1665 }
1666
1667 if (dist < objSize)
1668 {
1669 dist = objSize;
1670 }
1671
1672 Position pos = dest._position;
1673 m_caster->MovePositionToFirstCollision(pos, dist, angle);
1674
1675 dest.Relocate(pos);
1676 break;
1677 }
1678 }
1679
1680 CallScriptDestinationTargetSelectHandlers(dest, effIndex, targetType);
1681 m_targets.SetDst(dest);
1682}
#define VMAP_INVALID_HEIGHT_VALUE
Definition: IVMapMgr.h:49
@ SPELL_EFFECT_BIND
Definition: SharedDefines.h:789
@ SPELL_EFFECT_TELEPORT_UNITS
Definition: SharedDefines.h:783
@ TARGET_DEST_CASTER_RANDOM
Definition: SharedDefines.h:1476
@ TARGET_DEST_DB
Definition: SharedDefines.h:1422
@ TARGET_DEST_CASTER_FRONT_LEAP
Definition: SharedDefines.h:1459
@ TARGET_DEST_CASTER_FRONT_LEFT
Definition: SharedDefines.h:1448
@ TARGET_DEST_CASTER_BACK_RIGHT
Definition: SharedDefines.h:1446
@ TARGET_DEST_CASTER_FISHING
Definition: SharedDefines.h:1443
@ TARGET_DEST_CASTER_BACK_LEFT
Definition: SharedDefines.h:1447
@ TARGET_DEST_CASTER_SUMMON
Definition: SharedDefines.h:1436
@ TARGET_DEST_CASTER
Definition: SharedDefines.h:1423
@ TARGET_DEST_CASTER_FRONT_RIGHT
Definition: SharedDefines.h:1445
@ TARGET_DEST_CASTER_36
Definition: SharedDefines.h:1440
@ TARGET_DEST_HOME
Definition: SharedDefines.h:1418
@ SPELL_FAILED_TOO_SHALLOW
Definition: SharedDefines.h:1105
#define MAP_ALL_LIQUIDS
Definition: Map.h:158
@ MOVEMENTFLAG_FALLING
Definition: UnitDefines.h:356
static VMapMgr2 * createOrGetVMapMgr()
Definition: VMapFactory.cpp:27
bool GetObjectHitPos(unsigned int mapId, float x1, float y1, float z1, float x2, float y2, float z2, float &rx, float &ry, float &rz, float modifyDist) override
Definition: VMapMgr2.cpp:201
float GetMapHeight(float x, float y, float z, bool vmap=true, float distanceToSearch=50.0f) const
Definition: Object.cpp:3131
void GetNearPoint(WorldObject const *searcher, float &x, float &y, float &z, float searcher_size, float distance2d, float absAngle, float controlZ=0, Position const *startPos=nullptr) const
Definition: Object.cpp:2637
float GetCollisionHeight() const override
Return collision height sent to client.
Definition: Unit.cpp:21106
Definition: Map.h:169
float Level
Definition: Map.h:174
LiquidStatus Status
Definition: Map.h:176
float GetHeight(float x, float y, float z, bool checkVMap=true, float maxSearchDist=DEFAULT_HEIGHT_SEARCH) const
Definition: Map.cpp:2043
LiquidData const GetLiquidData(uint32 phaseMask, float x, float y, float z, float collisionHeight, uint8 ReqLiquidType)
Definition: Map.cpp:2204
bool IsInWater(uint32 phaseMask, float x, float y, float z, float collisionHeight) const
Definition: Map.cpp:2503
bool GetObjectHitPos(uint32 phasemask, float x1, float y1, float z1, float x2, float y2, float z2, float &rx, float &ry, float &rz, float modifyDist)
Definition: Map.cpp:2481
void CallScriptDestinationTargetSelectHandlers(SpellDestination &target, SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition: Spell.cpp:8711
Definition: SpellMgr.h:396

References SpellDestination::_position, SpellImplicitTargetInfo::CalcDirectionAngle(), CallScriptDestinationTargetSelectHandlers(), VMAP::VMapFactory::createOrGetVMapMgr(), DEFAULT_WORLD_OBJECT_SIZE, SpellInfo::Effects, finish(), Unit::GetCollisionHeight(), Unit::GetCombatReach(), Map::GetHeight(), Map::GetLiquidData(), WorldObject::GetMap(), WorldObject::GetMapHeight(), WorldLocation::GetMapId(), SpellInfo::GetMaxRange(), SpellInfo::GetMinRange(), WorldObject::GetNearPoint(), Map::GetObjectHitPos(), VMAP::VMapMgr2::GetObjectHitPos(), SpellCastTargets::GetObjectTarget(), Position::GetOrientation(), WorldObject::GetPhaseMask(), Position::GetPosition(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), SpellImplicitTargetInfo::GetTarget(), SpellInfo::HasEffect(), Unit::HasUnitMovementFlag(), SpellInfo::Id, Unit::IsInWater(), Map::IsInWater(), WorldObject::IsWithinLOS(), LiquidData::Level, LOG_DEBUG, m_caster, m_spellInfo, m_targets, MAP_ALL_LIQUIDS, MOVEMENTFLAG_FALLING, WorldObject::MovePositionToFirstCollision(), PET_FOLLOW_DIST, rand_norm(), Position::Relocate(), SpellDestination::Relocate(), SendCastResult(), SendChannelUpdate(), SpellCastTargets::SetDst(), SPELL_EFFECT_BIND, SPELL_EFFECT_TELEPORT_UNITS, SPELL_FAILED_LINE_OF_SIGHT, SPELL_FAILED_NOT_HERE, SPELL_FAILED_TOO_SHALLOW, sSpellMgr, LiquidData::Status, TARGET_DEST_CASTER, TARGET_DEST_CASTER_36, TARGET_DEST_CASTER_BACK_LEFT, TARGET_DEST_CASTER_BACK_RIGHT, TARGET_DEST_CASTER_FISHING, TARGET_DEST_CASTER_FRONT_LEAP, TARGET_DEST_CASTER_FRONT_LEFT, TARGET_DEST_CASTER_FRONT_RIGHT, TARGET_DEST_CASTER_RANDOM, TARGET_DEST_CASTER_SUMMON, TARGET_DEST_DB, TARGET_DEST_HOME, Object::ToPlayer(), and VMAP_INVALID_HEIGHT_VALUE.

Referenced by SelectEffectImplicitTargets().

◆ SelectImplicitCasterObjectTargets()

void Spell::SelectImplicitCasterObjectTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType 
)
1761{
1762 WorldObject* target = nullptr;
1763 bool checkIfValid = true;
1764
1765 switch (targetType.GetTarget())
1766 {
1767 case TARGET_UNIT_CASTER:
1768 target = m_caster;
1769 checkIfValid = false;
1770 break;
1771 case TARGET_UNIT_MASTER:
1772 target = m_caster->GetCharmerOrOwner();
1773 break;
1774 case TARGET_UNIT_PET:
1775 target = m_caster->GetGuardianPet();
1776 if (!target)
1777 target = m_caster->GetCharm();
1778 break;
1780 if (m_caster->IsSummon())
1781 target = m_caster->ToTempSummon()->GetSummonerUnit();
1782 break;
1784 target = m_caster->GetVehicleBase();
1785 break;
1795 target = m_caster->GetVehicleKit()->GetPassenger(targetType.GetTarget() - TARGET_UNIT_PASSENGER_0);
1796 break;
1797 default:
1798 break;
1799 }
1800
1801 CallScriptObjectTargetSelectHandlers(target, effIndex, targetType);
1802
1803 if (target && target->ToUnit())
1804 AddUnitTarget(target->ToUnit(), 1 << effIndex, checkIfValid);
1805}
@ TARGET_UNIT_PASSENGER_1
Definition: SharedDefines.h:1501
@ TARGET_UNIT_PASSENGER_6
Definition: SharedDefines.h:1506
@ TARGET_UNIT_VEHICLE
Definition: SharedDefines.h:1498
@ TARGET_UNIT_PASSENGER_2
Definition: SharedDefines.h:1502
@ TARGET_UNIT_PASSENGER_4
Definition: SharedDefines.h:1504
@ TARGET_UNIT_PASSENGER_7
Definition: SharedDefines.h:1507
@ TARGET_UNIT_MASTER
Definition: SharedDefines.h:1431
@ TARGET_UNIT_PASSENGER_5
Definition: SharedDefines.h:1505
@ TARGET_UNIT_PASSENGER_3
Definition: SharedDefines.h:1503
@ TARGET_UNIT_SUMMONER
Definition: SharedDefines.h:1496
@ TARGET_UNIT_PASSENGER_0
Definition: SharedDefines.h:1500
Unit * GetSummonerUnit() const
Definition: TemporarySummon.cpp:44
Unit * GetVehicleBase() const
Definition: Unit.cpp:18742
Unit * GetPassenger(int8 seatId) const
Definition: Vehicle.cpp:227

References AddUnitTarget(), CallScriptObjectTargetSelectHandlers(), Unit::GetCharm(), Unit::GetCharmerOrOwner(), Unit::GetGuardianPet(), Vehicle::GetPassenger(), TempSummon::GetSummonerUnit(), SpellImplicitTargetInfo::GetTarget(), Unit::GetVehicleBase(), Unit::GetVehicleKit(), Object::IsCreature(), Unit::IsSummon(), Unit::IsVehicle(), m_caster, TARGET_UNIT_CASTER, TARGET_UNIT_MASTER, TARGET_UNIT_PASSENGER_0, TARGET_UNIT_PASSENGER_1, TARGET_UNIT_PASSENGER_2, TARGET_UNIT_PASSENGER_3, TARGET_UNIT_PASSENGER_4, TARGET_UNIT_PASSENGER_5, TARGET_UNIT_PASSENGER_6, TARGET_UNIT_PASSENGER_7, TARGET_UNIT_PET, TARGET_UNIT_SUMMONER, TARGET_UNIT_VEHICLE, Object::ToCreature(), Unit::ToTempSummon(), and Object::ToUnit().

Referenced by SelectEffectImplicitTargets().

◆ SelectImplicitChainTargets()

void Spell::SelectImplicitChainTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType,
WorldObject target,
uint32  effMask 
)
1830{
1831 uint32 maxTargets = m_spellInfo->Effects[effIndex].ChainTarget;
1832 if (Player* modOwner = m_caster->GetSpellModOwner())
1833 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_JUMP_TARGETS, maxTargets, this);
1834
1835 if (maxTargets > 1)
1836 {
1837 // mark damage multipliers as used
1838 for (uint32 k = effIndex; k < MAX_SPELL_EFFECTS; ++k)
1839 if (effMask & (1 << k))
1840 m_damageMultipliers[k] = 1.0f;
1841 m_applyMultiplierMask |= effMask;
1842
1843 std::list<WorldObject*> targets;
1844 SearchChainTargets(targets, maxTargets - 1, target, targetType.GetObjectType(), targetType.GetCheckType(), targetType.GetSelectionCategory()
1845 , m_spellInfo->Effects[effIndex].ImplicitTargetConditions, targetType.GetTarget() == TARGET_UNIT_TARGET_CHAINHEAL_ALLY);
1846
1847 // Chain primary target is added earlier
1848 CallScriptObjectAreaTargetSelectHandlers(targets, effIndex, targetType);
1849
1850 for (std::list<WorldObject*>::iterator itr = targets.begin(); itr != targets.end(); ++itr)
1851 if (Unit* unitTarget = (*itr)->ToUnit())
1852 AddUnitTarget(unitTarget, effMask, false);
1853 }
1854}
@ TARGET_UNIT_TARGET_CHAINHEAL_ALLY
Definition: SharedDefines.h:1449
@ SPELLMOD_JUMP_TARGETS
Definition: SpellDefines.h:93
void SearchChainTargets(std::list< WorldObject * > &targets, uint32 chainTargets, WorldObject *target, SpellTargetObjectTypes objectType, SpellTargetCheckTypes selectType, SpellTargetSelectionCategories selectCategory, ConditionList *condList, bool isChainHeal)
Definition: Spell.cpp:2199

References AddUnitTarget(), CallScriptObjectAreaTargetSelectHandlers(), SpellInfo::Effects, SpellImplicitTargetInfo::GetCheckType(), SpellImplicitTargetInfo::GetObjectType(), SpellImplicitTargetInfo::GetSelectionCategory(), Unit::GetSpellModOwner(), SpellImplicitTargetInfo::GetTarget(), SpellInfo::Id, m_applyMultiplierMask, m_caster, m_damageMultipliers, m_spellInfo, MAX_SPELL_EFFECTS, SearchChainTargets(), SPELLMOD_JUMP_TARGETS, TARGET_UNIT_TARGET_CHAINHEAL_ALLY, Object::ToUnit(), and unitTarget.

Referenced by SelectImplicitNearbyTargets(), and SelectImplicitTargetObjectTargets().

◆ SelectImplicitChannelTargets()

void Spell::SelectImplicitChannelTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType 
)
1045{
1046 if (targetType.GetReferenceType() != TARGET_REFERENCE_TYPE_CASTER)
1047 {
1048 ASSERT(false && "Spell::SelectImplicitChannelTargets: received not implemented target reference type");
1049 return;
1050 }
1051
1052 switch (targetType.GetTarget())
1053 {
1055 {
1056 // Xinef: All channel selectors have needed data passed in m_targets structure
1058 if (target)
1059 {
1060 CallScriptObjectTargetSelectHandlers(target, effIndex, targetType);
1061 // unit target may be no longer avalible - teleported out of map for example
1062 if (target && target->ToUnit())
1063 AddUnitTarget(target->ToUnit(), 1 << effIndex);
1064 }
1065 else
1066 {
1067 LOG_DEBUG("spells.aura", "SPELL: cannot find channel spell target for spell ID {}, effect {}", m_spellInfo->Id, effIndex);
1068 }
1069 break;
1070 }
1075 {
1076 CallScriptObjectTargetSelectHandlers(target, effIndex, targetType);
1077 if (target)
1078 m_targets.SetDst(*target);
1079 }
1081 {
1082 if (channeledSpell->m_targets.GetUnitTarget())
1083 m_targets.SetDst(*channeledSpell->m_targets.GetUnitTarget());
1084 }
1085 else //if (!m_targets.HasDst())
1086 {
1087 LOG_DEBUG("spells.aura", "SPELL: cannot find channel spell destination for spell ID {}, effect {}", m_spellInfo->Id, effIndex);
1088 }
1089 break;
1091 if (GetOriginalCaster())
1093 break;
1094 default:
1095 ASSERT(false && "Spell::SelectImplicitChannelTargets: received not implemented target type");
1096 break;
1097 }
1098}
@ TARGET_DEST_CHANNEL_TARGET
Definition: SharedDefines.h:1480
@ TARGET_UNIT_CHANNEL_TARGET
Definition: SharedDefines.h:1481
@ TARGET_DEST_CHANNEL_CASTER
Definition: SharedDefines.h:1510
WorldObject * GetObjectTargetChannel(Unit *caster) const
Definition: Spell.cpp:464
SpellDestination const * GetDstChannel() const
Definition: Spell.cpp:474
bool HasDstChannel() const
Definition: Spell.cpp:469

References AddUnitTarget(), ASSERT, CallScriptObjectTargetSelectHandlers(), CURRENT_CHANNELED_SPELL, Unit::GetCurrentSpell(), SpellCastTargets::GetDstChannel(), SpellCastTargets::GetObjectTargetChannel(), GetOriginalCaster(), SpellImplicitTargetInfo::GetReferenceType(), SpellImplicitTargetInfo::GetTarget(), SpellCastTargets::HasDstChannel(), SpellInfo::Id, LOG_DEBUG, m_caster, m_originalCaster, m_spellInfo, m_targets, SpellCastTargets::SetDst(), TARGET_DEST_CHANNEL_CASTER, TARGET_DEST_CHANNEL_TARGET, TARGET_REFERENCE_TYPE_CASTER, TARGET_UNIT_CHANNEL_TARGET, and Object::ToUnit().

Referenced by SelectEffectImplicitTargets().

◆ SelectImplicitConeTargets()

void Spell::SelectImplicitConeTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType,
uint32  effMask 
)
1215{
1216 if (targetType.GetReferenceType() != TARGET_REFERENCE_TYPE_CASTER)
1217 {
1218 ASSERT(false && "Spell::SelectImplicitConeTargets: received not implemented target reference type");
1219 return;
1220 }
1221 std::list<WorldObject*> targets;
1222 SpellTargetObjectTypes objectType = targetType.GetObjectType();
1223 SpellTargetCheckTypes selectionType = targetType.GetCheckType();
1224 ConditionList* condList = m_spellInfo->Effects[effIndex].ImplicitTargetConditions;
1225 float coneAngle = M_PI / 2;
1226 float radius = m_spellInfo->Effects[effIndex].CalcRadius(m_caster) * m_spellValue->RadiusMod;
1227
1228 if (uint32 containerTypeMask = GetSearcherTypeMask(objectType, condList))
1229 {
1230 Acore::WorldObjectSpellConeTargetCheck check(coneAngle, radius, m_caster, m_spellInfo, selectionType, condList);
1231 Acore::WorldObjectListSearcher<Acore::WorldObjectSpellConeTargetCheck> searcher(m_caster, targets, check, containerTypeMask);
1232 SearchTargets<Acore::WorldObjectListSearcher<Acore::WorldObjectSpellConeTargetCheck> >(searcher, containerTypeMask, m_caster, m_caster, radius);
1233
1234 CallScriptObjectAreaTargetSelectHandlers(targets, effIndex, targetType);
1235
1236 if (!targets.empty())
1237 {
1238 // Other special target selection goes here
1239 if (uint32 maxTargets = m_spellValue->MaxAffectedTargets)
1240 {
1242 for (Unit::AuraEffectList::const_iterator j = Auras.begin(); j != Auras.end(); ++j)
1243 if ((*j)->IsAffectedOnSpell(m_spellInfo))
1244 maxTargets += (*j)->GetAmount();
1245
1246 Acore::Containers::RandomResize(targets, maxTargets);
1247 }
1248
1249 for (std::list<WorldObject*>::iterator itr = targets.begin(); itr != targets.end(); ++itr)
1250 {
1251 if (Unit* unit = (*itr)->ToUnit())
1252 {
1253 AddUnitTarget(unit, effMask, false);
1254 }
1255 else if (GameObject* gObjTarget = (*itr)->ToGameObject())
1256 {
1257 AddGOTarget(gObjTarget, effMask);
1258 }
1259 }
1260 }
1261 }
1262}
SpellTargetCheckTypes
Definition: SpellInfo.h:113
SpellTargetObjectTypes
Definition: SpellInfo.h:97

References AddGOTarget(), AddUnitTarget(), ASSERT, CallScriptObjectAreaTargetSelectHandlers(), SpellInfo::Effects, Unit::GetAuraEffectsByType(), SpellImplicitTargetInfo::GetCheckType(), SpellImplicitTargetInfo::GetObjectType(), SpellImplicitTargetInfo::GetReferenceType(), GetSearcherTypeMask(), m_caster, m_spellInfo, m_spellValue, SpellValue::MaxAffectedTargets, SpellValue::RadiusMod, Acore::Containers::RandomResize(), SPELL_AURA_MOD_MAX_AFFECTED_TARGETS, TARGET_REFERENCE_TYPE_CASTER, Object::ToGameObject(), and Object::ToUnit().

Referenced by SelectEffectImplicitTargets().

◆ SelectImplicitDestDestTargets()

void Spell::SelectImplicitDestDestTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType 
)
1722{
1723 // set destination to caster if no dest provided
1724 // can only happen if previous destination target could not be set for some reason
1725 // (not found nearby target, or channel target for example
1726 // maybe we should abort the spell in such case?
1727 CheckDst();
1728
1730
1731 switch (targetType.GetTarget())
1732 {
1736 case TARGET_DEST_DEST:
1737 return;
1738 case TARGET_DEST_TRAJ:
1739 SelectImplicitTrajTargets(effIndex, targetType);
1740 return;
1741 default:
1742 {
1743 float angle = targetType.CalcDirectionAngle();
1744 float dist = m_spellInfo->Effects[effIndex].CalcRadius(m_caster);
1745 if (targetType.GetTarget() == TARGET_DEST_DEST_RANDOM)
1746 dist *= float(rand_norm());
1747
1748 Position pos = dest._position;
1749 m_caster->MovePosition(pos, dist, angle);
1750
1751 dest.Relocate(pos);
1752 break;
1753 }
1754 }
1755
1756 CallScriptDestinationTargetSelectHandlers(dest, effIndex, targetType);
1757 m_targets.ModDst(dest);
1758}
@ TARGET_DEST_DYNOBJ_ENEMY
Definition: SharedDefines.h:1432
@ TARGET_DEST_DEST_RANDOM
Definition: SharedDefines.h:1490
@ TARGET_DEST_DEST
Definition: SharedDefines.h:1491
@ TARGET_DEST_DYNOBJ_NONE
Definition: SharedDefines.h:1492
@ TARGET_DEST_DYNOBJ_ALLY
Definition: SharedDefines.h:1433
@ TARGET_DEST_TRAJ
Definition: SharedDefines.h:1493
void MovePosition(Position &pos, float dist, float angle, bool disableWarning=false)
Definition: Object.cpp:2787
void ModDst(Position const &pos)
Definition: Spell.cpp:436
SpellDestination const * GetDst() const
Definition: Spell.cpp:396

References SpellDestination::_position, SpellImplicitTargetInfo::CalcDirectionAngle(), CallScriptDestinationTargetSelectHandlers(), CheckDst(), SpellInfo::Effects, SpellCastTargets::GetDst(), SpellImplicitTargetInfo::GetTarget(), m_caster, m_spellInfo, m_targets, SpellCastTargets::ModDst(), WorldObject::MovePosition(), rand_norm(), SpellDestination::Relocate(), SelectImplicitTrajTargets(), TARGET_DEST_DEST, TARGET_DEST_DEST_RANDOM, TARGET_DEST_DYNOBJ_ALLY, TARGET_DEST_DYNOBJ_ENEMY, TARGET_DEST_DYNOBJ_NONE, and TARGET_DEST_TRAJ.

Referenced by SelectEffectImplicitTargets().

◆ SelectImplicitNearbyTargets()

void Spell::SelectImplicitNearbyTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType,
uint32  effMask 
)
1101{
1102 if (targetType.GetReferenceType() != TARGET_REFERENCE_TYPE_CASTER)
1103 {
1104 ASSERT(false && "Spell::SelectImplicitNearbyTargets: received not implemented target reference type");
1105 return;
1106 }
1107
1108 float range = 0.0f;
1109 switch (targetType.GetCheckType())
1110 {
1111 case TARGET_CHECK_ENEMY:
1112 range = m_spellInfo->GetMaxRange(false, m_caster, this);
1113 break;
1114 case TARGET_CHECK_ALLY:
1115 case TARGET_CHECK_PARTY:
1116 case TARGET_CHECK_RAID:
1118 range = m_spellInfo->GetMaxRange(true, m_caster, this);
1119 break;
1120 case TARGET_CHECK_ENTRY:
1123 break;
1124 default:
1125 ASSERT(false && "Spell::SelectImplicitNearbyTargets: received not implemented selection check type");
1126 break;
1127 }
1128
1129 ConditionList* condList = m_spellInfo->Effects[effIndex].ImplicitTargetConditions;
1130
1131 // handle emergency case - try to use other provided targets if no conditions provided
1132 if (targetType.GetCheckType() == TARGET_CHECK_ENTRY && (!condList || condList->empty()))
1133 {
1134 LOG_DEBUG("spells.aura", "Spell::SelectImplicitNearbyTargets: no conditions entry for target with TARGET_CHECK_ENTRY of spell ID {}, effect {} - selecting default targets", m_spellInfo->Id, effIndex);
1135 switch (targetType.GetObjectType())
1136 {
1139 {
1140 if (focusObject)
1141 AddGOTarget(focusObject, effMask);
1142 return;
1143 }
1144 break;
1147 {
1148 if (focusObject)
1150 return;
1151 }
1152 break;
1153 default:
1154 break;
1155 }
1156 }
1157
1158 WorldObject* target = SearchNearbyTarget(range, targetType.GetObjectType(), targetType.GetCheckType(), condList);
1159 if (!target)
1160 {
1161 LOG_DEBUG("spells.aura", "Spell::SelectImplicitNearbyTargets: cannot find nearby target for spell ID {}, effect {}", m_spellInfo->Id, effIndex);
1162 return;
1163 }
1164
1165 CallScriptObjectTargetSelectHandlers(target, effIndex, targetType);
1166 if (!target)
1167 {
1168 //LOG_DEBUG("spells", "Spell::SelectImplicitNearbyTargets: OnObjectTargetSelect script hook for spell Id {} set nullptr target, effect {}", m_spellInfo->Id, effIndex);
1169 return;
1170 }
1171
1172 switch (targetType.GetObjectType())
1173 {
1175 {
1176 if (Unit* unit = target->ToUnit())
1177 {
1178 AddUnitTarget(unit, effMask, true, false);
1179 // xinef: important! if channeling spell have nearby entry, it has no unitTarget by default
1180 // and if channeled spell has target 77, it requires unitTarget, set it here!
1181 // xinef: if we have NO unit target
1182 if (!m_targets.GetUnitTarget())
1183 {
1185 }
1186 }
1187 else
1188 {
1189 //LOG_DEBUG("spells", "Spell::SelectImplicitNearbyTargets: OnObjectTargetSelect script hook for spell Id {} set object of wrong type, expected unit, got {}, effect {}", m_spellInfo->Id, target->GetGUID().GetTypeName(), effMask);
1190 return;
1191 }
1192 break;
1193 }
1195 if (GameObject* gobjTarget = target->ToGameObject())
1196 AddGOTarget(gobjTarget, effMask);
1197 else
1198 {
1199 //LOG_DEBUG("spells", "Spell::SelectImplicitNearbyTargets: OnObjectTargetSelect script hook for spell Id {} set object of wrong type, expected gameobject, got {}, effect {}", m_spellInfo->Id, target->GetGUID().GetTypeName(), effMask);
1200 return;
1201 }
1202 break;
1204 m_targets.SetDst(*target);
1205 break;
1206 default:
1207 ASSERT(false && "Spell::SelectImplicitNearbyTargets: received not implemented target object type");
1208 break;
1209 }
1210
1211 SelectImplicitChainTargets(effIndex, targetType, target, effMask);
1212}
@ TARGET_CHECK_PARTY
Definition: SpellInfo.h:118
@ TARGET_CHECK_ENEMY
Definition: SpellInfo.h:116
@ TARGET_CHECK_DEFAULT
Definition: SpellInfo.h:114
@ TARGET_CHECK_RAID_CLASS
Definition: SpellInfo.h:120
@ TARGET_CHECK_ALLY
Definition: SpellInfo.h:117
@ TARGET_CHECK_RAID
Definition: SpellInfo.h:119
WorldObject * SearchNearbyTarget(float range, SpellTargetObjectTypes objectType, SpellTargetCheckTypes selectionType, ConditionList *condList=nullptr)
Definition: Spell.cpp:2177
void SelectImplicitChainTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType, WorldObject *target, uint32 effMask)
Definition: Spell.cpp:1829

References AddGOTarget(), AddUnitTarget(), ASSERT, CallScriptObjectTargetSelectHandlers(), SpellInfo::Effects, focusObject, SpellImplicitTargetInfo::GetCheckType(), SpellInfo::GetMaxRange(), SpellImplicitTargetInfo::GetObjectType(), SpellImplicitTargetInfo::GetReferenceType(), SpellCastTargets::GetUnitTarget(), SpellInfo::Id, SpellInfo::IsPositive(), LOG_DEBUG, m_caster, m_spellInfo, m_targets, SpellInfo::RequiresSpellFocus, SearchNearbyTarget(), SelectImplicitChainTargets(), SpellCastTargets::SetDst(), SpellCastTargets::SetUnitTarget(), TARGET_CHECK_ALLY, TARGET_CHECK_DEFAULT, TARGET_CHECK_ENEMY, TARGET_CHECK_ENTRY, TARGET_CHECK_PARTY, TARGET_CHECK_RAID, TARGET_CHECK_RAID_CLASS, TARGET_OBJECT_TYPE_DEST, TARGET_OBJECT_TYPE_GOBJ, TARGET_OBJECT_TYPE_UNIT, TARGET_REFERENCE_TYPE_CASTER, Object::ToGameObject(), and Object::ToUnit().

Referenced by SelectEffectImplicitTargets().

◆ SelectImplicitTargetDestTargets()

void Spell::SelectImplicitTargetDestTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType 
)
1685{
1687
1688 SpellDestination dest(*target);
1689
1690 switch (targetType.GetTarget())
1691 {
1694 break;
1695 default:
1696 {
1697 float angle = targetType.CalcDirectionAngle();
1698 float dist = m_spellInfo->Effects[effIndex].CalcRadius(nullptr);
1699 if (targetType.GetTarget() == TARGET_DEST_TARGET_RANDOM)
1700 {
1701 dist *= float(rand_norm());
1702 }
1703
1704 if (targetType.GetTarget() == TARGET_DEST_TARGET_BACK)
1705 {
1707 }
1708
1709 Position pos = dest._position;
1710 target->MovePositionToFirstCollision(pos, dist, angle);
1711
1712 dest.Relocate(pos);
1713 break;
1714 }
1715 }
1716
1717 CallScriptDestinationTargetSelectHandlers(dest, effIndex, targetType);
1718 m_targets.SetDst(dest);
1719}
@ TARGET_DEST_TARGET_ANY
Definition: SharedDefines.h:1467
@ TARGET_DEST_TARGET_BACK
Definition: SharedDefines.h:1469
@ TARGET_DEST_TARGET_RANDOM
Definition: SharedDefines.h:1478
@ TARGET_DEST_TARGET_ENEMY
Definition: SharedDefines.h:1457
@ UNIT_FIELD_BOUNDINGRADIUS
Definition: UpdateFields.h:122

References SpellDestination::_position, SpellImplicitTargetInfo::CalcDirectionAngle(), CallScriptDestinationTargetSelectHandlers(), SpellInfo::Effects, Object::GetFloatValue(), SpellCastTargets::GetObjectTarget(), SpellImplicitTargetInfo::GetTarget(), m_spellInfo, m_targets, WorldObject::MovePositionToFirstCollision(), rand_norm(), SpellDestination::Relocate(), SpellCastTargets::SetDst(), TARGET_DEST_TARGET_ANY, TARGET_DEST_TARGET_BACK, TARGET_DEST_TARGET_ENEMY, TARGET_DEST_TARGET_RANDOM, and UNIT_FIELD_BOUNDINGRADIUS.

Referenced by SelectEffectImplicitTargets().

◆ SelectImplicitTargetObjectTargets()

void Spell::SelectImplicitTargetObjectTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType 
)
1808{
1809 ASSERT((m_targets.GetObjectTarget() || m_targets.GetItemTarget()) && "Spell::SelectImplicitTargetObjectTargets - no explicit object or item target available!");
1810
1812
1813 CallScriptObjectTargetSelectHandlers(target, effIndex, targetType);
1814
1815 if (target)
1816 {
1817 if (Unit* unit = target->ToUnit())
1818 AddUnitTarget(unit, 1 << effIndex, true, false);
1819 else if (GameObject* gobj = target->ToGameObject())
1820 AddGOTarget(gobj, 1 << effIndex);
1821
1822 SelectImplicitChainTargets(effIndex, targetType, target, 1 << effIndex);
1823 }
1824 // Script hook can remove object target and we would wrongly land here
1825 else if (Item* item = m_targets.GetItemTarget())
1826 AddItemTarget(item, 1 << effIndex);
1827}

References AddGOTarget(), AddItemTarget(), AddUnitTarget(), ASSERT, CallScriptObjectTargetSelectHandlers(), SpellCastTargets::GetItemTarget(), SpellCastTargets::GetObjectTarget(), m_targets, SelectImplicitChainTargets(), Object::ToGameObject(), and Object::ToUnit().

Referenced by SelectEffectImplicitTargets().

◆ SelectImplicitTrajTargets()

void Spell::SelectImplicitTrajTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType 
)
Todo:
: all calculation should be based on src instead of m_caster
1871{
1872 if (!m_targets.HasTraj())
1873 return;
1874
1875 float dist2d = m_targets.GetDist2d();
1876 if (!dist2d)
1877 return;
1878
1879 float srcToDestDelta = m_targets.GetDstPos()->m_positionZ - m_targets.GetSrcPos()->m_positionZ;
1880
1881 // xinef: supply correct target type, DEST_DEST and similar are ALWAYS undefined
1882 // xinef: correct target is stored in TRIGGERED SPELL, however as far as i noticed, all checks are ENTRY, ENEMY
1883 std::list<WorldObject*> targets;
1884 Acore::WorldObjectSpellTrajTargetCheck check(dist2d, m_targets.GetSrcPos(), m_caster, m_spellInfo, TARGET_CHECK_ENEMY /*targetCheckType*/, m_spellInfo->Effects[effIndex].ImplicitTargetConditions);
1886 SearchTargets<Acore::WorldObjectListSearcher<Acore::WorldObjectSpellTrajTargetCheck> > (searcher, GRID_MAP_TYPE_MASK_ALL, m_caster, m_targets.GetSrcPos(), dist2d);
1887 if (targets.empty())
1888 return;
1889
1891
1892 float b = tangent(m_targets.GetElevation());
1893 float a = (srcToDestDelta - dist2d * b) / (dist2d * dist2d);
1894 if (a > -0.0001f)
1895 a = 0;
1896
1897 LOG_DEBUG("spells", "Spell::SelectTrajTargets: a {} b {}", a, b);
1898
1899 // Xinef: hack for distance, many trajectory spells have RangeEntry 1 (self)
1900 float bestDist = m_spellInfo->GetMaxRange(false) * 2;
1901 if (bestDist < 1.0f)
1902 bestDist = 300.0f;
1903
1904 std::list<WorldObject*>::const_iterator itr = targets.begin();
1905 for (; itr != targets.end(); ++itr)
1906 {
1907 if (Unit* unitTarget = (*itr)->ToUnit())
1908 if (m_caster == *itr || m_caster->IsOnVehicle(unitTarget) || (unitTarget)->GetVehicle())//(*itr)->IsOnVehicle(m_caster))
1909 continue;
1910
1911 const float size = std::max((*itr)->GetObjectSize() * 0.7f, 1.0f); // 1/sqrt(3)
1913 const float objDist2d = std::fabs(m_targets.GetSrcPos()->GetExactDist2d(*itr) * cos(m_targets.GetSrcPos()->GetRelativeAngle(*itr)));
1914 const float dz = std::fabs((*itr)->GetPositionZ() - m_targets.GetSrcPos()->m_positionZ);
1915
1916 LOG_DEBUG("spells", "Spell::SelectTrajTargets: check {}, dist between {} {}, height between {} {}.",
1917 (*itr)->GetEntry(), objDist2d - size, objDist2d + size, dz - size, dz + size);
1918
1919 float dist = objDist2d - size;
1920 float height = dist * (a * dist + b);
1921
1922 LOG_DEBUG("spells", "Spell::SelectTrajTargets: dist {}, height {}.", dist, height);
1923
1924 if (dist < bestDist && height < dz + size && height > dz - size)
1925 {
1926 bestDist = dist > 0 ? dist : 0;
1927 break;
1928 }
1929
1930#define CHECK_DIST {\
1931 LOG_DEBUG("spells", "Spell::SelectTrajTargets: dist {}, height {}.", dist, height);\
1932 if (dist > bestDist)\
1933 continue;\
1934 if (dist < objDist2d + size && dist > objDist2d - size)\
1935 {\
1936 bestDist = dist;\
1937 break;\
1938 }\
1939 }
1940
1941 // RP-GG only, search in straight line, as item have no trajectory
1942 if (m_CastItem)
1943 {
1944 if (dist < bestDist && std::fabs(dz) < 6.0f) // closes target, also check Z difference)
1945 {
1946 bestDist = dist;
1947 break;
1948 }
1949
1950 continue;
1951 }
1952
1953 if (!a)
1954 {
1955 // Xinef: everything remade
1956 dist = m_targets.GetSrcPos()->GetExactDist(*itr);
1957 height = m_targets.GetSrcPos()->GetExactDist2d(*itr) * b;
1958
1959 if (height < dz + size * (b + 1) && height > dz - size * (b + 1) && dist < bestDist)
1960 {
1961 bestDist = dist;
1962 break;
1963 }
1964
1965 continue;
1966 }
1967
1968 height = dz - size;
1969 float sqrt1 = b * b + 4 * a * height;
1970 if (sqrt1 > 0)
1971 {
1972 sqrt1 = std::sqrt(sqrt1);
1973 dist = (sqrt1 - b) / (2 * a);
1974 CHECK_DIST;
1975 }
1976
1977 height = dz + size;
1978 float sqrt2 = b * b + 4 * a * height;
1979 if (sqrt2 > 0)
1980 {
1981 sqrt2 = std::sqrt(sqrt2);
1982 dist = (sqrt2 - b) / (2 * a);
1983 CHECK_DIST;
1984
1985 dist = (-sqrt2 - b) / (2 * a);
1986 CHECK_DIST;
1987 }
1988
1989 if (sqrt1 > 0)
1990 {
1991 dist = (-sqrt1 - b) / (2 * a);
1992 CHECK_DIST;
1993 }
1994 }
1995
1997 {
1998 float x = m_targets.GetSrcPos()->m_positionX + cos(m_caster->GetOrientation()) * bestDist;
1999 float y = m_targets.GetSrcPos()->m_positionY + std::sin(m_caster->GetOrientation()) * bestDist;
2000 float z = m_targets.GetSrcPos()->m_positionZ + bestDist * (a * bestDist + b);
2001
2002 if (itr != targets.end())
2003 {
2004 float distSq = (*itr)->GetExactDistSq(x, y, z);
2005 float sizeSq = (*itr)->GetObjectSize();
2006 sizeSq *= sizeSq;
2007 LOG_DEBUG("spells", "Spell::SelectTrajTargets: Initial {} {} {} {} {}", x, y, z, distSq, sizeSq);
2008 if (distSq > sizeSq)
2009 {
2010 float factor = 1 - std::sqrt(sizeSq / distSq);
2011 x += factor * ((*itr)->GetPositionX() - x);
2012 y += factor * ((*itr)->GetPositionY() - y);
2013 z += factor * ((*itr)->GetPositionZ() - z);
2014
2015 distSq = (*itr)->GetExactDistSq(x, y, z);
2016 LOG_DEBUG("spells", "Spell::SelectTrajTargets: Initial {} {} {} {} {}", x, y, z, distSq, sizeSq);
2017 }
2018 }
2019
2020 Position trajDst;
2021 trajDst.Relocate(x, y, z, m_caster->GetOrientation());
2023 dest.Relocate(trajDst);
2024
2025 CallScriptDestinationTargetSelectHandlers(dest, effIndex, targetType);
2026 m_targets.ModDst(dest);
2027 }
2028}
float tangent(float x)
Definition: Spell.cpp:1856
#define CHECK_DIST
Definition: Object.h:703
bool IsOnVehicle(Unit const *vehicle) const
Definition: Unit.h:1787
float GetElevation() const
Definition: Spell.h:170

References CallScriptDestinationTargetSelectHandlers(), CHECK_DIST, SpellInfo::Effects, SpellCastTargets::GetDist2d(), SpellCastTargets::GetDst(), SpellCastTargets::GetDstPos(), SpellCastTargets::GetElevation(), Position::GetExactDist(), Position::GetExactDist2d(), SpellInfo::GetMaxRange(), Position::GetOrientation(), Position::GetRelativeAngle(), SpellCastTargets::GetSrcPos(), GRID_MAP_TYPE_MASK_ALL, SpellCastTargets::HasTraj(), Unit::IsOnVehicle(), LOG_DEBUG, m_caster, m_CastItem, Position::m_positionX, Position::m_positionY, Position::m_positionZ, m_spellInfo, m_targets, SpellCastTargets::ModDst(), Position::Relocate(), SpellDestination::Relocate(), tangent(), TARGET_CHECK_ENEMY, Object::ToUnit(), and unitTarget.

Referenced by SelectEffectImplicitTargets(), and SelectImplicitDestDestTargets().

◆ SelectSpellTargets()

void Spell::SelectSpellTargets ( )
820{
821 // select targets for cast phase
823
824 uint32 processedAreaEffectsMask = 0;
825 for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i)
826 {
827 // not call for empty effect.
828 // Also some spells use not used effect targets for store targets for dummy effect in triggered spells
829 if (!m_spellInfo->Effects[i].IsEffect())
830 continue;
831
832 // set expected type of implicit targets to be sent to client
833 uint32 implicitTargetMask = GetTargetFlagMask(m_spellInfo->Effects[i].TargetA.GetObjectType()) | GetTargetFlagMask(m_spellInfo->Effects[i].TargetB.GetObjectType());
834 if (implicitTargetMask & TARGET_FLAG_UNIT)
836 if (implicitTargetMask & (TARGET_FLAG_GAMEOBJECT | TARGET_FLAG_GAMEOBJECT_ITEM))
838
839 SelectEffectImplicitTargets(SpellEffIndex(i), m_spellInfo->Effects[i].TargetA, processedAreaEffectsMask);
840 SelectEffectImplicitTargets(SpellEffIndex(i), m_spellInfo->Effects[i].TargetB, processedAreaEffectsMask);
841
842 // Select targets of effect based on effect type
843 // those are used when no valid target could be added for spell effect based on spell target type
844 // some spell effects use explicit target as a default target added to target map (like SPELL_EFFECT_LEARN_SPELL)
845 // some spell effects add target to target map only when target type specified (like SPELL_EFFECT_WEAPON)
846 // some spell effects don't add anything to target map (confirmed with sniffs) (like SPELL_EFFECT_DESTROY_ALL_TOTEMS)
848
849 if (m_targets.HasDst())
851
853 {
854 // maybe do this for all spells?
855 if (!focusObject && m_UniqueTargetInfo.empty() && m_UniqueGOTargetInfo.empty() && m_UniqueItemInfo.empty() && !m_targets.HasDst())
856 {
858 finish(false);
859 return;
860 }
861
862 uint8 mask = (1 << i);
863 for (auto ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
864 {
865 if (ihit->effectMask & mask)
866 {
868 break;
869 }
870 }
871 }
872 else if (m_auraScaleMask)
873 {
874 bool checkLvl = !m_UniqueTargetInfo.empty();
875 m_UniqueTargetInfo.erase(std::remove_if(std::begin(m_UniqueTargetInfo), std::end(m_UniqueTargetInfo), [&](TargetInfo const& targetInfo) -> bool
876 {
877 // remove targets which did not pass min level check
878 if (m_auraScaleMask && targetInfo.effectMask == m_auraScaleMask)
879 {
880 if (!targetInfo.scaleAura && targetInfo.targetGUID != m_caster->GetGUID())
881 return true;
882 }
883
884 return false;
885 }), std::end(m_UniqueTargetInfo));
886
887 if (checkLvl && m_UniqueTargetInfo.empty())
888 {
890 finish(false);
891 }
892 }
893 }
894
895 if (uint64 dstDelay = CalculateDelayMomentForDst())
896 m_delayMoment = dstDelay;
897}
@ TARGET_FLAG_GAMEOBJECT
Definition: SpellInfo.h:57
@ TARGET_FLAG_GAMEOBJECT_ITEM
Definition: SpellInfo.h:60
uint32 GetTargetFlagMask(SpellTargetObjectTypes objType)
Definition: SpellInfo.cpp:31
void SetTargetFlag(SpellCastTargetFlags flag)
Definition: Spell.h:122
void SelectEffectImplicitTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType, uint32 &processedEffectMask)
Definition: Spell.cpp:926
void SelectExplicitTargets()
Definition: Spell.cpp:786
void AddDestTarget(SpellDestination const &dest, uint32 effIndex)
Definition: Spell.cpp:2608
void SelectEffectTypeImplicitTargets(uint8 effIndex)
Definition: Spell.cpp:2030

References AddDestTarget(), CalculateDelayMomentForDst(), TargetInfo::effectMask, SpellInfo::Effects, finish(), focusObject, SpellCastTargets::GetDst(), GetTargetFlagMask(), SpellCastTargets::HasDst(), SpellInfo::IsChanneled(), m_auraScaleMask, m_channelTargetEffectMask, m_delayMoment, m_spellInfo, m_targets, m_UniqueGOTargetInfo, m_UniqueItemInfo, m_UniqueTargetInfo, MAX_SPELL_EFFECTS, SelectEffectImplicitTargets(), SelectEffectTypeImplicitTargets(), SelectExplicitTargets(), SendCastResult(), SpellCastTargets::SetTargetFlag(), SPELL_FAILED_BAD_IMPLICIT_TARGETS, SPELL_FAILED_LOWLEVEL, TARGET_FLAG_GAMEOBJECT, TARGET_FLAG_GAMEOBJECT_ITEM, and TARGET_FLAG_UNIT.

Referenced by _cast(), CanAutoCast(), spell_dk_raise_dead::CheckCast(), and prepare().

◆ SendCastResult() [1/2]

void Spell::SendCastResult ( Player caster,
SpellInfo const *  spellInfo,
uint8  castCount,
SpellCastResult  result,
SpellCustomErrors  customError = SPELL_CUSTOM_ERROR_NONE 
)
static
4675{
4676 if (result == SPELL_CAST_OK)
4677 return;
4678
4679 WorldPacket data(SMSG_CAST_FAILED, 1 + 4 + 1);
4680 WriteCastResultInfo(data, caster, spellInfo, castCount, result, customError);
4681
4682 caster->GetSession()->SendPacket(&data);
4683}
@ SMSG_CAST_FAILED
Definition: Opcodes.h:334
static void WriteCastResultInfo(WorldPacket &data, Player *caster, SpellInfo const *spellInfo, uint8 castCount, SpellCastResult result, SpellCustomErrors customError)
Definition: Spell.cpp:4569

References Player::GetSession(), WorldSession::SendPacket(), SMSG_CAST_FAILED, SPELL_CAST_OK, and WriteCastResultInfo().

Referenced by _cast(), Unit::AttackerStateUpdate(), cancel(), Player::CastItemUseSpell(), spell_q12237_rescue_villager::CheckCast(), spell_q12237_drop_off_villager::CheckCast(), spell_dk_raise_dead::CheckReagents(), spell_putricide_mutation_init::CheckRequirement(), EffectApplyGlyph(), EffectDuel(), EffectOpenLock(), EffectTaunt(), SpellScript::FinishCast(), go_soulwell::go_soulwellAI::GossipHello(), WorldSession::HandleAcceptTradeOpcode(), WorldSession::HandleCastSpellOpcode(), spell_the_flag_of_ownership::HandleFinish(), WorldSession::HandlePetActionHelper(), spell_putricide_mutated_transformation::HandleSummon(), misc_commandscript::HandleUnstuckCommand(), icecrown_citadel_teleport::OnGossipSelect(), at_frozen_throne_teleport::OnTrigger(), item_petrov_cluster_bombs::OnUse(), item_only_for_flight::OnUse(), prepare(), SelectImplicitCasterDestTargets(), SelectSpellTargets(), and SendCastResult().

◆ SendCastResult() [2/2]

void Spell::SendCastResult ( SpellCastResult  result)
4686{
4687 if (result == SPELL_CAST_OK)
4688 return;
4689
4690 if (!m_caster->IsPlayer() || m_caster->IsCharmed())
4691 return;
4692
4693 if (m_caster->ToPlayer()->GetSession()->PlayerLoading()) // don't send cast results at loading time
4694 return;
4695
4696 // Xinef: override every possible result, except for gm fail result... breaks many things and goes unnoticed because of this and makes me rage when i find this out
4698 result = SPELL_FAILED_DONT_REPORT;
4699
4701}
@ SPELL_FAILED_BM_OR_INVISGOD
Definition: SharedDefines.h:1108
@ TRIGGERED_DONT_REPORT_CAST_ERROR
Disallows proc events from triggered spell (default)
Definition: SpellDefines.h:149
bool IsCharmed() const
Definition: Unit.h:1235

References Player::GetSession(), HasTriggeredCastFlag(), Unit::IsCharmed(), Object::IsPlayer(), m_cast_count, m_caster, m_customError, m_spellInfo, WorldSession::PlayerLoading(), SendCastResult(), SPELL_CAST_OK, SPELL_FAILED_BM_OR_INVISGOD, SPELL_FAILED_DONT_REPORT, Object::ToPlayer(), and TRIGGERED_DONT_REPORT_CAST_ERROR.

◆ SendChannelStart()

void Spell::SendChannelStart ( uint32  duration)
5212{
5213 ObjectGuid channelTarget = m_targets.GetObjectTargetGUID();
5214 if (!channelTarget && !m_spellInfo->NeedsExplicitUnitTarget())
5215 if (m_UniqueTargetInfo.size() + m_UniqueGOTargetInfo.size() == 1) // this is for TARGET_SELECT_CATEGORY_NEARBY
5216 channelTarget = !m_UniqueTargetInfo.empty() ? m_UniqueTargetInfo.front().targetGUID : m_UniqueGOTargetInfo.front().targetGUID;
5217
5218 WorldPacket data(MSG_CHANNEL_START, (8 + 4 + 4));
5219 data << m_caster->GetPackGUID();
5220 data << uint32(m_spellInfo->Id);
5221 data << uint32(duration);
5222
5223 m_caster->SendMessageToSet(&data, true);
5224
5227
5228 m_timer = duration;
5229 if (channelTarget)
5231
5233}
@ MSG_CHANNEL_START
Definition: Opcodes.h:343

References WorldObject::FindMap(), Object::GetGUID(), SpellCastTargets::GetObjectTargetGUID(), Object::GetPackGUID(), SpellInfo::Id, Object::IsPlayer(), m_caster, m_spellInfo, m_targets, m_timer, m_UniqueGOTargetInfo, m_UniqueTargetInfo, MSG_CHANNEL_START, Player::NeedSendSpectatorData(), SpellInfo::NeedsExplicitUnitTarget(), ArenaSpectator::SendCommand_Spell(), WorldObject::SendMessageToSet(), Object::SetGuidValue(), Unit::SetUInt32Value(), Object::ToPlayer(), UNIT_CHANNEL_SPELL, and UNIT_FIELD_CHANNEL_OBJECT.

Referenced by handle_immediate().

◆ SendChannelUpdate()

◆ SendInterrupted()

void Spell::SendInterrupted ( uint8  result)
5180{
5181 WorldPacket data(SMSG_SPELL_FAILURE, (8 + 1 + 4 + 1));
5182 data << m_caster->GetPackGUID();
5183 data << uint8(m_cast_count);
5184 data << uint32(m_spellInfo->Id);
5185 data << uint8(result);
5186 m_caster->SendMessageToSet(&data, true);
5187
5188 data.Initialize(SMSG_SPELL_FAILED_OTHER, (8 + 1 + 4 + 1));
5189 data << m_caster->GetPackGUID();
5190 data << uint8(m_cast_count);
5191 data << uint32(m_spellInfo->Id);
5192 data << uint8(result);
5193 m_caster->SendMessageToSet(&data, true);
5194}
@ SMSG_SPELL_FAILURE
Definition: Opcodes.h:337
@ SMSG_SPELL_FAILED_OTHER
Definition: Opcodes.h:708

References Object::GetPackGUID(), SpellInfo::Id, WorldPacket::Initialize(), m_cast_count, m_caster, m_spellInfo, WorldObject::SendMessageToSet(), SMSG_SPELL_FAILED_OTHER, and SMSG_SPELL_FAILURE.

Referenced by _cast(), Unit::AttackerStateUpdate(), and cancel().

◆ SendLogExecute()

void Spell::SendLogExecute ( )
5079{
5080 WorldPacket data(SMSG_SPELLLOGEXECUTE, (8 + 4 + 4 + 4 + 4 + 8));
5081
5082 data << m_caster->GetPackGUID();
5083
5084 data << uint32(m_spellInfo->Id);
5085
5086 uint8 effCount = 0;
5087 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
5088 {
5089 if (m_effectExecuteData[i])
5090 ++effCount;
5091 }
5092
5093 if (!effCount)
5094 return;
5095
5096 data << uint32(effCount);
5097 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
5098 {
5099 if (!m_effectExecuteData[i])
5100 continue;
5101
5102 data << uint32(m_spellInfo->Effects[i].Effect); // spell effect
5103
5104 data.append(*m_effectExecuteData[i]);
5105
5106 delete m_effectExecuteData[i];
5107 m_effectExecuteData[i] = nullptr;
5108 }
5109 m_caster->SendMessageToSet(&data, true);
5110}
@ SMSG_SPELLLOGEXECUTE
Definition: Opcodes.h:618

References ByteBuffer::append(), SpellInfo::Effects, Object::GetPackGUID(), SpellInfo::Id, m_caster, m_effectExecuteData, m_spellInfo, MAX_SPELL_EFFECTS, WorldObject::SendMessageToSet(), and SMSG_SPELLLOGEXECUTE.

Referenced by FinishTargetProcessing().

◆ SendLoot()

void Spell::SendLoot ( ObjectGuid  guid,
LootType  loottype 
)
protected
2016{
2017 Player* player = m_caster->ToPlayer();
2018 if (!player)
2019 return;
2020
2021 if (gameObjTarget)
2022 {
2023 // Players shouldn't be able to loot gameobjects that are currently despawned
2024 if (!gameObjTarget->isSpawned() && !player->IsGameMaster())
2025 {
2026 LOG_ERROR("spells.effect", "Possible hacking attempt: Player {} [{}] tried to loot a gameobject [{}] which is on respawn time without being in GM mode!",
2027 player->GetName(), player->GetGUID().ToString(), gameObjTarget->GetGUID().ToString());
2028 return;
2029 }
2030 // special case, already has GossipHello inside so return and avoid calling twice
2032 {
2034 return;
2035 }
2036
2037 if (sScriptMgr->OnGossipHello(player, gameObjTarget))
2038 return;
2039
2040 if (gameObjTarget->AI()->GossipHello(player, false))
2041 return;
2042
2043 switch (gameObjTarget->GetGoType())
2044 {
2046 gameObjTarget->UseDoorOrButton(0, false, player);
2047 return;
2049 gameObjTarget->UseDoorOrButton(0, false, player);
2050
2051 // Xinef: properly link possible traps
2052 if (uint32 trapEntry = gameObjTarget->GetGOInfo()->button.linkedTrap)
2053 gameObjTarget->TriggeringLinkedGameObject(trapEntry, player);
2054 return;
2058 return;
2059
2061 // triggering linked GO
2064 return;
2065
2067 // triggering linked GO
2068 if (uint32 trapEntry = gameObjTarget->GetGOInfo()->chest.linkedTrapId)
2070
2071 // Don't return, let loots been taken
2072 default:
2073 break;
2074 }
2075 }
2076
2077 // Send loot
2078 player->SendLoot(guid, loottype);
2079}
@ GAMEOBJECT_TYPE_SPELL_FOCUS
Definition: SharedDefines.h:1568
@ GAMEOBJECT_TYPE_QUESTGIVER
Definition: SharedDefines.h:1562
virtual bool GossipHello(Player *, bool)
Definition: GameObjectAI.h:54
bool isSpawned() const
Definition: GameObject.h:189
void TriggeringLinkedGameObject(uint32 trapEntry, Unit *target)
Definition: GameObject.cpp:1387
struct GameObjectTemplate::@230::@234 questgiver
uint32 gossipID
Definition: GameObjectData.h:72
uint32 linkedTrap
Definition: GameObjectData.h:59
struct GameObjectTemplate::@230::@235 chest
uint32 linkedTrapId
Definition: GameObjectData.h:90
struct GameObjectTemplate::@230::@239 spellFocus
void SendPreparedGossip(WorldObject *source)
Definition: PlayerGossip.cpp:209
void PrepareGossipMenu(WorldObject *source, uint32 menuId=0, bool showQuests=false)
Definition: PlayerGossip.cpp:32

References GameObject::AI(), GameObjectTemplate::button, GameObjectTemplate::chest, GAMEOBJECT_TYPE_BUTTON, GAMEOBJECT_TYPE_CHEST, GAMEOBJECT_TYPE_DOOR, GAMEOBJECT_TYPE_GOOBER, GAMEOBJECT_TYPE_QUESTGIVER, GAMEOBJECT_TYPE_SPELL_FOCUS, gameObjTarget, GameObject::GetGOInfo(), GameObject::GetGoType(), Object::GetGUID(), WorldObject::GetName(), GameObjectAI::GossipHello(), GameObjectTemplate::gossipID, Player::IsGameMaster(), GameObject::isSpawned(), GameObjectTemplate::linkedTrap, GameObjectTemplate::linkedTrapId, LOG_ERROR, m_caster, Player::PrepareGossipMenu(), GameObjectTemplate::questgiver, Player::SendLoot(), Player::SendPreparedGossip(), GameObjectTemplate::spellFocus, sScriptMgr, Object::ToPlayer(), ObjectGuid::ToString(), GameObject::TriggeringLinkedGameObject(), GameObject::Use(), and GameObject::UseDoorOrButton().

Referenced by EffectOpenLock().

◆ SendPetCastResult()

void Spell::SendPetCastResult ( SpellCastResult  result)
4704{
4705 if (result == SPELL_CAST_OK)
4706 return;
4707
4708 Unit* owner = m_caster->GetCharmerOrOwner();
4709 if (!owner)
4710 return;
4711
4712 Player* player = owner->ToPlayer();
4713 if (!player)
4714 return;
4715
4716 WorldPacket data(SMSG_PET_CAST_FAILED, 1 + 4 + 1);
4718
4719 player->GetSession()->SendPacket(&data);
4720}
@ SMSG_PET_CAST_FAILED
Definition: Opcodes.h:342

References Unit::GetCharmerOrOwner(), Player::GetSession(), m_cast_count, m_caster, m_customError, m_spellInfo, WorldSession::SendPacket(), SMSG_PET_CAST_FAILED, SPELL_CAST_OK, Object::ToPlayer(), and WriteCastResultInfo().

Referenced by WorldSession::HandlePetActionHelper(), and WorldSession::HandlePetCastSpellOpcode().

◆ SendResurrectRequest()

void Spell::SendResurrectRequest ( Player target)
5236{
5237 // get resurrector name for creature resurrections, otherwise packet will be not accepted
5238 // for player resurrections the name is looked up by guid
5239 std::string const sentName(m_caster->IsPlayer()
5240 ? ""
5242
5243 WorldPacket data(SMSG_RESURRECT_REQUEST, (8 + 4 + sentName.size() + 1 + 1 + 1 + 4));
5244 data << m_caster->GetGUID();
5245 data << uint32(sentName.size() + 1);
5246
5247 data << sentName;
5248 data << uint8(0); // null terminator
5249
5250 data << uint8(m_caster->IsPlayer() ? 0 : 1); // "you'll be afflicted with resurrection sickness"
5251 // override delay sent with SMSG_CORPSE_RECLAIM_DELAY, set instant resurrection for spells with this attribute
5253 data << uint32(0);
5254 target->GetSession()->SendPacket(&data);
5255}
@ SPELL_ATTR3_NO_RES_TIMER
Definition: SharedDefines.h:497
@ SMSG_RESURRECT_REQUEST
Definition: Opcodes.h:377
virtual std::string const & GetNameForLocaleIdx(LocaleConstant) const
Definition: Object.h:466
LocaleConstant GetSessionDbLocaleIndex() const
Definition: WorldSession.h:498

References Object::GetGUID(), WorldObject::GetNameForLocaleIdx(), Player::GetSession(), WorldSession::GetSessionDbLocaleIndex(), SpellInfo::HasAttribute(), Object::IsPlayer(), m_caster, m_spellInfo, WorldSession::SendPacket(), SMSG_RESURRECT_REQUEST, and SPELL_ATTR3_NO_RES_TIMER.

Referenced by EffectResurrect(), and EffectResurrectNew().

◆ SendSpellCooldown()

void Spell::SendSpellCooldown ( )
4361{
4362 // xinef: properly add creature cooldowns
4363 if (!m_caster->IsPlayer())
4364 {
4366 {
4367 // xinef: this should be added here
4368 //m_caster->AddSpellCooldown(m_spellInfo->Id, 0, 0);
4369
4370 // xinef: this adds cooldowns to vehicle spells which misses them client-side (when we overwrote dbc info in eg.)
4373 {
4374 WorldPacket data(SMSG_SPELL_COOLDOWN, 8 + 1 + 4 + 4);
4375 data << m_caster->GetGUID();
4377 data << uint32(m_spellInfo->Id);
4379 player->SendDirectMessage(&data);
4380 }
4381 }
4382 return;
4383 }
4384
4385 Player* _player = m_caster->ToPlayer();
4386
4387 // mana/health/etc potions, disabled by client (until combat out as declarate)
4389 {
4390 // need in some way provided data for Spell::finish SendCooldownEvent
4391 _player->SetLastPotionId(m_CastItem->GetEntry());
4392 return;
4393 }
4394
4395 // have infinity cooldown but set at aura apply
4396 // do not set cooldown for triggered spells (needed by reincarnation)
4401 return;
4402
4404}
@ SPELL_COOLDOWN_FLAG_INCLUDE_GCD
Starts GCD in addition to normal cooldown specified in the packet.
Definition: Unit.h:617
@ SMSG_SPELL_COOLDOWN
Definition: Opcodes.h:338
void SetLastPotionId(uint32 item_id)
Definition: Player.h:1813
void AddSpellAndCategoryCooldowns(SpellInfo const *spellInfo, uint32 itemId, Spell *spell=nullptr, bool infinityCooldown=false)
Definition: Player.cpp:10942
uint32 RecoveryTime
Definition: SpellInfo.h:348
bool RequireCooldownInfo() const
Definition: SpellInfo.cpp:1182

References Player::AddSpellAndCategoryCooldowns(), Unit::GetCharmerOrOwnerPlayerOrPlayerItself(), Object::GetEntry(), Object::GetGUID(), HasTriggeredCastFlag(), SpellInfo::Id, SpellInfo::IsCooldownStartedOnEvent(), SpellInfo::IsPassive(), Object::IsPlayer(), Item::IsPotion(), m_caster, m_CastItem, m_spellInfo, SpellInfo::RecoveryTime, SpellInfo::RequireCooldownInfo(), Player::SetLastPotionId(), SMSG_SPELL_COOLDOWN, SPELL_COOLDOWN_FLAG_INCLUDE_GCD, Object::ToPlayer(), TRIGGERED_IGNORE_EFFECTS, and TRIGGERED_IGNORE_SPELL_AND_CATEGORY_CD.

Referenced by _cast().

◆ SendSpellGo()

void Spell::SendSpellGo ( )
4803{
4804 // not send invisible spell casting
4805 if (!IsNeedSendToClient(true))
4806 return;
4807
4808 //LOG_DEBUG("spells.aura", "Sending SMSG_SPELL_GO id={}", m_spellInfo->Id);
4809
4810 uint32 castFlags = CAST_FLAG_UNKNOWN_9;
4811
4812 // triggered spells with spell visual != 0
4814 castFlags |= CAST_FLAG_PENDING;
4815
4817 castFlags |= CAST_FLAG_PROJECTILE; // arrows/bullets visual
4818
4819 // should only be sent to self, but the current messaging doesn't make that possible
4820 if (m_caster->IsPlayer() || m_caster->IsPet())
4821 {
4822 switch (m_spellInfo->PowerType)
4823 {
4824 case POWER_HEALTH:
4825 break;
4826 case POWER_RUNE:
4827 castFlags |= CAST_FLAG_POWER_LEFT_SELF;
4828 break;
4829 default:
4830 if (m_powerCost != 0)
4831 {
4832 castFlags |= CAST_FLAG_POWER_LEFT_SELF;
4833 }
4834 break;
4835 }
4836 }
4837
4838 if ((m_caster->IsPlayer())
4842 {
4843 castFlags |= CAST_FLAG_NO_GCD; // not needed, but Blizzard sends it
4844 castFlags |= CAST_FLAG_RUNE_LIST; // rune cooldowns list
4845 }
4846
4848 castFlags |= CAST_FLAG_RUNE_LIST; // rune cooldowns list
4849
4850 if (m_targets.HasTraj())
4851 castFlags |= CAST_FLAG_ADJUST_MISSILE;
4852
4854 castFlags |= CAST_FLAG_NO_GCD;
4855
4856 PackedGuid realCasterGUID = m_caster->GetPackGUID();
4857 if (TempSummon const* tempSummon = m_caster->ToTempSummon())
4858 {
4859 if (tempSummon->GetEntry() == WORLD_TRIGGER)
4860 {
4861 if (GameObject* casterGameobject = tempSummon->GetSummonerGameObject())
4862 {
4863 realCasterGUID = casterGameobject->GetPackGUID();
4864 }
4865 }
4866 }
4867
4868 WorldPacket data(SMSG_SPELL_GO, 150); // guess size
4869
4870 if (m_CastItem)
4871 data << m_CastItem->GetPackGUID();
4872 else
4873 data << realCasterGUID;
4874
4875 data << realCasterGUID;
4876 data << uint8(m_cast_count); // pending spell cast?
4877 data << uint32(m_spellInfo->Id); // spellId
4878 data << uint32(castFlags); // cast flags
4879 data << uint32(GameTime::GetGameTimeMS().count()); // timestamp
4880
4881 WriteSpellGoTargets(&data);
4882
4883 m_targets.Write(data);
4884
4885 if (castFlags & CAST_FLAG_POWER_LEFT_SELF)
4887
4888 if (castFlags & CAST_FLAG_RUNE_LIST) // rune cooldowns list
4889 {
4890 //TODO: There is a crash caused by a spell with CAST_FLAG_RUNE_LIST casted by a creature
4891 //The creature is the mover of a player, so HandleCastSpellOpcode uses it as the caster
4892 if (Player* player = m_caster->ToPlayer())
4893 {
4894 uint8 runeMaskInitial = m_runesState;
4895 uint8 runeMaskAfterCast = player->GetRunesState();
4896 data << uint8(runeMaskInitial); // runes state before
4897 data << uint8(runeMaskAfterCast); // runes state after
4898 for (uint8 i = 0; i < MAX_RUNES; ++i)
4899 {
4900 uint8 mask = (1 << i);
4901 if (mask & runeMaskInitial && !(mask & runeMaskAfterCast)) // usable before andon cooldown now...
4902 {
4903 // float casts ensure the division is performed on floats as we need float result
4904 float baseCd = float(player->GetRuneBaseCooldown(i, true));
4905 data << uint8((baseCd - float(player->GetRuneCooldown(i))) / baseCd * 255); // rune cooldown passed
4906 }
4907 }
4908 }
4909 }
4910 if (castFlags & CAST_FLAG_ADJUST_MISSILE)
4911 {
4912 data << m_targets.GetElevation();
4914 }
4915
4916 if (castFlags & CAST_FLAG_PROJECTILE)
4917 WriteAmmoToPacket(&data);
4918
4919 if (castFlags & CAST_FLAG_VISUAL_CHAIN)
4920 {
4921 data << uint32(0);
4922 data << uint32(0);
4923 }
4924
4926 {
4927 data << uint8(0);
4928 }
4929
4930 m_caster->SendMessageToSet(&data, true);
4931}
@ SPELL_EFFECT_ACTIVATE_RUNE
Definition: SharedDefines.h:924
@ SPELL_ATTR0_USES_RANGED_SLOT
Definition: SharedDefines.h:383
@ SPELL_ATTR0_CU_NEEDS_AMMO_DATA
Definition: SpellInfo.h:195
@ CAST_FLAG_VISUAL_CHAIN
Definition: Spell.h:65
@ CAST_FLAG_ADJUST_MISSILE
Definition: Spell.h:63
@ CAST_FLAG_UNKNOWN_9
Definition: Spell.h:54
@ CAST_FLAG_NO_GCD
Definition: Spell.h:64
@ CAST_FLAG_PROJECTILE
Definition: Spell.h:51
@ CAST_FLAG_POWER_LEFT_SELF
Definition: Spell.h:57
@ CAST_FLAG_RUNE_LIST
Definition: Spell.h:67
@ CAST_FLAG_PENDING
Definition: Spell.h:46
@ SMSG_SPELL_GO
Definition: Opcodes.h:336
Definition: ObjectGuid.h:263
void Write(ByteBuffer &data)
Definition: Spell.cpp:179
void WriteSpellGoTargets(WorldPacket *data)
Writes miss and hit targets for a SMSG_SPELL_GO packet.
Definition: Spell.cpp:5018
void WriteAmmoToPacket(WorldPacket *data)
Definition: Spell.cpp:4933
bool IsNeedSendToClient(bool go) const
Definition: Spell.cpp:8096
SpellCastTimesEntry const * CastTimeEntry
Definition: SpellInfo.h:347
int32 CastTime
Definition: DBCStructure.h:1759

References CAST_FLAG_ADJUST_MISSILE, CAST_FLAG_NO_GCD, CAST_FLAG_PENDING, CAST_FLAG_POWER_LEFT_SELF, CAST_FLAG_PROJECTILE, CAST_FLAG_RUNE_LIST, CAST_FLAG_UNKNOWN_9, CAST_FLAG_VISUAL_CHAIN, SpellCastTimesEntry::CastTime, SpellInfo::CastTimeEntry, CLASS_CONTEXT_ABILITY, CLASS_DEATH_KNIGHT, SpellCastTargets::GetElevation(), GameTime::GetGameTimeMS(), Object::GetPackGUID(), Unit::GetPower(), SpellCastTargets::GetTargetMask(), SpellInfo::HasAttribute(), SpellInfo::HasEffect(), SpellCastTargets::HasTraj(), SpellInfo::Id, SpellInfo::IsAutoRepeatRangedSpell(), SpellInfo::IsChanneled(), Unit::IsClass(), IsNeedSendToClient(), Unit::IsPet(), Object::IsPlayer(), IsTriggered(), m_cast_count, m_caster, m_CastItem, m_delayMoment, m_delayTrajectory, m_powerCost, m_runesState, m_spellInfo, m_targets, m_triggeredByAuraSpell, MAX_RUNES, POWER_HEALTH, POWER_RUNE, SpellInfo::PowerType, SpellInfo::RuneCostID, WorldObject::SendMessageToSet(), SMSG_SPELL_GO, SPELL_ATTR0_CU_NEEDS_AMMO_DATA, SPELL_ATTR0_USES_RANGED_SLOT, SPELL_EFFECT_ACTIVATE_RUNE, SpellInfo::StartRecoveryTime, TARGET_FLAG_DEST_LOCATION, Object::ToPlayer(), Unit::ToTempSummon(), WORLD_TRIGGER, SpellCastTargets::Write(), WriteAmmoToPacket(), and WriteSpellGoTargets().

Referenced by _cast().

◆ SendSpellStart()

void Spell::SendSpellStart ( )
4723{
4724 if (!IsNeedSendToClient(false))
4725 return;
4726
4727 //LOG_DEBUG("spells.aura", "Sending SMSG_SPELL_START id={}", m_spellInfo->Id);
4728
4729 uint32 castFlags = CAST_FLAG_HAS_TRAJECTORY;
4730
4732 castFlags |= CAST_FLAG_PENDING;
4733
4735 castFlags |= CAST_FLAG_PROJECTILE;
4736
4737 if (m_caster->IsPlayer() || m_caster->IsPet())
4738 {
4739 switch (m_spellInfo->PowerType)
4740 {
4741 case POWER_HEALTH:
4742 break;
4743 case POWER_RUNE:
4744 castFlags |= CAST_FLAG_POWER_LEFT_SELF;
4745 break;
4746 default:
4747 if (m_powerCost != 0)
4748 {
4749 castFlags |= CAST_FLAG_POWER_LEFT_SELF;
4750 }
4751 break;
4752 }
4753 }
4754
4756 castFlags |= CAST_FLAG_NO_GCD; // not needed, but Blizzard sends it
4757
4758 PackedGuid realCasterGUID = m_caster->GetPackGUID();
4759 if (TempSummon const* tempSummon = m_caster->ToTempSummon())
4760 {
4761 if (tempSummon->GetEntry() == WORLD_TRIGGER)
4762 {
4763 if (GameObject* casterGameobject = tempSummon->GetSummonerGameObject())
4764 {
4765 realCasterGUID = casterGameobject->GetPackGUID();
4766 }
4767 }
4768 }
4769
4770 WorldPacket data(SMSG_SPELL_START, (8 + 8 + 4 + 4 + 2));
4771 if (m_CastItem)
4772 data << m_CastItem->GetPackGUID();
4773 else
4774 data << realCasterGUID;
4775
4776 data << realCasterGUID;
4777 data << uint8(m_cast_count); // pending spell cast?
4778 data << uint32(m_spellInfo->Id); // spellId
4779 data << uint32(castFlags); // cast flags
4780 data << int32(m_timer); // delay?
4781
4782 m_targets.Write(data);
4783
4784 if (castFlags & CAST_FLAG_POWER_LEFT_SELF)
4786
4787 if (castFlags & CAST_FLAG_PROJECTILE)
4788 WriteAmmoToPacket(&data);
4789
4790 if (castFlags & CAST_FLAG_UNKNOWN_23)
4791 {
4792 data << uint32(0);
4793 data << uint32(0);
4794 }
4795
4796 m_caster->SendMessageToSet(&data, true);
4797
4800}
@ CAST_FLAG_UNKNOWN_23
Definition: Spell.h:68
@ CAST_FLAG_HAS_TRAJECTORY
Definition: Spell.h:47
@ SMSG_SPELL_START
Definition: Opcodes.h:335

References CAST_FLAG_HAS_TRAJECTORY, CAST_FLAG_NO_GCD, CAST_FLAG_PENDING, CAST_FLAG_POWER_LEFT_SELF, CAST_FLAG_PROJECTILE, CAST_FLAG_UNKNOWN_23, SpellCastTimesEntry::CastTime, SpellInfo::CastTimeEntry, WorldObject::FindMap(), Object::GetGUID(), Object::GetPackGUID(), Unit::GetPower(), SpellInfo::HasAttribute(), SpellInfo::Id, SpellInfo::IsAutoRepeatRangedSpell(), SpellInfo::IsChanneled(), IsNeedSendToClient(), Unit::IsPet(), Object::IsPlayer(), IsTriggered(), m_cast_count, m_caster, m_CastItem, m_powerCost, m_spellInfo, m_targets, m_timer, m_triggeredByAuraSpell, Player::NeedSendSpectatorData(), POWER_HEALTH, POWER_RUNE, SpellInfo::PowerType, SpellInfo::RuneCostID, ArenaSpectator::SendCommand_Spell(), WorldObject::SendMessageToSet(), SMSG_SPELL_START, SPELL_ATTR0_CU_NEEDS_AMMO_DATA, SPELL_ATTR0_USES_RANGED_SLOT, Object::ToPlayer(), Unit::ToTempSummon(), WORLD_TRIGGER, SpellCastTargets::Write(), and WriteAmmoToPacket().

Referenced by prepare().

◆ SetAutoRepeat()

void Spell::SetAutoRepeat ( bool  rep)
inline
552{ m_autoRepeat = rep; }

References m_autoRepeat.

◆ SetDelayStart()

void Spell::SetDelayStart ( uint64  m_time)
inline
567{ m_delayStart = m_time; }

References m_delayStart.

Referenced by _cast(), and SpellEvent::Execute().

◆ SetExecutedCurrently()

void Spell::SetExecutedCurrently ( bool  yes)
inline
565{m_executedCurrently = yes;}

References m_executedCurrently.

Referenced by _cast(), and Unit::AttackerStateUpdate().

◆ SetReferencedFromCurrent()

void Spell::SetReferencedFromCurrent ( bool  yes)
inline

◆ SetSpellValue()

void Spell::SetSpellValue ( SpellValueMod  mod,
int32  value 
)
8438{
8439 switch (mod)
8440 {
8442 m_spellValue->EffectBasePoints[0] = m_spellInfo->Effects[EFFECT_0].CalcBaseValue(value);
8443 break;
8445 m_spellValue->EffectBasePoints[1] = m_spellInfo->Effects[EFFECT_1].CalcBaseValue(value);
8446 break;
8448 m_spellValue->EffectBasePoints[2] = m_spellInfo->Effects[EFFECT_2].CalcBaseValue(value);
8449 break;
8451 m_spellValue->RadiusMod = (float)value / 10000;
8452 break;
8455 break;
8458 break;
8460 m_spellValue->AuraDuration = value;
8461 break;
8463 m_spellValue->ForcedCritResult = (bool)value;
8464 break;
8466 m_spellValue->MiscVal[0] = value;
8467 break;
8469 m_spellValue->MiscVal[1] = value;
8470 break;
8472 m_spellValue->MiscVal[2] = value;
8473 break;
8474 }
8475}
@ SPELLVALUE_AURA_STACK
Definition: SpellDefines.h:118
@ SPELLVALUE_MISCVALUE1
Definition: SpellDefines.h:122
@ SPELLVALUE_AURA_DURATION
Definition: SpellDefines.h:119
@ SPELLVALUE_MISCVALUE2
Definition: SpellDefines.h:123
@ SPELLVALUE_RADIUS_MOD
Definition: SpellDefines.h:116
@ SPELLVALUE_MAX_TARGETS
Definition: SpellDefines.h:117
@ SPELLVALUE_FORCED_CRIT_RESULT
Definition: SpellDefines.h:120
@ SPELLVALUE_MISCVALUE0
Definition: SpellDefines.h:121
bool ForcedCritResult
Definition: Spell.h:220

References SpellValue::AuraDuration, SpellValue::AuraStackAmount, EFFECT_0, EFFECT_1, EFFECT_2, SpellValue::EffectBasePoints, SpellInfo::Effects, SpellValue::ForcedCritResult, m_spellInfo, m_spellValue, SpellValue::MaxAffectedTargets, SpellValue::MiscVal, SpellValue::RadiusMod, SPELLVALUE_AURA_DURATION, SPELLVALUE_AURA_STACK, SPELLVALUE_BASE_POINT0, SPELLVALUE_BASE_POINT1, SPELLVALUE_BASE_POINT2, SPELLVALUE_FORCED_CRIT_RESULT, SPELLVALUE_MAX_TARGETS, SPELLVALUE_MISCVALUE0, SPELLVALUE_MISCVALUE1, SPELLVALUE_MISCVALUE2, and SPELLVALUE_RADIUS_MOD.

Referenced by Player::CastItemUseSpell(), Unit::CastSpell(), and spell_gen_mod_radius_by_caster_scale::PrepareSpellScript().

◆ setState()

void Spell::setState ( uint32  state)
inline
486{ m_spellState = state; }

References m_spellState.

◆ SummonGuardian()

void Spell::SummonGuardian ( uint32  i,
uint32  entry,
SummonPropertiesEntry const *  properties,
uint32  numSummons,
bool  personalSpawn 
)
protected
5961{
5962 Unit* caster = m_originalCaster;
5963 if (!caster)
5964 return;
5965
5966 if (caster->IsTotem())
5967 caster = caster->ToTotem()->GetOwner();
5968
5969 // in another case summon new
5970 uint8 summonLevel = caster->GetLevel();
5971
5972 // level of pet summoned using engineering item based at engineering skill level
5973 if (m_CastItem && caster->IsPlayer())
5974 if (ItemTemplate const* proto = m_CastItem->GetTemplate())
5975 {
5976 // xinef: few special cases
5977 if (proto->RequiredSkill == SKILL_ENGINEERING)
5978 {
5979 if (uint16 skill202 = caster->ToPlayer()->GetSkillValue(SKILL_ENGINEERING))
5980 summonLevel = skill202 / 5;
5981 }
5982
5983 switch (m_spellInfo->Id)
5984 {
5985 // Dragon's Call
5986 case 13049:
5987 summonLevel = 55;
5988 break;
5989
5990 // Cleansed Timberling Heart: Summon Timberling
5991 case 5666:
5992 summonLevel = 7;
5993 break;
5994
5995 // Glowing Cat Figurine: Summon Ghost Saber
5996 case 6084:
5997 // minLevel 19, maxLevel 20
5998 summonLevel = 20;
5999 break;
6000
6001 // Spiked Collar: Summon Felhunter
6002 case 8176:
6003 summonLevel = 30;
6004 break;
6005
6006 // Dog Whistle: Summon Tracking Hound
6007 case 9515:
6008 summonLevel = 30;
6009 break;
6010
6011 // Barov Peasant Caller: Death by Peasant
6012 case 18307:
6013 case 18308:
6014 summonLevel = 60;
6015 break;
6016
6017 // Thornling Seed: Plant Thornling
6018 case 22792:
6019 summonLevel = 60;
6020 break;
6021
6022 // Cannonball Runner: Summon Crimson Cannon
6023 case 6251:
6024 summonLevel = 61;
6025 break;
6026 }
6027 }
6028
6029 summonLevel = std::min<uint8>(sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL) + sWorld->getIntConfig(CONFIG_WORLD_BOSS_LEVEL_DIFF), std::max<uint8>(1U, summonLevel));
6030
6031 float radius = 5.0f;
6032 int32 duration = m_spellInfo->GetDuration();
6033
6034 if (Player* modOwner = m_originalCaster->GetSpellModOwner())
6035 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_DURATION, duration);
6036
6037 //TempSummonType summonType = (duration == 0) ? TEMPSUMMON_DEAD_DESPAWN : TEMPSUMMON_TIMED_DESPAWN;
6038 Map* map = caster->GetMap();
6039 TempSummon* summon = nullptr;
6040
6041 uint32 currMinionsCount = m_caster->m_Controlled.size();
6042 uint32 totalNumGuardians = numGuardians + currMinionsCount;
6043
6044 for (uint32 count = 0; count < numGuardians; ++count)
6045 {
6046 Position pos;
6047
6048 // xinef: do not use precalculated position for effect summon pet in this function
6049 // it means it was cast by NPC and should have its position overridden unless the
6050 // target position is specified in the DB AND the effect has no or zero radius
6051 if ((totalNumGuardians == 1 && GetSpellInfo()->Effects[i].Effect != SPELL_EFFECT_SUMMON_PET) ||
6052 (GetSpellInfo()->Effects[i].TargetA.GetTarget() == TARGET_DEST_DB &&
6053 (!GetSpellInfo()->Effects[i].HasRadius() || GetSpellInfo()->Effects[i].RadiusEntry->RadiusMax == 0)))
6054 {
6055 pos = *destTarget;
6056 }
6057 else
6058 {
6059 // randomize position
6060 pos = m_caster->GetRandomPoint(*destTarget, radius);
6061 }
6062
6063 summon = map->SummonCreature(entry, pos, properties, duration, caster, m_spellInfo->Id, 0, personalSpawn);
6064 if (!summon)
6065 return;
6066
6067 // xinef: set calculated level
6068 summon->SetLevel(summonLevel);
6069
6070 // if summonLevel changed, set stats for calculated level
6071 if (summonLevel != caster->GetLevel())
6072 {
6073 ((Guardian*)summon)->InitStatsForLevel(summonLevel);
6074 }
6075
6076 // xinef: if we have more than one guardian, change follow angle
6077 if (summon->HasUnitTypeMask(UNIT_MASK_MINION) && totalNumGuardians > 1)
6078 ((Minion*)summon)->SetFollowAngle(m_caster->GetAbsoluteAngle(pos.GetPositionX(), pos.GetPositionY()));
6079 //else if (summon->HasUnitTypeMask(UNIT_MASK_MINION) && m_targets.HasDst())
6080 // ((Minion*)summon)->SetFollowAngle(m_caster->GetAngle(summon));
6081
6082 // xinef: move this here, some auras are added in initstatsforlevel!
6083 if (!summon->IsInCombat() && !summon->IsTrigger())
6084 {
6085 // summon->AI()->EnterEvadeMode();
6086 summon->GetMotionMaster()->Clear(false);
6088 }
6089
6090 if (properties && properties->Category == SUMMON_CATEGORY_ALLY)
6091 summon->SetFaction(caster->GetFaction());
6092
6094 }
6095}
@ SKILL_ENGINEERING
Definition: SharedDefines.h:2923
@ CONFIG_MAX_PLAYER_LEVEL
Definition: IWorld.h:236
@ CONFIG_WORLD_BOSS_LEVEL_DIFF
Definition: IWorld.h:286
bool IsTrigger() const
Definition: Creature.h:75
Definition: TemporarySummon.h:76
Unit * GetOwner() const
Definition: TemporarySummon.cpp:385
void SetLevel(uint8 lvl, bool showLevelChange=true)
Definition: Unit.cpp:15460

References SummonPropertiesEntry::Category, MotionMaster::Clear(), CONFIG_MAX_PLAYER_LEVEL, CONFIG_WORLD_BOSS_LEVEL_DIFF, destTarget, ExecuteLogEffectSummonObject(), Position::GetAbsoluteAngle(), SpellInfo::GetDuration(), Unit::GetFaction(), Unit::GetFollowAngle(), Unit::GetLevel(), WorldObject::GetMap(), Unit::GetMotionMaster(), Minion::GetOwner(), Position::GetPositionX(), Position::GetPositionY(), WorldObject::GetRandomPoint(), Player::GetSkillValue(), GetSpellInfo(), Unit::GetSpellModOwner(), Item::GetTemplate(), Unit::HasUnitTypeMask(), SpellInfo::Id, Unit::IsInCombat(), Object::IsPlayer(), Unit::IsTotem(), Creature::IsTrigger(), m_caster, m_CastItem, Unit::m_Controlled, m_originalCaster, m_spellInfo, MOTION_SLOT_ACTIVE, MotionMaster::MoveFollow(), PET_FOLLOW_DIST, Unit::SetFaction(), Unit::SetLevel(), SKILL_ENGINEERING, SPELL_EFFECT_SUMMON_PET, SPELLMOD_DURATION, SUMMON_CATEGORY_ALLY, Map::SummonCreature(), sWorld, TARGET_DEST_DB, Object::ToPlayer(), Unit::ToTotem(), and UNIT_MASK_MINION.

Referenced by EffectSummonPet(), and EffectSummonType().

◆ TakeAmmo()

void Spell::TakeAmmo ( )
5385{
5387 {
5389
5390 // wands don't have ammo
5391 if (!pItem || pItem->IsBroken() || pItem->GetTemplate()->SubClass == ITEM_SUBCLASS_WEAPON_WAND)
5392 return;
5393
5394 if (pItem->GetTemplate()->InventoryType == INVTYPE_THROWN)
5395 {
5396 if (pItem->GetMaxStackCount() == 1)
5397 {
5398 // decrease durability for non-stackable throw weapon
5400 }
5401 else
5402 {
5403 // decrease items amount for stackable throw weapon
5404 uint32 count = 1;
5405 m_caster->ToPlayer()->DestroyItemCount(pItem, count, true);
5406 }
5407 }
5409 m_caster->ToPlayer()->DestroyItemCount(ammo, 1, true);
5410 }
5411}
@ EQUIPMENT_SLOT_RANGED
Definition: Player.h:697
@ INVTYPE_THROWN
Definition: ItemTemplate.h:281
uint32 GetMaxStackCount() const
Definition: Item.h:274
void DurabilityPointLossForEquipSlot(EquipmentSlots slot)
Definition: Player.cpp:4835

References Player::DestroyItemCount(), Player::DurabilityPointLossForEquipSlot(), EQUIPMENT_SLOT_RANGED, Item::GetMaxStackCount(), Item::GetTemplate(), Object::GetUInt32Value(), Player::GetWeaponForAttack(), ItemTemplate::InventoryType, INVTYPE_THROWN, Item::IsBroken(), Object::IsPlayer(), ITEM_SUBCLASS_WEAPON_WAND, m_attackType, m_caster, PLAYER_AMMO_ID, RANGED_ATTACK, ItemTemplate::SubClass, and Object::ToPlayer().

Referenced by handle_immediate(), and HandleLaunchPhase().

◆ TakeCastItem()

void Spell::TakeCastItem ( )
5258{
5259 if (!m_CastItem || !m_caster->IsPlayer())
5260 return;
5261
5262 // not remove cast item at triggered spell (equipping, weapon damage, etc)
5264 return;
5265
5266 ItemTemplate const* proto = m_CastItem->GetTemplate();
5267
5268 if (!proto)
5269 {
5270 // This code is to avoid a crash
5271 // I'm not sure, if this is really an error, but I guess every item needs a prototype
5272 LOG_ERROR("spells", "Cast item has no item prototype {}", m_CastItem->GetGUID().ToString());
5273 return;
5274 }
5275
5276 bool expendable = false;
5277 bool withoutCharges = false;
5278
5279 for (int i = 0; i < MAX_ITEM_PROTO_SPELLS; ++i)
5280 {
5281 if (proto->Spells[i].SpellId)
5282 {
5283 // item has limited charges
5284 if (proto->Spells[i].SpellCharges)
5285 {
5286 if (proto->Spells[i].SpellCharges < 0)
5287 expendable = true;
5288
5289 int32 charges = m_CastItem->GetSpellCharges(i);
5290
5291 // item has charges left
5292 if (charges)
5293 {
5294 (charges > 0) ? --charges : ++charges; // std::abs(charges) less at 1 after use
5295 if (proto->Stackable == 1)
5296 m_CastItem->SetSpellCharges(i, charges);
5298 }
5299
5300 // all charges used
5301 withoutCharges = (charges == 0);
5302 }
5303 }
5304 }
5305
5306 if (expendable && withoutCharges)
5307 {
5308 uint32 count = 1;
5309 m_caster->ToPlayer()->DestroyItemCount(m_CastItem, count, true);
5310
5311 // prevent crash at access to deleted m_targets.GetItemTarget
5313 m_targets.SetItemTarget(nullptr);
5314
5315 m_CastItem = nullptr;
5317 }
5318}
void SetSpellCharges(uint8 index, int32 value)
Definition: Item.h:318
int32 Stackable
Definition: ItemTemplate.h:645

References ObjectGuid::Clear(), Player::DestroyItemCount(), Object::GetGUID(), SpellCastTargets::GetItemTarget(), Item::GetSpellCharges(), Item::GetTemplate(), HasTriggeredCastFlag(), Object::IsPlayer(), ITEM_CHANGED, LOG_ERROR, m_caster, m_CastItem, m_castItemGUID, m_targets, MAX_ITEM_PROTO_SPELLS, SpellCastTargets::SetItemTarget(), Item::SetSpellCharges(), Item::SetState(), _Spell::SpellCharges, _Spell::SpellId, ItemTemplate::Spells, ItemTemplate::Stackable, Object::ToPlayer(), ObjectGuid::ToString(), and TRIGGERED_IGNORE_CAST_ITEM.

Referenced by _cast(), and handle_immediate().

◆ TakePower()

void Spell::TakePower ( )
5321{
5323 return;
5324
5325 //Don't take power if the spell is cast while .cheat power is enabled.
5326 if (m_caster->IsPlayer())
5328 return;
5329
5331 bool hit = true;
5332 if (m_caster->IsPlayer())
5333 {
5335 if (ObjectGuid targetGUID = m_targets.GetUnitTargetGUID())
5336 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
5337 if (ihit->targetGUID == targetGUID)
5338 {
5339 if (ihit->missCondition != SPELL_MISS_NONE && ihit->missCondition != SPELL_MISS_BLOCK && ihit->missCondition != SPELL_MISS_ABSORB && ihit->missCondition != SPELL_MISS_REFLECT)
5340 {
5341 hit = false;
5342 //lower spell cost on fail (by talent aura)
5343 if (Player* modOwner = m_caster->ToPlayer()->GetSpellModOwner())
5344 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_SPELL_COST_REFUND_ON_FAIL, m_powerCost, this);
5345 }
5346 break;
5347 }
5348 }
5349
5350 if (PowerType == POWER_RUNE)
5351 {
5352 TakeRunePower(hit);
5353 return;
5354 }
5355
5356 if (!m_powerCost)
5357 return;
5358
5359 // health as power used
5360 if (PowerType == POWER_HEALTH)
5361 {
5363 return;
5364 }
5365
5366 if (PowerType >= MAX_POWERS)
5367 {
5368 LOG_ERROR("spells", "Spell::TakePower: Unknown power type '{}'", PowerType);
5369 return;
5370 }
5371
5372 if (hit)
5374 else
5376
5377 // Set the five second timer
5378 if (PowerType == POWER_MANA && m_powerCost > 0)
5379 {
5381 }
5382}
@ SPELL_MISS_ABSORB
Definition: SharedDefines.h:1529
@ SPELLMOD_SPELL_COST_REFUND_ON_FAIL
Definition: SpellDefines.h:106
int32 ModifyHealth(int32 val)
Definition: Unit.cpp:14091
void SetLastManaUse(uint32 spellCastTime)
Definition: Unit.h:1073
void TakeRunePower(bool didHit)
Definition: Spell.cpp:5467

References CHEAT_POWER, Player::GetCommandStatus(), GameTime::GetGameTimeMS(), Unit::GetSpellModOwner(), SpellCastTargets::GetUnitTargetGUID(), SpellInfo::Id, irand(), Object::IsPlayer(), LOG_ERROR, m_caster, m_CastItem, m_powerCost, m_spellInfo, m_targets, m_triggeredByAuraSpell, m_UniqueTargetInfo, MAX_POWERS, Unit::ModifyHealth(), Unit::ModifyPower(), POWER_ENERGY, POWER_HEALTH, POWER_MANA, POWER_RAGE, POWER_RUNE, POWER_RUNIC_POWER, SpellInfo::PowerType, Unit::SetLastManaUse(), SPELL_MISS_ABSORB, SPELL_MISS_BLOCK, SPELL_MISS_NONE, SPELL_MISS_REFLECT, SPELLMOD_SPELL_COST_REFUND_ON_FAIL, TakeRunePower(), and Object::ToPlayer().

Referenced by _cast().

◆ TakeReagents()

void Spell::TakeReagents ( )
5537{
5538 if (!m_caster->IsPlayer())
5539 return;
5540
5541 ItemTemplate const* castItemTemplate = m_CastItem ? m_CastItem->GetTemplate() : nullptr;
5542
5543 // do not take reagents for these item casts
5544 if (castItemTemplate && castItemTemplate->HasFlag(ITEM_FLAG_NO_REAGENT_COST))
5545 return;
5546
5547 Player* p_caster = m_caster->ToPlayer();
5548 if (p_caster->CanNoReagentCast(m_spellInfo))
5549 return;
5550
5551 for (uint32 x = 0; x < MAX_SPELL_REAGENTS; ++x)
5552 {
5553 if (m_spellInfo->Reagent[x] <= 0)
5554 continue;
5555
5556 uint32 itemid = m_spellInfo->Reagent[x];
5557 uint32 itemcount = m_spellInfo->ReagentCount[x];
5558
5559 // if CastItem is also spell reagent
5560 if (castItemTemplate && castItemTemplate->ItemId == itemid)
5561 {
5562 for (int s = 0; s < MAX_ITEM_PROTO_SPELLS; ++s)
5563 {
5564 // CastItem will be used up and does not count as reagent
5565 int32 charges = m_CastItem->GetSpellCharges(s);
5566 if (castItemTemplate->Spells[s].SpellCharges < 0 && std::abs(charges) < 2)
5567 {
5568 ++itemcount;
5569 break;
5570 }
5571 }
5572
5573 m_CastItem = nullptr;
5575 }
5576
5577 // if GetItemTarget is also spell reagent
5578 if (m_targets.GetItemTargetEntry() == itemid)
5579 m_targets.SetItemTarget(nullptr);
5580
5581 p_caster->DestroyItemCount(itemid, itemcount, true);
5582 }
5583}
uint32 ItemId
Definition: ItemTemplate.h:620

References Player::CanNoReagentCast(), ObjectGuid::Clear(), Player::DestroyItemCount(), SpellCastTargets::GetItemTargetEntry(), Item::GetSpellCharges(), Item::GetTemplate(), ItemTemplate::HasFlag(), Object::IsPlayer(), ITEM_FLAG_NO_REAGENT_COST, ItemTemplate::ItemId, m_caster, m_CastItem, m_castItemGUID, m_spellInfo, m_targets, MAX_ITEM_PROTO_SPELLS, MAX_SPELL_REAGENTS, SpellInfo::Reagent, SpellInfo::ReagentCount, SpellCastTargets::SetItemTarget(), _Spell::SpellCharges, ItemTemplate::Spells, and Object::ToPlayer().

Referenced by _cast().

◆ TakeRunePower()

void Spell::TakeRunePower ( bool  didHit)
5468{
5470 return;
5471
5472 SpellRuneCostEntry const* runeCostData = sSpellRuneCostStore.LookupEntry(m_spellInfo->RuneCostID);
5473 if (!runeCostData || (runeCostData->NoRuneCost() && runeCostData->NoRunicPowerGain()))
5474 return;
5475
5476 Player* player = m_caster->ToPlayer();
5477 m_runesState = player->GetRunesState(); // store previous state
5478
5479 int32 runeCost[NUM_RUNE_TYPES]; // blood, frost, unholy, death
5480
5481 for (uint32 i = 0; i < RUNE_DEATH; ++i)
5482 {
5483 runeCost[i] = runeCostData->RuneCost[i];
5484 if (Player* modOwner = m_caster->GetSpellModOwner())
5485 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_COST, runeCost[i], this);
5486 }
5487
5488 runeCost[RUNE_DEATH] = 0; // calculated later
5489
5490 for (uint32 i = 0; i < MAX_RUNES; ++i)
5491 {
5492 RuneType rune = player->GetCurrentRune(i);
5493 if (!player->GetRuneCooldown(i) && runeCost[rune] > 0)
5494 {
5495 player->SetRuneCooldown(i, didHit ? player->GetRuneBaseCooldown(i, false) : uint32(RUNE_MISS_COOLDOWN));
5496 player->SetLastUsedRune(rune);
5497 runeCost[rune]--;
5498 }
5499 }
5500
5501 // Xinef: firstly consume death runes of base type
5502 // Xinef: in second loop consume all available
5503 for (uint8 loop = 0; loop < 2; ++loop)
5504 {
5505 runeCost[RUNE_DEATH] = runeCost[RUNE_BLOOD] + runeCost[RUNE_UNHOLY] + runeCost[RUNE_FROST];
5506 if (runeCost[RUNE_DEATH] > 0)
5507 {
5508 for (uint8 i = 0; i < MAX_RUNES; ++i)
5509 {
5510 RuneType rune = player->GetCurrentRune(i);
5511 if (!player->GetRuneCooldown(i) && rune == RUNE_DEATH && (loop ? true : (runeCost[player->GetBaseRune(i)] > 0)))
5512 {
5513 player->SetRuneCooldown(i, didHit ? player->GetRuneBaseCooldown(i, false) : uint32(RUNE_MISS_COOLDOWN));
5514 player->SetLastUsedRune(rune);
5515 runeCost[rune]--;
5516 if (!loop)
5517 runeCost[player->GetBaseRune(i)]--;
5518
5519 // keep Death Rune type if missed
5520 if (didHit)
5521 player->RestoreBaseRune(i);
5522
5523 if (runeCost[RUNE_DEATH] == 0)
5524 break;
5525 }
5526 }
5527 }
5528 }
5529
5530 // you can gain some runic power when use runes
5531 if (didHit)
5532 if (int32 rp = int32(runeCostData->runePowerGain * sWorld->getRate(RATE_POWER_RUNICPOWER_INCOME)))
5533 player->ModifyPower(POWER_RUNIC_POWER, int32(rp));
5534}
@ RATE_POWER_RUNICPOWER_INCOME
Definition: IWorld.h:434
@ RUNE_UNHOLY
Definition: Player.h:415
@ RUNE_BLOOD
Definition: Player.h:414
@ RUNE_MISS_COOLDOWN
Definition: Player.h:409
void SetLastUsedRune(RuneType type)
Definition: Player.h:2513
uint32 GetRuneBaseCooldown(uint8 index, bool skipGrace)
Definition: Player.cpp:13404
void RestoreBaseRune(uint8 index)
Definition: Player.cpp:13433
bool NoRunicPowerGain() const
Definition: DBCStructure.h:1810
uint32 runePowerGain
Definition: DBCStructure.h:1807

References CLASS_CONTEXT_ABILITY, CLASS_DEATH_KNIGHT, Player::GetBaseRune(), Player::GetCurrentRune(), Player::GetRuneBaseCooldown(), Player::GetRuneCooldown(), Player::GetRunesState(), Unit::GetSpellModOwner(), SpellInfo::Id, Unit::IsClass(), Object::IsPlayer(), m_caster, m_runesState, m_spellInfo, MAX_RUNES, Unit::ModifyPower(), SpellRuneCostEntry::NoRuneCost(), SpellRuneCostEntry::NoRunicPowerGain(), NUM_RUNE_TYPES, POWER_RUNIC_POWER, RATE_POWER_RUNICPOWER_INCOME, Player::RestoreBaseRune(), RUNE_BLOOD, RUNE_DEATH, RUNE_FROST, RUNE_MISS_COOLDOWN, RUNE_UNHOLY, SpellRuneCostEntry::RuneCost, SpellInfo::RuneCostID, SpellRuneCostEntry::runePowerGain, Player::SetLastUsedRune(), Player::SetRuneCooldown(), SPELLMOD_COST, sSpellRuneCostStore, sWorld, and Object::ToPlayer().

Referenced by TakePower().

◆ TriggerGlobalCooldown()

void Spell::TriggerGlobalCooldown ( )
protected
8855{
8857 if (!gcd)
8858 {
8859 // Xinef: fix for charmed pet spells with no cooldown info
8861 gcd = MIN_GCD;
8862 else
8863 return;
8864 }
8865
8866 if (m_caster->IsPlayer())
8868 return;
8869
8870 // Global cooldown can't leave range 1..1.5 secs
8871 // There are some spells (mostly not casted directly by player) that have < 1 sec and > 1.5 sec global cooldowns
8872 // but as tests show are not affected by any spell mods.
8874 {
8875 // gcd modifier auras are applied only to own spells and only players have such mods
8876 if (m_caster->IsPlayer())
8878
8879 // Apply haste rating
8882 {
8883 gcd = int32(float(gcd) * m_caster->GetFloatValue(UNIT_MOD_CAST_SPEED));
8884 }
8885
8886 if (gcd < MIN_GCD)
8887 gcd = MIN_GCD;
8888 else if (gcd > MAX_GCD)
8889 gcd = MAX_GCD;
8890 }
8891
8892 // Only players or controlled units have global cooldown
8893 if (m_caster->GetCharmInfo())
8895 else if (m_caster->IsPlayer())
8897}
@ SPELLMOD_GLOBAL_COOLDOWN
Definition: SpellDefines.h:97
@ MIN_GCD
Definition: Spell.cpp:8839
@ MAX_GCD
Definition: Spell.cpp:8840
void AddGlobalCooldown(SpellInfo const *spellInfo, uint32 gcd)
Definition: CharmInfo.cpp:419

References GlobalCooldownMgr::AddGlobalCooldown(), Player::ApplySpellMod(), SpellInfo::CategoryRecoveryTime, CHEAT_COOLDOWN, SpellInfo::DmgClass, Unit::GetCharmInfo(), Player::GetCommandStatus(), Object::GetFloatValue(), Player::GetGlobalCooldownMgr(), CharmInfo::GetGlobalCooldownMgr(), SpellInfo::HasAttribute(), SpellInfo::Id, Object::IsPlayer(), m_caster, m_spellInfo, MAX_GCD, MIN_GCD, SpellInfo::RecoveryTime, SPELL_ATTR0_IS_ABILITY, SPELL_ATTR0_USES_RANGED_SLOT, SPELL_DAMAGE_CLASS_MELEE, SPELL_DAMAGE_CLASS_RANGED, SPELLMOD_GLOBAL_COOLDOWN, SpellInfo::StartRecoveryCategory, SpellInfo::StartRecoveryTime, Object::ToPlayer(), and UNIT_MOD_CAST_SPEED.

Referenced by prepare().

◆ update()

void Spell::update ( uint32  difftime)
4407{
4408 // update pointers based at it's GUIDs
4409 if (!UpdatePointers())
4410 {
4411 // cancel the spell if UpdatePointers() returned false, something wrong happened there
4412 cancel();
4413 return;
4414 }
4415
4417 {
4418 LOG_DEBUG("spells.aura", "Spell {} is cancelled due to removal of target.", m_spellInfo->Id);
4419 cancel();
4420 return;
4421 }
4422
4423 // check if the player caster has moved before the spell finished
4424 // xinef: added preparing state (real cast, skip channels as they have other flags for this)
4425 if ((m_caster->IsPlayer() && m_timer != 0) &&
4428 {
4429 // don't cancel for melee, autorepeat, triggered and instant spells
4431 cancel(true);
4432 }
4433
4434 switch (m_spellState)
4435 {
4437 {
4438 if (m_timer > 0)
4439 {
4440 if (difftime >= (uint32)m_timer)
4441 m_timer = 0;
4442 else
4443 m_timer -= difftime;
4444 }
4445
4446 if (m_timer == 0 && !IsNextMeleeSwingSpell() && !IsAutoRepeat())
4447 // don't CheckCast for instant spells - done in spell::prepare, skip duplicate checks, needed for range checks for example
4448 cast(!m_casttime);
4449 break;
4450 }
4452 {
4453 if (m_timer)
4454 {
4455 if (m_timer > 0)
4456 {
4457 if (difftime >= (uint32)m_timer)
4458 m_timer = 0;
4459 else
4460 m_timer -= difftime;
4461 }
4462 }
4463
4464 if (m_timer == 0)
4465 {
4467
4468 finish();
4469 }
4470 // Xinef: Dont update channeled target list on last tick, allow auras to update duration properly
4471 // Xinef: Added this strange check because of diffrent update routines for players / creatures
4472 // Xinef: If creature gets new aura in 800ms and in 840ms its updated with diff 270, not 40 is removed from duration but 270
4473 // Xinef: so the aura can be removed in different updates for all units
4474 else if ((m_timer < 0 || m_timer > 300) && !UpdateChanneledTargetList())
4475 {
4476 LOG_DEBUG("spells.aura", "Channeled spell {} is removed due to lack of targets", m_spellInfo->Id);
4478 finish();
4479 }
4480 break;
4481 }
4482 default:
4483 break;
4484 }
4485}
bool UpdateChanneledTargetList()
Definition: Spell.cpp:3392

References cancel(), cast(), SpellInfo::Effects, finish(), SpellCastTargets::GetUnitTarget(), SpellCastTargets::GetUnitTargetGUID(), Unit::HasUnitMovementFlag(), SpellInfo::Id, SpellInfo::InterruptFlags, IsAutoRepeat(), Unit::isMoving(), IsNextMeleeSwingSpell(), Object::IsPlayer(), IsTriggered(), LOG_DEBUG, m_caster, m_casttime, m_spellInfo, m_spellState, m_targets, m_timer, MOVEMENTFLAG_FALLING_FAR, SendChannelUpdate(), SPELL_EFFECT_STUCK, SPELL_INTERRUPT_FLAG_MOVEMENT, SPELL_STATE_CASTING, SPELL_STATE_PREPARING, UpdateChanneledTargetList(), and UpdatePointers().

Referenced by SpellEvent::Execute().

◆ UpdateChanneledTargetList()

bool Spell::UpdateChanneledTargetList ( )
protected
3393{
3394 // Not need check return true
3396 return true;
3397
3398 uint8 channelTargetEffectMask = m_channelTargetEffectMask;
3399 uint8 channelAuraMask = 0;
3400 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
3402 channelAuraMask |= 1 << i;
3403
3404 channelAuraMask &= channelTargetEffectMask;
3405
3406 float range = 0;
3407 if (channelAuraMask)
3408 {
3410 if (range == 0)
3411 for(int i = EFFECT_0; i <= EFFECT_2; ++i)
3412 if (channelAuraMask & (1 << i) && m_spellInfo->Effects[i].RadiusEntry)
3413 {
3414 range = m_spellInfo->Effects[i].CalcRadius(nullptr, nullptr);
3415 break;
3416 }
3417
3418 if (Player* modOwner = m_caster->GetSpellModOwner())
3419 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_RANGE, range, this);
3420
3421 // xinef: add little tolerance level
3422 range += std::min(3.0f, range * 0.1f); // 10% but no more than 3yd
3423 }
3424
3425 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
3426 {
3427 if (ihit->missCondition == SPELL_MISS_NONE && (channelTargetEffectMask & ihit->effectMask))
3428 {
3429 Unit* unit = m_caster->GetGUID() == ihit->targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID);
3430
3431 if (!unit)
3432 continue;
3433
3434 if (IsValidDeadOrAliveTarget(unit))
3435 {
3436 if (channelAuraMask & ihit->effectMask)
3437 {
3439 {
3440 if (m_caster != unit)
3441 {
3442 if (!m_caster->IsWithinDistInMap(unit, range))
3443 {
3444 ihit->effectMask &= ~aurApp->GetEffectMask();
3445 unit->RemoveAura(aurApp);
3446 continue;
3447 }
3448 // Xinef: Update Orientation server side (non players wont sent appropriate packets)
3451 }
3452 }
3453 else // aura is dispelled
3454 continue;
3455 }
3456
3457 channelTargetEffectMask &= ~ihit->effectMask; // remove from need alive mask effect that have alive target
3458 }
3459 }
3460 }
3461
3462 // Xinef: not all effects are covered, remove applications from all targets
3463 if (channelTargetEffectMask != 0)
3464 {
3465 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
3466 if (ihit->missCondition == SPELL_MISS_NONE && (channelAuraMask & ihit->effectMask))
3467 if (Unit* unit = m_caster->GetGUID() == ihit->targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID))
3468 if (IsValidDeadOrAliveTarget(unit))
3470 {
3471 ihit->effectMask &= ~aurApp->GetEffectMask();
3472 unit->RemoveAura(aurApp);
3473 }
3474 }
3475
3476 // is all effects from m_needAliveTargetMask have alive targets
3477 return channelTargetEffectMask == 0;
3478}
@ SPELL_ATTR1_TRACK_TARGET_IN_CHANNEL
Definition: SharedDefines.h:433
bool IsWithinDistInMap(WorldObject const *obj, float dist2compare, bool is3D=true, bool useBoundingRadius=true) const
Definition: Object.cpp:1332
AuraApplication * GetAuraApplication(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemCasterGUID=ObjectGuid::Empty, uint8 reqEffMask=0, AuraApplication *except=nullptr) const
Definition: Unit.cpp:5562
void UpdateOrientation(float orientation)
Only server-side orientation update, does not broadcast to client.
Definition: Unit.cpp:20063
bool IsValidDeadOrAliveTarget(Unit const *target) const
Definition: Spell.cpp:8228

References EFFECT_0, EFFECT_2, SpellInfo::Effects, Position::GetAngle(), Unit::GetAuraApplication(), Object::GetGUID(), SpellInfo::GetMaxRange(), Unit::GetSpellModOwner(), ObjectAccessor::GetUnit(), SpellInfo::HasAttribute(), SpellInfo::Id, SpellInfo::IsPositive(), IsValidDeadOrAliveTarget(), WorldObject::IsWithinDistInMap(), m_caster, m_channelTargetEffectMask, m_originalCasterGUID, m_spellInfo, m_UniqueTargetInfo, MAX_SPELL_EFFECTS, Unit::RemoveAura(), SPELL_ATTR1_TRACK_TARGET_IN_CHANNEL, SPELL_EFFECT_APPLY_AURA, SPELL_MISS_NONE, SPELLMOD_RANGE, and Unit::UpdateOrientation().

Referenced by update().

◆ UpdatePointers()

bool Spell::UpdatePointers ( )
7867{
7870 else
7871 {
7874 m_originalCaster = nullptr;
7875 }
7876
7878 {
7880 // cast item not found, somehow the item is no longer where we expected
7881 if (!m_CastItem)
7882 return false;
7883 }
7884 else
7885 m_CastItem = nullptr;
7886
7888
7889 // further actions done only for dest targets
7890 if (!m_targets.HasDst())
7891 return true;
7892
7893 // cache last transport
7894 WorldObject* transport = nullptr;
7895
7896 // update effect destinations (in case of moved transport dest target)
7897 for (uint8 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
7898 {
7899 SpellDestination& dest = m_destTargets[effIndex];
7900 if (!dest._transportGUID)
7901 continue;
7902
7903 if (!transport || transport->GetGUID() != dest._transportGUID)
7905
7906 if (transport)
7907 {
7908 dest._position.Relocate(transport);
7910 }
7911 }
7912
7913 return true;
7914}
WorldObject * GetWorldObject(WorldObject const &, ObjectGuid const guid)
Definition: ObjectAccessor.cpp:115
void RelocateOffset(const Position &offset)
Definition: Position.cpp:59
Position _transportOffset
Definition: Spell.h:107
ObjectGuid _transportGUID
Definition: Spell.h:106
void Update(Unit *caster)
Definition: Spell.cpp:479

References SpellDestination::_position, SpellDestination::_transportGUID, SpellDestination::_transportOffset, Object::GetGUID(), Player::GetItemByGuid(), ObjectAccessor::GetUnit(), ObjectAccessor::GetWorldObject(), SpellCastTargets::HasDst(), Object::IsInWorld(), Object::IsPlayer(), m_caster, m_CastItem, m_castItemGUID, m_destTargets, m_originalCaster, m_originalCasterGUID, m_targets, MAX_SPELL_EFFECTS, Position::Relocate(), Position::RelocateOffset(), Object::ToPlayer(), and SpellCastTargets::Update().

Referenced by _cast(), handle_delayed(), and update().

◆ WriteAmmoToPacket()

void Spell::WriteAmmoToPacket ( WorldPacket data)
4934{
4935 uint32 ammoInventoryType = 0;
4936 uint32 ammoDisplayID = 0;
4937
4938 if (m_caster->IsPlayer())
4939 {
4941 if (pItem)
4942 {
4943 ammoInventoryType = pItem->GetTemplate()->InventoryType;
4944 if (ammoInventoryType == INVTYPE_THROWN)
4945 ammoDisplayID = pItem->GetTemplate()->DisplayInfoID;
4946 else
4947 {
4949 if (ammoID)
4950 {
4951 ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(ammoID);
4952 if (pProto)
4953 {
4954 ammoDisplayID = pProto->DisplayInfoID;
4955 ammoInventoryType = pProto->InventoryType;
4956 }
4957 }
4958 else if (m_caster->HasAura(46699)) // Requires No Ammo
4959 {
4960 ammoDisplayID = 5996; // normal arrow
4961 ammoInventoryType = INVTYPE_AMMO;
4962 }
4963 }
4964 }
4965 }
4966 else
4967 {
4968 uint32 nonRangedAmmoDisplayID = 0;
4969 uint32 nonRangedAmmoInventoryType = 0;
4970 for (uint8 i = 0; i < 3; ++i)
4971 {
4973 {
4974 if (ItemEntry const* itemEntry = sItemStore.LookupEntry(item_id))
4975 {
4976 if (itemEntry->ClassID == ITEM_CLASS_WEAPON)
4977 {
4978 switch (itemEntry->SubclassID)
4979 {
4981 ammoDisplayID = itemEntry->DisplayInfoID;
4982 ammoInventoryType = itemEntry->InventoryType;
4983 break;
4986 ammoDisplayID = 5996; // is this need fixing?
4987 ammoInventoryType = INVTYPE_AMMO;
4988 break;
4990 ammoDisplayID = 5998; // is this need fixing?
4991 ammoInventoryType = INVTYPE_AMMO;
4992 break;
4993 default:
4994 nonRangedAmmoDisplayID = itemEntry->DisplayInfoID;
4995 nonRangedAmmoInventoryType = itemEntry->InventoryType;
4996 break;
4997 }
4998
4999 if (ammoDisplayID)
5000 break;
5001 }
5002 }
5003 }
5004 }
5005
5006 if (!ammoDisplayID && !ammoInventoryType)
5007 {
5008 ammoDisplayID = nonRangedAmmoDisplayID;
5009 ammoInventoryType = nonRangedAmmoInventoryType;
5010 }
5011 }
5012
5013 *data << uint32(ammoDisplayID);
5014 *data << uint32(ammoInventoryType);
5015}
@ INVTYPE_AMMO
Definition: ItemTemplate.h:280
@ UNIT_VIRTUAL_ITEM_SLOT_ID
Definition: UpdateFields.h:116
DBCStorage< ItemEntry > sItemStore(Itemfmt)
uint32 DisplayInfoID
Definition: ItemTemplate.h:625
Definition: DBCStructure.h:1139

References ItemTemplate::DisplayInfoID, Item::GetTemplate(), Object::GetUInt32Value(), Player::GetWeaponForAttack(), Unit::HasAura(), ItemTemplate::InventoryType, INVTYPE_AMMO, INVTYPE_THROWN, Object::IsPlayer(), ITEM_CLASS_WEAPON, ITEM_SUBCLASS_WEAPON_BOW, ITEM_SUBCLASS_WEAPON_CROSSBOW, ITEM_SUBCLASS_WEAPON_GUN, ITEM_SUBCLASS_WEAPON_THROWN, m_caster, PLAYER_AMMO_ID, RANGED_ATTACK, sItemStore, sObjectMgr, Object::ToPlayer(), and UNIT_VIRTUAL_ITEM_SLOT_ID.

Referenced by SendSpellGo(), and SendSpellStart().

◆ WriteCastResultInfo()

void Spell::WriteCastResultInfo ( WorldPacket data,
Player caster,
SpellInfo const *  spellInfo,
uint8  castCount,
SpellCastResult  result,
SpellCustomErrors  customError 
)
static
4570{
4571 data << uint8(castCount); // single cast or multi 2.3 (0/1)
4572 data << uint32(spellInfo->Id);
4573 data << uint8(result); // problem
4574 switch (result)
4575 {
4577 data << uint32(spellInfo->RequiresSpellFocus); // SpellFocusObject.dbc id
4578 break;
4579 case SPELL_FAILED_REQUIRES_AREA: // AreaTable.dbc id
4580 // hardcode areas limitation case
4581 switch (spellInfo->Id)
4582 {
4583 case 41617: // Cenarion Mana Salve
4584 case 41619: // Cenarion Healing Salve
4585 data << uint32(3905);
4586 break;
4587 case 41618: // Bottled Nethergon Energy
4588 case 41620: // Bottled Nethergon Vapor
4589 data << uint32(3842);
4590 break;
4591 case 45373: // Bloodberry Elixir
4592 data << uint32(4075);
4593 break;
4594 default: // default case (don't must be)
4595 data << uint32(0);
4596 break;
4597 }
4598 break;
4600 if (spellInfo->Totem[0])
4601 data << uint32(spellInfo->Totem[0]);
4602 if (spellInfo->Totem[1])
4603 data << uint32(spellInfo->Totem[1]);
4604 break;
4606 if (spellInfo->TotemCategory[0])
4607 data << uint32(spellInfo->TotemCategory[0]);
4608 if (spellInfo->TotemCategory[1])
4609 data << uint32(spellInfo->TotemCategory[1]);
4610 break;
4614 data << uint32(spellInfo->EquippedItemClass);
4615 data << uint32(spellInfo->EquippedItemSubClassMask);
4616 break;
4618 {
4619 uint32 item = 0;
4620 for (int8 eff = 0; eff < MAX_SPELL_EFFECTS; eff++)
4621 if (spellInfo->Effects[eff].ItemType)
4622 item = spellInfo->Effects[eff].ItemType;
4623 ItemTemplate const* proto = sObjectMgr->GetItemTemplate(item);
4624 if (proto && proto->ItemLimitCategory)
4625 data << uint32(proto->ItemLimitCategory);
4626 break;
4627 }
4629 data << uint32(customError);
4630 break;
4632 {
4633 uint32 missingItem = 0;
4634 for (uint32 i = 0; i < MAX_SPELL_REAGENTS; i++)
4635 {
4636 if (spellInfo->Reagent[i] <= 0)
4637 continue;
4638
4639 uint32 itemid = spellInfo->Reagent[i];
4640 uint32 itemcount = spellInfo->ReagentCount[i];
4641
4642 if (!caster->HasItemCount(itemid, itemcount))
4643 {
4644 missingItem = itemid;
4645 break;
4646 }
4647 }
4648
4649 data << uint32(missingItem); // first missing item
4650 break;
4651 }
4653 data << uint32(spellInfo->Mechanic);
4654 break;
4656 data << uint32(spellInfo->EquippedItemSubClassMask);
4657 break;
4659 data << uint32(0); // Item entry
4660 data << uint32(0); // Count
4661 break;
4663 data << uint32(0); // SkillLine.dbc Id
4664 data << uint32(0); // Amount
4665 break;
4667 data << uint32(0); // Skill level
4668 break;
4669 default:
4670 break;
4671 }
4672}
@ SPELL_FAILED_NEED_EXOTIC_AMMO
Definition: SharedDefines.h:1003
@ SPELL_FAILED_FISHING_TOO_LOW
Definition: SharedDefines.h:1130
@ SPELL_FAILED_MIN_SKILL
Definition: SharedDefines.h:1099
@ SPELL_FAILED_PREVENTED_BY_MECHANIC
Definition: SharedDefines.h:1096
@ SPELL_FAILED_REQUIRES_AREA
Definition: SharedDefines.h:1050

References SpellInfo::Effects, SpellInfo::EquippedItemClass, SpellInfo::EquippedItemSubClassMask, Player::HasItemCount(), SpellInfo::Id, ItemTemplate::ItemLimitCategory, MAX_SPELL_EFFECTS, MAX_SPELL_REAGENTS, SpellInfo::Mechanic, SpellInfo::Reagent, SpellInfo::ReagentCount, SpellInfo::RequiresSpellFocus, sObjectMgr, SPELL_FAILED_CUSTOM_ERROR, SPELL_FAILED_EQUIPPED_ITEM_CLASS, SPELL_FAILED_EQUIPPED_ITEM_CLASS_MAINHAND, SPELL_FAILED_EQUIPPED_ITEM_CLASS_OFFHAND, SPELL_FAILED_FISHING_TOO_LOW, SPELL_FAILED_MIN_SKILL, SPELL_FAILED_NEED_EXOTIC_AMMO, SPELL_FAILED_NEED_MORE_ITEMS, SPELL_FAILED_PREVENTED_BY_MECHANIC, SPELL_FAILED_REAGENTS, SPELL_FAILED_REQUIRES_AREA, SPELL_FAILED_REQUIRES_SPELL_FOCUS, SPELL_FAILED_TOO_MANY_OF_ITEM, SPELL_FAILED_TOTEM_CATEGORY, SPELL_FAILED_TOTEMS, SpellInfo::Totem, and SpellInfo::TotemCategory.

Referenced by SendCastResult(), and SendPetCastResult().

◆ WriteSpellGoTargets()

void Spell::WriteSpellGoTargets ( WorldPacket data)

Writes miss and hit targets for a SMSG_SPELL_GO packet.

5019{
5020 // This function also fill data for channeled spells:
5021 // m_needAliveTargetMask req for stop channelig if one target die
5022 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
5023 {
5024 if ((*ihit).effectMask == 0) // No effect apply - all immuned add state
5025 // possibly SPELL_MISS_IMMUNE2 for this??
5026 ihit->missCondition = SPELL_MISS_IMMUNE2;
5027 }
5028
5029 // Hit and miss target counts are both uint8, that limits us to 255 targets for each
5030 // sending more than 255 targets crashes the client (since count sent would be wrong)
5031 // Spells like 40647 (with a huge radius) can easily reach this limit (spell might need
5032 // target conditions but we still need to limit the number of targets sent and keeping
5033 // correct count for both hit and miss).
5034
5035 uint32 hit = 0;
5036 std::size_t hitPos = data->wpos();
5037 *data << (uint8)0; // placeholder
5038 for (std::list<TargetInfo>::const_iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end() && hit < 255; ++ihit)
5039 {
5040 if ((*ihit).missCondition == SPELL_MISS_NONE) // Add only hits
5041 {
5042 *data << ihit->targetGUID;
5043 // Xinef: No channeled spell checked, no anything
5044 //m_channelTargetEffectMask |=ihit->effectMask;
5045 ++hit;
5046 }
5047 }
5048
5049 for (std::list<GOTargetInfo>::const_iterator ighit = m_UniqueGOTargetInfo.begin(); ighit != m_UniqueGOTargetInfo.end() && hit < 255; ++ighit)
5050 {
5051 *data << ighit->targetGUID; // Always hits
5052 ++hit;
5053 }
5054
5055 uint32 miss = 0;
5056 std::size_t missPos = data->wpos();
5057 *data << (uint8)0; // placeholder
5058 for (std::list<TargetInfo>::const_iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end() && miss < 255; ++ihit)
5059 {
5060 if (ihit->missCondition != SPELL_MISS_NONE) // Add only miss
5061 {
5062 *data << ihit->targetGUID;
5063 *data << uint8(ihit->missCondition);
5064 if (ihit->missCondition == SPELL_MISS_REFLECT)
5065 *data << uint8(ihit->reflectResult);
5066 ++miss;
5067 }
5068 }
5069 // Reset m_needAliveTargetMask for non channeled spell
5070 // Xinef: Why do we reset something that is not set??????
5071 //if (!m_spellInfo->IsChanneled())
5072 // m_channelTargetEffectMask = 0;
5073
5074 data->put<uint8>(hitPos, (uint8)hit);
5075 data->put<uint8>(missPos, (uint8)miss);
5076}
std::size_t wpos() const
Definition: ByteBuffer.h:330
void put(std::size_t pos, T value)
Definition: ByteBuffer.h:137

References m_UniqueGOTargetInfo, m_UniqueTargetInfo, ByteBuffer::put(), SPELL_MISS_IMMUNE2, SPELL_MISS_NONE, SPELL_MISS_REFLECT, and ByteBuffer::wpos().

Referenced by SendSpellGo().

Friends And Related Function Documentation

◆ SpellScript

friend class SpellScript
friend

◆ Unit::SetCurrentCastedSpell

void Unit::SetCurrentCastedSpell ( Spell pSpell)
friend

Member Data Documentation

◆ _scriptsLoaded

bool Spell::_scriptsLoaded
protected

Referenced by LoadScripts(), and Spell().

◆ _spellEvent

SpellEvent* Spell::_spellEvent
protected

◆ _spellTargetsSelected

bool Spell::_spellTargetsSelected
protected

Referenced by _cast(), prepare(), and Spell().

◆ _triggeredCastFlags

TriggerCastFlags Spell::_triggeredCastFlags
protected

◆ damage

◆ destTarget

◆ effectHandleMode

SpellEffectHandleMode Spell::effectHandleMode
protected

Referenced by EffectActivateObject(), EffectActivateRune(), EffectActivateSpec(), EffectAddComboPoints(), EffectAddExtraAttacks(), EffectAddFarsight(), EffectAddHonor(), EffectApplyAreaAura(), EffectApplyAura(), EffectApplyGlyph(), EffectBind(), EffectBlock(), EffectCastButtons(), EffectCharge(), EffectChargeDest(), EffectCreateItem(), EffectCreateItem2(), EffectCreateRandomItem(), EffectCreateTamedPet(), EffectDestroyAllTotems(), EffectDiscoverTaxi(), EffectDisEnchant(), EffectDismissPet(), EffectDispel(), EffectDispelMechanic(), EffectDistract(), EffectDualWield(), EffectDuel(), EffectDummy(), EffectDurabilityDamage(), EffectDurabilityDamagePCT(), EffectEnchantHeldItem(), EffectEnchantItemPerm(), EffectEnchantItemPrismatic(), EffectEnchantItemTmp(), EffectEnergize(), EffectEnergizePct(), EffectEnvironmentalDMG(), EffectFeedPet(), EffectForceCast(), EffectForceDeselect(), EffectGameObjectDamage(), EffectGameObjectRepair(), EffectGameObjectSetDestructionState(), EffectHeal(), EffectHealMaxHealth(), EffectHealMechanical(), EffectHealPct(), EffectHealthLeech(), EffectInebriate(), EffectInstaKill(), EffectInterruptCast(), EffectJump(), EffectJumpDest(), EffectKillCredit(), EffectKillCreditPersonal(), EffectKnockBack(), EffectLeap(), EffectLeapBack(), EffectLearnPetSpell(), EffectLearnSkill(), EffectLearnSpell(), EffectMilling(), EffectModifyThreatPercent(), EffectOpenLock(), EffectParry(), EffectPersistentAA(), EffectPickPocket(), EffectPlayMusic(), EffectPlaySound(), EffectPowerBurn(), EffectPowerDrain(), EffectProficiency(), EffectProspecting(), EffectPullTowards(), EffectQuestClear(), EffectQuestComplete(), EffectQuestFail(), EffectQuestStart(), EffectRechargeManaGem(), EffectRedirectThreat(), EffectRemoveAura(), EffectRenamePet(), EffectReputation(), EffectResurrect(), EffectResurrectNew(), EffectResurrectPet(), EffectSanctuary(), EffectSchoolDMG(), EffectScriptEffect(), EffectSelfResurrect(), EffectSendEvent(), EffectSendTaxi(), EffectSkill(), EffectSkinning(), EffectSkinPlayerCorpse(), EffectSpecCount(), EffectSpiritHeal(), EffectStealBeneficialBuff(), EffectStuck(), EffectSummonChangeItem(), EffectSummonObject(), EffectSummonObjectWild(), EffectSummonPet(), EffectSummonPlayer(), EffectSummonRaFFriend(), EffectSummonType(), EffectTameCreature(), EffectTaunt(), EffectTeleportUnits(), EffectTeleUnitsFaceCaster(), EffectThreat(), EffectTitanGrip(), EffectTradeSkill(), EffectTransmitted(), EffectTriggerMissileSpell(), EffectTriggerRitualOfSummoning(), EffectTriggerSpell(), EffectUnlearnSpecialization(), EffectUntrainTalents(), EffectWeaponDmg(), HandleEffects(), and Spell().

◆ focusObject

◆ gameObjTarget

◆ itemTarget

◆ m_appliedMods

◆ m_applyMultiplierMask

uint8 Spell::m_applyMultiplierMask
protected

◆ m_attackType

◆ m_auraScaleMask

uint8 Spell::m_auraScaleMask
protected

◆ m_autoRepeat

bool Spell::m_autoRepeat
protected

◆ m_canReflect

bool Spell::m_canReflect
protected

Referenced by AddUnitTarget(), and Spell().

◆ m_cast_count

◆ m_caster

Unit* const Spell::m_caster
protected

Referenced by _cast(), _handle_finish_phase(), AddGOTarget(), AddUnitTarget(), CalculateDelayMomentForDst(), CalculateJumpSpeeds(), CalculateSpellDamage(), cancel(), CancelGlobalCooldown(), CanOpenLock(), cast(), CheckCast(), CheckCasterAuras(), CheckDst(), CheckEffectTarget(), CheckItems(), CheckPetCast(), CheckPower(), CheckRange(), CheckRuneCost(), CheckSpellFocus(), CheckSrc(), Delayed(), DelayedChannel(), DoAllEffectOnLaunchTarget(), DoAllEffectOnTarget(), DoSpellHitOnUnit(), DoTriggersOnSpellHit(), EffectActivateObject(), EffectActivateRune(), EffectAddFarsight(), EffectApplyGlyph(), EffectBind(), EffectBlock(), EffectCastButtons(), EffectCharge(), EffectChargeDest(), EffectDestroyAllTotems(), EffectDisEnchant(), EffectDispel(), EffectDispelMechanic(), EffectDuel(), EffectDummy(), EffectEnchantHeldItem(), EffectEnchantItemPerm(), EffectEnchantItemPrismatic(), EffectEnchantItemTmp(), EffectEnergize(), EffectEnergizePct(), EffectEnvironmentalDMG(), EffectFeedPet(), EffectForceCast(), EffectForceDeselect(), EffectGameObjectRepair(), EffectHeal(), EffectHealMaxHealth(), EffectHealthLeech(), EffectInstaKill(), EffectJump(), EffectJumpDest(), EffectKnockBack(), EffectLeap(), EffectLeapBack(), EffectLearnSpell(), EffectMilling(), EffectModifyThreatPercent(), EffectOpenLock(), EffectParry(), EffectPersistentAA(), EffectPickPocket(), EffectPowerBurn(), EffectPowerDrain(), EffectProficiency(), EffectProspecting(), EffectPullTowards(), EffectRechargeManaGem(), EffectRedirectThreat(), EffectResurrect(), EffectResurrectNew(), EffectResurrectPet(), EffectSchoolDMG(), EffectScriptEffect(), EffectSelfResurrect(), EffectSendEvent(), EffectSkinning(), EffectSkinPlayerCorpse(), EffectStealBeneficialBuff(), EffectStuck(), EffectSummonChangeItem(), EffectSummonObject(), EffectSummonObjectWild(), EffectSummonPet(), EffectSummonPlayer(), EffectSummonRaFFriend(), EffectSummonType(), EffectTameCreature(), EffectTaunt(), EffectTeleportUnits(), EffectTeleUnitsFaceCaster(), EffectThreat(), EffectTitanGrip(), EffectTradeSkill(), EffectTransmitted(), EffectTriggerMissileSpell(), EffectTriggerRitualOfSummoning(), EffectTriggerSpell(), EffectUnlearnSpecialization(), EffectUntrainTalents(), EffectWeaponDmg(), finish(), GetCaster(), handle_delayed(), handle_immediate(), HandleLaunchPhase(), HandleThreatSpells(), HasGlobalCooldown(), InitExplicitTargets(), IsChannelActive(), OnSpellLaunch(), prepare(), prepareDataForTriggerSystem(), PrepareTriggersExecutedOnHit(), RecalculateDelayMomentForDst(), SearchAreaTargets(), SearchChainTargets(), SearchNearbyTarget(), SelectEffectImplicitTargets(), SelectEffectTypeImplicitTargets(), SelectExplicitTargets(), SelectImplicitAreaTargets(), SelectImplicitCasterDestTargets(), SelectImplicitCasterObjectTargets(), SelectImplicitChainTargets(), SelectImplicitChannelTargets(), SelectImplicitConeTargets(), SelectImplicitDestDestTargets(), SelectImplicitNearbyTargets(), SelectImplicitTrajTargets(), SendCastResult(), SendChannelStart(), SendChannelUpdate(), SendInterrupted(), SendLogExecute(), SendLoot(), SendPetCastResult(), SendResurrectRequest(), SendSpellCooldown(), SendSpellGo(), SendSpellStart(), Spell(), SummonGuardian(), TakeAmmo(), TakeCastItem(), TakePower(), TakeReagents(), TakeRunePower(), TriggerGlobalCooldown(), update(), UpdateChanneledTargetList(), UpdatePointers(), and WriteAmmoToPacket().

◆ m_CastItem

◆ m_castItemGUID

◆ m_casttime

◆ m_channeledDuration

int32 Spell::m_channeledDuration
protected

◆ m_channelTargetEffectMask

uint8 Spell::m_channelTargetEffectMask
protected

◆ m_comboPointGain

int8 Spell::m_comboPointGain

◆ m_comboTarget

Unit* Spell::m_comboTarget

◆ m_customError

◆ m_damage

◆ m_damageMultipliers

float Spell::m_damageMultipliers[3]
protected

◆ m_delayAtDamageCount

uint8 Spell::m_delayAtDamageCount
protected

Referenced by isDelayableNoMore(), and Spell().

◆ m_delayMoment

◆ m_delayStart

uint64 Spell::m_delayStart
protected

Referenced by GetDelayStart(), SetDelayStart(), and Spell().

◆ m_delayTrajectory

uint64 Spell::m_delayTrajectory
protected

◆ m_destTargets

SpellDestination Spell::m_destTargets[MAX_SPELL_EFFECTS]
protected

◆ m_diminishGroup

DiminishingGroup Spell::m_diminishGroup
protected

◆ m_diminishLevel

DiminishingLevels Spell::m_diminishLevel
protected

◆ m_effectExecuteData

◆ m_executedCurrently

bool Spell::m_executedCurrently
protected

◆ m_glyphIndex

uint32 Spell::m_glyphIndex

◆ m_healing

◆ m_hitTriggerSpells

HitTriggerSpellList Spell::m_hitTriggerSpells
protected

◆ m_immediateHandled

bool Spell::m_immediateHandled
protected

Referenced by _cast(), handle_delayed(), and Spell().

◆ m_loadedScripts

◆ m_needComboPoints

bool Spell::m_needComboPoints
protected

◆ m_originalCaster

◆ m_originalCasterGUID

◆ m_powerCost

◆ m_preCastSpell

uint32 Spell::m_preCastSpell

◆ m_preGeneratedPath

std::unique_ptr<PathGenerator> Spell::m_preGeneratedPath
protected

Referenced by CheckCast(), and EffectCharge().

◆ m_procAttacker

uint32 Spell::m_procAttacker
protected

◆ m_procEx

uint32 Spell::m_procEx
protected

◆ m_procVictim

uint32 Spell::m_procVictim
protected

◆ m_referencedFromCurrentSpell

bool Spell::m_referencedFromCurrentSpell
protected

◆ m_runesState

uint8 Spell::m_runesState
protected

◆ m_selfContainer

Spell** Spell::m_selfContainer
protected

◆ m_skipCheck

bool Spell::m_skipCheck
protected

Referenced by AddUnitTarget(), and Spell().

◆ m_spellAura

◆ m_spellFlags

◆ m_spellInfo

SpellInfo const* const Spell::m_spellInfo

Referenced by _cast(), _handle_finish_phase(), _handle_immediate_phase(), Unit::_UpdateAutoRepeatSpell(), AddGOTarget(), AddItemTarget(), AddUnitTarget(), CalculateDelayMomentForDst(), CalculateJumpSpeeds(), CalculateSpellDamage(), CallScriptDestinationTargetSelectHandlers(), CallScriptEffectHandlers(), CallScriptObjectAreaTargetSelectHandlers(), CallScriptObjectTargetSelectHandlers(), CanAutoCast(), cancel(), CancelGlobalCooldown(), CanExecuteTriggersOnHit(), CanOpenLock(), CheckCast(), CheckCasterAuras(), CheckEffectTarget(), CheckItems(), CheckPetCast(), CheckPower(), CheckRange(), CheckRuneCost(), CheckScriptEffectImplicitTargets(), CheckSpellFocus(), Delayed(), DelayedChannel(), DoAllEffectOnLaunchTarget(), DoAllEffectOnTarget(), DoCreateItem(), DoSpellHitOnUnit(), DoTriggersOnSpellHit(), EffectActivateObject(), EffectActivateRune(), EffectAddFarsight(), EffectAddHonor(), EffectApplyGlyph(), EffectBind(), EffectCastButtons(), EffectCharge(), EffectCreateItem(), EffectCreateItem2(), EffectCreateRandomItem(), EffectCreateTamedPet(), EffectDiscoverTaxi(), EffectDisEnchant(), EffectDispel(), EffectDispelMechanic(), EffectDuel(), EffectDummy(), EffectDurabilityDamage(), EffectDurabilityDamagePCT(), EffectEnchantHeldItem(), EffectEnchantItemPerm(), EffectEnchantItemPrismatic(), EffectEnchantItemTmp(), EffectEnergize(), EffectEnergizePct(), EffectEnvironmentalDMG(), EffectFeedPet(), EffectForceCast(), EffectForceDeselect(), EffectGameObjectSetDestructionState(), EffectHeal(), EffectHealMechanical(), EffectHealPct(), EffectHealthLeech(), EffectInstaKill(), EffectInterruptCast(), EffectJumpDest(), EffectKillCredit(), EffectKillCreditPersonal(), EffectKnockBack(), EffectLeapBack(), EffectLearnPetSpell(), EffectLearnSkill(), EffectLearnSpell(), EffectOpenLock(), EffectPersistentAA(), EffectPlayMusic(), EffectPlaySound(), EffectPowerBurn(), EffectPowerDrain(), EffectProficiency(), EffectPullTowards(), EffectQuestClear(), EffectQuestComplete(), EffectQuestFail(), EffectQuestStart(), EffectRechargeManaGem(), EffectRemoveAura(), EffectReputation(), EffectResurrectNew(), EffectSanctuary(), EffectSchoolDMG(), EffectScriptEffect(), EffectSelfResurrect(), EffectSendEvent(), EffectSendTaxi(), EffectStealBeneficialBuff(), EffectSummonChangeItem(), EffectSummonObject(), EffectSummonObjectWild(), EffectSummonPet(), EffectSummonType(), EffectTameCreature(), EffectTaunt(), EffectTeleportUnits(), EffectTransmitted(), EffectTriggerMissileSpell(), EffectTriggerRitualOfSummoning(), EffectTriggerSpell(), EffectUnlearnSpecialization(), EffectWeaponDmg(), finish(), GetCurrentContainer(), GetSearcherTypeMask(), GetSpellInfo(), handle_immediate(), WorldSession::HandleCastSpellOpcode(), HandleEffects(), HandleLaunchPhase(), WorldSession::HandlePetCastSpellOpcode(), HandleThreatSpells(), WorldSession::HandleUpdateMissileTrajectory(), HasGlobalCooldown(), InitExplicitTargets(), IsAutoActionResetSpell(), IsNeedSendToClient(), IsNextMeleeSwingSpell(), IsValidDeadOrAliveTarget(), LoadScripts(), OnSpellLaunch(), prepare(), prepareDataForTriggerSystem(), PrepareTriggersExecutedOnHit(), Player::RemoveSpellMods(), Player::RestoreSpellMods(), SearchAreaTargets(), SearchChainTargets(), SearchNearbyTarget(), SelectEffectImplicitTargets(), SelectEffectTypeImplicitTargets(), SelectExplicitTargets(), SelectImplicitAreaTargets(), SelectImplicitCasterDestTargets(), SelectImplicitChainTargets(), SelectImplicitChannelTargets(), SelectImplicitConeTargets(), SelectImplicitDestDestTargets(), SelectImplicitNearbyTargets(), SelectImplicitTargetDestTargets(), SelectImplicitTrajTargets(), SelectSpellTargets(), SendCastResult(), SendChannelStart(), SendInterrupted(), SendLogExecute(), SendPetCastResult(), SendResurrectRequest(), SendSpellCooldown(), SendSpellGo(), SendSpellStart(), Unit::SetCurrentCastedSpell(), Player::SetSpellModTakingSpell(), SetSpellValue(), Spell(), SummonGuardian(), TakePower(), TakeReagents(), TakeRunePower(), TriggerGlobalCooldown(), update(), PetAI::UpdateAI(), UpdateChanneledTargetList(), Player::UpdatePotionCooldown(), ~Spell(), and SpellEvent::~SpellEvent().

◆ m_spellSchoolMask

◆ m_spellState

uint32 Spell::m_spellState
protected

◆ m_spellValue

◆ m_targets

SpellCastTargets Spell::m_targets

Referenced by _cast(), CalculateDelayMomentForDst(), CheckCast(), CheckDst(), CheckEffectTarget(), CheckItems(), CheckPetCast(), CheckRange(), CheckSrc(), Unit::DealDamage(), DoAllEffectOnTarget(), DoSpellHitOnUnit(), EffectBind(), EffectChargeDest(), EffectEnchantItemPerm(), EffectJumpDest(), EffectKnockBack(), EffectLeap(), EffectPullTowards(), EffectSummonChangeItem(), EffectSummonObject(), EffectSummonObjectWild(), EffectTeleportUnits(), EffectTeleUnitsFaceCaster(), EffectTransmitted(), EffectTriggerMissileSpell(), EffectTriggerSpell(), SpellScript::GetExplTargetDest(), SpellScript::GetExplTargetGObj(), SpellScript::GetExplTargetItem(), SpellScript::GetExplTargetUnit(), SpellScript::GetExplTargetWorldObject(), handle_delayed(), WorldSession::HandleAcceptTradeOpcode(), WorldSession::HandlePetActionHelper(), WorldSession::HandlePetCastSpellOpcode(), spell_vehicle_throw_passenger::HandleScript(), WorldSession::HandleUpdateMissileTrajectory(), WorldSession::HandleUpdateProjectilePosition(), InitExplicitTargets(), spell_ioc_launch::Launch(), OnSpellLaunch(), prepare(), SelectEffectImplicitTargets(), SelectEffectTypeImplicitTargets(), SelectExplicitTargets(), SelectImplicitAreaTargets(), SelectImplicitCasterDestTargets(), SelectImplicitChannelTargets(), SelectImplicitDestDestTargets(), SelectImplicitNearbyTargets(), SelectImplicitTargetDestTargets(), SelectImplicitTargetObjectTargets(), SelectImplicitTrajTargets(), SelectSpellTargets(), SendChannelStart(), SendSpellGo(), SendSpellStart(), SpellScript::SetExplTargetDest(), TakeCastItem(), TakePower(), TakeReagents(), update(), and UpdatePointers().

◆ m_timer

◆ m_triggeredByAuraSpell

◆ m_UniqueGOTargetInfo

◆ m_UniqueItemInfo

◆ m_UniqueTargetInfo

◆ m_weaponItem

Item* Spell::m_weaponItem

◆ unitTarget

Unit* Spell::unitTarget
protected

Referenced by CheckCast(), DoAllEffectOnTarget(), DoCreateItem(), DoSpellHitOnUnit(), EffectActivateSpec(), EffectAddComboPoints(), EffectAddExtraAttacks(), EffectAddHonor(), EffectApplyAreaAura(), EffectApplyAura(), EffectBind(), EffectCharge(), EffectCreateItem2(), EffectCreateRandomItem(), EffectCreateTamedPet(), EffectDiscoverTaxi(), EffectDismissPet(), EffectDispel(), EffectDispelMechanic(), EffectDistract(), EffectDualWield(), EffectDuel(), EffectDummy(), EffectDurabilityDamage(), EffectDurabilityDamagePCT(), EffectEnchantHeldItem(), EffectEnchantItemPerm(), EffectEnergize(), EffectEnergizePct(), EffectEnvironmentalDMG(), EffectForceCast(), EffectHeal(), EffectHealMaxHealth(), EffectHealMechanical(), EffectHealPct(), EffectHealthLeech(), EffectInebriate(), EffectInstaKill(), EffectInterruptCast(), EffectJump(), EffectKillCredit(), EffectKillCreditPersonal(), EffectKnockBack(), EffectLeap(), EffectLeapBack(), EffectLearnPetSpell(), EffectLearnSkill(), EffectLearnSpell(), EffectModifyThreatPercent(), EffectPickPocket(), EffectPlayMusic(), EffectPlaySound(), EffectPowerBurn(), EffectPowerDrain(), EffectPullTowards(), EffectQuestClear(), EffectQuestComplete(), EffectQuestFail(), EffectQuestStart(), EffectRechargeManaGem(), EffectRedirectThreat(), EffectRemoveAura(), EffectRenamePet(), EffectReputation(), EffectResurrect(), EffectResurrectNew(), EffectSanctuary(), EffectSchoolDMG(), EffectScriptEffect(), EffectSendEvent(), EffectSendTaxi(), EffectSkinning(), EffectSkinPlayerCorpse(), EffectSpecCount(), EffectStealBeneficialBuff(), EffectSummonPlayer(), EffectSummonRaFFriend(), EffectTameCreature(), EffectTaunt(), EffectTeleportUnits(), EffectTeleUnitsFaceCaster(), EffectThreat(), EffectTitanGrip(), EffectTriggerMissileSpell(), EffectTriggerSpell(), EffectUnlearnSpecialization(), EffectUntrainTalents(), EffectWeaponDmg(), SpellScript::GetHitCreature(), SpellScript::GetHitPlayer(), SpellScript::GetHitUnit(), HandleEffects(), SelectEffectTypeImplicitTargets(), SelectImplicitAreaTargets(), SelectImplicitChainTargets(), SelectImplicitTrajTargets(), and Spell().