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.
 
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}
#define MAX_SPELL_EFFECTS
Definition DBCStructure.h:1638
std::uint8_t uint8
Definition Define.h:109
std::uint32_t uint32
Definition Define.h:107
@ DIMINISHING_NONE
Definition SharedDefines.h:3508
@ SPELL_EFFECT_DISPEL
Definition SharedDefines.h:827
#define CLASSMASK_WAND_USERS
Definition SharedDefines.h:174
@ SPELL_ATTR2_AUTO_REPEAT
Definition SharedDefines.h:472
@ SPELL_ATTR1_NO_REFLECTION
Definition SharedDefines.h:437
@ SPELL_ATTR3_REQUIRES_OFF_HAND_WEAPON
Definition SharedDefines.h:528
@ SPELL_DAMAGE_CLASS_RANGED
Definition SharedDefines.h:1559
@ SPELL_DAMAGE_CLASS_MAGIC
Definition SharedDefines.h:1557
@ SPELL_DAMAGE_CLASS_MELEE
Definition SharedDefines.h:1558
@ SPELL_CUSTOM_ERROR_NONE
Definition SharedDefines.h:1154
@ SPELL_ATTR0_IS_ABILITY
Definition SharedDefines.h:397
@ SPELL_ATTR0_NO_IMMUNITIES
Definition SharedDefines.h:422
@ SPELL_ATTR4_ALLOW_CAST_WHILE_CASTING
Definition SharedDefines.h:548
@ SPELL_ATTR6_ORIGINATE_FROM_CONTROLLER
Definition SharedDefines.h:633
SpellSchoolMask
Definition SharedDefines.h:306
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
@ SPELL_EFFECT_HANDLE_LAUNCH
Definition Spell.h:244
@ SPELL_FLAG_NORMAL
Definition Spell.h:84
@ SPELL_STATE_NULL
Definition Spell.h:234
@ OFF_ATTACK
Definition Unit.h:212
@ BASE_ATTACK
Definition Unit.h:211
@ RANGED_ATTACK
Definition Unit.h:213
@ DIMINISHING_LEVEL_1
Definition Unit.h:265
Definition ByteBuffer.h:70
Definition Item.h:220
bool IsPlayer() const
Definition Object.h:201
Player * ToPlayer()
Definition Object.h:202
bool IsInWorld() const
Definition Object.h:108
static ObjectGuid GetGUID(Object const *o)
Definition Object.h:113
Item * GetWeaponForAttack(WeaponAttackType attackType, bool useable=false) const
Definition PlayerStorage.cpp:489
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
Unit * m_comboTarget
Definition Spell.h:553
int8 m_comboPointGain
Definition Spell.h:554
GameObject * gameObjTarget
Definition Spell.h:665
bool m_referencedFromCurrentSpell
Definition Spell.h:656
bool m_canReflect
Definition Spell.h:632
uint32 m_procVictim
Definition Spell.h:687
Unit * m_originalCaster
Definition Spell.h:620
bool m_needComboPoints
Definition Spell.h:658
uint64 m_delayStart
Definition Spell.h:650
bool _scriptsLoaded
Definition Spell.h:738
TriggerCastFlags _triggeredCastFlags
Definition Spell.h:779
int32 damage
Definition Spell.h:667
SpellEffectHandleMode effectHandleMode
Definition Spell.h:668
int32 m_channeledDuration
Definition Spell.h:631
Aura * m_spellAura
Definition Spell.h:670
SpellDestination m_destTargets[MAX_SPELL_EFFECTS]
Definition Spell.h:713
Unit *const m_caster
Definition Spell.h:614
uint8 m_delayAtDamageCount
Definition Spell.h:639
WeaponAttackType m_attackType
Definition Spell.h:628
bool m_immediateHandled
Definition Spell.h:653
uint32 m_spellState
Definition Spell.h:775
ObjectGuid m_originalCasterGUID
Definition Spell.h:618
void CleanupTargetList()
Definition Spell.cpp:2282
int32 m_timer
Definition Spell.h:776
int32 m_casttime
Definition Spell.h:630
Item * itemTarget
Definition Spell.h:664
uint8 m_cast_count
Definition Spell.h:535
int32 m_damage
Definition Spell.h:680
bool m_executedCurrently
Definition Spell.h:657
DiminishingLevels m_diminishLevel
Definition Spell.h:673
float m_damageMultipliers[3]
Definition Spell.h:660
ByteBuffer * m_effectExecuteData[MAX_SPELL_EFFECTS]
Definition Spell.h:793
uint8 m_auraScaleMask
Definition Spell.h:787
SpellCustomErrors m_customError
Definition Spell.h:539
uint8 m_spellFlags
Definition Spell.h:634
bool m_skipCheck
Definition Spell.h:786
int32 m_healing
Definition Spell.h:681
uint32 m_glyphIndex
Definition Spell.h:536
uint8 m_channelTargetEffectMask
Definition Spell.h:695
Item * m_weaponItem
Definition Spell.h:533
Unit * unitTarget
Definition Spell.h:663
SpellSchoolMask m_spellSchoolMask
Definition Spell.h:627
SpellEvent * _spellEvent
Definition Spell.h:778
bool _spellTargetsSelected
Definition Spell.h:791
uint32 m_preCastSpell
Definition Spell.h:537
WorldLocation * destTarget
Definition Spell.h:666
Spell ** m_selfContainer
Definition Spell.h:622
uint8 m_applyMultiplierMask
Definition Spell.h:659
DiminishingGroup m_diminishGroup
Definition Spell.h:674
uint32 m_procEx
Definition Spell.h:688
Item * m_CastItem
Definition Spell.h:532
SpellValue *const m_spellValue
Definition Spell.h:616
int32 m_powerCost
Definition Spell.h:629
uint32 m_procAttacker
Definition Spell.h:686
GameObject * focusObject
Definition Spell.h:677
SpellInfo const *const m_spellInfo
Definition Spell.h:531
uint8 m_runesState
Definition Spell.h:637
bool m_autoRepeat
Definition Spell.h:636
Unit * GetCharmerOrOwner() const
Definition Unit.h:1253
uint32 getClassMask() const
Definition Unit.h:828
Unit * GetUnit(WorldObject const &, ObjectGuid const &guid)
Definition ObjectAccessor.cpp:199
Definition Spell.h:104
Definition Spell.h:221

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.

Referenced by Creature::HasSpellFocus().

◆ ~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:158
uint32 Id
Definition SpellInfo.h:320
void CheckEffectExecuteData()
Definition Spell.cpp:8454
std::list< SpellScript * > m_loadedScripts
Definition Spell.h:753

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

3727{
3728 // update pointers base at GUIDs to prevent access to non-existed already object
3729 if (!UpdatePointers())
3730 {
3731 // cancel the spell if UpdatePointers() returned false, something wrong happened there
3732 cancel();
3733 return;
3734 }
3735
3736 // cancel at lost explicit target during cast
3738 {
3739 cancel();
3740 return;
3741 }
3742
3743 // Xinef: implement attribute SPELL_ATTR1_DISMISS_PET_FIRST, on spell cast current pet is dismissed and charms are removed
3745 {
3747 if (Pet* pet = m_caster->ToPlayer()->GetPet())
3749
3750 if (Unit* charm = m_caster->GetCharm())
3751 charm->RemoveAurasByType(SPELL_AURA_MOD_CHARM, m_caster->GetGUID());
3752 }
3753
3754 if (Player* playerCaster = m_caster->ToPlayer())
3755 {
3756 // now that we've done the basic check, now run the scripts
3757 // should be done before the spell is actually executed
3758 sScriptMgr->OnPlayerSpellCast(playerCaster, this, skipCheck);
3759
3760 // As of 3.0.2 pets begin attacking their owner's target immediately
3761 // Let any pets know we've attacked something. Check DmgClass for harmful spells only
3762 // This prevents spells such as Hunter's Mark from triggering pet attack
3763 // xinef: take into account SPELL_ATTR3_SUPPRESS_TARGET_PROCS
3765 if (!playerCaster->m_Controlled.empty())
3766 for (Unit::ControlSet::iterator itr = playerCaster->m_Controlled.begin(); itr != playerCaster->m_Controlled.end(); ++itr)
3767 if (Unit* pet = *itr)
3768 if (pet->IsAlive() && pet->IsCreature())
3769 pet->ToCreature()->AI()->OwnerAttacked(m_targets.GetUnitTarget());
3770 }
3771
3773
3777
3779
3780 Player* modOwner = m_caster->GetSpellModOwner();
3781 // skip check if done already (for instant cast spells for example)
3782 if (!skipCheck)
3783 {
3784 SpellCastResult castResult = CheckCast(false);
3785 if (castResult != SPELL_CAST_OK)
3786 {
3787 SendCastResult(castResult);
3788 SendInterrupted(0);
3789
3790 finish(false);
3791 SetExecutedCurrently(false);
3792 return;
3793 }
3794
3795 // additional check after cast bar completes (must not be in CheckCast)
3796 // if trade not complete then remember it in trade data
3798 {
3799 if (m_caster->IsPlayer())
3800 {
3801 if (TradeData* my_trade = m_caster->ToPlayer()->GetTradeData())
3802 {
3803 if (!my_trade->IsInAcceptProcess())
3804 {
3805 // Spell will be casted at completing the trade. Silently ignore at this place
3806 my_trade->SetSpell(m_spellInfo->Id, m_CastItem);
3808 SendInterrupted(0);
3809
3810 finish(false);
3811 SetExecutedCurrently(false);
3812 return;
3813 }
3814 }
3815 }
3816 }
3817 }
3818
3819 if (modOwner)
3820 modOwner->SetSpellModTakingSpell(this, true);
3821
3824
3825 if (modOwner)
3826 modOwner->SetSpellModTakingSpell(this, false);
3827
3828 // Spell may be finished after target map check
3830 {
3831 SendInterrupted(0);
3832 finish(false);
3833 SetExecutedCurrently(false);
3834 return;
3835 }
3836
3837 if (modOwner)
3838 modOwner->SetSpellModTakingSpell(this, true);
3839
3841
3843
3844 if (modOwner)
3845 modOwner->SetSpellModTakingSpell(this, false);
3846
3847 // traded items have trade slot instead of guid in m_itemTargetGUID
3848 // set to real guid to be sent later to the client
3850
3851 if (m_caster->IsPlayer())
3852 {
3854 {
3857 }
3858
3860 }
3861
3863 {
3864 // Powers have to be taken before SendSpellGo
3865 TakePower();
3866 TakeReagents(); // we must remove reagents before HandleEffects to allow place crafted item in same slot
3867 }
3868 else if (Item* targetItem = m_targets.GetItemTarget())
3869 {
3871 if (targetItem->GetOwnerGUID() != m_caster->GetGUID())
3872 TakeReagents();
3873 }
3874
3876
3877 // CAST SPELL
3878 if (modOwner)
3879 modOwner->SetSpellModTakingSpell(this, true);
3880
3882
3884
3885 // we must send smsg_spell_go packet before m_castItem delete in TakeCastItem()...
3886 SendSpellGo();
3887
3888 if (modOwner)
3889 modOwner->SetSpellModTakingSpell(this, false);
3890
3891 if (m_originalCaster)
3892 {
3893 // Handle procs on cast
3894 uint32 procAttacker = m_procAttacker;
3895 if (!procAttacker)
3896 {
3897 bool IsPositive = m_spellInfo->IsPositive();
3899 {
3901 }
3902 else
3903 {
3905 }
3906 }
3907
3908 uint32 procEx = PROC_EX_NORMAL_HIT;
3909
3910 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
3911 {
3912 if (ihit->missCondition != SPELL_MISS_NONE)
3913 {
3914 continue;
3915 }
3916
3917 if (!ihit->crit)
3918 {
3919 continue;
3920 }
3921
3922 procEx |= PROC_EX_CRITICAL_HIT;
3923 break;
3924 }
3925
3928 }
3929
3930 if (modOwner)
3931 modOwner->SetSpellModTakingSpell(this, true);
3932
3934 if (resetAttackTimers)
3935 {
3937 for (Unit::AuraEffectList::const_iterator i = vIgnoreReset.begin(); i != vIgnoreReset.end(); ++i)
3938 {
3939 if ((*i)->IsAffectedOnSpell(m_spellInfo))
3940 {
3941 resetAttackTimers = false;
3942 break;
3943 }
3944 }
3945 }
3946
3947 // Okay, everything is prepared. Now we need to distinguish between immediate and evented delayed spells
3948 if ((m_spellInfo->Speed > 0.0f && !m_spellInfo->IsChanneled())/* xinef: we dont need this || m_spellInfo->Id == 14157*/)
3949 {
3950 // Remove used for cast item if need (it can be already nullptr after TakeReagents call
3951 // in case delayed spell remove item at cast delay start
3952 TakeCastItem();
3953
3954 // Okay, maps created, now prepare flags
3955 m_immediateHandled = false;
3957 SetDelayStart(0);
3958
3961
3962 // remove all applied mods at this point
3963 // dont allow user to use them twice in case spell did not reach current target
3964 if (modOwner)
3965 modOwner->RemoveSpellMods(this);
3966
3967 // Xinef: why do we keep focus after spell is sent to air?
3968 // Xinef: Because of this, in the middle of some animation after setting targetguid to 0 etc
3969 // Xinef: we get focused to it out of nowhere...
3970 if (Creature* creatureCaster = m_caster->ToCreature())
3971 creatureCaster->ReleaseFocus(this);
3972 }
3973 else
3974 {
3975 // Immediate spell, no big deal
3977 }
3978
3979 if (resetAttackTimers)
3980 {
3981 if (m_casttime == 0 && m_spellInfo->CalcCastTime())
3982 {
3983 resetAttackTimers = false;
3984 }
3985
3986 if (resetAttackTimers)
3987 {
3989
3991 {
3993 }
3994
3996 }
3997 }
3998
4000
4001 if (modOwner)
4002 modOwner->SetSpellModTakingSpell(this, false);
4003
4004 if (std::vector<int32> const* spell_triggered = sSpellMgr->GetSpellLinked(m_spellInfo->Id))
4005 {
4006 for (int32 id : *spell_triggered)
4007 {
4008 if (id < 0)
4010 else
4012 }
4013 }
4014
4015 // Interrupt Spell casting
4016 // handle this here, in other places SpellHitTarget can be set to nullptr, if there is an error in this function
4018 if (Unit* target = m_targets.GetUnitTarget())
4019 if (target->IsCreature())
4020 m_caster->CastSpell(target, 32747, true);
4021
4022 // xinef: start combat at cast for delayed spells, only for explicit target
4023 if (Unit* target = m_targets.GetUnitTarget())
4026 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
4027
4028 if (m_caster->IsPlayer())
4031
4032 sScriptMgr->OnSpellCast(this, m_caster, m_spellInfo, skipCheck);
4033
4034 SetExecutedCurrently(false);
4035
4036 // Call CreatureAI hook OnSpellCastFinished
4037 if (m_originalCaster)
4038 if (Creature* caster = m_originalCaster->ToCreature())
4039 if (caster->IsAIEnabled)
4040 caster->AI()->OnSpellCastFinished(GetSpellInfo(), SPELL_FINISHED_SUCCESSFUL_CAST);
4041}
@ 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
std::int32_t int32
Definition Define.h:103
@ PET_SAVE_AS_CURRENT
Definition PetDefines.h:43
@ CHEAT_COOLDOWN
Definition Player.h:996
#define sScriptMgr
Definition ScriptMgr.h:728
@ SPELL_ATTR7_CAN_CAUSE_INTERRUPT
Definition SharedDefines.h:663
@ SPELL_EFFECT_SUMMON_PET
Definition SharedDefines.h:845
@ SPELL_ATTR2_DO_NOT_RESET_COMBAT_TIMERS
Definition SharedDefines.h:484
@ SPELL_ATTR1_DISMISS_PET_FIRST
Definition SharedDefines.h:430
@ SPELL_ATTR3_SUPPRESS_TARGET_PROCS
Definition SharedDefines.h:521
@ SPELL_DAMAGE_CLASS_NONE
Definition SharedDefines.h:1556
@ SPELL_MISS_NONE
Definition SharedDefines.h:1530
SpellCastResult
Definition SharedDefines.h:959
@ SPELL_FAILED_DONT_REPORT
Definition SharedDefines.h:987
@ SPELL_CAST_OK
Definition SharedDefines.h:1149
@ 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
@ 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
@ TARGET_FLAG_TRADE_ITEM
Definition SpellInfo.h:58
@ TARGET_FLAG_UNIT
Definition SpellInfo.h:47
@ 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
@ SPELL_FINISHED_SUCCESSFUL_CAST
Definition Spell.h:98
@ SPELL_STATE_DELAYED
Definition Spell.h:239
@ SPELL_STATE_FINISHED
Definition Spell.h:237
@ UNIT_STATE_CASTING
Definition UnitDefines.h:185
Definition Creature.h:47
uint32 GetEntry() const
Definition Object.h:116
bool IsCreature() const
Definition Object.h:205
Creature * ToCreature()
Definition Object.h:206
Definition Pet.h:41
Definition Player.h:1071
void UpdateAchievementCriteria(AchievementCriteriaTypes type, uint32 miscValue1=0, uint32 miscValue2=0, Unit *unit=nullptr)
Definition PlayerUpdates.cpp:2160
void SetSpellModTakingSpell(Spell *spell, bool apply)
Definition Player.cpp:10107
void StartTimedAchievement(AchievementCriteriaTimedTypes type, uint32 entry, uint32 timeLost=0)
Definition Player.cpp:13973
void RemoveSpellMods(Spell *spell)
Definition Player.cpp:10029
Pet * GetPet() const
Definition Player.cpp:8977
bool GetCommandStatus(uint32 command) const
Definition Player.h:1184
void RemovePet(Pet *pet, PetSaveMode mode, bool returnreagent=false)
Definition Player.cpp:9127
TradeData * GetTradeData() const
Definition Player.h:1375
void RemoveSpellCooldown(uint32 spell_id, bool update=false)
Definition Player.cpp:3535
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:149
uint32 GetTargetMask() const
Definition Spell.h:127
Unit * GetUnitTarget() const
Definition Spell.cpp:232
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:2364
bool HasAura(AuraType aura) const
Definition SpellInfo.cpp:893
SpellInfo const * GetSpellInfo() const
Definition Spell.h:587
void CallScriptAfterCastHandlers()
Definition Spell.cpp:8508
void PrepareTriggersExecutedOnHit()
Definition Spell.cpp:8714
bool HasTriggeredCastFlag(TriggerCastFlags flag) const
Definition Spell.h:565
SpellCastTargets m_targets
Definition Spell.h:538
TriggeredByAuraSpellData m_triggeredByAuraSpell
Definition Spell.h:784
void handle_immediate()
Definition Spell.cpp:4043
void SendSpellGo()
Definition Spell.cpp:4735
void TakeReagents()
Definition Spell.cpp:5470
void SetExecutedCurrently(bool yes)
Definition Spell.h:573
void SendInterrupted(uint8 result)
Definition Spell.cpp:5112
void PrepareScriptHitHandlers()
Definition Spell.cpp:8540
void CallScriptOnCastHandlers()
Definition Spell.cpp:8495
void cancel(bool bySelf=false)
Definition Spell.cpp:3636
void SendSpellCooldown()
Definition Spell.cpp:4283
void CallScriptBeforeCastHandlers()
Definition Spell.cpp:8482
void HandleLaunchPhase()
Definition Spell.cpp:8185
bool UpdatePointers()
Definition Spell.cpp:7815
void SetDelayStart(uint64 m_time)
Definition Spell.h:575
std::list< TargetInfo > m_UniqueTargetInfo
Definition Spell.h:694
void SelectSpellTargets()
Definition Spell.cpp:819
void TakePower()
Definition Spell.cpp:5253
SpellCastResult CheckCast(bool strict)
Definition Spell.cpp:5592
static void SendCastResult(Player *caster, SpellInfo const *spellInfo, uint8 castCount, SpellCastResult result, SpellCustomErrors customError=SPELL_CUSTOM_ERROR_NONE)
Definition Spell.cpp:4607
uint64 GetDelayMoment() const
Definition Spell.h:576
void TakeCastItem()
Definition Spell.cpp:5190
bool IsAutoActionResetSpell() const
Definition Spell.cpp:8029
void finish(bool ok=true)
Definition Spell.cpp:4415
Definition TradeData.h:36
Definition Unit.h:650
bool HasOffhandWeaponForAttack() const
Definition Unit.h:968
void ClearUnitState(uint32 f)
Definition Unit.h:722
AuraEffectList const & GetAuraEffectsByType(AuraType type) const
Definition Unit.h:1391
Unit * GetCharm() const
Definition Unit.cpp:10747
std::vector< AuraEffect * > AuraEffectList
Definition Unit.h:666
Player * GetSpellModOwner() const
Definition Unit.cpp:16588
void CombatStartOnCast(Unit *target, bool initialAggro=true, uint32 duration=0)
Definition Unit.cpp:13787
bool IsPet() const
Definition Unit.h:780
bool IsNonMeleeSpellCast(bool withDelayed, bool skipChanneled=false, bool skipAutorepeat=false, bool isAutoshoot=false, bool skipInstant=true) const
Definition Unit.cpp:4158
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:1194
void RemoveAurasDueToSpell(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, uint8 reqEffMask=0, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition Unit.cpp:4977
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:6477
bool HasUnitState(const uint32 f) const
Definition Unit.h:721
bool IsFriendlyTo(Unit const *unit) const
Definition Unit.cpp:10292
bool IsControlledByPlayer() const
Definition Unit.h:1274
void SetInFront(WorldObject const *target)
Definition Unit.cpp:20274
void resetAttackTimer(WeaponAttackType type=BASE_ATTACK)
Definition Unit.cpp:643
int8 effectIndex
Definition Spell.h:290
SpellInfo const * spellInfo
Definition Spell.h:289

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_FINISHED_SUCCESSFUL_CAST, 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 ( )
4209{
4210 // Take for real after all targets are processed
4212 {
4214 }
4215
4216 // Real add combo points from effects
4218 {
4219 // remove Premed-like effects unless they were caused by ourselves
4220 // (this Aura removes the already-added CP when it expires from duration - now that we've added CP, this shouldn't happen anymore!)
4222 {
4224 }
4225
4227 }
4228
4230 {
4232 }
4233
4236 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
4237 {
4238 // Xinef: Properly clear infinite cooldowns in some cases
4239 if (ihit->targetGUID == m_caster->GetGUID() && ihit->missCondition != SPELL_MISS_NONE)
4242 }
4243
4244 // Handle procs on finish
4245 if (m_originalCaster)
4246 {
4247 uint32 procAttacker = m_procAttacker;
4248 if (!procAttacker)
4249 {
4250 bool IsPositive = m_spellInfo->IsPositive();
4252 {
4254 }
4255 else
4256 {
4258 }
4259 }
4260
4261 uint32 procEx = PROC_EX_NORMAL_HIT;
4262 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
4263 {
4264 if (ihit->missCondition != SPELL_MISS_NONE)
4265 {
4266 continue;
4267 }
4268
4269 if (!ihit->crit)
4270 {
4271 continue;
4272 }
4273
4274 procEx |= PROC_EX_CRITICAL_HIT;
4275 break;
4276 }
4277
4280 }
4281}
@ SPELL_EFFECT_ADD_EXTRA_ATTACKS
Definition SharedDefines.h:808
@ 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:11127
bool IsCooldownStartedOnEvent() const
Definition SpellInfo.cpp:1212
bool IsAutoRepeat() const
Definition Spell.h:559
bool IsNextMeleeSwingSpell() const
Definition Spell.cpp:8019
void SetLastExtraAttackSpell(uint32 spellId)
Definition Unit.h:987
Player * GetCharmerOrOwnerPlayerOrPlayerItself() const
Definition Unit.cpp:10692
void ClearComboPoints()
Definition Unit.cpp:16890
void AddComboPoints(Unit *target, int8 count)
Definition Unit.cpp:16864
void RemoveAurasByType(AuraType auraType, ObjectGuid casterGUID=ObjectGuid::Empty, Aura *except=nullptr, bool negative=true, bool positive=true)
Definition Unit.cpp:5178

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 ( )
4181{
4182 m_spellAura = nullptr;
4183 // initialize Diminishing Returns Data
4186
4187 // handle some immediate features of the spell here
4189
4191
4192 // handle effects with SPELL_EFFECT_HANDLE_HIT mode
4193 for (uint32 j = 0; j < MAX_SPELL_EFFECTS; ++j)
4194 {
4195 // don't do anything for empty effect
4196 if (!m_spellInfo->Effects[j].IsEffect())
4197 continue;
4198
4199 // call effect handlers to handle destination hit
4200 HandleEffects(nullptr, nullptr, nullptr, j, SPELL_EFFECT_HANDLE_HIT);
4201 }
4202
4203 // process items
4204 for (std::list<ItemTargetInfo>::iterator ihit = m_UniqueItemInfo.begin(); ihit != m_UniqueItemInfo.end(); ++ihit)
4205 DoAllEffectOnTarget(&(*ihit));
4206}
@ SPELL_EFFECT_HANDLE_HIT
Definition Spell.h:246
std::array< SpellEffectInfo, MAX_SPELL_EFFECTS > Effects
Definition SpellInfo.h:393
void HandleThreatSpells()
Definition Spell.cpp:5519
void HandleEffects(Unit *pUnitTarget, Item *pItemTarget, GameObject *pGOTarget, uint32 i, SpellEffectHandleMode mode)
Definition Spell.cpp:5566
std::list< ItemTargetInfo > m_UniqueItemInfo
Definition Spell.h:711
void DoAllEffectOnTarget(TargetInfo *target)
Definition Spell.cpp:2520

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
542 {
543 if (target != m_comboTarget)
544 {
545 m_comboTarget = target;
546 m_comboPointGain = amount;
547 }
548 else
549 {
550 m_comboPointGain += amount;
551 }
552 }

References m_comboPointGain, and m_comboTarget.

Referenced by EffectAddComboPoints(), and EffectWeaponDmg().

◆ AddDestTarget()

void Spell::AddDestTarget ( SpellDestination const &  dest,
uint32  effIndex 
)
protected
2516{
2517 m_destTargets[effIndex] = dest;
2518}

References m_destTargets.

Referenced by SelectSpellTargets().

◆ AddGOTarget()

void Spell::AddGOTarget ( GameObject target,
uint32  effectMask 
)
protected
2425{
2426 for (uint32 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
2427 {
2428 if (!m_spellInfo->Effects[effIndex].IsEffect())
2429 effectMask &= ~(1 << effIndex);
2430 else
2431 {
2432 switch (m_spellInfo->Effects[effIndex].Effect)
2433 {
2437 if (go->GetGoType() != GAMEOBJECT_TYPE_DESTRUCTIBLE_BUILDING)
2438 effectMask &= ~(1 << effIndex);
2439 break;
2440 default:
2441 break;
2442 }
2443 }
2444 }
2445
2446 if (!effectMask)
2447 return;
2448
2449 ObjectGuid targetGUID = go->GetGUID();
2450
2451 // Lookup target in already in list
2452 for (std::list<GOTargetInfo>::iterator ihit = m_UniqueGOTargetInfo.begin(); ihit != m_UniqueGOTargetInfo.end(); ++ihit)
2453 {
2454 if (targetGUID == ihit->targetGUID) // Found in list
2455 {
2456 ihit->effectMask |= effectMask; // Add only effect mask
2457 return;
2458 }
2459 }
2460
2461 // This is new target calculate data for him
2462
2463 GOTargetInfo target;
2464 target.targetGUID = targetGUID;
2465 target.effectMask = effectMask;
2466 target.processed = false; // Effects not apply on target
2467
2468 // Spell have speed - need calculate incoming time
2469 if (m_spellInfo->Speed > 0.0f)
2470 {
2471 // calculate spell incoming interval
2472 float dist = m_caster->GetDistance(go->GetPositionX(), go->GetPositionY(), go->GetPositionZ());
2473 if (dist < 5.0f)
2474 dist = 5.0f;
2475 target.timeDelay = uint64(std::floor(dist / m_spellInfo->Speed * 1000.0f));
2476 if (m_delayMoment == 0 || m_delayMoment > target.timeDelay)
2477 m_delayMoment = target.timeDelay;
2478 }
2479 else
2480 target.timeDelay = 0LL;
2481
2482 // Add target to list
2483 m_UniqueGOTargetInfo.push_back(target);
2484}
std::uint64_t uint64
Definition Define.h:106
@ GAMEOBJECT_TYPE_DESTRUCTIBLE_BUILDING
Definition SharedDefines.h:1604
@ SPELL_EFFECT_GAMEOBJECT_REPAIR
Definition SharedDefines.h:877
@ SPELL_EFFECT_GAMEOBJECT_SET_DESTRUCTION_STATE
Definition SharedDefines.h:878
@ SPELL_EFFECT_GAMEOBJECT_DAMAGE
Definition SharedDefines.h:876
Definition ObjectGuid.h:118
uint64 m_delayMoment
Definition Spell.h:651
std::list< GOTargetInfo > m_UniqueGOTargetInfo
Definition Spell.h:704
float GetDistance(WorldObject const *obj) const
Definition Object.cpp:1278

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
2487{
2488 for (uint32 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
2489 if (!m_spellInfo->Effects[effIndex].IsEffect())
2490 effectMask &= ~(1 << effIndex);
2491
2492 // no effects left
2493 if (!effectMask)
2494 return;
2495
2496 // Lookup target in already in list
2497 for (std::list<ItemTargetInfo>::iterator ihit = m_UniqueItemInfo.begin(); ihit != m_UniqueItemInfo.end(); ++ihit)
2498 {
2499 if (item == ihit->item) // Found in list
2500 {
2501 ihit->effectMask |= effectMask; // Add only effect mask
2502 return;
2503 }
2504 }
2505
2506 // This is new target add data
2507
2508 ItemTargetInfo target;
2509 target.item = item;
2510 target.effectMask = effectMask;
2511
2512 m_UniqueItemInfo.push_back(target);
2513}

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)
2292{
2293 for (uint32 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
2294 if (!m_spellInfo->Effects[effIndex].IsEffect() || !CheckEffectTarget(target, effIndex))
2295 effectMask &= ~(1 << effIndex);
2296
2297 // no effects left
2298 if (!effectMask)
2299 return;
2300
2301 if (checkIfValid)
2302 {
2303 SpellCastResult res = m_spellInfo->CheckTarget(m_caster, target, implicit);
2304 if (res != SPELL_CAST_OK)
2305 return;
2306 }
2307
2308 // Check for effect immune skip if immuned
2309 for (uint32 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
2310 if (target->IsImmunedToSpellEffect(m_spellInfo, effIndex))
2311 effectMask &= ~(1 << effIndex);
2312
2313 ObjectGuid targetGUID = target->GetGUID();
2314
2315 // Lookup target in already in list
2316 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
2317 {
2318 if (targetGUID == ihit->targetGUID) // Found in list
2319 {
2320 ihit->effectMask |= effectMask; // Immune effects removed from mask
2321 ihit->scaleAura = false;
2322 if (m_auraScaleMask && ihit->effectMask == m_auraScaleMask && m_caster != target)
2323 {
2324 SpellInfo const* auraSpell = m_spellInfo->GetFirstRankSpell();
2325 if (uint32(target->GetLevel() + 10) >= auraSpell->SpellLevel)
2326 ihit->scaleAura = true;
2327 }
2328
2329 sScriptMgr->OnScaleAuraUnitAdd(this, target, effectMask, checkIfValid, implicit, m_auraScaleMask, *ihit);
2330 return;
2331 }
2332 }
2333
2334 // This is new target calculate data for him
2335
2336 // Get spell hit result on target
2337 TargetInfo targetInfo;
2338 targetInfo.targetGUID = targetGUID; // Store target GUID
2339 targetInfo.effectMask = effectMask; // Store all effects not immune
2340 targetInfo.processed = false; // Effects not apply on target
2341 targetInfo.alive = target->IsAlive();
2342 targetInfo.damage = 0;
2343 targetInfo.crit = false;
2344 targetInfo.scaleAura = false;
2345 if (m_auraScaleMask && targetInfo.effectMask == m_auraScaleMask && m_caster != target)
2346 {
2347 SpellInfo const* auraSpell = m_spellInfo->GetFirstRankSpell();
2348 if (uint32(target->GetLevel() + 10) >= auraSpell->SpellLevel)
2349 targetInfo.scaleAura = true;
2350 }
2351
2352 sScriptMgr->OnScaleAuraUnitAdd(this, target, effectMask, checkIfValid, implicit, m_auraScaleMask, targetInfo);
2353
2354 // Calculate hit result
2355 if (m_originalCaster)
2356 {
2357 targetInfo.missCondition = m_originalCaster->SpellHitResult(target, this, m_canReflect);
2358 if (m_skipCheck && targetInfo.missCondition != SPELL_MISS_IMMUNE)
2359 {
2360 targetInfo.missCondition = SPELL_MISS_NONE;
2361 }
2362 }
2363 else
2364 targetInfo.missCondition = SPELL_MISS_EVADE; //SPELL_MISS_NONE;
2365
2366 // Spell have speed - need calculate incoming time
2367 // Incoming time is zero for self casts. At least I think so.
2368 if (m_spellInfo->Speed > 0.0f && m_caster != target)
2369 {
2370 // calculate spell incoming interval
2372 float dist = m_caster->GetDistance(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ());
2373
2374 if (dist < 5.0f)
2375 dist = 5.0f;
2376 targetInfo.timeDelay = (uint64) std::floor(dist / m_spellInfo->Speed * 1000.0f);
2377
2378 // Calculate minimum incoming time
2379 if (m_delayMoment == 0 || m_delayMoment > targetInfo.timeDelay)
2380 m_delayMoment = targetInfo.timeDelay;
2381 }
2382 else
2383 targetInfo.timeDelay = 0LL;
2384
2385 // If target reflect spell back to caster
2386 if (targetInfo.missCondition == SPELL_MISS_REFLECT)
2387 {
2388 // Calculate reflected spell result on caster
2390
2391 if (targetInfo.reflectResult == SPELL_MISS_REFLECT) // Impossible reflect again, so simply deflect spell
2392 targetInfo.reflectResult = SPELL_MISS_PARRY;
2393
2394 // Increase time interval for reflected spells by 1.5
2396 targetInfo.timeDelay += targetInfo.timeDelay >> 1;
2397
2399
2400 // HACK: workaround check for succubus seduction case
2402 if (m_caster->IsPet())
2403 {
2404 CreatureTemplate const* ci = sObjectMgr->GetCreatureTemplate(m_caster->GetEntry());
2405 switch (ci->family)
2406 {
2408 {
2409 if (m_spellInfo->SpellIconID != 694) // Soothing Kiss
2410 cancel();
2411 }
2412 break;
2413 return;
2414 }
2415 }
2416 }
2417 else
2418 targetInfo.reflectResult = SPELL_MISS_NONE;
2419
2420 // Add target to list
2421 m_UniqueTargetInfo.push_back(targetInfo);
2422}
std::chrono::milliseconds Milliseconds
Milliseconds shorthand typedef.
Definition Duration.h:27
#define sObjectMgr
Definition ObjectMgr.h:1650
@ CREATURE_FAMILY_SUCCUBUS
Definition SharedDefines.h:2675
@ SPELL_MISS_PARRY
Definition SharedDefines.h:1534
@ SPELL_MISS_IMMUNE
Definition SharedDefines.h:1537
@ SPELL_MISS_EVADE
Definition SharedDefines.h:1536
@ SPELL_MISS_REFLECT
Definition SharedDefines.h:1541
@ SPELL_FLAG_REFLECTED
Definition Spell.h:85
void AddEventAtOffset(BasicEvent *event, Milliseconds offset, uint8 eventGroup=0)
Definition EventProcessor.h:108
Definition Spell.h:850
Definition SpellInfo.h:316
uint32 SpellLevel
Definition SpellInfo.h:360
SpellInfo const * GetFirstRankSpell() const
Definition SpellInfo.cpp:2513
uint32 SpellIconID
Definition SpellInfo.h:380
SpellCastResult CheckTarget(Unit const *caster, WorldObject const *target, bool implicit=true) const
Definition SpellInfo.cpp:1759
bool CheckEffectTarget(Unit const *target, uint32 eff) const
Definition Spell.cpp:7877
bool IsAlive() const
Definition Unit.h:1748
SpellMissInfo SpellHitResult(Unit *victim, SpellInfo const *spell, bool canReflect=false)
Definition Unit.cpp:3507
virtual bool IsImmunedToSpellEffect(SpellInfo const *spellInfo, uint32 index) const
Definition Unit.cpp:13085
uint8 GetLevel() const
Definition Unit.h:1065
EventProcessor m_Events
Definition Object.h:731
Definition CreatureData.h:186
uint32 family
Definition CreatureData.h:217
float GetPositionZ() const
Definition Position.h:123
float GetPositionX() const
Definition Position.h:121
float GetPositionY() const
Definition Position.h:122
Definition Spell.h:265
bool processed
Definition Spell.h:271
int32 damage
Definition Spell.h:275
SpellMissInfo missCondition
Definition Spell.h:268
bool scaleAura
Definition Spell.h:274
bool crit
Definition Spell.h:273
uint64 timeDelay
Definition Spell.h:267
ObjectGuid targetGUID
Definition Spell.h:266
SpellMissInfo reflectResult
Definition Spell.h:269
bool alive
Definition Spell.h:272
uint8 effectMask
Definition Spell.h:270

References EventProcessor::AddEventAtOffset(), TargetInfo::alive, 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}
bool HasTraj() const
Definition Spell.h:176
bool HasDst() const
Definition Spell.h:175
float GetSpeedXY() const
Definition Spell.h:184
float GetDist2d() const
Definition Spell.h:183
WorldLocation const * GetDstPos() const
Definition Spell.cpp:401
float GetExactDist(float x, float y, float z) const
Definition Position.h:182

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}
@ MOVE_RUN
Definition UnitDefines.h:354
float baseMoveSpeed[MAX_MOVE_TYPE]
Definition Unit.cpp:76
float playerBaseMoveSpeed[MAX_MOVE_TYPE]
Definition Unit.cpp:89
float GetSpeed(UnitMoveType mtype) const
Definition Unit.cpp:14512
double gravity
Definition MovementUtil.cpp:24

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:14880
int32 EffectBasePoints[MAX_SPELL_EFFECTS]
Definition Spell.h:223

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

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

◆ CallScriptAfterCastHandlers()

void Spell::CallScriptAfterCastHandlers ( )
protected
8509{
8510 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8511 {
8512 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_AFTER_CAST);
8513 std::list<SpellScript::CastHandler>::iterator hookItrEnd = (*scritr)->AfterCast.end(), hookItr = (*scritr)->AfterCast.begin();
8514 for (; hookItr != hookItrEnd; ++hookItr)
8515 (*hookItr).Call(*scritr);
8516
8517 (*scritr)->_FinishScriptCall();
8518 }
8519}
@ 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
8621{
8622 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8623 {
8624 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_AFTER_HIT);
8625 std::list<SpellScript::HitHandler>::iterator hookItrEnd = (*scritr)->AfterHit.end(), hookItr = (*scritr)->AfterHit.begin();
8626 for (; hookItr != hookItrEnd; ++hookItr)
8627 (*hookItr).Call(*scritr);
8628
8629 (*scritr)->_FinishScriptCall();
8630 }
8631}
@ SPELL_SCRIPT_HOOK_AFTER_HIT
Definition SpellScript.h:165

References m_loadedScripts, and SPELL_SCRIPT_HOOK_AFTER_HIT.

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

◆ CallScriptBeforeCastHandlers()

void Spell::CallScriptBeforeCastHandlers ( )
protected
8483{
8484 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8485 {
8486 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_BEFORE_CAST);
8487 std::list<SpellScript::CastHandler>::iterator hookItrEnd = (*scritr)->BeforeCast.end(), hookItr = (*scritr)->BeforeCast.begin();
8488 for (; hookItr != hookItrEnd; ++hookItr)
8489 (*hookItr).Call(*scritr);
8490
8491 (*scritr)->_FinishScriptCall();
8492 }
8493}
@ 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
8595{
8596 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8597 {
8598 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_BEFORE_HIT);
8599 std::list<SpellScript::BeforeHitHandler>::iterator hookItrEnd = (*scritr)->BeforeHit.end(), hookItr = (*scritr)->BeforeHit.begin();
8600 for (; hookItr != hookItrEnd; ++hookItr)
8601 (*hookItr).Call(*scritr, missInfo);
8602
8603 (*scritr)->_FinishScriptCall();
8604 }
8605}
@ SPELL_SCRIPT_HOOK_BEFORE_HIT
Definition SpellScript.h:163

References m_loadedScripts, and SPELL_SCRIPT_HOOK_BEFORE_HIT.

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

◆ CallScriptCheckCastHandlers()

SpellCastResult Spell::CallScriptCheckCastHandlers ( )
protected
8522{
8524 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8525 {
8526 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_CHECK_CAST);
8527 std::list<SpellScript::CheckCastHandler>::iterator hookItrEnd = (*scritr)->OnCheckCast.end(), hookItr = (*scritr)->OnCheckCast.begin();
8528 for (; hookItr != hookItrEnd; ++hookItr)
8529 {
8530 SpellCastResult tempResult = (*hookItr).Call(*scritr);
8531 if (retVal == SPELL_CAST_OK)
8532 retVal = tempResult;
8533 }
8534
8535 (*scritr)->_FinishScriptCall();
8536 }
8537 return retVal;
8538}
@ 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
8662{
8663 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8664 {
8665 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_DESTINATION_TARGET_SELECT);
8666 std::list<SpellScript::DestinationTargetSelectHandler>::iterator hookItrEnd = (*scritr)->OnDestinationTargetSelect.end(), hookItr = (*scritr)->OnDestinationTargetSelect.begin();
8667 for (; hookItr != hookItrEnd; ++hookItr)
8668 if (hookItr->IsEffectAffected(m_spellInfo, effIndex) && targetType.GetTarget() == hookItr->GetTarget())
8669 hookItr->Call(*scritr, target);
8670
8671 (*scritr)->_FinishScriptCall();
8672 }
8673}
@ 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
8547{
8548 // execute script effect handler hooks and check if effects was prevented
8549 bool preventDefault = false;
8550 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8551 {
8552 std::list<SpellScript::EffectHandler>::iterator effItr, effEndItr;
8553 SpellScriptHookType hookType;
8554 switch (mode)
8555 {
8557 effItr = (*scritr)->OnEffectLaunch.begin();
8558 effEndItr = (*scritr)->OnEffectLaunch.end();
8560 break;
8562 effItr = (*scritr)->OnEffectLaunchTarget.begin();
8563 effEndItr = (*scritr)->OnEffectLaunchTarget.end();
8565 break;
8567 effItr = (*scritr)->OnEffectHit.begin();
8568 effEndItr = (*scritr)->OnEffectHit.end();
8570 break;
8572 effItr = (*scritr)->OnEffectHitTarget.begin();
8573 effEndItr = (*scritr)->OnEffectHitTarget.end();
8575 break;
8576 default:
8577 ABORT();
8578 return false;
8579 }
8580 (*scritr)->_PrepareScriptCall(hookType);
8581 for (; effItr != effEndItr; ++effItr)
8582 // effect execution can be prevented
8583 if (!(*scritr)->_IsEffectPrevented(effIndex) && (*effItr).IsEffectAffected(m_spellInfo, effIndex))
8584 (*effItr).Call(*scritr, effIndex);
8585
8586 if (!preventDefault)
8587 preventDefault = (*scritr)->_IsDefaultEffectPrevented(effIndex);
8588
8589 (*scritr)->_FinishScriptCall();
8590 }
8591 return preventDefault;
8592}
#define ABORT
Definition Errors.h:76
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
@ SPELL_EFFECT_HANDLE_LAUNCH_TARGET
Definition Spell.h:245
@ SPELL_EFFECT_HANDLE_HIT_TARGET
Definition Spell.h:247

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
8634{
8635 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8636 {
8637 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_OBJECT_AREA_TARGET_SELECT);
8638 std::list<SpellScript::ObjectAreaTargetSelectHandler>::iterator hookItrEnd = (*scritr)->OnObjectAreaTargetSelect.end(), hookItr = (*scritr)->OnObjectAreaTargetSelect.begin();
8639 for (; hookItr != hookItrEnd; ++hookItr)
8640 if (hookItr->IsEffectAffected(m_spellInfo, effIndex) && targetType.GetTarget() == hookItr->GetTarget())
8641 hookItr->Call(*scritr, targets);
8642
8643 (*scritr)->_FinishScriptCall();
8644 }
8645}
@ 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
8648{
8649 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8650 {
8651 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_OBJECT_TARGET_SELECT);
8652 std::list<SpellScript::ObjectTargetSelectHandler>::iterator hookItrEnd = (*scritr)->OnObjectTargetSelect.end(), hookItr = (*scritr)->OnObjectTargetSelect.begin();
8653 for (; hookItr != hookItrEnd; ++hookItr)
8654 if (hookItr->IsEffectAffected(m_spellInfo, effIndex) && targetType.GetTarget() == hookItr->GetTarget())
8655 hookItr->Call(*scritr, target);
8656
8657 (*scritr)->_FinishScriptCall();
8658 }
8659}
@ 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
8496{
8497 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8498 {
8499 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_ON_CAST);
8500 std::list<SpellScript::CastHandler>::iterator hookItrEnd = (*scritr)->OnCast.end(), hookItr = (*scritr)->OnCast.begin();
8501 for (; hookItr != hookItrEnd; ++hookItr)
8502 (*hookItr).Call(*scritr);
8503
8504 (*scritr)->_FinishScriptCall();
8505 }
8506}
@ 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
8608{
8609 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8610 {
8611 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_HIT);
8612 std::list<SpellScript::HitHandler>::iterator hookItrEnd = (*scritr)->OnHit.end(), hookItr = (*scritr)->OnHit.begin();
8613 for (; hookItr != hookItrEnd; ++hookItr)
8614 (*hookItr).Call(*scritr);
8615
8616 (*scritr)->_FinishScriptCall();
8617 }
8618}
@ SPELL_SCRIPT_HOOK_HIT
Definition SpellScript.h:164

References m_loadedScripts, and SPELL_SCRIPT_HOOK_HIT.

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

◆ CanAutoCast()

bool Spell::CanAutoCast ( Unit target)
6947{
6948 ObjectGuid targetguid = target->GetGUID();
6949
6950 for (uint32 j = 0; j < MAX_SPELL_EFFECTS; ++j)
6951 {
6953 {
6954 if (m_spellInfo->StackAmount <= 1)
6955 {
6956 if (target->HasAuraEffect(m_spellInfo->Id, j))
6957 return false;
6958 }
6959 else
6960 {
6961 if (AuraEffect* aureff = target->GetAuraEffect(m_spellInfo->Id, j))
6962 if (aureff->GetBase()->GetStackAmount() >= m_spellInfo->StackAmount)
6963 return false;
6964 }
6965 }
6966 else if (m_spellInfo->Effects[j].IsAreaAuraEffect())
6967 {
6968 if (target->HasAuraEffect(m_spellInfo->Id, j))
6969 return false;
6970 }
6971 }
6972
6973 SpellCastResult result = CheckPetCast(target);
6974
6975 if (result == SPELL_CAST_OK || result == SPELL_FAILED_UNIT_NOT_INFRONT)
6976 {
6978 //check if among target units, our WANTED target is as well (->only self cast spells return false)
6979 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
6980 if (ihit->targetGUID == targetguid)
6981 return true;
6982 }
6983 return false; //target invalid
6984}
@ SPELL_EFFECT_APPLY_AURA
Definition SharedDefines.h:795
@ SPELL_FAILED_UNIT_NOT_INFRONT
Definition SharedDefines.h:1094
Definition SpellAuraEffects.h:39
uint32 StackAmount
Definition SpellInfo.h:371
SpellCastResult CheckPetCast(Unit *target)
Definition Spell.cpp:6753
AuraEffect * GetAuraEffect(uint32 spellId, uint8 effIndex, ObjectGuid casterGUID=ObjectGuid::Empty) const
Definition Unit.cpp:5562
bool HasAuraEffect(uint32 spellId, uint8 effIndex, ObjectGuid caster=ObjectGuid::Empty) const
Definition Unit.cpp:5736

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)
3637{
3639 return;
3640
3641 uint32 oldState = m_spellState;
3643
3644 m_autoRepeat = false;
3645 switch (oldState)
3646 {
3650
3651 if (m_caster->IsPlayer())
3652 {
3654 ArenaSpectator::SendCommand_Spell(m_caster->FindMap(), m_caster->GetGUID(), "SPE", m_spellInfo->Id, bySelf ? 99998 : 99999);
3655 }
3656 [[fallthrough]];
3659 break;
3661 if (!bySelf)
3662 {
3663 for (std::list<TargetInfo>::const_iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
3664 if ((*ihit).missCondition == SPELL_MISS_NONE)
3665 if (Unit* unit = m_caster->GetGUID() == ihit->targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID))
3666 unit->RemoveOwnedAura(m_spellInfo->Id, m_originalCasterGUID, 0, AURA_REMOVE_BY_CANCEL);
3667
3670
3673 }
3674
3676 ArenaSpectator::SendCommand_Spell(m_caster->FindMap(), m_caster->GetGUID(), "SPE", m_spellInfo->Id, bySelf ? 99998 : 99999);
3677
3678 // spell is canceled-take mods and clear list
3679 if (Player* player = m_caster->GetSpellModOwner())
3680 player->RemoveSpellMods(this);
3681
3682 m_appliedMods.clear();
3683 break;
3684 default:
3685 break;
3686 }
3687
3689 if (m_selfContainer && *m_selfContainer == this)
3690 *m_selfContainer = nullptr;
3691
3692 // Do not remove current far sight object (already done in Spell::EffectAddFarsight) to prevent from reset viewpoint to player
3694 {
3696 }
3697
3698 if (m_spellInfo->IsChanneled()) // if not channeled then the object for the current cast wasn't summoned yet
3700
3701 //set state back so finish will be processed
3702 m_spellState = oldState;
3703
3704 sScriptMgr->OnSpellCastCancel(this, m_caster, m_spellInfo, bySelf);
3705
3706 finish(false);
3707}
@ SPELL_EFFECT_ADD_FARSIGHT
Definition SharedDefines.h:861
@ SPELL_FAILED_INTERRUPTED
Definition SharedDefines.h:1000
@ AURA_REMOVE_BY_CANCEL
Definition SpellAuraDefines.h:393
@ SPELL_STATE_PREPARING
Definition Spell.h:235
@ SPELL_STATE_CASTING
Definition Spell.h:236
bool NeedSendSpectatorData() const
Definition Player.cpp:15518
void SendChannelUpdate(uint32 time)
Definition Spell.cpp:5129
void CancelGlobalCooldown()
Definition Spell.cpp:8849
void SetReferencedFromCurrent(bool yes)
Definition Spell.h:571
UsedSpellMods m_appliedMods
Definition Spell.h:556
void RemoveGameObject(GameObject *gameObj, bool del)
Definition Unit.cpp:6296
bool RemoveDynObject(uint32 spellId)
Definition Unit.cpp:6240
Map * FindMap() const
Definition Object.h:622
void SendCommand_Spell(T *o, ObjectGuid targetGUID, const char *prefix, uint32 id, int32 casttime)
Definition ArenaSpectator.h:80

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, sScriptMgr, and Object::ToPlayer().

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

◆ CancelGlobalCooldown()

void Spell::CancelGlobalCooldown ( )
protected
8850{
8852 return;
8853
8854 // Cancel global cooldown when interrupting current cast
8856 return;
8857
8858 // Only players or controlled units have global cooldown
8859 if (m_caster->GetCharmInfo())
8861 else if (m_caster->IsPlayer())
8863}
@ CURRENT_GENERIC_SPELL
Definition Unit.h:540
void CancelGlobalCooldown(SpellInfo const *spellInfo)
Definition CharmInfo.cpp:424
GlobalCooldownMgr & GetGlobalCooldownMgr()
Definition Player.h:1800
uint32 StartRecoveryTime
Definition SpellInfo.h:351
CharmInfo * GetCharmInfo()
Definition Unit.h:1248
Spell * GetCurrentSpell(CurrentSpellTypes spellType) const
Definition Unit.h:1535
GlobalCooldownMgr & GetGlobalCooldownMgr()
Definition CharmInfo.h:160

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
8699{
8700 // Relentless strikes, proc only from first effect
8701 if (triggeredByAura && triggeredByAura->SpellIconID == 559)
8702 return effMask & (1 << EFFECT_0);
8703
8704 bool only_on_caster = (triggeredByAura && triggeredByAura->HasAttribute(SPELL_ATTR4_CLASS_TRIGGER_ONLY_ON_TARGET));
8705 // If triggeredByAura has SPELL_ATTR4_CLASS_TRIGGER_ONLY_ON_TARGET then it can only proc on a casted spell with TARGET_UNIT_CASTER
8706 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
8707 {
8708 if ((effMask & (1 << i)) && (!only_on_caster || (m_spellInfo->Effects[i].TargetA.GetTarget() == TARGET_UNIT_CASTER)))
8709 return true;
8710 }
8711 return effMask;
8712}
@ EFFECT_0
Definition SharedDefines.h:31
@ TARGET_UNIT_CASTER
Definition SharedDefines.h:1421
@ SPELL_ATTR4_CLASS_TRIGGER_ONLY_ON_TARGET
Definition SharedDefines.h:542

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
8314{
8315 if (!lockId) // possible case for GO and maybe for items.
8316 return SPELL_CAST_OK;
8317
8318 // Get LockInfo
8319 LockEntry const* lockInfo = sLockStore.LookupEntry(lockId);
8320
8321 if (!lockInfo)
8323
8324 bool reqKey = false; // some locks not have reqs
8325
8326 for (int j = 0; j < MAX_LOCK_CASE; ++j)
8327 {
8328 switch (lockInfo->Type[j])
8329 {
8330 // check key item (many fit cases can be)
8331 case LOCK_KEY_ITEM:
8332 if (lockInfo->Index[j] && m_CastItem && m_CastItem->GetEntry() == lockInfo->Index[j])
8333 return SPELL_CAST_OK;
8334 reqKey = true;
8335 break;
8336 // check key skill (only single first fit case can be)
8337 case LOCK_KEY_SKILL:
8338 {
8339 reqKey = true;
8340
8341 // wrong locktype, skip
8342 if (uint32(m_spellInfo->Effects[effIndex].MiscValue) != lockInfo->Index[j])
8343 continue;
8344
8345 skillId = SkillByLockType(LockType(lockInfo->Index[j]));
8346
8347 if (skillId != SKILL_NONE)
8348 {
8349 reqSkillValue = lockInfo->Skill[j];
8350
8351 // castitem check: rogue using skeleton keys. the skill values should not be added in this case.
8352 skillValue = m_CastItem || !m_caster->IsPlayer() ?
8353 0 : m_caster->ToPlayer()->GetSkillValue(skillId);
8354
8355 // skill bonus provided by casting spell (mostly item spells)
8356 // add the effect base points modifier from the spell casted (cheat lock / skeleton key etc.)
8357 if ((m_spellInfo->Effects[effIndex].TargetA.GetTarget() == TARGET_GAMEOBJECT_ITEM_TARGET || m_spellInfo->Effects[effIndex].TargetB.GetTarget() == TARGET_GAMEOBJECT_ITEM_TARGET)
8359 {
8360 skillValue += m_spellInfo->Effects[effIndex].CalcValue();
8361 }
8362
8363 if (skillValue < reqSkillValue)
8365 }
8366
8367 return SPELL_CAST_OK;
8368 }
8369 case LOCK_KEY_SPELL:
8370 {
8371 if (m_spellInfo->Id == lockInfo->Index[j])
8372 {
8373 return SPELL_CAST_OK;
8374 }
8375 reqKey = true;
8376 break;
8377 }
8378 }
8379 }
8380
8381 if (reqKey)
8383
8384 return SPELL_CAST_OK;
8385}
DBCStorage< LockEntry > sLockStore(LockEntryfmt)
#define MAX_LOCK_CASE
Definition DBCStructure.h:1306
@ TARGET_GAMEOBJECT_ITEM_TARGET
Definition SharedDefines.h:1441
LockType
Definition SharedDefines.h:2602
@ LOCK_KEY_ITEM
Definition SharedDefines.h:2596
@ LOCK_KEY_SKILL
Definition SharedDefines.h:2597
@ LOCK_KEY_SPELL
Definition SharedDefines.h:2598
@ SPELL_FAILED_BAD_TARGETS
Definition SharedDefines.h:972
@ SPELL_FAILED_LOW_CASTLEVEL
Definition SharedDefines.h:1009
SkillType SkillByLockType(LockType locktype)
Definition SharedDefines.h:3270
@ SKILL_NONE
Definition SharedDefines.h:3114
@ SKILL_LOCKPICKING
Definition SharedDefines.h:3225
uint16 GetSkillValue(uint32 skill) const
Definition Player.cpp:5469
bool IsAbilityOfSkillType(uint32 skillType) const
Definition SpellInfo.cpp:1005
Definition DBCStructure.h:1309
uint32 Type[MAX_LOCK_CASE]
Definition DBCStructure.h:1311
uint32 Index[MAX_LOCK_CASE]
Definition DBCStructure.h:1312
uint32 Skill[MAX_LOCK_CASE]
Definition DBCStructure.h:1313

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)
3710{
3711 Player* modOwner = m_caster->GetSpellModOwner();
3712 Spell* lastMod = nullptr;
3713 if (modOwner)
3714 {
3715 lastMod = modOwner->m_spellModTakingSpell;
3716 if (lastMod)
3717 modOwner->SetSpellModTakingSpell(lastMod, false);
3718 }
3719
3720 _cast(skipCheck);
3721
3722 if (lastMod)
3723 modOwner->SetSpellModTakingSpell(lastMod, true);
3724}
Spell * m_spellModTakingSpell
Definition Player.h:2558
Definition Spell.h:295
void _cast(bool skipCheck)
Definition Spell.cpp:3726

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
5593{
5594 // check death state
5597
5598 // Spectator check
5599 if (m_caster->IsPlayer())
5600 if (((Player const*)m_caster)->IsSpectator() && m_spellInfo->Id != SPECTATOR_SPELL_BINDSIGHT)
5601 return SPELL_FAILED_NOT_HERE;
5602
5604
5605 sScriptMgr->OnSpellCheckCast(this, strict, res);
5606
5607 if (res != SPELL_CAST_OK)
5608 return res;
5609
5610 // check cooldowns to prevent cheating
5612 {
5613 if (m_caster->IsPlayer())
5614 {
5615 //can cast triggered (by aura only?) spells while have this flag
5618
5620 {
5623 else
5625 }
5626
5627 // check if we are using a potion in combat for the 2nd+ time. Cooldown is added only after caster gets out of combat
5630 }
5633 }
5634
5636 {
5639 }
5640
5641 // Check global cooldown
5644
5645 // only triggered spells can be processed an ended battleground
5646 if (!IsTriggered() && m_caster->IsPlayer())
5648 if (bg->GetStatus() == STATUS_WAIT_LEAVE)
5650
5651 if (m_caster->IsPlayer() /*&& VMAP::VMapFactory::createOrGetVMapMgr()->isLineOfSightCalcEnabled()*/) // pussywizard: optimization (commented)
5652 {
5654 !m_caster->IsOutdoors())
5656
5660 }
5661
5662 // only check at first call, Stealth auras are already removed at second call
5663 // for now, ignore triggered spells
5665 {
5666 bool checkForm = true;
5667 // Ignore form req aura
5669 for (Unit::AuraEffectList::const_iterator i = ignore.begin(); i != ignore.end(); ++i)
5670 {
5671 if (!(*i)->IsAffectedOnSpell(m_spellInfo))
5672 continue;
5673 checkForm = false;
5674 break;
5675 }
5676 if (checkForm)
5677 {
5678 // Cannot be used in this stance/form
5680 if (shapeError != SPELL_CAST_OK)
5681 return shapeError;
5682
5685 }
5686 }
5687
5689 for (Unit::AuraEffectList::const_iterator blockItr = blockSpells.begin(); blockItr != blockSpells.end(); ++blockItr)
5690 if (uint32((*blockItr)->GetMiscValue()) == m_spellInfo->SpellFamilyName)
5692
5693 bool reqCombat = true;
5695 for (Unit::AuraEffectList::const_iterator j = stateAuras.begin(); j != stateAuras.end(); ++j)
5696 {
5697 if ((*j)->IsAffectedOnSpell(m_spellInfo))
5698 {
5699 m_needComboPoints = false;
5700 if ((*j)->GetMiscValue() == 1)
5701 {
5702 reqCombat = false;
5703 break;
5704 }
5705 }
5706 }
5707
5708 // caster state requirements
5709 // not for triggered spells (needed by execute)
5711 {
5716
5717 // Note: spell 62473 requres CasterAuraSpell = triggering spell
5722
5723 if (reqCombat && m_caster->IsInCombat() && !m_spellInfo->CanBeUsedInCombat())
5725 }
5726
5727 // Xinef: exploit protection
5729 {
5730 if (m_caster->IsPlayer() && m_caster->GetMap()->IsDungeon())
5731 if (InstanceScript* instanceScript = m_caster->GetInstanceScript())
5732 if (instanceScript->IsEncounterInProgress())
5733 {
5734 if (Group* group = m_caster->ToPlayer()->GetGroup())
5735 for (GroupReference* itr = group->GetFirstMember(); itr != nullptr; itr = itr->next())
5736 if (Player* member = itr->GetSource())
5737 if (member->IsInMap(m_caster))
5738 if (Unit* victim = member->GetVictim())
5739 if (victim->IsInCombat() && m_caster->GetDistance(victim) < m_caster->GetVisibilityRange())
5740 {
5741 m_caster->CombatStart(victim);
5742 victim->AddThreat(m_caster, 1.0f);
5743 break;
5744 }
5746 }
5747 }
5748
5749 // cancel autorepeat spells if cast start when moving
5750 // (not wand currently autorepeat cast delayed to moving stop anyway in spell update code)
5751 if (m_caster->IsPlayer() && m_caster->ToPlayer()->isMoving() && !IsTriggered())
5752 {
5753 // skip stuck spell to allow use it in falling case and apply spell limitations at movement
5756 return SPELL_FAILED_MOVING;
5757 }
5758
5759 Vehicle* vehicle = m_caster->GetVehicle();
5761 {
5762 uint16 checkMask = 0;
5763 for (uint8 effIndex = EFFECT_0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
5764 {
5765 SpellEffectInfo const* effInfo = &m_spellInfo->Effects[effIndex];
5767 {
5768 SpellShapeshiftFormEntry const* shapeShiftEntry = sSpellShapeshiftFormStore.LookupEntry(effInfo->MiscValue);
5769 if (shapeShiftEntry && (shapeShiftEntry->flags1 & SHAPESHIFT_FLAG_STANCE) == 0)
5770 checkMask |= VEHICLE_SEAT_FLAG_UNCONTROLLED;
5771 break;
5772 }
5773 }
5774
5777
5778 if (!checkMask)
5779 checkMask = VEHICLE_SEAT_FLAG_CAN_ATTACK;
5780
5781 // All creatures should be able to cast as passengers freely, restriction and attribute are only for players
5782 VehicleSeatEntry const* vehicleSeat = vehicle->GetSeatForPassenger(m_caster);
5784 && (vehicleSeat->m_flags & checkMask) != checkMask && m_caster->IsPlayer())
5786 }
5787
5788 // check spell cast conditions from database
5789 {
5792 ConditionList conditions = sConditionMgr->GetConditionsForNotGroupedEntry(CONDITION_SOURCE_TYPE_SPELL, m_spellInfo->Id);
5793 if (!conditions.empty() && !sConditionMgr->IsObjectMeetToConditions(condInfo, conditions))
5794 {
5795 // mLastFailedCondition can be nullptr if there was an error processing the condition in Condition::Meets (i.e. wrong data for ConditionTarget or others)
5796 if (condInfo.mLastFailedCondition && condInfo.mLastFailedCondition->ErrorType)
5797 {
5801 }
5802 if (!condInfo.mLastFailedCondition || !condInfo.mLastFailedCondition->ConditionTarget)
5805 }
5806 }
5807
5808 // Don't check explicit target for passive spells (workaround) (check should be skipped only for learn case)
5809 // those spells may have incorrect target entries or not filled at all (for example 15332)
5810 // such spells when learned are not targeting anyone using targeting system, they should apply directly to caster instead
5811 // also, such casts shouldn't be sent to client
5812 // Xinef: do not check explicit casts for self cast of triggered spells (eg. reflect case)
5814 {
5815 // Check explicit target for m_originalCaster - todo: get rid of such workarounds
5816 // Xinef: do not check explicit target for triggered spell casted on self with targetflag enemy
5818 {
5820 if (castResult != SPELL_CAST_OK)
5821 return castResult;
5822 }
5823 }
5824
5825 if (Unit* target = m_targets.GetUnitTarget())
5826 {
5827 SpellCastResult castResult = m_spellInfo->CheckTarget(m_caster, target, false);
5828 if (castResult != SPELL_CAST_OK)
5829 return castResult;
5830
5831 if (target != m_caster)
5832 {
5833 // Must be behind the target
5834 if (m_spellInfo->HasAttribute(SPELL_ATTR0_CU_REQ_CASTER_BEHIND_TARGET) && target->HasInArc(static_cast<float>(M_PI), m_caster))
5836
5837 // Target must be facing you
5838 if (m_spellInfo->HasAttribute(SPELL_ATTR0_CU_REQ_TARGET_FACING_CASTER) && !target->HasInArc(static_cast<float>(M_PI), m_caster))
5840
5843 {
5844 bool castedByGameobject = false;
5845 uint32 losChecks = LINEOFSIGHT_ALL_CHECKS;
5847 {
5848 castedByGameobject = m_caster->GetMap()->GetGameObject(m_originalCasterGUID) != nullptr;
5849 }
5850 else if (m_caster->GetEntry() == WORLD_TRIGGER)
5851 {
5852 if (TempSummon* tempSummon = m_caster->ToTempSummon())
5853 {
5854 castedByGameobject = tempSummon->GetSummonerGameObject() != nullptr;
5855 }
5856 }
5857
5858 if (castedByGameobject)
5859 {
5860 // If spell casted by gameobject then ignore M2 models
5861 losChecks &= ~LINEOFSIGHT_CHECK_GOBJECT_M2;
5862 }
5863
5865 {
5867 }
5868 }
5869 }
5870 }
5871
5872 // Check for line of sight for spells with dest
5873 if (m_targets.HasDst())
5874 {
5875 float x, y, z;
5876 m_targets.GetDstPos()->GetPosition(x, y, z);
5877
5880 {
5881 bool castedByGameobject = false;
5882 uint32 losChecks = LINEOFSIGHT_ALL_CHECKS;
5884 {
5885 castedByGameobject = m_caster->GetMap()->GetGameObject(m_originalCasterGUID) != nullptr;
5886 }
5887 else if (m_caster->GetEntry() == WORLD_TRIGGER)
5888 {
5889 if (TempSummon* tempSummon = m_caster->ToTempSummon())
5890 {
5891 castedByGameobject = tempSummon->GetSummonerGameObject() != nullptr;
5892 }
5893 }
5894
5895 if (castedByGameobject)
5896 {
5897 // If spell casted by gameobject then ignore M2 models
5898 losChecks &= ~LINEOFSIGHT_CHECK_GOBJECT_M2;
5899 }
5900
5902 {
5904 }
5905 }
5906 }
5907
5908 // check pet presence
5909 for (int j = 0; j < MAX_SPELL_EFFECTS; ++j)
5910 {
5911 if (m_spellInfo->Effects[j].TargetA.GetTarget() == TARGET_UNIT_PET)
5912 {
5914 {
5915 if (m_triggeredByAuraSpell.spellInfo) // not report pet not existence for triggered spells
5917 else
5918 return SPELL_FAILED_NO_PET;
5919 }
5920 break;
5921 }
5922 }
5923 // Spell casted only on battleground
5925 if (!m_caster->ToPlayer()->InBattleground())
5927
5928 // do not allow spells to be cast in arenas
5929 // - with greater than 10 min CD without SPELL_ATTR4_IGNORE_DEFAULT_ARENA_RESTRICTIONS flag
5930 // - with SPELL_ATTR4_NOT_IN_ARENA_OR_RATED_BATTLEGROUND flag
5933 if (MapEntry const* mapEntry = sMapStore.LookupEntry(m_caster->GetMapId()))
5934 if (mapEntry->IsBattleArena())
5936
5937 // zone check
5939 {
5940 uint32 zone, area;
5941 m_caster->GetZoneAndAreaId(zone, area);
5942
5944 m_caster->IsPlayer() ? m_caster->ToPlayer() : nullptr);
5945 if (locRes != SPELL_CAST_OK)
5946 return locRes;
5947 }
5948
5949 // not let players cast spells at mount (and let do it to creatures)
5952 {
5953 if (m_caster->IsInFlight())
5955 else
5957 }
5958
5959 SpellCastResult castResult = SPELL_CAST_OK;
5960
5961 // always (except passive spells) check items (focus object can be required for any type casts)
5962 if (!m_spellInfo->IsPassive())
5963 {
5964 // spell focus needs to be checked not only for players! there are vehicle spells that require spell focus
5965 castResult = CheckSpellFocus();
5966 if (castResult != SPELL_CAST_OK)
5967 return castResult;
5968
5969 castResult = CheckItems();
5970 if (castResult != SPELL_CAST_OK)
5971 return castResult;
5972 }
5973
5974 // Triggered spells also have range check
5976 castResult = CheckRange(strict);
5977 if (castResult != SPELL_CAST_OK)
5978 return castResult;
5979
5981 {
5982 castResult = CheckPower();
5983 if (castResult != SPELL_CAST_OK)
5984 return castResult;
5985 }
5986
5988 {
5989 return SPELL_CAST_OK;
5990 }
5991
5992 // xinef: do not skip triggered spells if they posses prevention type (eg. Bladestorm vs Hand of Protection)
5994 {
5996 if (castResult != SPELL_CAST_OK)
5997 return castResult;
5998
5999 // 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).
6001 {
6003 for (SpellImmuneList::const_iterator itr = mechanicList.begin(); itr != mechanicList.end(); ++itr)
6004 if (itr->type == m_spellInfo->Mechanic)
6006 }
6007 }
6008
6009 // script hook
6010 castResult = CallScriptCheckCastHandlers();
6011 if (castResult != SPELL_CAST_OK)
6012 return castResult;
6013
6014 bool hasDispellableAura = false;
6015 bool hasNonDispelEffect = false;
6016 uint32 dispelMask = 0;
6017 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
6018 if (m_spellInfo->Effects[i].Effect == SPELL_EFFECT_DISPEL)
6019 {
6021 {
6022 hasDispellableAura = true;
6023 break;
6024 }
6025
6026 dispelMask |= SpellInfo::GetDispelMask(DispelType(m_spellInfo->Effects[i].MiscValue));
6027 }
6028 else if (m_spellInfo->Effects[i].IsEffect())
6029 {
6030 hasNonDispelEffect = true;
6031 break;
6032 }
6033
6034 if (!hasNonDispelEffect && !hasDispellableAura && dispelMask && !IsTriggered())
6035 {
6036 if (Unit* target = m_targets.GetUnitTarget())
6037 {
6038 // Xinef: do not allow to cast on hostile targets in sanctuary
6039 if (!m_caster->IsFriendlyTo(target))
6040 {
6041 if (m_caster->IsInSanctuary() || target->IsInSanctuary())
6042 {
6043 // Xinef: fix for duels
6044 Player* player = m_caster->ToPlayer();
6045 if (!player || !player->duel || target != player->duel->Opponent)
6047 }
6048 }
6049
6050 DispelChargesList dispelList;
6051 target->GetDispellableAuraList(m_caster, dispelMask, dispelList, m_spellInfo);
6052
6053 if (dispelList.empty())
6055 }
6056 }
6057
6058 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
6059 {
6060 // for effects of spells that have only one target
6061 switch (m_spellInfo->Effects[i].Effect)
6062 {
6064 {
6065 if (!m_caster->IsPlayer())
6067
6068 if (m_spellInfo->Effects[i].TargetA.GetTarget() != TARGET_UNIT_PET)
6069 break;
6070
6071 Pet* pet = m_caster->ToPlayer()->GetPet();
6072
6073 if (!pet)
6074 return SPELL_FAILED_NO_PET;
6075
6076 SpellInfo const* learn_spellproto = sSpellMgr->GetSpellInfo(m_spellInfo->Effects[i].TriggerSpell);
6077
6078 if (!learn_spellproto)
6080
6081 if (m_spellInfo->SpellLevel > pet->GetLevel())
6082 return SPELL_FAILED_LOWLEVEL;
6083
6084 break;
6085 }
6087 {
6088 // check target only for unit target case
6090 {
6091 if (!m_caster->IsPlayer())
6093
6094 Pet* pet = unitTarget->ToPet();
6095 if (!pet || pet->GetOwner() != m_caster)
6097
6098 SpellInfo const* learn_spellproto = sSpellMgr->GetSpellInfo(m_spellInfo->Effects[i].TriggerSpell);
6099
6100 if (!learn_spellproto)
6102
6103 if (m_spellInfo->SpellLevel > pet->GetLevel())
6104 return SPELL_FAILED_LOWLEVEL;
6105 }
6106 break;
6107 }
6109 {
6110 uint32 glyphId = m_spellInfo->Effects[i].MiscValue;
6111 if (GlyphPropertiesEntry const* gp = sGlyphPropertiesStore.LookupEntry(glyphId))
6112 if (m_caster->HasAura(gp->SpellId))
6114 break;
6115 }
6117 {
6118 if (!m_caster->IsPlayer())
6120
6121 Item* foodItem = m_targets.GetItemTarget();
6122 if (!foodItem)
6124
6125 Pet* pet = m_caster->ToPlayer()->GetPet();
6126
6127 if (!pet)
6128 return SPELL_FAILED_NO_PET;
6129
6130 if (!pet->HaveInDiet(foodItem->GetTemplate()))
6132
6133 if (!pet->GetCurrentFoodBenefitLevel(foodItem->GetTemplate()->ItemLevel))
6135
6136 if (m_caster->IsInCombat() || pet->IsInCombat())
6138
6139 break;
6140 }
6143 {
6144 // Can be area effect, Check only for players and not check if target - caster (spell can have multiply drain/burn effects)
6145 if (m_caster->IsPlayer())
6146 if (Unit* target = m_targets.GetUnitTarget())
6147 if (target != m_caster && !target->HasActivePowerType(Powers(m_spellInfo->Effects[i].MiscValue)))
6149 break;
6150 }
6152 {
6154 {
6156 }
6157
6159 {
6160 // Warbringer - can't be handled in proc system - should be done before checkcast root check and charge effect process
6161 if (strict && m_caster->IsScriptOverriden(m_spellInfo, 6953))
6163 }
6165 {
6166 // Exception for Master's Call
6167 if (m_spellInfo->Id != 54216)
6168 {
6169 return SPELL_FAILED_ROOTED;
6170 }
6171 }
6172 if (m_caster->IsPlayer())
6173 if (Unit* target = m_targets.GetUnitTarget())
6174 if (!target->IsAlive())
6176 // Xinef: Pass only explicit unit target spells
6177 // pussywizard:
6178 if (sDisableMgr->IsPathfindingEnabled(m_caster->FindMap()) && m_spellInfo->NeedsExplicitUnitTarget())
6179 {
6180 Unit* target = m_targets.GetUnitTarget();
6181 if (!target)
6183
6184 // first we must check to see if the target is in LoS. A path can usually be built but LoS matters for charge spells
6185 if (!target->IsWithinLOSInMap(m_caster)) //Do full LoS/Path check. Don't exclude m2
6187
6188 float objSize = target->GetCombatReach();
6189 float range = m_spellInfo->GetMaxRange(true, m_caster, this) * 1.5f + objSize; // can't be overly strict
6190
6191 m_preGeneratedPath = std::make_unique<PathGenerator>(m_caster);
6192 m_preGeneratedPath->SetPathLengthLimit(range);
6193
6194 // first try with raycast, if it fails fall back to normal path
6195 bool result = m_preGeneratedPath->CalculatePath(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), false);
6196 if (m_preGeneratedPath->GetPathType() & PATHFIND_SHORT)
6197 return SPELL_FAILED_NOPATH;
6198 else if (!result || m_preGeneratedPath->GetPathType() & (PATHFIND_NOPATH | PATHFIND_INCOMPLETE))
6199 return SPELL_FAILED_NOPATH;
6200 else if (m_preGeneratedPath->IsInvalidDestinationZ(target)) // Check position z, if not in a straight line
6201 return SPELL_FAILED_NOPATH;
6202
6203 m_preGeneratedPath->ShortenPathUntilDist(G3D::Vector3(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ()), objSize); // move back
6204 }
6205 if (Player* player = m_caster->ToPlayer())
6206 player->SetCanTeleport(true);
6207 break;
6208 }
6210 {
6213
6216
6217 Creature* creature = m_targets.GetUnitTarget()->ToCreature();
6218 if (!creature->IsCritter() && !creature->loot.isLooted())
6220
6221 uint32 skill = creature->GetCreatureTemplate()->GetRequiredLootSkill();
6222
6223 int32 skillValue = m_caster->ToPlayer()->GetSkillValue(skill);
6224 int32 TargetLevel = m_targets.GetUnitTarget()->GetLevel();
6225 int32 ReqValue = (skillValue < 100 ? (TargetLevel - 10) * 10 : TargetLevel * 5);
6226 if (ReqValue > skillValue)
6228
6229 break;
6230 }
6232 {
6233 if (m_spellInfo->Effects[i].TargetA.GetTarget() != TARGET_GAMEOBJECT_TARGET &&
6234 m_spellInfo->Effects[i].TargetA.GetTarget() != TARGET_GAMEOBJECT_ITEM_TARGET)
6235 break;
6236
6237 if (!m_caster->IsPlayer() // only players can open locks, gather etc.
6238 // we need a go target in case of TARGET_GAMEOBJECT_TARGET
6239 || (m_spellInfo->Effects[i].TargetA.GetTarget() == TARGET_GAMEOBJECT_TARGET && !m_targets.GetGOTarget()))
6241
6242 Item* pTempItem = nullptr;
6244 {
6245 if (TradeData* pTrade = m_caster->ToPlayer()->GetTradeData())
6246 pTempItem = pTrade->GetTraderData()->GetItem(TradeSlots(m_targets.GetItemTargetGUID().GetRawValue()));
6247 }
6250
6251 // we need a go target, or an openable item target in case of TARGET_GAMEOBJECT_ITEM_TARGET
6252 if (m_spellInfo->Effects[i].TargetA.GetTarget() == TARGET_GAMEOBJECT_ITEM_TARGET &&
6254 (!pTempItem || !pTempItem->GetTemplate()->LockID || !pTempItem->IsLocked()))
6256
6257 // We must also ensure the gameobject we are opening is still closed by the time the spell finishes.
6258 if (GameObject* go = m_targets.GetGOTarget())
6259 {
6260 if (go->GetGoType() == GAMEOBJECT_TYPE_DOOR && go->GetGoState() != GO_STATE_READY)
6261 {
6263 }
6264 }
6265 if (m_spellInfo->Id != 1842 || (m_targets.GetGOTarget() &&
6267 {
6268 if (m_targets.GetGOTarget() && m_targets.GetGOTarget()->GetEntry() == 179697)
6269 {
6270 if (!m_caster->ToPlayer()->CanUseBattlegroundObject(nullptr))
6272 }
6273 else if (m_caster->ToPlayer()->InBattleground() && // In Battleground players can use only flags and banners, or Gurubashi chest
6276 }
6277
6278 // get the lock entry
6279 uint32 lockId = 0;
6280 if (GameObject* go = m_targets.GetGOTarget())
6281 {
6282 lockId = go->GetGOInfo()->GetLockId();
6283 if (!lockId)
6285 }
6286 else if (Item* itm = m_targets.GetItemTarget())
6287 lockId = itm->GetTemplate()->LockID;
6288
6289 SkillType skillId = SKILL_NONE;
6290 int32 reqSkillValue = 0;
6291 int32 skillValue = 0;
6292
6293 // check lock compatibility
6294 SpellCastResult res = CanOpenLock(i, lockId, skillId, reqSkillValue, skillValue);
6295 if (res != SPELL_CAST_OK)
6296 return res;
6297
6298 // chance for fail at lockpicking attempt
6299 // second check prevent fail at rechecks
6300 // herbalism and mining cannot fail as of patch 3.1.0
6301 if (skillId != SKILL_NONE && skillId != SKILL_HERBALISM && skillId != SKILL_MINING && (!m_selfContainer || ((*m_selfContainer) != this)))
6302 {
6303 // chance for failure in orange lockpick
6304 if (skillId == SKILL_LOCKPICKING && reqSkillValue > irand(skillValue - 25, skillValue + 37))
6305 {
6307 }
6308 }
6309 break;
6310 }
6312 {
6313 Unit* unitCaster = m_caster->ToUnit();
6314 if (!unitCaster)
6315 {
6317 }
6318
6319 Creature* pet = unitCaster->GetGuardianPet();
6320 if (pet)
6321 {
6322 if (pet->IsAlive())
6323 {
6325 }
6326 }
6327 else if (Player* playerCaster = m_caster->ToPlayer())
6328 {
6329 PetStable& petStable = playerCaster->GetOrInitPetStable();
6330 if (!petStable.CurrentPet && petStable.UnslottedPets.empty())
6331 {
6332 return SPELL_FAILED_NO_PET;
6333 }
6334 }
6335
6336 break;
6337 }
6338 // This is generic summon effect
6340 {
6341 SummonPropertiesEntry const* SummonProperties = sSummonPropertiesStore.LookupEntry(m_spellInfo->Effects[i].MiscValueB);
6342 if (!SummonProperties || m_spellInfo->HasAttribute(SPELL_ATTR1_DISMISS_PET_FIRST))
6343 break;
6344 switch (SummonProperties->Category)
6345 {
6347 if (m_caster->GetPetGUID())
6349 [[fallthrough]];
6351 if (m_caster->GetCharmGUID())
6353 break;
6354 }
6355 break;
6356 }
6358 {
6360 {
6365 }
6366 break;
6367 }
6369 {
6370 Unit* unitCaster = m_caster->ToUnit();
6371 if (!unitCaster)
6373
6375 {
6376 if (m_caster->GetPetGUID())
6378 if (m_caster->GetCharmGUID())
6380 }
6381
6383 if (Pet* pet = m_caster->ToPlayer()->GetPet())
6384 pet->CastSpell(pet, 32752, true, nullptr, nullptr, pet->GetGUID()); //starting cast, trigger pet stun (cast by pet so it doesn't attack player)
6385
6386 Player* playerCaster = unitCaster->ToPlayer();
6387 if (playerCaster && playerCaster->GetPetStable())
6388 {
6389 std::pair<PetStable::PetInfo const*, PetSaveMode> info = Pet::GetLoadPetInfo(*playerCaster->GetPetStable(), m_spellInfo->Effects[i].MiscValue, 0, false);
6390 if (info.first)
6391 {
6392 if (info.first->Type == HUNTER_PET)
6393 {
6394 if (!info.first->Health)
6395 {
6396 playerCaster->SendTameFailure(PET_TAME_DEAD);
6398 }
6399
6400 CreatureTemplate const* creatureInfo = sObjectMgr->GetCreatureTemplate(info.first->CreatureId);
6401 if (!creatureInfo || !creatureInfo->IsTameable(playerCaster->CanTameExoticPets()))
6402 {
6403 // if problem in exotic pet
6404 if (creatureInfo && creatureInfo->IsTameable(true))
6406 else
6408
6410 }
6411 }
6412 }
6413 else if (!m_spellInfo->Effects[i].MiscValue) // when miscvalue is present it is allowed to create new pets
6414 {
6417 }
6418 }
6419 break;
6420 }
6422 {
6423 if (!m_caster->IsPlayer())
6425 if (!m_caster->GetTarget())
6427
6429 if (!target || (!target->IsInSameRaidWith(m_caster->ToPlayer()) && m_spellInfo->Id != 48955)) // refer-a-friend spell
6431
6432 // Xinef: Implement summon pending error
6433 if (target->GetSummonExpireTimer() > GameTime::GetGameTime().count())
6435
6436 // check if our map is dungeon
6437 MapEntry const* map = sMapStore.LookupEntry(m_caster->GetMapId());
6438 if (map->IsDungeon())
6439 {
6440 uint32 mapId = m_caster->GetMap()->GetId();
6441 Difficulty difficulty = m_caster->GetMap()->GetDifficulty();
6442 /*if (map->IsRaid())
6443 if (InstancePlayerBind* targetBind = target->GetBoundInstance(mapId, difficulty))
6444 if (targetBind->perm && targetBind != m_caster->ToPlayer()->GetBoundInstance(mapId, difficulty))
6445 return SPELL_FAILED_TARGET_LOCKED_TO_RAID_INSTANCE;*/
6446
6447 InstanceTemplate const* instance = sObjectMgr->GetInstanceTemplate(mapId);
6448 if (!instance)
6450 if (!target->Satisfy(sObjectMgr->GetAccessRequirement(mapId, difficulty), mapId))
6452 }
6453 break;
6454 }
6455 // RETURN HERE
6457 {
6458 if (!m_caster->IsPlayer())
6460
6461 Player* playerCaster = m_caster->ToPlayer();
6462 //
6463 if (!(playerCaster->GetTarget()))
6465
6467
6468 if (!target ||
6469 !(target->GetSession()->GetRecruiterId() == playerCaster->GetSession()->GetAccountId() || target->GetSession()->GetAccountId() == playerCaster->GetSession()->GetRecruiterId()))
6471
6472 // Xinef: Implement summon pending error
6473 if (target->GetSummonExpireTimer() > GameTime::GetGameTime().count())
6475
6476 break;
6477 }
6478 case SPELL_EFFECT_LEAP:
6480 {
6481 //Do not allow to cast it before BG starts.
6482 if (m_caster->IsPlayer())
6483 if (Battleground const* bg = m_caster->ToPlayer()->GetBattleground())
6484 if (bg->GetStatus() != STATUS_IN_PROGRESS)
6486 break;
6487 }
6489 {
6492
6493 bool found = false;
6495 for(Unit::VisibleAuraMap::const_iterator itr = visibleAuras->begin(); itr != visibleAuras->end(); ++itr)
6496 {
6497 if (itr->second->GetBase()->IsPassive())
6498 continue;
6499
6500 if (!itr->second->IsPositive())
6501 continue;
6502
6503 found = true;
6504 break;
6505 }
6506
6507 if (!found)
6509
6510 break;
6511 }
6513 {
6515 {
6516 if (m_caster->IsPlayer())
6517 return SPELL_FAILED_ROOTED;
6518 else
6520 }
6521 break;
6522 }
6523 // xinef: do not allow to use leaps while rooted
6524 case SPELL_EFFECT_JUMP:
6526 {
6528 return SPELL_FAILED_ROOTED;
6529 break;
6530 }
6532 if (!sScriptMgr->CanSelectSpecTalent(this))
6534 // can't change during already started arena/battleground
6535 if (m_caster->IsPlayer())
6536 if (Battleground const* bg = m_caster->ToPlayer()->GetBattleground())
6537 if (bg->GetStatus() == STATUS_IN_PROGRESS)
6539 break;
6540 default:
6541 break;
6542 }
6543 }
6544
6545 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
6546 {
6547 switch (m_spellInfo->Effects[i].ApplyAuraName)
6548 {
6549 case SPELL_AURA_DUMMY:
6550 break;
6552 {
6553 if (!m_caster->IsPlayer())
6554 return SPELL_FAILED_NO_PET;
6555
6556 Pet* pet = m_caster->ToPlayer()->GetPet();
6557 if (!pet)
6558 return SPELL_FAILED_NO_PET;
6559
6560 if (pet->GetCharmerGUID())
6561 return SPELL_FAILED_CHARMED;
6562 break;
6563 }
6567 {
6568 if (m_caster->GetCharmerGUID())
6569 return SPELL_FAILED_CHARMED;
6570
6571 // Xinef: allow SPELL_AURA_MOD_POSSESS to posses target if caster has some pet
6573 {
6574 if (m_caster->GetPetGUID())
6576
6577 if (m_caster->GetCharmGUID())
6579 }
6580 else if (m_spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_MOD_POSSESS)
6581 {
6582 if (m_caster->GetCharmGUID())
6584 }
6585
6586 if (Unit* target = m_targets.GetUnitTarget())
6587 {
6588 if (target->IsCreature() && target->ToCreature()->IsVehicle())
6590
6591 if (target->IsMounted())
6593
6594 if (target->GetCharmerGUID())
6595 return SPELL_FAILED_CHARMED;
6596
6597 if (target->GetOwnerGUID() && target->GetOwnerGUID().IsPlayer())
6599
6600 if (target->IsPet() && (!target->GetOwner() || target->GetOwner()->ToPlayer()))
6602
6603 int32 damage = CalculateSpellDamage(i, target);
6604 if (damage && int32(target->GetLevel()) > damage)
6606 }
6607
6608 break;
6609 }
6610 case SPELL_AURA_MOUNTED:
6611 {
6612 // Disallow casting flying mounts in water
6615
6616 // Ignore map check if spell have AreaId. AreaId already checked and this prevent special mount spells
6617 bool allowMount = !m_caster->GetMap()->IsDungeon() || m_caster->GetMap()->IsBattlegroundOrArena();
6618 InstanceTemplate const* it = sObjectMgr->GetInstanceTemplate(m_caster->GetMapId());
6619 if (it)
6620 allowMount = it->AllowMount;
6621 if (m_caster->IsPlayer() && !allowMount && !m_spellInfo->AreaGroupId)
6623
6626
6627 // xinef: dont allow to cast mounts in specific transforms
6628 if (m_caster->getTransForm())
6629 if (SpellInfo const* transformSpellInfo = sSpellMgr->GetSpellInfo(m_caster->getTransForm()))
6630 if (transformSpellInfo->HasAttribute(SPELL_ATTR0_NO_IMMUNITIES) &&
6631 !transformSpellInfo->HasAttribute(SpellAttr0(SPELL_ATTR0_ALLOW_WHILE_MOUNTED | SPELL_ATTR0_AURA_IS_DEBUFF)))
6633
6634 break;
6635 }
6637 {
6638 if (!m_targets.GetUnitTarget())
6640
6641 // can be casted at non-friendly unit or own pet/charm
6644
6645 break;
6646 }
6647 case SPELL_AURA_FLY:
6649 {
6650 // Xinef: added water check
6651 if (m_caster->IsInWater())
6653
6654 // not allow cast fly spells if not have req. skills (all spells is self target)
6655 // allow always ghost flight spells
6657 {
6658 Battlefield* Bf = sBattlefieldMgr->GetBattlefieldToZoneId(m_originalCaster->GetZoneId());
6659 if (AreaTableEntry const* pArea = sAreaTableStore.LookupEntry(m_originalCaster->GetAreaId()))
6660 if ((pArea->flags & AREA_FLAG_NO_FLY_ZONE) || (Bf && !Bf->CanFlyIn()))
6661 return SPELL_FAILED_NOT_HERE;
6662 }
6663 break;
6664 }
6666 {
6667 if (m_spellInfo->Effects[i].IsTargetingArea())
6668 break;
6669
6670 if (!m_caster->IsPlayer() || m_CastItem)
6671 break;
6672
6673 if (!m_targets.GetUnitTarget())
6675
6678
6679 break;
6680 }
6681 case SPELL_AURA_HOVER:
6682 {
6684 {
6686 }
6687 break;
6688 }
6690 {
6691 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.
6692 {
6694 }
6695 break;
6696 }
6697 default:
6698 break;
6699 }
6700 }
6701
6702 // check trade slot case (last, for allow catch any another cast problems)
6704 {
6705 if (m_CastItem)
6707
6708 if (!m_caster->IsPlayer())
6710
6711 TradeData* my_trade = m_caster->ToPlayer()->GetTradeData();
6712
6713 if (!my_trade)
6715
6717 if (slot != TRADE_SLOT_NONTRADED)
6719
6720 if (!IsTriggered())
6721 if (my_trade->GetSpell())
6723 }
6724
6725 // check if caster has at least 1 combo point on target for spells that require combo points
6727 {
6729 {
6731 {
6733 }
6734 }
6735 else
6736 {
6737 if (!m_caster->GetComboPoints())
6738 {
6740 }
6741 }
6742 }
6743
6744 // xinef: check relic cooldown
6748
6749 // all ok
6750 return SPELL_CAST_OK;
6751}
#define SPECTATOR_SPELL_BINDSIGHT
Definition ArenaSpectator.h:38
#define sBattlefieldMgr
Definition BattlefieldMgr.h:77
@ STATUS_WAIT_LEAVE
Definition Battleground.h:194
@ STATUS_IN_PROGRESS
Definition Battleground.h:193
constexpr auto IN_MILLISECONDS
Definition Common.h:53
constexpr auto MINUTE
Definition Common.h:47
#define sConditionMgr
Definition ConditionMgr.h:291
@ CONDITION_SOURCE_TYPE_SPELL
Definition ConditionMgr.h:141
std::list< Condition * > ConditionList
Definition ConditionMgr.h:238
@ 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
DBCStorage< SummonPropertiesEntry > sSummonPropertiesStore(SummonPropertiesfmt)
DBCStorage< SpellShapeshiftFormEntry > sSpellShapeshiftFormStore(SpellShapeshiftFormEntryfmt)
DBCStorage< MapEntry > sMapStore(MapEntryfmt)
DBCStorage< GlyphPropertiesEntry > sGlyphPropertiesStore(GlyphPropertiesfmt)
DBCStorage< AreaTableEntry > sAreaTableStore(AreaTableEntryfmt)
std::uint16_t uint16
Definition Define.h:108
#define sDisableMgr
Definition DisableMgr.h:88
@ GO_STATE_READY
Definition GameObjectData.h:692
@ INVTYPE_RELIC
Definition ItemTemplate.h:284
LineOfSightChecks
Definition Map.h:103
@ LINEOFSIGHT_ALL_CHECKS
Definition Map.h:110
@ PATHFIND_NOPATH
Definition PathGenerator.h:50
@ PATHFIND_SHORT
Definition PathGenerator.h:52
@ PATHFIND_INCOMPLETE
Definition PathGenerator.h:49
@ HUNTER_PET
Definition PetDefines.h:33
@ PLAYER_ALLOW_ONLY_ABILITY
Definition Player.h:491
int32 irand(int32 min, int32 max)
Definition Random.cpp:37
@ GAMEOBJECT_TYPE_TRAP
Definition SharedDefines.h:1577
@ GAMEOBJECT_TYPE_DOOR
Definition SharedDefines.h:1571
Powers
Definition SharedDefines.h:279
@ POWER_MANA
Definition SharedDefines.h:280
@ SPELL_ATTR7_DEBUG_SPELL
Definition SharedDefines.h:655
@ SPELL_EFFECT_LEAP
Definition SharedDefines.h:818
@ SPELL_EFFECT_POWER_BURN
Definition SharedDefines.h:851
@ SPELL_EFFECT_STUCK
Definition SharedDefines.h:873
@ SPELL_EFFECT_SUMMON_RAF_FRIEND
Definition SharedDefines.h:941
@ SPELL_EFFECT_APPLY_GLYPH
Definition SharedDefines.h:863
@ SPELL_EFFECT_FEED_PET
Definition SharedDefines.h:890
@ SPELL_EFFECT_SUMMON_PLAYER
Definition SharedDefines.h:874
@ SPELL_EFFECT_JUMP_DEST
Definition SharedDefines.h:831
@ SPELL_EFFECT_TELEPORT_UNITS_FACE_CASTER
Definition SharedDefines.h:832
@ SPELL_EFFECT_RESURRECT_PET
Definition SharedDefines.h:898
@ SPELL_EFFECT_LEAP_BACK
Definition SharedDefines.h:927
@ SPELL_EFFECT_SUMMON
Definition SharedDefines.h:817
@ SPELL_EFFECT_POWER_DRAIN
Definition SharedDefines.h:797
@ SPELL_EFFECT_RESURRECT
Definition SharedDefines.h:807
@ SPELL_EFFECT_CHARGE
Definition SharedDefines.h:885
@ SPELL_EFFECT_RESURRECT_NEW
Definition SharedDefines.h:902
@ SPELL_EFFECT_TALENT_SPEC_SELECT
Definition SharedDefines.h:951
@ SPELL_EFFECT_LEARN_SPELL
Definition SharedDefines.h:825
@ SPELL_EFFECT_JUMP
Definition SharedDefines.h:830
@ SPELL_EFFECT_SKINNING
Definition SharedDefines.h:884
@ SPELL_EFFECT_CREATE_TAMED_PET
Definition SharedDefines.h:942
@ SPELL_EFFECT_OPEN_LOCK
Definition SharedDefines.h:822
@ SPELL_EFFECT_STEAL_BENEFICIAL_BUFF
Definition SharedDefines.h:915
@ SPELL_EFFECT_LEARN_PET_SPELL
Definition SharedDefines.h:846
@ SPELL_PREVENTION_TYPE_NONE
Definition SharedDefines.h:1564
@ SPELL_ATTR5_ALWAYS_AOE_LINE_OF_SIGHT
Definition SharedDefines.h:604
@ TARGET_UNIT_PET
Definition SharedDefines.h:1425
@ TARGET_GAMEOBJECT_TARGET
Definition SharedDefines.h:1438
@ SPELL_ATTR2_IGNORE_LINE_OF_SIGHT
Definition SharedDefines.h:469
@ SPELL_ATTR1_INITIATE_COMBAT
Definition SharedDefines.h:439
@ SPELL_ATTR3_ONLY_BATTLEGROUNDS
Definition SharedDefines.h:515
@ PET_TAME_NOPET_AVAILABLE
Definition SharedDefines.h:3949
@ PET_TAME_DEAD
Definition SharedDefines.h:3952
@ PET_TAME_CANT_CONTROL_EXOTIC
Definition SharedDefines.h:3954
@ CLASS_WARLOCK
Definition SharedDefines.h:149
@ IMMUNITY_MECHANIC
Definition SharedDefines.h:1410
@ SPELLFAMILY_WARRIOR
Definition SharedDefines.h:3798
SpellCustomErrors
Definition SharedDefines.h:1153
@ SPELL_CUSTOM_ERROR_GM_ONLY
Definition SharedDefines.h:1219
SpellAttr0
Definition SharedDefines.h:392
@ SPELL_ATTR0_ONLY_INDOORS
Definition SharedDefines.h:407
@ SPELL_ATTR0_AURA_IS_DEBUFF
Definition SharedDefines.h:419
@ SPELL_ATTR0_ONLY_OUTDOORS
Definition SharedDefines.h:408
@ SPELL_ATTR0_ALLOW_WHILE_MOUNTED
Definition SharedDefines.h:417
@ SPELL_ATTR0_PASSIVE
Definition SharedDefines.h:399
@ SPELL_ATTR0_ALLOW_CAST_WHILE_DEAD
Definition SharedDefines.h:416
@ SPELL_ATTR0_ONLY_STEALTHED
Definition SharedDefines.h:410
AuraStateType
Definition SharedDefines.h:1299
DispelType
Definition SharedDefines.h:1382
@ SPELL_FAILED_TARGET_NOT_LOOTED
Definition SharedDefines.h:1081
@ SPELL_FAILED_NOT_INFRONT
Definition SharedDefines.h:1021
@ SPELL_FAILED_MOVING
Definition SharedDefines.h:1011
@ SPELL_FAILED_NOT_MOUNTED
Definition SharedDefines.h:1024
@ SPELL_FAILED_AFFECTING_COMBAT
Definition SharedDefines.h:961
@ SPELL_FAILED_CASTER_AURASTATE
Definition SharedDefines.h:982
@ SPELL_FAILED_NOTHING_TO_DISPEL
Definition SharedDefines.h:1046
@ SPELL_FAILED_NOT_KNOWN
Definition SharedDefines.h:1023
@ SPELL_FAILED_FOOD_LOWLEVEL
Definition SharedDefines.h:995
@ SPELL_FAILED_NOT_HERE
Definition SharedDefines.h:1020
@ SPELL_FAILED_ROOTED
Definition SharedDefines.h:1063
@ SPELL_FAILED_WRONG_PET_FOOD
Definition SharedDefines.h:1095
@ SPELL_FAILED_CUSTOM_ERROR
Definition SharedDefines.h:1132
@ SPELL_FAILED_SUMMON_PENDING
Definition SharedDefines.h:1143
@ SPELL_FAILED_DAMAGE_IMMUNE
Definition SharedDefines.h:1106
@ SPELL_FAILED_BAD_IMPLICIT_TARGETS
Definition SharedDefines.h:971
@ SPELL_FAILED_TRY_AGAIN
Definition SharedDefines.h:1092
@ SPELL_FAILED_NO_COMBO_POINTS
Definition SharedDefines.h:1038
@ SPELL_FAILED_ALREADY_HAVE_SUMMON
Definition SharedDefines.h:967
@ SPELL_FAILED_ALREADY_OPEN
Definition SharedDefines.h:968
@ SPELL_FAILED_NOT_TRADING
Definition SharedDefines.h:1031
@ SPELL_FAILED_NOTHING_TO_STEAL
Definition SharedDefines.h:1047
@ SPELL_FAILED_NO_MOUNTS_ALLOWED
Definition SharedDefines.h:1043
@ SPELL_FAILED_NOT_IN_BATTLEGROUND
Definition SharedDefines.h:1126
@ SPELL_FAILED_NOT_BEHIND
Definition SharedDefines.h:1017
@ SPELL_FAILED_ALREADY_HAVE_CHARM
Definition SharedDefines.h:966
@ SPELL_FAILED_TARGET_NOT_IN_INSTANCE
Definition SharedDefines.h:1097
@ SPELL_FAILED_HIGHLEVEL
Definition SharedDefines.h:996
@ SPELL_FAILED_LOWLEVEL
Definition SharedDefines.h:1008
@ SPELL_FAILED_NOT_READY
Definition SharedDefines.h:1027
@ SPELL_FAILED_ONLY_BATTLEGROUNDS
Definition SharedDefines.h:1102
@ SPELL_FAILED_NOT_IN_ARENA
Definition SharedDefines.h:1111
@ SPELL_FAILED_ITEM_ALREADY_ENCHANTED
Definition SharedDefines.h:1002
@ SPELL_FAILED_ONLY_STEALTHED
Definition SharedDefines.h:1055
@ SPELL_FAILED_TARGET_IS_PLAYER_CONTROLLED
Definition SharedDefines.h:1078
@ SPELL_FAILED_ONLY_ABOVEWATER
Definition SharedDefines.h:1048
@ SPELL_FAILED_CANT_BE_CHARMED
Definition SharedDefines.h:973
@ SPELL_FAILED_CASTER_DEAD
Definition SharedDefines.h:983
@ SPELL_FAILED_NOT_ON_MOUNTED
Definition SharedDefines.h:1115
@ SPELL_FAILED_ITEM_ENCHANT_TRADE_WINDOW
Definition SharedDefines.h:1142
@ SPELL_FAILED_TARGET_CANNOT_BE_RESURRECTED
Definition SharedDefines.h:1146
@ SPELL_FAILED_TARGET_UNSKINNABLE
Definition SharedDefines.h:1086
@ SPELL_FAILED_NOT_SHAPESHIFT
Definition SharedDefines.h:1028
@ SPELL_FAILED_UNIQUE_GLYPH
Definition SharedDefines.h:1136
@ SPELL_FAILED_ONLY_OUTDOORS
Definition SharedDefines.h:1053
@ SPELL_FAILED_CHARMED
Definition SharedDefines.h:984
@ SPELL_FAILED_LINE_OF_SIGHT
Definition SharedDefines.h:1007
@ SPELL_FAILED_SPELL_IN_PROGRESS
Definition SharedDefines.h:1065
@ SPELL_FAILED_NO_PET
Definition SharedDefines.h:1044
@ SPELL_FAILED_NOPATH
Definition SharedDefines.h:1016
@ SPELL_FAILED_SPELL_UNAVAILABLE
Definition SharedDefines.h:1067
@ SPELL_FAILED_ONLY_INDOORS
Definition SharedDefines.h:1050
@ SPELL_FAILED_NOT_ON_TAXI
Definition SharedDefines.h:1025
@ SPELL_FAILED_TARGET_FRIENDLY
Definition SharedDefines.h:1075
@ SPELL_ATTR4_IGNORE_DEFAULT_ARENA_RESTRICTIONS
Definition SharedDefines.h:558
@ SPELL_ATTR4_NOT_IN_ARENA_OR_RATED_BATTLEGROUND
Definition SharedDefines.h:557
@ SUMMON_CATEGORY_PET
Definition SharedDefines.h:3535
@ SUMMON_CATEGORY_PUPPET
Definition SharedDefines.h:3536
SkillType
Definition SharedDefines.h:3113
@ SKILL_MINING
Definition SharedDefines.h:3169
@ SKILL_HERBALISM
Definition SharedDefines.h:3165
@ SPELL_ATTR6_ALLOW_WHILE_RIDING_VEHICLE
Definition SharedDefines.h:627
@ 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
@ 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
@ 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
#define SPELL_RELIC_COOLDOWN
Definition SpellMgr.h:34
@ SPELL_FLAG_REDIRECTED
Definition Spell.h:86
TradeSlots
Definition TradeData.h:28
@ TRADE_SLOT_NONTRADED
Definition TradeData.h:31
@ MOVEMENTFLAG_FALLING_FAR
Definition UnitDefines.h:382
@ CLASS_CONTEXT_PET
Definition UnitDefines.h:240
@ UNIT_FLAG2_ALLOW_CHEAT_SPELLS
Definition UnitDefines.h:310
@ SHAPESHIFT_FLAG_STANCE
Definition UnitDefines.h:104
@ UNIT_STATE_ROOT
Definition UnitDefines.h:180
@ UNIT_STATE_CHARGING
Definition UnitDefines.h:187
@ UNIT_FLAG_SKINNABLE
Definition UnitDefines.h:280
#define WORLD_TRIGGER
Definition Unit.h:39
std::list< std::pair< Aura *, uint8 > > DispelChargesList
Definition Unit.h:79
Definition Battlefield.h:205
bool CanFlyIn()
Return if we can use mount in battlefield.
Definition Battlefield.h:342
Definition Battleground.h:294
Loot loot
Definition Creature.h:229
CreatureTemplate const * GetCreatureTemplate() const
Definition Creature.h:208
bool IsSpellProhibited(SpellSchoolMask idSchoolMask) const
Definition Creature.cpp:2846
Definition GameObject.h:120
GameObjectTemplate const * GetGOInfo() const
Definition GameObject.h:136
Definition GroupReference.h:27
GroupReference * next()
Definition GroupReference.h:36
Definition Group.h:169
Definition InstanceScript.h:143
bool IsLocked() const
Definition Item.h:253
ItemTemplate const * GetTemplate() const
Definition Item.cpp:544
bool IsPotion() const
Definition Item.h:337
bool IsDungeon() const
Definition Map.h:295
bool IsBattlegroundOrArena() const
Definition Map.h:303
GameObject * GetGameObject(ObjectGuid const &guid)
Definition Map.cpp:2362
uint32 GetId() const
Definition Map.h:229
Difficulty GetDifficulty() const
Definition Map.h:290
uint64 GetRawValue() const
Definition ObjectGuid.h:142
bool IsPlayer() const
Definition ObjectGuid.h:168
bool IsGameObject() const
Definition ObjectGuid.h:171
Unit * ToUnit()
Definition Object.h:210
Definition PetDefines.h:212
Optional< PetInfo > CurrentPet
Definition PetDefines.h:235
std::vector< PetInfo > UnslottedPets
Definition PetDefines.h:238
Player * GetOwner() const
Definition Pet.cpp:2496
bool HaveInDiet(ItemTemplate const *item) const
Definition Pet.cpp:1442
uint32 GetCurrentFoodBenefitLevel(uint32 itemlevel) const
Definition Pet.cpp:1460
static std::pair< PetStable::PetInfo const *, PetSaveMode > GetLoadPetInfo(PetStable const &stable, uint32 petEntry, uint32 petnumber, bool current)
Definition Pet.cpp:171
void SetCanTeleport(bool value)
Definition Player.h:2502
bool IsInSameRaidWith(Player const *p) const
Definition Player.h:1881
bool CanTameExoticPets() const
Definition Player.h:2189
bool CanUseBattlegroundObject(GameObject *gameobject) const
Definition Player.cpp:13266
bool InBattleground() const
Definition Player.h:2256
PetStable * GetPetStable()
Definition Player.h:1208
Battleground * GetBattleground(bool create=false) const
Definition Player.cpp:12246
WorldSession * GetSession() const
Definition Player.h:1998
bool HasSpellCooldown(uint32 spell_id) const override
Definition Player.cpp:16360
uint32 GetLastPotionId()
Definition Player.h:1807
Group * GetGroup()
Definition Player.h:2472
bool IsGameMaster() const
Definition Player.h:1161
time_t GetSummonExpireTimer() const
Definition Player.h:1103
bool Satisfy(DungeonProgressionRequirements const *ar, uint32 target_map, bool report=false)
Definition PlayerStorage.cpp:6719
bool HasPlayerFlag(PlayerFlags flags) const
Definition Player.h:1110
std::unique_ptr< DuelInfo > duel
Definition Player.h:1873
Item * GetItemByGuid(ObjectGuid guid) const
Definition PlayerStorage.cpp:408
GameObject * GetGOTarget() const
Definition Spell.cpp:264
ObjectGuid GetItemTargetGUID() const
Definition Spell.h:148
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:2052
uint32 GetRecoveryTime() const
Definition SpellInfo.cpp:2408
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:1998
int32 AreaGroupId
Definition SpellInfo.h:391
float GetMaxRange(bool positive=false, Unit *caster=nullptr, Spell *spell=nullptr) const
Definition SpellInfo.cpp:2335
uint32 GetExplicitTargetMask() const
Definition SpellInfo.cpp:2066
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:1948
std::unique_ptr< PathGenerator > m_preGeneratedPath
Definition Spell.h:788
SpellCastResult CheckSpellFocus()
Definition Spell.cpp:7700
SpellCastResult CanOpenLock(uint32 effIndex, uint32 lockid, SkillType &skillid, int32 &reqSkillValue, int32 &skillValue)
Definition Spell.cpp:8313
SpellCastResult CheckItems()
Definition Spell.cpp:7117
int32 CalculateSpellDamage(uint8 i, Unit const *target) const
Definition Spell.h:488
SpellCastResult CheckPower()
Definition Spell.cpp:7072
SpellCastResult CheckCasterAuras(bool preventionOnly) const
Definition Spell.cpp:6789
SpellCastResult CallScriptCheckCastHandlers()
Definition Spell.cpp:8521
bool IsTriggered() const
Definition Spell.h:564
SpellCastResult CheckRange(bool strict)
Definition Spell.cpp:6986
bool HasGlobalCooldown() const
Definition Spell.cpp:8793
Definition TemporarySummon.h:40
uint32 GetSpell() const
Definition TradeData.h:49
bool IsVehicle() const
Definition Unit.h:783
Vehicle * GetVehicle() const
Definition Unit.h:1880
Unit * GetOwner() const
Definition Unit.cpp:10676
Pet * ToPet()
Definition Unit.h:714
virtual bool HasSpellCooldown(uint32) const
Definition Unit.h:1302
ShapeshiftForm GetShapeshiftForm() const
Definition Unit.h:1911
virtual bool HasSpellItemCooldown(uint32, uint32) const
Definition Unit.h:1303
bool IsInDisallowedMountForm() const
Definition Unit.cpp:21143
void CombatStart(Unit *target, bool initialAggro=true)
Definition Unit.cpp:13707
bool HasUnitFlag2(UnitFlags2 flags) const
Definition Unit.h:738
bool IsInSanctuary() const
Definition Unit.h:1021
virtual bool IsClass(Classes unitClass, ClassContext context=CLASS_CONTEXT_NONE) const
Definition Unit.h:827
AuraEffect * IsScriptOverriden(SpellInfo const *spell, int32 script) const
Definition Unit.cpp:5900
float GetCombatReach() const override
Definition Unit.h:860
UnitFlags GetUnitFlags() const
Definition Unit.h:731
TempSummon * ToTempSummon()
Definition Unit.h:716
bool HasStealthAura() const
Definition Unit.h:1796
bool HasAura(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemCasterGUID=ObjectGuid::Empty, uint8 reqEffMask=0) const
Definition Unit.cpp:5789
std::map< uint8, AuraApplication * > VisibleAuraMap
Definition Unit.h:672
bool IsInFlight() const
Definition Unit.h:1660
SpellImmuneList m_spellImmune[MAX_SPELL_IMMUNITY]
Definition Unit.h:2047
void SendTameFailure(uint8 result)
Definition Unit.cpp:19758
void GetDispellableAuraList(Unit *caster, uint32 dispelMask, DispelChargesList &dispelList, SpellInfo const *dispelSpell)
Definition Unit.cpp:5673
bool HasUnitMovementFlag(uint32 f) const
Definition Unit.h:759
virtual bool IsInWater() const
Definition Unit.cpp:4407
bool HasAuraState(AuraStateType flag, SpellInfo const *spellProto=nullptr, Unit const *Caster=nullptr) const
Definition Unit.cpp:10623
bool isMoving() const
Definition Unit.h:1663
ObjectGuid GetCharmGUID() const
Definition Unit.h:706
VisibleAuraMap const * GetVisibleAuras()
Definition Unit.h:1498
bool IsMounted() const
Definition Unit.h:1841
Unit * GetVictim() const
Definition Unit.h:886
bool IsCritter() const
Definition Unit.h:816
ObjectGuid GetOwnerGUID() const
Definition Unit.h:698
uint8 GetComboPoints(Unit const *who=nullptr) const
Definition Unit.h:992
ObjectGuid GetCharmerGUID() const
Definition Unit.h:704
uint32 getTransForm() const
Definition Unit.h:1922
virtual bool HasActivePowerType(Powers power)
Definition Unit.h:1094
void RemoveMovementImpairingAuras(bool withRoot)
Definition Unit.cpp:5302
bool IsTotem() const
Definition Unit.h:782
Guardian * GetGuardianPet() const
Definition Unit.cpp:10727
ObjectGuid GetTarget() const
Definition Unit.h:844
bool IsInCombat() const
Definition Unit.h:917
ObjectGuid GetPetGUID() const
Definition Unit.h:708
Definition Vehicle.h:28
VehicleSeatEntry const * GetSeatForPassenger(Unit const *passenger)
Definition Vehicle.cpp:600
uint32 GetMapId() const
Definition Position.h:281
Map * GetMap() const
Definition Object.h:621
InstanceScript * GetInstanceScript() const
Definition Object.cpp:1221
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:1380
bool IsOutdoors() const
Definition Object.cpp:3088
bool IsWithinLOS(float x, float y, float z, VMAP::ModelIgnoreFlags ignoreFlags=VMAP::ModelIgnoreFlags::Nothing, LineOfSightChecks checks=LINEOFSIGHT_ALL_CHECKS) const
Definition Object.cpp:1359
float GetVisibilityRange() const
Definition Object.cpp:1678
uint32 GetAreaId() const
Definition Object.cpp:3071
uint32 GetZoneId() const
Definition Object.cpp:3063
void GetZoneAndAreaId(uint32 &zoneid, uint32 &areaid) const
Definition Object.cpp:3079
uint32 GetRecruiterId() const
Definition WorldSession.h:588
uint32 GetAccountId() const
Definition WorldSession.h:423
Seconds GetGameTime()
Definition GameTime.cpp:38
Player * FindPlayer(ObjectGuid const guid)
Definition ObjectAccessor.cpp:245
Definition DBCStructure.h:519
Definition ConditionMgr.h:183
Condition * mLastFailedCondition
Definition ConditionMgr.h:185
WorldObject * mConditionTargets[MAX_CONDITION_TARGETS]
Definition ConditionMgr.h:184
uint32 ErrorType
Definition ConditionMgr.h:206
uint8 ConditionTarget
Definition ConditionMgr.h:210
uint32 ErrorTextId
Definition ConditionMgr.h:207
SkillType GetRequiredLootSkill() const
Definition CreatureData.h:257
bool IsTameable(bool exotic) const
Definition CreatureData.h:274
uint32 type
Definition GameObjectData.h:33
Definition DBCStructure.h:1022
Definition Map.h:121
bool AllowMount
Definition Map.h:124
uint32 ItemLevel
Definition ItemTemplate.h:635
uint32 LockID
Definition ItemTemplate.h:669
uint32 InventoryType
Definition ItemTemplate.h:632
bool isLooted() const
Definition LootMgr.h:368
Definition DBCStructure.h:1326
bool IsDungeon() const
Definition DBCStructure.h:1352
void GetPosition(float &x, float &y) const
Definition Position.h:126
Definition DBCStructure.h:1818
uint32 flags1
Definition DBCStructure.h:1823
Definition DBCStructure.h:1910
uint32 Category
Definition DBCStructure.h:1912
Definition DBCStructure.h:2065
uint32 m_flags
Definition DBCStructure.h:2067

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, Unit::CastSpell(), 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(), Unit::GetDispellableAuraList(), 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(), 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, sDisableMgr, Unit::SendTameFailure(), sGlyphPropertiesStore, SHAPESHIFT_FLAG_STANCE, 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
6790{
6791 // spells totally immuned to caster auras (wsg flag drop, give marks etc)
6793 return SPELL_CAST_OK;
6794
6795 uint8 school_immune = 0;
6796 uint32 mechanic_immune = 0;
6797 uint32 dispel_immune = 0;
6798
6799 // Check if the spell grants school or mechanic immunity.
6800 // We use bitmasks so the loop is done only once and not on every aura check below.
6802 {
6803 for (int i = 0; i < MAX_SPELL_EFFECTS; ++i)
6804 {
6805 if (m_spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_SCHOOL_IMMUNITY)
6806 school_immune |= uint32(m_spellInfo->Effects[i].MiscValue);
6807 else if (m_spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_MECHANIC_IMMUNITY)
6808 mechanic_immune |= 1 << uint32(m_spellInfo->Effects[i].MiscValue);
6809 else if (m_spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_DISPEL_IMMUNITY)
6810 dispel_immune |= SpellInfo::GetDispelMask(DispelType(m_spellInfo->Effects[i].MiscValue));
6811 }
6812 // immune movement impairment and loss of control
6813 // PVP trinket EMFH TOC PVP trinket Bullheaded Bestial Wrath // Beath Within // Medalion of Immunity
6814 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)
6816 }
6817
6819
6820 // Glyph of Pain Suppression
6821 // there is no other way to handle it
6822 if (m_spellInfo->Id == 33206 && !m_caster->HasAura(63248))
6823 usableInStun = false;
6824
6825 // Check whether the cast should be prevented by any state you might have.
6826 SpellCastResult prevented_reason = SPELL_CAST_OK;
6827 // Have to check if there is a stun aura. Otherwise will have problems with ghost aura apply while logging out
6828 uint32 unitflag = m_caster->GetUnitFlags(); // Get unit state
6829
6830 // Xinef: if spell is triggered check preventionType only
6831 if (!preventionOnly)
6832 {
6833 if (unitflag & UNIT_FLAG_STUNNED)
6834 {
6835 // spell is usable while stunned, check if caster has only mechanic stun auras, another stun types must prevent cast spell
6836 if (usableInStun)
6837 {
6838 bool foundNotStun = false;
6839 uint32 mask = (1 << MECHANIC_STUN) | (1 << MECHANIC_FREEZE) | (1 << MECHANIC_HORROR);
6840 // Barkskin should skip sleep effects, sap and fears
6841 if (m_spellInfo->Id == 22812)
6842 mask |= 1 << MECHANIC_SAPPED | 1 << MECHANIC_HORROR | 1 << MECHANIC_SLEEP;
6843 // Hand of Freedom, can be used while sapped
6844 if (m_spellInfo->Id == 1044)
6845 mask |= 1 << MECHANIC_SAPPED;
6847 for (Unit::AuraEffectList::const_iterator i = stunAuras.begin(); i != stunAuras.end(); ++i)
6848 {
6849 if ((*i)->GetSpellInfo()->GetAllEffectsMechanicMask() && !((*i)->GetSpellInfo()->GetAllEffectsMechanicMask() & mask))
6850 {
6851 foundNotStun = true;
6852 break;
6853 }
6854 }
6855 if (foundNotStun)
6856 prevented_reason = SPELL_FAILED_STUNNED;
6857 }
6858 else
6859 prevented_reason = SPELL_FAILED_STUNNED;
6860 }
6862 prevented_reason = SPELL_FAILED_CONFUSED;
6864 prevented_reason = SPELL_FAILED_FLEEING;
6865 }
6866
6867 // Xinef: if there is no prevented_reason, check prevention types
6868 if (prevented_reason == SPELL_CAST_OK)
6869 {
6871 prevented_reason = SPELL_FAILED_SILENCED;
6873 prevented_reason = SPELL_FAILED_PACIFIED;
6874 }
6875
6876 // Attr must make flag drop spell totally immune from all effects
6877 if (prevented_reason != SPELL_CAST_OK)
6878 {
6879 if (school_immune || mechanic_immune || dispel_immune)
6880 {
6881 //Checking auras is needed now, because you are prevented by some state but the spell grants immunity.
6883 for (Unit::AuraApplicationMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
6884 {
6885 Aura const* aura = itr->second->GetBase();
6886 SpellInfo const* auraInfo = aura->GetSpellInfo();
6887 if (auraInfo->GetAllEffectsMechanicMask() & mechanic_immune)
6888 continue;
6889 if (auraInfo->GetSchoolMask() & school_immune && !auraInfo->HasAttribute(SPELL_ATTR1_IMMUNITY_TO_HOSTILE_AND_FRIENDLY_EFFECTS))
6890 continue;
6891 if (auraInfo->GetDispelMask() & dispel_immune)
6892 continue;
6893
6894 //Make a second check for spell failed so the right SPELL_FAILED message is returned.
6895 //That is needed when your casting is prevented by multiple states and you are only immune to some of them.
6896 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
6897 {
6898 if (AuraEffect* part = aura->GetEffect(i))
6899 {
6900 switch (part->GetAuraType())
6901 {
6903 {
6904 uint32 mask = 1 << MECHANIC_STUN;
6905 // Barkskin should skip sleep effects, sap and fears
6906 if (m_spellInfo->Id == 22812)
6907 mask |= 1 << MECHANIC_SAPPED | 1 << MECHANIC_HORROR | 1 << MECHANIC_SLEEP;
6908 // Hand of Freedom, can be used while sapped
6909 if (m_spellInfo->Id == 1044)
6910 mask |= 1 << MECHANIC_SAPPED;
6911
6912 if (!usableInStun || !(auraInfo->GetAllEffectsMechanicMask() & mask))
6913 return SPELL_FAILED_STUNNED;
6914 break;
6915 }
6918 return SPELL_FAILED_CONFUSED;
6919 break;
6922 return SPELL_FAILED_FLEEING;
6923 break;
6928 return SPELL_FAILED_PACIFIED;
6930 return SPELL_FAILED_SILENCED;
6931 break;
6932 default:
6933 break;
6934 }
6935 }
6936 }
6937 }
6938 }
6939 // You are prevented from casting and the spell casted does not grant immunity. Return a failed error.
6940 else
6941 return prevented_reason;
6942 }
6943 return SPELL_CAST_OK;
6944}
@ SPELL_PREVENTION_TYPE_SILENCE
Definition SharedDefines.h:1565
@ SPELL_PREVENTION_TYPE_PACIFY
Definition SharedDefines.h:1566
@ SPELL_ATTR5_ALLOW_WHILE_STUNNED
Definition SharedDefines.h:581
@ SPELL_ATTR5_ALLOW_WHILE_FLEEING
Definition SharedDefines.h:595
@ SPELL_ATTR5_ALLOW_WHILE_CONFUSED
Definition SharedDefines.h:596
@ SPELL_ATTR1_IMMUNITY_PURGES_EFFECT
Definition SharedDefines.h:445
@ SPELL_ATTR1_IMMUNITY_TO_HOSTILE_AND_FRIENDLY_EFFECTS
Definition SharedDefines.h:446
@ MECHANIC_STUN
Definition SharedDefines.h:1348
@ MECHANIC_FREEZE
Definition SharedDefines.h:1349
@ MECHANIC_SLEEP
Definition SharedDefines.h:1346
@ MECHANIC_SAPPED
Definition SharedDefines.h:1366
@ MECHANIC_HORROR
Definition SharedDefines.h:1360
#define IMMUNE_TO_MOVEMENT_IMPAIRMENT_AND_LOSS_CONTROL_MASK
Definition SharedDefines.h:1372
@ SPELL_FAILED_STUNNED
Definition SharedDefines.h:1068
@ SPELL_FAILED_CONFUSED
Definition SharedDefines.h:986
@ SPELL_FAILED_SILENCED
Definition SharedDefines.h:1064
@ SPELL_FAILED_FLEEING
Definition SharedDefines.h:994
@ SPELL_FAILED_PACIFIED
Definition SharedDefines.h:1058
@ SPELL_ATTR6_NOT_AN_ATTACK
Definition SharedDefines.h:617
@ 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:272
@ UNIT_FLAG_PACIFIED
Definition UnitDefines.h:271
@ UNIT_FLAG_CONFUSED
Definition UnitDefines.h:276
@ UNIT_FLAG_FLEEING
Definition UnitDefines.h:277
@ UNIT_FLAG_SILENCED
Definition UnitDefines.h:267
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:2003
std::multimap< uint32, AuraApplication * > AuraApplicationMap
Definition Unit.h:659
AuraApplicationMap & GetAppliedAuras()
Definition Unit.h:1346

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
8455{
8456 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
8458}
#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
7878{
7879 switch (m_spellInfo->Effects[eff].ApplyAuraName)
7880 {
7885 if (target->IsCreature() && target->IsVehicle())
7886 return false;
7887 if (target->IsMounted())
7888 return false;
7889 if (target->GetCharmerGUID())
7890 return false;
7891 if (int32 damage = CalculateSpellDamage(eff, target))
7892 if ((int32)target->GetLevel() > damage)
7893 return false;
7894 break;
7895 default:
7896 break;
7897 }
7898
7899 // xinef: skip los checking if spell has appropriate attribute, or target requires specific entry
7900 // 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
7901 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)))
7902 return true;
7903
7904 // if spell is triggered, need to check for LOS disable on the aura triggering it and inherit that behaviour
7907 {
7908 return true;
7909 }
7910
7912 //Check targets for LOS visibility (except spells without range limitations)
7913 switch (m_spellInfo->Effects[eff].Effect)
7914 {
7916 // player far away, maybe his corpse near?
7917 if (target != m_caster && !target->IsWithinLOSInMap(m_caster))
7918 {
7920 return false;
7921
7923 if (!corpse)
7924 return false;
7925
7926 if (target->GetGUID() != corpse->GetOwnerGUID())
7927 return false;
7928
7930 return false;
7931 }
7932 break;
7934 {
7936 {
7937 if (target->IsWithinLOSInMap(m_caster, VMAP::ModelIgnoreFlags::M2) && target->HasUnitFlag(UNIT_FLAG_SKINNABLE))
7938 return true;
7939
7940 return false;
7941 }
7942
7944 if (!corpse)
7945 return false;
7946
7947 if (target->GetGUID() != corpse->GetOwnerGUID())
7948 return false;
7949
7951 return false;
7952
7954 return false;
7955 }
7956 break;
7958 if (!m_caster->IsPlayer() || !target->IsPlayer())
7959 return false;
7960 if (m_caster->ToPlayer()->GetSession()->IsARecruiter() && target->ToPlayer()->GetSession()->GetRecruiterId() != m_caster->ToPlayer()->GetSession()->GetAccountId())
7961 return false;
7962 if (m_caster->ToPlayer()->GetSession()->GetRecruiterId() != target->ToPlayer()->GetSession()->GetAccountId() && target->ToPlayer()->GetSession()->IsARecruiter())
7963 return false;
7964 if (target->ToPlayer()->GetLevel() >= sWorld->getIntConfig(CONFIG_MAX_RECRUIT_A_FRIEND_BONUS_PLAYER_LEVEL))
7965 return false;
7966 break;
7967 default: // normal case
7968 {
7969 uint32 losChecks = LINEOFSIGHT_ALL_CHECKS;
7970 GameObject* gobCaster = nullptr;
7972 {
7974 }
7975 else if (m_caster->GetEntry() == WORLD_TRIGGER)
7976 {
7977 if (TempSummon* tempSummon = m_caster->ToTempSummon())
7978 {
7979 gobCaster = tempSummon->GetSummonerGameObject();
7980 }
7981 }
7982
7983 if (gobCaster)
7984 {
7985 if (gobCaster->GetGOInfo()->IsIgnoringLOSChecks())
7986 {
7987 return true;
7988 }
7989
7990 // If spell casted by gameobject then ignore M2 models
7991 losChecks &= ~LINEOFSIGHT_CHECK_GOBJECT_M2;
7992 }
7993
7994 if (target != m_caster)
7995 {
7996 if (m_targets.HasDst())
7997 {
7998 float x = m_targets.GetDstPos()->GetPositionX();
7999 float y = m_targets.GetDstPos()->GetPositionY();
8000 float z = m_targets.GetDstPos()->GetPositionZ();
8001
8002 if (!target->IsWithinLOS(x, y, z, VMAP::ModelIgnoreFlags::M2, LineOfSightChecks(losChecks)))
8003 {
8004 return false;
8005 }
8006 }
8008 {
8009 return false;
8010 }
8011 }
8012 break;
8013 }
8014 }
8015
8016 return true;
8017}
@ CORPSE_FLAG_LOOTABLE
Definition Corpse.h:45
@ SPELL_DISABLE_LOS
Definition DisableMgr.h:50
@ DISABLE_TYPE_SPELL
Definition DisableMgr.h:28
@ SPELL_EFFECT_SKIN_PLAYER_CORPSE
Definition SharedDefines.h:905
@ TARGET_CHECK_ENTRY
Definition SpellInfo.h:115
@ UNIT_FLAG_NOT_SELECTABLE
Definition UnitDefines.h:279
@ CORPSE_FIELD_FLAGS
Definition UpdateFields.h:427
@ CONFIG_MAX_RECRUIT_A_FRIEND_BONUS_PLAYER_LEVEL
Definition WorldConfig.h:200
Definition Corpse.h:49
ObjectGuid GetOwnerGUID() const
Definition Corpse.h:68
bool HasFlag(uint16 index, uint32 flag) const
Definition Object.cpp:878
ObjectGuid GetCorpseTargetGUID() const
Definition Spell.cpp:281
bool IsARecruiter() const
Definition WorldSession.h:589
#define sWorld
Definition World.h:316
Corpse * GetCorpse(WorldObject const &u, ObjectGuid const &guid)
Definition ObjectAccessor.cpp:179
bool IsIgnoringLOSChecks() const
Definition GameObjectData.h:644

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(), 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, sDisableMgr, 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.
7118{
7119 Player* player = m_caster->ToPlayer();
7120 if (!player)
7121 {
7122 // Non-player case: Check if creature is disarmed
7124 {
7126 }
7127
7128 return SPELL_CAST_OK;
7129 }
7130
7131 if (!m_CastItem)
7132 {
7133 if (m_castItemGUID)
7135 }
7136 else
7137 {
7138 uint32 itemid = m_CastItem->GetEntry();
7139 if (!player->HasItemCount(itemid))
7141
7142 ItemTemplate const* proto = m_CastItem->GetTemplate();
7143 if (!proto)
7145
7146 for (int i = 0; i < MAX_ITEM_SPELLS; ++i)
7147 if (proto->Spells[i].SpellCharges)
7148 if (m_CastItem->GetSpellCharges(i) == 0)
7150
7151 // consumable cast item checks
7153 {
7154 // such items should only fail if there is no suitable effect at all - see Rejuvenation Potions for example
7155 SpellCastResult failReason = SPELL_CAST_OK;
7156 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; i++)
7157 {
7158 // skip check, pet not required like checks, and for TARGET_UNIT_PET m_targets.GetUnitTarget() is not the real target but the caster
7159 if (m_spellInfo->Effects[i].TargetA.GetTarget() == TARGET_UNIT_PET)
7160 continue;
7161
7162 if (m_spellInfo->Effects[i].Effect == SPELL_EFFECT_HEAL)
7163 {
7165 {
7167 continue;
7168 }
7169 else
7170 {
7171 failReason = SPELL_CAST_OK;
7172 break;
7173 }
7174 }
7175
7176 // Mana Potion, Rage Potion, Thistle Tea(Rogue), ...
7177 if (m_spellInfo->Effects[i].Effect == SPELL_EFFECT_ENERGIZE)
7178 {
7179 if (m_spellInfo->Effects[i].MiscValue < 0 || m_spellInfo->Effects[i].MiscValue >= int8(MAX_POWERS))
7180 {
7182 continue;
7183 }
7184
7185 Powers power = Powers(m_spellInfo->Effects[i].MiscValue);
7187 {
7189 continue;
7190 }
7191 else
7192 {
7193 failReason = SPELL_CAST_OK;
7194 break;
7195 }
7196 }
7197 }
7198 if (failReason != SPELL_CAST_OK)
7199 return failReason;
7200 }
7201 }
7202
7203 // check target item
7205 {
7206 if (!m_caster->IsPlayer())
7208
7209 if (!m_targets.GetItemTarget())
7211
7214 }
7215 // if not item target then required item must be equipped
7216 else
7217 {
7218 // Xinef: this is not true in my opinion, in eg bladestorm will not be canceled after disarm
7219 //if (!HasTriggeredCastFlag(TRIGGERED_IGNORE_EQUIPPED_ITEM_REQUIREMENT))
7222 }
7223
7224 // do not take reagents for these item casts
7226 {
7228 // Not own traded item (in trader trade slot) requires reagents even if triggered spell
7229 if (!checkReagents)
7230 if (Item* targetItem = m_targets.GetItemTarget())
7231 if (targetItem->GetOwnerGUID() != m_caster->GetGUID())
7232 checkReagents = true;
7233
7234 // check reagents (ignore triggered spells with reagents processed by original spell) and special reagent ignore case.
7235 if (checkReagents)
7236 {
7237 for (uint32 i = 0; i < MAX_SPELL_REAGENTS; i++)
7238 {
7239 if (m_spellInfo->Reagent[i] <= 0)
7240 continue;
7241
7242 uint32 itemid = m_spellInfo->Reagent[i];
7243 uint32 itemcount = m_spellInfo->ReagentCount[i];
7244
7245 // if CastItem is also spell reagent
7246 if (m_CastItem && m_CastItem->GetEntry() == itemid)
7247 {
7248 ItemTemplate const* proto = m_CastItem->GetTemplate();
7249 if (!proto)
7251 for (int s = 0; s < MAX_ITEM_PROTO_SPELLS; ++s)
7252 {
7253 // CastItem will be used up and does not count as reagent
7254 int32 charges = m_CastItem->GetSpellCharges(s);
7255 if (proto->Spells[s].SpellCharges < 0 && std::abs(charges) < 2)
7256 {
7257 ++itemcount;
7258 break;
7259 }
7260 }
7261 }
7262 if (!player->HasItemCount(itemid, itemcount))
7263 return SPELL_FAILED_REAGENTS;
7264 }
7265 }
7266
7267 // check totem-item requirements (items presence in inventory)
7268 uint32 totems = 2;
7269 for (int i = 0; i < 2; ++i)
7270 {
7271 if (m_spellInfo->Totem[i] != 0)
7272 {
7273 if (player->HasItemCount(m_spellInfo->Totem[i]))
7274 {
7275 totems -= 1;
7276 continue;
7277 }
7278 }
7279 else
7280 totems -= 1;
7281 }
7282 if (totems != 0)
7283 return SPELL_FAILED_TOTEMS; //0x7C
7284
7285 // Check items for TotemCategory (items presence in inventory)
7287 for (int i = 0; i < 2; ++i)
7288 {
7289 if (m_spellInfo->TotemCategory[i] != 0)
7290 {
7292 {
7293 TotemCategory -= 1;
7294 continue;
7295 }
7296 }
7297 else
7298 TotemCategory -= 1;
7299 }
7300 if (TotemCategory != 0)
7301 return SPELL_FAILED_TOTEM_CATEGORY; //0x7B
7302 }
7303
7304 // special checks for spell effects
7305 for (int i = 0; i < MAX_SPELL_EFFECTS; i++)
7306 {
7307 switch (m_spellInfo->Effects[i].Effect)
7308 {
7311 {
7312 // m_targets.GetUnitTarget() means explicit cast, otherwise we dont check for possible equip error
7313 Unit* target = m_targets.GetUnitTarget() ? m_targets.GetUnitTarget() : player;
7314 if (target->IsPlayer() && !IsTriggered())
7315 {
7316 // 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,
7317 // so we need to make sure there is at least one free space in the player's inventory
7319 if (target->ToPlayer()->GetFreeInventorySpace() == 0)
7320 {
7321 player->SendEquipError(EQUIP_ERR_INVENTORY_FULL, nullptr, nullptr, m_spellInfo->Effects[i].ItemType);
7323 }
7324
7325 if (m_spellInfo->Effects[i].ItemType)
7326 {
7327 ItemTemplate const* itemTemplate = sObjectMgr->GetItemTemplate(m_spellInfo->Effects[i].ItemType);
7328 if (!itemTemplate)
7330
7331 uint32 createCount = std::clamp<uint32>(m_spellInfo->Effects[i].CalcValue(), 1u, itemTemplate->GetMaxStackSize());
7332 ItemPosCountVec dest;
7333 InventoryResult msg = target->ToPlayer()->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, m_spellInfo->Effects[i].ItemType, createCount);
7334 if (msg != EQUIP_ERR_OK)
7335 {
7337 if (!itemTemplate->ItemLimitCategory)
7338 {
7339 player->SendEquipError(msg, nullptr, nullptr, m_spellInfo->Effects[i].ItemType);
7341 }
7342 else
7343 {
7344 // Conjure Food/Water/Refreshment spells
7347 else if (!(target->ToPlayer()->HasItemCount(m_spellInfo->Effects[i].ItemType)))
7348 {
7349 player->SendEquipError(msg, nullptr, nullptr, m_spellInfo->Effects[i].ItemType);
7351 }
7352 else
7353 player->CastSpell(player, m_spellInfo->Effects[EFFECT_1].CalcValue(), false); // move this to anywhere
7354
7356 }
7357 }
7358 }
7359 }
7360 break;
7361 }
7363 {
7364 if (player->GetFreeInventorySpace() == 0)
7365 {
7366 player->SendEquipError(EQUIP_ERR_INVENTORY_FULL, nullptr, nullptr, m_spellInfo->Effects[i].ItemType);
7368 }
7369 break;
7370 }
7372 if (m_spellInfo->Effects[i].ItemType && m_targets.GetItemTarget()
7374 {
7375 // cannot enchant vellum for other player
7378 // do not allow to enchant vellum from scroll made by vellum-prevent exploit
7381 ItemPosCountVec dest;
7382 InventoryResult msg = player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, m_spellInfo->Effects[i].ItemType, 1);
7383 if (msg != EQUIP_ERR_OK)
7384 {
7385 player->SendEquipError(msg, nullptr, nullptr, m_spellInfo->Effects[i].ItemType);
7387 }
7388 }
7389 [[fallthrough]];
7391 {
7392 Item* targetItem = m_targets.GetItemTarget();
7393 if (!targetItem)
7395
7396 // Apply item level restriction
7398 {
7399 uint32 requiredLevel = targetItem->GetTemplate()->RequiredLevel;
7400 if (!requiredLevel)
7401 requiredLevel = targetItem->GetTemplate()->ItemLevel;
7402
7403 if (requiredLevel < m_spellInfo->BaseLevel)
7404 return SPELL_FAILED_LOWLEVEL;
7405 }
7406
7407 if (m_CastItem && m_spellInfo->MaxLevel > 0 && targetItem->GetTemplate()->ItemLevel > m_spellInfo->MaxLevel)
7409
7410 bool isItemUsable = false;
7411 for (uint8 e = 0; e < MAX_ITEM_PROTO_SPELLS; ++e)
7412 {
7413 ItemTemplate const* proto = targetItem->GetTemplate();
7414 if (proto->Spells[e].SpellId && (
7417 {
7418 isItemUsable = true;
7419 break;
7420 }
7421 }
7422
7423 SpellItemEnchantmentEntry const* enchantEntry = sSpellItemEnchantmentStore.LookupEntry(m_spellInfo->Effects[i].MiscValue);
7424 // do not allow adding usable enchantments to items that have use effect already
7425 if (enchantEntry)
7426 {
7427 for (uint8 s = 0; s < MAX_SPELL_ITEM_ENCHANTMENT_EFFECTS; ++s)
7428 {
7429 switch (enchantEntry->type[s])
7430 {
7432 if (isItemUsable)
7434 break;
7436 {
7437 uint32 numSockets = 0;
7438 for (uint32 socket = 0; socket < MAX_ITEM_PROTO_SOCKETS; ++socket)
7439 if (targetItem->GetTemplate()->Socket[socket].Color)
7440 ++numSockets;
7441
7442 if (numSockets == MAX_ITEM_PROTO_SOCKETS || targetItem->GetEnchantmentId(PRISMATIC_ENCHANTMENT_SLOT))
7444 break;
7445 }
7446 }
7447 }
7448 }
7449
7450 // Not allow enchant in trade slot for some enchant type
7451 if (targetItem->GetOwner() != m_caster)
7452 {
7453 if (!enchantEntry)
7454 return SPELL_FAILED_ERROR;
7455 if (enchantEntry->slot & ENCHANTMENT_CAN_SOULBOUND)
7457 }
7458 break;
7459 }
7461 {
7462 Item* item = m_targets.GetItemTarget();
7463 if (!item)
7465 // Not allow enchant in trade slot for some enchant type
7466 if (item->GetOwner() != m_caster)
7467 {
7468 uint32 enchant_id = m_spellInfo->Effects[i].MiscValue;
7469 SpellItemEnchantmentEntry const* pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id);
7470 if (!pEnchant)
7471 return SPELL_FAILED_ERROR;
7472 if (pEnchant->slot & ENCHANTMENT_CAN_SOULBOUND)
7474 }
7475
7476 // Apply item level restriction
7478 {
7479 uint32 requiredLevel = item->GetTemplate()->RequiredLevel;
7480 if (!requiredLevel)
7481 requiredLevel = item->GetTemplate()->ItemLevel;
7482
7483 if (requiredLevel < m_spellInfo->BaseLevel)
7484 return SPELL_FAILED_LOWLEVEL;
7485 }
7486
7489
7490 break;
7491 }
7493 // check item existence in effect code (not output errors at offhand hold item effect to main hand for example
7494 break;
7496 {
7497 if (!m_targets.GetItemTarget())
7499
7500 // prevent disenchanting in trade slot
7503
7504 ItemTemplate const* itemProto = m_targets.GetItemTarget()->GetTemplate();
7505 if (!itemProto)
7507
7508 uint32 item_quality = itemProto->Quality;
7509 // 2.0.x addon: Check player enchanting level against the item disenchanting requirements
7510 uint32 item_disenchantskilllevel = itemProto->RequiredDisenchantSkill;
7511 if (item_disenchantskilllevel == uint32(-1))
7513 if (item_disenchantskilllevel > player->GetSkillValue(SKILL_ENCHANTING))
7515 if (item_quality > 4 || item_quality < 2)
7517 if (itemProto->Class != ITEM_CLASS_WEAPON && itemProto->Class != ITEM_CLASS_ARMOR)
7519 if (!itemProto->DisenchantID)
7521 break;
7522 }
7524 {
7525 if (!m_targets.GetItemTarget())
7527 //ensure item is a prospectable ore
7530 //prevent prospecting in trade slot
7533 //Check for enough skill in jewelcrafting
7534 uint32 item_prospectingskilllevel = m_targets.GetItemTarget()->GetTemplate()->RequiredSkillRank;
7535 if (item_prospectingskilllevel > player->GetSkillValue(SKILL_JEWELCRAFTING))
7537 //make sure the player has the required ores in inventory
7538 if (m_targets.GetItemTarget()->GetCount() < 5)
7540
7543
7544 break;
7545 }
7547 {
7548 if (!m_targets.GetItemTarget())
7550 //ensure item is a millable herb
7553 //prevent milling in trade slot
7556 //Check for enough skill in inscription
7557 uint32 item_millingskilllevel = m_targets.GetItemTarget()->GetTemplate()->RequiredSkillRank;
7558 if (item_millingskilllevel > player->GetSkillValue(SKILL_INSCRIPTION))
7560 //make sure the player has the required herbs in inventory
7561 if (m_targets.GetItemTarget()->GetCount() < 5)
7563
7566
7567 break;
7568 }
7571 {
7572 if (!m_caster->IsPlayer())
7574
7576 break;
7577
7579 if (!pItem || pItem->IsBroken())
7581
7582 switch (pItem->GetTemplate()->SubClass)
7583 {
7585 {
7586 uint32 ammo = pItem->GetEntry();
7587 if (!m_caster->ToPlayer()->HasItemCount(ammo))
7588 return SPELL_FAILED_NO_AMMO;
7589 };
7590 break;
7594 {
7596 if (!ammo)
7597 {
7598 // Requires No Ammo
7599 if (m_caster->HasAura(46699))
7600 break; // skip other checks
7601
7602 return SPELL_FAILED_NO_AMMO;
7603 }
7604
7605 ItemTemplate const* ammoProto = sObjectMgr->GetItemTemplate(ammo);
7606 if (!ammoProto)
7607 return SPELL_FAILED_NO_AMMO;
7608
7609 if (ammoProto->Class != ITEM_CLASS_PROJECTILE)
7610 return SPELL_FAILED_NO_AMMO;
7611
7612 // check ammo ws. weapon compatibility
7613 switch (pItem->GetTemplate()->SubClass)
7614 {
7617 if (ammoProto->SubClass != ITEM_SUBCLASS_ARROW)
7618 return SPELL_FAILED_NO_AMMO;
7619 break;
7621 if (ammoProto->SubClass != ITEM_SUBCLASS_BULLET)
7622 return SPELL_FAILED_NO_AMMO;
7623 break;
7624 default:
7625 return SPELL_FAILED_NO_AMMO;
7626 }
7627
7628 if (!m_caster->ToPlayer()->HasItemCount(ammo))
7629 {
7631 return SPELL_FAILED_NO_AMMO;
7632 }
7633 };
7634 break;
7636 break;
7637 default:
7638 break;
7639 }
7640 break;
7641 }
7643 {
7644 uint32 item_id = m_spellInfo->Effects[i].ItemType;
7645 ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(item_id);
7646
7647 if (!pProto)
7649
7650 if (Item* pitem = player->GetItemByEntry(item_id))
7651 {
7652 for (int x = 0; x < MAX_ITEM_PROTO_SPELLS; ++x)
7653 if (pProto->Spells[x].SpellCharges != 0 && pitem->GetSpellCharges(x) == pProto->Spells[x].SpellCharges)
7655 }
7656 break;
7657 }
7658 default:
7659 break;
7660 }
7661 }
7662
7663 // check weapon presence in slots for main/offhand weapons
7664 if (/*never skip those checks !HasTriggeredCastFlag(TRIGGERED_IGNORE_EQUIPPED_ITEM_REQUIREMENT) &&*/ m_spellInfo->EquippedItemClass >= 0)
7665 {
7666 // main hand weapon required
7668 {
7670
7671 // skip spell if no weapon in slot or broken
7672 if (!item || item->IsBroken())
7674
7675 // skip spell if weapon not fit to triggered spell
7678 }
7679
7680 // offhand hand weapon required
7682 {
7684
7685 // skip spell if no weapon in slot or broken
7686 if (!item || item->IsBroken())
7688
7689 // skip spell if weapon not fit to triggered spell
7692 }
7693
7695 }
7696
7697 return SPELL_CAST_OK;
7698}
@ ITEM_ENCHANTMENT_TYPE_USE_SPELL
Definition DBCEnums.h:373
@ ITEM_ENCHANTMENT_TYPE_PRISMATIC_SOCKET
Definition DBCEnums.h:374
DBCStorage< SpellItemEnchantmentEntry > sSpellItemEnchantmentStore(SpellItemEnchantmentfmt)
#define MAX_SPELL_REAGENTS
Definition DBCStructure.h:1640
#define MAX_SPELL_ITEM_ENCHANTMENT_EFFECTS
Definition DBCStructure.h:1839
std::int8_t int8
Definition Define.h:105
@ 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
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
LootStore LootTemplates_Milling("milling_loot_template", "item entry (herb)", true)
LootStore LootTemplates_Prospecting("prospecting_loot_template", "item entry (ore)", true)
std::vector< ItemPosCount > ItemPosCountVec
Definition Player.h:766
@ EFFECT_1
Definition SharedDefines.h:32
@ MAX_POWERS
Definition SharedDefines.h:287
@ SPELL_EFFECT_DISENCHANT
Definition SharedDefines.h:888
@ SPELL_EFFECT_PROSPECTING
Definition SharedDefines.h:916
@ SPELL_EFFECT_ENCHANT_HELD_ITEM
Definition SharedDefines.h:881
@ SPELL_EFFECT_ENCHANT_ITEM
Definition SharedDefines.h:842
@ SPELL_EFFECT_WEAPON_DAMAGE
Definition SharedDefines.h:847
@ SPELL_EFFECT_HEAL
Definition SharedDefines.h:799
@ SPELL_EFFECT_MILLING
Definition SharedDefines.h:947
@ SPELL_EFFECT_CREATE_MANA_GEM
Definition SharedDefines.h:855
@ SPELL_EFFECT_CREATE_ITEM_2
Definition SharedDefines.h:946
@ SPELL_EFFECT_WEAPON_DAMAGE_NOSCHOOL
Definition SharedDefines.h:806
@ SPELL_EFFECT_ENERGIZE
Definition SharedDefines.h:819
@ SPELL_EFFECT_CREATE_RANDOM_ITEM
Definition SharedDefines.h:848
@ SPELL_EFFECT_ENCHANT_ITEM_PRISMATIC
Definition SharedDefines.h:945
@ SPELL_EFFECT_ENCHANT_ITEM_TEMPORARY
Definition SharedDefines.h:843
@ SPELL_EFFECT_CREATE_ITEM
Definition SharedDefines.h:813
@ SPELL_ATTR2_ALLOW_LOW_LEVEL_BUFF
Definition SharedDefines.h:470
@ SPELL_ATTR3_REQUIRES_MAIN_HAND_WEAPON
Definition SharedDefines.h:514
@ SPELLFAMILY_MAGE
Definition SharedDefines.h:3797
TotemCategory
Definition SharedDefines.h:3333
@ SPELL_FAILED_CANT_BE_MILLED
Definition SharedDefines.h:976
@ SPELL_FAILED_EQUIPPED_ITEM_CLASS_OFFHAND
Definition SharedDefines.h:991
@ SPELL_FAILED_EQUIPPED_ITEM_CLASS
Definition SharedDefines.h:989
@ SPELL_FAILED_ITEM_AT_MAX_CHARGES
Definition SharedDefines.h:1139
@ SPELL_FAILED_TARGET_NOT_PLAYER
Definition SharedDefines.h:1082
@ SPELL_FAILED_ALREADY_AT_FULL_POWER
Definition SharedDefines.h:964
@ SPELL_FAILED_NOT_TRADEABLE
Definition SharedDefines.h:1030
@ SPELL_FAILED_ITEM_NOT_READY
Definition SharedDefines.h:1005
@ SPELL_FAILED_NO_CHARGES_REMAIN
Definition SharedDefines.h:1036
@ SPELL_FAILED_ITEM_GONE
Definition SharedDefines.h:1003
@ SPELL_FAILED_NO_AMMO
Definition SharedDefines.h:1035
@ SPELL_FAILED_ITEM_NOT_FOUND
Definition SharedDefines.h:1004
@ SPELL_FAILED_EQUIPPED_ITEM
Definition SharedDefines.h:988
@ SPELL_FAILED_ALREADY_AT_FULL_HEALTH
Definition SharedDefines.h:962
@ SPELL_FAILED_ON_USE_ENCHANT
Definition SharedDefines.h:1130
@ SPELL_FAILED_TOTEMS
Definition SharedDefines.h:1091
@ SPELL_FAILED_ERROR
Definition SharedDefines.h:992
@ SPELL_FAILED_REAGENTS
Definition SharedDefines.h:1060
@ SPELL_FAILED_MAX_SOCKETS
Definition SharedDefines.h:1144
@ SPELL_FAILED_CANT_BE_DISENCHANTED
Definition SharedDefines.h:974
@ SPELL_FAILED_TOO_MANY_OF_ITEM
Definition SharedDefines.h:1089
@ SPELL_FAILED_NEED_MORE_ITEMS
Definition SharedDefines.h:1015
@ SPELL_FAILED_CANT_BE_PROSPECTED
Definition SharedDefines.h:977
@ SPELL_FAILED_EQUIPPED_ITEM_CLASS_MAINHAND
Definition SharedDefines.h:990
@ SPELL_FAILED_TOTEM_CATEGORY
Definition SharedDefines.h:1090
@ SKILL_INSCRIPTION
Definition SharedDefines.h:3252
@ SKILL_ENCHANTING
Definition SharedDefines.h:3204
@ SKILL_JEWELCRAFTING
Definition SharedDefines.h:3235
@ PLAYER_AMMO_ID
Definition UpdateFields.h:369
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
bool HaveLootFor(uint32 loot_id) const
Definition LootMgr.h:224
uint32 GetUInt32Value(uint16 index) const
Definition Object.cpp:294
bool HasItemFitToSpellRequirements(SpellInfo const *spellInfo, Item const *ignoreItem=nullptr) const
Definition Player.cpp:12568
uint32 GetFreeInventorySpace() const
Definition PlayerStorage.cpp:467
Item * GetItemByEntry(uint32 entry) const
Definition PlayerStorage.cpp:3368
bool HasItemCount(uint32 item, uint32 count=1, bool inBankAlso=false) const
Definition PlayerStorage.cpp:656
bool HasItemTotemCategory(uint32 TotemCategory) const
Definition PlayerStorage.cpp:852
bool CanNoReagentCast(SpellInfo const *spellInfo) const
Definition Player.cpp:12613
void SendEquipError(InventoryResult msg, Item *pItem, Item *pItem2=nullptr, uint32 itemid=0)
Definition PlayerStorage.cpp:4020
InventoryResult CanStoreNewItem(uint8 bag, uint8 slot, ItemPosCountVec &dest, uint32 item, uint32 count, uint32 *no_space_count=nullptr) const
Definition Player.h:1280
uint32 GetItemTargetEntry() const
Definition Spell.h:150
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
ObjectGuid m_castItemGUID
Definition Spell.h:534
bool IsFullHealth() const
Definition Unit.h:1076
bool CanUseAttackType(WeaponAttackType attacktype) const
Definition Unit.h:970
uint32 GetMaxPower(Powers power) const
Definition Unit.h:1098
void SetUInt32Value(uint16 index, uint32 value)
Definition Unit.cpp:21198
uint32 GetPower(Powers power) const
Definition Unit.h:1097
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:727
_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:825
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
Definition DBCStructure.h:1842
uint32 type[MAX_SPELL_ITEM_ENCHANTMENT_EFFECTS]
Definition DBCStructure.h:1845
uint32 slot
Definition DBCStructure.h:1852
uint32 Color
Definition ItemTemplate.h:602
int32 SpellCharges
Definition ItemTemplate.h:593
uint32 SpellTrigger
Definition ItemTemplate.h:592
int32 SpellId
Definition ItemTemplate.h:591

References BASE_ATTACK, 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_ATTR2_ALLOW_LOW_LEVEL_BUFF, 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)
6754{
6755 if (m_caster->HasUnitState(UNIT_STATE_CASTING) && !HasTriggeredCastFlag(TRIGGERED_IGNORE_CAST_IN_PROGRESS)) //prevent spellcast interruption by another spellcast
6757
6758 // dead owner (pets still alive when owners ressed?)
6759 if (Unit* owner = m_caster->GetCharmerOrOwner())
6760 if (!owner->IsAlive() && m_caster->GetEntry() != 30230) // Rise Ally
6762
6763 if (!target && m_targets.GetUnitTarget())
6764 target = m_targets.GetUnitTarget();
6765
6767 {
6768 if (!target)
6770 m_targets.SetUnitTarget(target);
6771 }
6772
6773 // xinef: Calculate power cost here, so funciton checking power can work properly and dont return bad results
6775
6776 // cooldown
6777 if (Creature const* creatureCaster = m_caster->ToCreature())
6778 if (creatureCaster->HasSpellCooldown(m_spellInfo->Id))
6780
6781 // Check if spell is affected by GCD
6785
6786 return CheckCast(true);
6787}
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:2413
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 ( )
7073{
7074 // item cast not used power
7075 if (m_CastItem)
7076 return SPELL_CAST_OK;
7077
7078 //While .cheat power is enabled dont check if we need power to cast the spell
7079 if (m_caster->IsPlayer())
7080 {
7082 {
7083 return SPELL_CAST_OK;
7084 }
7085 }
7086
7087 // health as power used - need check health amount
7089 {
7092 return SPELL_CAST_OK;
7093 }
7094 // Check valid power type
7096 {
7097 LOG_ERROR("spells", "Spell::CheckPower: Unknown power type '{}'", m_spellInfo->PowerType);
7098 return SPELL_FAILED_UNKNOWN;
7099 }
7100
7101 //check rune cost only if a spell has PowerType == POWER_RUNE
7103 {
7105 if (failReason != SPELL_CAST_OK)
7106 return failReason;
7107 }
7108
7109 // Check power amount
7112 return SPELL_FAILED_NO_POWER;
7113 else
7114 return SPELL_CAST_OK;
7115}
@ CHEAT_POWER
Definition Player.h:997
@ POWER_HEALTH
Definition SharedDefines.h:289
@ POWER_RUNE
Definition SharedDefines.h:285
@ SPELL_FAILED_NO_POWER
Definition SharedDefines.h:1045
@ SPELL_FAILED_UNKNOWN
Definition SharedDefines.h:1147
PowerType
Definition VehicleDefines.h:29
uint32 RuneCostID
Definition SpellInfo.h:368
uint32 PowerType
Definition SpellInfo.h:362
SpellCastResult CheckRuneCost(uint32 RuneCostID)
Definition Spell.cpp:5347
uint32 GetHealth() const
Definition Unit.h:1070

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)
6987{
6988 // Don't check for instant cast spells
6989 if (!strict && m_casttime == 0)
6990 return SPELL_CAST_OK;
6991
6992 uint32 range_type = 0;
6993
6995 {
6996 // check needed by 68766 51693 - both spells are cast on enemies and have 0 max range
6997 // these are triggered by other spells - possibly we should omit range check in that case?
6998 if (m_spellInfo->RangeEntry->ID == 1)
6999 return SPELL_CAST_OK;
7000
7001 range_type = m_spellInfo->RangeEntry->Flags;
7002 }
7003
7004 Unit* target = m_targets.GetUnitTarget();
7005 float max_range = m_caster->GetSpellMaxRangeForTarget(target, m_spellInfo);
7006 float min_range = m_caster->GetSpellMinRangeForTarget(target, m_spellInfo);
7007
7008 // xinef: hack for npc shooters
7009 if (min_range && GetCaster()->IsCreature() && !GetCaster()->GetOwnerGUID().IsPlayer() && min_range <= 6.0f)
7010 range_type = SPELL_RANGE_RANGED;
7011
7012 if (Player* modOwner = m_caster->GetSpellModOwner())
7013 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_RANGE, max_range, this);
7014
7015 // xinef: dont check max_range to strictly after cast
7016 if (range_type != SPELL_RANGE_MELEE && !strict)
7017 max_range += std::min(3.0f, max_range * 0.1f); // 10% but no more than 3yd
7018
7019 if (target)
7020 {
7021 if (target != m_caster)
7022 {
7023 // Xinef: Spells with 5yd range can hit target 9yd away?
7024 if (range_type == SPELL_RANGE_MELEE)
7025 {
7026 float real_max_range = max_range;
7028 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)
7029 else
7030 real_max_range -= 2 * MIN_MELEE_REACH;
7031
7032 if (!m_caster->IsWithinMeleeRange(target, std::max(real_max_range, 0.0f)))
7034 }
7035 else if (!m_caster->IsWithinCombatRange(target, max_range))
7036 return SPELL_FAILED_OUT_OF_RANGE; //0x5A;
7037
7039 {
7040 if (m_caster->IsWithinMeleeRange(target))
7042 }
7043
7044 if (m_caster->IsPlayer() && (m_spellInfo->FacingCasterFlags & SPELL_FACING_FLAG_INFRONT) && !m_caster->HasInArc(static_cast<float>(M_PI), target) && !m_caster->IsWithinBoundaryRadius(target))
7046 }
7047
7048 // Xinef: check min range for self casts
7049 if (min_range && range_type != SPELL_RANGE_RANGED && m_caster->IsWithinCombatRange(target, min_range)) // skip this check if min_range = 0
7051 }
7052
7053 if (GameObject* goTarget = m_targets.GetGOTarget())
7054 {
7055 if (!goTarget->IsAtInteractDistance(m_caster->ToPlayer(), m_spellInfo))
7056 {
7058 }
7059 }
7060
7061 if (m_targets.HasDst() && !m_targets.HasTraj())
7062 {
7063 if (!m_caster->IsWithinDist3d(m_targets.GetDstPos(), max_range))
7065 if (min_range && m_caster->IsWithinDist3d(m_targets.GetDstPos(), min_range))
7067 }
7068
7069 return SPELL_CAST_OK;
7070}
#define MIN_MELEE_REACH
Definition ObjectDefines.h:46
@ SPELL_FAILED_TOO_CLOSE
Definition SharedDefines.h:1088
@ SPELL_FAILED_OUT_OF_RANGE
Definition SharedDefines.h:1057
@ SPELLMOD_RANGE
Definition SpellDefines.h:81
@ SPELL_FACING_FLAG_INFRONT
Definition SpellDefines.h:128
@ SPELL_RANGE_MELEE
Definition Spell.h:92
@ SPELL_RANGE_RANGED
Definition Spell.h:93
SpellRangeEntry const * RangeEntry
Definition SpellInfo.h:369
uint32 FacingCasterFlags
Definition SpellInfo.h:338
Unit * GetCaster() const
Definition Spell.h:585
bool IsWithinBoundaryRadius(const Unit *obj) const
Definition Unit.cpp:704
bool IsWithinCombatRange(Unit const *obj, float dist2compare) const
Definition Unit.cpp:649
float GetSpellMinRangeForTarget(Unit const *target, SpellInfo const *spellInfo) const
Definition Unit.cpp:15196
bool IsWithinMeleeRange(Unit const *obj, float dist=0.f) const
Definition Unit.cpp:665
float GetSpellMaxRangeForTarget(Unit const *target, SpellInfo const *spellInfo) const
Definition Unit.cpp:15176
bool HasLeewayMovement() const
Definition Unit.h:1684
bool IsWithinDist3d(float x, float y, float z, float dist) const
Definition Object.cpp:1328
bool HasInArc(float arcangle, const Position *pos, float targetRadius=0.0f) const
Definition Position.cpp:148
uint32 Flags
Definition DBCStructure.h:1798
uint32 ID
Definition DBCStructure.h:1795

References SpellInfo::DmgClass, SpellInfo::FacingCasterFlags, SpellRangeEntry::Flags, GetCaster(), SpellCastTargets::GetDstPos(), SpellCastTargets::GetGOTarget(), Unit::GetSpellMaxRangeForTarget(), Unit::GetSpellMinRangeForTarget(), Unit::GetSpellModOwner(), SpellCastTargets::GetUnitTarget(), SpellCastTargets::HasDst(), Position::HasInArc(), Unit::HasLeewayMovement(), SpellCastTargets::HasTraj(), SpellInfo::Id, SpellRangeEntry::ID, Object::IsCreature(), Object::IsPlayer(), Unit::IsWithinBoundaryRadius(), 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)
5348{
5349 if (m_spellInfo->PowerType != POWER_RUNE || !RuneCostID)
5350 return SPELL_CAST_OK;
5351
5352 if (!m_caster->IsPlayer())
5353 return SPELL_CAST_OK;
5354
5355 Player* player = m_caster->ToPlayer();
5356 //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)
5357 if (player->GetCommandStatus(CHEAT_POWER))
5358 {
5359 return SPELL_CAST_OK;
5360 }
5361
5363 return SPELL_CAST_OK;
5364
5365 SpellRuneCostEntry const* src = sSpellRuneCostStore.LookupEntry(RuneCostID);
5366
5367 if (!src)
5368 return SPELL_CAST_OK;
5369
5370 if (src->NoRuneCost())
5371 return SPELL_CAST_OK;
5372
5373 int32 runeCost[NUM_RUNE_TYPES]; // blood, frost, unholy, death
5374
5375 for (uint32 i = 0; i < RUNE_DEATH; ++i)
5376 {
5377 runeCost[i] = src->RuneCost[i];
5378 if (Player* modOwner = m_caster->GetSpellModOwner())
5379 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_COST, runeCost[i], this);
5380 }
5381
5382 runeCost[RUNE_DEATH] = MAX_RUNES; // calculated later
5383
5384 for (uint32 i = 0; i < MAX_RUNES; ++i)
5385 {
5386 RuneType rune = player->GetCurrentRune(i);
5387 if ((player->GetRuneCooldown(i) == 0) && (runeCost[rune] > 0))
5388 runeCost[rune]--;
5389 }
5390
5391 for (uint32 i = 0; i < RUNE_DEATH; ++i)
5392 if (runeCost[i] > 0)
5393 runeCost[RUNE_DEATH] += runeCost[i];
5394
5395 if (runeCost[RUNE_DEATH] > MAX_RUNES)
5396 return SPELL_FAILED_NO_POWER; // not sure if result code is correct
5397
5398 return SPELL_CAST_OK;
5399}
DBCStorage< SpellRuneCostEntry > sSpellRuneCostStore(SpellRuneCostfmt)
RuneType
Definition Player.h:404
@ RUNE_DEATH
Definition Player.h:408
@ NUM_RUNE_TYPES
Definition Player.h:409
#define MAX_RUNES
Definition Player.h:394
@ CLASS_DEATH_KNIGHT
Definition SharedDefines.h:146
@ SPELLMOD_COST
Definition SpellDefines.h:90
@ CLASS_CONTEXT_ABILITY
Definition UnitDefines.h:238
uint32 GetRuneCooldown(uint8 index) const
Definition Player.h:2512
bool IsClass(Classes playerClass, ClassContext context=CLASS_CONTEXT_NONE) const override
Definition Player.cpp:1299
RuneType GetCurrentRune(uint8 index) const
Definition Player.h:2511
Definition DBCStructure.h:1806
uint32 RuneCost[3]
Definition DBCStructure.h:1808
bool NoRuneCost() const
Definition DBCStructure.h:1811

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
8676{
8677 // Skip if there are not any script
8678 if (!m_loadedScripts.size())
8679 return true;
8680
8681 for (std::list<SpellScript*>::iterator itr = m_loadedScripts.begin(); itr != m_loadedScripts.end(); ++itr)
8682 {
8683 std::list<SpellScript::ObjectTargetSelectHandler>::iterator targetSelectHookEnd = (*itr)->OnObjectTargetSelect.end(), targetSelectHookItr = (*itr)->OnObjectTargetSelect.begin();
8684 for (; targetSelectHookItr != targetSelectHookEnd; ++targetSelectHookItr)
8685 if (((*targetSelectHookItr).IsEffectAffected(m_spellInfo, effIndex) && !(*targetSelectHookItr).IsEffectAffected(m_spellInfo, effIndexToCheck)) ||
8686 (!(*targetSelectHookItr).IsEffectAffected(m_spellInfo, effIndex) && (*targetSelectHookItr).IsEffectAffected(m_spellInfo, effIndexToCheck)))
8687 return false;
8688
8689 std::list<SpellScript::ObjectAreaTargetSelectHandler>::iterator areaTargetSelectHookEnd = (*itr)->OnObjectAreaTargetSelect.end(), areaTargetSelectHookItr = (*itr)->OnObjectAreaTargetSelect.begin();
8690 for (; areaTargetSelectHookItr != areaTargetSelectHookEnd; ++areaTargetSelectHookItr)
8691 if (((*areaTargetSelectHookItr).IsEffectAffected(m_spellInfo, effIndex) && !(*areaTargetSelectHookItr).IsEffectAffected(m_spellInfo, effIndexToCheck)) ||
8692 (!(*areaTargetSelectHookItr).IsEffectAffected(m_spellInfo, effIndex) && (*areaTargetSelectHookItr).IsEffectAffected(m_spellInfo, effIndexToCheck)))
8693 return false;
8694 }
8695 return true;
8696}

References m_loadedScripts, and m_spellInfo.

Referenced by SelectEffectImplicitTargets().

◆ CheckSpellFocus()

SpellCastResult Spell::CheckSpellFocus ( )
7701{
7702 // check spell focus object
7704 {
7706 Cell cell(p);
7707
7708 GameObject* ok = nullptr;
7711
7713 Map& map = *m_caster->GetMap();
7714 cell.Visit(p, object_checker, map, *m_caster, m_caster->GetVisibilityRange());
7715
7716 if (!ok)
7718
7719 focusObject = ok; // game object found in range
7720 }
7721 return SPELL_CAST_OK;
7722}
@ SPELL_FAILED_REQUIRES_SPELL_FOCUS
Definition SharedDefines.h:1062
Definition GridNotifiers.h:648
Definition Map.h:163
void Visit(const Cell &cell, TypeContainerVisitor< T, CONTAINER > &visitor)
Definition Map.h:700
uint32 RequiresSpellFocus
Definition SpellInfo.h:337
Definition TypeContainerVisitor.h:105
Definition TypeContainer.h:118
CellCoord ComputeCellCoord(float x, float y)
Definition GridDefines.h:197
Definition GridNotifiers.h:310
Definition Cell.h:45

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:174
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 ( )
2283{
2284 m_UniqueTargetInfo.clear();
2285 m_UniqueGOTargetInfo.clear();
2286 m_UniqueItemInfo.clear();
2287 m_delayMoment = 0;
2289}
uint64 m_delayTrajectory
Definition Spell.h:652

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 ( )
7725{
7726 if (!m_caster)// || !m_caster->IsPlayer())
7727 return;
7728
7729 //if (m_spellState == SPELL_STATE_DELAYED)
7730 // return; // spell is active and can't be time-backed
7731
7732 if (isDelayableNoMore()) // Spells may only be delayed twice
7733 return;
7734
7736 return;
7737
7738 // spells not loosing casting time (slam, dynamites, bombs..)
7739 //if (!(m_spellInfo->InterruptFlags & SPELL_INTERRUPT_FLAG_DAMAGE))
7740 // return;
7741
7742 //check pushback reduce
7743 int32 delaytime = 500; // spellcasting delay is normally 500ms
7744 int32 delayReduce = 100; // must be initialized to 100 for percent modifiers
7747 if (delayReduce >= 100)
7748 return;
7749
7750 AddPct(delaytime, -delayReduce);
7751
7752 if (m_timer + delaytime > m_casttime)
7753 {
7754 delaytime = m_casttime - m_timer;
7756 }
7757 else
7758 m_timer += delaytime;
7759
7760 LOG_DEBUG("spells", "Spell {} partially interrupted for ({}) ms at damage", m_spellInfo->Id, delaytime);
7761
7762 WorldPacket data(SMSG_SPELL_DELAYED, 8 + 4);
7763 data << m_caster->GetPackGUID();
7764 data << uint32(delaytime);
7765
7766 m_caster->SendMessageToSet(&data, true);
7767}
#define LOG_DEBUG(filterType__,...)
Definition Log.h:170
@ SPELL_ATTR6_NO_PUSHBACK
Definition SharedDefines.h:630
@ SPELL_AURA_REDUCE_PUSHBACK
Definition SpellAuraDefines.h:212
@ SPELLMOD_NOT_LOSE_CASTING_TIME
Definition SpellDefines.h:85
T AddPct(T &base, U pct)
Definition Util.h:67
PackedGuid const & GetPackGUID() const
Definition Object.h:115
void ApplySpellMod(uint32 spellId, SpellModOp op, T &basevalue, Spell *spell=nullptr, bool temporaryPet=false)
Definition Player.cpp:9813
bool isDelayableNoMore()
Definition Spell.h:640
int32 GetTotalAuraModifier(AuraType auratype) const
Definition Unit.cpp:6009
virtual void SendMessageToSet(WorldPacket const *data, bool self) const
Definition Object.cpp:2090
Definition WorldPacket.h:26
@ SMSG_SPELL_DELAYED
Definition Opcodes.h:512

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 ( )
7770{
7772 return;
7773
7774 if (isDelayableNoMore()) // Spells may only be delayed twice
7775 return;
7776
7778 return;
7779
7780 //check pushback reduce
7781 // should be affected by modifiers, not take the dbc duration.
7782 int32 duration = ((m_channeledDuration > 0) ? m_channeledDuration : m_spellInfo->GetDuration());
7783
7784 int32 delaytime = CalculatePct(duration, 25); // channeling delay is normally 25% of its time per hit
7785 int32 delayReduce = 100; // must be initialized to 100 for percent modifiers
7788 if (delayReduce >= 100)
7789 return;
7790
7791 AddPct(delaytime, -delayReduce);
7792
7793 if (m_timer <= delaytime)
7794 {
7795 delaytime = m_timer;
7796 m_timer = 0;
7797 }
7798 else
7799 m_timer -= delaytime;
7800
7801 LOG_DEBUG("spells.aura", "Spell {} partially interrupted for {} ms, new duration: {} ms", m_spellInfo->Id, delaytime, m_timer);
7802
7803 for (std::list<TargetInfo>::const_iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
7804 if ((*ihit).missCondition == SPELL_MISS_NONE)
7805 if (Unit* unit = (m_caster->GetGUID() == ihit->targetGUID) ? m_caster : ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID))
7806 unit->DelayOwnedAuras(m_spellInfo->Id, m_originalCasterGUID, delaytime);
7807
7808 // partially interrupt persistent area auras
7810 dynObj->Delay(delaytime);
7811
7813}
T CalculatePct(T base, U pct)
Definition Util.h:61
Definition DynamicObject.h:35
uint32 getState() const
Definition Spell.h:493
DynamicObject * GetDynObject(uint32 spellId)
Definition Unit.cpp:6227

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
8253{
8254 Unit* unit = nullptr;
8255 // In case spell hit target, do all effect on that target
8256 if (targetInfo.missCondition == SPELL_MISS_NONE)
8257 unit = m_caster->GetGUID() == targetInfo.targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, targetInfo.targetGUID);
8258 // In case spell reflect from target, do all effect on caster (if hit)
8259 else if (targetInfo.missCondition == SPELL_MISS_REFLECT && targetInfo.reflectResult == SPELL_MISS_NONE)
8260 unit = m_caster;
8261 if (!unit)
8262 return;
8263
8264 for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i)
8265 {
8266 if (targetInfo.effectMask & (1 << i))
8267 {
8268 m_damage = 0;
8269 m_healing = 0;
8270
8271 HandleEffects(unit, nullptr, nullptr, i, SPELL_EFFECT_HANDLE_LAUNCH_TARGET);
8272
8273 if (m_damage > 0)
8274 {
8275 // Xinef: Area Auras, AoE Targetting spells AND Chain Target spells (cleave etc.)
8276 if (m_spellInfo->Effects[i].IsAreaAuraEffect() || m_spellInfo->Effects[i].IsTargetingArea() || (m_spellInfo->Effects[i].ChainTarget > 1 && m_spellInfo->DmgClass != SPELL_DAMAGE_CLASS_MAGIC))
8277 {
8280 if (m_caster->IsPlayer())
8281 {
8282 uint32 targetAmount = m_UniqueTargetInfo.size();
8283 if (targetAmount > 10)
8284 m_damage = m_damage * 10 / targetAmount;
8285 }
8286 }
8287 }
8288
8289 if (m_applyMultiplierMask & (1 << i))
8290 {
8292 m_damageMultipliers[i] *= multiplier[i];
8293 }
8294 targetInfo.damage += m_damage;
8295 }
8296 }
8297
8298 // xinef: totem's inherit owner crit chance and dancing rune weapon
8299 Unit* caster = m_caster;
8300 if (m_caster->IsTotem() || m_caster->GetEntry() == 27893)
8301 {
8302 if (Unit* owner = m_caster->GetOwner())
8303 caster = owner;
8304 }
8305 else if (m_originalCaster)
8306 caster = m_originalCaster;
8307
8308 float critChance = caster->SpellDoneCritChance(unit, m_spellInfo, m_spellSchoolMask, m_attackType, false);
8309 critChance = unit->SpellTakenCritChance(caster, m_spellInfo, m_spellSchoolMask, critChance, m_attackType, false);
8310 targetInfo.crit = roll_chance_f(std::max(0.0f, critChance));
8311}
bool roll_chance_f(float chance)
Definition Random.h:57
@ SPELL_ATTR7_TREAT_AS_NPC_AOE
Definition SharedDefines.h:678
uint32 SchoolMask
Definition SpellInfo.h:392
float SpellTakenCritChance(Unit const *caster, SpellInfo const *spellProto, SpellSchoolMask schoolMask, float doneChance, WeaponAttackType attackType, bool skipEffectCheck) const
Definition Unit.cpp:12147
float SpellDoneCritChance(Unit const *, SpellInfo const *spellProto, SpellSchoolMask schoolMask, WeaponAttackType attackType, bool skipEffectCheck) const
Definition Unit.cpp:12072
int32 CalculateAOEDamageReduction(int32 damage, uint32 schoolMask, bool npcCaster) const
Definition Unit.cpp:20153

References Unit::CalculateAOEDamageReduction(), TargetInfo::crit, TargetInfo::damage, SpellInfo::DmgClass, TargetInfo::effectMask, SpellInfo::Effects, Object::GetEntry(), Object::GetGUID(), Unit::GetOwner(), GetSpellInfo(), ObjectAccessor::GetUnit(), HandleEffects(), SpellInfo::HasAttribute(), Unit::IsControlledByPlayer(), 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_ATTR7_TREAT_AS_NPC_AOE, 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
3257{
3258 if (target->processed) // Check target
3259 return;
3260 target->processed = true; // Target checked in apply effects procedure
3261
3262 uint32 effectMask = target->effectMask;
3263 if (!effectMask)
3264 return;
3265
3266 GameObject* go = m_caster->GetMap()->GetGameObject(target->targetGUID);
3267 if (!go)
3268 return;
3269
3272
3273 for (uint32 effectNumber = 0; effectNumber < MAX_SPELL_EFFECTS; ++effectNumber)
3274 if (effectMask & (1 << effectNumber))
3275 HandleEffects(nullptr, nullptr, go, effectNumber, SPELL_EFFECT_HANDLE_HIT_TARGET);
3276
3277 // xinef: inform ai about spellhit
3279
3281
3283}
virtual void SpellHit(Unit *, SpellInfo const *)
Definition GameObjectAI.h:66
GameObjectAI * AI() const
Definition GameObject.h:305
void CallScriptBeforeHitHandlers(SpellMissInfo missInfo)
Definition Spell.cpp:8594
void CallScriptOnHitHandlers()
Definition Spell.cpp:8607
void CallScriptAfterHitHandlers()
Definition Spell.cpp:8620

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
3286{
3287 uint32 effectMask = target->effectMask;
3288 if (!target->item || !effectMask)
3289 return;
3290
3293
3294 for (uint32 effectNumber = 0; effectNumber < MAX_SPELL_EFFECTS; ++effectNumber)
3295 if (effectMask & (1 << effectNumber))
3296 HandleEffects(nullptr, target->item, nullptr, effectNumber, SPELL_EFFECT_HANDLE_HIT_TARGET);
3297
3299
3301}

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
2521{
2522 if (!target || target->processed)
2523 return;
2524
2525 target->processed = true; // Target checked in apply effects procedure
2526
2527 // Get mask of effects for target
2528 uint8 mask = target->effectMask;
2529
2530 Unit* effectUnit = m_caster->GetGUID() == target->targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, target->targetGUID);
2531 if (!effectUnit && !target->targetGUID.IsPlayer()) // only players may be targeted across maps
2532 return;
2533
2534 if (!effectUnit || m_spellInfo->Id == 45927)
2535 {
2536 uint8 farMask = 0;
2537 // create far target mask
2538 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
2539 if (m_spellInfo->Effects[i].IsFarUnitTargetEffect())
2540 if ((1 << i) & mask)
2541 farMask |= (1 << i);
2542
2543 if (!farMask)
2544 return;
2545 // find unit in world
2546 // Xinef: FindUnit Access without Map check!!! Intended
2547 effectUnit = ObjectAccessor::FindPlayer(target->targetGUID);
2548 if (!effectUnit)
2549 return;
2550
2551 // do far effects on the unit
2552 // can't use default call because of threading, do stuff as fast as possible
2553 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
2554 if (farMask & (1 << i))
2555 HandleEffects(effectUnit, nullptr, nullptr, i, SPELL_EFFECT_HANDLE_HIT_TARGET);
2556 return;
2557 }
2558
2559 if (effectUnit->IsAlive() != target->alive)
2560 return;
2561
2562 // Xinef: absorb delayed projectiles for 500ms
2564 (GameTime::GetGameTimeMS().count() - target->timeDelay) <= effectUnit->m_lastSanctuaryTime && GameTime::GetGameTimeMS().count() < (effectUnit->m_lastSanctuaryTime + 500) &&
2565 effectUnit->FindMap() && !effectUnit->FindMap()->IsDungeon()
2566 )
2567 return; // No missinfo in that case
2568
2569 // Get original caster (if exist) and calculate damage/healing from him data
2571
2572 // Skip if m_originalCaster not avaiable
2573 if (!caster)
2574 return;
2575
2576 SpellMissInfo missInfo = target->missCondition;
2577
2578 // Need init unitTarget by default unit (can changed in code on reflect)
2579 // Or on missInfo != SPELL_MISS_NONE unitTarget undefined (but need in trigger subsystem)
2580 unitTarget = effectUnit;
2581
2582 // Reset damage/healing counter
2583 m_damage = target->damage;
2584 m_healing = -target->damage;
2585
2586 m_spellAura = nullptr; // Set aura to null for every target-make sure that pointer is not used for unit without aura applied
2587
2590
2591 //Spells with this flag cannot trigger if effect is casted on self
2593 bool reflectedSpell = missInfo == SPELL_MISS_REFLECT;
2594 Unit* spellHitTarget = nullptr;
2595
2596 if (missInfo == SPELL_MISS_NONE) // In case spell hit target, do all effect on that target
2597 spellHitTarget = unitTarget;
2598 else if (missInfo == SPELL_MISS_REFLECT) // In case spell reflect from target, do all effect on caster (if hit)
2599 {
2600 missInfo = target->reflectResult;
2601 if (missInfo == SPELL_MISS_NONE) // If reflected spell hit caster -> do all effect on him
2602 {
2603 spellHitTarget = m_caster;
2605 if (m_caster->IsCreature())
2607 }
2608 }
2609
2610 if (spellHitTarget)
2611 {
2612 SpellMissInfo missInfo2 = DoSpellHitOnUnit(spellHitTarget, mask, target->scaleAura);
2613 if (missInfo2 != SPELL_MISS_NONE)
2614 {
2615 if (missInfo2 != SPELL_MISS_MISS)
2616 m_caster->SendSpellMiss(spellHitTarget, m_spellInfo->Id, missInfo2);
2617 m_damage = 0;
2618 spellHitTarget = nullptr;
2619
2620 // Xinef: if missInfo2 is MISS_EVADE, override base missinfo data
2621 if (missInfo2 == SPELL_MISS_EVADE)
2622 missInfo = SPELL_MISS_EVADE;
2623 }
2624 }
2625
2626 // Do not take combo points on dodge and miss
2627 if (missInfo != SPELL_MISS_NONE && m_needComboPoints && m_targets.GetUnitTargetGUID() == target->targetGUID)
2628 {
2629 m_needComboPoints = false;
2630 // Restore spell mods for a miss/dodge/parry Cold Blood
2632 if (m_caster->IsPlayer() && (missInfo == SPELL_MISS_MISS || missInfo == SPELL_MISS_DODGE || missInfo == SPELL_MISS_PARRY))
2633 m_caster->ToPlayer()->RestoreSpellMods(this, 14177);
2634 }
2635
2636 // Fill base trigger info
2637 uint32 procAttacker = m_procAttacker;
2638 uint32 procVictim = m_procVictim;
2639 uint32 procEx = m_procEx;
2640
2641 // Trigger info was not filled in spell::preparedatafortriggersystem - we do it now
2642 if (canEffectTrigger && !procAttacker && !procVictim)
2643 {
2644 bool positive = true;
2645 if (m_damage > 0)
2646 positive = false;
2647 else if (!m_healing)
2648 {
2649 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
2650 // If at least one effect negative spell is negative hit
2651 // Xinef: if missInfo is immune state check all effects to properly determine positiveness of spell
2652 if ((missInfo == SPELL_MISS_IMMUNE2 || (mask & (1 << i))) && !m_spellInfo->IsPositiveEffect(i))
2653 {
2654 positive = false;
2655 break;
2656 }
2657 }
2658 switch (m_spellInfo->DmgClass)
2659 {
2661 if (positive)
2662 {
2665 }
2666 else
2667 {
2670 }
2671 break;
2673 if (positive)
2674 {
2677 }
2678 else
2679 {
2682 }
2683 break;
2684 }
2685 }
2687
2688 // All calculated do it!
2689 // Do healing and triggers
2690 if (m_healing > 0)
2691 {
2692 bool crit = target->crit;
2693 uint32 addhealth = m_healing;
2694
2695 if (crit)
2696 {
2697 procEx |= PROC_EX_CRITICAL_HIT;
2698 addhealth = Unit::SpellCriticalHealingBonus(caster, m_spellInfo, addhealth, nullptr);
2699 }
2700 else
2701 procEx |= PROC_EX_NORMAL_HIT;
2702
2703 HealInfo healInfo(caster, unitTarget, addhealth, m_spellInfo, m_spellInfo->GetSchoolMask());
2704
2705 // Xinef: override with forced crit, only visual result
2706 if (GetSpellValue()->ForcedCritResult)
2707 {
2708 crit = true;
2709 procEx |= PROC_EX_CRITICAL_HIT;
2710 }
2711
2712 int32 gain = caster->HealBySpell(healInfo, crit);
2713 float threat = float(gain) * 0.5f;
2714 if (caster->IsClass(CLASS_PALADIN))
2715 threat *= 0.5f;
2716
2718 m_healing = gain;
2719
2720 // Xinef: if heal acutally healed something, add no overheal flag
2721 if (m_healing)
2722 procEx |= PROC_EX_NO_OVERHEAL;
2723
2724 // Do triggers for unit (reflect triggers passed on hit phase for correct drop charge)
2725 if (canEffectTrigger)
2726 Unit::ProcDamageAndSpell(caster, unitTarget, procAttacker, procVictim, procEx, addhealth, m_attackType, m_spellInfo, m_triggeredByAuraSpell.spellInfo,
2727 m_triggeredByAuraSpell.effectIndex, this, nullptr, &healInfo);
2728 }
2729 // Do damage and triggers
2730 else if (m_damage > 0)
2731 {
2733
2734 // Fill base damage struct (unitTarget - is real spell target)
2736
2737 // Add bonuses and fill damageInfo struct
2738 // Dancing Rune Weapon...
2739 if (m_caster->GetEntry() == 27893)
2740 {
2741 if (Unit* owner = m_caster->GetOwner())
2742 owner->CalculateSpellDamageTaken(&damageInfo, m_damage, m_spellInfo, m_attackType, target->crit);
2743 }
2744 else
2745 caster->CalculateSpellDamageTaken(&damageInfo, m_damage, m_spellInfo, m_attackType, target->crit);
2746
2747 // xinef: override miss info after absorb / block calculations
2748 if (missInfo == SPELL_MISS_NONE && damageInfo.damage == 0)
2749 {
2750 //if (damageInfo.absorb > 0)
2751 // missInfo = SPELL_MISS_ABSORB;
2752 if (damageInfo.blocked)
2753 missInfo = SPELL_MISS_BLOCK;
2754 }
2755
2756 // Xinef: override with forced crit, only visual result
2757 if (GetSpellValue()->ForcedCritResult)
2758 {
2759 damageInfo.HitInfo |= SPELL_HIT_TYPE_CRIT;
2760 }
2761
2762 Unit::DealDamageMods(damageInfo.target, damageInfo.damage, &damageInfo.absorb);
2763
2764 // xinef: health leech handling
2766 {
2767 uint8 effIndex = EFFECT_0;
2768 for (; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
2769 if (m_spellInfo->Effects[effIndex].Effect == SPELL_EFFECT_HEALTH_LEECH)
2770 break;
2771
2772 float healMultiplier = m_spellInfo->Effects[effIndex].CalcValueMultiplier(m_originalCaster, this);
2773
2774 // get max possible damage, don't count overkill for heal
2775 uint32 healthGain = uint32(-unitTarget->GetHealthGain(-int32(damageInfo.damage)) * healMultiplier);
2776
2777 if (m_caster->IsAlive())
2778 {
2779 healthGain = m_caster->SpellHealingBonusDone(m_caster, m_spellInfo, healthGain, HEAL, effIndex);
2780 healthGain = m_caster->SpellHealingBonusTaken(m_caster, m_spellInfo, healthGain, HEAL);
2781
2782 HealInfo healInfo(m_caster, m_caster, healthGain, m_spellInfo, m_spellInfo->GetSchoolMask());
2783 m_caster->HealBySpell(healInfo);
2784 }
2785 }
2786
2787 // Send log damage message to client
2788 caster->SendSpellNonMeleeDamageLog(&damageInfo);
2789 // Xinef: send info to target about reflect
2790 if (reflectedSpell)
2791 effectUnit->SendSpellNonMeleeReflectLog(&damageInfo, effectUnit);
2792
2793 procEx |= createProcExtendMask(&damageInfo, missInfo);
2794 procVictim |= PROC_FLAG_TAKEN_DAMAGE;
2795
2796 caster->DealSpellDamage(&damageInfo, true, this);
2797
2798 // do procs after damage, eg healing effects
2799 // no need to check if target is alive, done in procdamageandspell
2800
2801 // Do triggers for unit (reflect triggers passed on hit phase for correct drop charge)
2802 if (canEffectTrigger)
2803 {
2804 DamageInfo dmgInfo(damageInfo, SPELL_DIRECT_DAMAGE);
2805 Unit::ProcDamageAndSpell(caster, unitTarget, procAttacker, procVictim, procEx, damageInfo.damage, m_attackType, m_spellInfo, m_triggeredByAuraSpell.spellInfo,
2806 m_triggeredByAuraSpell.effectIndex, this, &dmgInfo);
2807
2810 caster->ToPlayer()->CastItemCombatSpell(unitTarget, m_attackType, procVictim, procEx);
2811 }
2812
2813 m_damage = damageInfo.damage;
2814 }
2815 // Passive spell hits/misses or active spells only misses (only triggers)
2816 else
2817 {
2818 // Fill base damage struct (unitTarget - is real spell target)
2820 procEx |= createProcExtendMask(&damageInfo, missInfo);
2821 // Do triggers for unit (reflect triggers passed on hit phase for correct drop charge)
2822 if (canEffectTrigger)
2823 {
2824 DamageInfo dmgInfo(damageInfo, NODAMAGE);
2825 Unit::ProcDamageAndSpell(caster, unitTarget, procAttacker, procVictim, procEx, 0, m_attackType, m_spellInfo, m_triggeredByAuraSpell.spellInfo,
2826 m_triggeredByAuraSpell.effectIndex, this, &dmgInfo);
2827
2828 // Xinef: eg. rogue poisons can proc off cheap shot, etc. so this block should be here also
2829 // Xinef: ofc count only spells that HIT the target, little hack used to fool the system
2833 }
2834
2835 // Failed Pickpocket, reveal rogue
2837 {
2841 }
2842 }
2843
2844 if (m_caster)
2845 {
2847 {
2850
2851 // 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.
2852 if (effectUnit->IsInCombatWith(m_caster))
2853 {
2854 if (Creature* creature = effectUnit->ToCreature())
2855 {
2856 if (!creature->hasLootRecipient() && m_caster->IsPlayer())
2857 {
2858 creature->SetLootRecipient(m_caster);
2859 }
2860 }
2861 }
2862
2863 // Unsure if there are more spells that are not supposed to stop enemy from
2864 // regenerating HP from food, so for now it stays as an ID.
2865 const uint32 SPELL_PREMEDITATION = 14183;
2866 if (m_spellInfo->Id != SPELL_PREMEDITATION)
2867 {
2868 if (!effectUnit->IsStandState())
2869 {
2871 }
2872 }
2873 }
2874 }
2875
2876 if (missInfo != SPELL_MISS_EVADE && effectUnit != m_caster && m_caster->IsFriendlyTo(effectUnit) && m_spellInfo->IsPositive() &&
2878 {
2879 m_caster->SetInCombatWith(effectUnit);
2880 }
2881
2882 // Check for SPELL_ATTR7_CAN_CAUSE_INTERRUPT
2884 caster->CastSpell(effectUnit, SPELL_INTERRUPT_NONPLAYER, true);
2885
2886 if (spellHitTarget)
2887 {
2888 //AI functions
2889 if (spellHitTarget->IsCreature())
2890 {
2891 if (spellHitTarget->ToCreature()->IsAIEnabled)
2892 spellHitTarget->ToCreature()->AI()->SpellHit(m_caster, m_spellInfo);
2893 }
2894
2896 m_caster->ToCreature()->AI()->SpellHitTarget(spellHitTarget, m_spellInfo);
2897
2898 // Needs to be called after dealing damage/healing to not remove breaking on damage auras
2899 DoTriggersOnSpellHit(spellHitTarget, mask);
2900
2901 // if target is fallged for pvp also flag caster if a player
2902 // xinef: do not flag spells with aura bind sight (no special attribute)
2903 if (effectUnit->IsPvP() && effectUnit != m_caster && effectUnit->GetOwnerGUID() != m_caster->GetGUID() &&
2905 {
2906 m_caster->ToPlayer()->UpdatePvP(true);
2907 }
2908
2910 }
2911}
@ SPELL_EFFECT_HEALTH_LEECH
Definition SharedDefines.h:798
@ SPELL_ATTR1_NO_THREAT
Definition SharedDefines.h:440
@ SPELL_ATTR3_SUPPRESS_CASTER_PROCS
Definition SharedDefines.h:520
@ CLASS_PALADIN
Definition SharedDefines.h:142
@ SPELL_ATTR0_CANCELS_AUTO_ATTACK_COMBAT
Definition SharedDefines.h:413
@ SPELL_HIT_TYPE_CRIT
Definition SharedDefines.h:1547
SpellMissInfo
Definition SharedDefines.h:1529
@ SPELL_MISS_DODGE
Definition SharedDefines.h:1533
@ SPELL_MISS_IMMUNE2
Definition SharedDefines.h:1538
@ SPELL_MISS_RESIST
Definition SharedDefines.h:1532
@ SPELL_MISS_MISS
Definition SharedDefines.h:1531
@ SPELL_MISS_BLOCK
Definition SharedDefines.h:1535
@ SPELL_ATTR4_SUPPRESS_WEAPON_PROCS
Definition SharedDefines.h:564
@ AURA_INTERRUPT_FLAG_TALK
Definition SpellDefines.h:53
@ SPELL_ATTR0_CU_NO_PVP_FLAG
Definition SpellInfo.h:183
@ SPELL_ATTR0_CU_PICKPOCKET
Definition SpellInfo.h:186
@ 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
static const uint32 SPELL_INTERRUPT_NONPLAYER
Definition Spell.h:278
@ UNIT_STAND_STATE_STAND
Definition UnitDefines.h:32
uint32 createProcExtendMask(SpellNonMeleeDamage *damageInfo, SpellMissInfo missCondition)
Definition Unit.cpp:16009
@ NODAMAGE
Definition Unit.h:254
@ SPELL_DIRECT_DAMAGE
Definition Unit.h:251
@ HEAL
Definition Unit.h:253
virtual void SpellHitTarget(Unit *, SpellInfo const *)
Definition CreatureAI.h:148
virtual void SpellHit(Unit *, SpellInfo const *)
Definition CreatureAI.h:145
void LowerPlayerDamageReq(uint32 unDamage, bool damagedByPlayer=true)
Definition Creature.cpp:3737
CreatureAI * AI() const
Definition Creature.h:145
Definition Unit.h:332
Definition Unit.h:375
void threatAssist(Unit *victim, float baseThreat, SpellInfo const *threatSpell=nullptr)
Definition HostileRefMgr.cpp:35
void RestoreSpellMods(Spell *spell, uint32 ownerAuraId=0, Aura *aura=nullptr)
Definition Player.cpp:9955
void CastItemCombatSpell(Unit *target, WeaponAttackType attType, uint32 procVictim, uint32 procEx)
Definition Player.cpp:7254
void UpdatePvP(bool state, bool _override=false)
Definition PlayerUpdates.cpp:1526
ObjectGuid GetUnitTargetGUID() const
Definition Spell.cpp:216
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
bool CanExecuteTriggersOnHit(uint8 effMask, SpellInfo const *triggeredByAura=nullptr) const
Definition Spell.cpp:8698
SpellValue const * GetSpellValue()
Definition Spell.h:595
SpellMissInfo DoSpellHitOnUnit(Unit *unit, uint32 effectMask, bool scaleAura)
Definition Spell.cpp:2913
void DoTriggersOnSpellHit(Unit *unit, uint8 effMask)
Definition Spell.cpp:3179
virtual void AttackStart(Unit *)
Definition UnitAI.cpp:27
uint32 m_lastSanctuaryTime
Definition Unit.h:2048
void DealSpellDamage(SpellNonMeleeDamage *damageInfo, bool durabilityLoss, Spell const *spell=nullptr)
Definition Unit.cpp:1470
void SendSpellMiss(Unit *target, uint32 spellID, SpellMissInfo missInfo)
Definition Unit.cpp:6544
void SendSpellNonMeleeReflectLog(SpellNonMeleeDamage *log, Unit *attacker)
Definition Unit.cpp:6377
bool CanProc()
Definition Unit.h:1516
bool IsPvP() const
Definition Unit.h:1022
uint32 SpellHealingBonusDone(Unit *victim, SpellInfo const *spellProto, uint32 healamount, DamageEffectType damagetype, uint8 effIndex, float TotalMod=0.0f, uint32 stack=1)
Definition Unit.cpp:12530
void SetInCombatWith(Unit *enemy, uint32 duration=0)
Definition Unit.cpp:13662
int32 HealBySpell(HealInfo &healInfo, bool critical=false)
Definition Unit.cpp:11321
bool IsStandState() const
Definition Unit.cpp:16737
bool IsInCombatWith(Unit const *who) const
Definition Unit.cpp:20914
HostileRefMgr & getHostileRefMgr()
Definition Unit.h:940
int32 GetHealthGain(int32 dVal)
Definition Unit.cpp:14211
static uint32 SpellCriticalHealingBonus(Unit const *caster, SpellInfo const *spellProto, uint32 damage, Unit const *victim)
Definition Unit.cpp:12399
void SendSpellNonMeleeDamageLog(SpellNonMeleeDamage *log)
Definition Unit.cpp:6409
bool IsAIEnabled
Definition Unit.h:2054
void SetLastDamagedTargetGuid(ObjectGuid const &guid)
Definition Unit.h:949
uint32 SpellHealingBonusTaken(Unit *caster, SpellInfo const *spellProto, uint32 healamount, DamageEffectType damagetype, uint32 stack=1)
Definition Unit.cpp:12648
void SetStandState(uint8 state)
Definition Unit.cpp:16752
void RemoveAurasWithInterruptFlags(uint32 flag, uint32 except=0, bool isAutoshot=false)
Definition Unit.cpp:5249
static void DealDamageMods(Unit const *victim, uint32 &damage, uint32 *absorb)
Definition Unit.cpp:814
void CalculateSpellDamageTaken(SpellNonMeleeDamage *damageInfo, int32 damage, SpellInfo const *spellInfo, WeaponAttackType attackType=BASE_ATTACK, bool crit=false)
Definition Unit.cpp:1327
Milliseconds GetGameTimeMS()
Definition GameTime.cpp:43
Definition Unit.h:491

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(), CLASS_PALADIN, 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(), Unit::IsClass(), 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 (m_caster->IsPlayer() && 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->OnPlayerCreateItem(player, pItem, addNumber);
1769
1770 // we succeeded in creating at least one item, so a levelup is possible
1771 if (SelfCast)
1773 }
1774}
@ SPELL_WS_MARK_WINNER
Definition Battleground.h:97
@ SPELL_AV_MARK_LOSER
Definition Battleground.h:101
@ SPELL_WS_MARK_TIE
Definition Battleground.h:98
@ SPELL_WS_MARK_LOSER
Definition Battleground.h:96
@ SPELL_AB_MARK_LOSER
Definition Battleground.h:99
@ SPELL_WG_MARK_WINNER
Definition Battleground.h:105
@ SPELL_AB_MARK_WINNER
Definition Battleground.h:100
@ SPELL_AV_MARK_WINNER
Definition Battleground.h:102
@ EQUIP_ERR_ITEM_NOT_FOUND
Definition Item.h:70
@ EQUIP_ERR_CANT_CARRY_MORE_OF_THIS
Definition Item.h:64
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
@ ITEM_FIELD_CREATOR
Definition UpdateFields.h:37
void SetGuidValue(uint16 index, ObjectGuid value)
Definition Object.cpp:712
bool UpdateCraftSkill(uint32 spellid)
Definition PlayerUpdates.cpp:824
void SendNewItem(Item *item, uint32 count, bool received, bool created, bool broadcast=false, bool sendChatMessage=true)
Definition PlayerStorage.cpp:4756
Item * StoreNewItem(ItemPosCountVec const &pos, uint32 item, bool update, int32 randomPropertyId=0)
Definition PlayerStorage.cpp:2530
bool HasSignature() const
Definition ItemTemplate.h:697

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, Object::IsPlayer(), ITEM_FIELD_CREATOR, m_caster, 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
2914{
2915 if (!unit || !effectMask)
2916 return SPELL_MISS_EVADE;
2917
2918 // For delayed spells immunity may be applied between missile launch and hit - check immunity for that case
2919 if (m_spellInfo->Speed && ((m_damage > 0 && unit->IsImmunedToDamage(this)) || unit->IsImmunedToSchool(this) || unit->IsImmunedToSpell(m_spellInfo, this)))
2920 {
2921 return SPELL_MISS_IMMUNE;
2922 }
2923
2924 // disable effects to which unit is immune
2925 SpellMissInfo returnVal = SPELL_MISS_IMMUNE;
2926 for (uint32 effectNumber = 0; effectNumber < MAX_SPELL_EFFECTS; ++effectNumber)
2927 {
2928 if (effectMask & (1 << effectNumber))
2929 {
2930 if (unit->IsImmunedToSpellEffect(m_spellInfo, effectNumber))
2931 effectMask &= ~(1 << effectNumber);
2932 // Xinef: Buggs out polymorph
2933 // Xinef: And this is checked in MagicSpellHitResult, why we check resistance twice?
2934 // Xinef: And why we check every spell effect basing on rand and generic dispel info? some effects will be appliend and some wont?
2935 /*else if (m_spellInfo->Effects[effectNumber].IsAura() && !m_spellInfo->IsPositiveEffect(effectNumber))
2936 {
2937 int32 debuff_resist_chance = unit->GetMaxPositiveAuraModifierByMiscValue(SPELL_AURA_MOD_DEBUFF_RESISTANCE, int32(m_spellInfo->Dispel));
2938 debuff_resist_chance += unit->GetMaxNegativeAuraModifierByMiscValue(SPELL_AURA_MOD_DEBUFF_RESISTANCE, int32(m_spellInfo->Dispel));
2939
2940 if (debuff_resist_chance > 0)
2941 if (irand(0,10000) <= (debuff_resist_chance * 100))
2942 {
2943 effectMask &= ~(1 << effectNumber);
2944 returnVal = SPELL_MISS_RESIST;
2945 }
2946 }*/
2947 }
2948 }
2949 if (!effectMask)
2950 return returnVal;
2951
2952 if (unit->IsPlayer())
2953 {
2957 }
2958
2959 if (m_caster->IsPlayer())
2960 {
2963 }
2964
2965 if (m_caster != unit)
2966 {
2967 // Recheck UNIT_FLAG_NON_ATTACKABLE for delayed spells
2968 // Xinef: Also check evade state
2969 if (m_spellInfo->Speed > 0.0f)
2970 {
2971 if (unit->IsCreature() && unit->ToCreature()->IsInEvadeMode())
2972 return SPELL_MISS_EVADE;
2973
2975 return SPELL_MISS_EVADE;
2976 }
2977
2978 if (m_caster->_IsValidAttackTarget(unit, m_spellInfo) && /*Intervene Trigger*/ m_spellInfo->Id != 59667)
2979 {
2981 }
2982 else if (m_caster->IsFriendlyTo(unit))
2983 {
2984 // for delayed spells ignore negative spells (after duel end) for friendly targets
2986 if (!IsTriggered() && m_spellInfo->Speed > 0.0f && unit->IsPlayer() && !m_spellInfo->IsPositive())
2987 return SPELL_MISS_EVADE;
2988
2989 // assisting case, healing and resurrection
2991 {
2994 m_caster->ToPlayer()->UpdatePvP(true);
2995 }
2996
2997 // xinef: triggered spells should not prolong combat
2999 {
3000 m_caster->SetInCombatState(unit->GetCombatTimer() > 0, unit);
3001 unit->getHostileRefMgr().threatAssist(m_caster, 0.0f);
3002 }
3003 }
3004 }
3005
3006 uint8 aura_effmask = 0;
3007 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
3008 if (effectMask & (1 << i) && m_spellInfo->Effects[i].IsUnitOwnedAuraEffect())
3009 aura_effmask |= 1 << i;
3010
3011 Unit* originalCaster = GetOriginalCaster();
3012 if (!originalCaster)
3013 originalCaster = m_caster;
3014
3015 // Get Data Needed for Diminishing Returns, some effects may have multiple auras, so this must be done on spell hit, not aura add
3016 // Xinef: Do not increase diminishing level for self cast
3018 // xinef: do not increase diminish level for bosses (eg. Void Reaver silence is never diminished)
3019 if (((m_spellFlags & SPELL_FLAG_REFLECTED) && !(unit->HasReflectSpellsAura())) || (aura_effmask && m_diminishGroup && unit != m_caster && (!m_caster->IsCreature() || !m_caster->ToCreature()->isWorldBoss())))
3020 {
3023
3024 uint32 flagsExtra = unit->IsCreature() ? unit->ToCreature()->GetCreatureTemplate()->flags_extra : 0;
3025
3026 // Increase Diminishing on unit, current informations for actually casts will use values above
3027 if ((type == DRTYPE_PLAYER && (unit->IsCharmedOwnedByPlayerOrPlayer() || flagsExtra & CREATURE_FLAG_EXTRA_ALL_DIMINISH ||
3029 {
3030 // Do not apply diminish return if caster is NPC
3032 {
3034 }
3035 }
3036 }
3037
3039 {
3041 }
3042
3043 if (aura_effmask)
3044 {
3045 // Select rank for aura with level requirements only in specific cases
3046 // 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
3047 SpellInfo const* aurSpellInfo = m_spellInfo;
3048 int32 basePoints[3];
3049 if (scaleAura)
3050 {
3052 ASSERT(aurSpellInfo);
3053 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
3054 {
3055 basePoints[i] = aurSpellInfo->Effects[i].BasePoints;
3056 if (m_spellInfo->Effects[i].Effect != aurSpellInfo->Effects[i].Effect)
3057 {
3058 aurSpellInfo = m_spellInfo;
3059 break;
3060 }
3061 }
3062 }
3063
3064 if (m_originalCaster)
3065 {
3066 bool refresh = false;
3068 m_spellAura = Aura::TryRefreshStackOrCreate(aurSpellInfo, effectMask, unit, m_originalCaster,
3069 (aurSpellInfo == m_spellInfo) ? &m_spellValue->EffectBasePoints[0] : &basePoints[0], m_CastItem, ObjectGuid::Empty, &refresh, refreshPeriodic);
3070
3071 // xinef: if aura was not refreshed, add proc ex
3072 if (!refresh)
3074
3075 if (m_spellAura)
3076 {
3077 // Prevent aura application if target is banished and immuned
3080 {
3082 return SPELL_MISS_IMMUNE;
3083 }
3084
3085 // Set aura stack amount to desired value
3087 {
3088 if (!refresh)
3090 else
3092 }
3093
3094 // Now Reduce spell duration using data received at spell hit
3095 int32 duration = m_spellAura->GetMaxDuration();
3096 int32 limitduration = GetDiminishingReturnsLimitDuration(m_diminishGroup, aurSpellInfo);
3097
3098 // Xinef: if unit == caster - test versus original unit if available
3099 float diminishMod = 1.0f;
3100 if (unit == m_caster && m_targets.GetUnitTarget())
3102 else
3103 diminishMod = unit->ApplyDiminishingToDuration(m_diminishGroup, duration, m_originalCaster, m_diminishLevel, limitduration);
3104
3105 // unit is immune to aura if it was diminished to 0 duration
3106 if (diminishMod == 0.0f)
3107 {
3110 return SPELL_MISS_IMMUNE;
3111 bool found = false;
3112 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
3113 if (effectMask & (1 << i) && m_spellInfo->Effects[i].Effect != SPELL_EFFECT_APPLY_AURA)
3114 found = true;
3115 if (!found)
3116 return SPELL_MISS_IMMUNE;
3117 }
3118 else
3119 {
3120 ((UnitAura*)m_spellAura)->SetDiminishGroup(m_diminishGroup);
3121
3122 bool positive = m_spellAura->GetSpellInfo()->IsPositive();
3124 positive = aurApp->IsPositive();
3125
3126 duration = m_originalCaster->ModSpellDuration(aurSpellInfo, unit, duration, positive, effectMask);
3127
3128 // xinef: haste affects duration of those spells twice
3131
3132 if (m_spellValue->AuraDuration != 0)
3133 {
3134 if (m_spellAura->GetMaxDuration() != -1)
3135 {
3137 }
3138
3140 }
3141 else if (duration != m_spellAura->GetMaxDuration())
3142 {
3143 m_spellAura->SetMaxDuration(duration);
3144 m_spellAura->SetDuration(duration);
3145 }
3146
3147 // xinef: apply relic cooldown, imo best place to add this
3150
3153 }
3154 }
3155 }
3156 }
3157
3158 int8 sanct_effect = -1;
3159
3160 for (uint32 effectNumber = 0; effectNumber < MAX_SPELL_EFFECTS; ++effectNumber)
3161 {
3162 // handle sanctuary effects after aura apply!
3163 if (m_spellInfo->Effects[effectNumber].Effect == SPELL_EFFECT_SANCTUARY)
3164 {
3165 sanct_effect = effectNumber;
3166 continue;
3167 }
3168
3169 if (effectMask & (1 << effectNumber))
3170 HandleEffects(unit, nullptr, nullptr, effectNumber, SPELL_EFFECT_HANDLE_HIT_TARGET);
3171 }
3172
3173 if (sanct_effect >= 0 && (effectMask & (1 << sanct_effect)))
3174 HandleEffects(unit, nullptr, nullptr, sanct_effect, SPELL_EFFECT_HANDLE_HIT_TARGET);
3175
3176 return SPELL_MISS_NONE;
3177}
@ CREATURE_FLAG_EXTRA_OBEYS_TAUNT_DIMINISHING_RETURNS
Definition CreatureData.h:64
@ CREATURE_FLAG_EXTRA_ALL_DIMINISH
Definition CreatureData.h:65
@ 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:3526
@ SPELL_EFFECT_SANCTUARY
Definition SharedDefines.h:868
@ SPELL_ATTR5_SPELL_HASTE_AFFECTS_PERIODIC
Definition SharedDefines.h:591
DiminishingReturnsType
Definition SharedDefines.h:3499
@ DRTYPE_PLAYER
Definition SharedDefines.h:3501
@ DRTYPE_ALL
Definition SharedDefines.h:3502
@ SPELL_AURA_PERIODIC_HASTE
Definition SpellAuraDefines.h:379
@ SPELL_AURA_MOD_STEALTH
Definition SpellAuraDefines.h:79
@ AURA_INTERRUPT_FLAG_HITBYSPELL
Definition SpellDefines.h:43
@ TRIGGERED_NO_PERIODIC_RESET
Will ignore equipped item requirements.
Definition SpellDefines.h:152
@ 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
@ PROC_EX_NO_AURA_REFRESH
Definition SpellMgr.h:214
@ UNIT_STATE_ATTACK_PLAYER
Definition UnitDefines.h:184
@ UNIT_STATE_ISOLATED
Definition UnitDefines.h:183
@ UNIT_FLAG_NON_ATTACKABLE
Definition UnitDefines.h:255
@ UNIT_MOD_CAST_SPEED
Definition UpdateFields.h:137
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
bool isWorldBoss() const
Definition Creature.h:125
bool IsInEvadeMode() const
Definition Creature.h:139
float GetFloatValue(uint16 index) const
Definition Object.cpp:306
SpellInfo const * GetAuraRankForLevel(uint8 level) const
Definition SpellInfo.cpp:2538
Unit * GetOriginalCaster() const
Definition Spell.h:586
Definition SpellAuras.h:279
bool HasAuraTypeWithAffectMask(AuraType auratype, SpellInfo const *affectedSpell) const
Definition Unit.cpp:5829
DiminishingLevels GetDiminishing(DiminishingGroup group)
Definition Unit.cpp:15036
void IncrDiminishing(DiminishingGroup group)
Definition Unit.cpp:15062
uint32 GetCombatTimer() const
Definition Unit.h:927
bool IsImmunedToSchool(SpellSchoolMask meleeSchoolMask) const
Definition Unit.cpp:12911
void SetContestedPvP(Player *attackedPlayer=nullptr, bool lookForNearContestedGuards=true)
Definition Unit.cpp:17274
bool HasUnitFlag(UnitFlags flags) const
Definition Unit.h:732
float ApplyDiminishingToDuration(DiminishingGroup group, int32 &duration, Unit *caster, DiminishingLevels Level, int32 limitduration)
Definition Unit.cpp:15076
int32 ModSpellDuration(SpellInfo const *spellProto, Unit const *target, int32 duration, bool positive, uint32 effectMask)
Definition Unit.cpp:14902
virtual void AddSpellCooldown(uint32, uint32, uint32, bool needSendToClient=false, bool forceSendToSpectator=false)
Definition Unit.h:1304
void SetInCombatState(bool PvP, Unit *enemy=nullptr, uint32 duration=0)
Definition Unit.cpp:13820
bool HasReflectSpellsAura() const
Definition Unit.h:1771
bool IsCharmedOwnedByPlayerOrPlayer() const
Definition Unit.h:1276
bool IsImmunedToDamage(SpellSchoolMask meleeSchoolMask) const
Definition Unit.cpp:12826
virtual bool IsImmunedToSpell(SpellInfo const *spellInfo, Spell const *spell=nullptr)
Definition Unit.cpp:12995
bool IsImmunedToDamageOrSchool(SpellSchoolMask meleeSchoolMask) const
Definition Unit.cpp:12980
bool IsHostileTo(Unit const *unit) const
Definition Unit.cpp:10287
bool _IsValidAttackTarget(Unit const *target, SpellInfo const *bySpell, WorldObject const *obj=nullptr) const
Definition Unit.cpp:13965
ObjectGuid GetCharmerOrOwnerGUID() const
Definition Unit.h:1262
uint32 flags_extra
Definition CreatureData.h:246
int32 AuraDuration
Definition Spell.h:227
uint8 AuraStackAmount
Definition Spell.h:226

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
3180{
3181 // Apply additional spell effects to target
3183 if (m_preCastSpell)
3184 {
3185 // Paladin immunity shields
3186 if (m_preCastSpell == 61988)
3187 {
3188 // Cast Forbearance
3189 m_caster->CastSpell(unit, 25771, true);
3190 // Cast Avenging Wrath Marker
3191 unit->CastSpell(unit, 61987, true);
3192 }
3193
3194 // Avenging Wrath
3195 if (m_preCastSpell == 61987)
3196 // Cast the serverside immunity shield marker
3197 m_caster->CastSpell(unit, 61988, true);
3198
3199 // Fearie Fire (Feral) - damage
3200 if (m_preCastSpell == 60089)
3201 m_caster->CastSpell(unit, m_preCastSpell, true);
3202 else if (sSpellMgr->GetSpellInfo(m_preCastSpell))
3203 // Blizz seems to just apply aura without bothering to cast
3205 }
3206
3207 // handle SPELL_AURA_ADD_TARGET_TRIGGER auras
3208 // this is executed after spell proc spells on target hit
3209 // spells are triggered for each hit spell target
3210 // info confirmed with retail sniffs of permafrost and shadow weaving
3211 if (!m_hitTriggerSpells.empty())
3212 {
3213 int _duration = 0;
3214 for (HitTriggerSpellList::const_iterator i = m_hitTriggerSpells.begin(); i != m_hitTriggerSpells.end(); ++i)
3215 {
3216 if (CanExecuteTriggersOnHit(effMask, i->triggeredByAura) && roll_chance_i(i->chance))
3217 {
3218 m_caster->CastSpell(unit, i->triggeredSpell->Id, true);
3219 LOG_DEBUG("spells.aura", "Spell {} triggered spell {} by SPELL_AURA_ADD_TARGET_TRIGGER aura", m_spellInfo->Id, i->triggeredSpell->Id);
3220
3221 // SPELL_AURA_ADD_TARGET_TRIGGER auras shouldn't trigger auras without duration
3222 // set duration of current aura to the triggered spell
3223 if (i->triggeredSpell->GetDuration() == -1)
3224 {
3225 if (Aura* triggeredAur = unit->GetAura(i->triggeredSpell->Id, m_caster->GetGUID()))
3226 {
3227 // get duration from aura-only once
3228 if (!_duration)
3229 {
3230 Aura* aur = unit->GetAura(m_spellInfo->Id, m_caster->GetGUID());
3231 _duration = aur ? aur->GetDuration() : -1;
3232 }
3233 triggeredAur->SetDuration(_duration);
3234 }
3235 }
3236 }
3237 }
3238 }
3239
3240 // trigger linked auras remove/apply
3242 if (std::vector<int32> const* spellTriggered = sSpellMgr->GetSpellLinked(m_spellInfo->Id + SPELL_LINK_HIT))
3243 {
3244 for (std::vector<int32>::const_iterator i = spellTriggered->begin(); i != spellTriggered->end(); ++i)
3245 if (*i < 0)
3246 {
3247 unit->RemoveAurasDueToSpell(-(*i));
3248 }
3249 else
3250 {
3251 unit->CastSpell(unit, *i, true, 0, 0, m_caster->GetGUID());
3252 }
3253 }
3254}
bool roll_chance_i(int chance)
Definition Random.h:63
@ SPELL_LINK_HIT
Definition SpellMgr.h:97
int32 GetDuration() const
Definition SpellAuras.h:133
HitTriggerSpellList m_hitTriggerSpells
Definition Spell.h:766
Aura * GetAura(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemCasterGUID=ObjectGuid::Empty, uint8 reqEffMask=0) const
Definition Unit.cpp:5649
Aura * AddAura(uint32 spellId, Unit *target)
Definition Unit.cpp:18894

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)
4252{
4254 return;
4255
4256 if (!gameObjTarget)
4257 return;
4258
4259 GameObjectActions action = GameObjectActions(m_spellInfo->Effects[effIndex].MiscValue);
4260 switch (action)
4261 {
4267 break;
4268 case GameObjectActions::Disturb: // What's the difference with Open?
4270 if (Unit* unitCaster = m_caster->ToUnit())
4271 gameObjTarget->Use(unitCaster);
4272 break;
4274 if (Unit* unitCaster = m_caster->ToUnit())
4275 gameObjTarget->UseDoorOrButton(0, false, unitCaster);
4276 [[fallthrough]];
4280 break;
4284 break;
4287 break;
4291 break;
4295 break;
4297 if (Unit* unitCaster = m_caster->ToUnit())
4298 gameObjTarget->UseDoorOrButton(0, true, unitCaster);
4299 break;
4304 {
4305 GameObjectTemplateAddon const* templateAddon = gameObjTarget->GetTemplateAddon();
4306
4307 uint32 artKitIndex = uint32(action) - uint32(GameObjectActions::UseArtKit0);
4308
4309 uint32 artKitValue = 0;
4310 if (templateAddon)
4311 artKitValue = templateAddon->artKits[artKitIndex];
4312
4313 if (artKitValue == 0)
4314 LOG_ERROR("sql.sql", "GameObject {} hit by spell {} needs `artkit{}` in `gameobject_template_addon`", gameObjTarget->GetEntry(), m_spellInfo->Id, artKitIndex);
4315 else
4316 gameObjTarget->SetGoArtKit(artKitValue);
4317
4318 break;
4319 }
4321 LOG_FATAL("spell", "Spell {} has action type NONE in effect {}", m_spellInfo->Id, int32(effIndex));
4322 break;
4323 default:
4324 LOG_ERROR("spell", "Spell {} has unhandled action {} in effect {}", m_spellInfo->Id, int32(action), int32(effIndex));
4325 break;
4326 }
4327}
GameObjectActions
Definition GameObject.h:76
#define LOG_FATAL(filterType__,...)
Definition Log.h:154
@ GO_FLAG_NOT_SELECTABLE
Definition SharedDefines.h:1618
@ GO_FLAG_LOCKED
Definition SharedDefines.h:1615
@ GAMEOBJECT_FLAGS
Definition UpdateFields.h:399
void UseDoorOrButton(uint32 time_to_restore=0, bool alternative=false, Unit *user=nullptr)
Definition GameObject.cpp:1410
void SetGoArtKit(uint8 artkit)
Definition GameObject.cpp:1424
void SendCustomAnim(uint32 anim)
Definition GameObject.cpp:2142
void ResetDoorOrButton()
Definition GameObject.cpp:1400
void DespawnOrUnsummon(Milliseconds delay=0ms, Seconds forcedRespawnTime=0s)
Definition GameObject.cpp:932
GameObjectTemplateAddon const * GetTemplateAddon() const
Definition GameObject.cpp:911
void Use(Unit *user)
Definition GameObject.cpp:1460
void SetFlag(uint16 index, uint32 newFlag)
Definition Object.cpp:834
void ApplyModFlag(uint16 index, uint32 flag, bool apply)
Definition Object.cpp:888
Definition GameObjectData.h:666
std::array< uint32, 4 > artKits
Definition GameObjectData.h:672

References AnimateCustom0, AnimateCustom1, AnimateCustom2, AnimateCustom3, Object::ApplyModFlag(), GameObjectTemplateAddon::artKits, Close, CloseAndLock, Despawn, GameObject::DespawnOrUnsummon(), Destroy, Disturb, effectHandleMode, SpellInfo::Effects, GAMEOBJECT_FLAGS, gameObjTarget, Object::GetEntry(), GameObject::GetTemplateAddon(), GO_FLAG_LOCKED, GO_FLAG_NOT_SELECTABLE, SpellInfo::Id, Lock, LOG_ERROR, LOG_FATAL, m_caster, m_spellInfo, MakeActive, MakeInert, None, Open, OpenAndUnlock, Rebuild, GameObject::ResetDoorOrButton(), GameObject::SendCustomAnim(), Object::SetFlag(), GameObject::SetGoArtKit(), SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToUnit(), Unlock, GameObject::Use(), UseArtKit0, UseArtKit1, UseArtKit2, UseArtKit3, and GameObject::UseDoorOrButton().

◆ EffectActivateRune()

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

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)
6145{
6147 return;
6148
6149 if (!unitTarget)
6150 return;
6151
6152 if (Player* player = unitTarget->ToPlayer())
6153 {
6154 player->ActivateSpec(damage - 1); // damage is 1 or 2, spec is 0 or 1
6155 }
6156}

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

◆ EffectAddComboPoints()

void Spell::EffectAddComboPoints ( SpellEffIndex  effIndex)
4089{
4091 {
4092 return;
4093 }
4094
4095 if (!unitTarget || damage <= 0)
4096 {
4097 return;
4098 }
4099
4101}
void AddComboPointGain(Unit *target, int8 amount)
Definition Spell.h:541

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

◆ EffectAddExtraAttacks()

void Spell::EffectAddExtraAttacks ( SpellEffIndex  effIndex)
4671{
4673 {
4674 return;
4675 }
4676
4677 if (!unitTarget || !unitTarget->IsAlive())
4678 {
4679 return;
4680 }
4681
4683
4685}
void ExecuteLogEffectExtraAttacks(uint8 effIndex, Unit *victim, uint32 attCount)
Definition Spell.cpp:5054
void AddExtraAttacks(uint32 count)
Definition Unit.cpp:2804

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

◆ EffectAddFarsight()

void Spell::EffectAddFarsight ( SpellEffIndex  effIndex)
2725{
2727 return;
2728
2729 if (!m_caster->IsPlayer())
2730 return;
2731
2732 float radius = m_spellInfo->Effects[effIndex].CalcRadius();
2733 int32 duration = m_spellInfo->GetDuration();
2734 // Caster not in world, might be spell triggered from aura removal
2735 if (!m_caster->IsInWorld())
2736 return;
2737
2738 // Remove old farsight if exist
2739 bool updateViewerVisibility = m_caster->RemoveDynObject(m_spellInfo->Id);
2740
2741 DynamicObject* dynObj = new DynamicObject();
2743 {
2744 delete dynObj;
2745 return;
2746 }
2747
2748 dynObj->SetDuration(duration);
2749 dynObj->SetCasterViewpoint(updateViewerVisibility);
2750}
@ DYNAMIC_OBJECT_FARSIGHT_FOCUS
Definition DynamicObject.h:31
void SetDuration(int32 newDuration)
Definition DynamicObject.cpp:198
void SetCasterViewpoint(bool updateViewerVisibility)
Definition DynamicObject.cpp:226
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:480
int32 GetDuration() const
Definition SpellInfo.cpp:2350

References DynamicObject::CreateDynamicObject(), destTarget, DYNAMIC_OBJECT_FARSIGHT_FOCUS, DynamicObject, 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)
2795{
2797 return;
2798
2799 if (!unitTarget->IsPlayer())
2800 return;
2801
2802 // not scale value for item based reward (/10 value expected)
2803 if (m_CastItem)
2804 {
2805 unitTarget->ToPlayer()->RewardHonor(nullptr, 1, damage / 10, false);
2806 LOG_DEBUG("spells.aura", "SpellEffect::AddHonor (spell_id {}) rewards {} honor points (item {}) for player: {}",
2808 return;
2809 }
2810
2811 // do not allow to add too many honor for player (50 * 21) = 1040 at level 70, or (50 * 31) = 1550 at level 80
2812 if (damage <= 50)
2813 {
2815 unitTarget->ToPlayer()->RewardHonor(nullptr, 1, honor_reward, false);
2816 LOG_DEBUG("spells.aura", "SpellEffect::AddHonor (spell_id {}) rewards {} honor points (scale) to player: {}",
2817 m_spellInfo->Id, honor_reward, unitTarget->ToPlayer()->GetGUID().ToString());
2818 }
2819 else
2820 {
2821 //maybe we have correct honor_gain in damage already
2822 unitTarget->ToPlayer()->RewardHonor(nullptr, 1, damage, false);
2823 LOG_DEBUG("spells.aura", "SpellEffect::AddHonor (spell_id {}) rewards {} honor points (non scale) for player: {}",
2825 }
2826}
std::string ToString() const
Definition ObjectGuid.cpp:47
bool RewardHonor(Unit *victim, uint32 groupsize, int32 honor=-1, bool awardXP=true)
Definition Player.cpp:6090
uint32 hk_honor_at_level(uint8 level, float multiplier=1.0f)
Definition Formulas.h:38

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

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

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)
4697{
4699 return;
4700
4701 if (m_caster->IsPlayer())
4702 m_caster->ToPlayer()->SetCanBlock(true);
4703}
void SetCanBlock(bool value)
Definition Player.cpp:13181

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.

6205{
6207 return;
6208
6209 if (!m_caster->IsPlayer())
6210 return;
6211
6212 Player* p_caster = m_caster->ToPlayer();
6213 uint32 button_id = m_spellInfo->Effects[effIndex].MiscValue + 132;
6214 uint32 n_buttons = m_spellInfo->Effects[effIndex].MiscValueB;
6215
6216 for (; n_buttons; --n_buttons, ++button_id)
6217 {
6218 ActionButton const* ab = p_caster->GetActionButton(button_id);
6219 if (!ab || ab->GetType() != ACTION_BUTTON_SPELL)
6220 continue;
6221
6224 uint32 spell_id = ab->GetAction();
6225 if (!spell_id)
6226 continue;
6227
6228 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spell_id);
6229 if (!spellInfo)
6230 continue;
6231
6232 if (!p_caster->HasSpell(spell_id) || p_caster->HasSpellCooldown(spell_id))
6233 continue;
6234
6236 continue;
6237
6238 uint32 cost = spellInfo->CalcPowerCost(m_caster, spellInfo->GetSchoolMask(), this);
6239 if (m_caster->GetPower(POWER_MANA) < cost)
6240 continue;
6241
6243 m_caster->CastSpell(m_caster, spell_id, triggerFlags);
6244 }
6245}
@ ACTION_BUTTON_SPELL
Definition Player.h:231
@ SPELL_ATTR7_CAN_BE_MULTI_CAST
Definition SharedDefines.h:657
ActionButton const * GetActionButton(uint8 button)
Definition Player.cpp:5670
bool HasSpell(uint32 spell) const override
Definition Player.cpp:3891
Definition Player.h:249
uint32 GetAction() const
Definition Player.h:257
ActionButtonType GetType() const
Definition Player.h:256

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)
4916{
4918 {
4919 if (!unitTarget)
4920 return;
4921
4922 ObjectGuid targetGUID = ObjectGuid::Empty;
4923 Player* player = m_caster->ToPlayer();
4924 if (player)
4925 {
4926 // charge changes fall time
4928
4930 {
4931 targetGUID = unitTarget->GetGUID();
4932 }
4933 }
4934
4935 float speed = G3D::fuzzyGt(m_spellInfo->Speed, 0.0f) ? m_spellInfo->Speed : SPEED_CHARGE;
4936 // Spell is not using explicit target - no generated path
4937 if (!m_preGeneratedPath)
4938 {
4940 m_caster->GetMotionMaster()->MoveCharge(pos.m_positionX, pos.m_positionY, pos.m_positionZ, speed, EVENT_CHARGE, nullptr, false, 0.0f, targetGUID);
4941 }
4942 else
4943 {
4944 m_caster->GetMotionMaster()->MoveCharge(*m_preGeneratedPath, speed, targetGUID);
4945 }
4946
4947 if (player)
4948 {
4949 sScriptMgr->AnticheatSetUnderACKmount(player);
4950 }
4951 }
4952}
#define SPEED_CHARGE
Definition MotionMaster.h:124
@ EVENT_CHARGE
Definition SharedDefines.h:3577
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:719
static ObjectGuid const Empty
Definition ObjectGuid.h:120
void SetFallInformation(uint32 time, float z)
Definition Player.h:2340
MotionMaster * GetMotionMaster()
Definition Unit.h:1713
Position GetFirstCollisionPosition(float startX, float startY, float startZ, float destX, float destY)
Definition Object.cpp:2839
Definition Position.h:27
float m_positionZ
Definition Position.h:57
float GetRelativeAngle(const Position *pos) const
Definition Position.h:201
float m_positionX
Definition Position.h:55
float m_positionY
Definition Position.h:56

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:5082
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:13536
void DestroyItemCount(uint32 item, uint32 count, bool update, bool unequip_check=false)
Definition PlayerStorage.cpp:3120
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)
5843{
5845 return;
5846
5848 return;
5849
5850 uint32 creatureEntry = m_spellInfo->Effects[effIndex].MiscValue;
5851 Pet* pet = unitTarget->CreateTamedPetFrom(creatureEntry, m_spellInfo->Id);
5852 if (!pet)
5853 return;
5854
5855 // add to world
5856 pet->GetMap()->AddToMap(pet->ToCreature(), true);
5857
5858 // unitTarget has pet now
5859 unitTarget->SetMinion(pet, true);
5860
5861 pet->InitTalentForLevel();
5862
5863 if (unitTarget->IsPlayer())
5864 {
5867 }
5868}
@ CLASS_HUNTER
Definition SharedDefines.h:143
bool AddToMap(T *, bool checkTransport=false)
Definition Map.cpp:305
void InitTalentForLevel()
Definition Pet.cpp:2228
void SavePetToDB(PetSaveMode mode)
Definition Pet.cpp:502
void PetSpellInitialize()
Definition Player.cpp:9552
void SetMinion(Minion *minion, bool apply)
Definition Unit.cpp:10761
Pet * CreateTamedPetFrom(Creature *creatureTarget, uint32 spell_id=0)
Definition Unit.cpp:17377

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)
5250{
5252 return;
5253
5254 int32 mana = 0;
5255 for (uint8 slot = SUMMON_SLOT_TOTEM_FIRE; slot < MAX_TOTEM_SLOT; ++slot)
5256 {
5257 if (!m_caster->m_SummonSlot[slot])
5258 continue;
5259
5261 if (totem && totem->IsTotem())
5262 {
5263 uint32 spell_id = totem->GetUInt32Value(UNIT_CREATED_BY_SPELL);
5264 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spell_id);
5265 if (spellInfo)
5266 {
5267 mana += spellInfo->ManaCost;
5269 }
5270 totem->ToTotem()->UnSummon();
5271 }
5272 }
5273 ApplyPct(mana, damage);
5274 if (mana)
5275 m_caster->CastCustomSpell(m_caster, 39104, &mana, nullptr, nullptr, true);
5276}
#define MAX_TOTEM_SLOT
Definition SharedDefines.h:3572
@ SUMMON_SLOT_TOTEM_FIRE
Definition SharedDefines.h:3562
@ UNIT_CREATED_BY_SPELL
Definition UpdateFields.h:138
T ApplyPct(T &base, U pct)
Definition Util.h:73
Creature * GetCreature(ObjectGuid const &guid)
Definition Map.cpp:2357
uint32 ManaCostPercentage
Definition SpellInfo.h:367
uint32 ManaCost
Definition SpellInfo.h:363
void UnSummon(Milliseconds msTime=0ms) override
Definition Totem.cpp:122
Totem * ToTotem()
Definition Unit.h:715
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:1251
uint32 GetCreateMana() const
Definition Unit.h:1111
ObjectGuid m_SummonSlot[MAX_SUMMON_SLOT]
Definition Unit.h:2036

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_FIRE, Unit::ToTotem(), UNIT_CREATED_BY_SPELL, and Totem::UnSummon().

◆ EffectDiscoverTaxi()

void Spell::EffectDiscoverTaxi ( SpellEffIndex  effIndex)
5871{
5873 return;
5874
5875 if (!unitTarget)
5876 return;
5877
5878 Player* player = unitTarget->ToPlayer();
5879 if (!player)
5880 {
5881 return;
5882 }
5883
5884 uint32 nodeid = m_spellInfo->Effects[effIndex].MiscValue;
5885 if (sTaxiNodesStore.LookupEntry(nodeid))
5886 player->GetSession()->SendDiscoverNewTaxiNode(nodeid);
5887}
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)
4467{
4469 return;
4470
4472 return;
4473
4474 if (Player* caster = m_caster->ToPlayer())
4475 {
4476 caster->UpdateCraftSkill(m_spellInfo->Id);
4477 caster->SendLoot(itemTarget->GetGUID(), LOOT_DISENCHANTING);
4478 }
4479
4480 // item will be removed at disenchanting end
4481}
@ 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)
4553{
4555 return;
4556
4557 if (!unitTarget || !unitTarget->IsPet())
4558 return;
4559
4560 Pet* pet = unitTarget->ToPet();
4561
4562 ExecuteLogEffectUnsummonObject(effIndex, pet);
4564}
@ PET_SAVE_NOT_IN_SLOT
Definition PetDefines.h:46
void Remove(PetSaveMode mode, bool returnreagent=false)
Definition Pet.cpp:881
void ExecuteLogEffectUnsummonObject(uint8 effIndex, WorldObject *obj)
Definition Spell.cpp:5100

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

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)
5155{
5157 return;
5158
5159 if (!unitTarget)
5160 return;
5161
5162 uint32 mechanic = m_spellInfo->Effects[effIndex].MiscValue;
5163
5164 std::queue<std::pair<uint32, ObjectGuid>> dispel_list;
5165
5166 Unit::AuraMap const& auras = unitTarget->GetOwnedAuras();
5167 for (Unit::AuraMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
5168 {
5169 Aura* aura = itr->second;
5171 continue;
5173 {
5174 if ((aura->GetSpellInfo()->GetAllEffectsMechanicMask() & (1 << mechanic)))
5175 {
5176 dispel_list.push(std::make_pair(aura->GetId(), aura->GetCasterGUID()));
5177
5178 // spell only removes 1 bleed effect do not continue
5179 if (m_spellInfo->Effects[effIndex].BasePoints == 1)
5180 {
5181 break;
5182 }
5183 }
5184 }
5185 }
5186
5187 for (; dispel_list.size(); dispel_list.pop())
5188 {
5189 unitTarget->RemoveAura(dispel_list.front().first, dispel_list.front().second, 0, AURA_REMOVE_BY_ENEMY_SPELL);
5190 }
5191
5192 // put in combat
5195}
@ AURA_REMOVE_BY_ENEMY_SPELL
Definition SpellAuraDefines.h:394
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
void RemoveAura(AuraApplicationMap::iterator &i, AuraRemoveMode mode=AURA_REMOVE_BY_DEFAULT)
Definition Unit.cpp:4844

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.

2697{
2699 return;
2700
2701 // Check for possible target
2702 if (!unitTarget || unitTarget->IsEngaged())
2703 return;
2704
2705 // target must be OK to do this
2707 return;
2708
2711}
@ UNIT_STATE_CONFUSED
Definition UnitDefines.h:181
@ UNIT_STATE_FLEEING
Definition UnitDefines.h:177
@ UNIT_STATE_STUNNED
Definition UnitDefines.h:173
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:847
void SetFacingTo(float ori)
Definition Unit.cpp:20280
bool IsEngaged() const
Definition Unit.h:914
float GetAngle(const Position *pos) const
Definition Position.cpp:85

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)
2683{
2685 return;
2686
2688}
virtual void SetCanDualWield(bool value)
Definition Unit.h:957

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

◆ EffectDuel()

void Spell::EffectDuel ( SpellEffIndex  effIndex)
4104{
4106 return;
4107
4108 if (!unitTarget || !m_caster->IsPlayer() || !unitTarget->IsPlayer())
4109 return;
4110
4111 Player* caster = m_caster->ToPlayer();
4112 Player* target = unitTarget->ToPlayer();
4113
4114 // caster or target already have requested duel
4115 if (caster->duel || target->duel || !target->GetSocial() || target->GetSocial()->HasIgnore(caster->GetGUID()))
4116 return;
4117
4118 // Players can only fight a duel in zones with this flag
4119 AreaTableEntry const* casterAreaEntry = sAreaTableStore.LookupEntry(caster->GetAreaId());
4120 if (casterAreaEntry && !(casterAreaEntry->flags & AREA_FLAG_ALLOW_DUELS))
4121 {
4122 SendCastResult(SPELL_FAILED_NO_DUELING); // Dueling isn't allowed here
4123 return;
4124 }
4125
4126 AreaTableEntry const* targetAreaEntry = sAreaTableStore.LookupEntry(target->GetAreaId());
4127 if (targetAreaEntry && !(targetAreaEntry->flags & AREA_FLAG_ALLOW_DUELS))
4128 {
4129 SendCastResult(SPELL_FAILED_NO_DUELING); // Dueling isn't allowed here
4130 return;
4131 }
4132
4133 //CREATE DUEL FLAG OBJECT
4134 uint32 gameobject_id = m_spellInfo->Effects[effIndex].MiscValue;
4135 GameObject* pGameObj = sObjectMgr->IsGameObjectStaticTransport(gameobject_id) ? new StaticTransport() : new GameObject();
4136
4137 Map* map = m_caster->GetMap();
4138 if (!pGameObj->Create(map->GenerateLowGuid<HighGuid::GameObject>(), gameobject_id,
4139 map, m_caster->GetPhaseMask(),
4143 m_caster->GetOrientation(), G3D::Quat(), 0, GO_STATE_READY))
4144 {
4145 delete pGameObj;
4146 return;
4147 }
4148
4151 int32 duration = m_spellInfo->GetDuration();
4152 pGameObj->SetRespawnTime(duration > 0 ? duration / IN_MILLISECONDS : 0);
4153 pGameObj->SetSpellId(m_spellInfo->Id);
4154
4155 ExecuteLogEffectSummonObject(effIndex, pGameObj);
4156
4157 m_caster->AddGameObject(pGameObj);
4158 map->AddToMap(pGameObj, true);
4159 //END
4160
4161 // Send request
4162 WorldPacket data(SMSG_DUEL_REQUESTED, 8 + 8);
4163 data << pGameObj->GetGUID();
4164 data << caster->GetGUID();
4165 caster->SendDirectMessage(&data);
4166 target->SendDirectMessage(&data);
4167
4168 // create duel-info
4169 bool isMounted = (GetSpellInfo()->Id == 62875);
4170 caster->duel = std::make_unique<DuelInfo>(target, caster, isMounted);
4171 target->duel = std::make_unique<DuelInfo>(caster, caster, isMounted);
4172
4173 caster->SetGuidValue(PLAYER_DUEL_ARBITER, pGameObj->GetGUID());
4174 target->SetGuidValue(PLAYER_DUEL_ARBITER, pGameObj->GetGUID());
4175
4176 sScriptMgr->OnPlayerDuelRequest(target, caster);
4177}
@ AREA_FLAG_ALLOW_DUELS
Definition DBCEnums.h:240
@ SPELL_FAILED_NO_DUELING
Definition SharedDefines.h:1039
@ PLAYER_DUEL_ARBITER
Definition UpdateFields.h:177
@ GAMEOBJECT_LEVEL
Definition UpdateFields.h:403
@ GAMEOBJECT_FACTION
Definition UpdateFields.h:402
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:1284
void SetSpellId(uint32 id)
Definition GameObject.h:176
void SetUInt32Value(uint16 index, uint32 value)
Definition Object.cpp:639
bool HasIgnore(ObjectGuid const &ignore_guid) const
Definition SocialMgr.cpp:193
PlayerSocial * GetSocial()
Definition Player.h:1143
void ExecuteLogEffectSummonObject(uint8 effIndex, WorldObject *obj)
Definition Spell.cpp:5094
Definition Transport.h:115
uint32 GetFaction() const
Definition Unit.h:834
void AddGameObject(GameObject *gameObj)
Definition Unit.cpp:6278
uint32 GetPhaseMask() const
Definition Object.h:513
@ SMSG_DUEL_REQUESTED
Definition Opcodes.h:389
uint32 flags
Definition DBCStructure.h:524
float GetOrientation() const
Definition Position.h:124

References Unit::AddGameObject(), Map::AddToMap(), AREA_FLAG_ALLOW_DUELS, GameObject::Create(), Player::duel, effectHandleMode, SpellInfo::Effects, ExecuteLogEffectSummonObject(), AreaTableEntry::flags, GameObject, 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::GetSocial(), GetSpellInfo(), GO_STATE_READY, PlayerSocial::HasIgnore(), SpellInfo::Id, IN_MILLISECONDS, Object::IsPlayer(), m_caster, m_spellInfo, PLAYER_DUEL_ARBITER, sAreaTableStore, SendCastResult(), Player::SendDirectMessage(), 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}
ScriptMapMap sSpellScripts
Definition ObjectMgr.cpp:59
@ TEMPSUMMON_TIMED_DESPAWN
Definition Object.h:50
@ SPELLFAMILY_GENERIC
Definition SharedDefines.h:3794
@ SPELLFAMILY_PALADIN
Definition SharedDefines.h:3804
@ SPELLFAMILY_ROGUE
Definition SharedDefines.h:3802
@ UNIT_FIELD_MOUNTDISPLAYID
Definition UpdateFields.h:126
uint8 GetGoAnimProgress() const
Definition GameObject.h:208
time_t GetRespawnTime() const
Definition GameObject.h:183
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
void AddPetAura(PetAura const *petSpell)
Definition Unit.cpp:17323
std::unordered_set< Unit * > AttackerSet
Definition Unit.h:652
AttackerSet const & getAttackers() const
Definition Unit.h:883
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:2359

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)
5279{
5281 return;
5282
5283 if (!unitTarget)
5284 return;
5285
5286 Player* player = unitTarget->ToPlayer();
5287 if (!player)
5288 {
5289 return;
5290 }
5291
5292 int32 slot = m_spellInfo->Effects[effIndex].MiscValue;
5293
5294 // -1 means all player equipped items and -2 all items
5295 if (slot < 0)
5296 {
5297 player->DurabilityPointsLossAll(damage, (slot < -1));
5299 return;
5300 }
5301
5302 // invalid slot value
5303 if (slot >= INVENTORY_SLOT_BAG_END)
5304 return;
5305
5306 if (Item* item = player->GetItemByPos(INVENTORY_SLOT_BAG_0, slot))
5307 {
5308 player->DurabilityPointsLoss(item, damage);
5309 ExecuteLogEffectDurabilityDamage(effIndex, unitTarget, item->GetEntry(), slot);
5310 }
5311}
@ INVENTORY_SLOT_BAG_END
Definition Player.h:695
#define INVENTORY_SLOT_BAG_0
Definition Player.h:665
Item * GetItemByPos(uint16 pos) const
Definition PlayerStorage.cpp:442
void DurabilityPointsLossAll(int32 points, bool inventory)
Definition Player.cpp:4780
void DurabilityPointsLoss(Item *item, int32 points)
Definition Player.cpp:4806
void ExecuteLogEffectDurabilityDamage(uint8 effIndex, Unit *victim, int32 itemId, int32 slot)
Definition Spell.cpp:5068

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)
5314{
5316 return;
5317
5318 if (!unitTarget)
5319 return;
5320
5321 Player* player = unitTarget->ToPlayer();
5322 if (!player)
5323 {
5324 return;
5325 }
5326
5327 int32 slot = m_spellInfo->Effects[effIndex].MiscValue;
5328
5329 // FIXME: some spells effects have value -1/-2
5330 // Possibly its mean -1 all player equipped items and -2 all items
5331 if (slot < 0)
5332 {
5333 player->DurabilityLossAll(float(damage) / 100.0f, (slot < -1));
5334 return;
5335 }
5336
5337 // invalid slot value
5338 if (slot >= INVENTORY_SLOT_BAG_END)
5339 return;
5340
5341 if (damage <= 0)
5342 return;
5343
5344 if (Item* item = player->GetItemByPos(INVENTORY_SLOT_BAG_0, slot))
5345 player->DurabilityLoss(item, float(damage) / 100.0f);
5346}
void DurabilityLossAll(double percent, bool inventory)
Definition Player.cpp:4736
void DurabilityLoss(Item *item, double percent)
Definition Player.cpp:4762

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)
4414{
4416 return;
4417
4418 // this is only item spell effect applied to main-hand weapon of target player (players in area)
4419 if (!unitTarget)
4420 return;
4421
4422 Player* item_owner = unitTarget->ToPlayer();
4423 if (!item_owner)
4424 {
4425 return;
4426 }
4427
4429 if (!item)
4430 return;
4431
4432 // must be equipped
4433 if (!item->IsEquipped())
4434 return;
4435
4436 if (m_spellInfo->Effects[effIndex].MiscValue)
4437 {
4438 uint32 enchant_id = m_spellInfo->Effects[effIndex].MiscValue;
4439 int32 duration = m_spellInfo->GetDuration(); //Try duration index first ..
4440 if (!duration)
4441 duration = damage * IN_MILLISECONDS; //+1; //Base points after ..
4442 if (!duration)
4443 duration = 10 * IN_MILLISECONDS; //10 seconds for enchants which don't have listed duration
4444
4445 // Xinef: Venomhide poison, no other spell uses this effect...
4446 if (m_spellInfo->Id == 14792)
4447 duration = 5 * MINUTE * IN_MILLISECONDS;
4448
4449 SpellItemEnchantmentEntry const* pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id);
4450 if (!pEnchant)
4451 return;
4452
4453 // Always go to temp enchantment slot
4455
4456 // Enchantment will not be applied if a different one already exists
4457 if (item->GetEnchantmentId(slot) && item->GetEnchantmentId(slot) != enchant_id)
4458 return;
4459
4460 // Apply the temporary enchantment
4461 item->SetEnchantment(slot, enchant_id, duration, pEnchant->charges, m_caster->GetGUID());
4462 item_owner->ApplyEnchantment(item, slot, true);
4463 }
4464}
EnchantmentSlot
Definition Item.h:168
@ TEMP_ENCHANTMENT_SLOT
Definition Item.h:170
@ EQUIPMENT_SLOT_MAINHAND
Definition Player.h:685
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:4303
uint32 charges
Definition DBCStructure.h:1844

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)
2841{
2843 return;
2844
2845 if (!m_caster->IsPlayer())
2846 return;
2847 if (!itemTarget)
2848 return;
2849
2850 Player* p_caster = m_caster->ToPlayer();
2851
2852 // Handle vellums
2854 {
2855 // destroy one vellum from stack
2856 uint32 count = 1;
2857 p_caster->DestroyItemCount(itemTarget, count, true);
2858 unitTarget = p_caster;
2859 // and add a scroll
2860 DoCreateItem(effIndex, m_spellInfo->Effects[effIndex].ItemType);
2861 itemTarget = nullptr;
2862 m_targets.SetItemTarget(nullptr);
2863 }
2864 else
2865 {
2866 // do not increase skill if vellum used
2868 p_caster->UpdateCraftSkill(m_spellInfo->Id);
2869
2870 uint32 enchant_id = m_spellInfo->Effects[effIndex].MiscValue;
2871 if (!enchant_id)
2872 return;
2873
2874 SpellItemEnchantmentEntry const* pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id);
2875 if (!pEnchant)
2876 return;
2877
2878 // item can be in trade slot and have owner diff. from caster
2879 Player* item_owner = itemTarget->GetOwner();
2880 if (!item_owner)
2881 return;
2882
2883 // remove old enchanting before applying new if equipped
2885
2887
2888 // add new enchanting if equipped
2890
2891 item_owner->RemoveTradeableItem(itemTarget);
2893 }
2894}
@ PERM_ENCHANTMENT_SLOT
Definition Item.h:169
void ClearSoulboundTradeable(Player *currentOwner)
Definition Item.cpp:1264
void RemoveTradeableItem(Item *item)
Definition PlayerStorage.cpp:4138
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)
2897{
2899 return;
2900
2901 if (!m_caster->IsPlayer())
2902 return;
2903 if (!itemTarget)
2904 return;
2905
2906 uint32 enchant_id = m_spellInfo->Effects[effIndex].MiscValue;
2907 if (!enchant_id)
2908 return;
2909
2910 SpellItemEnchantmentEntry const* pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id);
2911 if (!pEnchant)
2912 return;
2913
2914 // support only enchantings with add socket in this slot
2915 {
2916 bool add_socket = false;
2917 for (uint8 i = 0; i < MAX_SPELL_ITEM_ENCHANTMENT_EFFECTS; ++i)
2918 {
2919 if (pEnchant->type[i] == ITEM_ENCHANTMENT_TYPE_PRISMATIC_SOCKET)
2920 {
2921 add_socket = true;
2922 break;
2923 }
2924 }
2925 if (!add_socket)
2926 {
2927 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.",
2929 return;
2930 }
2931 }
2932
2933 // item can be in trade slot and have owner diff. from caster
2934 Player* item_owner = itemTarget->GetOwner();
2935 if (!item_owner)
2936 return;
2937
2938 // remove old enchanting before applying new if equipped
2940
2942
2943 // add new enchanting if equipped
2945
2946 item_owner->RemoveTradeableItem(itemTarget);
2948}

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

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:668
@ SPELLFAMILY_POTION
Definition SharedDefines.h:3807
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
void EnergizeBySpell(Unit *victim, uint32 SpellID, uint32 Damage, Powers powertype)
Definition Unit.cpp:11348
void SendSpellDamageImmune(Unit *target, uint32 spellId)
Definition Unit.cpp:6568
auto SelectRandomContainerElement(C const &container) -> typename std::add_const< decltype(*std::begin(container))>::type &
Definition Containers.h:133

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:834
uint32 EnvironmentalDamage(EnviromentalDamage type, uint32 damage)
Definition Player.cpp:768

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
4520{
4522 return;
4523
4524 Player* player = m_caster->ToPlayer();
4525 if (!player)
4526 return;
4527
4528 Item* foodItem = itemTarget;
4529 if (!foodItem)
4530 return;
4531
4532 Pet* pet = player->GetPet();
4533 if (!pet)
4534 return;
4535
4536 if (!pet->IsAlive())
4537 return;
4538
4539 int32 benefit = pet->GetCurrentFoodBenefitLevel(foodItem->GetTemplate()->ItemLevel);
4540 if (benefit <= 0)
4541 return;
4542
4543 ExecuteLogEffectDestroyItem(effIndex, foodItem->GetEntry());
4544
4545 uint32 count = 1;
4546 player->DestroyItemCount(foodItem, count, true);
4548
4549 m_caster->CastCustomSpell(pet, m_spellInfo->Effects[effIndex].TriggerSpell, &benefit, nullptr, nullptr, true);
4550}
void ExecuteLogEffectDestroyItem(uint8 effIndex, uint32 entry)
Definition Spell.cpp:5088

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

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, and Cell::VisitObjects().

◆ EffectGameObjectDamage()

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

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)
5945{
5947 return;
5948
5950 return;
5951
5954}
GameObjectDestructibleState
Definition SharedDefines.h:1637
void SetDestructibleState(GameObjectDestructibleState state, Player *eventInvoker=nullptr, bool setHealth=false)
Definition GameObject.cpp:2332

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:3801
@ SPELLFAMILY_DEATHKNIGHT
Definition SharedDefines.h:3809
@ AURA_STATE_SWIFTMEND
Definition SharedDefines.h:1318
@ SPELL_SCHOOL_MASK_HOLY
Definition SharedDefines.h:309
@ SPELL_AURA_PERIODIC_HEAL
Definition SpellAuraDefines.h:71
@ DOT
Definition Unit.h:252
SpellInfo const * GetSpellInfo() const
Definition SpellAuraEffects.h:54
uint32 GetId() const
Definition SpellAuraEffects.cpp:433
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
uint32 CountPctFromMaxHealth(int32 pct) const
Definition Unit.h:1083

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)
3677{
3679 return;
3680
3681 if (!unitTarget || !unitTarget->IsAlive())
3682 return;
3683
3685 {
3687 return;
3688 }
3689
3690 int32 addhealth = 0;
3691
3692 // damage == 0 - heal for caster max health
3693 if (damage == 0)
3694 addhealth = m_caster->GetMaxHealth();
3695 else
3696 addhealth = unitTarget->GetMaxHealth() - unitTarget->GetHealth();
3697
3698 m_healing += addhealth;
3699}
uint32 GetMaxHealth() const
Definition Unit.h:1071

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:11868
uint32 SpellDamageBonusDone(Unit *victim, SpellInfo const *spellProto, uint32 pdamage, DamageEffectType damagetype, uint8 effIndex, float TotalMod=0.0f, uint32 stack=1)
Definition Unit.cpp:11692

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

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}
@ CHEAT_GOD
Definition Player.h:994
@ SPELL_SCHOOL_MASK_NORMAL
Definition SharedDefines.h:308
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:824
@ SMSG_SPELLINSTAKILLLOG
Definition Opcodes.h:845

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
3702{
3704 return;
3705
3706 if (!unitTarget || !unitTarget->IsAlive())
3707 return;
3708
3710 // also exist case: apply cooldown to interrupted cast only and to all spells
3711 // there is no CURRENT_AUTOREPEAT_SPELL spells that can be interrupted
3713 {
3715 {
3716 SpellInfo const* curSpellInfo = spell->m_spellInfo;
3717 // check if we can interrupt spell
3718 if ((spell->getState() == SPELL_STATE_CASTING
3719 || (spell->getState() == SPELL_STATE_PREPARING && spell->GetCastTime() > 0.0f))
3723 {
3724 if (m_originalCaster)
3725 {
3727 unitTarget->ProhibitSpellSchool(curSpellInfo->GetSchoolMask(), duration/*spellInfo->GetDuration()*/);
3728 }
3729 ExecuteLogEffectInterruptCast(effIndex, unitTarget, curSpellInfo->Id);
3731 }
3732 }
3733 }
3734}
@ 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:545
CurrentSpellTypes
Definition Unit.h:538
@ CURRENT_CHANNELED_SPELL
Definition Unit.h:541
@ CURRENT_AUTOREPEAT_SPELL
Definition Unit.h:542
uint32 ChannelInterruptFlags
Definition SpellInfo.h:354
uint32 InterruptFlags
Definition SpellInfo.h:352
void ExecuteLogEffectInterruptCast(uint8 effIndex, Unit *victim, uint32 spellId)
Definition Spell.cpp:5061
void InterruptSpell(CurrentSpellTypes spellType, bool withDelayed=true, bool withInstant=true, bool bySelf=false)
Definition Unit.cpp:4116
int32 CalcSpellDuration(SpellInfo const *spellProto)
Definition Unit.cpp:14885
virtual void ProhibitSpellSchool(SpellSchoolMask, uint32)
Definition Unit.h:1543

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}
void MoveJump(Position const &pos, float speedXY, float speedZ, uint32 id=0)
Definition MotionMaster.h:244
void CalculateJumpSpeeds(uint8 i, float dist, float &speedxy, float &speedz)
Definition SpellEffects.cpp:1153
float GetExactDist2d(const float x, const float y) const
Definition Position.h:170

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 GridTerrainData.h:27
@ UNIT_FIELD_TARGET
Definition UpdateFields.h:92
ObjectGuid GetGuidValue(uint16 index) const
Definition Object.cpp:326
bool IsValidMapCoord(float c)
Definition GridDefines.h:210

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)
5707{
5709 return;
5710
5711 if (!unitTarget)
5712 return;
5713
5715 if (!player)
5716 {
5717 return;
5718 }
5719
5720 int32 creatureEntry = m_spellInfo->Effects[effIndex].MiscValue;
5721 if (!creatureEntry)
5722 {
5723 if (m_spellInfo->Id == 42793) // Burn Body
5724 creatureEntry = 24008; // Fallen Combatant
5725 }
5726
5727 if (creatureEntry)
5728 player->RewardPlayerAndGroupAtEvent(creatureEntry, unitTarget);
5729}
void RewardPlayerAndGroupAtEvent(uint32 creature_id, WorldObject *pRewardSource)
Definition Player.cpp:12781

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)
5693{
5695 return;
5696
5697 if (!unitTarget)
5698 return;
5699
5701 {
5702 player->KilledMonsterCredit(m_spellInfo->Effects[effIndex].MiscValue);
5703 }
5704}

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

◆ EffectKnockBack()

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

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)
4706{
4708 return;
4709
4710 if (!unitTarget || unitTarget->IsInFlight())
4711 return;
4712
4713 if (!m_targets.HasDst())
4714 return;
4715
4716 Position dstpos = destTarget->GetPosition();
4718}
void NearTeleportTo(Position &pos, bool casting=false, bool vehicleTeleport=false, bool withPet=false, bool removeTransport=false)
Definition Unit.cpp:19738

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)
5037{
5039 return;
5040
5041 if (!unitTarget)
5042 return;
5043
5044 float speedxy = m_spellInfo->Effects[effIndex].MiscValue / 10.0f;
5045 float speedz = damage / 10.0f;
5046 //1891: Disengage
5048
5049 if (m_caster->IsPlayer())
5050 {
5051 sScriptMgr->AnticheatSetUnderACKmount(m_caster->ToPlayer());
5052 }
5053
5054 // xinef: changes fall time
5055 if (m_caster->IsPlayer())
5057}
@ SPELLFAMILY_HUNTER
Definition SharedDefines.h:3803
void JumpTo(float speedXY, float speedZ, bool forward=true)
Definition Unit.cpp:19286

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)
3262{
3264 return;
3265
3266 if (!unitTarget)
3267 return;
3268
3269 if (unitTarget->ToPlayer())
3270 {
3271 EffectLearnSpell(effIndex);
3272 return;
3273 }
3274 Pet* pet = unitTarget->ToPet();
3275 if (!pet)
3276 return;
3277
3278 SpellInfo const* learn_spellproto = sSpellMgr->GetSpellInfo(m_spellInfo->Effects[effIndex].TriggerSpell);
3279 if (!learn_spellproto)
3280 return;
3281
3282 pet->learnSpell(learn_spellproto->Id);
3284 pet->GetOwner()->PetSpellInitialize();
3285}
bool learnSpell(uint32 spell_id)
Definition Pet.cpp:1915
void EffectLearnSpell(SpellEffIndex effIndex)
Definition SpellEffects.cpp:2548

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)
2779{
2781 return;
2782
2783 if (!unitTarget->IsPlayer())
2784 return;
2785
2786 if (damage < 0)
2787 return;
2788
2789 uint32 skillid = m_spellInfo->Effects[effIndex].MiscValue;
2790 uint16 skillval = unitTarget->ToPlayer()->GetPureSkillValue(skillid);
2791 unitTarget->ToPlayer()->SetSkill(skillid, m_spellInfo->Effects[effIndex].CalcValue(), skillval ? skillval : 1, damage * 75);
2792}
uint16 GetPureSkillValue(uint32 skill) const
Definition Player.cpp:5534
void SetSkill(uint16 id, uint16 step, uint16 currVal, uint16 maxVal)
Definition Player.cpp:5348

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)
2549{
2551 return;
2552
2553 if (!unitTarget)
2554 return;
2555
2556 if (!unitTarget->IsPlayer())
2557 {
2558 if (unitTarget->ToPet())
2559 EffectLearnPetSpell(effIndex);
2560 return;
2561 }
2562
2563 Player* player = unitTarget->ToPlayer();
2564
2565 uint32 spellToLearn = (m_spellInfo->Id == 483 || m_spellInfo->Id == 55884) ? damage : m_spellInfo->Effects[effIndex].TriggerSpell;
2566 player->learnSpell(spellToLearn);
2567
2568 LOG_DEBUG("spells.aura", "Spell: Player {} has learned spell {} from Npc {}",
2569 player->GetGUID().ToString(), spellToLearn, m_caster->GetGUID().ToString());
2570}
void learnSpell(uint32 spellId, bool temporary=false, bool learnFromSkill=false)
Definition Player.cpp:3303
void EffectLearnPetSpell(SpellEffIndex effIndex)
Definition SpellEffects.cpp:3261

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)
5516{
5518 return;
5519
5520 if (!m_caster->IsPlayer())
5521 return;
5522
5523 Player* p_caster = m_caster->ToPlayer();
5525 return;
5526
5527 if (itemTarget->GetCount() < 5)
5528 return;
5529
5530 if (sWorld->getBoolConfig(CONFIG_SKILL_MILLING))
5531 {
5532 uint32 SkillValue = p_caster->GetPureSkillValue(SKILL_INSCRIPTION);
5533 uint32 reqSkillValue = itemTarget->GetTemplate()->RequiredSkillRank;
5534 p_caster->UpdateGatherSkill(SKILL_INSCRIPTION, SkillValue, reqSkillValue);
5535 }
5536
5538}
@ LOOT_MILLING
Definition LootMgr.h:87
@ CONFIG_SKILL_MILLING
Definition WorldConfig.h:51
void SendLoot(ObjectGuid guid, LootType loot_type)
Definition Player.cpp:7831
bool UpdateGatherSkill(uint32 SkillId, uint32 SkillValue, uint32 RedLevel, uint32 Multiplicator=1)
Definition PlayerUpdates.cpp:762

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)
5349{
5351 return;
5352
5353 if (!unitTarget)
5354 return;
5355
5357}
void ModifyThreatByPercent(Unit *victim, int32 percent)
Definition ThreatMgr.cpp:508
ThreatMgr & GetThreatMgr()
Definition Unit.h:936

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}
@ GO_JUST_DEACTIVATED
Definition GameObject.h:113
@ ITEM_FIELD_FLAG_UNLOCKED
Definition ItemTemplate.h:111
@ ITEM_CHANGED
Definition Item.h:210
@ LOOT_SKINNING
Definition LootMgr.h:85
#define sOutdoorPvPMgr
Definition OutdoorPvPMgr.h:102
@ GAMEOBJECT_TYPE_BUTTON
Definition SharedDefines.h:1572
@ GAMEOBJECT_TYPE_FLAGSTAND
Definition SharedDefines.h:1595
@ GAMEOBJECT_TYPE_GOOBER
Definition SharedDefines.h:1581
@ BATTLEGROUND_EY
Definition SharedDefines.h:3753
@ ITEM_FIELD_FLAGS
Definition UpdateFields.h:42
Unit * GetOwner() const
Definition GameObject.cpp:1219
LootState getLootState() const
Definition GameObject.h:223
void SetLootState(LootState s, Unit *unit=nullptr)
Definition GameObject.cpp:2434
bool IsInSkillupList(ObjectGuid const &playerGuid) const
Definition GameObject.cpp:3066
void AddToSkillupList(ObjectGuid const &playerGuid)
Definition GameObject.cpp:3060
void SetState(ItemUpdateState state, Player *forplayer=nullptr)
Definition Item.cpp:714
Definition Object.h:104
void ExecuteLogEffectOpenLock(uint8 effIndex, Object *obj)
Definition Spell.cpp:5076
void SendLoot(ObjectGuid guid, LootType loottype)
Definition SpellEffects.cpp:2015
Definition GameObjectData.h:31
struct GameObjectTemplate::@232::@243 goober
uint32 GetAutoCloseTime() const
Definition GameObjectData.h:510
struct GameObjectTemplate::@232::@235 button
uint32 noDamageImmune
Definition GameObjectData.h:48
uint32 losOK
Definition GameObjectData.h:64
uint32 GetLockId() const
Definition GameObjectData.h:427

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)
4688{
4690 return;
4691
4692 if (m_caster->IsPlayer())
4693 m_caster->ToPlayer()->SetCanParry(true);
4694}
void SetCanParry(bool value)
Definition Player.cpp:13172

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();
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:1639
@ 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, DynamicObject, 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)
6106{
6108 return;
6109
6110 if (!unitTarget)
6111 return;
6112
6113 Player* player = unitTarget->ToPlayer();
6114 if (!player)
6115 {
6116 return;
6117 }
6118
6119 uint32 soundid = m_spellInfo->Effects[effIndex].MiscValue;
6120
6121 if (!sSoundEntriesStore.LookupEntry(soundid))
6122 {
6123 LOG_ERROR("spells.effect", "EffectPlayMusic: Sound (Id: {}) not exist in spell {}.", soundid, m_spellInfo->Id);
6124 return;
6125 }
6126
6128}
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)
6159{
6161 return;
6162
6163 if (!unitTarget)
6164 return;
6165
6166 Player* player = unitTarget->ToPlayer();
6167 if (!player)
6168 {
6169 return;
6170 }
6171
6172 switch (m_spellInfo->Id)
6173 {
6174 case 58730: // Restricted Flight Area
6175 case 58600: // Restricted Flight Area
6177 break;
6178 default:
6179 break;
6180 }
6181
6182 uint32 soundId = m_spellInfo->Effects[effIndex].MiscValue;
6183
6184 if (!sSoundEntriesStore.LookupEntry(soundId))
6185 {
6186 LOG_ERROR("spells.effect", "EffectPlayerSound: Sound (Id: {}) not exist in spell {}.", soundId, m_spellInfo->Id);
6187 return;
6188 }
6189
6190 player->PlayDirectSound(soundId, player);
6191}
@ LANG_ZONE_NOFLYZONE
Definition Language.h:759
Definition Chat.h:37
void SendNotification(std::string_view str)
Definition Chat.cpp:105
void PlayDirectSound(uint32 sound_id, Player *target=nullptr)
Definition Object.cpp:2908

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}
void ExecuteLogEffectTakeTargetPower(uint8 effIndex, Unit *target, uint32 PowerType, uint32 powerTaken, float gainMultiplier)
Definition Spell.cpp:5045
int32 ModifyPower(Powers power, int32 val, bool withPowerUpdate=true)
Definition Unit.cpp:14237
uint32 GetSpellCritDamageReduction(uint32 damage) const
Definition Unit.h:1243

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:1360
void SendProficiency(ItemClass itemClass, uint32 itemSubclassMask)
Definition Player.cpp:10131
uint32 GetWeaponProficiency() const
Definition Player.h:1359
void AddArmorProficiency(uint32 newflag)
Definition Player.h:1358
void AddWeaponProficiency(uint32 newflag)
Definition Player.h:1357
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
2691{
2693 EffectNULL(effIndex);
2694}
void EffectNULL(SpellEffIndex effIndex)
Definition SpellEffects.cpp:238

References EffectNULL().

◆ EffectPullTowards()

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

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)
5060{
5062 return;
5063
5064 if (!unitTarget)
5065 return;
5066
5067 Player* player = unitTarget->ToPlayer();
5068 if (!player)
5069 {
5070 return;
5071 }
5072
5073 uint32 quest_id = m_spellInfo->Effects[effIndex].MiscValue;
5074
5075 Quest const* quest = sObjectMgr->GetQuestTemplate(quest_id);
5076
5077 if (!quest)
5078 return;
5079
5080 // Player has never done this quest
5081 if (player->GetQuestStatus(quest_id) == QUEST_STATUS_NONE)
5082 return;
5083
5084 // remove all quest entries for 'entry' from quest log
5085 for (uint8 slot = 0; slot < MAX_QUEST_LOG_SIZE; ++slot)
5086 {
5087 uint32 logQuest = player->GetQuestSlotQuestId(slot);
5088 if (logQuest == quest_id)
5089 {
5090 player->SetQuestSlot(slot, 0);
5091
5092 // we ignore unequippable quest items in this case, it's still be equipped
5093 player->TakeQuestSourceItem(logQuest, false);
5094
5095 if (quest->HasFlag(QUEST_FLAGS_FLAGS_PVP))
5096 {
5097 player->pvpInfo.IsHostile = player->pvpInfo.IsInHostileArea || player->HasPvPForcingQuest();
5098 player->UpdatePvPState();
5099 }
5100 }
5101 }
5102
5103 player->RemoveRewardedQuest(quest_id);
5104 player->RemoveActiveQuest(quest_id, false);
5105}
@ 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 HasPvPForcingQuest() const
Definition PlayerQuest.cpp:2495
void UpdatePvPState()
Definition PlayerUpdates.cpp:1436
uint32 GetQuestSlotQuestId(uint16 slot) const
Definition Player.h:1482
void SetQuestSlot(uint16 slot, uint32 quest_id, uint32 timer=0)
Definition Player.h:1486
PvPInfo pvpInfo
Definition Player.h:1842
bool TakeQuestSourceItem(uint32 questId, bool msg)
Definition PlayerQuest.cpp:1363
void RemoveActiveQuest(uint32 questId, bool update=true)
Definition PlayerQuest.cpp:1495
QuestStatus GetQuestStatus(uint32 quest_id) const
Definition PlayerQuest.cpp:1430
void RemoveRewardedQuest(uint32 questId, bool update=true)
Definition PlayerQuest.cpp:1513
Definition QuestDef.h:210
bool HasFlag(uint32 flag) const
Definition QuestDef.h:221
bool IsHostile
Definition Player.h:356
bool IsInHostileArea
Definition Player.h:357

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)
4747{
4749 return;
4750
4751 if (!unitTarget)
4752 return;
4753
4754 Player* player = unitTarget->ToPlayer();
4755 if (!player)
4756 {
4757 return;
4758 }
4759
4760 uint32 questId = m_spellInfo->Effects[effIndex].MiscValue;
4761 if (questId)
4762 {
4763 Quest const* quest = sObjectMgr->GetQuestTemplate(questId);
4764 if (!quest)
4765 return;
4766
4767 uint16 logSlot = player->FindQuestSlot(questId);
4768 if (logSlot < MAX_QUEST_LOG_SIZE)
4769 player->AreaExploredOrEventHappens(questId);
4770 else if (player->CanTakeQuest(quest, false)) // Check if the quest has already been turned in.
4771 player->SetRewardedQuest(questId); // If not, set status to rewarded without broadcasting it to client.
4772 }
4773}
uint16 FindQuestSlot(uint32 quest_id) const
Definition PlayerQuest.cpp:1782
bool CanTakeQuest(Quest const *quest, bool msg)
Definition PlayerQuest.cpp:251
void SetRewardedQuest(uint32 quest_id)
Definition PlayerQuest.cpp:880
void AreaExploredOrEventHappens(uint32 questId)
Definition PlayerQuest.cpp:1791

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)
5732{
5734 return;
5735
5736 if (!unitTarget)
5737 return;
5738
5739 if (Player* player = unitTarget->ToPlayer())
5740 {
5741 player->FailQuest(m_spellInfo->Effects[effIndex].MiscValue);
5742 }
5743}

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

◆ EffectQuestStart()

void Spell::EffectQuestStart ( SpellEffIndex  effIndex)
5746{
5748 return;
5749
5750 if (!unitTarget)
5751 return;
5752
5753 Player* player = unitTarget->ToPlayer();
5754 if (!player)
5755 return;
5756
5757 if (Quest const* quest = sObjectMgr->GetQuestTemplate(m_spellInfo->Effects[effIndex].MiscValue))
5758 {
5759 if (!player->CanTakeQuest(quest, false))
5760 return;
5761
5762 if (quest->IsAutoAccept() && player->CanAddQuest(quest, false))
5763 player->AddQuestAndCheckCompletion(quest, player);
5764
5765 player->PlayerTalkClass->SendQuestGiverQuestDetails(quest, player->GetGUID(), true);
5766 }
5767}
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:421
PlayerMenu * PlayerTalkClass
Definition Player.h:2243

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

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)
5906{
5908 return;
5909
5910 if (unitTarget)
5912}
void SetRedirectThreat(ObjectGuid guid, uint32 pct)
Definition Unit.h:943

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

◆ EffectRemoveAura()

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

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

◆ EffectRenamePet()

void Spell::EffectRenamePet ( SpellEffIndex  effIndex)
6094{
6096 return;
6097
6098 if (!unitTarget || !unitTarget->IsCreature() ||
6100 return;
6101
6103}
@ UNIT_CAN_BE_RENAMED
Definition UnitDefines.h:149
@ UNIT_FIELD_BYTES_2
Definition UpdateFields.h:161
void SetByteFlag(uint16 index, uint8 offset, uint8 newFlag)
Definition Object.cpp:900
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)
4721{
4723 return;
4724
4725 if (!unitTarget)
4726 return;
4727
4728 Player* player = unitTarget->ToPlayer();
4729 if (!player)
4730 {
4731 return;
4732 }
4733
4734 float repChange = static_cast<float>(damage);
4735
4736 uint32 factionId = m_spellInfo->Effects[effIndex].MiscValue;
4737
4738 FactionEntry const* factionEntry = sFactionStore.LookupEntry(factionId);
4739 if (!factionEntry)
4740 return;
4741
4742 repChange = player->CalculateReputationGain(REPUTATION_SOURCE_SPELL, 0, repChange, factionId);
4743 player->GetReputationMgr().ModifyReputation(factionEntry, repChange);
4744}
DBCStorage< FactionEntry > sFactionStore(FactionEntryfmt)
@ REPUTATION_SOURCE_SPELL
Definition SharedDefines.h:198
float CalculateReputationGain(ReputationSource source, uint32 creatureOrQuestLevel, float rep, int32 faction, bool noQuestBonus=false)
Definition Player.cpp:5888
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:907

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)
4639{
4641 return;
4642
4643 if (!unitTarget)
4644 return;
4645
4646 if (!unitTarget)
4647 return;
4648
4649 Player* target = unitTarget->ToPlayer();
4650 if (!target)
4651 {
4652 return;
4653 }
4654
4655 if (unitTarget->IsAlive() || !unitTarget->IsInWorld())
4656 return;
4657
4658 if (target->isResurrectRequested()) // already have one active request
4659 return;
4660
4661 uint32 health = target->CountPctFromMaxHealth(damage);
4663
4664 ExecuteLogEffectResurrect(effIndex, target);
4665
4667 SendResurrectRequest(target);
4668}
void setResurrectRequestData(ObjectGuid guid, uint32 mapId, float X, float Y, float Z, uint32 health, uint32 mana)
Definition Player.h:1811
bool isResurrectRequested() const
Definition Player.h:1823
void ExecuteLogEffectResurrect(uint8 effIndex, Unit *target)
Definition Spell.cpp:5106
void SendResurrectRequest(Player *target)
Definition Spell.cpp:5168

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
5198{
5200 return;
5201
5202 if (damage < 0)
5203 return;
5204
5205 Player* player = m_caster->ToPlayer();
5206 if (!player)
5207 {
5208 return;
5209 }
5210
5211 Pet* pet = player->GetPet();
5212 if (!pet)
5213 {
5214 // Position passed to SummonPet is irrelevant with current implementation,
5215 // pet will be relocated without using these coords in Pet::LoadPetFromDB
5216 player->SummonPet(0, 0.0f, 0.0f, 0.0f, 0.0f, SUMMON_PET, 0ms, damage);
5217 return;
5218 }
5219
5221 if (pet->IsAlive())
5222 {
5223 return;
5224 }
5225
5226 // Reposition the pet's corpse before reviving so as not to grab aggro
5227 // We can use a different, more accurate version of GetClosePoint() since we have a pet
5228 float x, y, z; // Will be used later to reposition the pet if we have one
5229 player->GetClosePoint(x, y, z, pet->GetCombatReach(), PET_FOLLOW_DIST, pet->GetFollowAngle());
5230 pet->NearTeleportTo(x, y, z, player->GetOrientation());
5231 pet->Relocate(x, y, z, player->GetOrientation()); // This is needed so SaveStayPosition() will get the proper coords.
5235 pet->ClearUnitState(uint32(UNIT_STATE_ALL_STATE & ~(UNIT_STATE_POSSESSED))); // xinef: just in case
5237 pet->SetDisplayId(pet->GetNativeDisplayId());
5238
5239 // xinef: restore movement
5240 if (auto ci = pet->GetCharmInfo())
5241 {
5242 ci->SetIsAtStay(false);
5243 ci->SetIsFollowing(false);
5244 }
5245
5247}
constexpr float PET_FOLLOW_DIST
Definition PetDefines.h:206
@ SUMMON_PET
Definition PetDefines.h:32
@ UNIT_DYNFLAG_NONE
Definition SharedDefines.h:3370
@ UNIT_STATE_POSSESSED
Definition UnitDefines.h:186
@ UNIT_STATE_ALL_STATE
Definition UnitDefines.h:224
float GetFollowAngle() const override
Definition TemporarySummon.h:83
void setDeathState(DeathState s, bool despawn=false) override
A creature can be in 4 different states: Alive, JustDied, Corpse, and JustRespawned....
Definition Pet.cpp:626
void SetDisplayId(uint32 modelId, float displayScale=1.f) override
Definition Pet.cpp:2424
Pet * SummonPet(uint32 entry, float x, float y, float z, float ang, PetType petType, Milliseconds duration=0ms, uint32 healthPct=0)
Definition Player.cpp:9000
void ReplaceAllDynamicFlags(uint32 flag) override
Definition Unit.h:754
void SetHealth(uint32 val)
Definition Unit.cpp:15507
uint32 GetNativeDisplayId() const
Definition Unit.h:1930
void RemoveUnitFlag(UnitFlags flags)
UnitFlags available in UnitDefines.h.
Definition Unit.h:734
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:2717

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

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::VisitObjects().

◆ 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}
#define MAX_ITEM_PROTO_DAMAGES
Definition ItemTemplate.h:613
@ EFFECT_2
Definition SharedDefines.h:33
@ POWER_ENERGY
Definition SharedDefines.h:283
@ SPELLFAMILY_PRIEST
Definition SharedDefines.h:3800
@ AURA_STATE_CONFLAGRATE
Definition SharedDefines.h:1317
@ 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
@ SPELL_ATTR0_CU_SHARE_DAMAGE
Definition SpellInfo.h:179
@ FORM_SHADOW
Definition UnitDefines.h:95
@ MINDAMAGE
Definition Unit.h:137
@ MAXDAMAGE
Definition Unit.h:138
uint8 GetStackAmount() const
Definition SpellAuras.h:148
float GetTotalAttackPowerValue(WeaponAttackType attType, Unit *pVictim=nullptr) const
Definition Unit.cpp:15457
float ApplyEffectModifiers(SpellInfo const *spellProto, uint8 effect_index, float value) const
Definition Unit.cpp:14858
virtual uint32 GetShieldBlockValue() const =0
void RemoveAuraFromStack(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition Unit.cpp:4993
uint32 GetAttackTime(WeaponAttackType att) const
Definition Unit.h:897
AuraEffect * GetDummyAuraEffect(SpellFamilyNames name, uint32 iconId, uint8 effIndex) const
Definition Unit.h:1400

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

References BATTLEGROUND_SA, Unit::CastCustomSpell(), Unit::CastSpell(), Corpse, 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_FIRE, Unit::TextEmote(), Object::ToCreature(), Object::ToPlayer(), Unit::ToTempSummon(), unitTarget, TempSummon::UnSummon(), and urand().

◆ EffectSelfResurrect()

void Spell::EffectSelfResurrect ( SpellEffIndex  effIndex)
4849{
4851 return;
4852
4853 if (!m_caster || m_caster->IsAlive())
4854 return;
4855 if (!m_caster->IsPlayer())
4856 return;
4857 if (!m_caster->IsInWorld())
4858 return;
4859
4860 uint32 health = 0;
4861 uint32 mana = 0;
4862
4863 // flat case
4864 if (damage < 0)
4865 {
4866 health = uint32(-damage);
4867 mana = m_spellInfo->Effects[effIndex].MiscValue;
4868 }
4869 // percent case
4870 else
4871 {
4875 }
4876
4877 Player* player = m_caster->ToPlayer();
4878 player->ResurrectPlayer(0.0f);
4879
4880 player->SetHealth(health);
4881 player->SetPower(POWER_MANA, mana);
4882 player->SetPower(POWER_RAGE, 0);
4883 player->SetPower(POWER_ENERGY, player->GetMaxPower(POWER_ENERGY));
4884
4885 player->SpawnCorpseBones();
4886}
@ POWER_RAGE
Definition SharedDefines.h:281
void SpawnCorpseBones(bool triggerSave=true)
Definition Player.cpp:4706
void ResurrectPlayer(float restore_percent, bool applySickness=false)
Definition Player.cpp:4487
void SetPower(Powers power, uint32 val, bool withPowerUpdate=true, bool fromRegenerate=false)
Definition Unit.cpp:15595

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:472
ZoneScript * GetZoneScript() const
Definition Object.h:627
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)
5108{
5110 return;
5111
5112 if (!unitTarget)
5113 return;
5114
5115 if (Player* player = unitTarget->ToPlayer())
5116 {
5117 player->ActivateTaxiPathTo(m_spellInfo->Effects[effIndex].MiscValue, m_spellInfo->Id);
5118 }
5119}

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

◆ EffectSkill()

void Spell::EffectSkill ( SpellEffIndex  effIndex)
5541{
5543 return;
5544
5545 LOG_DEBUG("spells.aura", "WORLD: SkillEFFECT");
5546}

References effectHandleMode, LOG_DEBUG, and SPELL_EFFECT_HANDLE_HIT.

◆ EffectSkinning()

void Spell::EffectSkinning ( SpellEffIndex  effIndex)
4889{
4891 return;
4892
4893 if (!unitTarget->IsCreature())
4894 return;
4895 if (!m_caster->IsPlayer())
4896 return;
4897
4898 Creature* creature = unitTarget->ToCreature();
4899 int32 targetLevel = creature->GetLevel();
4900
4901 uint32 skill = creature->GetCreatureTemplate()->GetRequiredLootSkill();
4902
4906
4907 int32 reqValue = targetLevel < 10 ? 0 : targetLevel < 20 ? (targetLevel - 10) * 10 : targetLevel * 5;
4908
4909 int32 skillValue = m_caster->ToPlayer()->GetPureSkillValue(skill);
4910
4911 // Double chances for elites
4912 m_caster->ToPlayer()->UpdateGatherSkill(skill, skillValue, reqValue, creature->isElite() ? 2 : 1);
4913}
@ UNIT_DYNFLAG_LOOTABLE
Definition SharedDefines.h:3371
bool isElite() const
Definition Creature.h:116
virtual void SetDynamicFlag(uint32 flag)
Definition Object.h:124

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)
5572{
5574 return;
5575
5576 LOG_DEBUG("spells.aura", "Effect: SkinPlayerCorpse");
5577 if ((!m_caster->IsPlayer()) || (!unitTarget->IsPlayer()) || (unitTarget->IsAlive()))
5578 return;
5579
5581
5582 // We have a corpse object as the target.
5583 // This target was deleted in RemovedInsignia() -> ConvertCorpseToBones().
5585}
void RemovedInsignia(Player *looterPlr)
Definition Player.cpp:7792
void RemoveObjectTarget()
Definition Spell.cpp:321

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

◆ EffectSpecCount()

void Spell::EffectSpecCount ( SpellEffIndex  effIndex)
6131{
6133 return;
6134
6135 if (!unitTarget)
6136 return;
6137
6138 if (Player* player = unitTarget->ToPlayer())
6139 {
6140 player->UpdateSpecCount(damage);
6141 }
6142}

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

◆ EffectSpiritHeal()

void Spell::EffectSpiritHeal ( SpellEffIndex  effIndex)
5553{
5555 return;
5556
5557 /*
5558 if (!unitTarget->IsPlayer())
5559 return;
5560 if (!unitTarget->IsInWorld())
5561 return;
5562
5563 //m_spellInfo->Effects[i].BasePoints; == 99 (percent?)
5564 //unitTarget->ToPlayer()->setResurrect(m_caster->GetGUID(), unitTarget->GetPositionX(), unitTarget->GetPositionY(), unitTarget->GetPositionZ(), unitTarget->GetMaxHealth(), unitTarget->GetMaxPower(POWER_MANA));
5565 unitTarget->ToPlayer()->ResurrectPlayer(1.0f);
5566 unitTarget->ToPlayer()->SpawnCorpseBones();
5567 */
5568}

References effectHandleMode, and SPELL_EFFECT_HANDLE_HIT_TARGET.

◆ EffectStealBeneficialBuff()

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

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)
4180{
4182 return;
4183
4184 if (!m_caster->IsPlayer())
4185 return;
4186
4187 Player* target = m_caster->ToPlayer();
4188 if (target->IsInFlight())
4189 return;
4190
4191 // xinef: if player is dead - teleport to graveyard
4192 if (!target->IsAlive())
4193 {
4194 if (target->HasPreventResurectionAura())
4195 return;
4196
4197 // xinef: player is in corpse
4198 if (!target->HasPlayerFlag(PLAYER_FLAGS_GHOST))
4199 target->BuildPlayerRepop();
4200 target->RepopAtGraveyard();
4201 return;
4202 }
4203
4204 // xinef: no hearthstone in bag or on cooldown
4205 Item* hearthStone = target->GetItemByEntry(6948);
4206 if (!hearthStone || target->HasSpellCooldown(8690))
4207 {
4208 float o = rand_norm() * 2 * M_PI;
4209 Position pos = *target;
4210 target->MovePositionToFirstCollision(pos, 5.0f, o);
4211 target->NearTeleportTo(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), target->GetOrientation());
4212 return;
4213 }
4214
4215 // xinef: we have hearthstone not on cooldown, just use it
4217}
@ PLAYER_FLAGS_GHOST
Definition Player.h:472
double rand_norm()
Definition Random.cpp:85
void RepopAtGraveyard()
Definition Player.cpp:4938
void BuildPlayerRepop()
Definition Player.cpp:4438
bool HasPreventResurectionAura() const
Definition Unit.h:1762
void MovePositionToFirstCollision(Position &pos, float dist, float angle)
Definition Object.cpp:2876

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:1264
InventoryResult CanEquipItem(uint8 slot, uint16 &dest, Item *pItem, bool swap, bool not_loading=true) const
Definition PlayerStorage.cpp:1806
Item * BankItem(ItemPosCountVec const &dest, Item *pItem, bool update)
Definition Player.h:1333
InventoryResult CanStoreItem(uint8 bag, uint8 slot, ItemPosCountVec &dest, Item *pItem, bool swap=false) const
Definition Player.h:1284
void UpdateEnchantmentDurations()
Definition PlayerStorage.cpp:4740
Item * StoreItem(ItemPosCountVec const &pos, Item *pItem, bool update)
Definition PlayerStorage.cpp:2580
void DestroyItem(uint8 bag, uint8 slot, bool update)
Definition PlayerStorage.cpp:3024
static bool IsInventoryPos(uint16 pos)
Definition Player.h:1262
void AutoUnequipOffhandIfNeed(bool force=false)
Definition Player.cpp:12513
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:2038
void ItemAddedQuestCheck(uint32 entry, uint32 count)
Definition PlayerQuest.cpp:1835
static bool IsBankPos(uint16 pos)
Definition Player.h:1267

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

References Unit::AddGameObject(), Map::AddToMap(), ObjectGuid::Clear(), GameObject::Create(), DEFAULT_WORLD_OBJECT_SIZE, destTarget, effectHandleMode, SpellInfo::Effects, ExecuteLogEffectSummonObject(), GameObject, 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)
3737{
3739 return;
3740
3741 uint32 gameobject_id = m_spellInfo->Effects[effIndex].MiscValue;
3742
3743 GameObject* pGameObj = sObjectMgr->IsGameObjectStaticTransport(gameobject_id) ? new StaticTransport() : new GameObject();
3744
3745 WorldObject* target = focusObject;
3746 if (!target)
3747 target = m_caster;
3748
3749 float x, y, z;
3750 if (m_targets.HasDst())
3751 destTarget->GetPosition(x, y, z);
3752 else
3754
3755 Map* map = target->GetMap();
3756
3757 if (!pGameObj->Create(map->GenerateLowGuid<HighGuid::GameObject>(), gameobject_id, map, m_caster->GetPhaseMask(), x, y, z, target->GetOrientation(), G3D::Quat(), 100, GO_STATE_READY))
3758 {
3759 delete pGameObj;
3760 return;
3761 }
3762
3763 int32 duration = m_spellInfo->GetDuration();
3764
3765 pGameObj->SetRespawnTime(duration > 0 ? duration / IN_MILLISECONDS : 0);
3766 pGameObj->SetSpellId(m_spellInfo->Id);
3767
3768 ExecuteLogEffectSummonObject(effIndex, pGameObj);
3769
3770 // Wild object not have owner and check clickable by players
3771 map->AddToMap(pGameObj, true);
3772
3773 if (pGameObj->GetGoType() == GAMEOBJECT_TYPE_FLAGDROP)
3774 if (Player* player = m_caster->ToPlayer())
3775 if (Battleground* bg = player->GetBattleground())
3776 bg->SetDroppedFlagGUID(pGameObj->GetGUID(), player->GetTeamId() == TEAM_ALLIANCE ? TEAM_HORDE : TEAM_ALLIANCE);
3777
3778 if (GameObject* linkedTrap = pGameObj->GetLinkedTrap())
3779 {
3780 linkedTrap->SetRespawnTime(duration > 0 ? duration/IN_MILLISECONDS :0);
3781 linkedTrap->SetSpellId(m_spellInfo->Id);
3782 ExecuteLogEffectSummonObject(effIndex, linkedTrap);
3783 }
3784}
@ GAMEOBJECT_TYPE_FLAGDROP
Definition SharedDefines.h:1597
@ TEAM_ALLIANCE
Definition SharedDefines.h:771
@ TEAM_HORDE
Definition SharedDefines.h:772
GameObject * GetLinkedTrap()
Definition GameObject.cpp:2727
GameobjectTypes GetGoType() const
Definition GameObject.h:202

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

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)
4220{
4221 // workaround - this effect should not use target map
4223 return;
4224
4225 if (!unitTarget)
4226 return;
4227
4228 Player* player = unitTarget->ToPlayer();
4229 if (!player)
4230 {
4231 return;
4232 }
4233
4234 // Evil Twin (ignore player summon, but hide this for summoner)
4235 // Xinef: Unit Target may be on other map!!!, Need workaround
4236 if (unitTarget->HasAura(23445))
4237 return;
4238
4239 float x, y, z;
4240 m_caster->GetPosition(x, y, z);
4241
4242 player->SetSummonPoint(m_caster->GetMapId(), x, y, z);
4243
4244 WorldPacket data(SMSG_SUMMON_REQUEST, 8 + 4 + 4);
4245 data << m_caster->GetGUID(); // summoner guid
4246 data << uint32(m_caster->GetZoneId()); // summoner zone
4247 data << uint32(MAX_PLAYER_SUMMON_DELAY * IN_MILLISECONDS); // auto decline after msecs
4248 player->SendDirectMessage(&data);
4249}
#define MAX_PLAYER_SUMMON_DELAY
Definition Player.h:924
void SetSummonPoint(uint32 mapid, float x, float y, float z, uint32 delay=0, bool asSpectator=false)
Definition Player.cpp:16345
@ SMSG_SUMMON_REQUEST
Definition Opcodes.h:713

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

◆ EffectSummonRaFFriend()

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

References effectHandleMode, Object::GetGUID(), WorldLocation::GetMapId(), Position::GetPosition(), WorldObject::GetZoneId(), IN_MILLISECONDS, Object::IsPlayer(), m_caster, MAX_PLAYER_SUMMON_DELAY, Player::SendDirectMessage(), 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 }
2433 // For companions, recalculate the position to ensure they spawn at the intended π/4 angle.
2437 ));
2438 [[fallthrough]];
2439 case SUMMON_TYPE_JEEVES:
2440 {
2441 summon = m_caster->GetMap()->SummonCreature(entry, *destTarget, properties, duration, m_originalCaster, m_spellInfo->Id, 0, personalSpawn);
2442 if (!summon || !summon->HasUnitTypeMask(UNIT_MASK_MINION))
2443 return;
2444
2445 summon->SelectLevel(); // some summoned creaters have different from 1 DB data for level/hp
2447
2448 summon->SetImmuneToAll(true);
2450
2451 // Xinef: Pet can have some auras in creature_addon or in scripts, do not remove them instantly
2452 //summon->AI()->EnterEvadeMode();
2453 if (properties->Type != SUMMON_TYPE_JEEVES)
2454 {
2456 summon->GetMotionMaster()->Clear(false);
2458 }
2459 break;
2460 }
2461 default:
2462 {
2463 float radius = m_spellInfo->Effects[effIndex].CalcRadius();
2464
2465 TempSummonType summonType = (duration <= 0) ? TEMPSUMMON_DEAD_DESPAWN : TEMPSUMMON_TIMED_DESPAWN;
2466
2467 for (uint32 count = 0; count < numSummons; ++count)
2468 {
2469 Position pos;
2470 if (count == 0)
2471 pos = *destTarget;
2472 else
2473 // randomize position for multiple summons
2474 pos = m_caster->GetRandomPoint(*destTarget, radius);
2475
2476 summon = m_originalCaster->SummonCreature(entry, pos, summonType, duration, 0, nullptr, personalSpawn);
2477 if (!summon)
2478 continue;
2479
2480 summon->SetTempSummonType(summonType);
2481
2482 if (properties->Category == SUMMON_CATEGORY_ALLY)
2483 {
2486 }
2487
2488 ExecuteLogEffectSummonObject(effIndex, summon);
2489 }
2490 return;
2491 }
2492 }//switch
2493 break;
2495 // Xinef: SummonGuardian function can summon a few npcs of same type, remove old summons with same entry here
2496 if (m_originalCaster)
2498 SummonGuardian(effIndex, entry, properties, numSummons, personalSpawn);
2499 break;
2501 summon = m_caster->GetMap()->SummonCreature(entry, *destTarget, properties, duration, m_originalCaster, m_spellInfo->Id, 0, personalSpawn);
2502 break;
2504 // Summoning spells (usually triggered by npc_spellclick) that spawn a vehicle and that cause the clicker
2505 // to cast a ride vehicle spell on the summoned unit.
2506 //float x, y, z;
2507 //m_caster->GetClosePoint(x, y, z, DEFAULT_WORLD_OBJECT_SIZE);
2508 // xinef: vehicles summoned in air, eg. Cold Hearted quest
2509 if (std::fabs(m_caster->GetPositionZ() - destTarget->GetPositionZ()) > 6.0f)
2511
2512 summon = m_originalCaster->GetMap()->SummonCreature(entry, *destTarget, properties, duration, m_caster, m_spellInfo->Id, 0, personalSpawn);
2513 if (!summon || !summon->IsVehicle())
2514 return;
2515
2516 // The spell that this effect will trigger. It has SPELL_AURA_CONTROL_VEHICLE
2518 int32 basePoints = m_spellInfo->Effects[effIndex].CalcValue();
2519 if (basePoints > 1) // xinef: some summoning spells have value 1 - indicates vehicle seat
2520 {
2521 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(basePoints);
2522 if (spellInfo && spellInfo->HasAura(SPELL_AURA_CONTROL_VEHICLE))
2523 spellId = spellInfo->Id;
2524 }
2525
2526 // xinef: if we have small value, it indicates seat position
2527 if (basePoints > 0 && basePoints < MAX_VEHICLE_SEATS)
2528 m_originalCaster->CastCustomSpell(spellId, SPELLVALUE_BASE_POINT0, basePoints, summon, true);
2529 else
2530 m_originalCaster->CastSpell(summon, spellId, true);
2531
2532 // xinef: i think this is wrong, found only 2 vehicles with faction override and one of them should inherit caster faction...
2533 //uint32 faction = properties->Faction;
2534 //if (!faction)
2535 uint32 faction = m_originalCaster->GetFaction();
2536
2537 summon->SetFaction(faction);
2538 break;
2539 }
2540
2541 if (summon)
2542 {
2544 ExecuteLogEffectSummonObject(effIndex, summon);
2545 }
2546}
@ SUMMON_PROP_FLAG_ONLY_VISIBLE_TO_SUMMONER
Definition DBCEnums.h:428
#define MAX_VEHICLE_SEATS
Definition DBCStructure.h:2025
@ MOTION_SLOT_ACTIVE
Definition MotionMaster.h:64
TempSummonType
Definition Object.h:47
@ TEMPSUMMON_DEAD_DESPAWN
Definition Object.h:54
constexpr float MINI_PET_SUMMON_ANGLE
Definition PetDefines.h:208
constexpr float MINI_PET_FOLLOW_ANGLE
Definition PetDefines.h:209
@ SUMMON_TYPE_VEHICLE2
Definition SharedDefines.h:3554
@ SUMMON_TYPE_LIGHTWELL
Definition SharedDefines.h:3555
@ SUMMON_TYPE_MINION
Definition SharedDefines.h:3547
@ SUMMON_TYPE_GUARDIAN
Definition SharedDefines.h:3546
@ SUMMON_TYPE_JEEVES
Definition SharedDefines.h:3556
@ SUMMON_TYPE_PET
Definition SharedDefines.h:3545
@ SUMMON_TYPE_TOTEM
Definition SharedDefines.h:3548
@ SUMMON_TYPE_VEHICLE
Definition SharedDefines.h:3553
@ SUMMON_TYPE_MINIPET
Definition SharedDefines.h:3549
@ SUMMON_TYPE_GUARDIAN2
Definition SharedDefines.h:3550
@ SUMMON_CATEGORY_VEHICLE
Definition SharedDefines.h:3537
@ SUMMON_CATEGORY_ALLY
Definition SharedDefines.h:3534
@ SUMMON_CATEGORY_WILD
Definition SharedDefines.h:3533
@ SUMMON_CATEGORY_UNK
Definition SharedDefines.h:3538
@ SPELL_AURA_CONTROL_VEHICLE
Definition SpellAuraDefines.h:299
@ UNIT_MASK_MINION
Definition UnitDefines.h:157
NPCFlags
Non Player Character flags.
Definition UnitDefines.h:317
@ REACT_PASSIVE
Definition Unit.h:550
@ VEHICLE_SPELL_RIDE_HARDCODED
Definition VehicleDefines.h:52
void SelectLevel(bool changelevel=true)
Definition Creature.cpp:1523
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:2165
void MoveFollow(Unit *target, float dist, float angle, MovementSlot slot=MOTION_SLOT_ACTIVE, bool inheritWalkState=true, bool inheritSpeed=true)
The unit will follow this target. Doesn't work with UNIT_FLAG_DISABLE_MOVE.
Definition MotionMaster.cpp:446
void Clear(bool reset=true)
Definition MotionMaster.h:182
void SetTempSummonType(TempSummonType type)
Definition TemporarySummon.cpp:282
void SetFacingToObject(WorldObject *object, Milliseconds timed=0ms)
Definition Unit.cpp:20290
void SetFaction(uint32 faction)
Definition Unit.cpp:10107
void SetOwnerGUID(ObjectGuid owner)
Definition Unit.cpp:10649
uint32 HasUnitTypeMask(uint32 mask) const
Definition Unit.h:726
void SetMaxHealth(uint32 val)
Definition Unit.cpp:15557
void SetCreatorGUID(ObjectGuid creator)
Definition Unit.h:701
void ReplaceAllNpcFlags(NPCFlags flags)
Definition Unit.h:751
void RemoveAllMinionsByEntry(uint32 entry)
Definition Unit.cpp:10939
void SetImmuneToAll(bool apply, bool keepCombat=false)
Definition Unit.h:907
Position GetNearPosition(float dist, float angle)
Definition Object.cpp:2746
float GetDistance2d(WorldObject const *obj) const
Definition Object.cpp:1296
void GetRandomPoint(const Position &srcPos, float distance, float &rand_x, float &rand_y, float &rand_z) const
Definition Object.cpp:1535
uint32 npcflag
Definition CreatureData.h:199
uint32 MiscVal[MAX_SPELL_EFFECTS]
Definition Spell.h:229
uint32 Flags
Definition DBCStructure.h:1916
uint32 Type
Definition DBCStructure.h:1914
uint32 Id
Definition DBCStructure.h:1911

References Unit::CastCustomSpell(), Unit::CastSpell(), SummonPropertiesEntry::Category, MotionMaster::Clear(), Unit::CountPctFromMaxHealth(), damage, destTarget, effectHandleMode, SpellInfo::Effects, ExecuteLogEffectSummonObject(), SummonPropertiesEntry::Flags, Creature::GetCreatureTemplate(), WorldObject::GetDistance2d(), SpellInfo::GetDuration(), Unit::GetFaction(), Object::GetGUID(), WorldObject::GetMap(), Unit::GetMotionMaster(), WorldObject::GetNearPosition(), Position::GetPositionX(), Position::GetPositionY(), 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, MINI_PET_FOLLOW_ANGLE, MINI_PET_SUMMON_ANGLE, SpellValue::MiscVal, MOTION_SLOT_ACTIVE, MotionMaster::MoveFollow(), CreatureTemplate::npcflag, PET_FOLLOW_DIST, REACT_PASSIVE, Position::Relocate(), Unit::RemoveAllMinionsByEntry(), Unit::ReplaceAllNpcFlags(), Creature::SelectLevel(), Unit::SetCreatorGUID(), Unit::SetFacingToObject(), 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)
3092{
3094 return;
3095
3096 if (m_caster->GetPetGUID())
3097 return;
3098
3099 if (!unitTarget)
3100 return;
3101
3102 if (!unitTarget->IsCreature())
3103 return;
3104
3105 Creature* creatureTarget = unitTarget->ToCreature();
3106
3107 if (creatureTarget->IsPet())
3108 return;
3109
3111 return;
3112
3113 // cast finish successfully
3114 //SendChannelUpdate(0);
3115 finish();
3116
3117 Pet* pet = m_caster->CreateTamedPetFrom(creatureTarget, m_spellInfo->Id);
3118 if (!pet) // in very specific state like near world end/etc.
3119 return;
3120
3121 // "kill" original creature
3122 creatureTarget->DespawnOrUnsummon();
3123
3124 uint8 level = (creatureTarget->GetLevel() < (m_caster->GetLevel() - 5)) ? (m_caster->GetLevel() - 5) : creatureTarget->GetLevel();
3125
3126 // prepare visual effect for levelup
3127 pet->SetUInt32Value(UNIT_FIELD_LEVEL, level - 1);
3128
3129 // add to world
3130 pet->GetMap()->AddToMap(pet->ToCreature(), true);
3131
3132 // visual effect for levelup
3133 pet->SetUInt32Value(UNIT_FIELD_LEVEL, level);
3134
3135 // caster have pet now
3136 m_caster->SetMinion(pet, true);
3137
3138 pet->InitTalentForLevel();
3139
3140 if (m_caster->IsPlayer())
3141 {
3144 }
3145}
@ 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)
3288{
3290 return;
3291
3292 if (!unitTarget)
3293 return;
3294
3295 // xinef: Hand of Reckoning, cast before checing canhavethreatlist. fixes damage against pets
3296 if (m_spellInfo->Id == 62124 && unitTarget->GetVictim() != m_caster)
3297 {
3298 m_caster->CastSpell(unitTarget, 67485, true);
3300 }
3301
3302 // this effect use before aura Taunt apply for prevent taunt already attacking target
3303 // for spell as marked "non effective at already attacking target"
3305 {
3307 return;
3308 }
3309
3311 {
3312 // Also use this effect to set the taunter's threat to the taunted creature's highest value
3313 float myThreat = unitTarget->GetThreatMgr().GetThreat(m_caster);
3315 if (topThreat > myThreat)
3316 unitTarget->GetThreatMgr().DoAddThreat(m_caster, topThreat - myThreat);
3317
3318 //Set aggro victim to caster
3320 unitTarget->GetThreatMgr().setCurrentVictim(forcedVictim);
3321 }
3322}
@ 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:14643

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:820
@ TELE_TO_GM_MODE
Definition Player.h:816
#define MAPID_INVALID
Definition Position.h:253
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:1350
Vehicle * GetVehicleKit() const
Definition Unit.h:1879
void TeleportVehicle(float x, float y, float z, float ang)
Definition Vehicle.cpp:565

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)
3662{
3664 return;
3665
3666 if (!unitTarget || !unitTarget->IsAlive() || !m_caster->IsAlive())
3667 return;
3668
3669 // xinef: skip if target cannot have threat list or caster is friendly (ghoul leap)
3671 return;
3672
3674}
void AddThreat(Unit *victim, float fThreat, SpellSchoolMask schoolMask=SPELL_SCHOOL_MASK_NORMAL, SpellInfo const *threatSpell=nullptr)
Definition Unit.cpp:14682

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)
5890{
5892 return;
5893
5894 if (m_caster->IsPlayer())
5895 {
5896 if (Aura* aur = m_caster->GetAura(49152))
5897 aur->RecalculateAmountOfEffects();
5898 else
5899 m_caster->CastSpell(unitTarget, 49152, true); // damage reduction
5900
5902 }
5903}
void SetCanTitanGrip(bool value)
Definition Player.cpp:13190

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)
2829{
2831 return;
2832
2833 if (!m_caster->IsPlayer())
2834 return;
2835 // uint32 skillid = m_spellInfo->Effects[i].MiscValue;
2836 // uint16 skillmax = unitTarget->ToPlayer()->(skillid);
2837 // m_caster->ToPlayer()->SetSkill(skillid, skillval?skillval:1, skillmax+75);
2838}

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

◆ EffectTransmitted()

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

References Unit::AddGameObject(), Map::AddToMap(), GameObject::AddUniqueUse(), GameObject::Create(), DEFAULT_WORLD_OBJECT_SIZE, destTarget, effectHandleMode, SpellInfo::Effects, ExecuteLogEffectSummonObject(), FISHING_BOBBER_READY_TIME, GameObject, 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:937
@ 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:931
@ SPELL_EFFECT_TRIGGER_SPELL
Definition SharedDefines.h:853
@ MECHANIC_BLEED
Definition SharedDefines.h:1351
@ DISPEL_ALL
Definition SharedDefines.h:1390
@ 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:178
void removeSpell(uint32 spellId, uint8 removeSpecMask, bool onlyTemporary)
Definition Player.cpp:3344

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)
2753{
2755 return;
2756
2757 if (!unitTarget || m_caster->IsPlayer())
2758 return;
2759
2760 if (ObjectGuid guid = m_caster->GetGUID()) // the trainer is the caster
2762}
void SendTalentWipeConfirm(ObjectGuid guid)
Definition Player.cpp:8949

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)
3325{
3327 return;
3328
3329 if (!unitTarget || !unitTarget->IsAlive())
3330 return;
3331
3332 // multiple weapon dmg effect workaround
3333 // execute only the last weapon damage
3334 // and handle all effects at once
3335 for (uint32 j = effIndex + 1; j < MAX_SPELL_EFFECTS; ++j)
3336 {
3337 switch (m_spellInfo->Effects[j].Effect)
3338 {
3343 return; // we must calculate only at last weapon effect
3344 break;
3345 }
3346 }
3347
3348 // some spell specific modifiers
3349 float totalDamagePercentMod = 100.0f; // applied to final bonus+weapon damage
3350 int32 spell_bonus = 0; // bonus specific for spell
3351 bool normalized = false;
3352
3354 {
3356 {
3357 switch (m_spellInfo->Id)
3358 {
3359 // Trial of the Champion, Black Knight, Obliterate
3360 case 67725:
3361 case 67883:
3362 {
3363 AddPct(totalDamagePercentMod, unitTarget->GetDiseasesByCaster(m_caster->GetGUID(), 1) * 30.0f);
3364 break;
3365 }
3366 }
3367 break;
3368 }
3370 {
3371 // Devastate (player ones)
3372 if (m_spellInfo->SpellFamilyFlags[1] & 0x40)
3373 {
3374 m_caster->CastSpell(unitTarget, 58567, true);
3375
3376 if (Aura* aur = unitTarget->GetAura(58567))
3377 {
3378 // 58388 - Glyph of Devastate dummy aura.
3379 if (m_caster->HasAura(58388))
3380 aur->ModStackAmount(1);
3381
3382 spell_bonus += (aur->GetStackAmount() - 1) * CalculateSpellDamage(2, unitTarget);
3383 }
3384 }
3385 break;
3386 }
3387 case SPELLFAMILY_ROGUE:
3388 {
3389 // Fan of Knives, Hemorrhage, Ghostly Strike
3390 if ((m_spellInfo->SpellFamilyFlags[1] & 0x40000)
3391 || (m_spellInfo->SpellFamilyFlags[0] & 0x6000000))
3392 {
3393 // Hemorrhage
3394 if (m_spellInfo->SpellFamilyFlags[0] & 0x2000000)
3395 {
3397 }
3398 // 50% more damage with daggers
3399 if (m_caster->IsPlayer())
3400 if (Item* item = m_caster->ToPlayer()->GetWeaponForAttack(m_attackType, true))
3401 if (item->GetTemplate()->SubClass == ITEM_SUBCLASS_WEAPON_DAGGER)
3402 AddPct(totalDamagePercentMod, 50.0f);
3403 }
3404 // Mutilate (for each hand)
3405 else if (m_spellInfo->SpellFamilyFlags[1] & 0x6)
3406 {
3407 bool found = false;
3408 // fast check
3410 found = true;
3411 // full aura scan
3412 else
3413 {
3415 for (Unit::AuraApplicationMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
3416 {
3417 if (itr->second->GetBase()->GetSpellInfo()->Dispel == DISPEL_POISON)
3418 {
3419 found = true;
3420 break;
3421 }
3422 }
3423 }
3424
3425 if (found)
3426 AddPct(totalDamagePercentMod, 20.0f); // 120% if poisoned
3427 }
3428 break;
3429 }
3431 {
3432 switch (m_spellInfo->Id)
3433 {
3434 case 20467: // Seal of Command Unleashed
3435 spell_bonus += int32(0.08f * m_caster->GetTotalAttackPowerValue(BASE_ATTACK));
3437 break;
3438 case 53385: // Divine Storm deals normalized damage
3439 normalized = true;
3440 break;
3441 default:
3442 break;
3443 }
3444 break;
3445 }
3446 case SPELLFAMILY_SHAMAN:
3447 {
3448 // Skyshatter Harness item set bonus
3449 // Stormstrike
3450 if (AuraEffect* aurEff = m_caster->IsScriptOverriden(m_spellInfo, 5634))
3451 m_caster->CastSpell(m_caster, 38430, true, nullptr, aurEff);
3452 // Lava lash damage increased by Flametongue weapon
3454 AddPct(totalDamagePercentMod, 25.0f);
3455 break;
3456 }
3457 case SPELLFAMILY_DRUID:
3458 {
3459 // Mangle (Cat): CP
3460 if (m_spellInfo->SpellFamilyFlags[1] & 0x400)
3461 {
3463 }
3464 // Shred, Maul - Rend and Tear
3466 {
3467 if (AuraEffect const* rendAndTear = m_caster->GetDummyAuraEffect(SPELLFAMILY_DRUID, 2859, 0))
3468 AddPct(totalDamagePercentMod, rendAndTear->GetAmount());
3469 }
3470 break;
3471 }
3472 case SPELLFAMILY_HUNTER:
3473 {
3474 // Kill Shot
3475 if (m_spellInfo->SpellFamilyFlags[1] & 0x800000)
3476 {
3477 spell_bonus += int32(m_caster->GetTotalAttackPowerValue(RANGED_ATTACK) * 0.4f);
3478 }
3479 break;
3480 }
3482 {
3483 // Plague Strike
3484 if (m_spellInfo->SpellFamilyFlags[0] & 0x1)
3485 {
3486 // Glyph of Plague Strike
3487 if (AuraEffect const* aurEff = m_caster->GetAuraEffect(58657, EFFECT_0))
3488 AddPct(totalDamagePercentMod, aurEff->GetAmount());
3489 break;
3490 }
3491 // Blood Strike
3492 if (m_spellInfo->SpellFamilyFlags[0] & 0x400000)
3493 {
3494 float disease_amt = m_spellInfo->Effects[EFFECT_2].CalcValue();
3495 //Death Knight T8 Melee 4P Bonus
3496 if (AuraEffect* aurEff = m_caster->GetAuraEffectDummy(64736))
3497 AddPct(disease_amt, aurEff->GetAmount());
3498
3499 AddPct(totalDamagePercentMod, disease_amt * unitTarget->GetDiseasesByCaster(m_caster->GetGUID()) / 2.0f);
3500
3501 // Glyph of Blood Strike
3502 if (m_caster->GetAuraEffect(59332, EFFECT_0))
3504 AddPct(totalDamagePercentMod, 20.0f);
3505 break;
3506 }
3507 // Death Strike
3508 if (m_spellInfo->SpellFamilyFlags[0] & 0x10)
3509 {
3510 // Glyph of Death Strike
3511 if (AuraEffect const* aurEff = m_caster->GetAuraEffect(59336, EFFECT_0))
3512 if (uint32 runic = std::min<uint32>(m_caster->GetPower(POWER_RUNIC_POWER), aurEff->GetSpellInfo()->Effects[EFFECT_1].CalcValue()))
3513 AddPct(totalDamagePercentMod, runic);
3514 break;
3515 }
3516 // Obliterate (12.5% more damage per disease)
3517 if (m_spellInfo->SpellFamilyFlags[1] & 0x20000)
3518 {
3519 bool consumeDiseases = true;
3520 // Annihilation
3522 // Do not consume diseases if roll sucesses
3523 if (roll_chance_i(aurEff->GetAmount()))
3524 consumeDiseases = false;
3525
3526 float disease_amt = m_spellInfo->Effects[EFFECT_2].CalcValue();
3527 //Death Knight T8 Melee 4P Bonus
3528 if (AuraEffect* aurEff = m_caster->GetAuraEffectDummy(64736))
3529 AddPct(disease_amt, aurEff->GetAmount());
3530
3531 AddPct(totalDamagePercentMod, disease_amt * unitTarget->GetDiseasesByCaster(m_caster->GetGUID(), consumeDiseases) / 2.0f);
3532 break;
3533 }
3534 // Blood-Caked Strike - Blood-Caked Blade
3535 if (m_spellInfo->SpellIconID == 1736)
3536 {
3537 AddPct(totalDamagePercentMod, unitTarget->GetDiseasesByCaster(m_caster->GetGUID()) * 50.0f);
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 bool const isPhysical = (m_spellSchoolMask & SPELL_SCHOOL_MASK_NORMAL);
3585 if (isPhysical && (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 float weapon_total_pct = m_caster->GetModifierValue(unitMod, TOTAL_PCT);
3602 fixed_bonus = int32(fixed_bonus * weapon_total_pct);
3603 spell_bonus = int32(spell_bonus * weapon_total_pct);
3604 }
3605
3606 int32 weaponDamage = 0;
3607 // Dancing Rune Weapon
3608 if (m_caster->GetEntry() == 27893)
3609 {
3610 if (Unit* owner = m_caster->GetOwner())
3611 weaponDamage = owner->CalculateDamage(m_attackType, normalized, isPhysical);
3612 }
3613 else
3614 {
3615 weaponDamage = m_caster->CalculateDamage(m_attackType, normalized, isPhysical);
3616 }
3617
3618 // Sequence is important
3619 for (int j = 0; j < MAX_SPELL_EFFECTS; ++j)
3620 {
3621 // We assume that a spell have at most one fixed_bonus
3622 // and at most one weaponDamagePercentMod
3623 switch (m_spellInfo->Effects[j].Effect)
3624 {
3628 weaponDamage += fixed_bonus;
3629 break;
3631 ApplyPct(weaponDamage, weaponDamagePercentMod);
3632 default:
3633 break; // not weapon damage effect, just skip
3634 }
3635 }
3636
3637 weaponDamage += spell_bonus;
3638 ApplyPct(weaponDamage, totalDamagePercentMod);
3639
3640 // prevent negative damage
3641 uint32 eff_damage(std::max(weaponDamage, 0));
3642
3643 // Add melee damage bonuses (also check for negative)
3646
3647 // Meteor like spells (divided damage to targets)
3649 {
3650 uint32 count = 0;
3651 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
3652 if (ihit->effectMask & (1 << effIndex))
3653 ++count;
3654
3655 eff_damage /= count; // divide to all targets
3656 }
3657
3658 m_damage += eff_damage;
3659}
@ ITEM_SUBCLASS_WEAPON_DAGGER
Definition ItemTemplate.h:359
@ POWER_RUNIC_POWER
Definition SharedDefines.h:286
@ SPELL_EFFECT_NORMALIZED_WEAPON_DMG
Definition SharedDefines.h:910
@ SPELL_EFFECT_WEAPON_PERCENT_DAMAGE
Definition SharedDefines.h:820
@ AURA_STATE_DEADLY_POISON
Definition SharedDefines.h:1319
@ AURA_STATE_BLEEDING
Definition SharedDefines.h:1321
@ DISPEL_POISON
Definition SharedDefines.h:1387
UnitMods
Definition Unit.h:144
@ UNIT_MOD_DAMAGE_OFFHAND
Definition Unit.h:168
@ UNIT_MOD_DAMAGE_RANGED
Definition Unit.h:169
@ UNIT_MOD_DAMAGE_MAINHAND
Definition Unit.h:167
@ TOTAL_PCT
Definition Unit.h:131
uint32 MeleeDamageBonusTaken(Unit *attacker, uint32 pdamage, WeaponAttackType attType, SpellInfo const *spellProto=nullptr, SpellSchoolMask damageSchoolMask=SPELL_SCHOOL_MASK_NORMAL)
Definition Unit.cpp:13355
uint32 GetDiseasesByCaster(ObjectGuid casterGUID, uint8 mode=0)
Definition Unit.cpp:5912
bool HasDecreaseSpeedAura() const
Definition Unit.h:1781
AuraEffect * GetAuraEffectDummy(uint32 spellid) const
Definition Unit.cpp:5618
float GetModifierValue(UnitMods unitMod, UnitModifierType modifierType) const
Definition Unit.cpp:15317
uint32 CalculateDamage(WeaponAttackType attType, bool normalized, bool addTotalPct, uint8 itemDamagesMask=0)
Definition Unit.cpp:3021
int32 SpellBaseDamageBonusDone(SpellSchoolMask schoolMask)
Definition Unit.cpp:12014
uint32 MeleeDamageBonusDone(Unit *pVictim, uint32 damage, WeaponAttackType attType, SpellInfo const *spellProto=nullptr, SpellSchoolMask damageSchoolMask=SPELL_SCHOOL_MASK_NORMAL)
Definition Unit.cpp:13153

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_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 
)
5083{
5084 InitEffectExecuteData(effIndex);
5085 *m_effectExecuteData[effIndex] << uint32(entry);
5086}
void InitEffectExecuteData(uint8 effIndex)
Definition Spell.cpp:8437

References InitEffectExecuteData(), and m_effectExecuteData.

Referenced by EffectCreateItem().

◆ ExecuteLogEffectDestroyItem()

void Spell::ExecuteLogEffectDestroyItem ( uint8  effIndex,
uint32  entry 
)
5089{
5090 InitEffectExecuteData(effIndex);
5091 *m_effectExecuteData[effIndex] << uint32(entry);
5092}

References InitEffectExecuteData(), and m_effectExecuteData.

Referenced by EffectFeedPet().

◆ ExecuteLogEffectDurabilityDamage()

void Spell::ExecuteLogEffectDurabilityDamage ( uint8  effIndex,
Unit victim,
int32  itemId,
int32  slot 
)
5069{
5070 InitEffectExecuteData(effIndex);
5071 *m_effectExecuteData[effIndex] << victim->GetPackGUID();
5072 *m_effectExecuteData[effIndex] << int32(itemId);
5073 *m_effectExecuteData[effIndex] << int32(slot);
5074}

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

Referenced by EffectDurabilityDamage().

◆ ExecuteLogEffectExtraAttacks()

void Spell::ExecuteLogEffectExtraAttacks ( uint8  effIndex,
Unit victim,
uint32  attCount 
)
5055{
5056 InitEffectExecuteData(effIndex);
5057 *m_effectExecuteData[effIndex] << victim->GetPackGUID();
5058 *m_effectExecuteData[effIndex] << uint32(attCount);
5059}

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

Referenced by EffectAddExtraAttacks().

◆ ExecuteLogEffectInterruptCast()

void Spell::ExecuteLogEffectInterruptCast ( uint8  effIndex,
Unit victim,
uint32  spellId 
)
5062{
5063 InitEffectExecuteData(effIndex);
5064 *m_effectExecuteData[effIndex] << victim->GetPackGUID();
5065 *m_effectExecuteData[effIndex] << uint32(spellId);
5066}

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

Referenced by EffectInterruptCast().

◆ ExecuteLogEffectOpenLock()

void Spell::ExecuteLogEffectOpenLock ( uint8  effIndex,
Object obj 
)
5077{
5078 InitEffectExecuteData(effIndex);
5079 *m_effectExecuteData[effIndex] << obj->GetPackGUID();
5080}

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

Referenced by EffectOpenLock().

◆ ExecuteLogEffectResurrect()

void Spell::ExecuteLogEffectResurrect ( uint8  effIndex,
Unit target 
)
5107{
5108 InitEffectExecuteData(effIndex);
5109 *m_effectExecuteData[effIndex] << target->GetPackGUID();
5110}

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 
)
5046{
5047 InitEffectExecuteData(effIndex);
5048 *m_effectExecuteData[effIndex] << target->GetPackGUID();
5049 *m_effectExecuteData[effIndex] << uint32(powerTaken);
5050 *m_effectExecuteData[effIndex] << uint32(PowerType);
5051 *m_effectExecuteData[effIndex] << float(gainMultiplier);
5052}

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 
)
5101{
5102 InitEffectExecuteData(effIndex);
5103 *m_effectExecuteData[effIndex] << obj->GetPackGUID();
5104}

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

Referenced by EffectDismissPet().

◆ finish()

void Spell::finish ( bool  ok = true)
4416{
4417 if (!m_caster)
4418 return;
4419
4421 return;
4423
4424 if (m_spellInfo->IsChanneled())
4426
4429
4430 // Unsummon summon as possessed creatures on spell cancel
4432 {
4433 if (Unit* charm = m_caster->GetCharm())
4434 if (charm->IsCreature()
4435 && charm->ToCreature()->HasUnitTypeMask(UNIT_MASK_PUPPET)
4436 && charm->GetUInt32Value(UNIT_CREATED_BY_SPELL) == m_spellInfo->Id)
4437 ((Puppet*)charm)->UnSummon();
4438 }
4439
4440 if (Creature* creatureCaster = m_caster->ToCreature())
4441 creatureCaster->ReleaseFocus(this);
4442
4443 if (ok)
4444 {
4447 }
4448 else
4449 {
4450 if (m_caster->IsPlayer())
4451 {
4452 // Xinef: Restore spell mods in case of fail cast
4454
4455 // Xinef: Reset cooldown event in case of fail cast
4458
4459 // Rogue fix: Remove Cold Blood if Mutilate off-hand failed
4460 if (m_spellInfo->Id == 27576) // Mutilate, off-hand
4461 if (m_caster->HasAura(14177))
4462 m_caster->RemoveAura(14177);
4463 }
4464 return;
4465 }
4466
4467 // pussywizard:
4470
4472 {
4473 // Unsummon statue
4475 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spell);
4476 if (spellInfo && spellInfo->SpellIconID == 2056)
4477 {
4478 LOG_DEBUG("spells.aura", "Statue {} is unsummoned in spell {} finish", m_caster->GetGUID().ToString(), m_spellInfo->Id);
4480 return;
4481 }
4482 }
4483
4484 // potions disabled by client, send event "not in combat" if need
4487
4488 // Take mods after trigger spell (needed for 14177 to affect 48664)
4489 // mods are taken only on succesfull cast and independantly from targets of the spell
4490 if (Player* player = m_caster->GetSpellModOwner())
4491 player->RemoveSpellMods(this);
4492
4493 // xinef: clear reactive auras states after spell cast
4496
4497 // Stop Attack for some spells
4500}
@ ENCOUNTER_CREDIT_CAST_SPELL
Definition Map.h:159
@ AURA_STATE_DEFENSE
Definition SharedDefines.h:1303
@ AURA_STATE_HUNTER_PARRY
Definition SharedDefines.h:1309
@ SPELL_ATTR0_CU_ENCOUNTER_REWARD
Definition SpellInfo.h:207
@ UNIT_MASK_PUPPET
Definition UnitDefines.h:162
void UpdateEncounterState(EncounterCreditType type, uint32 creditEntry, Unit *source)
Definition Map.cpp:2514
void UpdatePotionCooldown(Spell *spell=nullptr)
Definition PlayerUpdates.cpp:1543
Definition TemporarySummon.h:115
virtual void setDeathState(DeathState s, bool despawn=false)
Definition Unit.cpp:14582
void UpdateInterruptMask()
Definition Unit.cpp:768
void ModifyAuraState(AuraStateType flag, bool apply)
Definition Unit.cpp:10573

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::HasAura(), Unit::HasUnitState(), SpellInfo::Id, SpellInfo::IsChanneled(), SpellInfo::IsCooldownStartedOnEvent(), Object::IsCreature(), Unit::IsNonMeleeSpellCast(), Object::IsPlayer(), Unit::IsSummon(), JustDied, LOG_DEBUG, m_caster, m_spellInfo, m_spellState, m_triggeredByAuraSpell, Unit::ModifyAuraState(), Unit::RemoveAura(), 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
8433{
8435}
void SendLogExecute()
Definition Spell.cpp:5011

References SendLogExecute().

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

◆ GetCaster()

Unit * Spell::GetCaster ( ) const
inline

◆ GetCastTime()

◆ GetCastTimeRemaining()

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

References m_timer.

◆ GetCurrentContainer()

CurrentSpellTypes Spell::GetCurrentContainer ( ) const

◆ GetDebugInfo()

std::string Spell::GetDebugInfo ( ) const
protected
8896{
8897 std::stringstream sstr;
8898 sstr << std::boolalpha
8899 << "Id: " << GetSpellInfo()->Id << " OriginalCaster: " << m_originalCasterGUID.ToString()
8900 << " State: " << getState();
8901 return sstr.str();
8902}

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

◆ GetDelayMoment()

uint64 Spell::GetDelayMoment ( ) const
inline

◆ GetDelayStart()

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

References m_delayStart.

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

◆ GetDelayTrajectory()

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

References m_delayTrajectory.

◆ GetOriginalCaster()

Unit * Spell::GetOriginalCaster ( ) const
inline

◆ GetPowerCost()

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

References m_powerCost.

Referenced by Unit::HandleDummyAuraProc().

◆ GetSearcherTypeMask()

uint32 Spell::GetSearcherTypeMask ( SpellTargetObjectTypes  objType,
ConditionList condList 
)
2043{
2044 // this function selects which containers need to be searched for spell target
2046
2047 // filter searchers based on searched object type
2048 switch (objType)
2049 {
2056 break;
2060 break;
2061 default:
2062 break;
2063 }
2065 retMask &= ~GRID_MAP_TYPE_MASK_CORPSE;
2069 retMask &= GRID_MAP_TYPE_MASK_PLAYER;
2071 retMask &= ~GRID_MAP_TYPE_MASK_PLAYER;
2072
2073 if (condList)
2074 retMask &= sConditionMgr->GetSearcherTypeMaskForConditionList(*condList);
2075 return retMask;
2076}
@ GRID_MAP_TYPE_MASK_PLAYER
Definition GridDefines.h:75
@ GRID_MAP_TYPE_MASK_CREATURE
Definition GridDefines.h:72
@ GRID_MAP_TYPE_MASK_ALL
Definition GridDefines.h:76
@ GRID_MAP_TYPE_MASK_GAMEOBJECT
Definition GridDefines.h:74
@ GRID_MAP_TYPE_MASK_CORPSE
Definition GridDefines.h:71
@ SPELL_ATTR5_NOT_ON_PLAYER
Definition SharedDefines.h:585
@ SPELL_ATTR2_ALLOW_DEAD_TARGET
Definition SharedDefines.h:467
@ SPELL_ATTR3_ONLY_ON_GHOSTS
Definition SharedDefines.h:516
@ SPELL_ATTR3_ONLY_ON_PLAYER
Definition SharedDefines.h:512
@ 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, SPELL_ATTR5_NOT_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
595{ return m_spellValue; }

References m_spellValue.

Referenced by DoAllEffectOnTarget().

◆ getState()

◆ GetTriggeredByAuraTickNumber()

uint32 Spell::GetTriggeredByAuraTickNumber ( ) const
inline

◆ GetTriggeredCastFlags()

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

References _triggeredCastFlags.

◆ GetUniqueTargetInfo()

◆ handle_delayed()

uint64 Spell::handle_delayed ( uint64  t_offset)
4104{
4105 if (!UpdatePointers())
4106 {
4107 // finish the spell if UpdatePointers() returned false, something wrong happened there
4108 finish(false);
4109 return 0;
4110 }
4111
4112 Player* modOwner = m_caster->GetSpellModOwner();
4113 if (modOwner)
4114 modOwner->SetSpellModTakingSpell(this, true);
4115
4116 uint64 next_time = m_delayTrajectory;
4117
4119
4120 if (!m_immediateHandled && m_delayTrajectory <= t_offset)
4121 {
4123 m_immediateHandled = true;
4125 next_time = 0;
4126 }
4127
4128 bool single_missile = (m_targets.HasDst());
4129
4130 // 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)
4131 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
4132 {
4133 if (ihit->processed == false)
4134 {
4135 if (single_missile || ihit->timeDelay <= t_offset)
4136 {
4137 ihit->timeDelay = t_offset;
4138 DoAllEffectOnTarget(&(*ihit));
4139 }
4140 else if (next_time == 0 || ihit->timeDelay < next_time)
4141 next_time = ihit->timeDelay;
4142 }
4143 }
4144
4145 // now recheck gameobject targeting correctness
4146 for (std::list<GOTargetInfo>::iterator ighit = m_UniqueGOTargetInfo.begin(); ighit != m_UniqueGOTargetInfo.end(); ++ighit)
4147 {
4148 if (ighit->processed == false)
4149 {
4150 if (single_missile || ighit->timeDelay <= t_offset)
4151 DoAllEffectOnTarget(&(*ighit));
4152 else if (next_time == 0 || ighit->timeDelay < next_time)
4153 next_time = ighit->timeDelay;
4154 }
4155 }
4156
4158
4159 if (modOwner)
4160 modOwner->SetSpellModTakingSpell(this, false);
4161
4162 // All targets passed - need finish phase
4163 if (next_time == 0)
4164 {
4165 // spell is finished, perform some last features of the spell here
4167
4168 finish(true); // successfully finish spell cast
4169
4170 // return zero, spell is finished now
4171 return 0;
4172 }
4173 else
4174 {
4175 // spell is unfinished, return next execution time
4176 return next_time;
4177 }
4178}
void _handle_finish_phase()
Definition Spell.cpp:4208
void PrepareTargetProcessing()
Definition Spell.cpp:8427
void _handle_immediate_phase()
Definition Spell.cpp:4180
void FinishTargetProcessing()
Definition Spell.cpp:8432

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 ( )
4044{
4045 // start channeling if applicable
4046 if (m_spellInfo->IsChanneled())
4047 {
4048 int32 duration = m_spellInfo->GetDuration();
4050 duration = -1;
4051
4052 if (duration > 0)
4053 {
4054 // First mod_duration then haste - see Missile Barrage
4055 // Apply duration mod
4056 if (Player* modOwner = m_caster->GetSpellModOwner())
4057 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_DURATION, duration);
4058
4059 // Apply haste mods
4061 duration = int32(duration * m_caster->GetFloatValue(UNIT_MOD_CAST_SPEED));
4062
4065 m_channeledDuration = duration;
4066 SendChannelStart(duration);
4067 }
4068 else if (duration == -1)
4069 {
4072 SendChannelStart(duration);
4073 }
4074 }
4075
4077
4078 // process immediate effects (items, ground, etc.) also initialize some variables
4080
4081 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
4082 DoAllEffectOnTarget(&(*ihit));
4083
4084 for (std::list<GOTargetInfo>::iterator ihit = m_UniqueGOTargetInfo.begin(); ihit != m_UniqueGOTargetInfo.end(); ++ihit)
4085 DoAllEffectOnTarget(&(*ihit));
4086
4088
4089 // spell is finished, perform some last features of the spell here
4091
4092 // Remove used for cast item if need (it can be already nullptr after TakeReagents call
4093 TakeCastItem();
4094
4095 // handle ammo consumption for Hunter's volley spell
4097 TakeAmmo();
4098
4100 finish(true); // successfully finish spell cast (not last in case autorepeat or channel spell)
4101}
void SendChannelStart(uint32 duration)
Definition Spell.cpp:5144
void TakeAmmo()
Definition Spell.cpp:5317
void AddInterruptMask(uint32 mask)
Definition Unit.h:1563

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 
)
5567{
5569 return;
5570
5571 effectHandleMode = mode;
5572 unitTarget = pUnitTarget;
5573 itemTarget = pItemTarget;
5574 gameObjTarget = pGOTarget;
5576
5577 uint8 eff = m_spellInfo->Effects[i].Effect;
5578
5579 LOG_DEBUG("spells.aura", "Spell: {} Effect : {}", m_spellInfo->Id, eff);
5580
5581 // we do not need DamageMultiplier here.
5582 damage = CalculateSpellDamage(i, nullptr);
5583
5584 bool preventDefault = CallScriptEffectHandlers((SpellEffIndex)i, mode);
5585
5586 if (!preventDefault && eff < TOTAL_SPELL_EFFECTS)
5587 {
5588 (this->*SpellEffects[eff])((SpellEffIndex)i);
5589 }
5590}
SpellEffIndex
Definition SharedDefines.h:30
SpellEffects
Definition SharedDefines.h:789
@ TOTAL_SPELL_EFFECTS
Definition SharedDefines.h:954
bool CallScriptEffectHandlers(SpellEffIndex effIndex, SpellEffectHandleMode mode)
Definition Spell.cpp:8546
WorldLocation _position
Definition Spell.h:113

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(), DoAllEffectOnTarget(), DoAllEffectOnTarget(), DoSpellHitOnUnit(), and HandleLaunchPhase().

◆ HandleLaunchPhase()

void Spell::HandleLaunchPhase ( )
protected
8186{
8187 // handle effects with SPELL_EFFECT_HANDLE_LAUNCH mode
8188 for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i)
8189 {
8190 // don't do anything for empty effect
8191 if (!m_spellInfo->Effects[i].IsEffect())
8192 continue;
8193
8194 HandleEffects(nullptr, nullptr, nullptr, i, SPELL_EFFECT_HANDLE_LAUNCH);
8195 }
8196
8197 float multiplier[MAX_SPELL_EFFECTS];
8198 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
8199 if (m_applyMultiplierMask & (1 << i))
8200 multiplier[i] = m_spellInfo->Effects[i].CalcDamageMultiplier(m_originalCaster, this);
8201
8204 for (Unit::AuraEffectList::const_iterator j = Auras.begin(); j != Auras.end(); ++j)
8205 {
8206 if ((*j)->IsAffectedOnSpell(m_spellInfo))
8207 usesAmmo = false;
8208 }
8209
8211
8212 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
8213 {
8214 TargetInfo& target = *ihit;
8215
8216 uint32 mask = target.effectMask;
8217 if (!mask)
8218 continue;
8219
8220 // do not consume ammo anymore for Hunter's volley spell
8222 usesAmmo = false;
8223
8224 if (usesAmmo)
8225 {
8226 bool ammoTaken = false;
8227 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; i++)
8228 {
8229 if (!(mask & 1 << i))
8230 continue;
8231 switch (m_spellInfo->Effects[i].Effect)
8232 {
8238 ammoTaken = true;
8239 TakeAmmo();
8240 }
8241 if (ammoTaken)
8242 break;
8243 }
8244 }
8245
8246 DoAllEffectOnLaunchTarget(target, multiplier);
8247 }
8248
8250}
@ SPELL_EFFECT_SCHOOL_DAMAGE
Definition SharedDefines.h:791
@ SPELL_AURA_ABILITY_CONSUME_NO_AMMO
Definition SpellAuraDefines.h:337
@ SPELL_ATTR0_CU_DIRECT_DAMAGE
Definition SpellInfo.h:184
void DoAllEffectOnLaunchTarget(TargetInfo &targetInfo, float *multiplier)
Definition Spell.cpp:8252

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 ( )
5520{
5521 if (m_UniqueTargetInfo.empty())
5522 return;
5523
5525 return;
5526
5527 float threat = 0.0f;
5528 if (SpellThreatEntry const* threatEntry = sSpellMgr->GetSpellThreatEntry(m_spellInfo->Id))
5529 {
5530 if (threatEntry->apPctMod != 0.0f)
5531 threat += threatEntry->apPctMod * m_caster->GetTotalAttackPowerValue(BASE_ATTACK);
5532
5533 threat += threatEntry->flatMod;
5534 }
5536 threat += m_spellInfo->SpellLevel;
5537
5538 // past this point only multiplicative effects occur
5539 if (threat == 0.0f)
5540 return;
5541
5542 // 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
5543 threat /= m_UniqueTargetInfo.size();
5544
5545 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
5546 {
5547 float threatToAdd = threat;
5548 if (ihit->missCondition != SPELL_MISS_NONE)
5549 threatToAdd = 0.0f;
5550
5551 Unit* target = ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID);
5552 if (!target)
5553 continue;
5554
5555 bool IsFriendly = m_caster->IsFriendlyTo(target);
5556 // positive spells distribute threat among all units that are in combat with target, like healing
5558 target->getHostileRefMgr().threatAssist(m_caster, threatToAdd, m_spellInfo);
5559 // for negative spells threat gets distributed among affected targets
5560 else if (!m_spellInfo->_IsPositiveSpell() && !IsFriendly && target->CanHaveThreatList())
5561 target->AddThreat(m_caster, threatToAdd, m_spellInfo->GetSchoolMask(), m_spellInfo);
5562 }
5563 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()));
5564}
@ SPELL_ATTR0_CU_NO_INITIAL_THREAT
Definition SpellInfo.h:180
static bool IsFriendly(Creature *piece, Creature *target)
Definition boss_chess_event.cpp:180
bool _IsPositiveSpell() const
Definition SpellInfo.cpp:2843
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
8056{
8057 for (std::list<TargetInfo>::const_iterator itr = m_UniqueTargetInfo.begin(); itr != m_UniqueTargetInfo.end(); ++itr)
8058 if (itr->effectMask & (1 << effect))
8059 return true;
8060
8061 for (std::list<GOTargetInfo>::const_iterator itr = m_UniqueGOTargetInfo.begin(); itr != m_UniqueGOTargetInfo.end(); ++itr)
8062 if (itr->effectMask & (1 << effect))
8063 return true;
8064
8065 for (std::list<ItemTargetInfo>::const_iterator itr = m_UniqueItemInfo.begin(); itr != m_UniqueItemInfo.end(); ++itr)
8066 if (itr->effectMask & (1 << effect))
8067 return true;
8068
8069 return false;
8070}

References m_UniqueGOTargetInfo, m_UniqueItemInfo, and m_UniqueTargetInfo.

◆ InitEffectExecuteData()

void Spell::InitEffectExecuteData ( uint8  effIndex)
protected
8438{
8439 ASSERT(effIndex < MAX_SPELL_EFFECTS);
8440 if (!m_effectExecuteData[effIndex])
8441 {
8442 m_effectExecuteData[effIndex] = new ByteBuffer(0x20);
8443 // first dword - target counter
8444 *m_effectExecuteData[effIndex] << uint32(1);
8445 }
8446 else
8447 {
8448 // increase target counter by one
8449 uint32 count = (*m_effectExecuteData[effIndex]).read<uint32>(0);
8450 (*m_effectExecuteData[effIndex]).put<uint32>(0, ++count);
8451 }
8452}

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 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?
8030{
8033 {
8034 return false;
8035 }
8036
8038 {
8039 return false;
8040 }
8041
8042 return true;
8043}
@ SPELL_ATTR6_DOESNT_RESET_SWING_TIMER_IF_INSTANT
Definition SharedDefines.h:640

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
641 {
642 if (m_delayAtDamageCount >= 2)
643 return true;
644
646 return false;
647 }

References m_delayAtDamageCount.

Referenced by Delayed(), and DelayedChannel().

◆ IsDeletable()

◆ IsIgnoringCooldowns()

bool Spell::IsIgnoringCooldowns ( ) const

◆ IsInterruptable()

bool Spell::IsInterruptable ( ) const
inline
572{ 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
8178{
8179 if (target->IsAlive())
8181
8183}
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 ( )
8461{
8462 if (_scriptsLoaded)
8463 return;
8464 _scriptsLoaded = true;
8465 sScriptMgr->CreateSpellScripts(m_spellInfo->Id, m_loadedScripts);
8466 for (std::list<SpellScript*>::iterator itr = m_loadedScripts.begin(); itr != m_loadedScripts.end();)
8467 {
8468 if (!(*itr)->_Load(this))
8469 {
8470 std::list<SpellScript*>::iterator bitr = itr;
8471 ++itr;
8472 delete (*bitr);
8473 m_loadedScripts.erase(bitr);
8474 continue;
8475 }
8476 LOG_DEBUG("spells.aura", "Spell::LoadScripts: Script `{}` for spell `{}` is loaded now", (*itr)->_GetScriptName()->c_str(), m_spellInfo->Id);
8477 (*itr)->Register();
8478 ++itr;
8479 }
8480}

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 ( )
8866{
8867 if (!m_caster || !m_caster->IsInWorld())
8868 return;
8869
8870 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(24390);
8871
8872 // Make sure the player is sending a valid GO target and lock ID. SPELL_EFFECT_OPEN_LOCK
8873 // can succeed with a lockId of 0
8874 if (m_spellInfo->Id == 21651)
8875 {
8876 if (GameObject* go = m_targets.GetGOTarget())
8877 {
8878 LockEntry const* lockInfo = sLockStore.LookupEntry(go->GetGOInfo()->GetLockId());
8879 if (lockInfo && lockInfo->Index[1] == LOCKTYPE_SLOW_OPEN)
8880 {
8881 Spell* visual = new Spell(m_caster, spellInfo, TRIGGERED_NONE);
8882 visual->prepare(&m_targets);
8883 }
8884 }
8885 }
8886}
@ LOCKTYPE_SLOW_OPEN
Definition SharedDefines.h:2619
@ 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 &&

3392{
3393 if (m_CastItem)
3394 {
3396 }
3397 else
3398 {
3400 }
3401
3402 InitExplicitTargets(*targets);
3403
3404 if (!sScriptMgr->CanPrepare(this, targets, triggeredByAura))
3405 {
3406 finish(false);
3407 return SPELL_FAILED_UNKNOWN;
3408 }
3409
3410 // Fill aura scaling information
3412 {
3413 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
3414 {
3415 if (m_spellInfo->Effects[i].Effect == SPELL_EFFECT_APPLY_AURA ||
3418 {
3419 // Change aura with ranks only if basepoints are taken from spellInfo and aura is positive
3421 {
3422 m_auraScaleMask |= (1 << i);
3423 if (m_spellValue->EffectBasePoints[i] != m_spellInfo->Effects[i].BasePoints)
3424 {
3425 m_auraScaleMask = 0;
3426 break;
3427 }
3428 }
3429 }
3430 }
3431 }
3432
3434
3435 if (triggeredByAura)
3436 {
3437 m_triggeredByAuraSpell.Init(triggeredByAura);
3438 }
3439
3440 // create and add update event for this spell
3441 _spellEvent = new SpellEvent(this);
3443
3444 if (sDisableMgr->IsDisabledFor(DISABLE_TYPE_SPELL, m_spellInfo->Id, m_caster))
3445 {
3447 finish(false);
3449 }
3450
3451 //Prevent casting at cast another spell (ServerSide check)
3453 {
3455 finish(false);
3457 }
3458
3459 LoadScripts();
3460
3461 OnSpellLaunch();
3462
3464
3465 // Set combo point requirement
3467 m_needComboPoints = false;
3468
3469 SpellCastResult result = CheckCast(true);
3470 if (result != SPELL_CAST_OK && !IsAutoRepeat()) //always cast autorepeat dummy for triggering
3471 {
3472 // Periodic auras should be interrupted when aura triggers a spell which can't be cast
3473 // for example bladestorm aura should be removed on disarm as of patch 3.3.5
3474 // channeled periodic spells should be affected by this (arcane missiles, penance, etc)
3475 // a possible alternative sollution for those would be validating aura target on unit state change
3476 if (m_caster->IsPlayer() && triggeredByAura && triggeredByAura->IsPeriodic() && !triggeredByAura->GetBase()->IsPassive())
3477 {
3479 triggeredByAura->GetBase()->SetDuration(0);
3480 }
3481
3482 // Allows to cast melee attack spell if result is SPELL_FAILED_OUT_OF_RANGE
3484 {
3485 SendCastResult(result);
3486
3487 finish(false);
3488 return result;
3489 }
3490 }
3491
3492 // Prepare data for triggers
3493 prepareDataForTriggerSystem(triggeredByAura);
3494
3495 // calculate cast time (calculated after first CheckCast check to prevent charge counting for first CheckCast fail)
3497
3498 if (m_caster->IsPlayer())
3500 m_casttime = 0;
3501
3502 // don't allow channeled spells / spells with cast time to be casted while moving
3503 // (even if they are interrupted on moving, spells with almost immediate effect get to have their effect processed before movement interrupter kicks in)
3505 {
3506 // 1. Has casttime, 2. Or doesn't have flag to allow action during channel
3508 {
3510 finish(false);
3511 return SPELL_FAILED_MOVING;
3512 }
3513 }
3514
3515 // xinef: if spell have nearby target entry only, do not allow to cast if no targets are found
3516 if (m_CastItem)
3517 {
3518 bool selectTargets = false;
3519 bool nearbyDest = false;
3520
3521 for (uint8 i = EFFECT_0; i < MAX_SPELL_EFFECTS; ++i)
3522 {
3523 if (!m_spellInfo->Effects[i].IsEffect())
3524 continue;
3525
3526 if (m_spellInfo->Effects[i].TargetA.GetSelectionCategory() != TARGET_SELECT_CATEGORY_NEARBY || m_spellInfo->Effects[i].TargetA.GetCheckType() != TARGET_CHECK_ENTRY)
3527 {
3528 selectTargets = false;
3529 break;
3530 }
3531
3532 if (m_spellInfo->Effects[i].TargetA.GetObjectType() == TARGET_OBJECT_TYPE_DEST)
3533 {
3534 nearbyDest = true;
3535 }
3536
3537 // xinef: by default set it to false, and to true if any valid target is found
3538 selectTargets = true;
3539 }
3540
3541 if (selectTargets)
3542 {
3544 _spellTargetsSelected = true;
3545 bool spellFailed = false;
3546
3547 if (m_UniqueTargetInfo.empty() && m_UniqueGOTargetInfo.empty())
3548 {
3549 // no valid nearby target unit or game object found; check if nearby destination type
3550 if (nearbyDest)
3551 {
3552 if (!m_targets.HasDst())
3553 {
3554 // no valid target destination
3555 spellFailed = true;
3556 }
3557 }
3558 else
3559 {
3560 spellFailed = true;
3561 }
3562 }
3563
3564 if (spellFailed)
3565 {
3567 finish(false);
3569 }
3570 }
3571 }
3572
3573 // set timer base at cast time
3574 ReSetTimer();
3575
3576 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());
3577
3579 {
3581 }
3582
3583 //Containers for channeled spells have to be set
3584 //TODO:Apply this to all casted spells if needed
3585 // Why check duration? 29350: channelled triggers channelled
3587 cast(true);
3588 else
3589 {
3590 // stealth must be removed at cast starting (at show channel bar)
3591 // skip triggered spell (item equip spell casting and other not explicit character casts/item uses)
3593 {
3594 // Farsight spells exception
3595 uint32 exceptSpellId = 0;
3597 {
3598 exceptSpellId = m_spellInfo->Id;
3599 }
3600
3603 }
3604
3607
3608 // set target for proper facing
3610 {
3613 {
3614 // Xinef: Creature should focus to cast target if there is explicit target or self if casting positive spell
3615 // Xinef: Creature should not rotate when casting spell... based on halion behavior
3617 }
3618 }
3619
3620 //item: first cast may destroy item and second cast causes crash
3621 // xinef: removed !m_spellInfo->StartRecoveryTime
3622 // second los check failed in events
3623 // xinef: removed itemguid check, currently there is no such item in database
3625 cast(true);
3626
3629 }
3630
3631 sScriptMgr->OnSpellPrepare(this, m_caster, m_spellInfo);
3632
3633 return SPELL_CAST_OK;
3634}
@ CHEAT_CASTTIME
Definition Player.h:995
@ SPELL_EFFECT_APPLY_AREA_AURA_PARTY
Definition SharedDefines.h:824
@ SPELL_EFFECT_APPLY_AREA_AURA_RAID
Definition SharedDefines.h:854
@ SPELL_ATTR0_ALLOW_WHILE_SITTING
Definition SharedDefines.h:420
@ 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
@ TARGET_SELECT_CATEGORY_NEARBY
Definition SpellInfo.h:80
@ TARGET_OBJECT_TYPE_DEST
Definition SpellInfo.h:100
void FocusTarget(Spell const *focusSpell, WorldObject const *target)
Definition Creature.cpp:3445
Definition Spell.cpp:519
bool IsActionAllowedChannel() const
Definition SpellInfo.cpp:1261
int32 GetMaxDuration() const
Definition SpellInfo.cpp:2357
uint32 Attributes
Definition SpellInfo.h:324
bool IsBreakingStealth() const
Definition SpellInfo.cpp:1271
void LoadScripts()
Definition Spell.cpp:8460
void cast(bool skipCheck=false)
Definition Spell.cpp:3709
void prepareDataForTriggerSystem(AuraEffect const *triggeredByAura)
Definition Spell.cpp:2202
void SendSpellStart()
Definition Spell.cpp:4655
void TriggerGlobalCooldown()
Definition Spell.cpp:8804
void OnSpellLaunch()
Definition Spell.cpp:8865
CurrentSpellTypes GetCurrentContainer() const
Definition Spell.cpp:7865
void ReSetTimer()
Definition Spell.h:561
void InitExplicitTargets(SpellCastTargets const &targets)
Definition Spell.cpp:717
void SetCurrentCastedSpell(Spell *pSpell)
Definition Unit.cpp:4013
bool IsSitState() const
Definition Unit.cpp:16728
void Init(AuraEffect const *aurEff)
Definition Spell.cpp:8888

References _spellEvent, _spellTargetsSelected, _triggeredCastFlags, EventProcessor::AddEventAtOffset(), SpellInfo::Attributes, AURA_INTERRUPT_FLAG_CAST, AURA_INTERRUPT_FLAG_NOT_SEATED, AURA_INTERRUPT_FLAG_SPELL_ATTACK, SpellInfo::AuraInterruptFlags, SpellInfo::CalcCastTime(), SpellInfo::CalcPowerCost(), 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(), 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(), sDisableMgr, 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
2203{
2204 //==========================================================================================
2205 // Now fill data for trigger system, need know:
2206 // can spell trigger another or not (m_canTrigger)
2207 // Create base triggers flags for Attacker and Victim (m_procAttacker, m_procVictim and m_procEx)
2208 //==========================================================================================
2209
2211 // Get data for type of attack and fill base info for trigger
2212 switch (m_spellInfo->DmgClass)
2213 {
2216 if (m_attackType == OFF_ATTACK)
2218 else
2221 break;
2223 // Auto attack
2225 {
2228 }
2229 else // Ranged spell attack
2230 {
2233 }
2234 break;
2235 default:
2238 && m_spellInfo->HasAttribute(SPELL_ATTR2_AUTO_REPEAT)) // Wands auto attack
2239 {
2242 }
2243 // For other spells trigger procflags are set in Spell::DoAllEffectOnTarget
2244 // Because spell positivity is dependant on target
2245 }
2247
2248 // Hunter trap spells - activation proc for Lock and Load, Entrapment and Misdirection
2250 (m_spellInfo->SpellFamilyFlags[0] & 0x18 || // Freezing and Frost Trap, Freezing Arrow
2251 m_spellInfo->Id == 57879 || m_spellInfo->Id == 45145 || // Snake Trap - done this way to avoid double proc
2252 m_spellInfo->SpellFamilyFlags[2] & 0x00064000)) // Explosive and Immolation Trap
2253 {
2255 }
2256
2257 /* Effects which are result of aura proc from triggered spell cannot proc
2258 to prevent chain proc of these spells */
2259
2260 // Hellfire Effect - trigger as DOT
2262 {
2265 }
2266
2267 // Ranged autorepeat attack is set as triggered spell - ignore it
2269 {
2276 }
2277 // Totem casts require spellfamilymask defined in spell_proc_event to proc
2280}
@ SPELL_ATTR2_ACTIVE_THREAT
Definition SharedDefines.h:497
@ SPELL_ATTR3_NOT_A_PROC
Definition SharedDefines.h:513
@ 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
8541{
8542 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8543 (*scritr)->_InitHit();
8544}

References m_loadedScripts.

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

◆ PrepareTargetProcessing()

void Spell::PrepareTargetProcessing ( )
protected

◆ PrepareTriggersExecutedOnHit()

void Spell::PrepareTriggersExecutedOnHit ( )
protected
Todo:
: move this to scripts
Todo:
: move this to scripts
8715{
8718 {
8719 SpellInfo const* excludeCasterSpellInfo = sSpellMgr->GetSpellInfo(m_spellInfo->ExcludeCasterAuraSpell);
8720 if (excludeCasterSpellInfo && !excludeCasterSpellInfo->IsPositive())
8722 SpellInfo const* excludeTargetSpellInfo = sSpellMgr->GetSpellInfo(m_spellInfo->ExcludeTargetAuraSpell);
8723 if (excludeTargetSpellInfo && !excludeTargetSpellInfo->IsPositive())
8725 }
8726
8729 {
8731 {
8732 if (m_spellInfo->SpellFamilyFlags[1] & 0x40000000)
8733 {
8735 for(Unit::AuraEffectList::const_iterator itr = mVindication.begin(); itr != mVindication.end(); ++itr)
8736 {
8737 if ((*itr)->GetSpellInfo()->Effects[EFFECT_0].TriggerSpell == 26017 )
8738 {
8739 m_preCastSpell = 26017;
8740 break;
8741 }
8742 else if ((*itr)->GetSpellInfo()->Effects[EFFECT_0].TriggerSpell == 67 )
8743 m_preCastSpell = 67;
8744 }
8745 }
8746 break;
8747 }
8748 case SPELLFAMILY_DRUID:
8749 {
8750 // Faerie Fire (Feral)
8752 m_preCastSpell = 60089;
8753
8754 break;
8755 }
8756 }
8757
8758 // handle SPELL_AURA_ADD_TARGET_TRIGGER auras:
8759 // save auras which were present on spell caster on cast, to prevent triggered auras from affecting caster
8760 // and to correctly calculate proc chance when combopoints are present
8762 for (Unit::AuraEffectList::const_iterator i = targetTriggers.begin(); i != targetTriggers.end(); ++i)
8763 {
8764 if (!(*i)->IsAffectedOnSpell(m_spellInfo))
8765 continue;
8766 SpellInfo const* auraSpellInfo = (*i)->GetSpellInfo();
8767 uint32 auraSpellIdx = (*i)->GetEffIndex();
8768 if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(auraSpellInfo->Effects[auraSpellIdx].TriggerSpell))
8769 {
8770 // calculate the chance using spell base amount, because aura amount is not updated on combo-points change
8771 // this possibly needs fixing
8772 int32 auraBaseAmount = (*i)->GetBaseAmount();
8773 // proc chance is stored in effect amount
8774 int32 chance = m_caster->CalculateSpellDamage(nullptr, auraSpellInfo, auraSpellIdx, &auraBaseAmount);
8775 // build trigger and add to the list
8776 HitTriggerSpell spellTriggerInfo;
8777 spellTriggerInfo.triggeredSpell = spellInfo;
8778 spellTriggerInfo.triggeredByAura = auraSpellInfo;
8779 spellTriggerInfo.triggeredByEffIdx = (*i)->GetEffIndex();
8780 spellTriggerInfo.chance = chance * (*i)->GetBase()->GetStackAmount();
8781 m_hitTriggerSpells.push_back(spellTriggerInfo);
8782 }
8783 }
8784}
@ 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}
void ModifyEventTime(BasicEvent *event, Milliseconds newTime)
Definition EventProcessor.cpp:145
uint64 CalculateDelayMomentForDst() const
Definition Spell.cpp:899
uint64 GetDelayStart() const
Definition Spell.h:574

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

Referenced by WorldSession::HandleUpdateProjectilePosition().

◆ ReSetTimer()

void Spell::ReSetTimer ( )
inline
561{ 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 
)
2100{
2101 uint32 containerTypeMask = GetSearcherTypeMask(objectType, condList);
2102 if (!containerTypeMask)
2103 return;
2104 Acore::WorldObjectSpellAreaTargetCheck check(range, position, m_caster, referer, m_spellInfo, selectionType, condList);
2105 Acore::WorldObjectListSearcher<Acore::WorldObjectSpellAreaTargetCheck> searcher(m_caster, targets, check, containerTypeMask);
2106 SearchTargets<Acore::WorldObjectListSearcher<Acore::WorldObjectSpellAreaTargetCheck> > (searcher, containerTypeMask, m_caster, position, range);
2107}
uint32 GetSearcherTypeMask(SpellTargetObjectTypes objType, ConditionList *condList)
Definition Spell.cpp:2042
Definition GridNotifiers.h:230

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 
)
2110{
2111 // max dist for jump target selection
2112 float jumpRadius = 0.0f;
2113 switch (m_spellInfo->DmgClass)
2114 {
2116 // 7.5y for multi shot
2117 jumpRadius = 7.5f;
2118 break;
2120 // 5y for swipe, cleave and similar
2121 jumpRadius = 5.0f;
2122 break;
2125 // 12.5y for chain heal spell since 3.2 patch
2126 if (isChainHeal)
2127 jumpRadius = 12.5f;
2128 // 10y as default for magic chain spells
2129 else
2130 jumpRadius = 10.0f;
2131 break;
2132 }
2133
2134 // chain lightning/heal spells and similar - allow to jump at larger distance and go out of los
2138
2139 // max dist which spell can reach
2140 float searchRadius = jumpRadius;
2141 if (isBouncingFar)
2142 searchRadius *= chainTargets;
2143
2145 std::list<WorldObject*> tempTargets;
2146 SearchAreaTargets(tempTargets, searchRadius, chainSource, m_caster, objectType, selectType, condList);
2147 tempTargets.remove(target);
2148
2149 // remove targets which are always invalid for chain spells
2150 // for some spells allow only chain targets in front of caster (swipe for example)
2151 if (!isBouncingFar)
2152 tempTargets.remove_if([this](WorldObject* target) { return !m_caster->HasInArc(static_cast<float>(M_PI), target); });
2153
2154 while (chainTargets)
2155 {
2156 // try to get unit for next chain jump
2157 std::list<WorldObject*>::iterator foundItr = tempTargets.end();
2158 // get unit with highest hp deficit in dist
2159 if (isChainHeal)
2160 {
2161 uint32 maxHPDeficit = 0;
2162 for (std::list<WorldObject*>::iterator itr = tempTargets.begin(); itr != tempTargets.end(); ++itr)
2163 {
2164 if (Unit* unit = (*itr)->ToUnit())
2165 {
2166 uint32 deficit = unit->GetMaxHealth() - unit->GetHealth();
2167 if (deficit > maxHPDeficit && chainSource->IsWithinDist(unit, jumpRadius) && chainSource->IsWithinLOSInMap(unit, VMAP::ModelIgnoreFlags::M2))
2168 {
2169 foundItr = itr;
2170 maxHPDeficit = deficit;
2171 }
2172 }
2173 }
2174 }
2175 // get closest object
2176 else
2177 {
2178 for (std::list<WorldObject*>::iterator itr = tempTargets.begin(); itr != tempTargets.end(); ++itr)
2179 {
2180 if (foundItr == tempTargets.end())
2181 {
2182 if ((!isBouncingFar || chainSource->IsWithinDist(*itr, jumpRadius)) && chainSource->IsWithinLOSInMap(*itr, VMAP::ModelIgnoreFlags::M2))
2183 foundItr = itr;
2184 }
2185 else if (chainSource->GetDistanceOrder(*itr, *foundItr) && chainSource->IsWithinLOSInMap(*itr, VMAP::ModelIgnoreFlags::M2))
2186 foundItr = itr;
2187 }
2188 }
2189 // not found any valid target - chain ends
2190 if (foundItr == tempTargets.end())
2191 break;
2192
2194 chainSource = *foundItr;
2195
2196 targets.push_back(*foundItr);
2197 tempTargets.erase(foundItr);
2198 --chainTargets;
2199 }
2200}
@ SPELL_ATTR2_CHAIN_FROM_CASTER
Definition SharedDefines.h:479
@ SPELL_ATTR4_BOUNCY_CHAIN_MISSILES
Definition SharedDefines.h:559
void SearchAreaTargets(std::list< WorldObject * > &targets, float range, Position const *position, Unit *referer, SpellTargetObjectTypes objectType, SpellTargetCheckTypes selectionType, ConditionList *condList)
Definition Spell.cpp:2099
bool GetDistanceOrder(WorldObject const *obj1, WorldObject const *obj2, bool is3D=true) const
Definition Object.cpp:1414
bool IsWithinDist(WorldObject const *obj, float dist2compare, bool is3D=true, bool incOwnRadius=true, bool incTargetRadius=true) const
Definition Object.cpp:1349

References SpellInfo::DmgClass, WorldObject::GetDistanceOrder(), SpellInfo::HasAttribute(), Position::HasInArc(), WorldObject::IsWithinDist(), WorldObject::IsWithinLOSInMap(), VMAP::M2, m_caster, m_spellInfo, SearchAreaTargets(), SPELL_ATTR2_CHAIN_FROM_CASTER, 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 
)
2088{
2089 WorldObject* target = nullptr;
2090 uint32 containerTypeMask = GetSearcherTypeMask(objectType, condList);
2091 if (!containerTypeMask)
2092 return nullptr;
2093 Acore::WorldObjectSpellNearbyTargetCheck check(range, m_caster, m_spellInfo, selectionType, condList);
2095 SearchTargets<Acore::WorldObjectLastSearcher<Acore::WorldObjectSpellNearbyTargetCheck> > (searcher, containerTypeMask, m_caster, m_caster, range);
2096 return target;
2097}
Definition GridNotifiers.h:210

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 
)
2080{
2081 if (!containerMask)
2082 return;
2083
2084 Cell::VisitObjects(pos->GetPositionX(), pos->GetPositionY(), referer->GetMap(), searcher, radius);
2085}

References WorldObject::GetMap(), Position::GetPositionX(), Position::GetPositionY(), and Cell::VisitObjects().

◆ 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:1730
void CheckDst()
Definition Spell.h:503
void SelectImplicitTrajTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition Spell.cpp:1876
void SelectImplicitConeTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType, uint32 effMask)
Definition Spell.cpp:1214
void SelectImplicitTargetDestTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition Spell.cpp:1693
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:1813
void SelectImplicitCasterObjectTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition Spell.cpp:1766
void SelectImplicitNearbyTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType, uint32 effMask)
Definition Spell.cpp:1100
bool CheckScriptEffectImplicitTargets(uint32 effIndex, uint32 effIndexToCheck)
Definition Spell.cpp:8675
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
1960{
1961 // special case for SPELL_EFFECT_SUMMON_RAF_FRIEND and SPELL_EFFECT_SUMMON_PLAYER
1963 switch (m_spellInfo->Effects[effIndex].Effect)
1964 {
1968 {
1970
1972
1973 if (target && target->ToPlayer())
1974 AddUnitTarget(target->ToUnit(), 1 << effIndex, false);
1975 }
1976 return;
1977 default:
1978 break;
1979 }
1980
1981 // select spell implicit targets based on effect type
1982 if (!m_spellInfo->Effects[effIndex].GetImplicitTargetType())
1983 return;
1984
1985 uint32 targetMask = m_spellInfo->Effects[effIndex].GetMissingTargetMask();
1986
1987 if (!targetMask)
1988 return;
1989
1990 WorldObject* target = nullptr;
1991
1992 switch (m_spellInfo->Effects[effIndex].GetImplicitTargetType())
1993 {
1994 // add explicit object target or self to the target map
1996 // player which not released his spirit is Unit, but target flag for it is TARGET_FLAG_CORPSE_MASK
1998 {
2000 target = unitTarget;
2001 else if (targetMask & TARGET_FLAG_CORPSE_MASK)
2002 {
2003 if (Corpse* corpseTarget = m_targets.GetCorpseTarget())
2004 {
2006 if (Player* owner = ObjectAccessor::FindPlayer(corpseTarget->GetOwnerGUID()))
2007 target = owner;
2008 }
2009 }
2010 else //if (targetMask & TARGET_FLAG_UNIT_MASK)
2011 target = m_caster;
2012 }
2013 if (targetMask & TARGET_FLAG_ITEM_MASK)
2014 {
2016 AddItemTarget(itemTarget, 1 << effIndex);
2017 return;
2018 }
2019 if (targetMask & TARGET_FLAG_GAMEOBJECT_MASK)
2020 target = m_targets.GetGOTarget();
2021 break;
2022 // add self to the target map
2024 if (targetMask & TARGET_FLAG_UNIT_MASK)
2025 target = m_caster;
2026 break;
2027 default:
2028 break;
2029 }
2030
2032
2033 if (target)
2034 {
2035 if (target->ToUnit())
2036 AddUnitTarget(target->ToUnit(), 1 << effIndex, false);
2037 else if (target->ToGameObject())
2038 AddGOTarget(target->ToGameObject(), 1 << effIndex);
2039 }
2040}
@ 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:214
Corpse * GetCorpseTarget() const
Definition Spell.cpp:294
Definition SpellInfo.h:217
void AddGOTarget(GameObject *target, uint32 effectMask)
Definition Spell.cpp:2424
void AddUnitTarget(Unit *target, uint32 effectMask, bool checkIfValid=true, bool implicit=true)
Definition Spell.cpp:2291
void AddItemTarget(Item *item, uint32 effectMask)
Definition Spell.cpp:2486
void CallScriptObjectTargetSelectHandlers(WorldObject *&target, SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition Spell.cpp:8647

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:11137
Unit * GetMagicHitRedirectTarget(Unit *victim, SpellInfo const *spellInfo)
Definition Unit.cpp:11099

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}
@ SPELL_AURA_MOD_MAX_AFFECTED_TARGETS
Definition SpellAuraDefines.h:340
@ TARGET_REFERENCE_TYPE_SRC
Definition SpellInfo.h:92
@ TARGET_REFERENCE_TYPE_LAST
Definition SpellInfo.h:91
Position const * GetSrcPos() const
Definition Spell.cpp:362
void CallScriptObjectAreaTargetSelectHandlers(std::list< WorldObject * > &targets, SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition Spell.cpp:8633
void RandomResize(C &container, std::size_t requestedSize)
Definition Containers.h:79
float RadiusMod
Definition Spell.h:225
uint32 MaxAffectedTargets
Definition Spell.h:224

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;
1387 LiquidData const& liquidData = m_caster->GetMap()->GetLiquidData(m_caster->GetPhaseMask(), x, y, z, m_caster->GetCollisionHeight(), {});
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 // Added GROUND_HEIGHT_TOLERANCE to account for cases where, during a jump,
1435 // the Z position may be slightly below the vmap ground level.
1436 // Without this tolerance, a ray trace might incorrectly attempt to find ground
1437 // beneath the actual surface.
1438 //
1439 // Example:
1440 // actual vmap ground: -56.342392
1441 // Z position: -56.347195
1442 float searchGroundZPos = pos.GetPositionZ()+GROUND_HEIGHT_TOLERANCE;
1443 float ground = map->GetHeight(phasemask, pos.GetPositionX(), pos.GetPositionY(), searchGroundZPos);
1444
1445 bool isCasterInWater = m_caster->IsInWater();
1446 if (!m_caster->HasUnitMovementFlag(MOVEMENTFLAG_FALLING) || (pos.GetPositionZ() - ground < distance))
1447 {
1448 float tstX = 0.0f, tstY = 0.0f, tstZ = 0.0f, prevX = 0.0f, prevY = 0.0f, prevZ = 0.0f;
1449 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;
1450 float maxtravelDistZ = 2.65f;
1451 float overdistance = 0.0f;
1452 float totalpath = 0.0f;
1453 float beforewaterz = 0.0f;
1454 bool inwater = false;
1455 bool wcol = false;
1456 const float step = 2.0f;
1457 const uint8 numChecks = std::ceil(std::fabs(distance / step));
1458 const float DELTA_X = (destx - pos.GetPositionX()) / numChecks;
1459 const float DELTA_Y = (desty - pos.GetPositionY()) / numChecks;
1460 int j = 1;
1461 for (; j < (numChecks + 1); j++)
1462 {
1463 prevX = pos.GetPositionX() + (float(j - 1) * DELTA_X);
1464 prevY = pos.GetPositionY() + (float(j - 1) * DELTA_Y);
1465 tstX = pos.GetPositionX() + (float(j) * DELTA_X);
1466 tstY = pos.GetPositionY() + (float(j) * DELTA_Y);
1467
1468 if (j < 2)
1469 {
1470 prevZ = pos.GetPositionZ();
1471 }
1472 else
1473 {
1474 prevZ = tstZ;
1475 }
1476
1477 tstZ = map->GetHeight(phasemask, tstX, tstY, prevZ + maxtravelDistZ, true);
1478 ground = tstZ;
1479
1480 if (!isCasterInWater)
1481 {
1482 if (map->IsInWater(phasemask, tstX, tstY, tstZ, collisionHeight))
1483 {
1484 if (!(beforewaterz != 0.0f))
1485 {
1486 beforewaterz = prevZ;
1487 }
1488 tstZ = beforewaterz;
1489 srange = sqrt((tstY - prevY) * (tstY - prevY) + (tstX - prevX) * (tstX - prevX));
1490 //LOG_ERROR("spells", "(start was from land) step in water , number of cycle = {} , distance of step = {}, total path = {}, Z = {}", j, srange, totalpath, tstZ);
1491 }
1492 }
1493 else if (map->IsInWater(phasemask, tstX, tstY, tstZ, collisionHeight))
1494 {
1495 prevZ = pos.GetPositionZ();
1496 tstZ = pos.GetPositionZ();
1497 srange = sqrt((tstY - prevY) * (tstY - prevY) + (tstX - prevX) * (tstX - prevX));
1498
1499 inwater = true;
1500 if (inwater && (fabs(tstZ - ground) < 2.0f))
1501 {
1502 wcol = true;
1503 //LOG_ERROR("spells", "step in water with collide and use standart check (for continue way after possible collide), number of cycle = {} ", j);
1504 }
1505
1506 // if (j < 2)
1507 // LOG_ERROR("spells", "(start in water) step in water, number of cycle = {} , distance of step = {}, total path = {}", j, srange, totalpath);
1508 // else
1509 // LOG_ERROR("spells", "step in water, number of cycle = {} , distance of step = {}, total path = {}", j, srange, totalpath);
1510 }
1511
1512 bool IsInWater = map->IsInWater(phasemask, tstX, tstY, tstZ, collisionHeight);
1513 if ((!IsInWater && tstZ != beforewaterz) || wcol) // second safety check z for blink way if on the ground
1514 {
1515 if (inwater && !IsInWater)
1516 inwater = false;
1517
1518 // highest available point
1519 tstZ1 = map->GetHeight(phasemask, tstX, tstY, prevZ + maxtravelDistZ, true, 25.0f);
1520 // upper or floor
1521 tstZ2 = map->GetHeight(phasemask, tstX, tstY, prevZ, true, 25.0f);
1522 //lower than floor
1523 tstZ3 = map->GetHeight(phasemask, tstX, tstY, prevZ - maxtravelDistZ / 2, true, 25.0f);
1524
1525 //distance of rays, will select the shortest in 3D
1526 srange1 = sqrt((tstY - prevY) * (tstY - prevY) + (tstX - prevX) * (tstX - prevX) + (tstZ1 - prevZ) * (tstZ1 - prevZ));
1527 //LOG_ERROR("spells", "step = {}, distance of ray1 = {}", j, srange1);
1528 srange2 = sqrt((tstY - prevY) * (tstY - prevY) + (tstX - prevX) * (tstX - prevX) + (tstZ2 - prevZ) * (tstZ2 - prevZ));
1529 //LOG_ERROR("spells", "step = {}, distance of ray2 = {}", j, srange2);
1530 srange3 = sqrt((tstY - prevY) * (tstY - prevY) + (tstX - prevX) * (tstX - prevX) + (tstZ3 - prevZ) * (tstZ3 - prevZ));
1531 //LOG_ERROR("spells", "step = {}, distance of ray3 = {}", j, srange3);
1532
1533 if (srange1 < srange2)
1534 {
1535 tstZ = tstZ1;
1536 srange = srange1;
1537 }
1538 else if (srange3 < srange2)
1539 {
1540 tstZ = tstZ3;
1541 srange = srange3;
1542 }
1543 else
1544 {
1545 tstZ = tstZ2;
1546 srange = srange2;
1547 }
1548
1549 //LOG_ERROR("spells", "step on ground, number of cycle = {} , distance of step = {}, total path = {}", j, srange, totalpath);
1550 }
1551
1552 destx = tstX;
1553 desty = tstY;
1554 destz = tstZ;
1555
1556 totalpath += srange;
1557
1558 if (totalpath > distance)
1559 {
1560 overdistance = totalpath - distance;
1561 //LOG_ERROR("spells", "total path > than distance in 3D , need to move back a bit for save distance, total path = {}, overdistance = {}", totalpath, overdistance);
1562 }
1563
1564 bool col = VMAP::VMapFactory::createOrGetVMapMgr()->GetObjectHitPos(mapid, prevX, prevY, prevZ + 0.5f, tstX, tstY, tstZ + 0.5f, tstX, tstY, tstZ, -0.5f);
1565 // check dynamic collision
1566 bool dcol = m_caster->GetMap()->GetObjectHitPos(phasemask, prevX, prevY, prevZ + 0.5f, tstX, tstY, tstZ + 0.5f, tstX, tstY, tstZ, -0.5f);
1567
1568 // collision occured
1569 if (col || dcol || (overdistance > 0.0f && !map->IsInWater(phasemask, tstX, tstY, ground, collisionHeight)) || (fabs(prevZ - tstZ) > maxtravelDistZ && (tstZ > prevZ)))
1570 {
1571 if ((overdistance > 0.0f) && (overdistance < 1.f))
1572 {
1573 destx = prevX + overdistance * cos(pos.GetOrientation());
1574 desty = prevY + overdistance * sin(pos.GetOrientation());
1575 //LOG_ERROR("spells", "(collision) collision occured 1");
1576 }
1577 else
1578 {
1579 // move back a bit
1580 destx = tstX - (0.6 * cos(pos.GetOrientation()));
1581 desty = tstY - (0.6 * sin(pos.GetOrientation()));
1582 //LOG_ERROR("spells", "(collision) collision occured 2");
1583 }
1584
1585 // highest available point
1586 destz1 = map->GetHeight(phasemask, destx, desty, prevZ + maxtravelDistZ, true, 25.0f);
1587 // upper or floor
1588 destz2 = map->GetHeight(phasemask, destx, desty, prevZ, true, 25.0f);
1589 //lower than floor
1590 destz3 = map->GetHeight(phasemask, destx, desty, prevZ - maxtravelDistZ / 2, true, 25.0f);
1591
1592 //distance of rays, will select the shortest in 3D
1593 srange1 = sqrt((desty - prevY) * (desty - prevY) + (destx - prevX) * (destx - prevX) + (destz1 - prevZ) * (destz1 - prevZ));
1594 srange2 = sqrt((desty - prevY) * (desty - prevY) + (destx - prevX) * (destx - prevX) + (destz2 - prevZ) * (destz2 - prevZ));
1595 srange3 = sqrt((desty - prevY) * (desty - prevY) + (destx - prevX) * (destx - prevX) + (destz3 - prevZ) * (destz3 - prevZ));
1596
1597 if (srange1 < srange2)
1598 destz = destz1;
1599 else if (srange3 < srange2)
1600 destz = destz3;
1601 else
1602 destz = destz2;
1603
1604 if (inwater && destz < prevZ && !wcol)
1605 destz = prevZ;
1606 //LOG_ERROR("spells", "(collision) destZ rewrited in prevZ");
1607
1608 // Don't make the player move backward from the xy adjustments by collisions.
1609 if ((DELTA_X > 0 && startx > destx) || (DELTA_X < 0 && startx < destx) ||
1610 (DELTA_Y > 0 && starty > desty) || (DELTA_Y < 0 && starty < desty))
1611 {
1612 destx = startx;
1613 desty = starty;
1614 destz = startz;
1615 }
1616
1617 break;
1618 }
1619 // we have correct destz now
1620 }
1621
1622 lastpos.Relocate(destx, desty, destz, pos.GetOrientation());
1623 dest = SpellDestination(lastpos);
1624 }
1625 else
1626 {
1627 float z = pos.GetPositionZ();
1628 bool col = VMAP::VMapFactory::createOrGetVMapMgr()->GetObjectHitPos(mapid, pos.GetPositionX(), pos.GetPositionY(), z, destx, desty, z, destx, desty, z, -0.5f);
1629 // check dynamic collision
1630 bool dcol = m_caster->GetMap()->GetObjectHitPos(phasemask, pos.GetPositionX(), pos.GetPositionY(), z, destx, desty, z, destx, desty, z, -0.5f);
1631
1632 // collision occured
1633 if (col || dcol)
1634 {
1635 // move back a bit
1636 destx = destx - (0.6 * cos(pos.GetOrientation()));
1637 desty = desty - (0.6 * sin(pos.GetOrientation()));
1638 }
1639
1640 lastpos.Relocate(destx, desty, z, pos.GetOrientation());
1641 dest = SpellDestination(lastpos);
1642 //float range = sqrt((desty - pos.GetPositionY())*(desty - pos.GetPositionY()) + (destx - pos.GetPositionX())*(destx - pos.GetPositionX()));
1643 //LOG_ERROR("spells", "Blink number 2, in falling but at a hight, distance of blink = {}", range);
1644 }
1645 break;
1646 }
1647 default:
1648 {
1649 float dist = m_spellInfo->Effects[effIndex].CalcRadius(m_caster);
1650 float angle = targetType.CalcDirectionAngle();
1651 float objSize = m_caster->GetCombatReach();
1652
1653 switch (targetType.GetTarget())
1654 {
1656 dist = PET_FOLLOW_DIST;
1657 break;
1659 if (dist > objSize)
1660 dist = objSize + (dist - objSize) * float(rand_norm());
1661 break;
1666 {
1667 static float const DefaultTotemDistance = 3.0f;
1668 if (!m_spellInfo->Effects[effIndex].HasRadius())
1669 dist = DefaultTotemDistance;
1670 break;
1671 }
1672 default:
1673 break;
1674 }
1675
1676 if (dist < objSize)
1677 {
1678 dist = objSize;
1679 }
1680
1681 Position pos = dest._position;
1682 m_caster->MovePositionToFirstCollision(pos, dist, angle);
1683
1684 dest.Relocate(pos);
1685 break;
1686 }
1687 }
1688
1689 CallScriptDestinationTargetSelectHandlers(dest, effIndex, targetType);
1690 m_targets.SetDst(dest);
1691}
#define VMAP_INVALID_HEIGHT_VALUE
Definition IVMapMgr.h:49
@ SPELL_EFFECT_BIND
Definition SharedDefines.h:800
@ SPELL_EFFECT_TELEPORT_UNITS
Definition SharedDefines.h:794
@ TARGET_DEST_CASTER_RANDOM
Definition SharedDefines.h:1487
@ TARGET_DEST_DB
Definition SharedDefines.h:1433
@ TARGET_DEST_CASTER_FRONT_LEAP
Definition SharedDefines.h:1470
@ TARGET_DEST_CASTER_FRONT_LEFT
Definition SharedDefines.h:1459
@ TARGET_DEST_CASTER_BACK_RIGHT
Definition SharedDefines.h:1457
@ TARGET_DEST_CASTER_FISHING
Definition SharedDefines.h:1454
@ TARGET_DEST_CASTER_BACK_LEFT
Definition SharedDefines.h:1458
@ TARGET_DEST_CASTER_SUMMON
Definition SharedDefines.h:1447
@ TARGET_DEST_CASTER
Definition SharedDefines.h:1434
@ TARGET_DEST_CASTER_FRONT_RIGHT
Definition SharedDefines.h:1456
@ TARGET_DEST_CASTER_36
Definition SharedDefines.h:1451
@ TARGET_DEST_HOME
Definition SharedDefines.h:1429
float const GROUND_HEIGHT_TOLERANCE
Definition SharedDefines.h:26
@ SPELL_FAILED_TOO_SHALLOW
Definition SharedDefines.h:1116
@ MOVEMENTFLAG_FALLING
Definition UnitDefines.h:381
LiquidData const GetLiquidData(uint32 phaseMask, float x, float y, float z, float collisionHeight, Optional< uint8 > ReqLiquidType)
Definition Map.cpp:1297
float GetHeight(float x, float y, float z, bool checkVMap=true, float maxSearchDist=DEFAULT_HEIGHT_SEARCH) const
Definition Map.cpp:1145
bool IsInWater(uint32 phaseMask, float x, float y, float z, float collisionHeight) const
Definition Map.cpp:1594
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:1572
void CallScriptDestinationTargetSelectHandlers(SpellDestination &target, SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition Spell.cpp:8661
float GetCollisionHeight() const override
Return collision height sent to client.
Definition Unit.cpp:20982
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:3037
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:2644
Definition GridTerrainData.h:199
float Level
Definition GridTerrainData.h:204
LiquidStatus Status
Definition GridTerrainData.h:206
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(), GROUND_HEIGHT_TOLERANCE, SpellInfo::HasEffect(), Unit::HasUnitMovementFlag(), SpellInfo::Id, Unit::IsInWater(), Map::IsInWater(), WorldObject::IsWithinLOS(), LiquidData::Level, LOG_DEBUG, m_caster, m_spellInfo, m_targets, 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 
)
1767{
1768 WorldObject* target = nullptr;
1769 bool checkIfValid = true;
1770
1771 switch (targetType.GetTarget())
1772 {
1773 case TARGET_UNIT_CASTER:
1774 target = m_caster;
1775 checkIfValid = false;
1776 break;
1777 case TARGET_UNIT_MASTER:
1778 target = m_caster->GetCharmerOrOwner();
1779 break;
1780 case TARGET_UNIT_PET:
1781 target = m_caster->GetGuardianPet();
1782 if (!target)
1783 target = m_caster->GetCharm();
1784 break;
1786 if (m_caster->IsSummon())
1787 target = m_caster->ToTempSummon()->GetSummonerUnit();
1788 break;
1790 target = m_caster->GetVehicleBase();
1791 break;
1801 target = m_caster->GetVehicleKit()->GetPassenger(targetType.GetTarget() - TARGET_UNIT_PASSENGER_0);
1802 break;
1803 default:
1804 break;
1805 }
1806
1807 CallScriptObjectTargetSelectHandlers(target, effIndex, targetType);
1808
1809 if (target && target->ToUnit())
1810 AddUnitTarget(target->ToUnit(), 1 << effIndex, checkIfValid);
1811}
@ TARGET_UNIT_PASSENGER_1
Definition SharedDefines.h:1512
@ TARGET_UNIT_PASSENGER_6
Definition SharedDefines.h:1517
@ TARGET_UNIT_VEHICLE
Definition SharedDefines.h:1509
@ TARGET_UNIT_PASSENGER_2
Definition SharedDefines.h:1513
@ TARGET_UNIT_PASSENGER_4
Definition SharedDefines.h:1515
@ TARGET_UNIT_PASSENGER_7
Definition SharedDefines.h:1518
@ TARGET_UNIT_MASTER
Definition SharedDefines.h:1442
@ TARGET_UNIT_PASSENGER_5
Definition SharedDefines.h:1516
@ TARGET_UNIT_PASSENGER_3
Definition SharedDefines.h:1514
@ TARGET_UNIT_SUMMONER
Definition SharedDefines.h:1507
@ TARGET_UNIT_PASSENGER_0
Definition SharedDefines.h:1511
Unit * GetSummonerUnit() const
Definition TemporarySummon.cpp:44
Unit * GetVehicleBase() const
Definition Unit.cpp:18773
Unit * GetPassenger(int8 seatId) const
Definition Vehicle.cpp:228

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 
)
1836{
1837 uint32 maxTargets = m_spellInfo->Effects[effIndex].ChainTarget;
1838 if (Player* modOwner = m_caster->GetSpellModOwner())
1839 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_JUMP_TARGETS, maxTargets, this);
1840
1841 if (maxTargets > 1)
1842 {
1843 // mark damage multipliers as used
1844 for (uint32 k = effIndex; k < MAX_SPELL_EFFECTS; ++k)
1845 if (effMask & (1 << k))
1846 m_damageMultipliers[k] = 1.0f;
1847 m_applyMultiplierMask |= effMask;
1848
1849 std::list<WorldObject*> targets;
1850 SearchChainTargets(targets, maxTargets - 1, target, targetType.GetObjectType(), targetType.GetCheckType(), targetType.GetSelectionCategory()
1851 , m_spellInfo->Effects[effIndex].ImplicitTargetConditions, targetType.GetTarget() == TARGET_UNIT_TARGET_CHAINHEAL_ALLY);
1852
1853 // Chain primary target is added earlier
1854 CallScriptObjectAreaTargetSelectHandlers(targets, effIndex, targetType);
1855
1856 for (std::list<WorldObject*>::iterator itr = targets.begin(); itr != targets.end(); ++itr)
1857 if (Unit* unitTarget = (*itr)->ToUnit())
1858 AddUnitTarget(unitTarget, effMask, false);
1859 }
1860}
@ TARGET_UNIT_TARGET_CHAINHEAL_ALLY
Definition SharedDefines.h:1460
@ 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:2109

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:1491
@ TARGET_UNIT_CHANNEL_TARGET
Definition SharedDefines.h:1492
@ TARGET_DEST_CHANNEL_CASTER
Definition SharedDefines.h:1521
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 
)
1731{
1732 // set destination to caster if no dest provided
1733 // can only happen if previous destination target could not be set for some reason
1734 // (not found nearby target, or channel target for example
1735 // maybe we should abort the spell in such case?
1736 CheckDst();
1737
1739
1740 switch (targetType.GetTarget())
1741 {
1745 case TARGET_DEST_DEST:
1746 return;
1747 default:
1748 {
1749 float angle = targetType.CalcDirectionAngle();
1750 float dist = m_spellInfo->Effects[effIndex].CalcRadius(m_caster);
1751 if (targetType.GetTarget() == TARGET_DEST_DEST_RANDOM)
1752 dist *= float(rand_norm());
1753
1754 Position pos = dest._position;
1755 m_caster->MovePosition(pos, dist, angle);
1756
1757 dest.Relocate(pos);
1758 break;
1759 }
1760 }
1761
1762 CallScriptDestinationTargetSelectHandlers(dest, effIndex, targetType);
1763 m_targets.ModDst(dest);
1764}
@ TARGET_DEST_DYNOBJ_ENEMY
Definition SharedDefines.h:1443
@ TARGET_DEST_DEST_RANDOM
Definition SharedDefines.h:1501
@ TARGET_DEST_DEST
Definition SharedDefines.h:1502
@ TARGET_DEST_DYNOBJ_NONE
Definition SharedDefines.h:1503
@ TARGET_DEST_DYNOBJ_ALLY
Definition SharedDefines.h:1444
void ModDst(Position const &pos)
Definition Spell.cpp:436
SpellDestination const * GetDst() const
Definition Spell.cpp:396
void MovePosition(Position &pos, float dist, float angle)
Definition Object.cpp:2794

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(), TARGET_DEST_DEST, TARGET_DEST_DEST_RANDOM, TARGET_DEST_DYNOBJ_ALLY, TARGET_DEST_DYNOBJ_ENEMY, and TARGET_DEST_DYNOBJ_NONE.

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:2087
void SelectImplicitChainTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType, WorldObject *target, uint32 effMask)
Definition Spell.cpp:1835

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 
)
1694{
1696
1697 SpellDestination dest(*target);
1698
1699 switch (targetType.GetTarget())
1700 {
1703 break;
1704 default:
1705 {
1706 float angle = targetType.CalcDirectionAngle();
1707 float dist = m_spellInfo->Effects[effIndex].CalcRadius(nullptr);
1708 if (targetType.GetTarget() == TARGET_DEST_TARGET_RANDOM)
1709 {
1710 dist *= float(rand_norm());
1711 }
1712
1713 if (targetType.GetTarget() == TARGET_DEST_TARGET_BACK)
1714 {
1716 }
1717
1718 Position pos = dest._position;
1719 target->MovePositionToFirstCollision(pos, dist, angle);
1720
1721 dest.Relocate(pos);
1722 break;
1723 }
1724 }
1725
1726 CallScriptDestinationTargetSelectHandlers(dest, effIndex, targetType);
1727 m_targets.SetDst(dest);
1728}
@ TARGET_DEST_TARGET_ANY
Definition SharedDefines.h:1478
@ TARGET_DEST_TARGET_BACK
Definition SharedDefines.h:1480
@ TARGET_DEST_TARGET_RANDOM
Definition SharedDefines.h:1489
@ TARGET_DEST_TARGET_ENEMY
Definition SharedDefines.h:1468
@ 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 
)
1814{
1815 ASSERT((m_targets.GetObjectTarget() || m_targets.GetItemTarget()) && "Spell::SelectImplicitTargetObjectTargets - no explicit object or item target available!");
1816
1818
1819 CallScriptObjectTargetSelectHandlers(target, effIndex, targetType);
1820
1821 if (target)
1822 {
1823 if (Unit* unit = target->ToUnit())
1824 AddUnitTarget(unit, 1 << effIndex, true, false);
1825 else if (GameObject* gobj = target->ToGameObject())
1826 AddGOTarget(gobj, 1 << effIndex);
1827
1828 SelectImplicitChainTargets(effIndex, targetType, target, 1 << effIndex);
1829 }
1830 // Script hook can remove object target and we would wrongly land here
1831 else if (Item* item = m_targets.GetItemTarget())
1832 AddItemTarget(item, 1 << effIndex);
1833}

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 
)
1877{
1878 if (!m_targets.HasTraj())
1879 return;
1880
1881 float dist2d = m_targets.GetDist2d();
1882 if (!dist2d)
1883 return;
1884
1885 Position srcPos = *m_targets.GetSrcPos();
1887 float srcToDestDelta = m_targets.GetDstPos()->m_positionZ - srcPos.m_positionZ;
1888
1889 std::list<WorldObject*> targets;
1890 Acore::WorldObjectSpellTrajTargetCheck check(dist2d, &srcPos, m_caster, m_spellInfo, targetType.GetCheckType(), m_spellInfo->Effects[effIndex].ImplicitTargetConditions);
1892 SearchTargets<Acore::WorldObjectListSearcher<Acore::WorldObjectSpellTrajTargetCheck> > (searcher, GRID_MAP_TYPE_MASK_ALL, m_caster, &srcPos, dist2d);
1893 if (targets.empty())
1894 return;
1895
1897
1898 float b = tangent(m_targets.GetElevation());
1899 float a = (srcToDestDelta - dist2d * b) / (dist2d * dist2d);
1900 if (a > -0.0001f)
1901 a = 0.f;
1902
1903 // We should check if triggered spell has greater range (which is true in many cases, and initial spell has too short max range)
1904 // limit max range to 300 yards, sometimes triggered spells can have 50000yds
1905 float bestDist = m_spellInfo->GetMaxRange(false);
1906 if (SpellInfo const* triggerSpellInfo = sSpellMgr->GetSpellInfo(m_spellInfo->Effects[effIndex].TriggerSpell))
1907 bestDist = std::min(std::max(bestDist, triggerSpellInfo->GetMaxRange(false)), std::min(dist2d, 300.0f));
1908
1909 // GameObjects don't cast traj
1910 Unit* unitCaster = ASSERT_NOTNULL(m_caster->ToUnit());
1911 for (auto itr = targets.begin(); itr != targets.end(); ++itr)
1912 {
1913 if (m_spellInfo->CheckTarget(unitCaster, *itr, true) != SPELL_CAST_OK)
1914 continue;
1915
1916 if (Unit* unit = (*itr)->ToUnit())
1917 {
1918 if (unitCaster == *itr || unitCaster->IsOnVehicle(unit) || unit->GetVehicle())
1919 continue;
1920
1921 if (Creature* creatureTarget = unit->ToCreature())
1922 {
1923 if (!(creatureTarget->GetCreatureTemplate()->type_flags & CREATURE_TYPE_FLAG_COLLIDE_WITH_MISSILES))
1924 continue;
1925 }
1926 }
1927
1928 float const size = std::max((*itr)->GetCombatReach(), 1.0f);
1929 float const objDist2d = srcPos.GetExactDist2d(*itr);
1930 float const dz = (*itr)->GetPositionZ() - srcPos.m_positionZ;
1931
1932 float const horizontalDistToTraj = std::fabs(objDist2d * std::sin(srcPos.GetRelativeAngle(*itr)));
1933 float const sizeFactor = std::cos((horizontalDistToTraj / size) * (M_PI / 2.0f));
1934 float const distToHitPoint = std::max(objDist2d * std::cos(srcPos.GetRelativeAngle(*itr)) - size * sizeFactor, 0.0f);
1935 float const height = distToHitPoint * (a * distToHitPoint + b);
1936
1937 if (fabs(dz - height) > size + b / 2.0f + TRAJECTORY_MISSILE_SIZE)
1938 continue;
1939
1940 if (distToHitPoint < bestDist)
1941 {
1942 bestDist = distToHitPoint;
1943 break;
1944 }
1945 }
1946
1947 if (dist2d > bestDist)
1948 {
1949 float x = m_targets.GetSrcPos()->m_positionX + std::cos(unitCaster->GetOrientation()) * bestDist;
1950 float y = m_targets.GetSrcPos()->m_positionY + std::sin(unitCaster->GetOrientation()) * bestDist;
1951 float z = m_targets.GetSrcPos()->m_positionZ + bestDist * (a * bestDist + b);
1952
1953 SpellDestination dest(x, y, z, unitCaster->GetOrientation());
1954 CallScriptDestinationTargetSelectHandlers(dest, effIndex, targetType);
1955 m_targets.ModDst(dest);
1956 }
1957}
#define ASSERT_NOTNULL(pointer)
Definition Errors.h:85
@ CREATURE_TYPE_FLAG_COLLIDE_WITH_MISSILES
Definition SharedDefines.h:2725
float tangent(float x)
Definition Spell.cpp:1862
#define TRAJECTORY_MISSILE_SIZE
Definition Spell.h:42
Definition Object.h:795
float GetElevation() const
Definition Spell.h:178
bool IsOnVehicle(Unit const *vehicle) const
Definition Unit.h:1881
void SetOrientation(float orientation)
Definition Position.h:116

References ASSERT_NOTNULL, CallScriptDestinationTargetSelectHandlers(), SpellInfo::CheckTarget(), CREATURE_TYPE_FLAG_COLLIDE_WITH_MISSILES, SpellInfo::Effects, SpellImplicitTargetInfo::GetCheckType(), SpellCastTargets::GetDist2d(), SpellCastTargets::GetDstPos(), SpellCastTargets::GetElevation(), Position::GetExactDist2d(), SpellInfo::GetMaxRange(), Position::GetOrientation(), Position::GetRelativeAngle(), SpellCastTargets::GetSrcPos(), GRID_MAP_TYPE_MASK_ALL, SpellCastTargets::HasTraj(), Unit::IsOnVehicle(), m_caster, Position::m_positionX, Position::m_positionY, Position::m_positionZ, m_spellInfo, m_targets, SpellCastTargets::ModDst(), Position::SetOrientation(), SPELL_CAST_OK, sSpellMgr, tangent(), Object::ToCreature(), Object::ToUnit(), and TRAJECTORY_MISSILE_SIZE.

Referenced by SelectEffectImplicitTargets().

◆ 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}
uint32 GetTargetFlagMask(SpellTargetObjectTypes objType)
Definition SpellInfo.cpp:31
@ TARGET_FLAG_GAMEOBJECT
Definition SpellInfo.h:57
@ TARGET_FLAG_GAMEOBJECT_ITEM
Definition SpellInfo.h:60
void SetTargetFlag(SpellCastTargetFlags flag)
Definition Spell.h:130
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:2515
void SelectEffectTypeImplicitTargets(uint8 effIndex)
Definition Spell.cpp:1959

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
4608{
4609 if (result == SPELL_CAST_OK)
4610 return;
4611
4612 WorldPacket data(SMSG_CAST_FAILED, 1 + 4 + 1);
4613 WriteCastResultInfo(data, caster, spellInfo, castCount, result, customError);
4614
4615 caster->SendDirectMessage(&data);
4616}
static void WriteCastResultInfo(WorldPacket &data, Player *caster, SpellInfo const *spellInfo, uint8 castCount, SpellCastResult result, SpellCustomErrors customError)
Definition Spell.cpp:4502
@ SMSG_CAST_FAILED
Definition Opcodes.h:334

References Player::SendDirectMessage(), 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)
4619{
4620 if (result == SPELL_CAST_OK)
4621 return;
4622
4623 if (!m_caster->IsPlayer() || m_caster->IsCharmed())
4624 return;
4625
4626 if (m_caster->ToPlayer()->GetSession()->PlayerLoading()) // don't send cast results at loading time
4627 return;
4628
4629 // 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
4631 result = SPELL_FAILED_DONT_REPORT;
4632
4634}
@ SPELL_FAILED_BM_OR_INVISGOD
Definition SharedDefines.h:1119
@ TRIGGERED_DONT_REPORT_CAST_ERROR
Disallows proc events from triggered spell (default)
Definition SpellDefines.h:149
bool IsCharmed() const
Definition Unit.h:1277

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)
5145{
5146 ObjectGuid channelTarget = m_targets.GetObjectTargetGUID();
5147 if (!channelTarget && !m_spellInfo->NeedsExplicitUnitTarget())
5148 if (m_UniqueTargetInfo.size() + m_UniqueGOTargetInfo.size() == 1) // this is for TARGET_SELECT_CATEGORY_NEARBY
5149 channelTarget = !m_UniqueTargetInfo.empty() ? m_UniqueTargetInfo.front().targetGUID : m_UniqueGOTargetInfo.front().targetGUID;
5150
5151 WorldPacket data(MSG_CHANNEL_START, (8 + 4 + 4));
5152 data << m_caster->GetPackGUID();
5153 data << uint32(m_spellInfo->Id);
5154 data << uint32(duration);
5155
5156 m_caster->SendMessageToSet(&data, true);
5157
5160
5161 m_timer = duration;
5162 if (channelTarget)
5164
5166}
@ 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)
5113{
5114 WorldPacket data(SMSG_SPELL_FAILURE, (8 + 1 + 4 + 1));
5115 data << m_caster->GetPackGUID();
5116 data << uint8(m_cast_count);
5117 data << uint32(m_spellInfo->Id);
5118 data << uint8(result);
5119 m_caster->SendMessageToSet(&data, true);
5120
5121 data.Initialize(SMSG_SPELL_FAILED_OTHER, (8 + 1 + 4 + 1));
5122 data << m_caster->GetPackGUID();
5123 data << uint8(m_cast_count);
5124 data << uint32(m_spellInfo->Id);
5125 data << uint8(result);
5126 m_caster->SendMessageToSet(&data, true);
5127}
@ 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 ( )
5012{
5013 WorldPacket data(SMSG_SPELLLOGEXECUTE, (8 + 4 + 4 + 4 + 4 + 8));
5014
5015 data << m_caster->GetPackGUID();
5016
5017 data << uint32(m_spellInfo->Id);
5018
5019 uint8 effCount = 0;
5020 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
5021 {
5022 if (m_effectExecuteData[i])
5023 ++effCount;
5024 }
5025
5026 if (!effCount)
5027 return;
5028
5029 data << uint32(effCount);
5030 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
5031 {
5032 if (!m_effectExecuteData[i])
5033 continue;
5034
5035 data << uint32(m_spellInfo->Effects[i].Effect); // spell effect
5036
5037 data.append(*m_effectExecuteData[i]);
5038
5039 delete m_effectExecuteData[i];
5040 m_effectExecuteData[i] = nullptr;
5041 }
5042 m_caster->SendMessageToSet(&data, true);
5043}
@ 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:1579
@ GAMEOBJECT_TYPE_QUESTGIVER
Definition SharedDefines.h:1573
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:1366
void SendPreparedGossip(WorldObject *source)
Definition PlayerGossip.cpp:209
void PrepareGossipMenu(WorldObject *source, uint32 menuId=0, bool showQuests=false)
Definition PlayerGossip.cpp:32
struct GameObjectTemplate::@232::@236 questgiver
uint32 gossipID
Definition GameObjectData.h:72
uint32 linkedTrap
Definition GameObjectData.h:59
struct GameObjectTemplate::@232::@241 spellFocus
struct GameObjectTemplate::@232::@237 chest
uint32 linkedTrapId
Definition GameObjectData.h:90

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)
4637{
4638 if (result == SPELL_CAST_OK)
4639 return;
4640
4641 Unit* owner = m_caster->GetCharmerOrOwner();
4642 if (!owner)
4643 return;
4644
4645 Player* player = owner->ToPlayer();
4646 if (!player)
4647 return;
4648
4649 WorldPacket data(SMSG_PET_CAST_FAILED, 1 + 4 + 1);
4651
4652 player->SendDirectMessage(&data);
4653}
@ SMSG_PET_CAST_FAILED
Definition Opcodes.h:342

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

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

◆ SendResurrectRequest()

void Spell::SendResurrectRequest ( Player target)
5169{
5170 // get resurrector name for creature resurrections, otherwise packet will be not accepted
5171 // for player resurrections the name is looked up by guid
5172 std::string const sentName(m_caster->IsPlayer()
5173 ? ""
5174 : m_caster->GetNameForLocaleIdx(target->GetSession()->GetSessionDbLocaleIndex()));
5175
5176 WorldPacket data(SMSG_RESURRECT_REQUEST, (8 + 4 + sentName.size() + 1 + 1 + 1 + 4));
5177 data << m_caster->GetGUID();
5178 data << uint32(sentName.size() + 1);
5179
5180 data << sentName;
5181 data << uint8(0); // null terminator
5182
5183 data << uint8(m_caster->IsPlayer() ? 0 : 1); // "you'll be afflicted with resurrection sickness"
5184 // override delay sent with SMSG_CORPSE_RECLAIM_DELAY, set instant resurrection for spells with this attribute
5186 data << uint32(0);
5187 target->SendDirectMessage(&data);
5188}
@ SPELL_ATTR3_NO_RES_TIMER
Definition SharedDefines.h:508
@ SMSG_RESURRECT_REQUEST
Definition Opcodes.h:377

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

Referenced by EffectResurrect(), and EffectResurrectNew().

◆ SendSpellCooldown()

void Spell::SendSpellCooldown ( )
4284{
4285 // xinef: properly add creature cooldowns
4286 if (!m_caster->IsPlayer())
4287 {
4289 {
4290 // xinef: this should be added here
4291 //m_caster->AddSpellCooldown(m_spellInfo->Id, 0, 0);
4292
4293 // xinef: this adds cooldowns to vehicle spells which misses them client-side (when we overwrote dbc info in eg.)
4296 {
4297 WorldPacket data(SMSG_SPELL_COOLDOWN, 8 + 1 + 4 + 4);
4298 data << m_caster->GetGUID();
4300 data << uint32(m_spellInfo->Id);
4302 player->SendDirectMessage(&data);
4303 }
4304 }
4305 return;
4306 }
4307
4308 Player* _player = m_caster->ToPlayer();
4309
4310 // mana/health/etc potions, disabled by client (until combat out as declarate)
4312 {
4313 // need in some way provided data for Spell::finish SendCooldownEvent
4314 _player->SetLastPotionId(m_CastItem->GetEntry());
4315 return;
4316 }
4317
4318 // have infinity cooldown but set at aura apply
4319 // do not set cooldown for triggered spells (needed by reincarnation)
4324 return;
4325
4327}
@ SPELL_COOLDOWN_FLAG_INCLUDE_GCD
Starts GCD in addition to normal cooldown specified in the packet.
Definition Unit.h:615
void SetLastPotionId(uint32 item_id)
Definition Player.h:1808
void AddSpellAndCategoryCooldowns(SpellInfo const *spellInfo, uint32 itemId, Spell *spell=nullptr, bool infinityCooldown=false)
Definition Player.cpp:10929
uint32 RecoveryTime
Definition SpellInfo.h:348
bool RequireCooldownInfo() const
Definition SpellInfo.cpp:1182
@ SMSG_SPELL_COOLDOWN
Definition Opcodes.h:338

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 ( )
4736{
4737 // not send invisible spell casting
4738 if (!IsNeedSendToClient(true))
4739 return;
4740
4741 //LOG_DEBUG("spells.aura", "Sending SMSG_SPELL_GO id={}", m_spellInfo->Id);
4742
4743 uint32 castFlags = CAST_FLAG_UNKNOWN_9;
4744
4745 // triggered spells with spell visual != 0
4747 castFlags |= CAST_FLAG_PENDING;
4748
4750 castFlags |= CAST_FLAG_PROJECTILE; // arrows/bullets visual
4751
4752 // should only be sent to self, but the current messaging doesn't make that possible
4753 if (m_caster->IsPlayer() || m_caster->IsPet())
4754 {
4755 switch (m_spellInfo->PowerType)
4756 {
4757 case POWER_HEALTH:
4758 break;
4759 case POWER_RUNE:
4760 castFlags |= CAST_FLAG_POWER_LEFT_SELF;
4761 break;
4762 default:
4763 if (m_powerCost != 0)
4764 {
4765 castFlags |= CAST_FLAG_POWER_LEFT_SELF;
4766 }
4767 break;
4768 }
4769 }
4770
4771 if ((m_caster->IsPlayer())
4775 {
4776 castFlags |= CAST_FLAG_NO_GCD; // not needed, but Blizzard sends it
4777 castFlags |= CAST_FLAG_RUNE_LIST; // rune cooldowns list
4778 }
4779
4781 castFlags |= CAST_FLAG_RUNE_LIST; // rune cooldowns list
4782
4783 if (m_targets.HasTraj())
4784 castFlags |= CAST_FLAG_ADJUST_MISSILE;
4785
4787 castFlags |= CAST_FLAG_NO_GCD;
4788
4789 PackedGuid realCasterGUID = m_caster->GetPackGUID();
4790 if (TempSummon const* tempSummon = m_caster->ToTempSummon())
4791 {
4792 if (tempSummon->GetEntry() == WORLD_TRIGGER)
4793 {
4794 if (GameObject* casterGameobject = tempSummon->GetSummonerGameObject())
4795 {
4796 realCasterGUID = casterGameobject->GetPackGUID();
4797 }
4798 }
4799 }
4800
4801 WorldPacket data(SMSG_SPELL_GO, 150); // guess size
4802
4803 if (m_CastItem)
4804 data << m_CastItem->GetPackGUID();
4805 else
4806 data << realCasterGUID;
4807
4808 data << realCasterGUID;
4809 data << uint8(m_cast_count); // pending spell cast?
4810 data << uint32(m_spellInfo->Id); // spellId
4811 data << uint32(castFlags); // cast flags
4812 data << uint32(GameTime::GetGameTimeMS().count()); // timestamp
4813
4814 WriteSpellGoTargets(&data);
4815
4816 m_targets.Write(data);
4817
4818 if (castFlags & CAST_FLAG_POWER_LEFT_SELF)
4820
4821 if (castFlags & CAST_FLAG_RUNE_LIST) // rune cooldowns list
4822 {
4823 //TODO: There is a crash caused by a spell with CAST_FLAG_RUNE_LIST casted by a creature
4824 //The creature is the mover of a player, so HandleCastSpellOpcode uses it as the caster
4825 if (Player* player = m_caster->ToPlayer())
4826 {
4827 uint8 runeMaskInitial = m_runesState;
4828 uint8 runeMaskAfterCast = player->GetRunesState();
4829 data << uint8(runeMaskInitial); // runes state before
4830 data << uint8(runeMaskAfterCast); // runes state after
4831 for (uint8 i = 0; i < MAX_RUNES; ++i)
4832 {
4833 uint8 mask = (1 << i);
4834 if (mask & runeMaskInitial && !(mask & runeMaskAfterCast)) // usable before andon cooldown now...
4835 {
4836 // float casts ensure the division is performed on floats as we need float result
4837 float baseCd = float(player->GetRuneBaseCooldown(i, true));
4838 data << uint8((baseCd - float(player->GetRuneCooldown(i))) / baseCd * 255); // rune cooldown passed
4839 }
4840 }
4841 }
4842 }
4843 if (castFlags & CAST_FLAG_ADJUST_MISSILE)
4844 {
4845 data << m_targets.GetElevation();
4847 }
4848
4849 if (castFlags & CAST_FLAG_PROJECTILE)
4850 WriteAmmoToPacket(&data);
4851
4852 if (castFlags & CAST_FLAG_VISUAL_CHAIN)
4853 {
4854 data << uint32(0);
4855 data << uint32(0);
4856 }
4857
4859 {
4860 data << uint8(0);
4861 }
4862
4863 m_caster->SendMessageToSet(&data, true);
4864}
@ SPELL_EFFECT_ACTIVATE_RUNE
Definition SharedDefines.h:935
@ SPELL_ATTR0_USES_RANGED_SLOT
Definition SharedDefines.h:394
@ SPELL_ATTR0_CU_NEEDS_AMMO_DATA
Definition SpellInfo.h:195
@ CAST_FLAG_VISUAL_CHAIN
Definition Spell.h:66
@ CAST_FLAG_ADJUST_MISSILE
Definition Spell.h:64
@ CAST_FLAG_UNKNOWN_9
Definition Spell.h:55
@ CAST_FLAG_NO_GCD
Definition Spell.h:65
@ CAST_FLAG_PROJECTILE
Definition Spell.h:52
@ CAST_FLAG_POWER_LEFT_SELF
Definition Spell.h:58
@ CAST_FLAG_RUNE_LIST
Definition Spell.h:68
@ CAST_FLAG_PENDING
Definition Spell.h:47
Definition ObjectGuid.h:263
void Write(ByteBuffer &data)
Definition Spell.cpp:179
SpellCastTimesEntry const * CastTimeEntry
Definition SpellInfo.h:347
void WriteSpellGoTargets(WorldPacket *data)
Writes miss and hit targets for a SMSG_SPELL_GO packet.
Definition Spell.cpp:4951
void WriteAmmoToPacket(WorldPacket *data)
Definition Spell.cpp:4866
bool IsNeedSendToClient(bool go) const
Definition Spell.cpp:8045
@ SMSG_SPELL_GO
Definition Opcodes.h:336
int32 CastTime
Definition DBCStructure.h:1761

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 ( )
4656{
4657 if (!IsNeedSendToClient(false))
4658 return;
4659
4660 //LOG_DEBUG("spells.aura", "Sending SMSG_SPELL_START id={}", m_spellInfo->Id);
4661
4662 uint32 castFlags = CAST_FLAG_HAS_TRAJECTORY;
4663
4665 castFlags |= CAST_FLAG_PENDING;
4666
4668 castFlags |= CAST_FLAG_PROJECTILE;
4669
4670 if (m_caster->IsPlayer() || m_caster->IsPet())
4671 {
4672 switch (m_spellInfo->PowerType)
4673 {
4674 case POWER_HEALTH:
4675 break;
4676 case POWER_RUNE:
4677 castFlags |= CAST_FLAG_POWER_LEFT_SELF;
4678 break;
4679 default:
4680 if (m_powerCost != 0)
4681 {
4682 castFlags |= CAST_FLAG_POWER_LEFT_SELF;
4683 }
4684 break;
4685 }
4686 }
4687
4689 castFlags |= CAST_FLAG_NO_GCD; // not needed, but Blizzard sends it
4690
4691 PackedGuid realCasterGUID = m_caster->GetPackGUID();
4692 if (TempSummon const* tempSummon = m_caster->ToTempSummon())
4693 {
4694 if (tempSummon->GetEntry() == WORLD_TRIGGER)
4695 {
4696 if (GameObject* casterGameobject = tempSummon->GetSummonerGameObject())
4697 {
4698 realCasterGUID = casterGameobject->GetPackGUID();
4699 }
4700 }
4701 }
4702
4703 WorldPacket data(SMSG_SPELL_START, (8 + 8 + 4 + 4 + 2));
4704 if (m_CastItem)
4705 data << m_CastItem->GetPackGUID();
4706 else
4707 data << realCasterGUID;
4708
4709 data << realCasterGUID;
4710 data << uint8(m_cast_count); // pending spell cast?
4711 data << uint32(m_spellInfo->Id); // spellId
4712 data << uint32(castFlags); // cast flags
4713 data << int32(m_timer); // delay?
4714
4715 m_targets.Write(data);
4716
4717 if (castFlags & CAST_FLAG_POWER_LEFT_SELF)
4719
4720 if (castFlags & CAST_FLAG_PROJECTILE)
4721 WriteAmmoToPacket(&data);
4722
4723 if (castFlags & CAST_FLAG_UNKNOWN_23)
4724 {
4725 data << uint32(0);
4726 data << uint32(0);
4727 }
4728
4729 m_caster->SendMessageToSet(&data, true);
4730
4733}
@ CAST_FLAG_UNKNOWN_23
Definition Spell.h:69
@ CAST_FLAG_HAS_TRAJECTORY
Definition Spell.h:48
@ 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
560{ m_autoRepeat = rep; }

References m_autoRepeat.

◆ SetDelayStart()

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

References m_delayStart.

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

◆ SetExecutedCurrently()

void Spell::SetExecutedCurrently ( bool  yes)
inline
573{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 
)
8388{
8389 switch (mod)
8390 {
8392 m_spellValue->EffectBasePoints[0] = m_spellInfo->Effects[EFFECT_0].CalcBaseValue(value);
8393 break;
8395 m_spellValue->EffectBasePoints[1] = m_spellInfo->Effects[EFFECT_1].CalcBaseValue(value);
8396 break;
8398 m_spellValue->EffectBasePoints[2] = m_spellInfo->Effects[EFFECT_2].CalcBaseValue(value);
8399 break;
8401 m_spellValue->RadiusMod = (float)value / 10000;
8402 break;
8405 break;
8408 break;
8410 m_spellValue->AuraDuration = value;
8411 break;
8413 m_spellValue->ForcedCritResult = (bool)value;
8414 break;
8416 m_spellValue->MiscVal[0] = value;
8417 break;
8419 m_spellValue->MiscVal[1] = value;
8420 break;
8422 m_spellValue->MiscVal[2] = value;
8423 break;
8424 }
8425}
@ 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:228

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
494{ m_spellState = state; }

References m_spellState.

◆ SummonGuardian()

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

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 ( )
5318{
5320 {
5322
5323 // wands don't have ammo
5324 if (!pItem || pItem->IsBroken() || pItem->GetTemplate()->SubClass == ITEM_SUBCLASS_WEAPON_WAND)
5325 return;
5326
5327 if (pItem->GetTemplate()->InventoryType == INVTYPE_THROWN)
5328 {
5329 if (pItem->GetMaxStackCount() == 1)
5330 {
5331 // decrease durability for non-stackable throw weapon
5333 }
5334 else if (!sWorld->getBoolConfig(CONFIG_ENABLE_INFINITEAMMO))
5335 {
5336 // decrease items amount for stackable throw weapon
5337 uint32 count = 1;
5338 m_caster->ToPlayer()->DestroyItemCount(pItem, count, true);
5339 }
5340 }
5341 else if (!sWorld->getBoolConfig(CONFIG_ENABLE_INFINITEAMMO))
5343 m_caster->ToPlayer()->DestroyItemCount(ammo, 1, true);
5344 }
5345}
@ INVTYPE_THROWN
Definition ItemTemplate.h:281
@ EQUIPMENT_SLOT_RANGED
Definition Player.h:687
@ SPELL_ATTR6_DO_NOT_CONSUME_RESOURCES
Definition SharedDefines.h:620
@ CONFIG_ENABLE_INFINITEAMMO
Definition WorldConfig.h:145
uint32 GetMaxStackCount() const
Definition Item.h:274
void DurabilityPointLossForEquipSlot(EquipmentSlots slot)
Definition Player.cpp:4836

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

Referenced by handle_immediate(), spell_hun_explosive_shot::HandleFinish(), and HandleLaunchPhase().

◆ TakeCastItem()

void Spell::TakeCastItem ( )
5191{
5192 if (!m_CastItem || !m_caster->IsPlayer())
5193 return;
5194
5195 // not remove cast item at triggered spell (equipping, weapon damage, etc)
5197 return;
5198
5199 ItemTemplate const* proto = m_CastItem->GetTemplate();
5200
5201 if (!proto)
5202 {
5203 // This code is to avoid a crash
5204 // I'm not sure, if this is really an error, but I guess every item needs a prototype
5205 LOG_ERROR("spells", "Cast item has no item prototype {}", m_CastItem->GetGUID().ToString());
5206 return;
5207 }
5208
5209 bool expendable = false;
5210 bool withoutCharges = false;
5211
5212 for (int i = 0; i < MAX_ITEM_PROTO_SPELLS; ++i)
5213 {
5214 if (proto->Spells[i].SpellId)
5215 {
5216 // item has limited charges
5217 if (proto->Spells[i].SpellCharges)
5218 {
5219 if (proto->Spells[i].SpellCharges < 0)
5220 expendable = true;
5221
5222 int32 charges = m_CastItem->GetSpellCharges(i);
5223
5224 // item has charges left
5225 if (charges)
5226 {
5227 (charges > 0) ? --charges : ++charges; // std::abs(charges) less at 1 after use
5228 if (proto->Stackable == 1)
5229 m_CastItem->SetSpellCharges(i, charges);
5231 }
5232
5233 // all charges used
5234 withoutCharges = (charges == 0);
5235 }
5236 }
5237 }
5238
5239 if (expendable && withoutCharges)
5240 {
5241 uint32 count = 1;
5242 m_caster->ToPlayer()->DestroyItemCount(m_CastItem, count, true);
5243
5244 // prevent crash at access to deleted m_targets.GetItemTarget
5246 m_targets.SetItemTarget(nullptr);
5247
5248 m_CastItem = nullptr;
5250 }
5251}
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 ( )
5254{
5256 return;
5257
5258 //Don't take power if the spell is cast while .cheat power is enabled.
5259 if (m_caster->IsPlayer())
5261 return;
5262
5264 bool hit = true;
5265 if (m_caster->IsPlayer())
5266 {
5268 if (ObjectGuid targetGUID = m_targets.GetUnitTargetGUID())
5269 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
5270 if (ihit->targetGUID == targetGUID)
5271 {
5272 if (ihit->missCondition != SPELL_MISS_NONE && ihit->missCondition != SPELL_MISS_BLOCK && ihit->missCondition != SPELL_MISS_ABSORB && ihit->missCondition != SPELL_MISS_REFLECT)
5273 {
5274 hit = false;
5275 //lower spell cost on fail (by talent aura)
5276 if (Player* modOwner = m_caster->ToPlayer()->GetSpellModOwner())
5277 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_SPELL_COST_REFUND_ON_FAIL, m_powerCost, this);
5278 }
5279 break;
5280 }
5281 }
5282
5283 if (PowerType == POWER_RUNE)
5284 {
5285 TakeRunePower(hit);
5286 return;
5287 }
5288
5289 if (!m_powerCost)
5290 return;
5291
5292 // health as power used
5293 if (PowerType == POWER_HEALTH)
5294 {
5296 return;
5297 }
5298
5299 if (PowerType >= MAX_POWERS)
5300 {
5301 LOG_ERROR("spells", "Spell::TakePower: Unknown power type '{}'", PowerType);
5302 return;
5303 }
5304
5305 if (hit)
5307 else
5309
5310 // Set the five second timer
5311 if (PowerType == POWER_MANA && m_powerCost > 0)
5312 {
5314 }
5315}
@ SPELL_MISS_ABSORB
Definition SharedDefines.h:1540
@ SPELLMOD_SPELL_COST_REFUND_ON_FAIL
Definition SpellDefines.h:106
void TakeRunePower(bool didHit)
Definition Spell.cpp:5401
int32 ModifyHealth(int32 val)
Definition Unit.cpp:14179
void SetLastManaUse(uint32 spellCastTime)
Definition Unit.h:1114

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 ( )
5471{
5472 if (!m_caster->IsPlayer())
5473 return;
5474
5475 ItemTemplate const* castItemTemplate = m_CastItem ? m_CastItem->GetTemplate() : nullptr;
5476
5477 // do not take reagents for these item casts
5478 if (castItemTemplate && castItemTemplate->HasFlag(ITEM_FLAG_NO_REAGENT_COST))
5479 return;
5480
5481 Player* p_caster = m_caster->ToPlayer();
5482 if (p_caster->CanNoReagentCast(m_spellInfo))
5483 return;
5484
5485 for (uint32 x = 0; x < MAX_SPELL_REAGENTS; ++x)
5486 {
5487 if (m_spellInfo->Reagent[x] <= 0)
5488 continue;
5489
5490 uint32 itemid = m_spellInfo->Reagent[x];
5491 uint32 itemcount = m_spellInfo->ReagentCount[x];
5492
5493 // if CastItem is also spell reagent
5494 if (castItemTemplate && castItemTemplate->ItemId == itemid)
5495 {
5496 for (int s = 0; s < MAX_ITEM_PROTO_SPELLS; ++s)
5497 {
5498 // CastItem will be used up and does not count as reagent
5499 int32 charges = m_CastItem->GetSpellCharges(s);
5500 if (castItemTemplate->Spells[s].SpellCharges < 0 && std::abs(charges) < 2)
5501 {
5502 ++itemcount;
5503 break;
5504 }
5505 }
5506
5507 m_CastItem = nullptr;
5509 }
5510
5511 // if GetItemTarget is also spell reagent
5512 if (m_targets.GetItemTargetEntry() == itemid)
5513 m_targets.SetItemTarget(nullptr);
5514
5515 p_caster->DestroyItemCount(itemid, itemcount, true);
5516 }
5517}
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)
5402{
5404 return;
5405
5406 SpellRuneCostEntry const* runeCostData = sSpellRuneCostStore.LookupEntry(m_spellInfo->RuneCostID);
5407 if (!runeCostData || (runeCostData->NoRuneCost() && runeCostData->NoRunicPowerGain()))
5408 return;
5409
5410 Player* player = m_caster->ToPlayer();
5411 m_runesState = player->GetRunesState(); // store previous state
5412
5413 int32 runeCost[NUM_RUNE_TYPES]; // blood, frost, unholy, death
5414
5415 for (uint32 i = 0; i < RUNE_DEATH; ++i)
5416 {
5417 runeCost[i] = runeCostData->RuneCost[i];
5418 if (Player* modOwner = m_caster->GetSpellModOwner())
5419 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_COST, runeCost[i], this);
5420 }
5421
5422 runeCost[RUNE_DEATH] = 0; // calculated later
5423
5424 for (uint32 i = 0; i < MAX_RUNES; ++i)
5425 {
5426 RuneType rune = player->GetCurrentRune(i);
5427 if (!player->GetRuneCooldown(i) && runeCost[rune] > 0)
5428 {
5429 player->SetRuneCooldown(i, didHit ? player->GetRuneBaseCooldown(i, false) : uint32(RUNE_MISS_COOLDOWN));
5430 player->SetLastUsedRune(rune);
5431 runeCost[rune]--;
5432 }
5433 }
5434
5435 // Xinef: firstly consume death runes of base type
5436 // Xinef: in second loop consume all available
5437 for (uint8 loop = 0; loop < 2; ++loop)
5438 {
5439 runeCost[RUNE_DEATH] = runeCost[RUNE_BLOOD] + runeCost[RUNE_UNHOLY] + runeCost[RUNE_FROST];
5440 if (runeCost[RUNE_DEATH] > 0)
5441 {
5442 for (uint8 i = 0; i < MAX_RUNES; ++i)
5443 {
5444 RuneType rune = player->GetCurrentRune(i);
5445 if (!player->GetRuneCooldown(i) && rune == RUNE_DEATH && (loop ? true : (runeCost[player->GetBaseRune(i)] > 0)))
5446 {
5447 player->SetRuneCooldown(i, didHit ? player->GetRuneBaseCooldown(i, false) : uint32(RUNE_MISS_COOLDOWN));
5448 player->SetLastUsedRune(rune);
5449 runeCost[rune]--;
5450 if (!loop)
5451 runeCost[player->GetBaseRune(i)]--;
5452
5453 // keep Death Rune type if missed
5454 if (didHit)
5455 player->RestoreBaseRune(i);
5456
5457 if (runeCost[RUNE_DEATH] == 0)
5458 break;
5459 }
5460 }
5461 }
5462 }
5463
5464 // you can gain some runic power when use runes
5465 if (didHit)
5466 if (int32 rp = int32(runeCostData->runePowerGain * sWorld->getRate(RATE_POWER_RUNICPOWER_INCOME)))
5467 player->ModifyPower(POWER_RUNIC_POWER, int32(rp));
5468}
@ RUNE_UNHOLY
Definition Player.h:406
@ RUNE_BLOOD
Definition Player.h:405
@ RUNE_MISS_COOLDOWN
Definition Player.h:400
@ RATE_POWER_RUNICPOWER_INCOME
Definition WorldConfig.h:392
void SetLastUsedRune(RuneType type)
Definition Player.h:2517
uint32 GetRuneBaseCooldown(uint8 index, bool skipGrace)
Definition Player.cpp:13416
void RestoreBaseRune(uint8 index)
Definition Player.cpp:13445
bool NoRunicPowerGain() const
Definition DBCStructure.h:1812
uint32 runePowerGain
Definition DBCStructure.h:1809

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
8805{
8807 if (!gcd)
8808 {
8809 // Xinef: fix for charmed pet spells with no cooldown info
8811 gcd = MIN_GCD;
8812 else
8813 return;
8814 }
8815
8816 if (m_caster->IsPlayer())
8818 return;
8819
8820 // Global cooldown can't leave range 1..1.5 secs
8821 // There are some spells (mostly not casted directly by player) that have < 1 sec and > 1.5 sec global cooldowns
8822 // but as tests show are not affected by any spell mods.
8824 {
8825 // gcd modifier auras are applied only to own spells and only players have such mods
8826 if (m_caster->IsPlayer())
8828
8829 // Apply haste rating
8832 {
8833 gcd = int32(float(gcd) * m_caster->GetFloatValue(UNIT_MOD_CAST_SPEED));
8834 }
8835
8836 if (gcd < MIN_GCD)
8837 gcd = MIN_GCD;
8838 else if (gcd > MAX_GCD)
8839 gcd = MAX_GCD;
8840 }
8841
8842 // Only players or controlled units have global cooldown
8843 if (m_caster->GetCharmInfo())
8845 else if (m_caster->IsPlayer())
8847}
@ SPELLMOD_GLOBAL_COOLDOWN
Definition SpellDefines.h:97
@ MIN_GCD
Definition Spell.cpp:8789
@ MAX_GCD
Definition Spell.cpp:8790
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)
4330{
4331 // update pointers based at it's GUIDs
4332 if (!UpdatePointers())
4333 {
4334 // cancel the spell if UpdatePointers() returned false, something wrong happened there
4335 cancel();
4336 return;
4337 }
4338
4340 {
4341 LOG_DEBUG("spells.aura", "Spell {} is cancelled due to removal of target.", m_spellInfo->Id);
4342 cancel();
4343 return;
4344 }
4345
4346 // check if the player caster has moved before the spell finished
4347 // xinef: added preparing state (real cast, skip channels as they have other flags for this)
4348 if ((m_caster->IsPlayer() && m_timer != 0) &&
4351 {
4352 // don't cancel for melee, autorepeat, triggered and instant spells
4354 cancel(true);
4355 }
4356
4357 switch (m_spellState)
4358 {
4360 {
4361 if (m_timer > 0)
4362 {
4363 if (difftime >= (uint32)m_timer)
4364 m_timer = 0;
4365 else
4366 m_timer -= difftime;
4367 }
4368
4369 if (m_timer == 0 && !IsNextMeleeSwingSpell() && !IsAutoRepeat())
4370 // don't CheckCast for instant spells - done in spell::prepare, skip duplicate checks, needed for range checks for example
4371 cast(!m_casttime);
4372 break;
4373 }
4375 {
4376 if (m_timer)
4377 {
4378 if (m_timer > 0)
4379 {
4380 if (difftime >= (uint32)m_timer)
4381 m_timer = 0;
4382 else
4383 m_timer -= difftime;
4384 }
4385 }
4386
4387 if (m_timer == 0)
4388 {
4390
4391 finish();
4392
4393 // We call the hook here instead of in Spell::finish because we only want to call it for completed channeling. Everything else is handled by interrupts
4394 if (Creature* creatureCaster = m_caster->ToCreature())
4395 if (creatureCaster->IsAIEnabled)
4396 creatureCaster->AI()->OnSpellCastFinished(m_spellInfo, SPELL_FINISHED_CHANNELING_COMPLETE);
4397 }
4398 // Xinef: Dont update channeled target list on last tick, allow auras to update duration properly
4399 // Xinef: Added this strange check because of diffrent update routines for players / creatures
4400 // Xinef: If creature gets new aura in 800ms and in 840ms its updated with diff 270, not 40 is removed from duration but 270
4401 // Xinef: so the aura can be removed in different updates for all units
4402 else if ((m_timer < 0 || m_timer > 300) && !UpdateChanneledTargetList())
4403 {
4404 LOG_DEBUG("spells.aura", "Channeled spell {} is removed due to lack of targets", m_spellInfo->Id);
4406 finish();
4407 }
4408 break;
4409 }
4410 default:
4411 break;
4412 }
4413}
@ SPELL_FINISHED_CHANNELING_COMPLETE
Definition Spell.h:100
bool UpdateChanneledTargetList()
Definition Spell.cpp:3303

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_FINISHED_CHANNELING_COMPLETE, SPELL_INTERRUPT_FLAG_MOVEMENT, SPELL_STATE_CASTING, SPELL_STATE_PREPARING, Object::ToCreature(), UpdateChanneledTargetList(), and UpdatePointers().

Referenced by SpellEvent::Execute().

◆ UpdateChanneledTargetList()

bool Spell::UpdateChanneledTargetList ( )
protected
3304{
3305 // Not need check return true
3307 return true;
3308
3309 uint8 channelTargetEffectMask = m_channelTargetEffectMask;
3310 uint8 channelAuraMask = 0;
3311 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
3313 channelAuraMask |= 1 << i;
3314
3315 channelAuraMask &= channelTargetEffectMask;
3316
3317 float range = 0;
3318 if (channelAuraMask)
3319 {
3321 if (range == 0)
3322 for(int i = EFFECT_0; i <= EFFECT_2; ++i)
3323 if (channelAuraMask & (1 << i) && m_spellInfo->Effects[i].RadiusEntry)
3324 {
3325 range = m_spellInfo->Effects[i].CalcRadius(nullptr, nullptr);
3326 break;
3327 }
3328
3329 if (Player* modOwner = m_caster->GetSpellModOwner())
3330 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_RANGE, range, this);
3331
3332 // xinef: add little tolerance level
3333 range += std::min(3.0f, range * 0.1f); // 10% but no more than 3yd
3334 }
3335
3336 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
3337 {
3338 if (ihit->missCondition == SPELL_MISS_NONE && (channelTargetEffectMask & ihit->effectMask))
3339 {
3340 Unit* unit = m_caster->GetGUID() == ihit->targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID);
3341
3342 if (!unit)
3343 continue;
3344
3345 if (IsValidDeadOrAliveTarget(unit))
3346 {
3347 if (channelAuraMask & ihit->effectMask)
3348 {
3350 {
3351 if (m_caster != unit)
3352 {
3353 if (!m_caster->IsWithinDistInMap(unit, range))
3354 {
3355 ihit->effectMask &= ~aurApp->GetEffectMask();
3356 unit->RemoveAura(aurApp);
3357 continue;
3358 }
3359 // Xinef: Update Orientation server side (non players wont sent appropriate packets)
3362 }
3363 }
3364 else // aura is dispelled
3365 continue;
3366 }
3367
3368 channelTargetEffectMask &= ~ihit->effectMask; // remove from need alive mask effect that have alive target
3369 }
3370 }
3371 }
3372
3373 // Xinef: not all effects are covered, remove applications from all targets
3374 if (channelTargetEffectMask != 0)
3375 {
3376 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
3377 if (ihit->missCondition == SPELL_MISS_NONE && (channelAuraMask & ihit->effectMask))
3378 if (Unit* unit = m_caster->GetGUID() == ihit->targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID))
3379 if (IsValidDeadOrAliveTarget(unit))
3381 {
3382 ihit->effectMask &= ~aurApp->GetEffectMask();
3383 unit->RemoveAura(aurApp);
3384 }
3385 }
3386
3387 // is all effects from m_needAliveTargetMask have alive targets
3388 return channelTargetEffectMask == 0;
3389}
@ SPELL_ATTR1_TRACK_TARGET_IN_CHANNEL
Definition SharedDefines.h:444
bool IsValidDeadOrAliveTarget(Unit const *target) const
Definition Spell.cpp:8177
AuraApplication * GetAuraApplication(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemCasterGUID=ObjectGuid::Empty, uint8 reqEffMask=0, AuraApplication *except=nullptr) const
Definition Unit.cpp:5630
void UpdateOrientation(float orientation)
Only server-side orientation update, does not broadcast to client.
Definition Unit.cpp:19822
bool IsWithinDistInMap(WorldObject const *obj, float dist2compare, bool is3D=true, bool incOwnRadius=true, bool incTargetRadius=true) const
Definition Object.cpp:1354

References EFFECT_0, EFFECT_2, SpellInfo::Effects, Position::GetAngle(), Unit::GetAuraApplication(), Object::GetGUID(), SpellInfo::GetMaxRange(), Unit::GetSpellModOwner(), ObjectAccessor::GetUnit(), SpellInfo::HasAttribute(), SpellInfo::Id, Object::IsPlayer(), 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 ( )
7816{
7819 else
7820 {
7823 m_originalCaster = nullptr;
7824 }
7825
7827 {
7829 // cast item not found, somehow the item is no longer where we expected
7830 if (!m_CastItem)
7831 return false;
7832 }
7833 else
7834 m_CastItem = nullptr;
7835
7837
7838 // further actions done only for dest targets
7839 if (!m_targets.HasDst())
7840 return true;
7841
7842 // cache last transport
7843 WorldObject* transport = nullptr;
7844
7845 // update effect destinations (in case of moved transport dest target)
7846 for (uint8 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
7847 {
7848 SpellDestination& dest = m_destTargets[effIndex];
7849 if (!dest._transportGUID)
7850 continue;
7851
7852 if (!transport || transport->GetGUID() != dest._transportGUID)
7854
7855 if (transport)
7856 {
7857 dest._position.Relocate(transport);
7859 }
7860 }
7861
7862 return true;
7863}
void Update(Unit *caster)
Definition Spell.cpp:479
WorldObject * GetWorldObject(WorldObject const &, ObjectGuid const &guid)
Definition ObjectAccessor.cpp:115
void RelocateOffset(const Position &offset)
Definition Position.cpp:66
Position _transportOffset
Definition Spell.h:115
ObjectGuid _transportGUID
Definition Spell.h:114

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)
4867{
4868 uint32 ammoInventoryType = 0;
4869 uint32 ammoDisplayID = 0;
4870
4871 if (m_caster->IsPlayer())
4872 {
4874 if (pItem)
4875 {
4876 ammoInventoryType = pItem->GetTemplate()->InventoryType;
4877 if (ammoInventoryType == INVTYPE_THROWN)
4878 ammoDisplayID = pItem->GetTemplate()->DisplayInfoID;
4879 else
4880 {
4882 if (ammoID)
4883 {
4884 ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(ammoID);
4885 if (pProto)
4886 {
4887 ammoDisplayID = pProto->DisplayInfoID;
4888 ammoInventoryType = pProto->InventoryType;
4889 }
4890 }
4891 else if (m_caster->HasAura(46699)) // Requires No Ammo
4892 {
4893 ammoDisplayID = 5996; // normal arrow
4894 ammoInventoryType = INVTYPE_AMMO;
4895 }
4896 }
4897 }
4898 }
4899 else
4900 {
4901 uint32 nonRangedAmmoDisplayID = 0;
4902 uint32 nonRangedAmmoInventoryType = 0;
4903 for (uint8 i = 0; i < 3; ++i)
4904 {
4906 {
4907 if (ItemEntry const* itemEntry = sItemStore.LookupEntry(item_id))
4908 {
4909 if (itemEntry->ClassID == ITEM_CLASS_WEAPON)
4910 {
4911 switch (itemEntry->SubclassID)
4912 {
4914 ammoDisplayID = itemEntry->DisplayInfoID;
4915 ammoInventoryType = itemEntry->InventoryType;
4916 break;
4919 ammoDisplayID = 5996; // is this need fixing?
4920 ammoInventoryType = INVTYPE_AMMO;
4921 break;
4923 ammoDisplayID = 5998; // is this need fixing?
4924 ammoInventoryType = INVTYPE_AMMO;
4925 break;
4926 default:
4927 nonRangedAmmoDisplayID = itemEntry->DisplayInfoID;
4928 nonRangedAmmoInventoryType = itemEntry->InventoryType;
4929 break;
4930 }
4931
4932 if (ammoDisplayID)
4933 break;
4934 }
4935 }
4936 }
4937 }
4938
4939 if (!ammoDisplayID && !ammoInventoryType)
4940 {
4941 ammoDisplayID = nonRangedAmmoDisplayID;
4942 ammoInventoryType = nonRangedAmmoInventoryType;
4943 }
4944 }
4945
4946 *data << uint32(ammoDisplayID);
4947 *data << uint32(ammoInventoryType);
4948}
DBCStorage< ItemEntry > sItemStore(Itemfmt)
@ INVTYPE_AMMO
Definition ItemTemplate.h:280
@ UNIT_VIRTUAL_ITEM_SLOT_ID
Definition UpdateFields.h:116
Definition DBCStructure.h:1141
uint32 DisplayInfoID
Definition ItemTemplate.h:625

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
4503{
4504 data << uint8(castCount); // single cast or multi 2.3 (0/1)
4505 data << uint32(spellInfo->Id);
4506 data << uint8(result); // problem
4507 switch (result)
4508 {
4510 data << uint32(spellInfo->RequiresSpellFocus); // SpellFocusObject.dbc id
4511 break;
4512 case SPELL_FAILED_REQUIRES_AREA: // AreaTable.dbc id
4513 // hardcode areas limitation case
4514 switch (spellInfo->Id)
4515 {
4516 case 41617: // Cenarion Mana Salve
4517 case 41619: // Cenarion Healing Salve
4518 data << uint32(3905);
4519 break;
4520 case 41618: // Bottled Nethergon Energy
4521 case 41620: // Bottled Nethergon Vapor
4522 data << uint32(3842);
4523 break;
4524 case 45373: // Bloodberry Elixir
4525 data << uint32(4075);
4526 break;
4527 default: // default case (don't must be)
4528 data << uint32(0);
4529 break;
4530 }
4531 break;
4533 if (spellInfo->Totem[0])
4534 data << uint32(spellInfo->Totem[0]);
4535 if (spellInfo->Totem[1])
4536 data << uint32(spellInfo->Totem[1]);
4537 break;
4539 if (spellInfo->TotemCategory[0])
4540 data << uint32(spellInfo->TotemCategory[0]);
4541 if (spellInfo->TotemCategory[1])
4542 data << uint32(spellInfo->TotemCategory[1]);
4543 break;
4547 data << uint32(spellInfo->EquippedItemClass);
4548 data << uint32(spellInfo->EquippedItemSubClassMask);
4549 break;
4551 {
4552 uint32 item = 0;
4553 for (int8 eff = 0; eff < MAX_SPELL_EFFECTS; eff++)
4554 if (spellInfo->Effects[eff].ItemType)
4555 item = spellInfo->Effects[eff].ItemType;
4556 ItemTemplate const* proto = sObjectMgr->GetItemTemplate(item);
4557 if (proto && proto->ItemLimitCategory)
4558 data << uint32(proto->ItemLimitCategory);
4559 break;
4560 }
4562 data << uint32(customError);
4563 break;
4565 {
4566 uint32 missingItem = 0;
4567 for (uint32 i = 0; i < MAX_SPELL_REAGENTS; i++)
4568 {
4569 if (spellInfo->Reagent[i] <= 0)
4570 continue;
4571
4572 uint32 itemid = spellInfo->Reagent[i];
4573 uint32 itemcount = spellInfo->ReagentCount[i];
4574
4575 if (!caster->HasItemCount(itemid, itemcount))
4576 {
4577 missingItem = itemid;
4578 break;
4579 }
4580 }
4581
4582 data << uint32(missingItem); // first missing item
4583 break;
4584 }
4586 data << uint32(spellInfo->Mechanic);
4587 break;
4589 data << uint32(spellInfo->EquippedItemSubClassMask);
4590 break;
4592 data << uint32(0); // Item entry
4593 data << uint32(0); // Count
4594 break;
4596 data << uint32(0); // SkillLine.dbc Id
4597 data << uint32(0); // Amount
4598 break;
4600 data << uint32(0); // Skill level
4601 break;
4602 default:
4603 break;
4604 }
4605}
@ SPELL_FAILED_NEED_EXOTIC_AMMO
Definition SharedDefines.h:1014
@ SPELL_FAILED_FISHING_TOO_LOW
Definition SharedDefines.h:1141
@ SPELL_FAILED_MIN_SKILL
Definition SharedDefines.h:1110
@ SPELL_FAILED_PREVENTED_BY_MECHANIC
Definition SharedDefines.h:1107
@ SPELL_FAILED_REQUIRES_AREA
Definition SharedDefines.h:1061

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.

4952{
4953 // This function also fill data for channeled spells:
4954 // m_needAliveTargetMask req for stop channelig if one target die
4955 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
4956 {
4957 if ((*ihit).effectMask == 0) // No effect apply - all immuned add state
4958 // possibly SPELL_MISS_IMMUNE2 for this??
4959 ihit->missCondition = SPELL_MISS_IMMUNE2;
4960 }
4961
4962 // Hit and miss target counts are both uint8, that limits us to 255 targets for each
4963 // sending more than 255 targets crashes the client (since count sent would be wrong)
4964 // Spells like 40647 (with a huge radius) can easily reach this limit (spell might need
4965 // target conditions but we still need to limit the number of targets sent and keeping
4966 // correct count for both hit and miss).
4967
4968 uint32 hit = 0;
4969 std::size_t hitPos = data->wpos();
4970 *data << (uint8)0; // placeholder
4971 for (std::list<TargetInfo>::const_iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end() && hit < 255; ++ihit)
4972 {
4973 if ((*ihit).missCondition == SPELL_MISS_NONE) // Add only hits
4974 {
4975 *data << ihit->targetGUID;
4976 // Xinef: No channeled spell checked, no anything
4977 //m_channelTargetEffectMask |=ihit->effectMask;
4978 ++hit;
4979 }
4980 }
4981
4982 for (std::list<GOTargetInfo>::const_iterator ighit = m_UniqueGOTargetInfo.begin(); ighit != m_UniqueGOTargetInfo.end() && hit < 255; ++ighit)
4983 {
4984 *data << ighit->targetGUID; // Always hits
4985 ++hit;
4986 }
4987
4988 uint32 miss = 0;
4989 std::size_t missPos = data->wpos();
4990 *data << (uint8)0; // placeholder
4991 for (std::list<TargetInfo>::const_iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end() && miss < 255; ++ihit)
4992 {
4993 if (ihit->missCondition != SPELL_MISS_NONE) // Add only miss
4994 {
4995 *data << ihit->targetGUID;
4996 *data << uint8(ihit->missCondition);
4997 if (ihit->missCondition == SPELL_MISS_REFLECT)
4998 *data << uint8(ihit->reflectResult);
4999 ++miss;
5000 }
5001 }
5002 // Reset m_needAliveTargetMask for non channeled spell
5003 // Xinef: Why do we reset something that is not set??????
5004 //if (!m_spellInfo->IsChanneled())
5005 // m_channelTargetEffectMask = 0;
5006
5007 data->put<uint8>(hitPos, (uint8)hit);
5008 data->put<uint8>(missPos, (uint8)miss);
5009}
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 Symbol 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(), DoAllEffectOnTarget(), DoCreateItem(), 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(), 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(), TakeAmmo(), 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(), EffectSkinPlayerCorpse(), 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(), and Spell().


The documentation for this class was generated from the following files: