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 ()
 
bool IsNextMeleeSwingSpell () const
 
bool IsTriggered () 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 
)
561 :
562 m_spellInfo(sSpellMgr->GetSpellForDifficultyFromSpell(info, caster)),
563 m_caster((info->HasAttribute(SPELL_ATTR6_ORIGINATE_FROM_CONTROLLER) && caster->GetCharmerOrOwner()) ? caster->GetCharmerOrOwner() : caster)
565{
567 m_skipCheck = skipCheck;
568 m_selfContainer = nullptr;
570 m_executedCurrently = false;
573 m_comboTarget = nullptr;
574 m_delayStart = 0;
576
578 m_auraScaleMask = 0;
579 memset(m_damageMultipliers, 0, sizeof(m_damageMultipliers));
580
581 // Get data for type of attack
582 switch (m_spellInfo->DmgClass)
583 {
587 else
589 break;
592 break;
593 default:
594 // Wands
597 else
599 break;
600 }
601
602 m_spellSchoolMask = info->GetSchoolMask(); // Can be override for some spell (wand shoot for example)
603
605 // wand case
608 m_spellSchoolMask = SpellSchoolMask(1 << pItem->GetTemplate()->Damage[0].DamageType);
609
610 if (originalCasterGUID)
611 m_originalCasterGUID = originalCasterGUID;
612 else
614
617 else
618 {
621 m_originalCaster = nullptr;
622 }
623
625 _triggeredCastFlags = triggerFlags;
626 if (info->HasAttribute(SPELL_ATTR4_ALLOW_CAST_WHILE_CASTING))
628
629 m_CastItem = nullptr;
630
631 unitTarget = nullptr;
632 itemTarget = nullptr;
633 gameObjTarget = nullptr;
634 destTarget = nullptr;
635 damage = 0;
639 m_damage = 0;
640 m_healing = 0;
641 m_procAttacker = 0;
642 m_procVictim = 0;
643 m_procEx = 0;
644 focusObject = nullptr;
645 m_cast_count = 0;
646 m_glyphIndex = 0;
647 m_preCastSpell = 0;
648 m_spellAura = nullptr;
649 _scriptsLoaded = false;
650
651 //Auto Shot & Shoot (wand)
653
654 m_runesState = 0;
655 m_powerCost = 0; // setup to correct value in Spell::prepare, must not be used before.
656 m_casttime = 0; // setup to correct value in Spell::prepare, must not be used before.
657 m_timer = 0; // will set to castime in prepare
658 m_channeledDuration = 0; // will be setup in Spell::handle_immediate
659 m_immediateHandled = false;
660
662
664
665 // Determine if spell can be reflected back to the caster
666 // Patch 1.2 notes: Spell Reflection no longer reflects abilities
670
672 memset(m_effectExecuteData, 0, MAX_SPELL_EFFECTS * sizeof(ByteBuffer*));
673
674 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
676
677 // xinef:
678 _spellTargetsSelected = false;
679
680 m_weaponItem = nullptr;
681}
std::uint8_t uint8
Definition: Define.h:110
std::uint32_t uint32
Definition: Define.h:108
@ TYPEID_PLAYER
Definition: ObjectGuid.h:38
@ OFF_ATTACK
Definition: Unit.h:397
@ BASE_ATTACK
Definition: Unit.h:396
@ RANGED_ATTACK
Definition: Unit.h:398
@ DIMINISHING_LEVEL_1
Definition: Unit.h:694
@ SPELL_EFFECT_HANDLE_LAUNCH
Definition: Spell.h:233
@ SPELL_FLAG_NORMAL
Definition: Spell.h:81
@ SPELL_STATE_NULL
Definition: Spell.h:223
TriggerCastFlags
Definition: SpellDefines.h:130
@ TRIGGERED_CAST_DIRECTLY
Will ignore combo point requirement.
Definition: SpellDefines.h:139
@ TRIGGERED_IGNORE_CAST_IN_PROGRESS
Will ignore aura scaling.
Definition: SpellDefines.h:137
#define sSpellMgr
Definition: SpellMgr.h:818
#define MAX_SPELL_EFFECTS
Definition: DBCStructure.h:1610
@ DIMINISHING_NONE
Definition: SharedDefines.h:3230
@ SPELL_EFFECT_DISPEL
Definition: SharedDefines.h:788
#define CLASSMASK_WAND_USERS
Definition: SharedDefines.h:146
@ SPELL_ATTR2_AUTO_REPEAT
Definition: SharedDefines.h:433
@ SPELL_ATTR1_NO_REFLECTION
Definition: SharedDefines.h:398
@ SPELL_ATTR3_REQUIRES_OFF_HAND_WEAPON
Definition: SharedDefines.h:489
@ SPELL_DAMAGE_CLASS_RANGED
Definition: SharedDefines.h:1520
@ SPELL_DAMAGE_CLASS_MAGIC
Definition: SharedDefines.h:1518
@ SPELL_DAMAGE_CLASS_MELEE
Definition: SharedDefines.h:1519
@ SPELL_CUSTOM_ERROR_NONE
Definition: SharedDefines.h:1115
@ SPELL_ATTR0_IS_ABILITY
Definition: SharedDefines.h:358
@ SPELL_ATTR0_NO_IMMUNITIES
Definition: SharedDefines.h:383
@ SPELL_ATTR4_ALLOW_CAST_WHILE_CASTING
Definition: SharedDefines.h:509
@ SPELL_ATTR6_ORIGINATE_FROM_CONTROLLER
Definition: SharedDefines.h:594
SpellSchoolMask
Definition: SharedDefines.h:267
Unit * GetUnit(WorldObject const &, ObjectGuid const guid)
Definition: ObjectAccessor.cpp:204
Definition: Item.h:214
Player * ToPlayer()
Definition: Object.h:195
bool IsInWorld() const
Definition: Object.h:101
TypeID GetTypeId() const
Definition: Object.h:121
static ObjectGuid GetGUID(Object const *o)
Definition: Object.h:106
Item * GetWeaponForAttack(WeaponAttackType attackType, bool useable=false) const
Definition: PlayerStorage.cpp:519
Unit * GetCharmerOrOwner() const
Definition: Unit.h:1847
uint32 getClassMask() const
Definition: Unit.h:1427
Definition: Spell.h:94
Definition: Spell.h:211
Unit * m_comboTarget
Definition: Spell.h:542
int8 m_comboPointGain
Definition: Spell.h:543
GameObject * gameObjTarget
Definition: Spell.h:652
bool m_referencedFromCurrentSpell
Definition: Spell.h:643
bool m_canReflect
Definition: Spell.h:619
uint32 m_procVictim
Definition: Spell.h:674
Unit * m_originalCaster
Definition: Spell.h:607
bool m_needComboPoints
Definition: Spell.h:645
uint64 m_delayStart
Definition: Spell.h:637
bool _scriptsLoaded
Definition: Spell.h:725
TriggerCastFlags _triggeredCastFlags
Definition: Spell.h:766
int32 damage
Definition: Spell.h:654
SpellEffectHandleMode effectHandleMode
Definition: Spell.h:655
int32 m_channeledDuration
Definition: Spell.h:618
Aura * m_spellAura
Definition: Spell.h:657
SpellDestination m_destTargets[MAX_SPELL_EFFECTS]
Definition: Spell.h:700
Unit *const m_caster
Definition: Spell.h:601
uint8 m_delayAtDamageCount
Definition: Spell.h:626
WeaponAttackType m_attackType
Definition: Spell.h:615
bool m_immediateHandled
Definition: Spell.h:640
uint32 m_spellState
Definition: Spell.h:762
ObjectGuid m_originalCasterGUID
Definition: Spell.h:605
void CleanupTargetList()
Definition: Spell.cpp:2356
int32 m_timer
Definition: Spell.h:763
int32 m_casttime
Definition: Spell.h:617
Item * itemTarget
Definition: Spell.h:651
uint8 m_cast_count
Definition: Spell.h:524
int32 m_damage
Definition: Spell.h:667
bool m_executedCurrently
Definition: Spell.h:644
DiminishingLevels m_diminishLevel
Definition: Spell.h:660
float m_damageMultipliers[3]
Definition: Spell.h:647
ByteBuffer * m_effectExecuteData[MAX_SPELL_EFFECTS]
Definition: Spell.h:780
uint8 m_auraScaleMask
Definition: Spell.h:774
SpellCustomErrors m_customError
Definition: Spell.h:528
uint8 m_spellFlags
Definition: Spell.h:621
bool m_skipCheck
Definition: Spell.h:773
int32 m_healing
Definition: Spell.h:668
uint32 m_glyphIndex
Definition: Spell.h:525
uint8 m_channelTargetEffectMask
Definition: Spell.h:682
Item * m_weaponItem
Definition: Spell.h:522
Unit * unitTarget
Definition: Spell.h:650
SpellSchoolMask m_spellSchoolMask
Definition: Spell.h:614
SpellEvent * _spellEvent
Definition: Spell.h:765
bool _spellTargetsSelected
Definition: Spell.h:778
uint32 m_preCastSpell
Definition: Spell.h:526
WorldLocation * destTarget
Definition: Spell.h:653
Spell ** m_selfContainer
Definition: Spell.h:609
uint8 m_applyMultiplierMask
Definition: Spell.h:646
DiminishingGroup m_diminishGroup
Definition: Spell.h:661
uint32 m_procEx
Definition: Spell.h:675
Item * m_CastItem
Definition: Spell.h:521
SpellValue *const m_spellValue
Definition: Spell.h:603
int32 m_powerCost
Definition: Spell.h:616
uint32 m_procAttacker
Definition: Spell.h:673
GameObject * focusObject
Definition: Spell.h:664
SpellInfo const *const m_spellInfo
Definition: Spell.h:520
uint8 m_runesState
Definition: Spell.h:624
bool m_autoRepeat
Definition: Spell.h:623
bool IsPassive() const
Definition: SpellInfo.cpp:1082
bool NeedsComboPoints() const
Definition: SpellInfo.cpp:1250
bool HasAttribute(SpellAttr0 attribute) const
Definition: SpellInfo.h:412
bool HasEffect(SpellEffects effect) const
Definition: SpellInfo.cpp:869
bool IsPositive() const
Definition: SpellInfo.cpp:1221
bool IsAutoRepeatRangedSpell() const
Definition: SpellInfo.cpp:1267
uint32 DmgClass
Definition: SpellInfo.h:387
bool IsRangedWeaponSpell() const
Definition: SpellInfo.cpp:1260
Definition: ByteBuffer.h:70

References _scriptsLoaded, _spellTargetsSelected, _triggeredCastFlags, BASE_ATTACK, CLASSMASK_WAND_USERS, CleanupTargetList(), damage, destTarget, DIMINISHING_LEVEL_1, DIMINISHING_NONE, SpellInfo::DmgClass, effectHandleMode, focusObject, gameObjTarget, Unit::getClassMask(), Object::GetGUID(), SpellInfo::GetSchoolMask(), Object::GetTypeId(), ObjectAccessor::GetUnit(), Player::GetWeaponForAttack(), SpellInfo::HasAttribute(), SpellInfo::HasEffect(), SpellInfo::IsAutoRepeatRangedSpell(), Object::IsInWorld(), SpellInfo::IsPassive(), 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, TYPEID_PLAYER, and unitTarget.

◆ ~Spell()

Spell::~Spell ( )
684{
685 // unload scripts
686 while (!m_loadedScripts.empty())
687 {
688 std::list<SpellScript*>::iterator itr = m_loadedScripts.begin();
689 (*itr)->_Unload();
690 delete (*itr);
691 m_loadedScripts.erase(itr);
692 }
693
695 {
696 // Clean the reference to avoid later crash.
697 // If this error is repeating, we may have to add an ASSERT to better track down how we get into this case.
698 LOG_ERROR("spells", "Spell::~Spell: deleting spell for spell ID {}. However, spell still referenced.", m_spellInfo->Id);
699 *m_selfContainer = nullptr;
700 }
701
702 delete m_spellValue;
703
705}
#define LOG_ERROR(filterType__,...)
Definition: Log.h:159
void CheckEffectExecuteData()
Definition: Spell.cpp:8450
std::list< SpellScript * > m_loadedScripts
Definition: Spell.h:740
uint32 Id
Definition: SpellInfo.h:318

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

3783{
3784 // update pointers base at GUIDs to prevent access to non-existed already object
3785 if (!UpdatePointers())
3786 {
3787 // cancel the spell if UpdatePointers() returned false, something wrong happened there
3788 cancel();
3789 return;
3790 }
3791
3792 // cancel at lost explicit target during cast
3794 {
3795 cancel();
3796 return;
3797 }
3798
3799 // Xinef: implement attribute SPELL_ATTR1_DISMISS_PET_FIRST, on spell cast current pet is dismissed and charms are removed
3801 {
3803 if (Pet* pet = m_caster->ToPlayer()->GetPet())
3805
3806 if (Unit* charm = m_caster->GetCharm())
3807 charm->RemoveAurasByType(SPELL_AURA_MOD_CHARM, m_caster->GetGUID());
3808 }
3809
3810 if (Player* playerCaster = m_caster->ToPlayer())
3811 {
3812 // now that we've done the basic check, now run the scripts
3813 // should be done before the spell is actually executed
3814 sScriptMgr->OnPlayerSpellCast(playerCaster, this, skipCheck);
3815
3816 // As of 3.0.2 pets begin attacking their owner's target immediately
3817 // Let any pets know we've attacked something. Check DmgClass for harmful spells only
3818 // This prevents spells such as Hunter's Mark from triggering pet attack
3819 // xinef: take into account SPELL_ATTR3_SUPRESS_TARGET_PROCS
3821 if (!playerCaster->m_Controlled.empty())
3822 for (Unit::ControlSet::iterator itr = playerCaster->m_Controlled.begin(); itr != playerCaster->m_Controlled.end(); ++itr)
3823 if (Unit* pet = *itr)
3824 if (pet->IsAlive() && pet->GetTypeId() == TYPEID_UNIT)
3825 pet->ToCreature()->AI()->OwnerAttacked(m_targets.GetUnitTarget());
3826 }
3827
3829
3833
3835
3836 Player* modOwner = m_caster->GetSpellModOwner();
3837 // skip check if done already (for instant cast spells for example)
3838 if (!skipCheck)
3839 {
3840 SpellCastResult castResult = CheckCast(false);
3841 if (castResult != SPELL_CAST_OK)
3842 {
3843 SendCastResult(castResult);
3844 SendInterrupted(0);
3845
3846 finish(false);
3847 SetExecutedCurrently(false);
3848 return;
3849 }
3850
3851 // additional check after cast bar completes (must not be in CheckCast)
3852 // if trade not complete then remember it in trade data
3854 {
3856 {
3857 if (TradeData* my_trade = m_caster->ToPlayer()->GetTradeData())
3858 {
3859 if (!my_trade->IsInAcceptProcess())
3860 {
3861 // Spell will be casted at completing the trade. Silently ignore at this place
3862 my_trade->SetSpell(m_spellInfo->Id, m_CastItem);
3864 SendInterrupted(0);
3865
3866 finish(false);
3867 SetExecutedCurrently(false);
3868 return;
3869 }
3870 }
3871 }
3872 }
3873 }
3874
3875 if (modOwner)
3876 modOwner->SetSpellModTakingSpell(this, true);
3877
3880
3881 if (modOwner)
3882 modOwner->SetSpellModTakingSpell(this, false);
3883
3884 // Spell may be finished after target map check
3886 {
3887 SendInterrupted(0);
3888 finish(false);
3889 SetExecutedCurrently(false);
3890 return;
3891 }
3892
3893 if (modOwner)
3894 modOwner->SetSpellModTakingSpell(this, true);
3895
3897
3899
3900 if (modOwner)
3901 modOwner->SetSpellModTakingSpell(this, false);
3902
3903 // traded items have trade slot instead of guid in m_itemTargetGUID
3904 // set to real guid to be sent later to the client
3906
3908 {
3910 {
3913 }
3914
3916 }
3917
3919 {
3920 // Powers have to be taken before SendSpellGo
3921 TakePower();
3922 TakeReagents(); // we must remove reagents before HandleEffects to allow place crafted item in same slot
3923 }
3924 else if (Item* targetItem = m_targets.GetItemTarget())
3925 {
3927 if (targetItem->GetOwnerGUID() != m_caster->GetGUID())
3928 TakeReagents();
3929 }
3930
3932
3933 // CAST SPELL
3934 if (modOwner)
3935 modOwner->SetSpellModTakingSpell(this, true);
3936
3938
3940
3941 // we must send smsg_spell_go packet before m_castItem delete in TakeCastItem()...
3942 SendSpellGo();
3943
3944 if (modOwner)
3945 modOwner->SetSpellModTakingSpell(this, false);
3946
3947 if (m_originalCaster)
3948 {
3949 // Handle procs on cast
3950 uint32 procAttacker = m_procAttacker;
3951 if (!procAttacker)
3952 {
3953 bool IsPositive = m_spellInfo->IsPositive();
3955 {
3957 }
3958 else
3959 {
3961 }
3962 }
3963
3964 uint32 procEx = PROC_EX_NORMAL_HIT;
3965
3966 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
3967 {
3968 if (ihit->missCondition != SPELL_MISS_NONE)
3969 {
3970 continue;
3971 }
3972
3973 if (!ihit->crit)
3974 {
3975 continue;
3976 }
3977
3978 procEx |= PROC_EX_CRITICAL_HIT;
3979 break;
3980 }
3981
3984 }
3985
3986 if (modOwner)
3987 modOwner->SetSpellModTakingSpell(this, true);
3988
3990 if (resetAttackTimers)
3991 {
3993 for (Unit::AuraEffectList::const_iterator i = vIgnoreReset.begin(); i != vIgnoreReset.end(); ++i)
3994 {
3995 if ((*i)->IsAffectedOnSpell(m_spellInfo))
3996 {
3997 resetAttackTimers = false;
3998 break;
3999 }
4000 }
4001 }
4002
4003 // Okay, everything is prepared. Now we need to distinguish between immediate and evented delayed spells
4004 if ((m_spellInfo->Speed > 0.0f && !m_spellInfo->IsChanneled())/* xinef: we dont need this || m_spellInfo->Id == 14157*/)
4005 {
4006 // Remove used for cast item if need (it can be already nullptr after TakeReagents call
4007 // in case delayed spell remove item at cast delay start
4008 TakeCastItem();
4009
4010 // Okay, maps created, now prepare flags
4011 m_immediateHandled = false;
4013 SetDelayStart(0);
4014
4017
4018 // remove all applied mods at this point
4019 // dont allow user to use them twice in case spell did not reach current target
4020 if (modOwner)
4021 modOwner->RemoveSpellMods(this);
4022
4023 // Xinef: why do we keep focus after spell is sent to air?
4024 // Xinef: Because of this, in the middle of some animation after setting targetguid to 0 etc
4025 // Xinef: we get focused to it out of nowhere...
4026 if (Creature* creatureCaster = m_caster->ToCreature())
4027 creatureCaster->ReleaseFocus(this);
4028 }
4029 else
4030 {
4031 // Immediate spell, no big deal
4033 }
4034
4035 if (resetAttackTimers)
4036 {
4037 if (m_casttime == 0 && m_spellInfo->CalcCastTime())
4038 {
4039 resetAttackTimers = false;
4040 }
4041
4042 if (resetAttackTimers)
4043 {
4045
4047 {
4049 }
4050
4052 }
4053 }
4054
4056
4057 if (modOwner)
4058 modOwner->SetSpellModTakingSpell(this, false);
4059
4060 if (const std::vector<int32>* spell_triggered = sSpellMgr->GetSpellLinked(m_spellInfo->Id))
4061 {
4062 for (std::vector<int32>::const_iterator i = spell_triggered->begin(); i != spell_triggered->end(); ++i)
4063 if (*i < 0)
4065 else
4067 }
4068
4069 // Interrupt Spell casting
4070 // handle this here, in other places SpellHitTarget can be set to nullptr, if there is an error in this function
4072 if (Unit* target = m_targets.GetUnitTarget())
4073 if (target->GetTypeId() == TYPEID_UNIT)
4074 m_caster->CastSpell(target, 32747, true);
4075
4076 // xinef: start combat at cast for delayed spells, only for explicit target
4077 if (Unit* target = m_targets.GetUnitTarget())
4080 m_caster->CombatStartOnCast(target, !m_spellInfo->HasAttribute(SPELL_ATTR3_SUPRESS_TARGET_PROCS), GetDelayMoment() + 500); // xinef: increase this time so we dont leave and enter combat in a moment
4081
4085
4086 SetExecutedCurrently(false);
4087}
@ TYPEID_UNIT
Definition: ObjectGuid.h:37
@ PET_SAVE_AS_CURRENT
Definition: PetDefines.h:42
@ CHEAT_COOLDOWN
Definition: Player.h:993
@ UNIT_STATE_CASTING
Definition: Unit.h:340
#define sScriptMgr
Definition: ScriptMgr.h:2702
@ 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
@ SPELL_STATE_DELAYED
Definition: Spell.h:228
@ SPELL_STATE_FINISHED
Definition: Spell.h:226
@ TRIGGERED_IGNORE_POWER_AND_REAGENT_COST
Will ignore Spell and Category cooldowns.
Definition: SpellDefines.h:134
@ TRIGGERED_IGNORE_CAST_ITEM
Will ignore power and reagent cost.
Definition: SpellDefines.h:135
@ TRIGGERED_IGNORE_SET_FACING
Will ignore interruptible aura's at cast.
Definition: SpellDefines.h:141
@ 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
@ ACHIEVEMENT_TIMED_TYPE_ITEM
Definition: DBCEnums.h:121
@ ACHIEVEMENT_CRITERIA_TYPE_USE_ITEM
Definition: DBCEnums.h:161
@ ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL
Definition: DBCEnums.h:149
@ SPELL_ATTR7_CAN_CAUSE_INTERRUPT
Definition: SharedDefines.h:624
@ SPELL_EFFECT_SUMMON_PET
Definition: SharedDefines.h:806
@ SPELL_ATTR2_DO_NOT_RESET_COMBAT_TIMERS
Definition: SharedDefines.h:445
@ SPELL_ATTR1_DISMISS_PET_FIRST
Definition: SharedDefines.h:391
@ SPELL_ATTR3_SUPRESS_TARGET_PROCS
Definition: SharedDefines.h:482
@ SPELL_DAMAGE_CLASS_NONE
Definition: SharedDefines.h:1517
@ SPELL_MISS_NONE
Definition: SharedDefines.h:1491
SpellCastResult
Definition: SharedDefines.h:920
@ SPELL_FAILED_DONT_REPORT
Definition: SharedDefines.h:948
@ SPELL_CAST_OK
Definition: SharedDefines.h:1110
Definition: Creature.h:46
uint32 GetEntry() const
Definition: Object.h:109
Creature * ToCreature()
Definition: Object.h:197
Definition: Pet.h:40
Definition: Player.h:1046
void UpdateAchievementCriteria(AchievementCriteriaTypes type, uint32 miscValue1=0, uint32 miscValue2=0, Unit *unit=nullptr)
Definition: PlayerUpdates.cpp:2128
void SetSpellModTakingSpell(Spell *spell, bool apply)
Definition: Player.cpp:9975
void StartTimedAchievement(AchievementCriteriaTimedTypes type, uint32 entry, uint32 timeLost=0)
Definition: Player.cpp:13803
void RemoveSpellMods(Spell *spell)
Definition: Player.cpp:9907
Pet * GetPet() const
Definition: Player.cpp:8784
bool GetCommandStatus(uint32 command) const
Definition: Player.h:1154
void RemovePet(Pet *pet, PetSaveMode mode, bool returnreagent=false)
Definition: Player.cpp:8935
TradeData * GetTradeData() const
Definition: Player.h:1344
void RemoveSpellCooldown(uint32 spell_id, bool update=false)
Definition: Player.cpp:3462
Definition: TradeData.h:36
Definition: Unit.h:1290
void ClearUnitState(uint32 f)
Definition: Unit.h:1399
AuraEffectList const & GetAuraEffectsByType(AuraType type) const
Definition: Unit.h:1967
Unit * GetCharm() const
Definition: Unit.cpp:10626
Player * GetSpellModOwner() const
Definition: Unit.cpp:16751
void CombatStartOnCast(Unit *target, bool initialAggro=true, uint32 duration=0)
Definition: Unit.cpp:13612
bool haveOffhandWeapon() const
Definition: Unit.cpp:540
bool IsPet() const
Definition: Unit.h:1413
bool IsNonMeleeSpellCast(bool withDelayed, bool skipChanneled=false, bool skipAutorepeat=false, bool isAutoshoot=false, bool skipInstant=true) const
Definition: Unit.cpp:4039
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:1169
void RemoveAurasDueToSpell(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, uint8 reqEffMask=0, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition: Unit.cpp:4835
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:6290
bool HasUnitState(const uint32 f) const
Definition: Unit.h:1398
bool IsFriendlyTo(Unit const *unit) const
Definition: Unit.cpp:10214
bool IsControlledByPlayer() const
Definition: Unit.h:1828
std::list< AuraEffect * > AuraEffectList
Definition: Unit.h:1306
void SetInFront(WorldObject const *target)
Definition: Unit.cpp:20776
void resetAttackTimer(WeaponAttackType type=BASE_ATTACK)
Definition: Unit.cpp:661
WorldObject * GetObjectTarget() const
Definition: Spell.cpp:305
void UpdateTradeSlotItem()
Definition: Spell.cpp:342
ObjectGuid GetObjectTargetGUID() const
Definition: Spell.cpp:310
Item * GetItemTarget() const
Definition: Spell.h:139
uint32 GetTargetMask() const
Definition: Spell.h:117
Unit * GetUnitTarget() const
Definition: Spell.cpp:226
int8 effectIndex
Definition: Spell.h:279
SpellInfo const * spellInfo
Definition: Spell.h:278
SpellInfo const * GetSpellInfo() const
Definition: Spell.h:574
void CallScriptAfterCastHandlers()
Definition: Spell.cpp:8504
void PrepareTriggersExecutedOnHit()
Definition: Spell.cpp:8710
SpellCastTargets m_targets
Definition: Spell.h:527
TriggeredByAuraSpellData m_triggeredByAuraSpell
Definition: Spell.h:771
void handle_immediate()
Definition: Spell.cpp:4089
void SendSpellGo()
Definition: Spell.cpp:4759
void TakeReagents()
Definition: Spell.cpp:5493
void SetExecutedCurrently(bool yes)
Definition: Spell.h:560
void SendInterrupted(uint8 result)
Definition: Spell.cpp:5136
void PrepareScriptHitHandlers()
Definition: Spell.cpp:8536
void CallScriptOnCastHandlers()
Definition: Spell.cpp:8491
void cancel(bool bySelf=false)
Definition: Spell.cpp:3693
void SendSpellCooldown()
Definition: Spell.cpp:4326
void CallScriptBeforeCastHandlers()
Definition: Spell.cpp:8478
void HandleLaunchPhase()
Definition: Spell.cpp:8191
bool UpdatePointers()
Definition: Spell.cpp:7824
void SetDelayStart(uint64 m_time)
Definition: Spell.h:562
std::list< TargetInfo > m_UniqueTargetInfo
Definition: Spell.h:681
void SelectSpellTargets()
Definition: Spell.cpp:809
void TakePower()
Definition: Spell.cpp:5277
SpellCastResult CheckCast(bool strict)
Definition: Spell.cpp:5612
static void SendCastResult(Player *caster, SpellInfo const *spellInfo, uint8 castCount, SpellCastResult result, SpellCustomErrors customError=SPELL_CUSTOM_ERROR_NONE)
Definition: Spell.cpp:4631
uint64 GetDelayMoment() const
Definition: Spell.h:563
void TakeCastItem()
Definition: Spell.cpp:5214
bool IsAutoActionResetSpell() const
Definition: Spell.cpp:8038
void finish(bool ok=true)
Definition: Spell.cpp:4449
float Speed
Definition: SpellInfo.h:368
bool IsChanneled() const
Definition: SpellInfo.cpp:1240
uint32 CalcCastTime(Unit *caster=nullptr, Spell *spell=nullptr) const
Definition: SpellInfo.cpp:2335
bool HasAura(AuraType aura) const
Definition: SpellInfo.cpp:877

References _spellTargetsSelected, _triggeredCastFlags, 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(), Object::GetTypeId(), SpellCastTargets::GetUnitTarget(), handle_immediate(), HandleLaunchPhase(), SpellInfo::HasAttribute(), SpellInfo::HasAura(), SpellInfo::HasEffect(), Unit::HasUnitState(), Unit::haveOffhandWeapon(), SpellInfo::Id, IsAutoActionResetSpell(), SpellInfo::IsChanneled(), Unit::IsControlledByPlayer(), Unit::IsFriendlyTo(), Unit::IsNonMeleeSpellCast(), Unit::IsPet(), 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_SUPRESS_TARGET_PROCS, SPELL_ATTR7_CAN_CAUSE_INTERRUPT, SPELL_AURA_BIND_SIGHT, SPELL_AURA_IGNORE_MELEE_RESET, SPELL_AURA_MOD_CHARM, SPELL_CAST_OK, SPELL_DAMAGE_CLASS_MAGIC, SPELL_DAMAGE_CLASS_NONE, SPELL_EFFECT_DISPEL, SPELL_EFFECT_SUMMON_PET, SPELL_FAILED_DONT_REPORT, SPELL_MISS_NONE, SPELL_STATE_DELAYED, SPELL_STATE_FINISHED, TriggeredByAuraSpellData::spellInfo, sScriptMgr, sSpellMgr, Player::StartTimedAchievement(), TakeCastItem(), TakePower(), TakeReagents(), TARGET_FLAG_TRADE_ITEM, TARGET_FLAG_UNIT, Object::ToCreature(), Object::ToPlayer(), TRIGGERED_IGNORE_CAST_ITEM, TRIGGERED_IGNORE_POWER_AND_REAGENT_COST, TRIGGERED_IGNORE_SET_FACING, TYPEID_PLAYER, TYPEID_UNIT, UNIT_STATE_CASTING, Player::UpdateAchievementCriteria(), UpdatePointers(), and SpellCastTargets::UpdateTradeSlotItem().

Referenced by cast().

◆ _handle_finish_phase()

void Spell::_handle_finish_phase ( )
4252{
4253 // Take for real after all targets are processed
4255 {
4257 }
4258
4259 // Real add combo points from effects
4261 {
4262 // remove Premed-like effects unless they were caused by ourselves
4263 // (this Aura removes the already-added CP when it expires from duration - now that we've added CP, this shouldn't happen anymore!)
4265 {
4267 }
4268
4270 }
4271
4273 {
4275 }
4276
4279 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
4280 {
4281 // Xinef: Properly clear infinite cooldowns in some cases
4282 if (ihit->targetGUID == m_caster->GetGUID() && ihit->missCondition != SPELL_MISS_NONE)
4285 }
4286
4287 // Handle procs on finish
4288 if (m_originalCaster)
4289 {
4290 uint32 procAttacker = m_procAttacker;
4291 if (!procAttacker)
4292 {
4293 bool IsPositive = m_spellInfo->IsPositive();
4295 {
4297 }
4298 else
4299 {
4301 }
4302 }
4303
4304 uint32 procEx = PROC_EX_NORMAL_HIT;
4305 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
4306 {
4307 if (ihit->missCondition != SPELL_MISS_NONE)
4308 {
4309 continue;
4310 }
4311
4312 if (!ihit->crit)
4313 {
4314 continue;
4315 }
4316
4317 procEx |= PROC_EX_CRITICAL_HIT;
4318 break;
4319 }
4320
4323 }
4324}
@ SPELL_AURA_RETAIN_COMBO_POINTS
Definition: SpellAuraDefines.h:211
@ PROC_SPELL_PHASE_FINISH
Definition: SpellMgr.h:245
@ SPELL_EFFECT_ADD_EXTRA_ATTACKS
Definition: SharedDefines.h:769
void SendCooldownEvent(SpellInfo const *spellInfo, uint32 itemId=0, Spell *spell=nullptr, bool setCooldown=true)
Definition: Player.cpp:11003
void SetLastExtraAttackSpell(uint32 spellId)
Definition: Unit.h:1569
Player * GetCharmerOrOwnerPlayerOrPlayerItself() const
Definition: Unit.cpp:10576
void ClearComboPoints()
Definition: Unit.cpp:17035
void AddComboPoints(Unit *target, int8 count)
Definition: Unit.cpp:17009
void RemoveAurasByType(AuraType auraType, ObjectGuid casterGUID=ObjectGuid::Empty, Aura *except=nullptr, bool negative=true, bool positive=true)
Definition: Unit.cpp:5025
bool IsAutoRepeat() const
Definition: Spell.h:548
bool IsNextMeleeSwingSpell() const
Definition: Spell.cpp:8028
bool IsCooldownStartedOnEvent() const
Definition: SpellInfo.cpp:1196

References Unit::AddComboPoints(), BASE_ATTACK, Unit::ClearComboPoints(), SpellInfo::DmgClass, TriggeredByAuraSpellData::effectIndex, Unit::GetCharmerOrOwnerPlayerOrPlayerItself(), Object::GetGUID(), Object::GetTypeId(), SpellInfo::HasAura(), SpellInfo::HasEffect(), SpellInfo::Id, IsAutoRepeat(), SpellInfo::IsCooldownStartedOnEvent(), IsNextMeleeSwingSpell(), 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, Object::ToPlayer(), and TYPEID_PLAYER.

Referenced by handle_delayed(), and handle_immediate().

◆ _handle_immediate_phase()

void Spell::_handle_immediate_phase ( )
4224{
4225 m_spellAura = nullptr;
4226 // initialize Diminishing Returns Data
4229
4230 // handle some immediate features of the spell here
4232
4234
4235 // handle effects with SPELL_EFFECT_HANDLE_HIT mode
4236 for (uint32 j = 0; j < MAX_SPELL_EFFECTS; ++j)
4237 {
4238 // don't do anything for empty effect
4239 if (!m_spellInfo->Effects[j].IsEffect())
4240 continue;
4241
4242 // call effect handlers to handle destination hit
4243 HandleEffects(nullptr, nullptr, nullptr, j, SPELL_EFFECT_HANDLE_HIT);
4244 }
4245
4246 // process items
4247 for (std::list<ItemTargetInfo>::iterator ihit = m_UniqueItemInfo.begin(); ihit != m_UniqueItemInfo.end(); ++ihit)
4248 DoAllEffectOnTarget(&(*ihit));
4249}
@ SPELL_EFFECT_HANDLE_HIT
Definition: Spell.h:235
void HandleThreatSpells()
Definition: Spell.cpp:5542
void HandleEffects(Unit *pUnitTarget, Item *pItemTarget, GameObject *pGOTarget, uint32 i, SpellEffectHandleMode mode)
Definition: Spell.cpp:5589
std::list< ItemTargetInfo > m_UniqueItemInfo
Definition: Spell.h:698
void DoAllEffectOnTarget(TargetInfo *target)
Definition: Spell.cpp:2594
std::array< SpellEffectInfo, MAX_SPELL_EFFECTS > Effects
Definition: SpellInfo.h:391

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
531 {
532 if (target != m_comboTarget)
533 {
534 m_comboTarget = target;
535 m_comboPointGain = amount;
536 }
537 else
538 {
539 m_comboPointGain += amount;
540 }
541 }

References m_comboPointGain, and m_comboTarget.

Referenced by EffectAddComboPoints(), and EffectWeaponDmg().

◆ AddDestTarget()

void Spell::AddDestTarget ( SpellDestination const &  dest,
uint32  effIndex 
)
protected
2590{
2591 m_destTargets[effIndex] = dest;
2592}

References m_destTargets.

Referenced by SelectSpellTargets().

◆ AddGOTarget()

void Spell::AddGOTarget ( GameObject target,
uint32  effectMask 
)
protected
2499{
2500 for (uint32 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
2501 {
2502 if (!m_spellInfo->Effects[effIndex].IsEffect())
2503 effectMask &= ~(1 << effIndex);
2504 else
2505 {
2506 switch (m_spellInfo->Effects[effIndex].Effect)
2507 {
2511 if (go->GetGoType() != GAMEOBJECT_TYPE_DESTRUCTIBLE_BUILDING)
2512 effectMask &= ~(1 << effIndex);
2513 break;
2514 default:
2515 break;
2516 }
2517 }
2518 }
2519
2520 if (!effectMask)
2521 return;
2522
2523 ObjectGuid targetGUID = go->GetGUID();
2524
2525 // Lookup target in already in list
2526 for (std::list<GOTargetInfo>::iterator ihit = m_UniqueGOTargetInfo.begin(); ihit != m_UniqueGOTargetInfo.end(); ++ihit)
2527 {
2528 if (targetGUID == ihit->targetGUID) // Found in list
2529 {
2530 ihit->effectMask |= effectMask; // Add only effect mask
2531 return;
2532 }
2533 }
2534
2535 // This is new target calculate data for him
2536
2537 GOTargetInfo target;
2538 target.targetGUID = targetGUID;
2539 target.effectMask = effectMask;
2540 target.processed = false; // Effects not apply on target
2541
2542 // Spell have speed - need calculate incoming time
2543 if (m_spellInfo->Speed > 0.0f)
2544 {
2545 // calculate spell incoming interval
2546 float dist = m_caster->GetDistance(go->GetPositionX(), go->GetPositionY(), go->GetPositionZ());
2547 if (dist < 5.0f)
2548 dist = 5.0f;
2549 target.timeDelay = uint64(floor(dist / m_spellInfo->Speed * 1000.0f));
2550 if (m_delayMoment == 0 || m_delayMoment > target.timeDelay)
2551 m_delayMoment = target.timeDelay;
2552 }
2553 else
2554 target.timeDelay = 0LL;
2555
2556 // Add target to list
2557 m_UniqueGOTargetInfo.push_back(target);
2558}
std::uint64_t uint64
Definition: Define.h:107
@ GAMEOBJECT_TYPE_DESTRUCTIBLE_BUILDING
Definition: SharedDefines.h:1565
@ SPELL_EFFECT_GAMEOBJECT_REPAIR
Definition: SharedDefines.h:838
@ SPELL_EFFECT_GAMEOBJECT_SET_DESTRUCTION_STATE
Definition: SharedDefines.h:839
@ SPELL_EFFECT_GAMEOBJECT_DAMAGE
Definition: SharedDefines.h:837
float GetDistance(WorldObject const *obj) const
Definition: Object.cpp:1245
Definition: ObjectGuid.h:120
uint64 m_delayMoment
Definition: Spell.h:638
std::list< GOTargetInfo > m_UniqueGOTargetInfo
Definition: Spell.h:691

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
2561{
2562 for (uint32 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
2563 if (!m_spellInfo->Effects[effIndex].IsEffect())
2564 effectMask &= ~(1 << effIndex);
2565
2566 // no effects left
2567 if (!effectMask)
2568 return;
2569
2570 // Lookup target in already in list
2571 for (std::list<ItemTargetInfo>::iterator ihit = m_UniqueItemInfo.begin(); ihit != m_UniqueItemInfo.end(); ++ihit)
2572 {
2573 if (item == ihit->item) // Found in list
2574 {
2575 ihit->effectMask |= effectMask; // Add only effect mask
2576 return;
2577 }
2578 }
2579
2580 // This is new target add data
2581
2582 ItemTargetInfo target;
2583 target.item = item;
2584 target.effectMask = effectMask;
2585
2586 m_UniqueItemInfo.push_back(target);
2587}

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)
2366{
2367 for (uint32 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
2368 if (!m_spellInfo->Effects[effIndex].IsEffect() || !CheckEffectTarget(target, effIndex))
2369 effectMask &= ~(1 << effIndex);
2370
2371 // no effects left
2372 if (!effectMask)
2373 return;
2374
2375 if (checkIfValid)
2376 {
2377 SpellCastResult res = m_spellInfo->CheckTarget(m_caster, target, implicit);
2378 if (res != SPELL_CAST_OK)
2379 return;
2380 }
2381
2382 // Check for effect immune skip if immuned
2383 for (uint32 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
2384 if (target->IsImmunedToSpellEffect(m_spellInfo, effIndex))
2385 effectMask &= ~(1 << effIndex);
2386
2387 ObjectGuid targetGUID = target->GetGUID();
2388
2389 // Lookup target in already in list
2390 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
2391 {
2392 if (targetGUID == ihit->targetGUID) // Found in list
2393 {
2394 ihit->effectMask |= effectMask; // Immune effects removed from mask
2395 ihit->scaleAura = false;
2396 if (m_auraScaleMask && ihit->effectMask == m_auraScaleMask && m_caster != target)
2397 {
2398 SpellInfo const* auraSpell = m_spellInfo->GetFirstRankSpell();
2399 if (uint32(target->GetLevel() + 10) >= auraSpell->SpellLevel)
2400 ihit->scaleAura = true;
2401 }
2402
2403 sScriptMgr->OnScaleAuraUnitAdd(this, target, effectMask, checkIfValid, implicit, m_auraScaleMask, *ihit);
2404 return;
2405 }
2406 }
2407
2408 // This is new target calculate data for him
2409
2410 // Get spell hit result on target
2411 TargetInfo targetInfo;
2412 targetInfo.targetGUID = targetGUID; // Store target GUID
2413 targetInfo.effectMask = effectMask; // Store all effects not immune
2414 targetInfo.processed = false; // Effects not apply on target
2415 targetInfo.alive = target->IsAlive();
2416 targetInfo.damage = 0;
2417 targetInfo.crit = false;
2418 targetInfo.scaleAura = false;
2419 if (m_auraScaleMask && targetInfo.effectMask == m_auraScaleMask && m_caster != target)
2420 {
2421 SpellInfo const* auraSpell = m_spellInfo->GetFirstRankSpell();
2422 if (uint32(target->GetLevel() + 10) >= auraSpell->SpellLevel)
2423 targetInfo.scaleAura = true;
2424 }
2425
2426 sScriptMgr->OnScaleAuraUnitAdd(this, target, effectMask, checkIfValid, implicit, m_auraScaleMask, targetInfo);
2427
2428 // Calculate hit result
2429 if (m_originalCaster)
2430 {
2431 targetInfo.missCondition = m_originalCaster->SpellHitResult(target, this, m_canReflect);
2432 if (m_skipCheck && targetInfo.missCondition != SPELL_MISS_IMMUNE)
2433 {
2434 targetInfo.missCondition = SPELL_MISS_NONE;
2435 }
2436 }
2437 else
2438 targetInfo.missCondition = SPELL_MISS_EVADE; //SPELL_MISS_NONE;
2439
2440 // Spell have speed - need calculate incoming time
2441 // Incoming time is zero for self casts. At least I think so.
2442 if (m_spellInfo->Speed > 0.0f && m_caster != target)
2443 {
2444 // calculate spell incoming interval
2446 float dist = m_caster->GetDistance(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ());
2447
2448 if (dist < 5.0f)
2449 dist = 5.0f;
2450 targetInfo.timeDelay = (uint64) floor(dist / m_spellInfo->Speed * 1000.0f);
2451
2452 // Calculate minimum incoming time
2453 if (m_delayMoment == 0 || m_delayMoment > targetInfo.timeDelay)
2454 m_delayMoment = targetInfo.timeDelay;
2455 }
2456 else
2457 targetInfo.timeDelay = 0LL;
2458
2459 // If target reflect spell back to caster
2460 if (targetInfo.missCondition == SPELL_MISS_REFLECT)
2461 {
2462 // Calculate reflected spell result on caster
2464
2465 if (targetInfo.reflectResult == SPELL_MISS_REFLECT) // Impossible reflect again, so simply deflect spell
2466 targetInfo.reflectResult = SPELL_MISS_PARRY;
2467
2468 // Increase time interval for reflected spells by 1.5
2470 targetInfo.timeDelay += targetInfo.timeDelay >> 1;
2471
2473
2474 // HACK: workaround check for succubus seduction case
2476 if (m_caster->IsPet())
2477 {
2478 CreatureTemplate const* ci = sObjectMgr->GetCreatureTemplate(m_caster->GetEntry());
2479 switch (ci->family)
2480 {
2482 {
2483 if (m_spellInfo->SpellIconID != 694) // Soothing Kiss
2484 cancel();
2485 }
2486 break;
2487 return;
2488 }
2489 }
2490 }
2491 else
2492 targetInfo.reflectResult = SPELL_MISS_NONE;
2493
2494 // Add target to list
2495 m_UniqueTargetInfo.push_back(targetInfo);
2496}
#define sObjectMgr
Definition: ObjectMgr.h:1640
@ SPELL_FLAG_REFLECTED
Definition: Spell.h:82
@ CREATURE_FAMILY_SUCCUBUS
Definition: SharedDefines.h:2636
@ SPELL_MISS_PARRY
Definition: SharedDefines.h:1495
@ SPELL_MISS_IMMUNE
Definition: SharedDefines.h:1498
@ SPELL_MISS_EVADE
Definition: SharedDefines.h:1497
@ SPELL_MISS_REFLECT
Definition: SharedDefines.h:1502
void AddEvent(BasicEvent *Event, uint64 e_time, bool set_addtime=true)
Definition: EventProcessor.h:105
uint64 CalculateTime(uint64 t_offset) const
Definition: EventProcessor.cpp:158
Definition: CreatureData.h:176
uint32 family
Definition: CreatureData.h:210
float GetPositionZ() const
Definition: Position.h:119
float GetPositionX() const
Definition: Position.h:117
float GetPositionY() const
Definition: Position.h:118
bool IsAlive() const
Definition: Unit.h:1808
SpellMissInfo SpellHitResult(Unit *victim, SpellInfo const *spell, bool canReflect=false)
Definition: Unit.cpp:3424
EventProcessor m_Events
Definition: Unit.h:2094
virtual bool IsImmunedToSpellEffect(SpellInfo const *spellInfo, uint32 index) const
Definition: Unit.cpp:12917
uint8 GetLevel() const
Definition: Unit.h:1420
Definition: Spell.h:254
bool processed
Definition: Spell.h:260
int32 damage
Definition: Spell.h:264
SpellMissInfo missCondition
Definition: Spell.h:257
bool scaleAura
Definition: Spell.h:263
bool crit
Definition: Spell.h:262
uint64 timeDelay
Definition: Spell.h:256
ObjectGuid targetGUID
Definition: Spell.h:255
SpellMissInfo reflectResult
Definition: Spell.h:258
bool alive
Definition: Spell.h:261
uint8 effectMask
Definition: Spell.h:259
bool CheckEffectTarget(Unit const *target, uint32 eff) const
Definition: Spell.cpp:7886
Definition: Spell.h:845
Definition: SpellInfo.h:314
uint32 SpellLevel
Definition: SpellInfo.h:358
SpellInfo const * GetFirstRankSpell() const
Definition: SpellInfo.cpp:2484
uint32 SpellIconID
Definition: SpellInfo.h:378
SpellCastResult CheckTarget(Unit const *caster, WorldObject const *target, bool implicit=true) const
Definition: SpellInfo.cpp:1744

References EventProcessor::AddEvent(), TargetInfo::alive, EventProcessor::CalculateTime(), cancel(), CheckEffectTarget(), SpellInfo::CheckTarget(), CREATURE_FAMILY_SUCCUBUS, TargetInfo::crit, TargetInfo::damage, TargetInfo::effectMask, SpellInfo::Effects, CreatureTemplate::family, WorldObject::GetDistance(), Object::GetEntry(), SpellInfo::GetFirstRankSpell(), Object::GetGUID(), Unit::GetLevel(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), Unit::IsAlive(), Unit::IsImmunedToSpellEffect(), Unit::IsPet(), m_auraScaleMask, m_canReflect, m_caster, m_delayMoment, Unit::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
890{
891 if (m_targets.HasDst())
892 {
893 if (m_targets.HasTraj())
894 {
895 float speed = m_targets.GetSpeedXY();
896 if (speed > 0.0f)
897 return (uint64)floor(m_targets.GetDist2d() / speed * 1000.0f);
898 }
899 else if (m_spellInfo->Speed > 0.0f)
900 {
901 // We should not subtract caster size from dist calculation (fixes execution time desync with animation on client, eg. Malleable Goo cast by PP)
902 float dist = m_caster->GetExactDist(*m_targets.GetDstPos());
903 return (uint64)std::floor(dist / m_spellInfo->Speed * 1000.0f);
904 }
905 }
906
907 return 0;
908}
float GetExactDist(float x, float y, float z) const
Definition: Position.h:178
bool HasTraj() const
Definition: Spell.h:166
bool HasDst() const
Definition: Spell.h:165
float GetSpeedXY() const
Definition: Spell.h:174
float GetDist2d() const
Definition: Spell.h:173
WorldLocation const * GetDstPos() const
Definition: Spell.cpp:395

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
1178{
1179 if (m_spellInfo->Effects[i].MiscValue)
1180 speedZ = float(m_spellInfo->Effects[i].MiscValue) / 10;
1181 else if (m_spellInfo->Effects[i].MiscValueB)
1182 speedZ = float(m_spellInfo->Effects[i].MiscValueB) / 10;
1183 else
1184 speedZ = 10.0f;
1185 speedXY = dist * 10.0f / speedZ;
1186}

References SpellInfo::Effects, and m_spellInfo.

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

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

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

◆ CallScriptAfterCastHandlers()

void Spell::CallScriptAfterCastHandlers ( )
protected
8505{
8506 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8507 {
8508 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_AFTER_CAST);
8509 std::list<SpellScript::CastHandler>::iterator hookItrEnd = (*scritr)->AfterCast.end(), hookItr = (*scritr)->AfterCast.begin();
8510 for (; hookItr != hookItrEnd; ++hookItr)
8511 (*hookItr).Call(*scritr);
8512
8513 (*scritr)->_FinishScriptCall();
8514 }
8515}
@ 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
8617{
8618 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8619 {
8620 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_AFTER_HIT);
8621 std::list<SpellScript::HitHandler>::iterator hookItrEnd = (*scritr)->AfterHit.end(), hookItr = (*scritr)->AfterHit.begin();
8622 for (; hookItr != hookItrEnd; ++hookItr)
8623 (*hookItr).Call(*scritr);
8624
8625 (*scritr)->_FinishScriptCall();
8626 }
8627}
@ SPELL_SCRIPT_HOOK_AFTER_HIT
Definition: SpellScript.h:165

References m_loadedScripts, and SPELL_SCRIPT_HOOK_AFTER_HIT.

Referenced by DoAllEffectOnTarget().

◆ CallScriptBeforeCastHandlers()

void Spell::CallScriptBeforeCastHandlers ( )
protected
8479{
8480 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8481 {
8482 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_BEFORE_CAST);
8483 std::list<SpellScript::CastHandler>::iterator hookItrEnd = (*scritr)->BeforeCast.end(), hookItr = (*scritr)->BeforeCast.begin();
8484 for (; hookItr != hookItrEnd; ++hookItr)
8485 (*hookItr).Call(*scritr);
8486
8487 (*scritr)->_FinishScriptCall();
8488 }
8489}
@ 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
8591{
8592 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8593 {
8594 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_BEFORE_HIT);
8595 std::list<SpellScript::BeforeHitHandler>::iterator hookItrEnd = (*scritr)->BeforeHit.end(), hookItr = (*scritr)->BeforeHit.begin();
8596 for (; hookItr != hookItrEnd; ++hookItr)
8597 (*hookItr).Call(*scritr, missInfo);
8598
8599 (*scritr)->_FinishScriptCall();
8600 }
8601}
@ SPELL_SCRIPT_HOOK_BEFORE_HIT
Definition: SpellScript.h:163

References m_loadedScripts, and SPELL_SCRIPT_HOOK_BEFORE_HIT.

Referenced by DoAllEffectOnTarget().

◆ CallScriptCheckCastHandlers()

SpellCastResult Spell::CallScriptCheckCastHandlers ( )
protected
8518{
8520 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8521 {
8522 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_CHECK_CAST);
8523 std::list<SpellScript::CheckCastHandler>::iterator hookItrEnd = (*scritr)->OnCheckCast.end(), hookItr = (*scritr)->OnCheckCast.begin();
8524 for (; hookItr != hookItrEnd; ++hookItr)
8525 {
8526 SpellCastResult tempResult = (*hookItr).Call(*scritr);
8527 if (retVal == SPELL_CAST_OK)
8528 retVal = tempResult;
8529 }
8530
8531 (*scritr)->_FinishScriptCall();
8532 }
8533 return retVal;
8534}
@ 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
8658{
8659 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8660 {
8661 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_DESTINATION_TARGET_SELECT);
8662 std::list<SpellScript::DestinationTargetSelectHandler>::iterator hookItrEnd = (*scritr)->OnDestinationTargetSelect.end(), hookItr = (*scritr)->OnDestinationTargetSelect.begin();
8663 for (; hookItr != hookItrEnd; ++hookItr)
8664 if (hookItr->IsEffectAffected(m_spellInfo, effIndex) && targetType.GetTarget() == hookItr->GetTarget())
8665 hookItr->Call(*scritr, target);
8666
8667 (*scritr)->_FinishScriptCall();
8668 }
8669}
@ 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
8543{
8544 // execute script effect handler hooks and check if effects was prevented
8545 bool preventDefault = false;
8546 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8547 {
8548 std::list<SpellScript::EffectHandler>::iterator effItr, effEndItr;
8549 SpellScriptHookType hookType;
8550 switch (mode)
8551 {
8553 effItr = (*scritr)->OnEffectLaunch.begin();
8554 effEndItr = (*scritr)->OnEffectLaunch.end();
8556 break;
8558 effItr = (*scritr)->OnEffectLaunchTarget.begin();
8559 effEndItr = (*scritr)->OnEffectLaunchTarget.end();
8561 break;
8563 effItr = (*scritr)->OnEffectHit.begin();
8564 effEndItr = (*scritr)->OnEffectHit.end();
8566 break;
8568 effItr = (*scritr)->OnEffectHitTarget.begin();
8569 effEndItr = (*scritr)->OnEffectHitTarget.end();
8571 break;
8572 default:
8573 ABORT();
8574 return false;
8575 }
8576 (*scritr)->_PrepareScriptCall(hookType);
8577 for (; effItr != effEndItr; ++effItr)
8578 // effect execution can be prevented
8579 if (!(*scritr)->_IsEffectPrevented(effIndex) && (*effItr).IsEffectAffected(m_spellInfo, effIndex))
8580 (*effItr).Call(*scritr, effIndex);
8581
8582 if (!preventDefault)
8583 preventDefault = (*scritr)->_IsDefaultEffectPrevented(effIndex);
8584
8585 (*scritr)->_FinishScriptCall();
8586 }
8587 return preventDefault;
8588}
#define ABORT
Definition: Errors.h:76
@ SPELL_EFFECT_HANDLE_LAUNCH_TARGET
Definition: Spell.h:234
@ SPELL_EFFECT_HANDLE_HIT_TARGET
Definition: Spell.h:236
SpellScriptHookType
Definition: SpellScript.h:158
@ SPELL_SCRIPT_HOOK_EFFECT_HIT
Definition: SpellScript.h:161
@ SPELL_SCRIPT_HOOK_EFFECT_LAUNCH
Definition: SpellScript.h:159
@ SPELL_SCRIPT_HOOK_EFFECT_LAUNCH_TARGET
Definition: SpellScript.h:160
@ SPELL_SCRIPT_HOOK_EFFECT_HIT_TARGET
Definition: SpellScript.h:162

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

Referenced by HandleEffects().

◆ CallScriptObjectAreaTargetSelectHandlers()

void Spell::CallScriptObjectAreaTargetSelectHandlers ( std::list< WorldObject * > &  targets,
SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType 
)
protected
8630{
8631 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8632 {
8633 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_OBJECT_AREA_TARGET_SELECT);
8634 std::list<SpellScript::ObjectAreaTargetSelectHandler>::iterator hookItrEnd = (*scritr)->OnObjectAreaTargetSelect.end(), hookItr = (*scritr)->OnObjectAreaTargetSelect.begin();
8635 for (; hookItr != hookItrEnd; ++hookItr)
8636 if (hookItr->IsEffectAffected(m_spellInfo, effIndex) && targetType.GetTarget() == hookItr->GetTarget())
8637 hookItr->Call(*scritr, targets);
8638
8639 (*scritr)->_FinishScriptCall();
8640 }
8641}
@ 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
8644{
8645 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8646 {
8647 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_OBJECT_TARGET_SELECT);
8648 std::list<SpellScript::ObjectTargetSelectHandler>::iterator hookItrEnd = (*scritr)->OnObjectTargetSelect.end(), hookItr = (*scritr)->OnObjectTargetSelect.begin();
8649 for (; hookItr != hookItrEnd; ++hookItr)
8650 if (hookItr->IsEffectAffected(m_spellInfo, effIndex) && targetType.GetTarget() == hookItr->GetTarget())
8651 hookItr->Call(*scritr, target);
8652
8653 (*scritr)->_FinishScriptCall();
8654 }
8655}
@ 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
8492{
8493 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8494 {
8495 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_ON_CAST);
8496 std::list<SpellScript::CastHandler>::iterator hookItrEnd = (*scritr)->OnCast.end(), hookItr = (*scritr)->OnCast.begin();
8497 for (; hookItr != hookItrEnd; ++hookItr)
8498 (*hookItr).Call(*scritr);
8499
8500 (*scritr)->_FinishScriptCall();
8501 }
8502}
@ 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
8604{
8605 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8606 {
8607 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_HIT);
8608 std::list<SpellScript::HitHandler>::iterator hookItrEnd = (*scritr)->OnHit.end(), hookItr = (*scritr)->OnHit.begin();
8609 for (; hookItr != hookItrEnd; ++hookItr)
8610 (*hookItr).Call(*scritr);
8611
8612 (*scritr)->_FinishScriptCall();
8613 }
8614}
@ SPELL_SCRIPT_HOOK_HIT
Definition: SpellScript.h:164

References m_loadedScripts, and SPELL_SCRIPT_HOOK_HIT.

Referenced by DoAllEffectOnTarget().

◆ CanAutoCast()

bool Spell::CanAutoCast ( Unit target)
6977{
6978 ObjectGuid targetguid = target->GetGUID();
6979
6980 for (uint32 j = 0; j < MAX_SPELL_EFFECTS; ++j)
6981 {
6983 {
6984 if (m_spellInfo->StackAmount <= 1)
6985 {
6986 if (target->HasAuraEffect(m_spellInfo->Id, j))
6987 return false;
6988 }
6989 else
6990 {
6991 if (AuraEffect* aureff = target->GetAuraEffect(m_spellInfo->Id, j))
6992 if (aureff->GetBase()->GetStackAmount() >= m_spellInfo->StackAmount)
6993 return false;
6994 }
6995 }
6996 else if (m_spellInfo->Effects[j].IsAreaAuraEffect())
6997 {
6998 if (target->HasAuraEffect(m_spellInfo->Id, j))
6999 return false;
7000 }
7001 }
7002
7003 SpellCastResult result = CheckPetCast(target);
7004
7005 if (result == SPELL_CAST_OK || result == SPELL_FAILED_UNIT_NOT_INFRONT)
7006 {
7008 //check if among target units, our WANTED target is as well (->only self cast spells return false)
7009 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
7010 if (ihit->targetGUID == targetguid)
7011 return true;
7012 }
7013 return false; //target invalid
7014}
@ SPELL_EFFECT_APPLY_AURA
Definition: SharedDefines.h:756
@ SPELL_FAILED_UNIT_NOT_INFRONT
Definition: SharedDefines.h:1055
AuraEffect * GetAuraEffect(uint32 spellId, uint8 effIndex, ObjectGuid casterGUID=ObjectGuid::Empty) const
Definition: Unit.cpp:5412
bool HasAuraEffect(uint32 spellId, uint8 effIndex, ObjectGuid caster=ObjectGuid::Empty) const
Definition: Unit.cpp:5580
Definition: SpellAuraEffects.h:39
SpellCastResult CheckPetCast(Unit *target)
Definition: Spell.cpp:6783
uint32 StackAmount
Definition: SpellInfo.h:369

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)
Todo:
: Not sure whether the fallthrough was a mistake (forgetting a break) or intended. This should be double-checked.
3694{
3696 return;
3697
3698 uint32 oldState = m_spellState;
3699 bool autoRepeat = m_autoRepeat;
3701
3702 m_autoRepeat = false;
3703 switch (oldState)
3704 {
3708 {
3710 ArenaSpectator::SendCommand_Spell(m_caster->FindMap(), m_caster->GetGUID(), "SPE", m_spellInfo->Id, bySelf ? 99998 : 99999);
3711 }
3712 [[fallthrough]];
3714 SendInterrupted(0);
3715 // xinef: fixes bugged gcd reset in some cases
3716 if (!autoRepeat)
3718 break;
3719
3721 if (!bySelf)
3722 {
3723 for (std::list<TargetInfo>::const_iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
3724 if ((*ihit).missCondition == SPELL_MISS_NONE)
3725 if (Unit* unit = m_caster->GetGUID() == ihit->targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID))
3726 unit->RemoveOwnedAura(m_spellInfo->Id, m_originalCasterGUID, 0, AURA_REMOVE_BY_CANCEL);
3727
3729 SendInterrupted(0);
3731 }
3732
3734 ArenaSpectator::SendCommand_Spell(m_caster->FindMap(), m_caster->GetGUID(), "SPE", m_spellInfo->Id, bySelf ? 99998 : 99999);
3735
3736 // spell is canceled-take mods and clear list
3737 if (Player* player = m_caster->GetSpellModOwner())
3738 player->RemoveSpellMods(this);
3739
3740 m_appliedMods.clear();
3741 break;
3742 default:
3743 break;
3744 }
3745
3747 if (m_selfContainer && *m_selfContainer == this)
3748 *m_selfContainer = nullptr;
3749
3750 // Do not remove current far sight object (already done in Spell::EffectAddFarsight) to prevent from reset viewpoint to player
3752 {
3754 }
3755
3756 if (m_spellInfo->IsChanneled()) // if not channeled then the object for the current cast wasn't summoned yet
3758
3759 //set state back so finish will be processed
3760 m_spellState = oldState;
3761
3762 finish(false);
3763}
@ AURA_REMOVE_BY_CANCEL
Definition: SpellAuraDefines.h:393
@ SPELL_STATE_PREPARING
Definition: Spell.h:224
@ SPELL_STATE_CASTING
Definition: Spell.h:225
@ SPELL_EFFECT_ADD_FARSIGHT
Definition: SharedDefines.h:822
@ SPELL_FAILED_INTERRUPTED
Definition: SharedDefines.h:961
void SendCommand_Spell(T *o, ObjectGuid targetGUID, const char *prefix, uint32 id, int32 casttime)
Definition: ArenaSpectator.h:80
Map * FindMap() const
Definition: Object.h:518
bool NeedSendSpectatorData() const
Definition: Player.cpp:15282
void RemoveGameObject(GameObject *gameObj, bool del)
Definition: Unit.cpp:6109
bool RemoveDynObject(uint32 spellId)
Definition: Unit.cpp:6053
void SendChannelUpdate(uint32 time)
Definition: Spell.cpp:5153
void CancelGlobalCooldown()
Definition: Spell.cpp:8845
void SetReferencedFromCurrent(bool yes)
Definition: Spell.h:558
UsedSpellMods m_appliedMods
Definition: Spell.h:545

References AURA_REMOVE_BY_CANCEL, CancelGlobalCooldown(), WorldObject::FindMap(), finish(), Object::GetGUID(), Unit::GetSpellModOwner(), Object::GetTypeId(), ObjectAccessor::GetUnit(), SpellInfo::HasEffect(), SpellInfo::Id, SpellInfo::IsChanneled(), m_appliedMods, m_autoRepeat, m_caster, m_originalCasterGUID, m_selfContainer, m_spellInfo, m_spellState, m_UniqueTargetInfo, Player::NeedSendSpectatorData(), Unit::RemoveDynObject(), Unit::RemoveGameObject(), 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, Object::ToPlayer(), and TYPEID_PLAYER.

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

◆ CancelGlobalCooldown()

void Spell::CancelGlobalCooldown ( )
protected
8846{
8848 return;
8849
8850 // Cancel global cooldown when interrupting current cast
8852 return;
8853
8854 // Only players or controlled units have global cooldown
8855 if (m_caster->GetCharmInfo())
8857 else if (m_caster->GetTypeId() == TYPEID_PLAYER)
8859}
@ CURRENT_GENERIC_SPELL
Definition: Unit.h:979
GlobalCooldownMgr & GetGlobalCooldownMgr()
Definition: Player.h:1755
void CancelGlobalCooldown(SpellInfo const *spellInfo)
Definition: Unit.cpp:352
GlobalCooldownMgr & GetGlobalCooldownMgr()
Definition: Unit.h:1127
CharmInfo * GetCharmInfo()
Definition: Unit.h:1883
Spell * GetCurrentSpell(CurrentSpellTypes spellType) const
Definition: Unit.h:2061
uint32 StartRecoveryTime
Definition: SpellInfo.h:349

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

Referenced by cancel().

◆ CanExecuteTriggersOnHit()

bool Spell::CanExecuteTriggersOnHit ( uint8  effMask,
SpellInfo const *  triggeredByAura = nullptr 
) const
protected
8695{
8696 // Relentless strikes, proc only from first effect
8697 if (triggeredByAura && triggeredByAura->SpellIconID == 559)
8698 return effMask & (1 << EFFECT_0);
8699
8700 bool only_on_caster = (triggeredByAura && triggeredByAura->HasAttribute(SPELL_ATTR4_CLASS_TRIGGER_ONLY_ON_TARGET));
8701 // If triggeredByAura has SPELL_ATTR4_CLASS_TRIGGER_ONLY_ON_TARGET then it can only proc on a casted spell with TARGET_UNIT_CASTER
8702 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
8703 {
8704 if ((effMask & (1 << i)) && (!only_on_caster || (m_spellInfo->Effects[i].TargetA.GetTarget() == TARGET_UNIT_CASTER)))
8705 return true;
8706 }
8707 return effMask;
8708}
@ EFFECT_0
Definition: SharedDefines.h:30
@ TARGET_UNIT_CASTER
Definition: SharedDefines.h:1382
@ SPELL_ATTR4_CLASS_TRIGGER_ONLY_ON_TARGET
Definition: SharedDefines.h:503

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
8319{
8320 if (!lockId) // possible case for GO and maybe for items.
8321 return SPELL_CAST_OK;
8322
8323 // Get LockInfo
8324 LockEntry const* lockInfo = sLockStore.LookupEntry(lockId);
8325
8326 if (!lockInfo)
8328
8329 bool reqKey = false; // some locks not have reqs
8330
8331 for (int j = 0; j < MAX_LOCK_CASE; ++j)
8332 {
8333 switch (lockInfo->Type[j])
8334 {
8335 // check key item (many fit cases can be)
8336 case LOCK_KEY_ITEM:
8337 if (lockInfo->Index[j] && m_CastItem && m_CastItem->GetEntry() == lockInfo->Index[j])
8338 return SPELL_CAST_OK;
8339 reqKey = true;
8340 break;
8341 // check key skill (only single first fit case can be)
8342 case LOCK_KEY_SKILL:
8343 {
8344 reqKey = true;
8345
8346 // wrong locktype, skip
8347 if (uint32(m_spellInfo->Effects[effIndex].MiscValue) != lockInfo->Index[j])
8348 continue;
8349
8350 skillId = SkillByLockType(LockType(lockInfo->Index[j]));
8351
8352 if (skillId != SKILL_NONE)
8353 {
8354 reqSkillValue = lockInfo->Skill[j];
8355
8356 // castitem check: rogue using skeleton keys. the skill values should not be added in this case.
8357 skillValue = m_CastItem || m_caster->GetTypeId() != TYPEID_PLAYER ?
8358 0 : m_caster->ToPlayer()->GetSkillValue(skillId);
8359
8360 // skill bonus provided by casting spell (mostly item spells)
8361 // add the effect base points modifier from the spell casted (cheat lock / skeleton key etc.)
8362 if ((m_spellInfo->Effects[effIndex].TargetA.GetTarget() == TARGET_GAMEOBJECT_ITEM_TARGET || m_spellInfo->Effects[effIndex].TargetB.GetTarget() == TARGET_GAMEOBJECT_ITEM_TARGET)
8364 {
8365 skillValue += m_spellInfo->Effects[effIndex].CalcValue();
8366 }
8367
8368 if (skillValue < reqSkillValue)
8370 }
8371
8372 return SPELL_CAST_OK;
8373 }
8374 case LOCK_KEY_SPELL:
8375 {
8376 if (m_spellInfo->Id == lockInfo->Index[j])
8377 {
8378 return SPELL_CAST_OK;
8379 }
8380 reqKey = true;
8381 break;
8382 }
8383 }
8384 }
8385
8386 if (reqKey)
8388
8389 return SPELL_CAST_OK;
8390}
DBCStorage< LockEntry > sLockStore(LockEntryfmt)
#define MAX_LOCK_CASE
Definition: DBCStructure.h:1288
@ TARGET_GAMEOBJECT_ITEM_TARGET
Definition: SharedDefines.h:1402
LockType
Definition: SharedDefines.h:2563
@ LOCK_KEY_ITEM
Definition: SharedDefines.h:2557
@ LOCK_KEY_SKILL
Definition: SharedDefines.h:2558
@ LOCK_KEY_SPELL
Definition: SharedDefines.h:2559
@ SPELL_FAILED_BAD_TARGETS
Definition: SharedDefines.h:933
@ SPELL_FAILED_LOW_CASTLEVEL
Definition: SharedDefines.h:970
SkillType SkillByLockType(LockType locktype)
Definition: SharedDefines.h:2992
@ SKILL_NONE
Definition: SharedDefines.h:2836
@ SKILL_LOCKPICKING
Definition: SharedDefines.h:2947
uint16 GetSkillValue(uint32 skill) const
Definition: Player.cpp:5354
bool IsAbilityOfSkillType(uint32 skillType) const
Definition: SpellInfo.cpp:989
Definition: DBCStructure.h:1291
uint32 Type[MAX_LOCK_CASE]
Definition: DBCStructure.h:1293
uint32 Index[MAX_LOCK_CASE]
Definition: DBCStructure.h:1294
uint32 Skill[MAX_LOCK_CASE]
Definition: DBCStructure.h:1295

References SpellInfo::Effects, Object::GetEntry(), Player::GetSkillValue(), Object::GetTypeId(), SpellInfo::Id, LockEntry::Index, SpellInfo::IsAbilityOfSkillType(), 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(), LockEntry::Type, and TYPEID_PLAYER.

Referenced by CheckCast(), and EffectOpenLock().

◆ cast()

void Spell::cast ( bool  skipCheck = false)
3766{
3767 Player* modOwner = m_caster->GetSpellModOwner();
3768 Spell* lastMod = nullptr;
3769 if (modOwner)
3770 {
3771 lastMod = modOwner->m_spellModTakingSpell;
3772 if (lastMod)
3773 modOwner->SetSpellModTakingSpell(lastMod, false);
3774 }
3775
3776 _cast(skipCheck);
3777
3778 if (lastMod)
3779 modOwner->SetSpellModTakingSpell(lastMod, true);
3780}
Spell * m_spellModTakingSpell
Definition: Player.h:2499
Definition: Spell.h:284
void _cast(bool skipCheck)
Definition: Spell.cpp:3782

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
5613{
5614 // check death state
5617
5618 // Spectator check
5620 if (((Player const*)m_caster)->IsSpectator() && m_spellInfo->Id != SPECTATOR_SPELL_BINDSIGHT)
5621 return SPELL_FAILED_NOT_HERE;
5622
5624
5625 sScriptMgr->OnSpellCheckCast(this, strict, res);
5626
5627 if (res != SPELL_CAST_OK)
5628 return res;
5629
5630 // check cooldowns to prevent cheating
5632 {
5634 {
5635 //can cast triggered (by aura only?) spells while have this flag
5638
5640 {
5643 else
5645 }
5646
5647 // check if we are using a potion in combat for the 2nd+ time. Cooldown is added only after caster gets out of combat
5650 }
5653 }
5654
5656 {
5659 }
5660
5661 // Check global cooldown
5664
5665 // only triggered spells can be processed an ended battleground
5668 if (bg->GetStatus() == STATUS_WAIT_LEAVE)
5670
5671 if (m_caster->GetTypeId() == TYPEID_PLAYER /*&& VMAP::VMapFactory::createOrGetVMapMgr()->isLineOfSightCalcEnabled()*/) // pussywizard: optimization (commented)
5672 {
5674 !m_caster->IsOutdoors())
5676
5680 }
5681
5682 // only check at first call, Stealth auras are already removed at second call
5683 // for now, ignore triggered spells
5685 {
5686 bool checkForm = true;
5687 // Ignore form req aura
5689 for (Unit::AuraEffectList::const_iterator i = ignore.begin(); i != ignore.end(); ++i)
5690 {
5691 if (!(*i)->IsAffectedOnSpell(m_spellInfo))
5692 continue;
5693 checkForm = false;
5694 break;
5695 }
5696 if (checkForm)
5697 {
5698 // Cannot be used in this stance/form
5700 if (shapeError != SPELL_CAST_OK)
5701 return shapeError;
5702
5705 }
5706 }
5707
5709 for (Unit::AuraEffectList::const_iterator blockItr = blockSpells.begin(); blockItr != blockSpells.end(); ++blockItr)
5710 if (uint32((*blockItr)->GetMiscValue()) == m_spellInfo->SpellFamilyName)
5712
5713 bool reqCombat = true;
5715 for (Unit::AuraEffectList::const_iterator j = stateAuras.begin(); j != stateAuras.end(); ++j)
5716 {
5717 if ((*j)->IsAffectedOnSpell(m_spellInfo))
5718 {
5719 m_needComboPoints = false;
5720 if ((*j)->GetMiscValue() == 1)
5721 {
5722 reqCombat = false;
5723 break;
5724 }
5725 }
5726 }
5727
5728 // caster state requirements
5729 // not for triggered spells (needed by execute)
5731 {
5736
5737 // Note: spell 62473 requres CasterAuraSpell = triggering spell
5742
5743 if (reqCombat && m_caster->IsInCombat() && !m_spellInfo->CanBeUsedInCombat())
5745 }
5746
5747 // Xinef: exploit protection
5749 {
5751 if (InstanceScript* instanceScript = m_caster->GetInstanceScript())
5752 if (instanceScript->IsEncounterInProgress())
5753 {
5754 if (Group* group = m_caster->ToPlayer()->GetGroup())
5755 for (GroupReference* itr = group->GetFirstMember(); itr != nullptr; itr = itr->next())
5756 if (Player* member = itr->GetSource())
5757 if (member->IsInMap(m_caster))
5758 if (Unit* victim = member->GetVictim())
5759 if (victim->IsInCombat() && m_caster->GetDistance(victim) < m_caster->GetVisibilityRange())
5760 {
5761 m_caster->CombatStart(victim);
5762 victim->AddThreat(m_caster, 1.0f);
5763 break;
5764 }
5766 }
5767 }
5768
5769 // cancel autorepeat spells if cast start when moving
5770 // (not wand currently autorepeat cast delayed to moving stop anyway in spell update code)
5772 {
5773 // skip stuck spell to allow use it in falling case and apply spell limitations at movement
5776 return SPELL_FAILED_MOVING;
5777 }
5778
5779 Vehicle* vehicle = m_caster->GetVehicle();
5781 {
5782 uint16 checkMask = 0;
5783 for (uint8 effIndex = EFFECT_0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
5784 {
5785 SpellEffectInfo const* effInfo = &m_spellInfo->Effects[effIndex];
5787 {
5788 SpellShapeshiftEntry const* shapeShiftEntry = sSpellShapeshiftStore.LookupEntry(effInfo->MiscValue);
5789 if (shapeShiftEntry && (shapeShiftEntry->flags1 & 1) == 0) // unk flag
5790 checkMask |= VEHICLE_SEAT_FLAG_UNCONTROLLED;
5791 break;
5792 }
5793 }
5794
5797
5798 if (!checkMask)
5799 checkMask = VEHICLE_SEAT_FLAG_CAN_ATTACK;
5800
5801 // All creatures should be able to cast as passengers freely, restriction and attribute are only for players
5802 VehicleSeatEntry const* vehicleSeat = vehicle->GetSeatForPassenger(m_caster);
5804 && (vehicleSeat->m_flags & checkMask) != checkMask && m_caster->GetTypeId() == TYPEID_PLAYER)
5806 }
5807
5808 // check spell cast conditions from database
5809 {
5812 ConditionList conditions = sConditionMgr->GetConditionsForNotGroupedEntry(CONDITION_SOURCE_TYPE_SPELL, m_spellInfo->Id);
5813 if (!conditions.empty() && !sConditionMgr->IsObjectMeetToConditions(condInfo, conditions))
5814 {
5815 // mLastFailedCondition can be nullptr if there was an error processing the condition in Condition::Meets (i.e. wrong data for ConditionTarget or others)
5816 if (condInfo.mLastFailedCondition && condInfo.mLastFailedCondition->ErrorType)
5817 {
5821 }
5822 if (!condInfo.mLastFailedCondition || !condInfo.mLastFailedCondition->ConditionTarget)
5825 }
5826 }
5827
5828 // Don't check explicit target for passive spells (workaround) (check should be skipped only for learn case)
5829 // those spells may have incorrect target entries or not filled at all (for example 15332)
5830 // such spells when learned are not targeting anyone using targeting system, they should apply directly to caster instead
5831 // also, such casts shouldn't be sent to client
5832 // Xinef: do not check explicit casts for self cast of triggered spells (eg. reflect case)
5834 {
5835 // Check explicit target for m_originalCaster - todo: get rid of such workarounds
5836 // Xinef: do not check explicit target for triggered spell casted on self with targetflag enemy
5838 {
5840 if (castResult != SPELL_CAST_OK)
5841 return castResult;
5842 }
5843 }
5844
5845 if (Unit* target = m_targets.GetUnitTarget())
5846 {
5847 SpellCastResult castResult = m_spellInfo->CheckTarget(m_caster, target, false);
5848 if (castResult != SPELL_CAST_OK)
5849 return castResult;
5850
5851 if (target != m_caster)
5852 {
5853 // Must be behind the target
5854 if (m_spellInfo->HasAttribute(SPELL_ATTR0_CU_REQ_CASTER_BEHIND_TARGET) && target->HasInArc(static_cast<float>(M_PI), m_caster))
5856
5857 // Target must be facing you
5858 if (m_spellInfo->HasAttribute(SPELL_ATTR0_CU_REQ_TARGET_FACING_CASTER) && !target->HasInArc(static_cast<float>(M_PI), m_caster))
5860
5863 {
5864 bool castedByGameobject = false;
5865 uint32 losChecks = LINEOFSIGHT_ALL_CHECKS;
5867 {
5868 castedByGameobject = m_caster->GetMap()->GetGameObject(m_originalCasterGUID) != nullptr;
5869 }
5870 else if (m_caster->GetEntry() == WORLD_TRIGGER)
5871 {
5872 if (TempSummon* tempSummon = m_caster->ToTempSummon())
5873 {
5874 castedByGameobject = tempSummon->GetSummonerGameObject() != nullptr;
5875 }
5876 }
5877
5878 if (castedByGameobject)
5879 {
5880 // If spell casted by gameobject then ignore M2 models
5881 losChecks &= ~LINEOFSIGHT_CHECK_GOBJECT_M2;
5882 }
5883
5885 {
5887 }
5888 }
5889 }
5890 }
5891
5892 // Check for line of sight for spells with dest
5893 if (m_targets.HasDst())
5894 {
5895 float x, y, z;
5896 m_targets.GetDstPos()->GetPosition(x, y, z);
5897
5900 {
5901 bool castedByGameobject = false;
5902 uint32 losChecks = LINEOFSIGHT_ALL_CHECKS;
5904 {
5905 castedByGameobject = m_caster->GetMap()->GetGameObject(m_originalCasterGUID) != nullptr;
5906 }
5907 else if (m_caster->GetEntry() == WORLD_TRIGGER)
5908 {
5909 if (TempSummon* tempSummon = m_caster->ToTempSummon())
5910 {
5911 castedByGameobject = tempSummon->GetSummonerGameObject() != nullptr;
5912 }
5913 }
5914
5915 if (castedByGameobject)
5916 {
5917 // If spell casted by gameobject then ignore M2 models
5918 losChecks &= ~LINEOFSIGHT_CHECK_GOBJECT_M2;
5919 }
5920
5922 {
5924 }
5925 }
5926 }
5927
5928 // check pet presence
5929 for (int j = 0; j < MAX_SPELL_EFFECTS; ++j)
5930 {
5931 if (m_spellInfo->Effects[j].TargetA.GetTarget() == TARGET_UNIT_PET)
5932 {
5934 {
5935 if (m_triggeredByAuraSpell.spellInfo) // not report pet not existence for triggered spells
5937 else
5938 return SPELL_FAILED_NO_PET;
5939 }
5940 break;
5941 }
5942 }
5943 // Spell casted only on battleground
5945 if (!m_caster->ToPlayer()->InBattleground())
5947
5948 // do not allow spells to be cast in arenas
5949 // - with greater than 10 min CD without SPELL_ATTR4_IGNORE_DEFAULT_ARENA_RESTRICTIONS flag
5950 // - with SPELL_ATTR4_NOT_IN_ARENA_OR_RATED_BATTLEGROUND flag
5953 if (MapEntry const* mapEntry = sMapStore.LookupEntry(m_caster->GetMapId()))
5954 if (mapEntry->IsBattleArena())
5956
5957 // zone check
5959 {
5960 uint32 zone, area;
5961 m_caster->GetZoneAndAreaId(zone, area);
5962
5964 m_caster->GetTypeId() == TYPEID_PLAYER ? m_caster->ToPlayer() : nullptr);
5965 if (locRes != SPELL_CAST_OK)
5966 return locRes;
5967 }
5968
5969 // not let players cast spells at mount (and let do it to creatures)
5972 {
5973 if (m_caster->IsInFlight())
5975 else
5977 }
5978
5979 SpellCastResult castResult = SPELL_CAST_OK;
5980
5981 // always (except passive spells) check items (focus object can be required for any type casts)
5982 if (!m_spellInfo->IsPassive())
5983 {
5984 // spell focus needs to be checked not only for players! there are vehicle spells that require spell focus
5985 castResult = CheckSpellFocus();
5986 if (castResult != SPELL_CAST_OK)
5987 return castResult;
5988
5989 castResult = CheckItems();
5990 if (castResult != SPELL_CAST_OK)
5991 return castResult;
5992 }
5993
5994 // Triggered spells also have range check
5996 castResult = CheckRange(strict);
5997 if (castResult != SPELL_CAST_OK)
5998 return castResult;
5999
6001 {
6002 castResult = CheckPower();
6003 if (castResult != SPELL_CAST_OK)
6004 return castResult;
6005 }
6006
6007 // xinef: do not skip triggered spells if they posses prevention type (eg. Bladestorm vs Hand of Protection)
6009 {
6011 if (castResult != SPELL_CAST_OK)
6012 return castResult;
6013
6014 // 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).
6016 {
6018 for (SpellImmuneList::const_iterator itr = mechanicList.begin(); itr != mechanicList.end(); ++itr)
6019 if (itr->type == m_spellInfo->Mechanic)
6021 }
6022 }
6023
6024 // script hook
6025 castResult = CallScriptCheckCastHandlers();
6026 if (castResult != SPELL_CAST_OK)
6027 return castResult;
6028
6029 bool hasDispellableAura = false;
6030 bool hasNonDispelEffect = false;
6031 uint32 dispelMask = 0;
6032 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
6033 if (m_spellInfo->Effects[i].Effect == SPELL_EFFECT_DISPEL)
6034 {
6036 {
6037 hasDispellableAura = true;
6038 break;
6039 }
6040
6041 dispelMask |= SpellInfo::GetDispelMask(DispelType(m_spellInfo->Effects[i].MiscValue));
6042 }
6043 else if (m_spellInfo->Effects[i].IsEffect())
6044 {
6045 hasNonDispelEffect = true;
6046 break;
6047 }
6048
6049 if (!hasNonDispelEffect && !hasDispellableAura && dispelMask && !IsTriggered())
6050 {
6051 if (Unit* target = m_targets.GetUnitTarget())
6052 {
6053 // Xinef: do not allow to cast on hostile targets in sanctuary
6054 if (!m_caster->IsFriendlyTo(target))
6055 {
6056 if (m_caster->IsInSanctuary() || target->IsInSanctuary())
6057 {
6058 // Xinef: fix for duels
6059 Player* player = m_caster->ToPlayer();
6060 if (!player || !player->duel || target != player->duel->Opponent)
6062 }
6063 }
6064
6065 DispelChargesList dispelList;
6066 target->GetDispellableAuraList(m_caster, dispelMask, dispelList);
6067 if (dispelList.empty())
6069 }
6070 }
6071
6072 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
6073 {
6074 // for effects of spells that have only one target
6075 switch (m_spellInfo->Effects[i].Effect)
6076 {
6077 case SPELL_EFFECT_DUMMY:
6078 {
6080 {
6081 // Raise Ally
6082 if( m_spellInfo->Id == 61999 )
6083 {
6084 Unit* target = m_targets.GetUnitTarget();
6085 if (!target)
6087
6088 if (target->IsAlive()) // not discovered attributeEx5?
6090 }
6091 }
6092 break;
6093 }
6095 {
6098
6099 if (m_spellInfo->Effects[i].TargetA.GetTarget() != TARGET_UNIT_PET)
6100 break;
6101
6102 Pet* pet = m_caster->ToPlayer()->GetPet();
6103
6104 if (!pet)
6105 return SPELL_FAILED_NO_PET;
6106
6107 SpellInfo const* learn_spellproto = sSpellMgr->GetSpellInfo(m_spellInfo->Effects[i].TriggerSpell);
6108
6109 if (!learn_spellproto)
6111
6112 if (m_spellInfo->SpellLevel > pet->GetLevel())
6113 return SPELL_FAILED_LOWLEVEL;
6114
6115 break;
6116 }
6118 {
6119 // check target only for unit target case
6121 {
6124
6125 Pet* pet = unitTarget->ToPet();
6126 if (!pet || pet->GetOwner() != m_caster)
6128
6129 SpellInfo const* learn_spellproto = sSpellMgr->GetSpellInfo(m_spellInfo->Effects[i].TriggerSpell);
6130
6131 if (!learn_spellproto)
6133
6134 if (m_spellInfo->SpellLevel > pet->GetLevel())
6135 return SPELL_FAILED_LOWLEVEL;
6136 }
6137 break;
6138 }
6140 {
6141 uint32 glyphId = m_spellInfo->Effects[i].MiscValue;
6142 if (GlyphPropertiesEntry const* gp = sGlyphPropertiesStore.LookupEntry(glyphId))
6143 if (m_caster->HasAura(gp->SpellId))
6145 break;
6146 }
6148 {
6151
6152 Item* foodItem = m_targets.GetItemTarget();
6153 if (!foodItem)
6155
6156 Pet* pet = m_caster->ToPlayer()->GetPet();
6157
6158 if (!pet)
6159 return SPELL_FAILED_NO_PET;
6160
6161 if (!pet->HaveInDiet(foodItem->GetTemplate()))
6163
6164 if (!pet->GetCurrentFoodBenefitLevel(foodItem->GetTemplate()->ItemLevel))
6166
6167 if (m_caster->IsInCombat() || pet->IsInCombat())
6169
6170 break;
6171 }
6174 {
6175 // Can be area effect, Check only for players and not check if target - caster (spell can have multiply drain/burn effects)
6177 if (Unit* target = m_targets.GetUnitTarget())
6178 if (target != m_caster && target->getPowerType() != Powers(m_spellInfo->Effects[i].MiscValue))
6180 break;
6181 }
6183 {
6185 {
6187 }
6188
6190 {
6191 // Warbringer - can't be handled in proc system - should be done before checkcast root check and charge effect process
6192 if (strict && m_caster->IsScriptOverriden(m_spellInfo, 6953))
6194 }
6196 {
6197 // Exception for Master's Call
6198 if (m_spellInfo->Id != 54216)
6199 {
6200 return SPELL_FAILED_ROOTED;
6201 }
6202 }
6204 if (Unit* target = m_targets.GetUnitTarget())
6205 if (!target->IsAlive())
6207 // Xinef: Pass only explicit unit target spells
6208 // pussywizard:
6210 {
6211 Unit* target = m_targets.GetUnitTarget();
6212 if (!target)
6214
6215 // first we must check to see if the target is in LoS. A path can usually be built but LoS matters for charge spells
6216 if (!target->IsWithinLOSInMap(m_caster)) //Do full LoS/Path check. Don't exclude m2
6218
6219 float objSize = target->GetCombatReach();
6220 float range = m_spellInfo->GetMaxRange(true, m_caster, this) * 1.5f + objSize; // can't be overly strict
6221
6222 m_preGeneratedPath = std::make_unique<PathGenerator>(m_caster);
6223 m_preGeneratedPath->SetPathLengthLimit(range);
6224
6225 // first try with raycast, if it fails fall back to normal path
6226 bool result = m_preGeneratedPath->CalculatePath(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), false);
6227 if (m_preGeneratedPath->GetPathType() & PATHFIND_SHORT)
6228 return SPELL_FAILED_NOPATH;
6229 else if (!result || m_preGeneratedPath->GetPathType() & (PATHFIND_NOPATH | PATHFIND_INCOMPLETE))
6230 return SPELL_FAILED_NOPATH;
6231 else if (m_preGeneratedPath->IsInvalidDestinationZ(target)) // Check position z, if not in a straight line
6232 return SPELL_FAILED_NOPATH;
6233
6234 m_preGeneratedPath->ShortenPathUntilDist(G3D::Vector3(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ()), objSize); // move back
6235 }
6236 if (Player* player = m_caster->ToPlayer())
6237 player->SetCanTeleport(true);
6238 break;
6239 }
6241 {
6244
6247
6248 Creature* creature = m_targets.GetUnitTarget()->ToCreature();
6249 if (!creature->IsCritter() && !creature->loot.isLooted())
6251
6252 uint32 skill = creature->GetCreatureTemplate()->GetRequiredLootSkill();
6253
6254 int32 skillValue = m_caster->ToPlayer()->GetSkillValue(skill);
6255 int32 TargetLevel = m_targets.GetUnitTarget()->GetLevel();
6256 int32 ReqValue = (skillValue < 100 ? (TargetLevel - 10) * 10 : TargetLevel * 5);
6257 if (ReqValue > skillValue)
6259
6260 break;
6261 }
6263 {
6264 if (m_spellInfo->Effects[i].TargetA.GetTarget() != TARGET_GAMEOBJECT_TARGET &&
6265 m_spellInfo->Effects[i].TargetA.GetTarget() != TARGET_GAMEOBJECT_ITEM_TARGET)
6266 break;
6267
6268 if (m_caster->GetTypeId() != TYPEID_PLAYER // only players can open locks, gather etc.
6269 // we need a go target in case of TARGET_GAMEOBJECT_TARGET
6270 || (m_spellInfo->Effects[i].TargetA.GetTarget() == TARGET_GAMEOBJECT_TARGET && !m_targets.GetGOTarget()))
6272
6273 Item* pTempItem = nullptr;
6275 {
6276 if (TradeData* pTrade = m_caster->ToPlayer()->GetTradeData())
6277 pTempItem = pTrade->GetTraderData()->GetItem(TradeSlots(m_targets.GetItemTargetGUID().GetRawValue()));
6278 }
6281
6282 // we need a go target, or an openable item target in case of TARGET_GAMEOBJECT_ITEM_TARGET
6283 if (m_spellInfo->Effects[i].TargetA.GetTarget() == TARGET_GAMEOBJECT_ITEM_TARGET &&
6285 (!pTempItem || !pTempItem->GetTemplate()->LockID || !pTempItem->IsLocked()))
6287
6288 // We must also ensure the gameobject we are opening is still closed by the time the spell finishes.
6289 if (GameObject* go = m_targets.GetGOTarget())
6290 {
6291 if (go->GetGoType() == GAMEOBJECT_TYPE_DOOR && go->GetGoState() != GO_STATE_READY)
6292 {
6294 }
6295 }
6296 if (m_spellInfo->Id != 1842 || (m_targets.GetGOTarget() &&
6298 {
6299 if (m_targets.GetGOTarget() && m_targets.GetGOTarget()->GetEntry() == 179697)
6300 {
6301 if (!m_caster->ToPlayer()->CanUseBattlegroundObject(nullptr))
6303 }
6304 else if (m_caster->ToPlayer()->InBattleground() && // In Battleground players can use only flags and banners, or Gurubashi chest
6307 }
6308
6309 // get the lock entry
6310 uint32 lockId = 0;
6311 if (GameObject* go = m_targets.GetGOTarget())
6312 {
6313 lockId = go->GetGOInfo()->GetLockId();
6314 if (!lockId)
6316 }
6317 else if (Item* itm = m_targets.GetItemTarget())
6318 lockId = itm->GetTemplate()->LockID;
6319
6320 SkillType skillId = SKILL_NONE;
6321 int32 reqSkillValue = 0;
6322 int32 skillValue = 0;
6323
6324 // check lock compatibility
6325 SpellCastResult res = CanOpenLock(i, lockId, skillId, reqSkillValue, skillValue);
6326 if (res != SPELL_CAST_OK)
6327 return res;
6328
6329 // chance for fail at lockpicking attempt
6330 // second check prevent fail at rechecks
6331 if (skillId != SKILL_NONE && (!m_selfContainer || ((*m_selfContainer) != this)))
6332 {
6333 // chance for failure in orange lockpick
6334 if (skillId == SKILL_LOCKPICKING && reqSkillValue > irand(skillValue - 25, skillValue + 37))
6335 {
6337 }
6338 }
6339 break;
6340 }
6342 {
6343 Unit* unitCaster = m_caster->ToUnit();
6344 if (!unitCaster)
6345 {
6347 }
6348
6349 Creature* pet = unitCaster->GetGuardianPet();
6350 if (pet)
6351 {
6352 if (pet->IsAlive())
6353 {
6355 }
6356 }
6357 else if (Player* playerCaster = m_caster->ToPlayer())
6358 {
6359 PetStable& petStable = playerCaster->GetOrInitPetStable();
6360 if (!petStable.CurrentPet && petStable.UnslottedPets.empty())
6361 {
6362 return SPELL_FAILED_NO_PET;
6363 }
6364 }
6365
6366 break;
6367 }
6368 // This is generic summon effect
6370 {
6371 SummonPropertiesEntry const* SummonProperties = sSummonPropertiesStore.LookupEntry(m_spellInfo->Effects[i].MiscValueB);
6372 if (!SummonProperties || m_spellInfo->HasAttribute(SPELL_ATTR1_DISMISS_PET_FIRST))
6373 break;
6374 switch (SummonProperties->Category)
6375 {
6377 if (m_caster->GetPetGUID())
6379 [[fallthrough]];
6381 if (m_caster->GetCharmGUID())
6383 break;
6384 }
6385 break;
6386 }
6388 {
6390 {
6395 }
6396 break;
6397 }
6399 {
6400 Unit* unitCaster = m_caster->ToUnit();
6401 if (!unitCaster)
6403
6405 {
6406 if (m_caster->GetPetGUID())
6408 if (m_caster->GetCharmGUID())
6410 }
6411
6412 if (m_caster->GetTypeId() == TYPEID_PLAYER && m_caster->getClass() == CLASS_WARLOCK && strict)
6413 if (Pet* pet = m_caster->ToPlayer()->GetPet())
6414 pet->CastSpell(pet, 32752, true, nullptr, nullptr, pet->GetGUID()); //starting cast, trigger pet stun (cast by pet so it doesn't attack player)
6415
6416 Player* playerCaster = unitCaster->ToPlayer();
6417 if (playerCaster && playerCaster->GetPetStable())
6418 {
6419 std::pair<PetStable::PetInfo const*, PetSaveMode> info = Pet::GetLoadPetInfo(*playerCaster->GetPetStable(), m_spellInfo->Effects[i].MiscValue, 0, false);
6420 if (info.first)
6421 {
6422 if (info.first->Type == HUNTER_PET)
6423 {
6424 if (!info.first->Health)
6425 {
6426 playerCaster->SendTameFailure(PET_TAME_DEAD);
6428 }
6429
6430 CreatureTemplate const* creatureInfo = sObjectMgr->GetCreatureTemplate(info.first->CreatureId);
6431 if (!creatureInfo || !creatureInfo->IsTameable(playerCaster->CanTameExoticPets()))
6432 {
6433 // if problem in exotic pet
6434 if (creatureInfo && creatureInfo->IsTameable(true))
6436 else
6438
6440 }
6441 }
6442 }
6443 else if (!m_spellInfo->Effects[i].MiscValue) // when miscvalue is present it is allowed to create new pets
6444 {
6447 }
6448 }
6449 break;
6450 }
6452 {
6455 if (!m_caster->GetTarget())
6457
6459 if (!target || m_caster->ToPlayer() == target || (!target->IsInSameRaidWith(m_caster->ToPlayer()) && m_spellInfo->Id != 48955)) // refer-a-friend spell
6461
6462 // Xinef: Implement summon pending error
6463 if (target->GetSummonExpireTimer() > GameTime::GetGameTime().count())
6465
6466 // check if our map is dungeon
6467 MapEntry const* map = sMapStore.LookupEntry(m_caster->GetMapId());
6468 if (map->IsDungeon())
6469 {
6470 uint32 mapId = m_caster->GetMap()->GetId();
6471 Difficulty difficulty = m_caster->GetMap()->GetDifficulty();
6472 /*if (map->IsRaid())
6473 if (InstancePlayerBind* targetBind = target->GetBoundInstance(mapId, difficulty))
6474 if (targetBind->perm && targetBind != m_caster->ToPlayer()->GetBoundInstance(mapId, difficulty))
6475 return SPELL_FAILED_TARGET_LOCKED_TO_RAID_INSTANCE;*/
6476
6477 InstanceTemplate const* instance = sObjectMgr->GetInstanceTemplate(mapId);
6478 if (!instance)
6480 if (!target->Satisfy(sObjectMgr->GetAccessRequirement(mapId, difficulty), mapId))
6482 }
6483 break;
6484 }
6485 // RETURN HERE
6487 {
6490
6491 Player* playerCaster = m_caster->ToPlayer();
6492 //
6493 if (!(playerCaster->GetTarget()))
6495
6497
6498 if (!target ||
6499 !(target->GetSession()->GetRecruiterId() == playerCaster->GetSession()->GetAccountId() || target->GetSession()->GetAccountId() == playerCaster->GetSession()->GetRecruiterId()))
6501
6502 // Xinef: Implement summon pending error
6503 if (target->GetSummonExpireTimer() > GameTime::GetGameTime().count())
6505
6506 break;
6507 }
6508 case SPELL_EFFECT_LEAP:
6510 {
6511 //Do not allow to cast it before BG starts.
6513 if (Battleground const* bg = m_caster->ToPlayer()->GetBattleground())
6514 if (bg->GetStatus() != STATUS_IN_PROGRESS)
6516 break;
6517 }
6519 {
6522
6523 bool found = false;
6525 for(Unit::VisibleAuraMap::const_iterator itr = visibleAuras->begin(); itr != visibleAuras->end(); ++itr)
6526 {
6527 if( itr->second->GetBase()->IsPassive() )
6528 continue;
6529
6530 if( !itr->second->IsPositive() )
6531 continue;
6532
6533 found = true;
6534 break;
6535 }
6536
6537 if( !found )
6539
6540 break;
6541 }
6543 {
6545 {
6547 return SPELL_FAILED_ROOTED;
6548 else
6550 }
6551 break;
6552 }
6553 // xinef: do not allow to use leaps while rooted
6554 case SPELL_EFFECT_JUMP:
6556 {
6558 return SPELL_FAILED_ROOTED;
6559 break;
6560 }
6562 if (!sScriptMgr->CanSelectSpecTalent(this))
6564 // can't change during already started arena/battleground
6566 if (Battleground const* bg = m_caster->ToPlayer()->GetBattleground())
6567 if (bg->GetStatus() == STATUS_IN_PROGRESS)
6569 break;
6570 default:
6571 break;
6572 }
6573 }
6574
6575 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
6576 {
6577 switch (m_spellInfo->Effects[i].ApplyAuraName)
6578 {
6579 case SPELL_AURA_DUMMY:
6580 break;
6582 {
6584 return SPELL_FAILED_NO_PET;
6585
6586 Pet* pet = m_caster->ToPlayer()->GetPet();
6587 if (!pet)
6588 return SPELL_FAILED_NO_PET;
6589
6590 if (pet->GetCharmerGUID())
6591 return SPELL_FAILED_CHARMED;
6592 break;
6593 }
6597 {
6598 if (m_caster->GetCharmerGUID())
6599 return SPELL_FAILED_CHARMED;
6600
6601 // Xinef: allow SPELL_AURA_MOD_POSSESS to posses target if caster has some pet
6603 {
6604 if (m_caster->GetPetGUID())
6606
6607 if (m_caster->GetCharmGUID())
6609 }
6610 else if (m_spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_MOD_POSSESS)
6611 {
6612 if (m_caster->GetCharmGUID())
6614 }
6615
6616 if (Unit* target = m_targets.GetUnitTarget())
6617 {
6618 if (target->GetTypeId() == TYPEID_UNIT && target->ToCreature()->IsVehicle())
6620
6621 if (target->IsMounted())
6623
6624 if (target->GetCharmerGUID())
6625 return SPELL_FAILED_CHARMED;
6626
6627 if (target->GetOwnerGUID() && target->GetOwnerGUID().IsPlayer())
6629
6630 if (target->IsPet() && (!target->GetOwner() || target->GetOwner()->ToPlayer()))
6632
6633 int32 damage = CalculateSpellDamage(i, target);
6634 if (damage && int32(target->GetLevel()) > damage)
6636 }
6637
6638 break;
6639 }
6640 case SPELL_AURA_MOUNTED:
6641 {
6642 // Xinef: disallow casting in water for mounts not increasing water movement Speed
6645
6646 // Ignore map check if spell have AreaId. AreaId already checked and this prevent special mount spells
6647 bool allowMount = !m_caster->GetMap()->IsDungeon() || m_caster->GetMap()->IsBattlegroundOrArena();
6648 InstanceTemplate const* it = sObjectMgr->GetInstanceTemplate(m_caster->GetMapId());
6649 if (it)
6650 allowMount = it->AllowMount;
6651 if (m_caster->GetTypeId() == TYPEID_PLAYER && !allowMount && !m_spellInfo->AreaGroupId)
6653
6656
6657 // xinef: dont allow to cast mounts in specific transforms
6658 if (m_caster->getTransForm())
6659 if (SpellInfo const* transformSpellInfo = sSpellMgr->GetSpellInfo(m_caster->getTransForm()))
6660 if (transformSpellInfo->HasAttribute(SPELL_ATTR0_NO_IMMUNITIES) &&
6661 !transformSpellInfo->HasAttribute(SpellAttr0(SPELL_ATTR0_ALLOW_WHILE_MOUNTED | SPELL_ATTR0_AURA_IS_DEBUFF)))
6663
6664 break;
6665 }
6667 {
6668 if (!m_targets.GetUnitTarget())
6670
6671 // can be casted at non-friendly unit or own pet/charm
6674
6675 break;
6676 }
6677 case SPELL_AURA_FLY:
6679 {
6680 // Xinef: added water check
6681 if (m_caster->IsInWater())
6683
6684 // not allow cast fly spells if not have req. skills (all spells is self target)
6685 // allow always ghost flight spells
6687 {
6688 Battlefield* Bf = sBattlefieldMgr->GetBattlefieldToZoneId(m_originalCaster->GetZoneId());
6689 if (AreaTableEntry const* pArea = sAreaTableStore.LookupEntry(m_originalCaster->GetAreaId()))
6690 if ((pArea->flags & AREA_FLAG_NO_FLY_ZONE) || (Bf && !Bf->CanFlyIn()))
6691 return SPELL_FAILED_NOT_HERE;
6692 }
6693 break;
6694 }
6696 {
6697 if (m_spellInfo->Effects[i].IsTargetingArea())
6698 break;
6699
6701 break;
6702
6703 if (!m_targets.GetUnitTarget())
6705
6708
6709 break;
6710 }
6711 case SPELL_AURA_HOVER:
6712 {
6714 {
6716 }
6717 break;
6718 }
6720 {
6721 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.
6722 {
6724 }
6725 break;
6726 }
6727 default:
6728 break;
6729 }
6730 }
6731
6732 // check trade slot case (last, for allow catch any another cast problems)
6734 {
6735 if (m_CastItem)
6737
6740
6741 TradeData* my_trade = m_caster->ToPlayer()->GetTradeData();
6742
6743 if (!my_trade)
6745
6747 if (slot != TRADE_SLOT_NONTRADED)
6749
6750 if (!IsTriggered())
6751 if (my_trade->GetSpell())
6753 }
6754
6755 // check if caster has at least 1 combo point on target for spells that require combo points
6757 {
6759 {
6761 {
6763 }
6764 }
6765 else
6766 {
6767 if (!m_caster->GetComboPoints())
6768 {
6770 }
6771 }
6772 }
6773
6774 // xinef: check relic cooldown
6778
6779 // all ok
6780 return SPELL_CAST_OK;
6781}
constexpr auto IN_MILLISECONDS
Definition: Common.h:62
constexpr auto MINUTE
Definition: Common.h:56
std::int32_t int32
Definition: Define.h:104
std::uint16_t uint16
Definition: Define.h:109
int32 irand(int32 min, int32 max)
Definition: Random.cpp:37
#define SPECTATOR_SPELL_BINDSIGHT
Definition: ArenaSpectator.h:38
#define sBattlefieldMgr
Definition: BattlefieldMgr.h:77
@ STATUS_WAIT_LEAVE
Definition: Battleground.h:198
@ STATUS_IN_PROGRESS
Definition: Battleground.h:197
#define sConditionMgr
Definition: ConditionMgr.h:289
@ CONDITION_SOURCE_TYPE_SPELL
Definition: ConditionMgr.h:139
std::list< Condition * > ConditionList
Definition: ConditionMgr.h:236
DBCStorage< SpellShapeshiftEntry > sSpellShapeshiftStore(SpellShapeshiftfmt)
DBCStorage< SummonPropertiesEntry > sSummonPropertiesStore(SummonPropertiesfmt)
DBCStorage< MapEntry > sMapStore(MapEntryfmt)
DBCStorage< GlyphPropertiesEntry > sGlyphPropertiesStore(GlyphPropertiesfmt)
DBCStorage< AreaTableEntry > sAreaTableStore(AreaTableEntryfmt)
@ GO_STATE_READY
Definition: GameObjectData.h:691
@ INVTYPE_RELIC
Definition: ItemTemplate.h:293
@ HUNTER_PET
Definition: PetDefines.h:32
@ PLAYER_ALLOW_ONLY_ABILITY
Definition: Player.h:498
TradeSlots
Definition: TradeData.h:28
@ TRADE_SLOT_NONTRADED
Definition: TradeData.h:31
@ MOVEMENTFLAG_FALLING_FAR
Definition: Unit.h:565
#define WORLD_TRIGGER
Definition: Unit.h:36
@ UNIT_FLAG2_ALLOW_CHEAT_SPELLS
Definition: Unit.h:505
std::list< std::pair< Aura *, uint8 > > DispelChargesList
Definition: Unit.h:241
@ UNIT_STATE_ROOT
Definition: Unit.h:335
@ UNIT_STATE_CHARGING
Definition: Unit.h:342
@ UNIT_FLAG_SKINNABLE
Definition: Unit.h:474
LineOfSightChecks
Definition: Map.h:190
@ LINEOFSIGHT_ALL_CHECKS
Definition: Map.h:197
@ PATHFIND_NOPATH
Definition: PathGenerator.h:51
@ PATHFIND_SHORT
Definition: PathGenerator.h:53
@ PATHFIND_INCOMPLETE
Definition: PathGenerator.h:50
@ 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_MOD_INCREASE_SWIM_SPEED
Definition: SpellAuraDefines.h:121
@ 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
@ SPELL_FLAG_REDIRECTED
Definition: Spell.h:83
@ AURA_INTERRUPT_FLAG_NOT_SEATED
Definition: SpellDefines.h:62
@ AURA_INTERRUPT_FLAG_MOUNT
Definition: SpellDefines.h:61
@ TRIGGERED_IGNORE_SPELL_AND_CATEGORY_CD
Will ignore GCD.
Definition: SpellDefines.h:133
@ TRIGGERED_IGNORE_CASTER_AURASTATE
Will ignore shapeshift checks.
Definition: SpellDefines.h:143
@ TRIGGERED_IGNORE_CASTER_MOUNTED_OR_ON_VEHICLE
Will ignore caster aura states including combat requirements and death state.
Definition: SpellDefines.h:144
@ TRIGGERED_IGNORE_SHAPESHIFT
Will not adjust facing to target (if any)
Definition: SpellDefines.h:142
@ TRIGGERED_IGNORE_GCD
Not triggered.
Definition: SpellDefines.h:132
@ TRIGGERED_IGNORE_CASTER_AURAS
Will ignore mounted/on vehicle restrictions.
Definition: SpellDefines.h:145
std::vector< SpellImmune > SpellImmuneList
Definition: SpellDefines.h:179
@ 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
@ VEHICLE_SEAT_FLAG_CAN_CAST_MOUNT_SPELL
Definition: DBCEnums.h:461
@ VEHICLE_SEAT_FLAG_UNCONTROLLED
Definition: DBCEnums.h:462
@ VEHICLE_SEAT_FLAG_CAN_ATTACK
Definition: DBCEnums.h:463
Difficulty
Definition: DBCEnums.h:271
@ AREA_FLAG_NO_FLY_ZONE
Definition: DBCEnums.h:267
@ GAMEOBJECT_TYPE_TRAP
Definition: SharedDefines.h:1538
@ GAMEOBJECT_TYPE_DOOR
Definition: SharedDefines.h:1532
Powers
Definition: SharedDefines.h:240
@ POWER_MANA
Definition: SharedDefines.h:241
@ SPELL_ATTR7_DEBUG_SPELL
Definition: SharedDefines.h:616
@ SPELL_EFFECT_DUMMY
Definition: SharedDefines.h:753
@ SPELL_EFFECT_LEAP
Definition: SharedDefines.h:779
@ SPELL_EFFECT_POWER_BURN
Definition: SharedDefines.h:812
@ SPELL_EFFECT_STUCK
Definition: SharedDefines.h:834
@ SPELL_EFFECT_SUMMON_RAF_FRIEND
Definition: SharedDefines.h:902
@ SPELL_EFFECT_APPLY_GLYPH
Definition: SharedDefines.h:824
@ SPELL_EFFECT_FEED_PET
Definition: SharedDefines.h:851
@ SPELL_EFFECT_SUMMON_PLAYER
Definition: SharedDefines.h:835
@ SPELL_EFFECT_JUMP_DEST
Definition: SharedDefines.h:792
@ SPELL_EFFECT_TELEPORT_UNITS_FACE_CASTER
Definition: SharedDefines.h:793
@ SPELL_EFFECT_RESURRECT_PET
Definition: SharedDefines.h:859
@ SPELL_EFFECT_LEAP_BACK
Definition: SharedDefines.h:888
@ SPELL_EFFECT_SUMMON
Definition: SharedDefines.h:778
@ SPELL_EFFECT_POWER_DRAIN
Definition: SharedDefines.h:758
@ SPELL_EFFECT_RESURRECT
Definition: SharedDefines.h:768
@ SPELL_EFFECT_CHARGE
Definition: SharedDefines.h:846
@ SPELL_EFFECT_RESURRECT_NEW
Definition: SharedDefines.h:863
@ SPELL_EFFECT_TALENT_SPEC_SELECT
Definition: SharedDefines.h:912
@ SPELL_EFFECT_LEARN_SPELL
Definition: SharedDefines.h:786
@ SPELL_EFFECT_JUMP
Definition: SharedDefines.h:791
@ SPELL_EFFECT_SKINNING
Definition: SharedDefines.h:845
@ SPELL_EFFECT_CREATE_TAMED_PET
Definition: SharedDefines.h:903
@ SPELL_EFFECT_OPEN_LOCK
Definition: SharedDefines.h:783
@ SPELL_EFFECT_STEAL_BENEFICIAL_BUFF
Definition: SharedDefines.h:876
@ SPELL_EFFECT_LEARN_PET_SPELL
Definition: SharedDefines.h:807
@ SPELL_PREVENTION_TYPE_NONE
Definition: SharedDefines.h:1525
@ SPELL_ATTR5_ALWAYS_AOE_LINE_OF_SIGHT
Definition: SharedDefines.h:565
@ TARGET_UNIT_PET
Definition: SharedDefines.h:1386
@ TARGET_GAMEOBJECT_TARGET
Definition: SharedDefines.h:1399
@ SPELL_ATTR2_IGNORE_LINE_OF_SIGHT
Definition: SharedDefines.h:430
@ SPELL_ATTR1_INITIATE_COMBAT
Definition: SharedDefines.h:400
@ SPELL_ATTR3_ONLY_BATTLEGROUNDS
Definition: SharedDefines.h:476
@ PET_TAME_NOPET_AVAILABLE
Definition: SharedDefines.h:3655
@ PET_TAME_DEAD
Definition: SharedDefines.h:3658
@ PET_TAME_CANT_CONTROL_EXOTIC
Definition: SharedDefines.h:3660
@ CLASS_WARLOCK
Definition: SharedDefines.h:121
@ IMMUNITY_MECHANIC
Definition: SharedDefines.h:1371
@ SPELLFAMILY_WARRIOR
Definition: SharedDefines.h:3504
@ SPELLFAMILY_DEATHKNIGHT
Definition: SharedDefines.h:3515
SpellCustomErrors
Definition: SharedDefines.h:1114
@ SPELL_CUSTOM_ERROR_GM_ONLY
Definition: SharedDefines.h:1180
SpellAttr0
Definition: SharedDefines.h:353
@ SPELL_ATTR0_ONLY_INDOORS
Definition: SharedDefines.h:368
@ SPELL_ATTR0_AURA_IS_DEBUFF
Definition: SharedDefines.h:380
@ SPELL_ATTR0_ONLY_OUTDOORS
Definition: SharedDefines.h:369
@ SPELL_ATTR0_ALLOW_WHILE_MOUNTED
Definition: SharedDefines.h:378
@ SPELL_ATTR0_PASSIVE
Definition: SharedDefines.h:360
@ SPELL_ATTR0_ALLOW_CAST_WHILE_DEAD
Definition: SharedDefines.h:377
@ SPELL_ATTR0_ONLY_STEALTHED
Definition: SharedDefines.h:371
AuraStateType
Definition: SharedDefines.h:1260
DispelType
Definition: SharedDefines.h:1343
@ SPELL_FAILED_TARGET_NOT_LOOTED
Definition: SharedDefines.h:1042
@ SPELL_FAILED_NOT_INFRONT
Definition: SharedDefines.h:982
@ SPELL_FAILED_MOVING
Definition: SharedDefines.h:972
@ SPELL_FAILED_NOT_MOUNTED
Definition: SharedDefines.h:985
@ SPELL_FAILED_AFFECTING_COMBAT
Definition: SharedDefines.h:922
@ SPELL_FAILED_CASTER_AURASTATE
Definition: SharedDefines.h:943
@ SPELL_FAILED_NOTHING_TO_DISPEL
Definition: SharedDefines.h:1007
@ SPELL_FAILED_NOT_KNOWN
Definition: SharedDefines.h:984
@ SPELL_FAILED_FOOD_LOWLEVEL
Definition: SharedDefines.h:956
@ SPELL_FAILED_NOT_HERE
Definition: SharedDefines.h:981
@ SPELL_FAILED_ROOTED
Definition: SharedDefines.h:1024
@ SPELL_FAILED_TARGET_NOT_DEAD
Definition: SharedDefines.h:1040
@ SPELL_FAILED_WRONG_PET_FOOD
Definition: SharedDefines.h:1056
@ SPELL_FAILED_CUSTOM_ERROR
Definition: SharedDefines.h:1093
@ SPELL_FAILED_SUMMON_PENDING
Definition: SharedDefines.h:1104
@ SPELL_FAILED_DAMAGE_IMMUNE
Definition: SharedDefines.h:1067
@ SPELL_FAILED_BAD_IMPLICIT_TARGETS
Definition: SharedDefines.h:932
@ SPELL_FAILED_TRY_AGAIN
Definition: SharedDefines.h:1053
@ SPELL_FAILED_NO_COMBO_POINTS
Definition: SharedDefines.h:999
@ SPELL_FAILED_ALREADY_HAVE_SUMMON
Definition: SharedDefines.h:928
@ SPELL_FAILED_ALREADY_OPEN
Definition: SharedDefines.h:929
@ SPELL_FAILED_NOT_TRADING
Definition: SharedDefines.h:992
@ SPELL_FAILED_NOTHING_TO_STEAL
Definition: SharedDefines.h:1008
@ SPELL_FAILED_NO_MOUNTS_ALLOWED
Definition: SharedDefines.h:1004
@ SPELL_FAILED_NOT_IN_BATTLEGROUND
Definition: SharedDefines.h:1087
@ SPELL_FAILED_NOT_BEHIND
Definition: SharedDefines.h:978
@ SPELL_FAILED_ALREADY_HAVE_CHARM
Definition: SharedDefines.h:927
@ SPELL_FAILED_TARGET_NOT_IN_INSTANCE
Definition: SharedDefines.h:1058
@ SPELL_FAILED_HIGHLEVEL
Definition: SharedDefines.h:957
@ SPELL_FAILED_LOWLEVEL
Definition: SharedDefines.h:969
@ SPELL_FAILED_NOT_READY
Definition: SharedDefines.h:988
@ SPELL_FAILED_ONLY_BATTLEGROUNDS
Definition: SharedDefines.h:1063
@ SPELL_FAILED_NOT_IN_ARENA
Definition: SharedDefines.h:1072
@ SPELL_FAILED_ITEM_ALREADY_ENCHANTED
Definition: SharedDefines.h:963
@ SPELL_FAILED_ONLY_STEALTHED
Definition: SharedDefines.h:1016
@ SPELL_FAILED_TARGET_IS_PLAYER_CONTROLLED
Definition: SharedDefines.h:1039
@ SPELL_FAILED_ONLY_ABOVEWATER
Definition: SharedDefines.h:1009
@ SPELL_FAILED_CANT_BE_CHARMED
Definition: SharedDefines.h:934
@ SPELL_FAILED_CASTER_DEAD
Definition: SharedDefines.h:944
@ SPELL_FAILED_NOT_ON_MOUNTED
Definition: SharedDefines.h:1076
@ SPELL_FAILED_ITEM_ENCHANT_TRADE_WINDOW
Definition: SharedDefines.h:1103
@ SPELL_FAILED_TARGET_CANNOT_BE_RESURRECTED
Definition: SharedDefines.h:1107
@ SPELL_FAILED_TARGET_UNSKINNABLE
Definition: SharedDefines.h:1047
@ SPELL_FAILED_NOT_SHAPESHIFT
Definition: SharedDefines.h:989
@ SPELL_FAILED_UNIQUE_GLYPH
Definition: SharedDefines.h:1097
@ SPELL_FAILED_ONLY_OUTDOORS
Definition: SharedDefines.h:1014
@ SPELL_FAILED_CHARMED
Definition: SharedDefines.h:945
@ SPELL_FAILED_LINE_OF_SIGHT
Definition: SharedDefines.h:968
@ SPELL_FAILED_SPELL_IN_PROGRESS
Definition: SharedDefines.h:1026
@ SPELL_FAILED_NO_PET
Definition: SharedDefines.h:1005
@ SPELL_FAILED_NOPATH
Definition: SharedDefines.h:977
@ SPELL_FAILED_SPELL_UNAVAILABLE
Definition: SharedDefines.h:1028
@ SPELL_FAILED_ONLY_INDOORS
Definition: SharedDefines.h:1011
@ SPELL_FAILED_NOT_ON_TAXI
Definition: SharedDefines.h:986
@ SPELL_FAILED_TARGET_FRIENDLY
Definition: SharedDefines.h:1036
@ SPELL_ATTR4_IGNORE_DEFAULT_ARENA_RESTRICTIONS
Definition: SharedDefines.h:519
@ SPELL_ATTR4_NOT_IN_ARENA_OR_RATED_BATTLEGROUND
Definition: SharedDefines.h:518
@ SUMMON_CATEGORY_PET
Definition: SharedDefines.h:3257
@ SUMMON_CATEGORY_PUPPET
Definition: SharedDefines.h:3258
SkillType
Definition: SharedDefines.h:2835
@ SPELL_ATTR6_ALLOW_WHILE_RIDING_VEHICLE
Definition: SharedDefines.h:588
bool IsPathfindingEnabled(const Map *map)
Definition: DisableMgr.cpp:411
Player * FindPlayer(ObjectGuid const guid)
Definition: ObjectAccessor.cpp:250
Seconds GetGameTime()
Definition: GameTime.cpp:38
Definition: Battlefield.h:205
bool CanFlyIn()
Return if we can use mount in battlefield.
Definition: Battlefield.h:341
Definition: Battleground.h:293
Definition: ConditionMgr.h:181
Condition * mLastFailedCondition
Definition: ConditionMgr.h:183
WorldObject * mConditionTargets[MAX_CONDITION_TARGETS]
Definition: ConditionMgr.h:182
uint32 ErrorType
Definition: ConditionMgr.h:204
uint8 ConditionTarget
Definition: ConditionMgr.h:208
uint32 ErrorTextId
Definition: ConditionMgr.h:205
Loot loot
Definition: Creature.h:218
CreatureTemplate const * GetCreatureTemplate() const
Definition: Creature.h:197
bool IsSpellProhibited(SpellSchoolMask idSchoolMask) const
Definition: Creature.cpp:2740
SkillType GetRequiredLootSkill() const
Definition: CreatureData.h:246
bool IsTameable(bool exotic) const
Definition: CreatureData.h:263
Definition: TemporarySummon.h:40
Definition: GameObject.h:122
GameObjectTemplate const * GetGOInfo() const
Definition: GameObject.h:138
uint32 type
Definition: GameObjectData.h:34
bool IsLocked() const
Definition: Item.h:247
ItemTemplate const * GetTemplate() const
Definition: Item.cpp:546
bool IsPotion() const
Definition: Item.h:328
uint32 ItemLevel
Definition: ItemTemplate.h:644
uint32 LockID
Definition: ItemTemplate.h:678
uint32 InventoryType
Definition: ItemTemplate.h:641
Unit * ToUnit()
Definition: Object.h:200
Map * GetMap() const
Definition: Object.h:517
InstanceScript * GetInstanceScript() const
Definition: Object.cpp:1192
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:1347
bool IsOutdoors() const
Definition: Object.cpp:3100
bool IsWithinLOS(float x, float y, float z, VMAP::ModelIgnoreFlags ignoreFlags=VMAP::ModelIgnoreFlags::Nothing, LineOfSightChecks checks=LINEOFSIGHT_ALL_CHECKS) const
Definition: Object.cpp:1326
float GetVisibilityRange() const
Definition: Object.cpp:1645
uint32 GetAreaId() const
Definition: Object.cpp:3083
uint32 GetZoneId() const
Definition: Object.cpp:3075
void GetZoneAndAreaId(uint32 &zoneid, uint32 &areaid) const
Definition: Object.cpp:3091
uint64 GetRawValue() const
Definition: ObjectGuid.h:144
bool IsPlayer() const
Definition: ObjectGuid.h:170
bool IsGameObject() const
Definition: ObjectGuid.h:173
void GetPosition(float &x, float &y) const
Definition: Position.h:122
uint32 GetMapId() const
Definition: Position.h:276
Player * GetOwner() const
Definition: Pet.cpp:2436
bool HaveInDiet(ItemTemplate const *item) const
Definition: Pet.cpp:1401
uint32 GetCurrentFoodBenefitLevel(uint32 itemlevel) const
Definition: Pet.cpp:1419
static std::pair< PetStable::PetInfo const *, PetSaveMode > GetLoadPetInfo(PetStable const &stable, uint32 petEntry, uint32 petnumber, bool current)
Definition: Pet.cpp:162
Definition: PetDefines.h:197
Optional< PetInfo > CurrentPet
Definition: PetDefines.h:220
std::vector< PetInfo > UnslottedPets
Definition: PetDefines.h:223
void SetCanTeleport(bool value)
Definition: Player.h:2448
bool IsInSameRaidWith(Player const *p) const
Definition: Player.h:1836
bool CanTameExoticPets() const
Definition: Player.h:2138
bool CanUseBattlegroundObject(GameObject *gameobject) const
Definition: Player.cpp:13112
bool InBattleground() const
Definition: Player.h:2201
PetStable * GetPetStable()
Definition: Player.h:1178
Battleground * GetBattleground(bool create=false) const
Definition: Player.cpp:12097
WorldSession * GetSession() const
Definition: Player.h:1948
bool HasSpellCooldown(uint32 spell_id) const override
Definition: Player.cpp:16214
uint32 GetLastPotionId()
Definition: Player.h:1762
Group * GetGroup()
Definition: Player.h:2418
bool IsGameMaster() const
Definition: Player.h:1136
time_t GetSummonExpireTimer() const
Definition: Player.h:1083
bool Satisfy(DungeonProgressionRequirements const *ar, uint32 target_map, bool report=false)
Definition: PlayerStorage.cpp:6727
bool HasPlayerFlag(PlayerFlags flags) const
Definition: Player.h:1090
std::unique_ptr< DuelInfo > duel
Definition: Player.h:1828
Item * GetItemByGuid(ObjectGuid guid) const
Definition: PlayerStorage.cpp:438
uint32 GetSpell() const
Definition: TradeData.h:49
bool IsVehicle() const
Definition: Unit.h:1416
Vehicle * GetVehicle() const
Definition: Unit.h:2354
Unit * GetOwner() const
Definition: Unit.cpp:10560
Pet * ToPet()
Definition: Unit.h:2398
virtual bool HasSpellCooldown(uint32) const
Definition: Unit.h:2418
ShapeshiftForm GetShapeshiftForm() const
Definition: Unit.h:2071
virtual bool HasSpellItemCooldown(uint32, uint32) const
Definition: Unit.h:2419
bool IsInDisallowedMountForm() const
Definition: Unit.cpp:21407
void CombatStart(Unit *target, bool initialAggro=true)
Definition: Unit.cpp:13536
bool HasUnitFlag2(UnitFlags2 flags) const
Definition: Unit.h:1486
bool IsInSanctuary() const
Definition: Unit.h:1516
uint8 getClass() const
Definition: Unit.h:1426
AuraEffect * IsScriptOverriden(SpellInfo const *spell, int32 script) const
Definition: Unit.cpp:5721
float GetCombatReach() const override
Definition: Unit.h:1347
UnitFlags GetUnitFlags() const
Definition: Unit.h:1479
TempSummon * ToTempSummon()
Definition: Unit.h:2400
bool HasStealthAura() const
Definition: Unit.h:1706
bool HasAura(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemCasterGUID=ObjectGuid::Empty, uint8 reqEffMask=0) const
Definition: Unit.cpp:5610
std::map< uint8, AuraApplication * > VisibleAuraMap
Definition: Unit.h:1312
bool IsInFlight() const
Definition: Unit.h:1676
SpellImmuneList m_spellImmune[MAX_SPELL_IMMUNITY]
Definition: Unit.h:2136
void SendTameFailure(uint8 result)
Definition: Unit.cpp:20168
bool HasUnitMovementFlag(uint32 f) const
Definition: Unit.h:2274
virtual bool IsInWater() const
Definition: Unit.cpp:4279
bool HasAuraState(AuraStateType flag, SpellInfo const *spellProto=nullptr, Unit const *Caster=nullptr) const
Definition: Unit.cpp:10507
bool isMoving() const
Definition: Unit.h:2380
ObjectGuid GetCharmGUID() const
Definition: Unit.h:1822
VisibleAuraMap const * GetVisibleAuras()
Definition: Unit.h:2151
bool IsMounted() const
Definition: Unit.h:1542
Unit * GetVictim() const
Definition: Unit.h:1386
bool IsCritter() const
Definition: Unit.h:1674
ObjectGuid GetOwnerGUID() const
Definition: Unit.h:1814
uint8 GetComboPoints(Unit const *who=nullptr) const
--------—Combo point system----------------—
Definition: Unit.h:2290
ObjectGuid GetCharmerGUID() const
Definition: Unit.h:1820
uint32 getTransForm() const
Definition: Unit.h:2174
Powers getPowerType() const
Definition: Unit.h:1459
void RemoveMovementImpairingAuras(bool withRoot)
Definition: Unit.cpp:5149
bool IsTotem() const
Definition: Unit.h:1415
Guardian * GetGuardianPet() const
Definition: Unit.cpp:10611
ObjectGuid GetTarget() const
Definition: Unit.h:2433
bool IsInCombat() const
Definition: Unit.h:1688
ObjectGuid GetPetGUID() const
Definition: Unit.h:1824
Definition: Vehicle.h:30
VehicleSeatEntry const * GetSeatForPassenger(Unit const *passenger)
Definition: Vehicle.cpp:585
Definition: Group.h:168
Definition: GroupReference.h:27
GroupReference * next()
Definition: GroupReference.h:36
Definition: InstanceScript.h:140
bool isLooted() const
Definition: LootMgr.h:368
Definition: Map.h:273
bool AllowMount
Definition: Map.h:276
bool IsDungeon() const
Definition: Map.h:447
bool IsBattlegroundOrArena() const
Definition: Map.h:455
GameObject * GetGameObject(ObjectGuid const guid)
Definition: Map.cpp:3298
uint32 GetId() const
Definition: Map.h:378
Difficulty GetDifficulty() const
Definition: Map.h:442
uint32 GetRecruiterId() const
Definition: WorldSession.h:524
uint32 GetAccountId() const
Definition: WorldSession.h:360
GameObject * GetGOTarget() const
Definition: Spell.cpp:258
ObjectGuid GetItemTargetGUID() const
Definition: Spell.h:138
std::unique_ptr< PathGenerator > m_preGeneratedPath
Definition: Spell.h:775
SpellCastResult CheckSpellFocus()
Definition: Spell.cpp:7715
SpellCastResult CanOpenLock(uint32 effIndex, uint32 lockid, SkillType &skillid, int32 &reqSkillValue, int32 &skillValue)
Definition: Spell.cpp:8318
SpellCastResult CheckItems()
Definition: Spell.cpp:7147
int32 CalculateSpellDamage(uint8 i, Unit const *target) const
Definition: Spell.h:477
SpellCastResult CheckPower()
Definition: Spell.cpp:7102
SpellCastResult CheckCasterAuras(bool preventionOnly) const
Definition: Spell.cpp:6819
SpellCastResult CallScriptCheckCastHandlers()
Definition: Spell.cpp:8517
bool IsTriggered() const
Definition: Spell.h:552
SpellCastResult CheckRange(bool strict)
Definition: Spell.cpp:7016
bool HasGlobalCooldown() const
Definition: Spell.cpp:8789
Definition: SpellInfo.h:247
int32 MiscValue
Definition: SpellInfo.h:261
uint32 ApplyAuraName
Definition: SpellInfo.h:252
uint32 PreventionType
Definition: SpellInfo.h:388
uint32 CasterAuraSpell
Definition: SpellInfo.h:341
SpellCastResult CheckShapeshift(uint32 form) const
Definition: SpellInfo.cpp:1418
uint32 Mechanic
Definition: SpellInfo.h:321
uint32 GetDispelMask() const
Definition: SpellInfo.cpp:2026
uint32 GetRecoveryTime() const
Definition: SpellInfo.cpp:2379
bool IsSelfCast() const
Definition: SpellInfo.cpp:1074
uint32 CasterAuraState
Definition: SpellInfo.h:337
bool CanBeUsedInCombat() const
Definition: SpellInfo.cpp:1216
uint32 CasterAuraStateNot
Definition: SpellInfo.h:339
SpellSchoolMask GetSchoolMask() const
Definition: SpellInfo.cpp:1972
int32 AreaGroupId
Definition: SpellInfo.h:389
float GetMaxRange(bool positive=false, Unit *caster=nullptr, Spell *spell=nullptr) const
Definition: SpellInfo.cpp:2306
uint32 GetExplicitTargetMask() const
Definition: SpellInfo.cpp:2040
bool NeedsExplicitUnitTarget() const
Definition: SpellInfo.cpp:1017
SpellCastResult CheckLocation(uint32 map_id, uint32 zone_id, uint32 area_id, Player const *player=nullptr, bool strict=true) const
Definition: SpellInfo.cpp:1473
uint32 ExcludeCasterAuraSpell
Definition: SpellInfo.h:343
uint32 SpellFamilyName
Definition: SpellInfo.h:385
uint32 AuraInterruptFlags
Definition: SpellInfo.h:351
SpellCastResult CheckExplicitTarget(Unit const *caster, WorldObject const *target, Item const *itemTarget=nullptr) const
Definition: SpellInfo.cpp:1922
Definition: DBCStructure.h:519
Definition: DBCStructure.h:1012
Definition: DBCStructure.h:1308
bool IsDungeon() const
Definition: DBCStructure.h:1334
Definition: DBCStructure.h:1792
uint32 flags1
Definition: DBCStructure.h:1797
Definition: DBCStructure.h:1885
uint32 Category
Definition: DBCStructure.h:1887
Definition: DBCStructure.h:2040
uint32 m_flags
Definition: DBCStructure.h:2042

References _triggeredCastFlags, InstanceTemplate::AllowMount, SpellEffectInfo::ApplyAuraName, AREA_FLAG_NO_FLY_ZONE, SpellInfo::AreaGroupId, AURA_INTERRUPT_FLAG_MOUNT, AURA_INTERRUPT_FLAG_NOT_SEATED, SpellInfo::AuraInterruptFlags, CalculateSpellDamage(), CallScriptCheckCastHandlers(), SpellInfo::CanBeUsedInCombat(), Battlefield::CanFlyIn(), CanOpenLock(), Player::CanTameExoticPets(), Player::CanUseBattlegroundObject(), SpellInfo::CasterAuraSpell, SpellInfo::CasterAuraState, SpellInfo::CasterAuraStateNot, SummonPropertiesEntry::Category, CheckCasterAuras(), SpellInfo::CheckExplicitTarget(), CheckItems(), SpellInfo::CheckLocation(), CheckPower(), CheckRange(), SpellInfo::CheckShapeshift(), CheckSpellFocus(), SpellInfo::CheckTarget(), CLASS_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(), SpellShapeshiftEntry::flags1, GAMEOBJECT_TYPE_DOOR, GAMEOBJECT_TYPE_TRAP, WorldSession::GetAccountId(), WorldObject::GetAreaId(), Unit::GetAuraEffectsByType(), Player::GetBattleground(), Unit::GetCharm(), Unit::GetCharmerGUID(), Unit::GetCharmGUID(), Unit::getClass(), Unit::GetCombatReach(), Unit::GetComboPoints(), Creature::GetCreatureTemplate(), Pet::GetCurrentFoodBenefitLevel(), Map::GetDifficulty(), SpellInfo::GetDispelMask(), WorldObject::GetDistance(), SpellCastTargets::GetDstPos(), Object::GetEntry(), SpellInfo::GetExplicitTargetMask(), Map::GetGameObject(), GameTime::GetGameTime(), GameObject::GetGOInfo(), SpellCastTargets::GetGOTarget(), Player::GetGroup(), Unit::GetGuardianPet(), Map::GetId(), WorldObject::GetInstanceScript(), Player::GetItemByGuid(), SpellCastTargets::GetItemTarget(), SpellCastTargets::GetItemTargetGUID(), Player::GetLastPotionId(), Unit::GetLevel(), Pet::GetLoadPetInfo(), WorldObject::GetMap(), WorldLocation::GetMapId(), SpellInfo::GetMaxRange(), SpellCastTargets::GetObjectTarget(), Pet::GetOwner(), Player::GetPet(), Unit::GetPetGUID(), Player::GetPetStable(), Position::GetPosition(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), Unit::getPowerType(), 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(), Object::GetTypeId(), Unit::GetUnitFlags(), SpellCastTargets::GetUnitTarget(), Unit::GetVehicle(), Unit::GetVictim(), WorldObject::GetVisibilityRange(), Unit::GetVisibleAuras(), WorldObject::GetZoneAndAreaId(), WorldObject::GetZoneId(), GO_STATE_READY, SpellInfo::HasAttribute(), SpellInfo::HasAura(), Unit::HasAura(), Unit::HasAuraState(), SpellCastTargets::HasDst(), SpellInfo::HasEffect(), HasGlobalCooldown(), Player::HasPlayerFlag(), Player::HasSpellCooldown(), Unit::HasSpellCooldown(), Unit::HasSpellItemCooldown(), Unit::HasStealthAura(), 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(), SpellInfo::IsCooldownStartedOnEvent(), 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(), WorldObject::IsOutdoors(), SpellInfo::IsPassive(), DisableMgr::IsPathfindingEnabled(), SpellInfo::IsPositive(), Item::IsPotion(), Unit::IsScriptOverriden(), SpellInfo::IsSelfCast(), Creature::IsSpellProhibited(), CreatureTemplate::IsTameable(), Unit::IsTotem(), IsTriggered(), WorldObject::IsWithinLOS(), WorldObject::IsWithinLOSInMap(), ItemTemplate::ItemLevel, LINEOFSIGHT_ALL_CHECKS, ItemTemplate::LockID, Creature::loot, VMAP::M2, m_caster, m_CastItem, m_customError, VehicleSeatEntry::m_flags, m_needComboPoints, m_originalCaster, m_originalCasterGUID, m_preGeneratedPath, m_selfContainer, m_spellFlags, Unit::m_spellImmune, m_spellInfo, m_targets, m_triggeredByAuraSpell, MAX_SPELL_EFFECTS, ConditionSourceInfo::mConditionTargets, SpellInfo::Mechanic, MINUTE, SpellEffectInfo::MiscValue, ConditionSourceInfo::mLastFailedCondition, MOVEMENTFLAG_FALLING_FAR, SpellInfo::NeedsExplicitUnitTarget(), GroupReference::next(), PATHFIND_INCOMPLETE, PATHFIND_NOPATH, PATHFIND_SHORT, PET_TAME_CANT_CONTROL_EXOTIC, PET_TAME_DEAD, PET_TAME_NOPET_AVAILABLE, PLAYER_ALLOW_ONLY_ABILITY, POWER_MANA, SpellInfo::PreventionType, Unit::RemoveMovementImpairingAuras(), sAreaTableStore, Player::Satisfy(), sBattlefieldMgr, sConditionMgr, Unit::SendTameFailure(), sGlyphPropertiesStore, SKILL_LOCKPICKING, 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_INCREASE_SWIM_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_DUMMY, 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_DEAD, 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_DEATHKNIGHT, SPELLFAMILY_WARRIOR, SpellInfo::SpellFamilyName, TriggeredByAuraSpellData::spellInfo, SpellInfo::SpellLevel, sScriptMgr, sSpellMgr, sSpellShapeshiftStore, 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_GCD, TRIGGERED_IGNORE_POWER_AND_REAGENT_COST, TRIGGERED_IGNORE_SHAPESHIFT, TRIGGERED_IGNORE_SPELL_AND_CATEGORY_CD, GameObjectTemplate::type, TYPEID_PLAYER, TYPEID_UNIT, 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
6820{
6821 // spells totally immuned to caster auras (wsg flag drop, give marks etc)
6823 return SPELL_CAST_OK;
6824
6825 uint8 school_immune = 0;
6826 uint32 mechanic_immune = 0;
6827 uint32 dispel_immune = 0;
6828
6829 // Check if the spell grants school or mechanic immunity.
6830 // We use bitmasks so the loop is done only once and not on every aura check below.
6832 {
6833 for (int i = 0; i < MAX_SPELL_EFFECTS; ++i)
6834 {
6835 if (m_spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_SCHOOL_IMMUNITY)
6836 school_immune |= uint32(m_spellInfo->Effects[i].MiscValue);
6837 else if (m_spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_MECHANIC_IMMUNITY)
6838 mechanic_immune |= 1 << uint32(m_spellInfo->Effects[i].MiscValue);
6839 else if (m_spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_DISPEL_IMMUNITY)
6840 dispel_immune |= SpellInfo::GetDispelMask(DispelType(m_spellInfo->Effects[i].MiscValue));
6841 }
6842 // immune movement impairment and loss of control
6843 // PVP trinket EMFH TOC PVP trinket Bullheaded Bestial Wrath // Beath Within // Medalion of Immunity
6844 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)
6846 }
6847
6849
6850 // Glyph of Pain Suppression
6851 // there is no other way to handle it
6852 if (m_spellInfo->Id == 33206 && !m_caster->HasAura(63248))
6853 usableInStun = false;
6854
6855 // Check whether the cast should be prevented by any state you might have.
6856 SpellCastResult prevented_reason = SPELL_CAST_OK;
6857 // Have to check if there is a stun aura. Otherwise will have problems with ghost aura apply while logging out
6858 uint32 unitflag = m_caster->GetUnitFlags(); // Get unit state
6859
6860 // Xinef: if spell is triggered check preventionType only
6861 if (!preventionOnly)
6862 {
6863 if (unitflag & UNIT_FLAG_STUNNED)
6864 {
6865 // spell is usable while stunned, check if caster has only mechanic stun auras, another stun types must prevent cast spell
6866 if (usableInStun)
6867 {
6868 bool foundNotStun = false;
6869 uint32 mask = (1 << MECHANIC_STUN) | (1 << MECHANIC_FREEZE) | (1 << MECHANIC_HORROR);
6870 // Barkskin should skip sleep effects, sap and fears
6871 if (m_spellInfo->Id == 22812)
6872 mask |= 1 << MECHANIC_SAPPED | 1 << MECHANIC_HORROR | 1 << MECHANIC_SLEEP;
6873 // Hand of Freedom, can be used while sapped
6874 if (m_spellInfo->Id == 1044)
6875 mask |= 1 << MECHANIC_SAPPED;
6877 for (Unit::AuraEffectList::const_iterator i = stunAuras.begin(); i != stunAuras.end(); ++i)
6878 {
6879 if ((*i)->GetSpellInfo()->GetAllEffectsMechanicMask() && !((*i)->GetSpellInfo()->GetAllEffectsMechanicMask() & mask))
6880 {
6881 foundNotStun = true;
6882 break;
6883 }
6884 }
6885 if (foundNotStun)
6886 prevented_reason = SPELL_FAILED_STUNNED;
6887 }
6888 else
6889 prevented_reason = SPELL_FAILED_STUNNED;
6890 }
6892 prevented_reason = SPELL_FAILED_CONFUSED;
6894 prevented_reason = SPELL_FAILED_FLEEING;
6895 }
6896
6897 // Xinef: if there is no prevented_reason, check prevention types
6898 if (prevented_reason == SPELL_CAST_OK)
6899 {
6901 prevented_reason = SPELL_FAILED_SILENCED;
6903 prevented_reason = SPELL_FAILED_PACIFIED;
6904 }
6905
6906 // Attr must make flag drop spell totally immune from all effects
6907 if (prevented_reason != SPELL_CAST_OK)
6908 {
6909 if (school_immune || mechanic_immune || dispel_immune)
6910 {
6911 //Checking auras is needed now, because you are prevented by some state but the spell grants immunity.
6913 for (Unit::AuraApplicationMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
6914 {
6915 Aura const* aura = itr->second->GetBase();
6916 SpellInfo const* auraInfo = aura->GetSpellInfo();
6917 if (auraInfo->GetAllEffectsMechanicMask() & mechanic_immune)
6918 continue;
6919 if (auraInfo->GetSchoolMask() & school_immune && !auraInfo->HasAttribute(SPELL_ATTR1_IMMUNITY_TO_HOSTILE_AND_FRIENDLY_EFFECTS))
6920 continue;
6921 if (auraInfo->GetDispelMask() & dispel_immune)
6922 continue;
6923
6924 //Make a second check for spell failed so the right SPELL_FAILED message is returned.
6925 //That is needed when your casting is prevented by multiple states and you are only immune to some of them.
6926 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
6927 {
6928 if (AuraEffect* part = aura->GetEffect(i))
6929 {
6930 switch (part->GetAuraType())
6931 {
6933 {
6934 uint32 mask = 1 << MECHANIC_STUN;
6935 // Barkskin should skip sleep effects, sap and fears
6936 if (m_spellInfo->Id == 22812)
6937 mask |= 1 << MECHANIC_SAPPED | 1 << MECHANIC_HORROR | 1 << MECHANIC_SLEEP;
6938 // Hand of Freedom, can be used while sapped
6939 if (m_spellInfo->Id == 1044)
6940 mask |= 1 << MECHANIC_SAPPED;
6941
6942 if (!usableInStun || !(auraInfo->GetAllEffectsMechanicMask() & mask))
6943 return SPELL_FAILED_STUNNED;
6944 break;
6945 }
6948 return SPELL_FAILED_CONFUSED;
6949 break;
6952 return SPELL_FAILED_FLEEING;
6953 break;
6958 return SPELL_FAILED_PACIFIED;
6960 return SPELL_FAILED_SILENCED;
6961 break;
6962 default:
6963 break;
6964 }
6965 }
6966 }
6967 }
6968 }
6969 // You are prevented from casting and the spell casted does not grant immunity. Return a failed error.
6970 else
6971 return prevented_reason;
6972 }
6973 return SPELL_CAST_OK;
6974}
@ UNIT_FLAG_STUNNED
Definition: Unit.h:466
@ UNIT_FLAG_PACIFIED
Definition: Unit.h:465
@ UNIT_FLAG_CONFUSED
Definition: Unit.h:470
@ UNIT_FLAG_FLEEING
Definition: Unit.h:471
@ UNIT_FLAG_SILENCED
Definition: Unit.h:461
@ 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
@ SPELL_PREVENTION_TYPE_SILENCE
Definition: SharedDefines.h:1526
@ SPELL_PREVENTION_TYPE_PACIFY
Definition: SharedDefines.h:1527
@ SPELL_ATTR5_ALLOW_WHILE_STUNNED
Definition: SharedDefines.h:542
@ SPELL_ATTR5_ALLOW_WHILE_FLEEING
Definition: SharedDefines.h:556
@ SPELL_ATTR5_ALLOW_WHILE_CONFUSED
Definition: SharedDefines.h:557
@ SPELL_ATTR1_IMMUNITY_PURGES_EFFECT
Definition: SharedDefines.h:406
@ SPELL_ATTR1_IMMUNITY_TO_HOSTILE_AND_FRIENDLY_EFFECTS
Definition: SharedDefines.h:407
@ MECHANIC_STUN
Definition: SharedDefines.h:1309
@ MECHANIC_FREEZE
Definition: SharedDefines.h:1310
@ MECHANIC_SLEEP
Definition: SharedDefines.h:1307
@ MECHANIC_SAPPED
Definition: SharedDefines.h:1327
@ MECHANIC_HORROR
Definition: SharedDefines.h:1321
#define IMMUNE_TO_MOVEMENT_IMPAIRMENT_AND_LOSS_CONTROL_MASK
Definition: SharedDefines.h:1333
@ SPELL_FAILED_STUNNED
Definition: SharedDefines.h:1029
@ SPELL_FAILED_CONFUSED
Definition: SharedDefines.h:947
@ SPELL_FAILED_SILENCED
Definition: SharedDefines.h:1025
@ SPELL_FAILED_FLEEING
Definition: SharedDefines.h:955
@ SPELL_FAILED_PACIFIED
Definition: SharedDefines.h:1019
@ SPELL_ATTR6_NOT_AN_ATTACK
Definition: SharedDefines.h:578
std::multimap< uint32, AuraApplication * > AuraApplicationMap
Definition: Unit.h:1299
AuraApplicationMap & GetAppliedAuras()
Definition: Unit.h:1924
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:1977

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:400

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

Referenced by SelectEffectImplicitTargets(), and SelectImplicitDestDestTargets().

◆ CheckEffectExecuteData()

void Spell::CheckEffectExecuteData ( )
protected
8451{
8452 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
8454}
#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
7887{
7888 switch (m_spellInfo->Effects[eff].ApplyAuraName)
7889 {
7894 if (target->GetTypeId() == TYPEID_UNIT && target->IsVehicle())
7895 return false;
7896 if (target->IsMounted())
7897 return false;
7898 if (target->GetCharmerGUID())
7899 return false;
7900 if (int32 damage = CalculateSpellDamage(eff, target))
7901 if ((int32)target->GetLevel() > damage)
7902 return false;
7903 break;
7904 default:
7905 break;
7906 }
7907
7908 // xinef: skip los checking if spell has appropriate attribute, or target requires specific entry
7909 // 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
7910 if (m_spellInfo->HasAttribute(SPELL_ATTR2_IGNORE_LINE_OF_SIGHT) || (target->GetTypeId() == TYPEID_UNIT && target->HasUnitFlag(UNIT_FLAG_NOT_SELECTABLE) && (m_spellInfo->Effects[eff].TargetA.GetCheckType() == TARGET_CHECK_ENTRY || m_spellInfo->Effects[eff].TargetB.GetCheckType() == TARGET_CHECK_ENTRY)))
7911 return true;
7912
7913 // if spell is triggered, need to check for LOS disable on the aura triggering it and inherit that behaviour
7916 {
7917 return true;
7918 }
7919
7921 //Check targets for LOS visibility (except spells without range limitations)
7922 switch (m_spellInfo->Effects[eff].Effect)
7923 {
7925 // player far away, maybe his corpse near?
7926 if (target != m_caster && !target->IsWithinLOSInMap(m_caster))
7927 {
7929 return false;
7930
7932 if (!corpse)
7933 return false;
7934
7935 if (target->GetGUID() != corpse->GetOwnerGUID())
7936 return false;
7937
7939 return false;
7940 }
7941 break;
7943 {
7945 {
7946 if (target->IsWithinLOSInMap(m_caster, VMAP::ModelIgnoreFlags::M2) && target->HasUnitFlag(UNIT_FLAG_SKINNABLE))
7947 return true;
7948
7949 return false;
7950 }
7951
7953 if (!corpse)
7954 return false;
7955
7956 if (target->GetGUID() != corpse->GetOwnerGUID())
7957 return false;
7958
7960 return false;
7961
7963 return false;
7964 }
7965 break;
7967 if (m_caster->GetTypeId() != TYPEID_PLAYER || target->GetTypeId() != TYPEID_PLAYER)
7968 return false;
7969 if (m_caster->ToPlayer()->GetSession()->IsARecruiter() && target->ToPlayer()->GetSession()->GetRecruiterId() != m_caster->ToPlayer()->GetSession()->GetAccountId())
7970 return false;
7971 if (m_caster->ToPlayer()->GetSession()->GetRecruiterId() != target->ToPlayer()->GetSession()->GetAccountId() && target->ToPlayer()->GetSession()->IsARecruiter())
7972 return false;
7973 if (target->ToPlayer()->GetLevel() >= sWorld->getIntConfig(CONFIG_MAX_RECRUIT_A_FRIEND_BONUS_PLAYER_LEVEL))
7974 return false;
7975 break;
7976 default: // normal case
7977 {
7978 uint32 losChecks = LINEOFSIGHT_ALL_CHECKS;
7979 GameObject* gobCaster = nullptr;
7981 {
7983 }
7984 else if (m_caster->GetEntry() == WORLD_TRIGGER)
7985 {
7986 if (TempSummon* tempSummon = m_caster->ToTempSummon())
7987 {
7988 gobCaster = tempSummon->GetSummonerGameObject();
7989 }
7990 }
7991
7992 if (gobCaster)
7993 {
7994 if (gobCaster->GetGOInfo()->IsIgnoringLOSChecks())
7995 {
7996 return true;
7997 }
7998
7999 // If spell casted by gameobject then ignore M2 models
8000 losChecks &= ~LINEOFSIGHT_CHECK_GOBJECT_M2;
8001 }
8002
8003 if (target != m_caster)
8004 {
8005 if (m_targets.HasDst())
8006 {
8007 float x = m_targets.GetDstPos()->GetPositionX();
8008 float y = m_targets.GetDstPos()->GetPositionY();
8009 float z = m_targets.GetDstPos()->GetPositionZ();
8010
8011 if (!target->IsWithinLOS(x, y, z, VMAP::ModelIgnoreFlags::M2, LineOfSightChecks(losChecks)))
8012 {
8013 return false;
8014 }
8015 }
8017 {
8018 return false;
8019 }
8020 }
8021 break;
8022 }
8023 }
8024
8025 return true;
8026}
@ SPELL_DISABLE_LOS
Definition: DisableMgr.h:50
@ DISABLE_TYPE_SPELL
Definition: DisableMgr.h:29
@ CORPSE_FLAG_LOOTABLE
Definition: Corpse.h:45
@ CORPSE_FIELD_FLAGS
Definition: UpdateFields.h:427
@ UNIT_FLAG_NOT_SELECTABLE
Definition: Unit.h:473
@ TARGET_CHECK_ENTRY
Definition: SpellInfo.h:115
@ CONFIG_MAX_RECRUIT_A_FRIEND_BONUS_PLAYER_LEVEL
Definition: IWorld.h:245
@ SPELL_EFFECT_SKIN_PLAYER_CORPSE
Definition: SharedDefines.h:866
#define sWorld
Definition: World.h:451
bool IsDisabledFor(DisableType type, uint32 entry, Unit const *unit, uint8 flags)
Definition: DisableMgr.cpp:306
Corpse * GetCorpse(WorldObject const &u, ObjectGuid const guid)
Definition: ObjectAccessor.cpp:184
Definition: Corpse.h:49
ObjectGuid GetOwnerGUID() const
Definition: Corpse.h:68
bool IsIgnoringLOSChecks() const
Definition: GameObjectData.h:643
bool HasFlag(uint16 index, uint32 flag) const
Definition: Object.cpp:889
bool IsARecruiter() const
Definition: WorldSession.h:525
ObjectGuid GetCorpseTargetGUID() const
Definition: Spell.cpp:275

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(), Object::GetTypeId(), SpellInfo::HasAttribute(), SpellCastTargets::HasDst(), Object::HasFlag(), Unit::HasUnitFlag(), SpellInfo::Id, WorldSession::IsARecruiter(), DisableMgr::IsDisabledFor(), ObjectGuid::IsGameObject(), GameObjectTemplate::IsIgnoringLOSChecks(), Unit::IsMounted(), IsTriggered(), Unit::IsVehicle(), WorldObject::IsWithinLOS(), WorldObject::IsWithinLOSInMap(), LINEOFSIGHT_ALL_CHECKS, VMAP::M2, m_caster, m_originalCasterGUID, m_spellFlags, m_spellInfo, m_targets, m_triggeredByAuraSpell, SPELL_ATTR2_IGNORE_LINE_OF_SIGHT, SPELL_AURA_AOE_CHARM, SPELL_AURA_MOD_CHARM, SPELL_AURA_MOD_POSSESS, SPELL_AURA_MOD_POSSESS_PET, SPELL_DISABLE_LOS, SPELL_EFFECT_RESURRECT_NEW, SPELL_EFFECT_SKIN_PLAYER_CORPSE, SPELL_EFFECT_SUMMON_RAF_FRIEND, SPELL_FLAG_REDIRECTED, TriggeredByAuraSpellData::spellInfo, sWorld, TARGET_CHECK_ENTRY, Object::ToPlayer(), Unit::ToTempSummon(), TYPEID_PLAYER, TYPEID_UNIT, 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.
7148{
7149 Player* player = m_caster->ToPlayer();
7150 if (!player)
7151 {
7152 // Non-player case: Check if creature is disarmed
7154 {
7156 }
7157
7158 return SPELL_CAST_OK;
7159 }
7160
7161 if (!m_CastItem)
7162 {
7163 if (m_castItemGUID)
7165 }
7166 else
7167 {
7168 uint32 itemid = m_CastItem->GetEntry();
7169 if (!player->HasItemCount(itemid))
7171
7172 ItemTemplate const* proto = m_CastItem->GetTemplate();
7173 if (!proto)
7175
7176 for (int i = 0; i < MAX_ITEM_SPELLS; ++i)
7177 if (proto->Spells[i].SpellCharges)
7178 if (m_CastItem->GetSpellCharges(i) == 0)
7180
7181 // consumable cast item checks
7183 {
7184 // such items should only fail if there is no suitable effect at all - see Rejuvenation Potions for example
7185 SpellCastResult failReason = SPELL_CAST_OK;
7186 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; i++)
7187 {
7188 // skip check, pet not required like checks, and for TARGET_UNIT_PET m_targets.GetUnitTarget() is not the real target but the caster
7189 if (m_spellInfo->Effects[i].TargetA.GetTarget() == TARGET_UNIT_PET)
7190 continue;
7191
7192 if (m_spellInfo->Effects[i].Effect == SPELL_EFFECT_HEAL)
7193 {
7195 {
7197 continue;
7198 }
7199 else
7200 {
7201 failReason = SPELL_CAST_OK;
7202 break;
7203 }
7204 }
7205
7206 // Mana Potion, Rage Potion, Thistle Tea(Rogue), ...
7207 if (m_spellInfo->Effects[i].Effect == SPELL_EFFECT_ENERGIZE)
7208 {
7209 if (m_spellInfo->Effects[i].MiscValue < 0 || m_spellInfo->Effects[i].MiscValue >= int8(MAX_POWERS))
7210 {
7212 continue;
7213 }
7214
7215 Powers power = Powers(m_spellInfo->Effects[i].MiscValue);
7217 {
7219 continue;
7220 }
7221 else
7222 {
7223 failReason = SPELL_CAST_OK;
7224 break;
7225 }
7226 }
7227 }
7228 if (failReason != SPELL_CAST_OK)
7229 return failReason;
7230 }
7231 }
7232
7233 // check target item
7235 {
7238
7239 if (!m_targets.GetItemTarget())
7241
7244 }
7245 // if not item target then required item must be equipped
7246 else
7247 {
7248 // Xinef: this is not true in my opinion, in eg bladestorm will not be canceled after disarm
7249 //if (!(_triggeredCastFlags & TRIGGERED_IGNORE_EQUIPPED_ITEM_REQUIREMENT))
7252 }
7253
7254 // do not take reagents for these item casts
7256 {
7258 // Not own traded item (in trader trade slot) requires reagents even if triggered spell
7259 if (!checkReagents)
7260 if (Item* targetItem = m_targets.GetItemTarget())
7261 if (targetItem->GetOwnerGUID() != m_caster->GetGUID())
7262 checkReagents = true;
7263
7264 // check reagents (ignore triggered spells with reagents processed by original spell) and special reagent ignore case.
7265 if (checkReagents)
7266 {
7267 for (uint32 i = 0; i < MAX_SPELL_REAGENTS; i++)
7268 {
7269 if (m_spellInfo->Reagent[i] <= 0)
7270 continue;
7271
7272 uint32 itemid = m_spellInfo->Reagent[i];
7273 uint32 itemcount = m_spellInfo->ReagentCount[i];
7274
7275 // if CastItem is also spell reagent
7276 if (m_CastItem && m_CastItem->GetEntry() == itemid)
7277 {
7278 ItemTemplate const* proto = m_CastItem->GetTemplate();
7279 if (!proto)
7281 for (int s = 0; s < MAX_ITEM_PROTO_SPELLS; ++s)
7282 {
7283 // CastItem will be used up and does not count as reagent
7284 int32 charges = m_CastItem->GetSpellCharges(s);
7285 if (proto->Spells[s].SpellCharges < 0 && std::abs(charges) < 2)
7286 {
7287 ++itemcount;
7288 break;
7289 }
7290 }
7291 }
7292 if (!player->HasItemCount(itemid, itemcount))
7293 return SPELL_FAILED_REAGENTS;
7294 }
7295 }
7296
7297 // check totem-item requirements (items presence in inventory)
7298 uint32 totems = 2;
7299 for (int i = 0; i < 2; ++i)
7300 {
7301 if (m_spellInfo->Totem[i] != 0)
7302 {
7303 if (player->HasItemCount(m_spellInfo->Totem[i]))
7304 {
7305 totems -= 1;
7306 continue;
7307 }
7308 }
7309 else
7310 totems -= 1;
7311 }
7312 if (totems != 0)
7313 return SPELL_FAILED_TOTEMS; //0x7C
7314
7315 // Check items for TotemCategory (items presence in inventory)
7317 for (int i = 0; i < 2; ++i)
7318 {
7319 if (m_spellInfo->TotemCategory[i] != 0)
7320 {
7322 {
7323 TotemCategory -= 1;
7324 continue;
7325 }
7326 }
7327 else
7328 TotemCategory -= 1;
7329 }
7330 if (TotemCategory != 0)
7331 return SPELL_FAILED_TOTEM_CATEGORY; //0x7B
7332 }
7333
7334 // special checks for spell effects
7335 for (int i = 0; i < MAX_SPELL_EFFECTS; i++)
7336 {
7337 switch (m_spellInfo->Effects[i].Effect)
7338 {
7341 {
7342 // m_targets.GetUnitTarget() means explicit cast, otherwise we dont check for possible equip error
7343 Unit* target = m_targets.GetUnitTarget() ? m_targets.GetUnitTarget() : player;
7344 if (target->GetTypeId() == TYPEID_PLAYER && !IsTriggered())
7345 {
7346 // 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,
7347 // so we need to make sure there is at least one free space in the player's inventory
7349 if (target->ToPlayer()->GetFreeInventorySpace() == 0)
7350 {
7351 player->SendEquipError(EQUIP_ERR_INVENTORY_FULL, nullptr, nullptr, m_spellInfo->Effects[i].ItemType);
7353 }
7354
7355 if (m_spellInfo->Effects[i].ItemType)
7356 {
7357 ItemTemplate const* itemTemplate = sObjectMgr->GetItemTemplate(m_spellInfo->Effects[i].ItemType);
7358 if (!itemTemplate)
7360
7361 uint32 createCount = std::clamp<uint32>(m_spellInfo->Effects[i].CalcValue(), 1u, itemTemplate->GetMaxStackSize());
7362 ItemPosCountVec dest;
7363 InventoryResult msg = target->ToPlayer()->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, m_spellInfo->Effects[i].ItemType, createCount);
7364 if (msg != EQUIP_ERR_OK)
7365 {
7367 if (!itemTemplate->ItemLimitCategory)
7368 {
7369 player->SendEquipError(msg, nullptr, nullptr, m_spellInfo->Effects[i].ItemType);
7371 }
7372 else
7373 {
7374 // Conjure Food/Water/Refreshment spells
7377 else if (!(target->ToPlayer()->HasItemCount(m_spellInfo->Effects[i].ItemType)))
7378 {
7379 player->SendEquipError(msg, nullptr, nullptr, m_spellInfo->Effects[i].ItemType);
7381 }
7382 else
7383 player->CastSpell(player, m_spellInfo->Effects[EFFECT_1].CalcValue(), false); // move this to anywhere
7384
7386 }
7387 }
7388 }
7389 }
7390 break;
7391 }
7393 {
7394 if (player->GetFreeInventorySpace() == 0)
7395 {
7396 player->SendEquipError(EQUIP_ERR_INVENTORY_FULL, nullptr, nullptr, m_spellInfo->Effects[i].ItemType);
7398 }
7399 break;
7400 }
7402 if (m_spellInfo->Effects[i].ItemType && m_targets.GetItemTarget()
7404 {
7405 // cannot enchant vellum for other player
7408 // do not allow to enchant vellum from scroll made by vellum-prevent exploit
7411 ItemPosCountVec dest;
7412 InventoryResult msg = player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, m_spellInfo->Effects[i].ItemType, 1);
7413 if (msg != EQUIP_ERR_OK)
7414 {
7415 player->SendEquipError(msg, nullptr, nullptr, m_spellInfo->Effects[i].ItemType);
7417 }
7418 }
7419 [[fallthrough]];
7421 {
7422 Item* targetItem = m_targets.GetItemTarget();
7423 if (!targetItem)
7425
7426 // xinef: required level has to be checked also! Exploit fix
7427 if (targetItem->GetTemplate()->ItemLevel < m_spellInfo->BaseLevel || (targetItem->GetTemplate()->RequiredLevel && targetItem->GetTemplate()->RequiredLevel < m_spellInfo->BaseLevel))
7428 return SPELL_FAILED_LOWLEVEL;
7429
7430 bool isItemUsable = false;
7431 for (uint8 e = 0; e < MAX_ITEM_PROTO_SPELLS; ++e)
7432 {
7433 ItemTemplate const* proto = targetItem->GetTemplate();
7434 if (proto->Spells[e].SpellId && (
7437 {
7438 isItemUsable = true;
7439 break;
7440 }
7441 }
7442
7443 SpellItemEnchantmentEntry const* enchantEntry = sSpellItemEnchantmentStore.LookupEntry(m_spellInfo->Effects[i].MiscValue);
7444 // do not allow adding usable enchantments to items that have use effect already
7445 if (enchantEntry)
7446 {
7447 for (uint8 s = 0; s < MAX_SPELL_ITEM_ENCHANTMENT_EFFECTS; ++s)
7448 {
7449 switch (enchantEntry->type[s])
7450 {
7452 if (isItemUsable)
7454 break;
7456 {
7457 uint32 numSockets = 0;
7458 for (uint32 socket = 0; socket < MAX_ITEM_PROTO_SOCKETS; ++socket)
7459 if (targetItem->GetTemplate()->Socket[socket].Color)
7460 ++numSockets;
7461
7462 if (numSockets == MAX_ITEM_PROTO_SOCKETS || targetItem->GetEnchantmentId(PRISMATIC_ENCHANTMENT_SLOT))
7464 break;
7465 }
7466 }
7467 }
7468 }
7469
7470 // Not allow enchant in trade slot for some enchant type
7471 if (targetItem->GetOwner() != m_caster)
7472 {
7473 if (!enchantEntry)
7474 return SPELL_FAILED_ERROR;
7475 if (enchantEntry->slot & ENCHANTMENT_CAN_SOULBOUND)
7477 }
7478 break;
7479 }
7481 {
7482 Item* item = m_targets.GetItemTarget();
7483 if (!item)
7485 // Not allow enchant in trade slot for some enchant type
7486 if (item->GetOwner() != m_caster)
7487 {
7488 uint32 enchant_id = m_spellInfo->Effects[i].MiscValue;
7489 SpellItemEnchantmentEntry const* pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id);
7490 if (!pEnchant)
7491 return SPELL_FAILED_ERROR;
7492 if (pEnchant->slot & ENCHANTMENT_CAN_SOULBOUND)
7494 }
7495
7496 // Xinef: Apply item level restriction if the enchanting spell has max level restrition set
7497 if (m_CastItem && m_spellInfo->MaxLevel > 0)
7498 {
7500 return SPELL_FAILED_LOWLEVEL;
7501 if (item->GetTemplate()->ItemLevel > m_spellInfo->MaxLevel)
7503 }
7504
7505 break;
7506 }
7508 // check item existence in effect code (not output errors at offhand hold item effect to main hand for example
7509 break;
7511 {
7512 if (!m_targets.GetItemTarget())
7514
7515 // prevent disenchanting in trade slot
7518
7519 ItemTemplate const* itemProto = m_targets.GetItemTarget()->GetTemplate();
7520 if (!itemProto)
7522
7523 uint32 item_quality = itemProto->Quality;
7524 // 2.0.x addon: Check player enchanting level against the item disenchanting requirements
7525 uint32 item_disenchantskilllevel = itemProto->RequiredDisenchantSkill;
7526 if (item_disenchantskilllevel == uint32(-1))
7528 if (item_disenchantskilllevel > player->GetSkillValue(SKILL_ENCHANTING))
7530 if (item_quality > 4 || item_quality < 2)
7532 if (itemProto->Class != ITEM_CLASS_WEAPON && itemProto->Class != ITEM_CLASS_ARMOR)
7534 if (!itemProto->DisenchantID)
7536 break;
7537 }
7539 {
7540 if (!m_targets.GetItemTarget())
7542 //ensure item is a prospectable ore
7545 //prevent prospecting in trade slot
7548 //Check for enough skill in jewelcrafting
7549 uint32 item_prospectingskilllevel = m_targets.GetItemTarget()->GetTemplate()->RequiredSkillRank;
7550 if (item_prospectingskilllevel > player->GetSkillValue(SKILL_JEWELCRAFTING))
7552 //make sure the player has the required ores in inventory
7553 if (m_targets.GetItemTarget()->GetCount() < 5)
7555
7558
7559 break;
7560 }
7562 {
7563 if (!m_targets.GetItemTarget())
7565 //ensure item is a millable herb
7568 //prevent milling in trade slot
7571 //Check for enough skill in inscription
7572 uint32 item_millingskilllevel = m_targets.GetItemTarget()->GetTemplate()->RequiredSkillRank;
7573 if (item_millingskilllevel > player->GetSkillValue(SKILL_INSCRIPTION))
7575 //make sure the player has the required herbs in inventory
7576 if (m_targets.GetItemTarget()->GetCount() < 5)
7578
7581
7582 break;
7583 }
7586 {
7589
7591 break;
7592
7594 if (!pItem || pItem->IsBroken())
7596
7597 switch (pItem->GetTemplate()->SubClass)
7598 {
7600 {
7601 uint32 ammo = pItem->GetEntry();
7602 if (!m_caster->ToPlayer()->HasItemCount(ammo))
7603 return SPELL_FAILED_NO_AMMO;
7604 };
7605 break;
7609 {
7611 if (!ammo)
7612 {
7613 // Requires No Ammo
7614 if (m_caster->HasAura(46699))
7615 break; // skip other checks
7616
7617 return SPELL_FAILED_NO_AMMO;
7618 }
7619
7620 ItemTemplate const* ammoProto = sObjectMgr->GetItemTemplate(ammo);
7621 if (!ammoProto)
7622 return SPELL_FAILED_NO_AMMO;
7623
7624 if (ammoProto->Class != ITEM_CLASS_PROJECTILE)
7625 return SPELL_FAILED_NO_AMMO;
7626
7627 // check ammo ws. weapon compatibility
7628 switch (pItem->GetTemplate()->SubClass)
7629 {
7632 if (ammoProto->SubClass != ITEM_SUBCLASS_ARROW)
7633 return SPELL_FAILED_NO_AMMO;
7634 break;
7636 if (ammoProto->SubClass != ITEM_SUBCLASS_BULLET)
7637 return SPELL_FAILED_NO_AMMO;
7638 break;
7639 default:
7640 return SPELL_FAILED_NO_AMMO;
7641 }
7642
7643 if (!m_caster->ToPlayer()->HasItemCount(ammo))
7644 {
7646 return SPELL_FAILED_NO_AMMO;
7647 }
7648 };
7649 break;
7651 break;
7652 default:
7653 break;
7654 }
7655 break;
7656 }
7658 {
7659 uint32 item_id = m_spellInfo->Effects[i].ItemType;
7660 ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(item_id);
7661
7662 if (!pProto)
7664
7665 if (Item* pitem = player->GetItemByEntry(item_id))
7666 {
7667 for (int x = 0; x < MAX_ITEM_PROTO_SPELLS; ++x)
7668 if (pProto->Spells[x].SpellCharges != 0 && pitem->GetSpellCharges(x) == pProto->Spells[x].SpellCharges)
7670 }
7671 break;
7672 }
7673 default:
7674 break;
7675 }
7676 }
7677
7678 // check weapon presence in slots for main/offhand weapons
7679 if (/*never skip those checks !(_triggeredCastFlags & TRIGGERED_IGNORE_EQUIPPED_ITEM_REQUIREMENT) &&*/ m_spellInfo->EquippedItemClass >= 0)
7680 {
7681 // main hand weapon required
7683 {
7685
7686 // skip spell if no weapon in slot or broken
7687 if (!item || item->IsBroken())
7689
7690 // skip spell if weapon not fit to triggered spell
7693 }
7694
7695 // offhand hand weapon required
7697 {
7699
7700 // skip spell if no weapon in slot or broken
7701 if (!item || item->IsBroken())
7703
7704 // skip spell if weapon not fit to triggered spell
7707 }
7708
7710 }
7711
7712 return SPELL_CAST_OK;
7713}
std::int8_t int8
Definition: Define.h:106
DBCStorage< SpellItemEnchantmentEntry > sSpellItemEnchantmentStore(SpellItemEnchantmentfmt)
#define MAX_ITEM_SPELLS
Definition: Item.h:209
@ PRISMATIC_ENCHANTMENT_SLOT
Definition: Item.h:169
@ ENCHANTMENT_CAN_SOULBOUND
Definition: Item.h:195
InventoryResult
Definition: Item.h:40
@ EQUIP_ERR_OK
Definition: Item.h:41
@ EQUIP_ERR_INVENTORY_FULL
Definition: Item.h:91
@ ITEM_SUBCLASS_WEAPON_CROSSBOW
Definition: ItemTemplate.h:371
@ ITEM_SUBCLASS_WEAPON_GUN
Definition: ItemTemplate.h:356
@ ITEM_SUBCLASS_WEAPON_BOW
Definition: ItemTemplate.h:355
@ ITEM_SUBCLASS_WEAPON_WAND
Definition: ItemTemplate.h:372
@ ITEM_SUBCLASS_WEAPON_THROWN
Definition: ItemTemplate.h:369
@ ITEM_SPELLTRIGGER_ON_USE
Definition: ItemTemplate.h:78
@ ITEM_SPELLTRIGGER_ON_NO_DELAY_USE
Definition: ItemTemplate.h:88
@ ITEM_FLAG_IS_MILLABLE
Definition: ItemTemplate.h:177
@ ITEM_FLAG_NO_REAGENT_COST
Definition: ItemTemplate.h:176
@ ITEM_FLAG_IS_PROSPECTABLE
Definition: ItemTemplate.h:166
@ ITEM_SUBCLASS_ARROW
Definition: ItemTemplate.h:425
@ ITEM_SUBCLASS_BULLET
Definition: ItemTemplate.h:426
#define MAX_ITEM_PROTO_SOCKETS
Definition: ItemTemplate.h:623
#define MAX_ITEM_PROTO_SPELLS
Definition: ItemTemplate.h:624
@ ITEM_CLASS_PROJECTILE
Definition: ItemTemplate.h:306
@ ITEM_CLASS_ARMOR
Definition: ItemTemplate.h:304
@ ITEM_CLASS_WEAPON
Definition: ItemTemplate.h:302
@ ITEM_CLASS_CONSUMABLE
Definition: ItemTemplate.h:300
@ PLAYER_AMMO_ID
Definition: UpdateFields.h:369
std::vector< ItemPosCount > ItemPosCountVec
Definition: Player.h:772
@ NULL_BAG
Definition: Unit.h:210
@ NULL_SLOT
Definition: Unit.h:211
LootStore LootTemplates_Milling("milling_loot_template", "item entry (herb)", true)
LootStore LootTemplates_Prospecting("prospecting_loot_template", "item entry (ore)", true)
@ ITEM_ENCHANTMENT_TYPE_USE_SPELL
Definition: DBCEnums.h:378
@ ITEM_ENCHANTMENT_TYPE_PRISMATIC_SOCKET
Definition: DBCEnums.h:379
#define MAX_SPELL_REAGENTS
Definition: DBCStructure.h:1612
#define MAX_SPELL_ITEM_ENCHANTMENT_EFFECTS
Definition: DBCStructure.h:1814
@ EFFECT_1
Definition: SharedDefines.h:31
@ MAX_POWERS
Definition: SharedDefines.h:248
@ SPELL_EFFECT_DISENCHANT
Definition: SharedDefines.h:849
@ SPELL_EFFECT_PROSPECTING
Definition: SharedDefines.h:877
@ SPELL_EFFECT_ENCHANT_HELD_ITEM
Definition: SharedDefines.h:842
@ SPELL_EFFECT_ENCHANT_ITEM
Definition: SharedDefines.h:803
@ SPELL_EFFECT_WEAPON_DAMAGE
Definition: SharedDefines.h:808
@ SPELL_EFFECT_HEAL
Definition: SharedDefines.h:760
@ SPELL_EFFECT_MILLING
Definition: SharedDefines.h:908
@ SPELL_EFFECT_CREATE_MANA_GEM
Definition: SharedDefines.h:816
@ SPELL_EFFECT_CREATE_ITEM_2
Definition: SharedDefines.h:907
@ SPELL_EFFECT_WEAPON_DAMAGE_NOSCHOOL
Definition: SharedDefines.h:767
@ SPELL_EFFECT_ENERGIZE
Definition: SharedDefines.h:780
@ SPELL_EFFECT_CREATE_RANDOM_ITEM
Definition: SharedDefines.h:809
@ SPELL_EFFECT_ENCHANT_ITEM_PRISMATIC
Definition: SharedDefines.h:906
@ SPELL_EFFECT_ENCHANT_ITEM_TEMPORARY
Definition: SharedDefines.h:804
@ SPELL_EFFECT_CREATE_ITEM
Definition: SharedDefines.h:774
@ SPELL_ATTR3_REQUIRES_MAIN_HAND_WEAPON
Definition: SharedDefines.h:475
@ SPELLFAMILY_MAGE
Definition: SharedDefines.h:3503
TotemCategory
Definition: SharedDefines.h:3055
@ SPELL_FAILED_CANT_BE_MILLED
Definition: SharedDefines.h:937
@ SPELL_FAILED_EQUIPPED_ITEM_CLASS_OFFHAND
Definition: SharedDefines.h:952
@ SPELL_FAILED_EQUIPPED_ITEM_CLASS
Definition: SharedDefines.h:950
@ SPELL_FAILED_ITEM_AT_MAX_CHARGES
Definition: SharedDefines.h:1100
@ SPELL_FAILED_TARGET_NOT_PLAYER
Definition: SharedDefines.h:1043
@ SPELL_FAILED_ALREADY_AT_FULL_POWER
Definition: SharedDefines.h:925
@ SPELL_FAILED_NOT_TRADEABLE
Definition: SharedDefines.h:991
@ SPELL_FAILED_ITEM_NOT_READY
Definition: SharedDefines.h:966
@ SPELL_FAILED_NO_CHARGES_REMAIN
Definition: SharedDefines.h:997
@ SPELL_FAILED_ITEM_GONE
Definition: SharedDefines.h:964
@ SPELL_FAILED_NO_AMMO
Definition: SharedDefines.h:996
@ SPELL_FAILED_ITEM_NOT_FOUND
Definition: SharedDefines.h:965
@ SPELL_FAILED_EQUIPPED_ITEM
Definition: SharedDefines.h:949
@ SPELL_FAILED_ALREADY_AT_FULL_HEALTH
Definition: SharedDefines.h:923
@ SPELL_FAILED_ON_USE_ENCHANT
Definition: SharedDefines.h:1091
@ SPELL_FAILED_TOTEMS
Definition: SharedDefines.h:1052
@ SPELL_FAILED_ERROR
Definition: SharedDefines.h:953
@ SPELL_FAILED_REAGENTS
Definition: SharedDefines.h:1021
@ SPELL_FAILED_MAX_SOCKETS
Definition: SharedDefines.h:1105
@ SPELL_FAILED_CANT_BE_DISENCHANTED
Definition: SharedDefines.h:935
@ SPELL_FAILED_TOO_MANY_OF_ITEM
Definition: SharedDefines.h:1050
@ SPELL_FAILED_NEED_MORE_ITEMS
Definition: SharedDefines.h:976
@ SPELL_FAILED_CANT_BE_PROSPECTED
Definition: SharedDefines.h:938
@ SPELL_FAILED_EQUIPPED_ITEM_CLASS_MAINHAND
Definition: SharedDefines.h:951
@ SPELL_FAILED_TOTEM_CATEGORY
Definition: SharedDefines.h:1051
@ SKILL_INSCRIPTION
Definition: SharedDefines.h:2974
@ SKILL_ENCHANTING
Definition: SharedDefines.h:2926
@ SKILL_JEWELCRAFTING
Definition: SharedDefines.h:2957
uint32 GetEnchantmentId(EnchantmentSlot slot) const
Definition: Item.h:295
int32 GetSpellCharges(uint8 index=0) const
Definition: Item.h:308
bool IsBroken() const
Definition: Item.h:251
bool IsWeaponVellum() const
Definition: Item.h:329
bool IsArmorVellum() const
Definition: Item.h:330
Player * GetOwner() const
Definition: Item.cpp:551
ObjectGuid GetOwnerGUID() const
Definition: Item.h:225
uint32 GetCount() const
Definition: Item.h:263
bool IsFitToSpellRequirements(SpellInfo const *spellInfo) const
Definition: Item.cpp:886
int32 SpellCharges
Definition: ItemTemplate.h:602
uint32 SpellTrigger
Definition: ItemTemplate.h:601
int32 SpellId
Definition: ItemTemplate.h:600
uint32 Color
Definition: ItemTemplate.h:611
Definition: ItemTemplate.h:628
uint32 DisenchantID
Definition: ItemTemplate.h:699
uint32 Quality
Definition: ItemTemplate.h:635
uint32 RequiredSkillRank
Definition: ItemTemplate.h:647
uint32 GetMaxStackSize() const
Definition: ItemTemplate.h:738
_Spell Spells[MAX_ITEM_PROTO_SPELLS]
Definition: ItemTemplate.h:671
uint32 RequiredDisenchantSkill
Definition: ItemTemplate.h:693
uint32 Flags
Definition: ItemTemplate.h:636
uint32 RequiredLevel
Definition: ItemTemplate.h:645
uint32 Class
Definition: ItemTemplate.h:630
uint32 ItemLimitCategory
Definition: ItemTemplate.h:696
uint32 SubClass
Definition: ItemTemplate.h:631
_Socket Socket[MAX_ITEM_PROTO_SOCKETS]
Definition: ItemTemplate.h:690
uint32 GetUInt32Value(uint16 index) const
Definition: Object.cpp:305
void SetUInt32Value(uint16 index, uint32 value)
Definition: Object.cpp:650
bool HasItemFitToSpellRequirements(SpellInfo const *spellInfo, Item const *ignoreItem=nullptr) const
Definition: Player.cpp:12411
uint32 GetFreeInventorySpace() const
Definition: PlayerStorage.cpp:497
Item * GetItemByEntry(uint32 entry) const
Definition: PlayerStorage.cpp:3397
bool HasItemCount(uint32 item, uint32 count=1, bool inBankAlso=false) const
Definition: PlayerStorage.cpp:686
bool HasItemTotemCategory(uint32 TotemCategory) const
Definition: PlayerStorage.cpp:882
bool CanNoReagentCast(SpellInfo const *spellInfo) const
Definition: Player.cpp:12456
void SendEquipError(InventoryResult msg, Item *pItem, Item *pItem2=nullptr, uint32 itemid=0)
Definition: PlayerStorage.cpp:4049
InventoryResult CanStoreNewItem(uint8 bag, uint8 slot, ItemPosCountVec &dest, uint32 item, uint32 count, uint32 *no_space_count=nullptr) const
Definition: Player.h:1248
bool CanUseAttackType(uint8 attacktype) const
Definition: Unit.h:1607
bool IsFullHealth() const
Definition: Unit.h:1443
uint32 GetMaxPower(Powers power) const
Definition: Unit.h:1462
uint32 GetPower(Powers power) const
Definition: Unit.h:1461
bool HaveLootFor(uint32 loot_id) const
Definition: LootMgr.h:224
uint32 GetItemTargetEntry() const
Definition: Spell.h:140
ObjectGuid m_castItemGUID
Definition: Spell.h:523
uint32 BaseLevel
Definition: SpellInfo.h:357
uint32 MaxLevel
Definition: SpellInfo.h:356
std::array< int32, MAX_SPELL_REAGENTS > Reagent
Definition: SpellInfo.h:371
flag96 SpellFamilyFlags
Definition: SpellInfo.h:386
std::array< uint32, 2 > TotemCategory
Definition: SpellInfo.h:376
int32 EquippedItemClass
Definition: SpellInfo.h:373
std::array< uint32, 2 > Totem
Definition: SpellInfo.h:370
std::array< uint32, MAX_SPELL_REAGENTS > ReagentCount
Definition: SpellInfo.h:372
Definition: DBCStructure.h:1817
uint32 type[MAX_SPELL_ITEM_ENCHANTMENT_EFFECTS]
Definition: DBCStructure.h:1820
uint32 slot
Definition: DBCStructure.h:1827

References _triggeredCastFlags, BASE_ATTACK, SpellInfo::BaseLevel, Player::CanNoReagentCast(), Player::CanStoreNewItem(), Unit::CanUseAttackType(), Unit::CastSpell(), ItemTemplate::Class, _Socket::Color, ItemTemplate::DisenchantID, SpellInfo::DmgClass, EFFECT_1, SpellInfo::Effects, ENCHANTMENT_CAN_SOULBOUND, EQUIP_ERR_INVENTORY_FULL, EQUIP_ERR_OK, SpellInfo::EquippedItemClass, ItemTemplate::Flags, 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::GetTypeId(), Object::GetUInt32Value(), SpellCastTargets::GetUnitTarget(), Player::GetWeaponForAttack(), SpellInfo::HasAttribute(), Unit::HasAura(), Player::HasItemCount(), Player::HasItemFitToSpellRequirements(), Player::HasItemTotemCategory(), LootStore::HaveLootFor(), Item::IsArmorVellum(), Item::IsBroken(), Item::IsFitToSpellRequirements(), Unit::IsFullHealth(), 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(), Object::SetUInt32Value(), SKILL_ENCHANTING, SKILL_INSCRIPTION, SKILL_JEWELCRAFTING, SpellItemEnchantmentEntry::slot, sObjectMgr, ItemTemplate::Socket, SPELL_ATTR3_REQUIRES_MAIN_HAND_WEAPON, SPELL_ATTR3_REQUIRES_OFF_HAND_WEAPON, SPELL_CAST_OK, SPELL_DAMAGE_CLASS_MELEE, SPELL_DAMAGE_CLASS_RANGED, SPELL_EFFECT_CREATE_ITEM, SPELL_EFFECT_CREATE_ITEM_2, SPELL_EFFECT_CREATE_MANA_GEM, SPELL_EFFECT_CREATE_RANDOM_ITEM, SPELL_EFFECT_DISENCHANT, SPELL_EFFECT_ENCHANT_HELD_ITEM, SPELL_EFFECT_ENCHANT_ITEM, SPELL_EFFECT_ENCHANT_ITEM_PRISMATIC, SPELL_EFFECT_ENCHANT_ITEM_TEMPORARY, SPELL_EFFECT_ENERGIZE, SPELL_EFFECT_HEAL, SPELL_EFFECT_MILLING, SPELL_EFFECT_PROSPECTING, SPELL_EFFECT_WEAPON_DAMAGE, SPELL_EFFECT_WEAPON_DAMAGE_NOSCHOOL, SPELL_FAILED_ALREADY_AT_FULL_HEALTH, SPELL_FAILED_ALREADY_AT_FULL_POWER, SPELL_FAILED_BAD_TARGETS, SPELL_FAILED_CANT_BE_DISENCHANTED, SPELL_FAILED_CANT_BE_MILLED, SPELL_FAILED_CANT_BE_PROSPECTED, SPELL_FAILED_DONT_REPORT, SPELL_FAILED_EQUIPPED_ITEM, SPELL_FAILED_EQUIPPED_ITEM_CLASS, SPELL_FAILED_EQUIPPED_ITEM_CLASS_MAINHAND, SPELL_FAILED_EQUIPPED_ITEM_CLASS_OFFHAND, SPELL_FAILED_ERROR, SPELL_FAILED_HIGHLEVEL, SPELL_FAILED_ITEM_AT_MAX_CHARGES, SPELL_FAILED_ITEM_GONE, SPELL_FAILED_ITEM_NOT_FOUND, SPELL_FAILED_ITEM_NOT_READY, SPELL_FAILED_LOW_CASTLEVEL, SPELL_FAILED_LOWLEVEL, SPELL_FAILED_MAX_SOCKETS, SPELL_FAILED_NEED_MORE_ITEMS, SPELL_FAILED_NO_AMMO, SPELL_FAILED_NO_CHARGES_REMAIN, SPELL_FAILED_NOT_TRADEABLE, SPELL_FAILED_ON_USE_ENCHANT, SPELL_FAILED_REAGENTS, SPELL_FAILED_TARGET_NOT_PLAYER, SPELL_FAILED_TOO_MANY_OF_ITEM, SPELL_FAILED_TOTEM_CATEGORY, SPELL_FAILED_TOTEMS, _Spell::SpellCharges, SPELLFAMILY_MAGE, SpellInfo::SpellFamilyFlags, SpellInfo::SpellFamilyName, _Spell::SpellId, ItemTemplate::Spells, _Spell::SpellTrigger, sSpellItemEnchantmentStore, ItemTemplate::SubClass, TARGET_UNIT_PET, Object::ToPlayer(), SpellInfo::Totem, SpellInfo::TotemCategory, TRIGGERED_IGNORE_POWER_AND_REAGENT_COST, SpellItemEnchantmentEntry::type, and TYPEID_PLAYER.

Referenced by CheckCast().

◆ CheckPetCast()

SpellCastResult Spell::CheckPetCast ( Unit target)
6784{
6785 if (m_caster->HasUnitState(UNIT_STATE_CASTING) && !(_triggeredCastFlags & TRIGGERED_IGNORE_CAST_IN_PROGRESS)) //prevent spellcast interruption by another spellcast
6787
6788 // dead owner (pets still alive when owners ressed?)
6789 if (Unit* owner = m_caster->GetCharmerOrOwner())
6790 if (!owner->IsAlive() && m_caster->GetEntry() != 30230) // Rise Ally
6792
6793 if (!target && m_targets.GetUnitTarget())
6794 target = m_targets.GetUnitTarget();
6795
6797 {
6798 if (!target)
6800 m_targets.SetUnitTarget(target);
6801 }
6802
6803 // xinef: Calculate power cost here, so funciton checking power can work properly and dont return bad results
6805
6806 // cooldown
6807 if (Creature const* creatureCaster = m_caster->ToCreature())
6808 if (creatureCaster->HasSpellCooldown(m_spellInfo->Id))
6810
6811 // Check if spell is affected by GCD
6815
6816 return CheckCast(true);
6817}
bool HasGlobalCooldown(SpellInfo const *spellInfo) const
Definition: Unit.cpp:341
void SetUnitTarget(Unit *target)
Definition: Spell.cpp:233
int32 CalcPowerCost(Unit const *caster, SpellSchoolMask schoolMask, Spell *spell=nullptr) const
Definition: SpellInfo.cpp:2384
uint32 StartRecoveryCategory
Definition: SpellInfo.h:348

References _triggeredCastFlags, SpellInfo::CalcPowerCost(), CheckCast(), Unit::GetCharmerOrOwner(), Unit::GetCharmInfo(), Object::GetEntry(), CharmInfo::GetGlobalCooldownMgr(), SpellCastTargets::GetUnitTarget(), GlobalCooldownMgr::HasGlobalCooldown(), 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 ( )
7103{
7104 // item cast not used power
7105 if (m_CastItem)
7106 return SPELL_CAST_OK;
7107
7108 //While .cheat power is enabled dont check if we need power to cast the spell
7110 {
7112 {
7113 return SPELL_CAST_OK;
7114 }
7115 }
7116
7117 // health as power used - need check health amount
7119 {
7122 return SPELL_CAST_OK;
7123 }
7124 // Check valid power type
7126 {
7127 LOG_ERROR("spells", "Spell::CheckPower: Unknown power type '{}'", m_spellInfo->PowerType);
7128 return SPELL_FAILED_UNKNOWN;
7129 }
7130
7131 //check rune cost only if a spell has PowerType == POWER_RUNE
7133 {
7135 if (failReason != SPELL_CAST_OK)
7136 return failReason;
7137 }
7138
7139 // Check power amount
7142 return SPELL_FAILED_NO_POWER;
7143 else
7144 return SPELL_CAST_OK;
7145}
@ CHEAT_POWER
Definition: Player.h:994
PowerType
Definition: VehicleDefines.h:30
@ POWER_HEALTH
Definition: SharedDefines.h:250
@ POWER_RUNE
Definition: SharedDefines.h:246
@ SPELL_FAILED_NO_POWER
Definition: SharedDefines.h:1006
@ SPELL_FAILED_UNKNOWN
Definition: SharedDefines.h:1108
uint32 GetHealth() const
Definition: Unit.h:1440
SpellCastResult CheckRuneCost(uint32 RuneCostID)
Definition: Spell.cpp:5370
uint32 RuneCostID
Definition: SpellInfo.h:366
uint32 PowerType
Definition: SpellInfo.h:360

References CHEAT_POWER, CheckRuneCost(), Player::GetCommandStatus(), Unit::GetHealth(), Unit::GetPower(), Object::GetTypeId(), 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, Object::ToPlayer(), and TYPEID_PLAYER.

Referenced by CheckCast().

◆ CheckRange()

SpellCastResult Spell::CheckRange ( bool  strict)
7017{
7018 // Don't check for instant cast spells
7019 if (!strict && m_casttime == 0)
7020 return SPELL_CAST_OK;
7021
7022 uint32 range_type = 0;
7023
7025 {
7026 // check needed by 68766 51693 - both spells are cast on enemies and have 0 max range
7027 // these are triggered by other spells - possibly we should omit range check in that case?
7028 if (m_spellInfo->RangeEntry->ID == 1)
7029 return SPELL_CAST_OK;
7030
7031 range_type = m_spellInfo->RangeEntry->Flags;
7032 }
7033
7034 Unit* target = m_targets.GetUnitTarget();
7035 float max_range = m_caster->GetSpellMaxRangeForTarget(target, m_spellInfo);
7036 float min_range = m_caster->GetSpellMinRangeForTarget(target, m_spellInfo);
7037
7038 // xinef: hack for npc shooters
7039 if (min_range && GetCaster()->GetTypeId() == TYPEID_UNIT && !GetCaster()->GetOwnerGUID().IsPlayer() && min_range <= 6.0f)
7040 range_type = SPELL_RANGE_RANGED;
7041
7042 if (Player* modOwner = m_caster->GetSpellModOwner())
7043 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_RANGE, max_range, this);
7044
7045 // xinef: dont check max_range to strictly after cast
7046 if (range_type != SPELL_RANGE_MELEE && !strict)
7047 max_range += std::min(3.0f, max_range * 0.1f); // 10% but no more than 3yd
7048
7049 if (target)
7050 {
7051 if (target != m_caster)
7052 {
7053 // Xinef: Spells with 5yd range can hit target 9yd away?
7054 if (range_type == SPELL_RANGE_MELEE)
7055 {
7056 float real_max_range = max_range;
7057 if (m_caster->GetTypeId() != TYPEID_UNIT && m_caster->isMoving() && target->isMoving() && !m_caster->IsWalking() && !target->IsWalking())
7058 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)
7059 else
7060 real_max_range -= 2 * MIN_MELEE_REACH;
7061
7062 if (!m_caster->IsWithinMeleeRange(target, std::max(real_max_range, 0.0f)))
7064 }
7065 else if (!m_caster->IsWithinCombatRange(target, max_range))
7066 return SPELL_FAILED_OUT_OF_RANGE; //0x5A;
7067
7069 {
7070 if (m_caster->IsWithinMeleeRange(target))
7072 }
7073
7074 if (m_caster->GetTypeId() == TYPEID_PLAYER && (m_spellInfo->FacingCasterFlags & SPELL_FACING_FLAG_INFRONT) && !m_caster->HasInArc(static_cast<float>(M_PI), target))
7076 }
7077
7078 // Xinef: check min range for self casts
7079 if (min_range && range_type != SPELL_RANGE_RANGED && m_caster->IsWithinCombatRange(target, min_range)) // skip this check if min_range = 0
7081 }
7082
7083 if (GameObject* goTarget = m_targets.GetGOTarget())
7084 {
7085 if (!goTarget->IsAtInteractDistance(m_caster->ToPlayer(), m_spellInfo))
7086 {
7088 }
7089 }
7090
7091 if (m_targets.HasDst() && !m_targets.HasTraj())
7092 {
7093 if (!m_caster->IsWithinDist3d(m_targets.GetDstPos(), max_range))
7095 if (min_range && m_caster->IsWithinDist3d(m_targets.GetDstPos(), min_range))
7097 }
7098
7099 return SPELL_CAST_OK;
7100}
#define MIN_MELEE_REACH
Definition: ObjectDefines.h:47
@ SPELL_RANGE_MELEE
Definition: Spell.h:89
@ SPELL_RANGE_RANGED
Definition: Spell.h:90
@ SPELLMOD_RANGE
Definition: SpellDefines.h:82
@ SPELL_FACING_FLAG_INFRONT
Definition: SpellDefines.h:126
@ SPELL_FAILED_TOO_CLOSE
Definition: SharedDefines.h:1049
@ SPELL_FAILED_OUT_OF_RANGE
Definition: SharedDefines.h:1018
bool IsWithinDist3d(float x, float y, float z, float dist) const
Definition: Object.cpp:1295
bool HasInArc(float arcangle, const Position *pos, float targetRadius=0.0f) const
Definition: Position.cpp:140
bool IsWithinCombatRange(Unit const *obj, float dist2compare) const
Definition: Unit.cpp:667
float GetSpellMinRangeForTarget(Unit const *target, SpellInfo const *spellInfo) const
Definition: Unit.cpp:15059
bool IsWithinMeleeRange(Unit const *obj, float dist=0.f) const
Definition: Unit.cpp:683
float GetSpellMaxRangeForTarget(Unit const *target, SpellInfo const *spellInfo) const
Definition: Unit.cpp:15039
bool IsWalking() const
Definition: Unit.h:2379
Unit * GetCaster() const
Definition: Spell.h:572
SpellRangeEntry const * RangeEntry
Definition: SpellInfo.h:367
uint32 FacingCasterFlags
Definition: SpellInfo.h:336
uint32 Flags
Definition: DBCStructure.h:1772
uint32 ID
Definition: DBCStructure.h:1769

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

Referenced by CheckCast().

◆ CheckRuneCost()

SpellCastResult Spell::CheckRuneCost ( uint32  RuneCostID)
5371{
5372 if (m_spellInfo->PowerType != POWER_RUNE || !RuneCostID)
5373 return SPELL_CAST_OK;
5374
5376 return SPELL_CAST_OK;
5377
5378 Player* player = m_caster->ToPlayer();
5379 //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)
5380 if (player->GetCommandStatus(CHEAT_POWER))
5381 {
5382 return SPELL_CAST_OK;
5383 }
5384
5385 if (player->getClass() != CLASS_DEATH_KNIGHT)
5386 return SPELL_CAST_OK;
5387
5388 SpellRuneCostEntry const* src = sSpellRuneCostStore.LookupEntry(RuneCostID);
5389
5390 if (!src)
5391 return SPELL_CAST_OK;
5392
5393 if (src->NoRuneCost())
5394 return SPELL_CAST_OK;
5395
5396 int32 runeCost[NUM_RUNE_TYPES]; // blood, frost, unholy, death
5397
5398 for (uint32 i = 0; i < RUNE_DEATH; ++i)
5399 {
5400 runeCost[i] = src->RuneCost[i];
5401 if (Player* modOwner = m_caster->GetSpellModOwner())
5402 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_COST, runeCost[i], this);
5403 }
5404
5405 runeCost[RUNE_DEATH] = MAX_RUNES; // calculated later
5406
5407 for (uint32 i = 0; i < MAX_RUNES; ++i)
5408 {
5409 RuneType rune = player->GetCurrentRune(i);
5410 if ((player->GetRuneCooldown(i) == 0) && (runeCost[rune] > 0))
5411 runeCost[rune]--;
5412 }
5413
5414 for (uint32 i = 0; i < RUNE_DEATH; ++i)
5415 if (runeCost[i] > 0)
5416 runeCost[RUNE_DEATH] += runeCost[i];
5417
5418 if (runeCost[RUNE_DEATH] > MAX_RUNES)
5419 return SPELL_FAILED_NO_POWER; // not sure if result code is correct
5420
5421 return SPELL_CAST_OK;
5422}
DBCStorage< SpellRuneCostEntry > sSpellRuneCostStore(SpellRuneCostfmt)
RuneType
Definition: Player.h:409
@ RUNE_DEATH
Definition: Player.h:413
@ NUM_RUNE_TYPES
Definition: Player.h:414
#define MAX_RUNES
Definition: Player.h:399
@ SPELLMOD_COST
Definition: SpellDefines.h:91
@ CLASS_DEATH_KNIGHT
Definition: SharedDefines.h:118
uint32 GetRuneCooldown(uint8 index) const
Definition: Player.h:2458
RuneType GetCurrentRune(uint8 index) const
Definition: Player.h:2457
Definition: DBCStructure.h:1780
uint32 RuneCost[3]
Definition: DBCStructure.h:1782
bool NoRuneCost() const
Definition: DBCStructure.h:1785

References CHEAT_POWER, CLASS_DEATH_KNIGHT, Unit::getClass(), Player::GetCommandStatus(), Player::GetCurrentRune(), Player::GetRuneCooldown(), Unit::GetSpellModOwner(), Object::GetTypeId(), SpellInfo::Id, 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, Object::ToPlayer(), and TYPEID_PLAYER.

Referenced by CheckPower().

◆ CheckScriptEffectImplicitTargets()

bool Spell::CheckScriptEffectImplicitTargets ( uint32  effIndex,
uint32  effIndexToCheck 
)
protected
8672{
8673 // Skip if there are not any script
8674 if (!m_loadedScripts.size())
8675 return true;
8676
8677 for (std::list<SpellScript*>::iterator itr = m_loadedScripts.begin(); itr != m_loadedScripts.end(); ++itr)
8678 {
8679 std::list<SpellScript::ObjectTargetSelectHandler>::iterator targetSelectHookEnd = (*itr)->OnObjectTargetSelect.end(), targetSelectHookItr = (*itr)->OnObjectTargetSelect.begin();
8680 for (; targetSelectHookItr != targetSelectHookEnd; ++targetSelectHookItr)
8681 if (((*targetSelectHookItr).IsEffectAffected(m_spellInfo, effIndex) && !(*targetSelectHookItr).IsEffectAffected(m_spellInfo, effIndexToCheck)) ||
8682 (!(*targetSelectHookItr).IsEffectAffected(m_spellInfo, effIndex) && (*targetSelectHookItr).IsEffectAffected(m_spellInfo, effIndexToCheck)))
8683 return false;
8684
8685 std::list<SpellScript::ObjectAreaTargetSelectHandler>::iterator areaTargetSelectHookEnd = (*itr)->OnObjectAreaTargetSelect.end(), areaTargetSelectHookItr = (*itr)->OnObjectAreaTargetSelect.begin();
8686 for (; areaTargetSelectHookItr != areaTargetSelectHookEnd; ++areaTargetSelectHookItr)
8687 if (((*areaTargetSelectHookItr).IsEffectAffected(m_spellInfo, effIndex) && !(*areaTargetSelectHookItr).IsEffectAffected(m_spellInfo, effIndexToCheck)) ||
8688 (!(*areaTargetSelectHookItr).IsEffectAffected(m_spellInfo, effIndex) && (*areaTargetSelectHookItr).IsEffectAffected(m_spellInfo, effIndexToCheck)))
8689 return false;
8690 }
8691 return true;
8692}

References m_loadedScripts, and m_spellInfo.

Referenced by SelectEffectImplicitTargets().

◆ CheckSpellFocus()

SpellCastResult Spell::CheckSpellFocus ( )
7716{
7717 // check spell focus object
7719 {
7721 Cell cell(p);
7722
7723 GameObject* ok = nullptr;
7726
7728 Map& map = *m_caster->GetMap();
7729 cell.Visit(p, object_checker, map, *m_caster, m_caster->GetVisibilityRange());
7730
7731 if (!ok)
7733
7734 focusObject = ok; // game object found in range
7735 }
7736 return SPELL_CAST_OK;
7737}
@ SPELL_FAILED_REQUIRES_SPELL_FOCUS
Definition: SharedDefines.h:1023
CellCoord ComputeCellCoord(float x, float y)
Definition: GridDefines.h:191
Definition: TypeContainer.h:103
Definition: TypeContainerVisitor.h:85
Definition: Cell.h:46
Definition: GridNotifiers.h:316
Definition: GridNotifiers.h:654
Definition: Map.h:312
void Visit(const Cell &cell, TypeContainerVisitor< T, CONTAINER > &visitor)
Definition: Map.h:867
uint32 RequiresSpellFocus
Definition: SpellInfo.h:335

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:164
void SetSrc(float x, float y, float z)
Definition: Spell.cpp:361

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

◆ CleanupTargetList()

void Spell::CleanupTargetList ( )
2357{
2358 m_UniqueTargetInfo.clear();
2359 m_UniqueGOTargetInfo.clear();
2360 m_UniqueItemInfo.clear();
2361 m_delayMoment = 0;
2363}
uint64 m_delayTrajectory
Definition: Spell.h:639

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 ( )
7740{
7741 if (!m_caster)// || m_caster->GetTypeId() != TYPEID_PLAYER)
7742 return;
7743
7744 //if (m_spellState == SPELL_STATE_DELAYED)
7745 // return; // spell is active and can't be time-backed
7746
7747 if (isDelayableNoMore()) // Spells may only be delayed twice
7748 return;
7749
7750 // spells not loosing casting time (slam, dynamites, bombs..)
7751 //if (!(m_spellInfo->InterruptFlags & SPELL_INTERRUPT_FLAG_DAMAGE))
7752 // return;
7753
7754 //check pushback reduce
7755 int32 delaytime = 500; // spellcasting delay is normally 500ms
7756 int32 delayReduce = 100; // must be initialized to 100 for percent modifiers
7759 if (delayReduce >= 100)
7760 return;
7761
7762 AddPct(delaytime, -delayReduce);
7763
7764 if (m_timer + delaytime > m_casttime)
7765 {
7766 delaytime = m_casttime - m_timer;
7768 }
7769 else
7770 m_timer += delaytime;
7771
7772 LOG_DEBUG("spells", "Spell {} partially interrupted for ({}) ms at damage", m_spellInfo->Id, delaytime);
7773
7774 WorldPacket data(SMSG_SPELL_DELAYED, 8 + 4);
7775 data << m_caster->GetPackGUID();
7776 data << uint32(delaytime);
7777
7778 m_caster->SendMessageToSet(&data, true);
7779}
#define LOG_DEBUG(filterType__,...)
Definition: Log.h:171
T AddPct(T &base, U pct)
Definition: Util.h:67
@ SPELL_AURA_REDUCE_PUSHBACK
Definition: SpellAuraDefines.h:212
@ SPELLMOD_NOT_LOSE_CASTING_TIME
Definition: SpellDefines.h:86
@ SMSG_SPELL_DELAYED
Definition: Opcodes.h:512
PackedGuid const & GetPackGUID() const
Definition: Object.h:108
virtual void SendMessageToSet(WorldPacket const *data, bool self) const
Definition: Object.h:482
void ApplySpellMod(uint32 spellId, SpellModOp op, T &basevalue, Spell *spell=nullptr, bool temporaryPet=false)
Definition: Player.cpp:9627
int32 GetTotalAuraModifier(AuraType auratype) const
Definition: Unit.cpp:5822
Definition: WorldPacket.h:27
bool isDelayableNoMore()
Definition: Spell.h:627

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

◆ DelayedChannel()

void Spell::DelayedChannel ( )
7782{
7784 return;
7785
7786 if (isDelayableNoMore()) // Spells may only be delayed twice
7787 return;
7788
7789 //check pushback reduce
7790 // should be affected by modifiers, not take the dbc duration.
7792
7793 int32 delaytime = CalculatePct(duration, 25); // channeling delay is normally 25% of its time per hit
7794 int32 delayReduce = 100; // must be initialized to 100 for percent modifiers
7797 if (delayReduce >= 100)
7798 return;
7799
7800 AddPct(delaytime, -delayReduce);
7801
7802 if (m_timer <= delaytime)
7803 {
7804 delaytime = m_timer;
7805 m_timer = 0;
7806 }
7807 else
7808 m_timer -= delaytime;
7809
7810 LOG_DEBUG("spells.aura", "Spell {} partially interrupted for {} ms, new duration: {} ms", m_spellInfo->Id, delaytime, m_timer);
7811
7812 for (std::list<TargetInfo>::const_iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
7813 if ((*ihit).missCondition == SPELL_MISS_NONE)
7814 if (Unit* unit = (m_caster->GetGUID() == ihit->targetGUID) ? m_caster : ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID))
7815 unit->DelayOwnedAuras(m_spellInfo->Id, m_originalCasterGUID, delaytime);
7816
7817 // partially interrupt persistent area auras
7819 dynObj->Delay(delaytime);
7820
7822}
T CalculatePct(T base, U pct)
Definition: Util.h:61
Definition: DynamicObject.h:35
DynamicObject * GetDynObject(uint32 spellId)
Definition: Unit.cpp:6040
uint32 getState() const
Definition: Spell.h:482
int32 GetDuration() const
Definition: SpellInfo.cpp:2321

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

◆ DoAllEffectOnLaunchTarget()

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

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

Referenced by HandleLaunchPhase().

◆ DoAllEffectOnTarget() [1/3]

void Spell::DoAllEffectOnTarget ( GOTargetInfo target)
protected
3316{
3317 if (target->processed) // Check target
3318 return;
3319 target->processed = true; // Target checked in apply effects procedure
3320
3321 uint32 effectMask = target->effectMask;
3322 if (!effectMask)
3323 return;
3324
3325 GameObject* go = m_caster->GetMap()->GetGameObject(target->targetGUID);
3326 if (!go)
3327 return;
3328
3331
3332 for (uint32 effectNumber = 0; effectNumber < MAX_SPELL_EFFECTS; ++effectNumber)
3333 if (effectMask & (1 << effectNumber))
3334 HandleEffects(nullptr, nullptr, go, effectNumber, SPELL_EFFECT_HANDLE_HIT_TARGET);
3335
3336 // xinef: inform ai about spellhit
3338
3340
3342}
virtual void SpellHit(Unit *, SpellInfo const *)
Definition: GameObjectAI.h:67
GameObjectAI * AI() const
Definition: GameObject.h:310
void CallScriptBeforeHitHandlers(SpellMissInfo missInfo)
Definition: Spell.cpp:8590
void CallScriptOnHitHandlers()
Definition: Spell.cpp:8603
void CallScriptAfterHitHandlers()
Definition: Spell.cpp:8616

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
3345{
3346 uint32 effectMask = target->effectMask;
3347 if (!target->item || !effectMask)
3348 return;
3349
3352
3353 for (uint32 effectNumber = 0; effectNumber < MAX_SPELL_EFFECTS; ++effectNumber)
3354 if (effectMask & (1 << effectNumber))
3355 HandleEffects(nullptr, target->item, nullptr, effectNumber, SPELL_EFFECT_HANDLE_HIT_TARGET);
3356
3358
3360}

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
2595{
2596 if (!target || target->processed)
2597 return;
2598
2599 target->processed = true; // Target checked in apply effects procedure
2600
2601 // Get mask of effects for target
2602 uint8 mask = target->effectMask;
2603
2604 Unit* effectUnit = m_caster->GetGUID() == target->targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, target->targetGUID);
2605 if (!effectUnit && !target->targetGUID.IsPlayer()) // only players may be targeted across maps
2606 return;
2607
2608 if (!effectUnit || m_spellInfo->Id == 45927)
2609 {
2610 uint8 farMask = 0;
2611 // create far target mask
2612 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
2613 if (m_spellInfo->Effects[i].IsFarUnitTargetEffect())
2614 if ((1 << i) & mask)
2615 farMask |= (1 << i);
2616
2617 if (!farMask)
2618 return;
2619 // find unit in world
2620 // Xinef: FindUnit Access without Map check!!! Intended
2621 effectUnit = ObjectAccessor::FindPlayer(target->targetGUID);
2622 if (!effectUnit)
2623 return;
2624
2625 // do far effects on the unit
2626 // can't use default call because of threading, do stuff as fast as possible
2627 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
2628 if (farMask & (1 << i))
2629 HandleEffects(effectUnit, nullptr, nullptr, i, SPELL_EFFECT_HANDLE_HIT_TARGET);
2630 return;
2631 }
2632
2633 if (effectUnit->IsAlive() != target->alive)
2634 return;
2635
2636 // Xinef: absorb delayed projectiles for 500ms
2638 (GameTime::GetGameTimeMS().count() - target->timeDelay) <= effectUnit->m_lastSanctuaryTime && GameTime::GetGameTimeMS().count() < (effectUnit->m_lastSanctuaryTime + 500) &&
2639 effectUnit->FindMap() && !effectUnit->FindMap()->IsDungeon()
2640 )
2641 return; // No missinfo in that case
2642
2643 // Get original caster (if exist) and calculate damage/healing from him data
2645
2646 // Skip if m_originalCaster not avaiable
2647 if (!caster)
2648 return;
2649
2650 SpellMissInfo missInfo = target->missCondition;
2651
2652 // Need init unitTarget by default unit (can changed in code on reflect)
2653 // Or on missInfo != SPELL_MISS_NONE unitTarget undefined (but need in trigger subsystem)
2654 unitTarget = effectUnit;
2655
2656 // Reset damage/healing counter
2657 m_damage = target->damage;
2658 m_healing = -target->damage;
2659
2660 m_spellAura = nullptr; // Set aura to null for every target-make sure that pointer is not used for unit without aura applied
2661
2664
2665 //Spells with this flag cannot trigger if effect is casted on self
2667 bool reflectedSpell = missInfo == SPELL_MISS_REFLECT;
2668 Unit* spellHitTarget = nullptr;
2669
2670 if (missInfo == SPELL_MISS_NONE) // In case spell hit target, do all effect on that target
2671 spellHitTarget = unitTarget;
2672 else if (missInfo == SPELL_MISS_REFLECT) // In case spell reflect from target, do all effect on caster (if hit)
2673 {
2674 missInfo = target->reflectResult;
2675 if (missInfo == SPELL_MISS_NONE) // If reflected spell hit caster -> do all effect on him
2676 {
2677 spellHitTarget = m_caster;
2679 if (m_caster->GetTypeId() == TYPEID_UNIT)
2681 }
2682 }
2683
2684 if (spellHitTarget)
2685 {
2686 SpellMissInfo missInfo2 = DoSpellHitOnUnit(spellHitTarget, mask, target->scaleAura);
2687 if (missInfo2 != SPELL_MISS_NONE)
2688 {
2689 if (missInfo2 != SPELL_MISS_MISS)
2690 m_caster->SendSpellMiss(spellHitTarget, m_spellInfo->Id, missInfo2);
2691 m_damage = 0;
2692 spellHitTarget = nullptr;
2693
2694 // Xinef: if missInfo2 is MISS_EVADE, override base missinfo data
2695 if (missInfo2 == SPELL_MISS_EVADE)
2696 missInfo = SPELL_MISS_EVADE;
2697 }
2698 }
2699
2700 // Do not take combo points on dodge and miss
2701 if (missInfo != SPELL_MISS_NONE && m_needComboPoints && m_targets.GetUnitTargetGUID() == target->targetGUID)
2702 {
2703 m_needComboPoints = false;
2704 // Restore spell mods for a miss/dodge/parry Cold Blood
2706 if (m_caster->GetTypeId() == TYPEID_PLAYER && (missInfo == SPELL_MISS_MISS || missInfo == SPELL_MISS_DODGE || missInfo == SPELL_MISS_PARRY))
2707 m_caster->ToPlayer()->RestoreSpellMods(this, 14177);
2708 }
2709
2710 // Fill base trigger info
2711 uint32 procAttacker = m_procAttacker;
2712 uint32 procVictim = m_procVictim;
2713 uint32 procEx = m_procEx;
2714
2715 // Trigger info was not filled in spell::preparedatafortriggersystem - we do it now
2716 if (canEffectTrigger && !procAttacker && !procVictim)
2717 {
2718 bool positive = true;
2719 if (m_damage > 0)
2720 positive = false;
2721 else if (!m_healing)
2722 {
2723 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
2724 // If at least one effect negative spell is negative hit
2725 // Xinef: if missInfo is immune state check all effects to properly determine positiveness of spell
2726 if ((missInfo == SPELL_MISS_IMMUNE2 || (mask & (1 << i))) && !m_spellInfo->IsPositiveEffect(i))
2727 {
2728 positive = false;
2729 break;
2730 }
2731 }
2732 switch (m_spellInfo->DmgClass)
2733 {
2735 if (positive)
2736 {
2739 }
2740 else
2741 {
2744 }
2745 break;
2747 if (positive)
2748 {
2751 }
2752 else
2753 {
2756 }
2757 break;
2758 }
2759 }
2761
2762 // All calculated do it!
2763 // Do healing and triggers
2764 if (m_healing > 0)
2765 {
2766 bool crit = target->crit;
2767 uint32 addhealth = m_healing;
2768
2769 if (crit)
2770 {
2771 procEx |= PROC_EX_CRITICAL_HIT;
2772 addhealth = Unit::SpellCriticalHealingBonus(caster, m_spellInfo, addhealth, nullptr);
2773 }
2774 else
2775 procEx |= PROC_EX_NORMAL_HIT;
2776
2777 HealInfo healInfo(caster, unitTarget, addhealth, m_spellInfo, m_spellInfo->GetSchoolMask());
2778
2779 // Xinef: override with forced crit, only visual result
2780 if (GetSpellValue()->ForcedCritResult)
2781 {
2782 crit = true;
2783 procEx |= PROC_EX_CRITICAL_HIT;
2784 }
2785
2786 int32 gain = caster->HealBySpell(healInfo, crit);
2787 unitTarget->getHostileRefMgr().threatAssist(caster, float(gain) * 0.5f, m_spellInfo);
2788 m_healing = gain;
2789
2790 // Xinef: if heal acutally healed something, add no overheal flag
2791 if (m_healing)
2792 procEx |= PROC_EX_NO_OVERHEAL;
2793
2794 // Do triggers for unit (reflect triggers passed on hit phase for correct drop charge)
2795 if (canEffectTrigger)
2796 Unit::ProcDamageAndSpell(caster, unitTarget, procAttacker, procVictim, procEx, addhealth, m_attackType, m_spellInfo, m_triggeredByAuraSpell.spellInfo,
2797 m_triggeredByAuraSpell.effectIndex, this, nullptr, &healInfo);
2798 }
2799 // Do damage and triggers
2800 else if (m_damage > 0)
2801 {
2803
2804 // Fill base damage struct (unitTarget - is real spell target)
2806
2807 // Add bonuses and fill damageInfo struct
2808 // Dancing Rune Weapon...
2809 if (m_caster->GetEntry() == 27893)
2810 {
2811 if (Unit* owner = m_caster->GetOwner())
2812 owner->CalculateSpellDamageTaken(&damageInfo, m_damage, m_spellInfo, m_attackType, target->crit);
2813 }
2814 else
2815 caster->CalculateSpellDamageTaken(&damageInfo, m_damage, m_spellInfo, m_attackType, target->crit);
2816
2817 // xinef: override miss info after absorb / block calculations
2818 if (missInfo == SPELL_MISS_NONE && damageInfo.damage == 0)
2819 {
2820 //if (damageInfo.absorb > 0)
2821 // missInfo = SPELL_MISS_ABSORB;
2822 if (damageInfo.blocked)
2823 missInfo = SPELL_MISS_BLOCK;
2824 }
2825
2826 // Xinef: override with forced crit, only visual result
2827 if (GetSpellValue()->ForcedCritResult)
2828 {
2829 damageInfo.HitInfo |= SPELL_HIT_TYPE_CRIT;
2830 }
2831
2832 Unit::DealDamageMods(damageInfo.target, damageInfo.damage, &damageInfo.absorb);
2833
2834 // xinef: health leech handling
2836 {
2837 uint8 effIndex = EFFECT_0;
2838 for (; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
2839 if (m_spellInfo->Effects[effIndex].Effect == SPELL_EFFECT_HEALTH_LEECH)
2840 break;
2841
2842 float healMultiplier = m_spellInfo->Effects[effIndex].CalcValueMultiplier(m_originalCaster, this);
2843
2844 // get max possible damage, don't count overkill for heal
2845 uint32 healthGain = uint32(-unitTarget->GetHealthGain(-int32(damageInfo.damage)) * healMultiplier);
2846
2847 if (m_caster->IsAlive())
2848 {
2849 healthGain = m_caster->SpellHealingBonusDone(m_caster, m_spellInfo, healthGain, HEAL, effIndex);
2850 healthGain = m_caster->SpellHealingBonusTaken(m_caster, m_spellInfo, healthGain, HEAL);
2851
2852 HealInfo healInfo(m_caster, m_caster, healthGain, m_spellInfo, m_spellInfo->GetSchoolMask());
2853 m_caster->HealBySpell(healInfo);
2854 }
2855 }
2856
2857 // Send log damage message to client
2858 caster->SendSpellNonMeleeDamageLog(&damageInfo);
2859 // Xinef: send info to target about reflect
2860 if (reflectedSpell)
2861 effectUnit->SendSpellNonMeleeReflectLog(&damageInfo, effectUnit);
2862
2863 procEx |= createProcExtendMask(&damageInfo, missInfo);
2864 procVictim |= PROC_FLAG_TAKEN_DAMAGE;
2865
2866 caster->DealSpellDamage(&damageInfo, true, this);
2867
2868 // do procs after damage, eg healing effects
2869 // no need to check if target is alive, done in procdamageandspell
2870
2871 // Do triggers for unit (reflect triggers passed on hit phase for correct drop charge)
2872 if (canEffectTrigger)
2873 {
2874 DamageInfo dmgInfo(damageInfo, SPELL_DIRECT_DAMAGE);
2875 Unit::ProcDamageAndSpell(caster, unitTarget, procAttacker, procVictim, procEx, damageInfo.damage, m_attackType, m_spellInfo, m_triggeredByAuraSpell.spellInfo,
2876 m_triggeredByAuraSpell.effectIndex, this, &dmgInfo);
2877
2880 caster->ToPlayer()->CastItemCombatSpell(unitTarget, m_attackType, procVictim, procEx);
2881 }
2882
2883 m_damage = damageInfo.damage;
2884 }
2885 // Passive spell hits/misses or active spells only misses (only triggers)
2886 else
2887 {
2888 // Fill base damage struct (unitTarget - is real spell target)
2890 procEx |= createProcExtendMask(&damageInfo, missInfo);
2891 // Do triggers for unit (reflect triggers passed on hit phase for correct drop charge)
2892 if (canEffectTrigger)
2893 {
2894 DamageInfo dmgInfo(damageInfo, NODAMAGE);
2895 Unit::ProcDamageAndSpell(caster, unitTarget, procAttacker, procVictim, procEx, 0, m_attackType, m_spellInfo, m_triggeredByAuraSpell.spellInfo,
2896 m_triggeredByAuraSpell.effectIndex, this, &dmgInfo);
2897
2898 // Xinef: eg. rogue poisons can proc off cheap shot, etc. so this block should be here also
2899 // Xinef: ofc count only spells that HIT the target, little hack used to fool the system
2903 }
2904
2905 // Failed Pickpocket, reveal rogue
2907 {
2911 }
2912 }
2913
2914 if (m_caster)
2915 {
2917 {
2919
2920 // 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.
2921 if (effectUnit->IsInCombatWith(m_caster))
2922 {
2923 if (Creature* creature = effectUnit->ToCreature())
2924 {
2925 if (!creature->hasLootRecipient() && m_caster->IsPlayer())
2926 {
2927 creature->SetLootRecipient(m_caster);
2928 }
2929 }
2930 }
2931
2932 // Unsure if there are more spells that are not supposed to stop enemy from
2933 // regenerating HP from food, so for now it stays as an ID.
2934 const uint32 SPELL_PREMEDITATION = 14183;
2935 if (m_spellInfo->Id != SPELL_PREMEDITATION)
2936 {
2937 if (!effectUnit->IsStandState())
2938 {
2940 }
2941 }
2942 }
2943 }
2944
2945 if (missInfo != SPELL_MISS_EVADE && effectUnit != m_caster && m_caster->IsFriendlyTo(effectUnit) && m_spellInfo->IsPositive() &&
2947 {
2948 m_caster->SetInCombatWith(effectUnit);
2949 }
2950
2951 // Check for SPELL_ATTR7_CAN_CAUSE_INTERRUPT
2953 caster->CastSpell(effectUnit, SPELL_INTERRUPT_NONPLAYER, true);
2954
2955 if (spellHitTarget)
2956 {
2957 //AI functions
2958 if (spellHitTarget->GetTypeId() == TYPEID_UNIT)
2959 {
2960 if (spellHitTarget->ToCreature()->IsAIEnabled)
2961 spellHitTarget->ToCreature()->AI()->SpellHit(m_caster, m_spellInfo);
2962 }
2963
2965 m_caster->ToCreature()->AI()->SpellHitTarget(spellHitTarget, m_spellInfo);
2966
2967 // Needs to be called after dealing damage/healing to not remove breaking on damage auras
2968 DoTriggersOnSpellHit(spellHitTarget, mask);
2969
2970 // if target is fallged for pvp also flag caster if a player
2971 // xinef: do not flag spells with aura bind sight (no special attribute)
2972 if (effectUnit->IsPvP() && effectUnit != m_caster && effectUnit->GetOwnerGUID() != m_caster->GetGUID() &&
2974 {
2975 m_caster->ToPlayer()->UpdatePvP(true);
2976 }
2977
2979 }
2980}
uint32 createProcExtendMask(SpellNonMeleeDamage *damageInfo, SpellMissInfo missCondition)
Definition: Unit.cpp:16168
@ UNIT_STAND_STATE_STAND
Definition: Unit.h:53
@ NODAMAGE
Definition: Unit.h:439
@ SPELL_DIRECT_DAMAGE
Definition: Unit.h:436
@ HEAL
Definition: Unit.h:438
static const uint32 SPELL_INTERRUPT_NONPLAYER
Definition: Spell.h:267
@ AURA_INTERRUPT_FLAG_TALK
Definition: SpellDefines.h:54
@ 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
@ SPELL_EFFECT_HEALTH_LEECH
Definition: SharedDefines.h:759
@ SPELL_ATTR1_NO_THREAT
Definition: SharedDefines.h:401
@ SPELL_ATTR3_SUPRESS_CASTER_PROCS
Definition: SharedDefines.h:481
@ SPELL_ATTR0_CANCELS_AUTO_ATTACK_COMBAT
Definition: SharedDefines.h:374
@ SPELL_HIT_TYPE_CRIT
Definition: SharedDefines.h:1508
SpellMissInfo
Definition: SharedDefines.h:1490
@ SPELL_MISS_DODGE
Definition: SharedDefines.h:1494
@ SPELL_MISS_IMMUNE2
Definition: SharedDefines.h:1499
@ SPELL_MISS_RESIST
Definition: SharedDefines.h:1493
@ SPELL_MISS_MISS
Definition: SharedDefines.h:1492
@ SPELL_MISS_BLOCK
Definition: SharedDefines.h:1496
@ SPELL_ATTR4_SUPRESS_WEAPON_PROCS
Definition: SharedDefines.h:525
Milliseconds GetGameTimeMS()
Definition: GameTime.cpp:43
virtual void AttackStart(Unit *)
Definition: UnitAI.cpp:28
virtual void SpellHitTarget(Unit *, SpellInfo const *)
Definition: CreatureAI.h:142
virtual void SpellHit(Unit *, SpellInfo const *)
Definition: CreatureAI.h:139
void threatAssist(Unit *victim, float baseThreat, SpellInfo const *threatSpell=nullptr)
Definition: HostileRefMgr.cpp:35
void LowerPlayerDamageReq(uint32 unDamage, bool damagedByPlayer=true)
Definition: Creature.cpp:3689
CreatureAI * AI() const
Definition: Creature.h:135
bool IsPlayer() const
Definition: Object.h:194
void RestoreSpellMods(Spell *spell, uint32 ownerAuraId=0, Aura *aura=nullptr)
Definition: Player.cpp:9833
void CastItemCombatSpell(Unit *target, WeaponAttackType attType, uint32 procVictim, uint32 procEx)
Definition: Player.cpp:7093
void UpdatePvP(bool state, bool _override=false)
Definition: PlayerUpdates.cpp:1481
Definition: Unit.h:761
Definition: Unit.h:804
Definition: Unit.h:908
uint32 m_lastSanctuaryTime
Definition: Unit.h:2137
void DealSpellDamage(SpellNonMeleeDamage *damageInfo, bool durabilityLoss, Spell const *spell=nullptr)
Definition: Unit.cpp:1435
void SendSpellMiss(Unit *target, uint32 spellID, SpellMissInfo missInfo)
Definition: Unit.cpp:6357
void SendSpellNonMeleeReflectLog(SpellNonMeleeDamage *log, Unit *attacker)
Definition: Unit.cpp:6190
bool CanProc()
Definition: Unit.h:2320
bool IsPvP() const
Definition: Unit.h:1517
uint32 SpellHealingBonusDone(Unit *victim, SpellInfo const *spellProto, uint32 healamount, DamageEffectType damagetype, uint8 effIndex, float TotalMod=0.0f, uint32 stack=1)
Definition: Unit.cpp:12370
void SetInCombatWith(Unit *enemy, uint32 duration=0)
Definition: Unit.cpp:13492
int32 HealBySpell(HealInfo &healInfo, bool critical=false)
Definition: Unit.cpp:11197
bool IsStandState() const
Definition: Unit.cpp:16894
bool IsInCombatWith(Unit const *who) const
Definition: Unit.cpp:21205
HostileRefMgr & getHostileRefMgr()
Definition: Unit.h:2149
int32 GetHealthGain(int32 dVal)
Definition: Unit.cpp:14025
static uint32 SpellCriticalHealingBonus(Unit const *caster, SpellInfo const *spellProto, uint32 damage, Unit const *victim)
Definition: Unit.cpp:12239
void SendSpellNonMeleeDamageLog(SpellNonMeleeDamage *log)
Definition: Unit.cpp:6222
bool IsAIEnabled
Definition: Unit.h:2350
void SetLastDamagedTargetGuid(ObjectGuid const &guid)
Definition: Unit.h:1572
uint32 SpellHealingBonusTaken(Unit *caster, SpellInfo const *spellProto, uint32 healamount, DamageEffectType damagetype, uint32 stack=1)
Definition: Unit.cpp:12481
void SetStandState(uint8 state)
Definition: Unit.cpp:16900
void RemoveAurasWithInterruptFlags(uint32 flag, uint32 except=0, bool isAutoshot=false)
Definition: Unit.cpp:5096
static void DealDamageMods(Unit const *victim, uint32 &damage, uint32 *absorb)
Definition: Unit.cpp:805
void CalculateSpellDamageTaken(SpellNonMeleeDamage *damageInfo, int32 damage, SpellInfo const *spellInfo, WeaponAttackType attackType=BASE_ATTACK, bool crit=false)
Definition: Unit.cpp:1297
ObjectGuid GetUnitTargetGUID() const
Definition: Spell.cpp:210
bool CanExecuteTriggersOnHit(uint8 effMask, SpellInfo const *triggeredByAura=nullptr) const
Definition: Spell.cpp:8694
SpellValue const * GetSpellValue()
Definition: Spell.h:582
SpellMissInfo DoSpellHitOnUnit(Unit *unit, uint32 effectMask, bool scaleAura)
Definition: Spell.cpp:2982
void DoTriggersOnSpellHit(Unit *unit, uint8 effMask)
Definition: Spell.cpp:3238
uint32 AttributesEx3
Definition: SpellInfo.h:325
bool IsTargetingArea() const
Definition: SpellInfo.cpp:1009
bool IsPositiveEffect(uint8 effIndex) const
Definition: SpellInfo.cpp:1226

References SpellNonMeleeDamage::absorb, Creature::AI(), TargetInfo::alive, UnitAI::AttackStart(), SpellInfo::AttributesEx3, AURA_INTERRUPT_FLAG_TALK, SpellNonMeleeDamage::blocked, Unit::CalculateSpellDamageTaken(), CallScriptAfterHitHandlers(), CallScriptBeforeHitHandlers(), CallScriptOnHitHandlers(), CanExecuteTriggersOnHit(), Unit::CanProc(), Player::CastItemCombatSpell(), Unit::CastSpell(), Unit::CombatStart(), createProcExtendMask(), TargetInfo::crit, SpellNonMeleeDamage::damage, TargetInfo::damage, Unit::DealDamageMods(), Unit::DealSpellDamage(), SpellInfo::DmgClass, DoSpellHitOnUnit(), DoTriggersOnSpellHit(), EFFECT_0, TriggeredByAuraSpellData::effectIndex, TargetInfo::effectMask, SpellInfo::Effects, WorldObject::FindMap(), ObjectAccessor::FindPlayer(), Object::GetEntry(), GameTime::GetGameTimeMS(), Object::GetGUID(), Unit::GetHealthGain(), Unit::getHostileRefMgr(), Unit::GetOwner(), Unit::GetOwnerGUID(), SpellInfo::GetSchoolMask(), GetSpellValue(), getState(), Object::GetTypeId(), ObjectAccessor::GetUnit(), SpellCastTargets::GetUnitTargetGUID(), HandleEffects(), SpellInfo::HasAttribute(), SpellInfo::HasEffect(), HEAL, Unit::HealBySpell(), SpellNonMeleeDamage::HitInfo, SpellInfo::Id, Unit::IsAIEnabled, Unit::IsAlive(), 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_SUPRESS_CASTER_PROCS, SPELL_ATTR3_SUPRESS_TARGET_PROCS, SPELL_ATTR4_SUPRESS_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(), TYPEID_PLAYER, TYPEID_UNIT, 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 
)
1656{
1657 if (!unitTarget)
1658 return;
1659
1660 Player* player = unitTarget->ToPlayer();
1661 if (!player)
1662 {
1663 return;
1664 }
1665
1666 uint32 newitemid = itemId;
1667
1668 ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(newitemid);
1669 if (!pProto)
1670 {
1671 player->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, nullptr, nullptr);
1672 return;
1673 }
1674
1675 uint32 addNumber = damage;
1676
1677 // bg reward have some special in code work
1678 bool SelfCast = true;
1679 switch (m_spellInfo->Id)
1680 {
1685 case SPELL_WS_MARK_TIE:
1688 SelfCast = true;
1689 break;
1691 if (player->HasAura(55629 /*SPELL_LIEUTENANT*/))
1692 addNumber = 3;
1693 else if (player->HasAura(33280 /*SPELL_CORPORAL*/))
1694 addNumber = 2;
1695 else
1696 addNumber = 1;
1697 SelfCast = true;
1698 break;
1699 }
1700
1701 if (addNumber < 1)
1702 addNumber = 1;
1703 if (addNumber > pProto->GetMaxStackSize())
1704 addNumber = pProto->GetMaxStackSize();
1705
1706 /* == gem perfection handling == */
1707
1708 // the chance of getting a perfect result
1709 float perfectCreateChance = 0.0f;
1710
1711 // the resulting perfect item if successful
1712 uint32 perfectItemType = itemId;
1713
1714 // get perfection capability and chance
1715 if (CanCreatePerfectItem(player, m_spellInfo->Id, perfectCreateChance, perfectItemType))
1716 if (roll_chance_f(perfectCreateChance)) // if the roll succeeds...
1717 newitemid = perfectItemType; // the perfect item replaces the regular one
1718
1719 /* == gem perfection handling over == */
1720
1721 /* == profession specialization handling == */
1722
1723 // init items_count to 1, since 1 item will be created regardless of specialization
1724 int32 itemsCount = 1;
1725 float additionalCreateChance = 0.0f;
1726 int32 additionalMaxNum = 0;
1727 // get the chance and maximum number for creating extra items
1728 if (canCreateExtraItems(player, m_spellInfo->Id, additionalCreateChance, additionalMaxNum))
1729 {
1730 // roll with this chance till we roll not to create or we create the max num
1731 while (roll_chance_f(additionalCreateChance) && itemsCount <= additionalMaxNum)
1732 ++itemsCount;
1733 }
1734
1735 // really will be created more items
1736 addNumber *= itemsCount;
1737
1738 /* == profession specialization handling over == */
1739
1740 // can the player store the new item?
1741 ItemPosCountVec dest;
1742 uint32 no_space = 0;
1743 InventoryResult msg = player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, newitemid, addNumber, &no_space);
1744 if (msg != EQUIP_ERR_OK)
1745 {
1746 // convert to possible store amount
1748 addNumber -= no_space;
1749 else
1750 {
1751 // if not created by another reason from full inventory or unique items amount limitation
1752 player->SendEquipError(msg, nullptr, nullptr, newitemid);
1753 return;
1754 }
1755 }
1756
1757 if (addNumber)
1758 {
1759 // create the new item and store it
1760 Item* pItem = player->StoreNewItem(dest, newitemid, true);
1761
1762 // was it successful? return error if not
1763 if (!pItem)
1764 {
1765 player->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, nullptr, nullptr);
1766 return;
1767 }
1768
1769 // set the "Crafted by ..." property of the item
1770 if (pItem->GetTemplate()->HasSignature())
1771 pItem->SetGuidValue(ITEM_FIELD_CREATOR, player->GetGUID());
1772
1773 // send info to the client
1774 player->SendNewItem(pItem, addNumber, true, SelfCast);
1775
1776 sScriptMgr->OnCreateItem(player, pItem, addNumber);
1777
1778 // we succeeded in creating at least one item, so a levelup is possible
1779 if (SelfCast)
1781 }
1782}
@ SPELL_WS_MARK_WINNER
Definition: Battleground.h:101
@ SPELL_AV_MARK_LOSER
Definition: Battleground.h:105
@ SPELL_WS_MARK_TIE
Definition: Battleground.h:102
@ SPELL_WS_MARK_LOSER
Definition: Battleground.h:100
@ SPELL_AB_MARK_LOSER
Definition: Battleground.h:103
@ SPELL_WG_MARK_WINNER
Definition: Battleground.h:109
@ SPELL_AB_MARK_WINNER
Definition: Battleground.h:104
@ SPELL_AV_MARK_WINNER
Definition: Battleground.h:106
@ EQUIP_ERR_ITEM_NOT_FOUND
Definition: Item.h:64
@ EQUIP_ERR_CANT_CARRY_MORE_OF_THIS
Definition: Item.h:58
@ ITEM_FIELD_CREATOR
Definition: UpdateFields.h:37
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
bool HasSignature() const
Definition: ItemTemplate.h:707
void SetGuidValue(uint16 index, ObjectGuid value)
Definition: Object.cpp:723
bool UpdateCraftSkill(uint32 spellid)
Definition: PlayerUpdates.cpp:783
void SendNewItem(Item *item, uint32 count, bool received, bool created, bool broadcast=false, bool sendChatMessage=true)
Definition: PlayerStorage.cpp:4776
Item * StoreNewItem(ItemPosCountVec const &pos, uint32 item, bool update, int32 randomPropertyId=0)
Definition: PlayerStorage.cpp:2552

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

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

◆ DoSpellHitOnUnit()

SpellMissInfo Spell::DoSpellHitOnUnit ( Unit unit,
uint32  effectMask,
bool  scaleAura 
)
protected
Todo:
: this cause soul transfer bugged
2983{
2984 if (!unit || !effectMask)
2985 return SPELL_MISS_EVADE;
2986
2987 // For delayed spells immunity may be applied between missile launch and hit - check immunity for that case
2988 if (m_spellInfo->Speed && ((m_damage > 0 && unit->IsImmunedToDamage(this)) || unit->IsImmunedToSchool(this) || unit->IsImmunedToSpell(m_spellInfo, this)))
2989 {
2990 return SPELL_MISS_IMMUNE;
2991 }
2992
2993 // disable effects to which unit is immune
2994 SpellMissInfo returnVal = SPELL_MISS_IMMUNE;
2995 for (uint32 effectNumber = 0; effectNumber < MAX_SPELL_EFFECTS; ++effectNumber)
2996 {
2997 if (effectMask & (1 << effectNumber))
2998 {
2999 if (unit->IsImmunedToSpellEffect(m_spellInfo, effectNumber))
3000 effectMask &= ~(1 << effectNumber);
3001 // Xinef: Buggs out polymorph
3002 // Xinef: And this is checked in MagicSpellHitResult, why we check resistance twice?
3003 // Xinef: And why we check every spell effect basing on rand and generic dispel info? some effects will be appliend and some wont?
3004 /*else if (m_spellInfo->Effects[effectNumber].IsAura() && !m_spellInfo->IsPositiveEffect(effectNumber))
3005 {
3006 int32 debuff_resist_chance = unit->GetMaxPositiveAuraModifierByMiscValue(SPELL_AURA_MOD_DEBUFF_RESISTANCE, int32(m_spellInfo->Dispel));
3007 debuff_resist_chance += unit->GetMaxNegativeAuraModifierByMiscValue(SPELL_AURA_MOD_DEBUFF_RESISTANCE, int32(m_spellInfo->Dispel));
3008
3009 if (debuff_resist_chance > 0)
3010 if (irand(0,10000) <= (debuff_resist_chance * 100))
3011 {
3012 effectMask &= ~(1 << effectNumber);
3013 returnVal = SPELL_MISS_RESIST;
3014 }
3015 }*/
3016 }
3017 }
3018 if (!effectMask)
3019 return returnVal;
3020
3021 if (unit->GetTypeId() == TYPEID_PLAYER)
3022 {
3026 }
3027
3029 {
3032 }
3033
3034 if (m_caster != unit)
3035 {
3036 // Recheck UNIT_FLAG_NON_ATTACKABLE for delayed spells
3037 // Xinef: Also check evade state
3038 if (m_spellInfo->Speed > 0.0f)
3039 {
3040 if (unit->GetTypeId() == TYPEID_UNIT && unit->ToCreature()->IsInEvadeMode())
3041 return SPELL_MISS_EVADE;
3042
3044 return SPELL_MISS_EVADE;
3045 }
3046
3047 if (m_caster->_IsValidAttackTarget(unit, m_spellInfo) && /*Intervene Trigger*/ m_spellInfo->Id != 59667)
3048 {
3050 }
3051 else if (m_caster->IsFriendlyTo(unit))
3052 {
3053 // for delayed spells ignore negative spells (after duel end) for friendly targets
3055 if(!IsTriggered() && m_spellInfo->Speed > 0.0f && unit->GetTypeId() == TYPEID_PLAYER && !m_spellInfo->IsPositive())
3056 return SPELL_MISS_EVADE;
3057
3058 // assisting case, healing and resurrection
3060 {
3063 m_caster->ToPlayer()->UpdatePvP(true);
3064 }
3065
3066 // xinef: triggered spells should not prolong combat
3068 {
3069 m_caster->SetInCombatState(unit->GetCombatTimer() > 0, unit);
3070 unit->getHostileRefMgr().threatAssist(m_caster, 0.0f);
3071 }
3072 }
3073 }
3074
3075 uint8 aura_effmask = 0;
3076 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
3077 if (effectMask & (1 << i) && m_spellInfo->Effects[i].IsUnitOwnedAuraEffect())
3078 aura_effmask |= 1 << i;
3079
3080 Unit* originalCaster = GetOriginalCaster();
3081 if (!originalCaster)
3082 originalCaster = m_caster;
3083
3084 // Get Data Needed for Diminishing Returns, some effects may have multiple auras, so this must be done on spell hit, not aura add
3085 // Xinef: Do not increase diminishing level for self cast
3087 // xinef: do not increase diminish level for bosses (eg. Void Reaver silence is never diminished)
3089 {
3092
3093 uint32 flagsExtra = unit->GetTypeId() == TYPEID_UNIT ? unit->ToCreature()->GetCreatureTemplate()->flags_extra : 0;
3094
3095 // Increase Diminishing on unit, current informations for actually casts will use values above
3096 if ((type == DRTYPE_PLAYER && (unit->IsCharmedOwnedByPlayerOrPlayer() || flagsExtra & CREATURE_FLAG_EXTRA_ALL_DIMINISH ||
3098 {
3099 // Do not apply diminish return if caster is NPC
3101 {
3103 }
3104 }
3105 }
3106
3108 {
3110 }
3111
3112 if (aura_effmask)
3113 {
3114 // Select rank for aura with level requirements only in specific cases
3115 // 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
3116 SpellInfo const* aurSpellInfo = m_spellInfo;
3117 int32 basePoints[3];
3118 if (scaleAura)
3119 {
3121 ASSERT(aurSpellInfo);
3122 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
3123 {
3124 basePoints[i] = aurSpellInfo->Effects[i].BasePoints;
3125 if (m_spellInfo->Effects[i].Effect != aurSpellInfo->Effects[i].Effect)
3126 {
3127 aurSpellInfo = m_spellInfo;
3128 break;
3129 }
3130 }
3131 }
3132
3133 if (m_originalCaster)
3134 {
3135 bool refresh = false;
3136 bool refreshPeriodic = m_spellInfo->StackAmount < 2 && !(_triggeredCastFlags & TRIGGERED_NO_PERIODIC_RESET);
3137 m_spellAura = Aura::TryRefreshStackOrCreate(aurSpellInfo, effectMask, unit, m_originalCaster,
3138 (aurSpellInfo == m_spellInfo) ? &m_spellValue->EffectBasePoints[0] : &basePoints[0], m_CastItem, ObjectGuid::Empty, &refresh, refreshPeriodic);
3139
3140 // xinef: if aura was not refreshed, add proc ex
3141 if (!refresh)
3143
3144 if (m_spellAura)
3145 {
3146 // Set aura stack amount to desired value
3148 {
3149 if (!refresh)
3151 else
3153 }
3154
3155 // Now Reduce spell duration using data received at spell hit
3156 int32 duration = m_spellAura->GetMaxDuration();
3157 int32 limitduration = GetDiminishingReturnsLimitDuration(m_diminishGroup, aurSpellInfo);
3158
3159 // Xinef: if unit == caster - test versus original unit if available
3160 float diminishMod = 1.0f;
3161 if (unit == m_caster && m_targets.GetUnitTarget())
3163 else
3164 diminishMod = unit->ApplyDiminishingToDuration(m_diminishGroup, duration, m_originalCaster, m_diminishLevel, limitduration);
3165
3166 // unit is immune to aura if it was diminished to 0 duration
3167 if (diminishMod == 0.0f)
3168 {
3170 bool found = false;
3171 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
3172 if (effectMask & (1 << i) && m_spellInfo->Effects[i].Effect != SPELL_EFFECT_APPLY_AURA)
3173 found = true;
3174 if (!found)
3175 return SPELL_MISS_IMMUNE;
3176 }
3177 else
3178 {
3179 ((UnitAura*)m_spellAura)->SetDiminishGroup(m_diminishGroup);
3180
3181 bool positive = m_spellAura->GetSpellInfo()->IsPositive();
3183 positive = aurApp->IsPositive();
3184
3185 duration = m_originalCaster->ModSpellDuration(aurSpellInfo, unit, duration, positive, effectMask);
3186
3187 // xinef: haste affects duration of those spells twice
3190
3191 if (m_spellValue->AuraDuration != 0)
3192 {
3193 if (m_spellAura->GetMaxDuration() != -1)
3194 {
3196 }
3197
3199 }
3200 else if (duration != m_spellAura->GetMaxDuration())
3201 {
3202 m_spellAura->SetMaxDuration(duration);
3203 m_spellAura->SetDuration(duration);
3204 }
3205
3206 // xinef: apply relic cooldown, imo best place to add this
3209
3212 }
3213 }
3214 }
3215 }
3216
3217 int8 sanct_effect = -1;
3218
3219 for (uint32 effectNumber = 0; effectNumber < MAX_SPELL_EFFECTS; ++effectNumber)
3220 {
3221 // handle sanctuary effects after aura apply!
3222 if (m_spellInfo->Effects[effectNumber].Effect == SPELL_EFFECT_SANCTUARY)
3223 {
3224 sanct_effect = effectNumber;
3225 continue;
3226 }
3227
3228 if (effectMask & (1 << effectNumber))
3229 HandleEffects(unit, nullptr, nullptr, effectNumber, SPELL_EFFECT_HANDLE_HIT_TARGET);
3230 }
3231
3232 if( sanct_effect >= 0 && (effectMask & (1 << sanct_effect)) )
3233 HandleEffects(unit, nullptr, nullptr, sanct_effect, SPELL_EFFECT_HANDLE_HIT_TARGET);
3234
3235 return SPELL_MISS_NONE;
3236}
@ CREATURE_FLAG_EXTRA_OBEYS_TAUNT_DIMINISHING_RETURNS
Definition: CreatureData.h:68
@ CREATURE_FLAG_EXTRA_ALL_DIMINISH
Definition: CreatureData.h:69
@ UNIT_MOD_CAST_SPEED
Definition: UpdateFields.h:137
@ UNIT_STATE_ATTACK_PLAYER
Definition: Unit.h:339
@ UNIT_FLAG_NON_ATTACKABLE
Definition: Unit.h:449
@ SPELL_AURA_PERIODIC_HASTE
Definition: SpellAuraDefines.h:379
@ SPELL_AURA_REFLECT_SPELLS
Definition: SpellAuraDefines.h:91
@ SPELL_AURA_MOD_STEALTH
Definition: SpellAuraDefines.h:79
@ AURA_INTERRUPT_FLAG_HITBYSPELL
Definition: SpellDefines.h:44
@ TRIGGERED_NO_PERIODIC_RESET
Will ignore equipped item requirements.
Definition: SpellDefines.h:150
@ SPELL_ATTR0_CU_DONT_BREAK_STEALTH
Definition: SpellInfo.h:182
int32 GetDiminishingReturnsLimitDuration(DiminishingGroup group, SpellInfo const *spellproto)
Definition: SpellMgr.cpp:276
DiminishingGroup GetDiminishingReturnsGroupForSpell(SpellInfo const *spellproto, bool triggered)
Definition: SpellMgr.cpp:59
DiminishingReturnsType GetDiminishingReturnsGroupType(DiminishingGroup group)
Definition: SpellMgr.cpp:246
@ PROC_EX_NO_AURA_REFRESH
Definition: SpellMgr.h:214
@ ACHIEVEMENT_TIMED_TYPE_SPELL_CASTER
Definition: DBCEnums.h:118
@ ACHIEVEMENT_TIMED_TYPE_SPELL_TARGET
Definition: DBCEnums.h:119
@ ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET2
Definition: DBCEnums.h:187
@ ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET
Definition: DBCEnums.h:148
@ ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL2
Definition: DBCEnums.h:223
@ DIMINISHING_TAUNT
Definition: SharedDefines.h:3248
@ SPELL_EFFECT_SANCTUARY
Definition: SharedDefines.h:829
@ SPELL_ATTR5_SPELL_HASTE_AFFECTS_PERIODIC
Definition: SharedDefines.h:552
DiminishingReturnsType
Definition: SharedDefines.h:3221
@ DRTYPE_PLAYER
Definition: SharedDefines.h:3223
@ DRTYPE_ALL
Definition: SharedDefines.h:3224
bool isWorldBoss() const
Definition: Creature.h:115
bool IsInEvadeMode() const
Definition: Creature.h:129
uint32 flags_extra
Definition: CreatureData.h:239
float GetFloatValue(uint16 index) const
Definition: Object.cpp:317
static ObjectGuid const Empty
Definition: ObjectGuid.h:122
bool HasAuraTypeWithAffectMask(AuraType auratype, SpellInfo const *affectedSpell) const
Definition: Unit.cpp:5650
DiminishingLevels GetDiminishing(DiminishingGroup group)
Definition: Unit.cpp:14899
void IncrDiminishing(DiminishingGroup group)
Definition: Unit.cpp:14925
uint32 GetCombatTimer() const
Definition: Unit.h:1698
bool IsImmunedToSchool(SpellSchoolMask meleeSchoolMask) const
Definition: Unit.cpp:12743
void SetContestedPvP(Player *attackedPlayer=nullptr, bool lookForNearContestedGuards=true)
Definition: Unit.cpp:17419
bool HasUnitFlag(UnitFlags flags) const
Definition: Unit.h:1480
float ApplyDiminishingToDuration(DiminishingGroup group, int32 &duration, Unit *caster, DiminishingLevels Level, int32 limitduration)
Definition: Unit.cpp:14939
int32 ModSpellDuration(SpellInfo const *spellProto, Unit const *target, int32 duration, bool positive, uint32 effectMask)
Definition: Unit.cpp:14765
virtual void AddSpellCooldown(uint32, uint32, uint32, bool needSendToClient=false, bool forceSendToSpectator=false)
Definition: Unit.h:2420
void SetInCombatState(bool PvP, Unit *enemy=nullptr, uint32 duration=0)
Definition: Unit.cpp:13639
bool IsCharmedOwnedByPlayerOrPlayer() const
Definition: Unit.h:1838
bool HasAuraType(AuraType auraType) const
Definition: Unit.cpp:5617
bool IsImmunedToDamage(SpellSchoolMask meleeSchoolMask) const
Definition: Unit.cpp:12658
virtual bool IsImmunedToSpell(SpellInfo const *spellInfo, Spell const *spell=nullptr)
Definition: Unit.cpp:12827
bool IsHostileTo(Unit const *unit) const
Definition: Unit.cpp:10209
bool _IsValidAttackTarget(Unit const *target, SpellInfo const *bySpell, WorldObject const *obj=nullptr) const
Definition: Unit.cpp:13782
ObjectGuid GetCharmerOrOwnerGUID() const
Definition: Unit.h:1830
Definition: SpellAuras.h:37
int32 GetMaxDuration() const
Definition: SpellAuras.h:129
void SetStackAmount(uint8 num)
Definition: SpellAuras.cpp:1009
void SetTriggeredByAuraSpellInfo(SpellInfo const *triggeredByAuraSpellInfo)
Definition: SpellAuras.cpp:2751
void _RegisterForTargets()
Definition: SpellAuras.h:121
bool ModStackAmount(int32 num, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT, bool periodicReset=false)
Definition: SpellAuras.cpp:1035
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:882
const AuraApplication * GetApplicationOfTarget(ObjectGuid guid) const
Definition: SpellAuras.h:183
void SetMaxDuration(int32 duration)
Definition: SpellAuras.h:130
virtual void Remove(AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)=0
Definition: SpellAuras.h:279
int32 AuraDuration
Definition: Spell.h:217
uint8 AuraStackAmount
Definition: Spell.h:216
Unit * GetOriginalCaster() const
Definition: Spell.h:573
SpellInfo const * GetAuraRankForLevel(uint8 level) const
Definition: SpellInfo.cpp:2509

References Unit::_IsValidAttackTarget(), Aura::_RegisterForTargets(), _triggeredCastFlags, 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(), Object::GetTypeId(), SpellCastTargets::GetUnitTarget(), HandleEffects(), SpellInfo::HasAttribute(), Unit::HasAuraType(), Unit::HasAuraTypeWithAffectMask(), Unit::HasUnitFlag(), Unit::HasUnitState(), SpellInfo::Id, Unit::IncrDiminishing(), ItemTemplate::InventoryType, INVTYPE_RELIC, Unit::IsCharmedOwnedByPlayerOrPlayer(), Unit::IsFriendlyTo(), Unit::IsHostileTo(), Unit::IsImmunedToDamage(), Unit::IsImmunedToSchool(), Unit::IsImmunedToSpell(), Unit::IsImmunedToSpellEffect(), Unit::IsInCombat(), Creature::IsInEvadeMode(), 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_SUPRESS_TARGET_PROCS, SPELL_ATTR5_SPELL_HASTE_AFFECTS_PERIODIC, SPELL_AURA_MOD_STEALTH, SPELL_AURA_PERIODIC_HASTE, SPELL_AURA_REFLECT_SPELLS, 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(), TYPEID_PLAYER, TYPEID_UNIT, UNIT_FLAG_NON_ATTACKABLE, UNIT_MOD_CAST_SPEED, UNIT_STATE_ATTACK_PLAYER, 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
3239{
3240 // Apply additional spell effects to target
3242 if (m_preCastSpell)
3243 {
3244 // Paladin immunity shields
3245 if (m_preCastSpell == 61988)
3246 {
3247 // Cast Forbearance
3248 m_caster->CastSpell(unit, 25771, true);
3249 // Cast Avenging Wrath Marker
3250 unit->CastSpell(unit, 61987, true);
3251 }
3252
3253 // Avenging Wrath
3254 if (m_preCastSpell == 61987)
3255 // Cast the serverside immunity shield marker
3256 m_caster->CastSpell(unit, 61988, true);
3257
3258 // Fearie Fire (Feral) - damage
3259 if( m_preCastSpell == 60089 )
3260 m_caster->CastSpell(unit, m_preCastSpell, true);
3261 else if (sSpellMgr->GetSpellInfo(m_preCastSpell))
3262 // Blizz seems to just apply aura without bothering to cast
3264 }
3265
3266 // handle SPELL_AURA_ADD_TARGET_TRIGGER auras
3267 // this is executed after spell proc spells on target hit
3268 // spells are triggered for each hit spell target
3269 // info confirmed with retail sniffs of permafrost and shadow weaving
3270 if (!m_hitTriggerSpells.empty())
3271 {
3272 int _duration = 0;
3273 for (HitTriggerSpellList::const_iterator i = m_hitTriggerSpells.begin(); i != m_hitTriggerSpells.end(); ++i)
3274 {
3275 if (CanExecuteTriggersOnHit(effMask, i->triggeredByAura) && roll_chance_i(i->chance))
3276 {
3277 m_caster->CastSpell(unit, i->triggeredSpell->Id, true);
3278 LOG_DEBUG("spells.aura", "Spell {} triggered spell {} by SPELL_AURA_ADD_TARGET_TRIGGER aura", m_spellInfo->Id, i->triggeredSpell->Id);
3279
3280 // SPELL_AURA_ADD_TARGET_TRIGGER auras shouldn't trigger auras without duration
3281 // set duration of current aura to the triggered spell
3282 if (i->triggeredSpell->GetDuration() == -1)
3283 {
3284 if (Aura* triggeredAur = unit->GetAura(i->triggeredSpell->Id, m_caster->GetGUID()))
3285 {
3286 // get duration from aura-only once
3287 if (!_duration)
3288 {
3289 Aura* aur = unit->GetAura(m_spellInfo->Id, m_caster->GetGUID());
3290 _duration = aur ? aur->GetDuration() : -1;
3291 }
3292 triggeredAur->SetDuration(_duration);
3293 }
3294 }
3295 }
3296 }
3297 }
3298
3299 // trigger linked auras remove/apply
3301 if (std::vector<int32> const* spellTriggered = sSpellMgr->GetSpellLinked(m_spellInfo->Id + SPELL_LINK_HIT))
3302 {
3303 for (std::vector<int32>::const_iterator i = spellTriggered->begin(); i != spellTriggered->end(); ++i)
3304 if (*i < 0)
3305 {
3306 unit->RemoveAurasDueToSpell(-(*i));
3307 }
3308 else
3309 {
3310 unit->CastSpell(unit, *i, true, 0, 0, m_caster->GetGUID());
3311 }
3312 }
3313}
bool roll_chance_i(int chance)
Definition: Random.h:59
@ SPELL_LINK_HIT
Definition: SpellMgr.h:97
Aura * GetAura(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemCasterGUID=ObjectGuid::Empty, uint8 reqEffMask=0) const
Definition: Unit.cpp:5499
Aura * AddAura(uint32 spellId, Unit *target)
Definition: Unit.cpp:19031
int32 GetDuration() const
Definition: SpellAuras.h:133
HitTriggerSpellList m_hitTriggerSpells
Definition: Spell.h:753

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)
4278{
4280 return;
4281
4282 if (!gameObjTarget)
4283 return;
4284
4285 GameObjectActions action = GameObjectActions(m_spellInfo->Effects[effIndex].MiscValue);
4286 switch (action)
4287 {
4288 case GameObjectActions::AnimateCustom0:
4289 case GameObjectActions::AnimateCustom1:
4290 case GameObjectActions::AnimateCustom2:
4291 case GameObjectActions::AnimateCustom3:
4292 gameObjTarget->SendCustomAnim(uint32(action) - uint32(GameObjectActions::AnimateCustom0));
4293 break;
4294 case GameObjectActions::Disturb: // What's the difference with Open?
4295 case GameObjectActions::Open:
4296 if (Unit* unitCaster = m_caster->ToUnit())
4297 gameObjTarget->Use(unitCaster);
4298 break;
4299 case GameObjectActions::OpenAndUnlock:
4300 if (Unit* unitCaster = m_caster->ToUnit())
4301 gameObjTarget->UseDoorOrButton(0, false, unitCaster);
4302 [[fallthrough]];
4303 case GameObjectActions::Unlock:
4304 case GameObjectActions::Lock:
4305 gameObjTarget->ApplyModFlag(GAMEOBJECT_FLAGS, GO_FLAG_LOCKED, action == GameObjectActions::Lock);
4306 break;
4307 case GameObjectActions::Close:
4308 case GameObjectActions::Rebuild:
4310 break;
4311 case GameObjectActions::Despawn:
4313 break;
4314 case GameObjectActions::MakeInert:
4315 case GameObjectActions::MakeActive:
4316 gameObjTarget->ApplyModFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE, action == GameObjectActions::MakeInert);
4317 break;
4318 case GameObjectActions::CloseAndLock:
4321 break;
4322 case GameObjectActions::Destroy:
4323 if (Unit* unitCaster = m_caster->ToUnit())
4324 gameObjTarget->UseDoorOrButton(0, true, unitCaster);
4325 break;
4326 case GameObjectActions::UseArtKit0:
4327 case GameObjectActions::UseArtKit1:
4328 case GameObjectActions::UseArtKit2:
4329 case GameObjectActions::UseArtKit3:
4330 {
4331 GameObjectTemplateAddon const* templateAddon = gameObjTarget->GetTemplateAddon();
4332
4333 uint32 artKitIndex = uint32(action) - uint32(GameObjectActions::UseArtKit0);
4334
4335 uint32 artKitValue = 0;
4336 if (templateAddon)
4337 artKitValue = templateAddon->artKits[artKitIndex];
4338
4339 if (artKitValue == 0)
4340 LOG_ERROR("sql.sql", "GameObject {} hit by spell {} needs `artkit{}` in `gameobject_template_addon`", gameObjTarget->GetEntry(), m_spellInfo->Id, artKitIndex);
4341 else
4342 gameObjTarget->SetGoArtKit(artKitValue);
4343
4344 break;
4345 }
4346 case GameObjectActions::None:
4347 LOG_FATAL("spell", "Spell {} has action type NONE in effect {}", m_spellInfo->Id, int32(effIndex));
4348 break;
4349 default:
4350 LOG_ERROR("spell", "Spell {} has unhandled action {} in effect {}", m_spellInfo->Id, int32(action), int32(effIndex));
4351 break;
4352 }
4353}
#define LOG_FATAL(filterType__,...)
Definition: Log.h:155
GameObjectActions
Definition: GameObject.h:78
@ GAMEOBJECT_FLAGS
Definition: UpdateFields.h:399
@ GO_FLAG_NOT_SELECTABLE
Definition: SharedDefines.h:1579
@ GO_FLAG_LOCKED
Definition: SharedDefines.h:1576
void UseDoorOrButton(uint32 time_to_restore=0, bool alternative=false, Unit *user=nullptr)
Definition: GameObject.cpp:1427
void SetGoArtKit(uint8 artkit)
Definition: GameObject.cpp:1441
void SendCustomAnim(uint32 anim)
Definition: GameObject.cpp:2138
void ResetDoorOrButton()
Definition: GameObject.cpp:1417
void DespawnOrUnsummon(Milliseconds delay=0ms, Seconds forcedRespawnTime=0s)
Definition: GameObject.cpp:930
GameObjectTemplateAddon const * GetTemplateAddon() const
Definition: GameObject.cpp:909
void Use(Unit *user)
Definition: GameObject.cpp:1477
Definition: GameObjectData.h:665
std::array< uint32, 4 > artKits
Definition: GameObjectData.h:671
void SetFlag(uint16 index, uint32 newFlag)
Definition: Object.cpp:845
void ApplyModFlag(uint16 index, uint32 flag, bool apply)
Definition: Object.cpp:899

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

◆ EffectActivateRune()

void Spell::EffectActivateRune ( SpellEffIndex  effIndex)
5815{
5817 return;
5818
5820 return;
5821
5822 Player* player = m_caster->ToPlayer();
5823
5824 if (player->getClass() != CLASS_DEATH_KNIGHT)
5825 return;
5826
5827 // needed later
5829
5830 uint32 count = damage;
5831 if (count == 0) count = 1;
5832 for (uint32 j = 0; j < MAX_RUNES && count > 0; ++j)
5833 {
5834 if (player->GetRuneCooldown(j) && player->GetCurrentRune(j) == RuneType(m_spellInfo->Effects[effIndex].MiscValue))
5835 {
5836 if (m_spellInfo->Id == 45529)
5837 if (player->GetBaseRune(j) != RuneType(m_spellInfo->Effects[effIndex].MiscValueB))
5838 continue;
5839 player->SetRuneCooldown(j, 0);
5840 player->SetGracePeriod(j, player->IsInCombat()); // xinef: reset grace period
5841 --count;
5842 }
5843 }
5844
5845 // Blood Tap
5846 if (m_spellInfo->Id == 45529 && count > 0)
5847 {
5848 for (uint32 l = 0; l < MAX_RUNES && count > 0; ++l)
5849 {
5850 // Check if both runes are on cd as that is the only time when this needs to come into effect
5851 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)))
5852 {
5853 // Should always update the rune with the lowest cd
5854 if (player->GetRuneCooldown(l) >= player->GetRuneCooldown(l + 1))
5855 l++;
5856 player->SetRuneCooldown(l, 0);
5857 player->SetGracePeriod(l, player->IsInCombat()); // xinef: reset grace period
5858 --count;
5859 }
5860 else
5861 break;
5862 }
5863 }
5864
5865 // Empower rune weapon
5866 if (m_spellInfo->Id == 47568)
5867 {
5868 // Need to do this just once
5869 if (effIndex != 0)
5870 return;
5871
5872 for (uint32 i = 0; i < MAX_RUNES; ++i)
5873 {
5874 if (player->GetRuneCooldown(i) && (player->GetCurrentRune(i) == RUNE_FROST || player->GetCurrentRune(i) == RUNE_DEATH))
5875 {
5876 player->SetRuneCooldown(i, 0);
5877 player->SetGracePeriod(i, player->IsInCombat()); // xinef: reset grace period
5878 }
5879 }
5880 }
5881
5882 // is needed to push through to the client that the rune is active
5883 //player->ResyncRunes(MAX_RUNES);
5884 m_caster->CastSpell(m_caster, 47804, true);
5885}
@ RUNE_FROST
Definition: Player.h:412
void SetRuneCooldown(uint8 index, uint32 cooldown)
Definition: Player.h:2466
uint8 GetRunesState() const
Definition: Player.h:2455
void SetGracePeriod(uint8 index, uint32 period)
Definition: Player.h:2467
RuneType GetBaseRune(uint8 index) const
Definition: Player.h:2456

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

◆ EffectActivateSpec()

void Spell::EffectActivateSpec ( SpellEffIndex  effIndex)
6207{
6209 return;
6210
6211 if (!unitTarget)
6212 return;
6213
6214 Player* player = unitTarget->ToPlayer();
6215 if (!player)
6216 {
6217 return;
6218 }
6219
6220 player->ActivateSpec(damage - 1); // damage is 1 or 2, spec is 0 or 1
6221}
void ActivateSpec(uint8 spec)
Definition: Player.cpp:14953

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

◆ EffectAddComboPoints()

void Spell::EffectAddComboPoints ( SpellEffIndex  effIndex)
4115{
4117 {
4118 return;
4119 }
4120
4121 if (!unitTarget || damage <= 0)
4122 {
4123 return;
4124 }
4125
4127}
void AddComboPointGain(Unit *target, int8 amount)
Definition: Spell.h:530

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

◆ EffectAddExtraAttacks()

void Spell::EffectAddExtraAttacks ( SpellEffIndex  effIndex)
4689{
4691 {
4692 return;
4693 }
4694
4695 if (!unitTarget || !unitTarget->IsAlive())
4696 {
4697 return;
4698 }
4699
4701
4703}
void AddExtraAttacks(uint32 count)
Definition: Unit.cpp:2727
void ExecuteLogEffectExtraAttacks(uint8 effIndex, Unit *victim, uint32 attCount)
Definition: Spell.cpp:5078

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

◆ EffectAddFarsight()

void Spell::EffectAddFarsight ( SpellEffIndex  effIndex)
2726{
2728 return;
2729
2731 return;
2732
2733 float radius = m_spellInfo->Effects[effIndex].CalcRadius();
2734 int32 duration = m_spellInfo->GetDuration();
2735 // Caster not in world, might be spell triggered from aura removal
2736 if (!m_caster->IsInWorld())
2737 return;
2738
2739 // Remove old farsight if exist
2740 bool updateViewerVisibility = m_caster->RemoveDynObject(m_spellInfo->Id);
2741
2742 DynamicObject* dynObj = new DynamicObject(true);
2743 if (!dynObj->CreateDynamicObject(m_caster->GetMap()->GenerateLowGuid<HighGuid::DynamicObject>(), m_caster, m_spellInfo->Id, *destTarget, radius, DYNAMIC_OBJECT_FARSIGHT_FOCUS))
2744 {
2745 delete dynObj;
2746 return;
2747 }
2748
2749 dynObj->SetDuration(duration);
2750 dynObj->SetCasterViewpoint(updateViewerVisibility);
2751}
@ DYNAMIC_OBJECT_FARSIGHT_FOCUS
Definition: DynamicObject.h:31
void SetDuration(int32 newDuration)
Definition: DynamicObject.cpp:207
void SetCasterViewpoint(bool updateViewerVisibility)
Definition: DynamicObject.cpp:235
bool CreateDynamicObject(ObjectGuid::LowType guidlow, Unit *caster, uint32 spellId, Position const &pos, float radius, DynamicObjectType type)
Definition: DynamicObject.cpp:101
ObjectGuid::LowType GenerateLowGuid()
Definition: Map.h:632

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

◆ EffectAddHonor()

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

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

◆ EffectApplyAreaAura()

void Spell::EffectApplyAreaAura ( SpellEffIndex  effIndex)
1328{
1330 return;
1331
1332 if (!m_spellAura || !unitTarget)
1333 return;
1336}
WorldObject * GetOwner() const
Definition: SpellAuras.h:107
void _ApplyEffectForTargets(uint8 effIndex)
Definition: SpellAuras.cpp:749

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)
4356{
4358 return;
4359
4361 return;
4362
4363 Player* player = m_caster->ToPlayer();
4364
4365 // glyph sockets level requirement
4366 uint8 minLevel = 0;
4367 switch (m_glyphIndex)
4368 {
4369 case 0:
4370 case 1:
4371 minLevel = 15;
4372 break;
4373 case 2:
4374 minLevel = 50;
4375 break;
4376 case 3:
4377 minLevel = 30;
4378 break;
4379 case 4:
4380 minLevel = 70;
4381 break;
4382 case 5:
4383 minLevel = 80;
4384 break;
4385 }
4386 if (minLevel && m_caster->GetLevel() < minLevel)
4387 {
4389 return;
4390 }
4391
4392 // apply new one
4393 if (uint32 glyph = m_spellInfo->Effects[effIndex].MiscValue)
4394 {
4395 if (GlyphPropertiesEntry const* glyphEntry = sGlyphPropertiesStore.LookupEntry(glyph))
4396 {
4397 if (GlyphSlotEntry const* glyphSlotEntry = sGlyphSlotStore.LookupEntry(player->GetGlyphSlot(m_glyphIndex)))
4398 {
4399 if (glyphEntry->TypeFlags != glyphSlotEntry->TypeFlags)
4400 {
4402 return; // glyph slot mismatch
4403 }
4404 }
4405
4406 // remove old glyph aura
4407 if (uint32 oldGlyph = player->GetGlyph(m_glyphIndex))
4408 if (GlyphPropertiesEntry const* oldGlyphEntry = sGlyphPropertiesStore.LookupEntry(oldGlyph))
4409 {
4410 player->RemoveAurasDueToSpell(oldGlyphEntry->SpellId);
4411
4412 // Removed any triggered auras
4413 Unit::AuraMap& ownedAuras = player->GetOwnedAuras();
4414 for (Unit::AuraMap::iterator iter = ownedAuras.begin(); iter != ownedAuras.end();)
4415 {
4416 Aura* aura = iter->second;
4417 if (SpellInfo const* triggeredByAuraSpellInfo = aura->GetTriggeredByAuraSpellInfo())
4418 {
4419 if (triggeredByAuraSpellInfo->Id == oldGlyphEntry->SpellId)
4420 {
4421 player->RemoveOwnedAura(iter);
4422 continue;
4423 }
4424 }
4425 ++iter;
4426 }
4427
4428 player->SendLearnPacket(oldGlyphEntry->SpellId, false); // Send packet to properly handle client-side spell tooltips
4429 }
4430
4431 player->SendLearnPacket(glyphEntry->SpellId, true); // Send packet to properly handle client-side spell tooltips
4433 player->SetGlyph(m_glyphIndex, glyph, !player->GetSession()->PlayerLoading());
4434 player->SendTalentsInfoData(false);
4435 }
4436 }
4437}
DBCStorage< GlyphSlotEntry > sGlyphSlotStore(GlyphSlotfmt)
@ TRIGGERED_FULL_MASK
Will return SPELL_FAILED_DONT_REPORT in CheckCast functions.
Definition: SpellDefines.h:148
#define MAX_GLYPH_SLOT_INDEX
Definition: SharedDefines.h:648
@ SPELL_FAILED_GLYPH_SOCKET_LOCKED
Definition: SharedDefines.h:1098
@ SPELL_FAILED_INVALID_GLYPH
Definition: SharedDefines.h:1096
void SendTalentsInfoData(bool pet)
Definition: Player.cpp:14305
void SendLearnPacket(uint32 spellId, bool learn)
Definition: Player.cpp:2978
uint32 GetGlyph(uint8 slot) const
Definition: Player.h:1720
uint32 GetGlyphSlot(uint8 slot) const
Definition: Player.h:1711
void SetGlyph(uint8 slot, uint32 glyph, bool save)
Definition: Player.h:1712
void RemoveOwnedAura(AuraMap::iterator &i, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition: Unit.cpp:4637
std::multimap< uint32, Aura * > AuraMap
Definition: Unit.h:1295
AuraMap & GetOwnedAuras()
Definition: Unit.h:1914
bool PlayerLoading() const
Definition: WorldSession.h:335
SpellInfo const * GetTriggeredByAuraSpellInfo() const
Definition: SpellAuras.cpp:2765
Definition: DBCStructure.h:1020

References Unit::CastSpell(), effectHandleMode, SpellInfo::Effects, Player::GetGlyph(), Player::GetGlyphSlot(), Unit::GetLevel(), Unit::GetOwnedAuras(), Player::GetSession(), Aura::GetTriggeredByAuraSpellInfo(), Object::GetTypeId(), 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, TRIGGERED_IGNORE_SHAPESHIFT, and TYPEID_PLAYER.

◆ EffectBind()

void Spell::EffectBind ( SpellEffIndex  effIndex)
6343{
6345 return;
6346
6347 if (!unitTarget)
6348 return;
6349
6350 Player* player = unitTarget->ToPlayer();
6351 if (!player)
6352 {
6353 return;
6354 }
6355
6356 WorldLocation homeLoc;
6357 uint32 areaId = player->GetAreaId();
6358
6359 if (m_spellInfo->Effects[effIndex].MiscValue)
6360 areaId = m_spellInfo->Effects[effIndex].MiscValue;
6361
6362 if (m_targets.HasDst())
6363 homeLoc.WorldRelocate(*destTarget);
6364 else
6365 {
6366 homeLoc = player->GetWorldLocation();
6367 }
6368
6369 player->SetHomebind(homeLoc, areaId);
6370
6371 // binding
6372 WorldPacket data(SMSG_BINDPOINTUPDATE, 4 + 4 + 4 + 4 + 4);
6373 data << float(homeLoc.GetPositionX());
6374 data << float(homeLoc.GetPositionY());
6375 data << float(homeLoc.GetPositionZ());
6376 data << uint32(homeLoc.GetMapId());
6377 data << uint32(areaId);
6378 player->SendDirectMessage(&data);
6379
6380 LOG_DEBUG("spells.aura", "EffectBind: New homebind X: {}, Y: {}, Z: {}, MapId: {}, AreaId: {}",
6381 homeLoc.GetPositionX(), homeLoc.GetPositionY(), homeLoc.GetPositionZ(), homeLoc.GetMapId(), areaId);
6382 // zone update
6383 data.Initialize(SMSG_PLAYERBOUND, 8 + 4);
6384 data << m_caster->GetGUID();
6385 data << uint32(areaId);
6386 player->SendDirectMessage(&data);
6387}
@ SMSG_BINDPOINTUPDATE
Definition: Opcodes.h:371
@ SMSG_PLAYERBOUND
Definition: Opcodes.h:374
Definition: Position.h:251
void WorldRelocate(const WorldLocation &loc)
Definition: Position.h:259
void GetWorldLocation(uint32 &mapId, float &x, float &y) const
Definition: Position.h:281
void SendDirectMessage(WorldPacket const *data) const
Definition: Player.cpp:5594
void SetHomebind(WorldLocation const &loc, uint32 areaId)
Definition: PlayerStorage.cpp:4922

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)
4715{
4717 return;
4718
4720 m_caster->ToPlayer()->SetCanBlock(true);
4721}
void SetCanBlock(bool value)
Definition: Player.cpp:13027

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

◆ 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.

6270{
6272 return;
6273
6275 return;
6276
6277 Player* p_caster = m_caster->ToPlayer();
6278 uint32 button_id = m_spellInfo->Effects[effIndex].MiscValue + 132;
6279 uint32 n_buttons = m_spellInfo->Effects[effIndex].MiscValueB;
6280
6281 for (; n_buttons; --n_buttons, ++button_id)
6282 {
6283 ActionButton const* ab = p_caster->GetActionButton(button_id);
6284 if (!ab || ab->GetType() != ACTION_BUTTON_SPELL)
6285 continue;
6286
6289 uint32 spell_id = ab->GetAction();
6290 if (!spell_id)
6291 continue;
6292
6293 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spell_id);
6294 if (!spellInfo)
6295 continue;
6296
6297 if (!p_caster->HasSpell(spell_id) || p_caster->HasSpellCooldown(spell_id))
6298 continue;
6299
6301 continue;
6302
6303 uint32 cost = spellInfo->CalcPowerCost(m_caster, spellInfo->GetSchoolMask(), this);
6304 if (m_caster->GetPower(POWER_MANA) < cost)
6305 continue;
6306
6308 m_caster->CastSpell(m_caster, spell_id, triggerFlags);
6309 }
6310}
@ ACTION_BUTTON_SPELL
Definition: Player.h:230
@ SPELL_ATTR7_CAN_BE_MULTI_CAST
Definition: SharedDefines.h:618
Definition: Player.h:254
uint32 GetAction() const
Definition: Player.h:262
ActionButtonType GetType() const
Definition: Player.h:261
ActionButton const * GetActionButton(uint8 button)
Definition: Player.cpp:5555
bool HasSpell(uint32 spell) const override
Definition: Player.cpp:3818

References ACTION_BUTTON_SPELL, SpellInfo::CalcPowerCost(), Unit::CastSpell(), effectHandleMode, SpellInfo::Effects, ActionButton::GetAction(), Player::GetActionButton(), Unit::GetPower(), SpellInfo::GetSchoolMask(), ActionButton::GetType(), Object::GetTypeId(), SpellInfo::HasAttribute(), Player::HasSpell(), Player::HasSpellCooldown(), 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, TRIGGERED_IGNORE_GCD, and TYPEID_PLAYER.

◆ EffectCharge()

void Spell::EffectCharge ( SpellEffIndex  effIndex)
4934{
4936 {
4937 if (!unitTarget)
4938 return;
4939
4941 {
4942 sScriptMgr->AnticheatSetSkipOnePacketForASH(m_caster->ToPlayer(), true);
4943 }
4944
4945 // charge changes fall time
4946 if( m_caster->GetTypeId() == TYPEID_PLAYER )
4948
4949 ObjectGuid targetGUID = ObjectGuid::Empty;
4952 {
4953 targetGUID = unitTarget->GetGUID();
4954 }
4955
4956 float speed = G3D::fuzzyGt(m_spellInfo->Speed, 0.0f) ? m_spellInfo->Speed : SPEED_CHARGE;
4957 // Spell is not using explicit target - no generated path
4958 if (!m_preGeneratedPath)
4959 {
4961 m_caster->GetMotionMaster()->MoveCharge(pos.m_positionX, pos.m_positionY, pos.m_positionZ, speed, EVENT_CHARGE, nullptr, false, 0.0f, targetGUID);
4962
4964 {
4965 sScriptMgr->AnticheatSetUnderACKmount(m_caster->ToPlayer());
4966 }
4967 }
4968 else
4969 {
4970 m_caster->GetMotionMaster()->MoveCharge(*m_preGeneratedPath, speed, targetGUID);
4971
4973 {
4974 sScriptMgr->AnticheatSetUnderACKmount(m_caster->ToPlayer());
4975 }
4976 }
4977 }
4978
4980 {
4981 sScriptMgr->AnticheatSetSkipOnePacketForASH(m_caster->ToPlayer(), true);
4982 }
4983}
#define SPEED_CHARGE
Definition: MotionMaster.h:107
@ EVENT_CHARGE
Definition: SharedDefines.h:3283
Position GetFirstCollisionPosition(float startX, float startY, float startZ, float destX, float destY)
Definition: Object.cpp:2784
Definition: Position.h:28
float m_positionZ
Definition: Position.h:58
float GetRelativeAngle(const Position *pos) const
Definition: Position.h:197
float m_positionX
Definition: Position.h:56
float m_positionY
Definition: Position.h:57
void SetFallInformation(uint32 time, float z)
Definition: Player.h:2285
MotionMaster * GetMotionMaster()
Definition: Unit.h:2262
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)
Definition: MotionMaster.cpp:586

References effectHandleMode, ObjectGuid::Empty, EVENT_CHARGE, Unit::GetCombatReach(), WorldObject::GetFirstCollisionPosition(), GameTime::GetGameTime(), Object::GetGUID(), Unit::GetMotionMaster(), Position::GetPositionZ(), Position::GetRelativeAngle(), Unit::GetTarget(), Object::GetTypeId(), 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_HIT_TARGET, SPELL_EFFECT_HANDLE_LAUNCH_TARGET, sScriptMgr, Object::ToPlayer(), TYPEID_PLAYER, and unitTarget.

◆ EffectChargeDest()

◆ EffectCreateItem()

void Spell::EffectCreateItem ( SpellEffIndex  effIndex)
1785{
1787 return;
1788
1789 DoCreateItem(effIndex, m_spellInfo->Effects[effIndex].ItemType);
1790 ExecuteLogEffectCreateItem(effIndex, m_spellInfo->Effects[effIndex].ItemType);
1791}
void ExecuteLogEffectCreateItem(uint8 effIndex, uint32 entry)
Definition: Spell.cpp:5106
void DoCreateItem(uint8 effIndex, uint32 itemId)
Definition: SpellEffects.cpp:1655

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);
1794{
1796 return;
1797
1798 if (!unitTarget)
1799 return;
1800
1801 Player* player = unitTarget->ToPlayer();
1802 if (!player)
1803 {
1804 return;
1805 }
1806
1807 uint32 itemId = m_spellInfo->Effects[effIndex].ItemType;
1808
1809 if (itemId)
1810 DoCreateItem(effIndex, itemId);
1811
1812 // special case: fake item replaced by generate using spell_loot_template
1814 {
1815 if (itemId)
1816 {
1817 if (!player->HasItemCount(itemId))
1818 return;
1819
1820 // remove reagent
1821 uint32 count = 1;
1822 player->DestroyItemCount(itemId, count, true);
1823
1824 // create some random items
1826 }
1827 else
1828 player->AutoStoreLoot(m_spellInfo->Id, LootTemplates_Spell); // create some random items
1829 }
1831}
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:13380
void DestroyItemCount(uint32 item, uint32 count, bool update, bool unequip_check=false)
Definition: PlayerStorage.cpp:3149
bool IsLootCrafting() const
Definition: SpellInfo.cpp:909

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);
1834{
1836 return;
1837
1838 if (!unitTarget)
1839 return;
1840
1841 Player* player = unitTarget->ToPlayer();
1842 if (!player)
1843 {
1844 return;
1845 }
1846
1847 // create some random items
1850}

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)
5888{
5890 return;
5891
5893 return;
5894
5895 uint32 creatureEntry = m_spellInfo->Effects[effIndex].MiscValue;
5896 Pet* pet = unitTarget->CreateTamedPetFrom(creatureEntry, m_spellInfo->Id);
5897 if (!pet)
5898 return;
5899
5900 // add to world
5901 pet->GetMap()->AddToMap(pet->ToCreature(), true);
5902
5903 // unitTarget has pet now
5904 unitTarget->SetMinion(pet, true);
5905
5906 pet->InitTalentForLevel();
5907
5909 {
5912 }
5913}
@ CLASS_HUNTER
Definition: SharedDefines.h:115
void InitTalentForLevel()
Definition: Pet.cpp:2165
void SavePetToDB(PetSaveMode mode)
Definition: Pet.cpp:494
void PetSpellInitialize()
Definition: Player.cpp:9366
void SetMinion(Minion *minion, bool apply)
Definition: Unit.cpp:10640
Pet * CreateTamedPetFrom(Creature *creatureTarget, uint32 spell_id=0)
Definition: Unit.cpp:17511
bool AddToMap(T *, bool checkTransport=false)
Definition: Map.cpp:557

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

◆ EffectDestroyAllTotems()

void Spell::EffectDestroyAllTotems ( SpellEffIndex  effIndex)
5290{
5292 return;
5293
5294 int32 mana = 0;
5295 for (uint8 slot = SUMMON_SLOT_TOTEM; slot < MAX_TOTEM_SLOT; ++slot)
5296 {
5297 if (!m_caster->m_SummonSlot[slot])
5298 continue;
5299
5301 if (totem && totem->IsTotem())
5302 {
5303 uint32 spell_id = totem->GetUInt32Value(UNIT_CREATED_BY_SPELL);
5304 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spell_id);
5305 if (spellInfo)
5306 {
5307 mana += spellInfo->ManaCost;
5309 }
5310 totem->ToTotem()->UnSummon();
5311 }
5312 }
5313 ApplyPct(mana, damage);
5314 if (mana)
5315 m_caster->CastCustomSpell(m_caster, 39104, &mana, nullptr, nullptr, true);
5316}
T ApplyPct(T &base, U pct)
Definition: Util.h:73
@ UNIT_CREATED_BY_SPELL
Definition: UpdateFields.h:138
#define SUMMON_SLOT_TOTEM
Definition: Unit.h:1211
#define MAX_TOTEM_SLOT
Definition: Unit.h:1212
void UnSummon(uint32 msTime=0) override
Definition: Totem.cpp:122
Totem * ToTotem()
Definition: Unit.h:2399
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:1226
uint32 GetCreateMana() const
Definition: Unit.h:2041
ObjectGuid m_SummonSlot[MAX_SUMMON_SLOT]
Definition: Unit.h:2068
Creature * GetCreature(ObjectGuid const guid)
Definition: Map.cpp:3293
uint32 ManaCostPercentage
Definition: SpellInfo.h:365
uint32 ManaCost
Definition: SpellInfo.h:361

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

◆ EffectDiscoverTaxi()

void Spell::EffectDiscoverTaxi ( SpellEffIndex  effIndex)
5916{
5918 return;
5919
5920 if (!unitTarget)
5921 return;
5922
5923 Player* player = unitTarget->ToPlayer();
5924 if (!player)
5925 {
5926 return;
5927 }
5928
5929 uint32 nodeid = m_spellInfo->Effects[effIndex].MiscValue;
5930 if (sTaxiNodesStore.LookupEntry(nodeid))
5931 player->GetSession()->SendDiscoverNewTaxiNode(nodeid);
5932}
DBCStorage< TaxiNodesEntry > sTaxiNodesStore(TaxiNodesEntryfmt)
void SendDiscoverNewTaxiNode(uint32 nodeid)
Definition: TaxiHandler.cpp:160

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)
4493{
4495 return;
4496
4498 return;
4499
4500 if (Player* caster = m_caster->ToPlayer())
4501 {
4502 caster->UpdateCraftSkill(m_spellInfo->Id);
4503 caster->SendLoot(itemTarget->GetGUID(), LOOT_DISENCHANTING);
4504 }
4505
4506 // item will be removed at disenchanting end
4507}
@ LOOT_DISENCHANTING
Definition: LootMgr.h:84

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)
4571{
4573 return;
4574
4575 if (!unitTarget || !unitTarget->IsPet())
4576 return;
4577
4578 Pet* pet = unitTarget->ToPet();
4579
4580 ExecuteLogEffectUnsummonObject(effIndex, pet);
4582}
@ PET_SAVE_NOT_IN_SLOT
Definition: PetDefines.h:45
void Remove(PetSaveMode mode, bool returnreagent=false)
Definition: Pet.cpp:872
void ExecuteLogEffectUnsummonObject(uint8 effIndex, WorldObject *obj)
Definition: Spell.cpp:5124

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

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)
5195{
5197 return;
5198
5199 if (!unitTarget)
5200 return;
5201
5202 uint32 mechanic = m_spellInfo->Effects[effIndex].MiscValue;
5203
5204 std::queue<std::pair<uint32, ObjectGuid>> dispel_list;
5205
5206 Unit::AuraMap const& auras = unitTarget->GetOwnedAuras();
5207 for (Unit::AuraMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
5208 {
5209 Aura* aura = itr->second;
5211 continue;
5213 {
5214 if ((aura->GetSpellInfo()->GetAllEffectsMechanicMask() & (1 << mechanic)))
5215 {
5216 dispel_list.push(std::make_pair(aura->GetId(), aura->GetCasterGUID()));
5217
5218 // spell only removes 1 bleed effect do not continue
5219 if (m_spellInfo->Effects[effIndex].BasePoints == 1)
5220 {
5221 break;
5222 }
5223 }
5224 }
5225 }
5226
5227 for (; dispel_list.size(); dispel_list.pop())
5228 {
5229 unitTarget->RemoveAura(dispel_list.front().first, dispel_list.front().second, 0, AURA_REMOVE_BY_ENEMY_SPELL);
5230 }
5231
5232 // put in combat
5235}
@ AURA_REMOVE_BY_ENEMY_SPELL
Definition: SpellAuraDefines.h:394
void RemoveAura(AuraApplicationMap::iterator &i, AuraRemoveMode mode=AURA_REMOVE_BY_DEFAULT)
Definition: Unit.cpp:4708
ObjectGuid GetCasterGUID() const
Definition: SpellAuras.h:105
uint32 GetId() const
Definition: SpellAuras.cpp:466
int32 CalcDispelChance(Unit *auraTarget, bool offensive) const
Definition: SpellAuras.cpp:1196

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)
2695{
2697 return;
2698
2699 // Check for possible target
2700 if (!unitTarget || unitTarget->IsEngaged())
2701 return;
2702
2703 // target must be OK to do this
2705 return;
2706
2709
2712}
@ UNIT_STATE_CONFUSED
Definition: Unit.h:336
@ UNIT_STATE_FLEEING
Definition: Unit.h:332
@ UNIT_STATE_MOVING
Definition: Unit.h:364
@ UNIT_STATE_STUNNED
Definition: Unit.h:328
float GetAngle(const Position *pos) const
Definition: Position.cpp:77
void SetFacingTo(float ori)
Definition: Unit.cpp:20782
bool IsEngaged() const
Definition: Unit.h:1685
void MoveDistract(uint32 time)
Definition: MotionMaster.cpp:706

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

◆ EffectDualWield()

void Spell::EffectDualWield ( SpellEffIndex  effIndex)
2681{
2683 return;
2684
2686}
virtual void SetCanDualWield(bool value)
Definition: Unit.h:1346

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

◆ EffectDuel()

void Spell::EffectDuel ( SpellEffIndex  effIndex)
4130{
4132 return;
4133
4135 return;
4136
4137 Player* caster = m_caster->ToPlayer();
4138 Player* target = unitTarget->ToPlayer();
4139
4140 // caster or target already have requested duel
4141 if (caster->duel || target->duel || !target->GetSocial() || target->GetSocial()->HasIgnore(caster->GetGUID()))
4142 return;
4143
4144 // Players can only fight a duel in zones with this flag
4145 AreaTableEntry const* casterAreaEntry = sAreaTableStore.LookupEntry(caster->GetAreaId());
4146 if (casterAreaEntry && !(casterAreaEntry->flags & AREA_FLAG_ALLOW_DUELS))
4147 {
4148 SendCastResult(SPELL_FAILED_NO_DUELING); // Dueling isn't allowed here
4149 return;
4150 }
4151
4152 AreaTableEntry const* targetAreaEntry = sAreaTableStore.LookupEntry(target->GetAreaId());
4153 if (targetAreaEntry && !(targetAreaEntry->flags & AREA_FLAG_ALLOW_DUELS))
4154 {
4155 SendCastResult(SPELL_FAILED_NO_DUELING); // Dueling isn't allowed here
4156 return;
4157 }
4158
4159 //CREATE DUEL FLAG OBJECT
4160 uint32 gameobject_id = m_spellInfo->Effects[effIndex].MiscValue;
4161 GameObject* pGameObj = sObjectMgr->IsGameObjectStaticTransport(gameobject_id) ? new StaticTransport() : new GameObject();
4162
4163 Map* map = m_caster->GetMap();
4164 if (!pGameObj->Create(map->GenerateLowGuid<HighGuid::GameObject>(), gameobject_id,
4165 map, m_caster->GetPhaseMask(),
4169 m_caster->GetOrientation(), G3D::Quat(), 0, GO_STATE_READY))
4170 {
4171 delete pGameObj;
4172 return;
4173 }
4174
4177 int32 duration = m_spellInfo->GetDuration();
4178 pGameObj->SetRespawnTime(duration > 0 ? duration / IN_MILLISECONDS : 0);
4179 pGameObj->SetSpellId(m_spellInfo->Id);
4180
4181 ExecuteLogEffectSummonObject(effIndex, pGameObj);
4182
4183 m_caster->AddGameObject(pGameObj);
4184 map->AddToMap(pGameObj, true);
4185 //END
4186
4187 // Send request
4188 WorldPacket data(SMSG_DUEL_REQUESTED, 8 + 8);
4189 data << pGameObj->GetGUID();
4190 data << caster->GetGUID();
4191 caster->GetSession()->SendPacket(&data);
4192 target->GetSession()->SendPacket(&data);
4193
4194 // create duel-info
4195 bool isMounted = (GetSpellInfo()->Id == 62875);
4196 caster->duel = std::make_unique<DuelInfo>(target, caster, isMounted);
4197 target->duel = std::make_unique<DuelInfo>(caster, caster, isMounted);
4198
4199 caster->SetGuidValue(PLAYER_DUEL_ARBITER, pGameObj->GetGUID());
4200 target->SetGuidValue(PLAYER_DUEL_ARBITER, pGameObj->GetGUID());
4201
4202 sScriptMgr->OnPlayerDuelRequest(target, caster);
4203}
@ PLAYER_DUEL_ARBITER
Definition: UpdateFields.h:177
@ GAMEOBJECT_LEVEL
Definition: UpdateFields.h:403
@ GAMEOBJECT_FACTION
Definition: UpdateFields.h:402
@ AREA_FLAG_ALLOW_DUELS
Definition: DBCEnums.h:245
@ SPELL_FAILED_NO_DUELING
Definition: SharedDefines.h:1000
@ SMSG_DUEL_REQUESTED
Definition: Opcodes.h:389
virtual bool Create(ObjectGuid::LowType guidlow, uint32 name_id, Map *map, uint32 phaseMask, float x, float y, float z, float ang, G3D::Quat const &rotation, uint32 animprogress, GOState go_state, uint32 artKit=0)
Definition: GameObject.cpp:248
void SetRespawnTime(int32 respawn)
Definition: GameObject.cpp:1301
void SetSpellId(uint32 id)
Definition: GameObject.h:178
uint32 GetPhaseMask() const
Definition: Object.h:434
float GetOrientation() const
Definition: Position.h:120
PlayerSocial * GetSocial()
Definition: Player.h:1121
bool HasIgnore(ObjectGuid ignore_guid) const
Definition: SocialMgr.cpp:193
Definition: Transport.h:112
uint32 GetFaction() const
Definition: Unit.h:1495
void AddGameObject(GameObject *gameObj)
Definition: Unit.cpp:6091
void SendPacket(WorldPacket const *packet)
Send a packet to the client.
Definition: WorldSession.cpp:207
void ExecuteLogEffectSummonObject(uint8 effIndex, WorldObject *obj)
Definition: Spell.cpp:5118
uint32 flags
Definition: DBCStructure.h:524

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

◆ EffectDummy()

void Spell::EffectDummy ( SpellEffIndex  effIndex)
670{
672 return;
673
675 return;
676
677 // selection by spell family
679 {
681 {
682 switch (m_spellInfo->Id)
683 {
684 // Trial of the Champion, Trample
685 case 67866:
686 {
688 unitTarget->CastSpell(unitTarget, 67867, false);
689 return;
690 }
691 // Trial of the Champion, Hammer of the Righteous
692 case 66867:
693 {
694 if( !unitTarget )
695 return;
696 if( unitTarget->HasAura(66940) )
697 m_caster->CastSpell(unitTarget, 66903, true);
698 else
699 m_caster->CastSpell(unitTarget, 66904, true);
700 return;
701 }
702 case 17731:
703 case 69294:
704 {
706 return;
707
711 trigger->CastSpell(trigger, 17731, false);
712
713 return;
714 }
715 // HoL, Arc Weld
716 case 59086:
717 {
719 m_caster->CastSpell(m_caster, 59097, true);
720
721 return;
722 }
723 }
724 break;
725 }
727 switch (m_spellInfo->Id)
728 {
729 case 31789: // Righteous Defense (step 1)
730 {
731 if (!unitTarget)
732 return;
733 // not empty (checked), copy
735
736 // remove invalid attackers
737 for (Unit::AttackerSet::iterator aItr = attackers.begin(); aItr != attackers.end();)
738 if (!(*aItr)->IsValidAttackTarget(m_caster))
739 aItr = attackers.erase(aItr);
740 else
741 ++aItr;
742
743 // selected from list 3
744 uint32 maxTargets = std::min<uint32>(3, attackers.size());
745 for (uint32 i = 0; i < maxTargets; ++i)
746 {
747 Unit::AttackerSet::iterator aItr = attackers.begin();
748 std::advance(aItr, urand(0, attackers.size() - 1));
749 m_caster->CastSpell((*aItr), 31790, true);
750 attackers.erase(aItr);
751 }
752
753 return;
754 }
755 }
756 break;
758 // Hunger for Blood
759 if( m_spellInfo->Id == 51662 )
760 {
761 m_caster->CastSpell(m_caster, 63848, true);
762 return;
763 }
764 break;
765 }
766
767 // pet auras
768 if (PetAura const* petSpell = sSpellMgr->GetPetAura(m_spellInfo->Id, effIndex))
769 {
770 m_caster->AddPetAura(petSpell);
771 return;
772 }
773
774 // normal DB scripted effect
775 LOG_DEBUG("spells.aura", "Spell ScriptStart spellid {} in EffectDummy({})", m_spellInfo->Id, effIndex);
777
778 if (gameObjTarget)
779 {
780 sScriptMgr->OnDummyEffect(m_caster, m_spellInfo->Id, effIndex, gameObjTarget);
781 }
782 else if (unitTarget && unitTarget->GetTypeId() == TYPEID_UNIT)
783 {
784 sScriptMgr->OnDummyEffect(m_caster, m_spellInfo->Id, effIndex, unitTarget->ToCreature());
785 }
786 else if (itemTarget)
787 {
788 sScriptMgr->OnDummyEffect(m_caster, m_spellInfo->Id, effIndex, itemTarget);
789 }
790}
@ TEMPSUMMON_TIMED_DESPAWN
Definition: Object.h:44
@ UNIT_FIELD_MOUNTDISPLAYID
Definition: UpdateFields.h:126
ScriptMapMap sSpellScripts
Definition: ObjectMgr.cpp:59
@ SPELLFAMILY_GENERIC
Definition: SharedDefines.h:3500
@ SPELLFAMILY_PALADIN
Definition: SharedDefines.h:3510
@ SPELLFAMILY_ROGUE
Definition: SharedDefines.h:3508
uint8 GetGoAnimProgress() const
Definition: GameObject.h:211
time_t GetRespawnTime() const
Definition: GameObject.h:185
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:2318
void AddPetAura(PetAura const *petSpell)
Definition: Unit.cpp:17457
std::unordered_set< Unit * > AttackerSet
Definition: Unit.h:1292
AttackerSet const & getAttackers() const
Definition: Unit.h:1383
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:34
Definition: SpellMgr.h:463

References Unit::AddPetAura(), Unit::CastSpell(), effectHandleMode, gameObjTarget, Unit::getAttackers(), GameTime::GetGameTime(), GameObject::GetGoAnimProgress(), WorldObject::GetMap(), GameObject::GetRespawnTime(), Object::GetTypeId(), Object::GetUInt32Value(), Unit::HasAura(), SpellInfo::Id, Unit::isMoving(), 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(), TYPEID_PLAYER, TYPEID_UNIT, UNIT_FIELD_MOUNTDISPLAYID, unitTarget, and urand().

◆ EffectDurabilityDamage()

void Spell::EffectDurabilityDamage ( SpellEffIndex  effIndex)
5319{
5321 return;
5322
5323 if (!unitTarget)
5324 return;
5325
5326 Player* player = unitTarget->ToPlayer();
5327 if (!player)
5328 {
5329 return;
5330 }
5331
5332 int32 slot = m_spellInfo->Effects[effIndex].MiscValue;
5333
5334 // -1 means all player equipped items and -2 all items
5335 if (slot < 0)
5336 {
5337 player->DurabilityPointsLossAll(damage, (slot < -1));
5339 return;
5340 }
5341
5342 // invalid slot value
5343 if (slot >= INVENTORY_SLOT_BAG_END)
5344 return;
5345
5346 if (Item* item = player->GetItemByPos(INVENTORY_SLOT_BAG_0, slot))
5347 {
5348 player->DurabilityPointsLoss(item, damage);
5349 ExecuteLogEffectDurabilityDamage(effIndex, unitTarget, item->GetEntry(), slot);
5350 }
5351}
@ INVENTORY_SLOT_BAG_END
Definition: Player.h:701
#define INVENTORY_SLOT_BAG_0
Definition: Player.h:671
Item * GetItemByPos(uint16 pos) const
Definition: PlayerStorage.cpp:472
void DurabilityPointsLossAll(int32 points, bool inventory)
Definition: Player.cpp:4661
void DurabilityPointsLoss(Item *item, int32 points)
Definition: Player.cpp:4687
void ExecuteLogEffectDurabilityDamage(uint8 effIndex, Unit *victim, int32 itemId, int32 slot)
Definition: Spell.cpp:5092

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)
5354{
5356 return;
5357
5358 if (!unitTarget)
5359 return;
5360
5361 Player* player = unitTarget->ToPlayer();
5362 if (!player)
5363 {
5364 return;
5365 }
5366
5367 int32 slot = m_spellInfo->Effects[effIndex].MiscValue;
5368
5369 // FIXME: some spells effects have value -1/-2
5370 // Possibly its mean -1 all player equipped items and -2 all items
5371 if (slot < 0)
5372 {
5373 player->DurabilityLossAll(float(damage) / 100.0f, (slot < -1));
5374 return;
5375 }
5376
5377 // invalid slot value
5378 if (slot >= INVENTORY_SLOT_BAG_END)
5379 return;
5380
5381 if (damage <= 0)
5382 return;
5383
5384 if (Item* item = player->GetItemByPos(INVENTORY_SLOT_BAG_0, slot))
5385 player->DurabilityLoss(item, float(damage) / 100.0f);
5386}
void DurabilityLossAll(double percent, bool inventory)
Definition: Player.cpp:4617
void DurabilityLoss(Item *item, double percent)
Definition: Player.cpp:4643

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)
4440{
4442 return;
4443
4444 // this is only item spell effect applied to main-hand weapon of target player (players in area)
4445 if (!unitTarget)
4446 return;
4447
4448 Player* item_owner = unitTarget->ToPlayer();
4449 if (!item_owner)
4450 {
4451 return;
4452 }
4453
4455 if (!item)
4456 return;
4457
4458 // must be equipped
4459 if (!item->IsEquipped())
4460 return;
4461
4462 if (m_spellInfo->Effects[effIndex].MiscValue)
4463 {
4464 uint32 enchant_id = m_spellInfo->Effects[effIndex].MiscValue;
4465 int32 duration = m_spellInfo->GetDuration(); //Try duration index first ..
4466 if (!duration)
4467 duration = damage * IN_MILLISECONDS; //+1; //Base points after ..
4468 if (!duration)
4469 duration = 10 * IN_MILLISECONDS; //10 seconds for enchants which don't have listed duration
4470
4471 // Xinef: Venomhide poison, no other spell uses this effect...
4472 if (m_spellInfo->Id == 14792)
4473 duration = 5 * MINUTE * IN_MILLISECONDS;
4474
4475 SpellItemEnchantmentEntry const* pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id);
4476 if (!pEnchant)
4477 return;
4478
4479 // Always go to temp enchantment slot
4481
4482 // Enchantment will not be applied if a different one already exists
4483 if (item->GetEnchantmentId(slot) && item->GetEnchantmentId(slot) != enchant_id)
4484 return;
4485
4486 // Apply the temporary enchantment
4487 item->SetEnchantment(slot, enchant_id, duration, pEnchant->charges, m_caster->GetGUID());
4488 item_owner->ApplyEnchantment(item, slot, true);
4489 }
4490}
EnchantmentSlot
Definition: Item.h:162
@ TEMP_ENCHANTMENT_SLOT
Definition: Item.h:164
@ EQUIPMENT_SLOT_MAINHAND
Definition: Player.h:691
bool IsEquipped() const
Definition: Item.cpp:791
void SetEnchantment(EnchantmentSlot slot, uint32 id, uint32 duration, uint32 charges, ObjectGuid caster=ObjectGuid::Empty)
Definition: Item.cpp:922
void ApplyEnchantment(Item *item, EnchantmentSlot slot, bool apply, bool apply_dur=true, bool ignore_condition=false)
Definition: PlayerStorage.cpp:4332
uint32 charges
Definition: DBCStructure.h:1819

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)
2842{
2844 return;
2845
2847 return;
2848 if (!itemTarget)
2849 return;
2850
2851 Player* p_caster = m_caster->ToPlayer();
2852
2853 // Handle vellums
2855 {
2856 // destroy one vellum from stack
2857 uint32 count = 1;
2858 p_caster->DestroyItemCount(itemTarget, count, true);
2859 unitTarget = p_caster;
2860 // and add a scroll
2861 DoCreateItem(effIndex, m_spellInfo->Effects[effIndex].ItemType);
2862 itemTarget = nullptr;
2863 m_targets.SetItemTarget(nullptr);
2864 }
2865 else
2866 {
2867 // do not increase skill if vellum used
2869 p_caster->UpdateCraftSkill(m_spellInfo->Id);
2870
2871 uint32 enchant_id = m_spellInfo->Effects[effIndex].MiscValue;
2872 if (!enchant_id)
2873 return;
2874
2875 SpellItemEnchantmentEntry const* pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id);
2876 if (!pEnchant)
2877 return;
2878
2879 // item can be in trade slot and have owner diff. from caster
2880 Player* item_owner = itemTarget->GetOwner();
2881 if (!item_owner)
2882 return;
2883
2884 // remove old enchanting before applying new if equipped
2886
2888
2889 // add new enchanting if equipped
2891
2892 item_owner->RemoveTradeableItem(itemTarget);
2894 }
2895}
@ PERM_ENCHANTMENT_SLOT
Definition: Item.h:163
void ClearSoulboundTradeable(Player *currentOwner)
Definition: Item.cpp:1266
void RemoveTradeableItem(Item *item)
Definition: PlayerStorage.cpp:4167
void SetItemTarget(Item *item)
Definition: Spell.cpp:322

References Player::ApplyEnchantment(), Item::ClearSoulboundTradeable(), Player::DestroyItemCount(), DoCreateItem(), effectHandleMode, SpellInfo::Effects, ItemTemplate::Flags, Object::GetGUID(), Item::GetOwner(), Item::GetTemplate(), Object::GetTypeId(), SpellInfo::Id, Item::IsArmorVellum(), 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(), TYPEID_PLAYER, unitTarget, and Player::UpdateCraftSkill().

◆ EffectEnchantItemPrismatic()

void Spell::EffectEnchantItemPrismatic ( SpellEffIndex  effIndex)
2898{
2900 return;
2901
2903 return;
2904 if (!itemTarget)
2905 return;
2906
2907 uint32 enchant_id = m_spellInfo->Effects[effIndex].MiscValue;
2908 if (!enchant_id)
2909 return;
2910
2911 SpellItemEnchantmentEntry const* pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id);
2912 if (!pEnchant)
2913 return;
2914
2915 // support only enchantings with add socket in this slot
2916 {
2917 bool add_socket = false;
2918 for (uint8 i = 0; i < MAX_SPELL_ITEM_ENCHANTMENT_EFFECTS; ++i)
2919 {
2920 if (pEnchant->type[i] == ITEM_ENCHANTMENT_TYPE_PRISMATIC_SOCKET)
2921 {
2922 add_socket = true;
2923 break;
2924 }
2925 }
2926 if (!add_socket)
2927 {
2928 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.",
2930 return;
2931 }
2932 }
2933
2934 // item can be in trade slot and have owner diff. from caster
2935 Player* item_owner = itemTarget->GetOwner();
2936 if (!item_owner)
2937 return;
2938
2939 // remove old enchanting before applying new if equipped
2941
2943
2944 // add new enchanting if equipped
2946
2947 item_owner->RemoveTradeableItem(itemTarget);
2949}

References Player::ApplyEnchantment(), Item::ClearSoulboundTradeable(), effectHandleMode, SpellInfo::Effects, Object::GetGUID(), Item::GetOwner(), Object::GetTypeId(), SpellInfo::Id, 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, SpellItemEnchantmentEntry::type, and TYPEID_PLAYER.

◆ EffectEnchantItemTmp()

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

References Player::ApplyEnchantment(), BASE_ATTACK, SpellItemEnchantmentEntry::charges, Item::ClearSoulboundTradeable(), damage, effectHandleMode, SpellInfo::Effects, Object::GetGUID(), Item::GetOwner(), Object::GetTypeId(), Player::GetWeaponForAttack(), SpellInfo::Id, 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(), TRIGGERED_FULL_MASK, and TYPEID_PLAYER.

◆ EffectEnergize()

void Spell::EffectEnergize ( SpellEffIndex  effIndex)
1887{
1889 return;
1890
1891 if (!unitTarget)
1892 return;
1893 if (!unitTarget->IsAlive())
1894 return;
1895
1896 if (m_spellInfo->Effects[effIndex].MiscValue < 0 || m_spellInfo->Effects[effIndex].MiscValue >= int8(MAX_POWERS))
1897 return;
1898
1899 Powers power = Powers(m_spellInfo->Effects[effIndex].MiscValue);
1900
1903 return;
1904
1905 if (unitTarget->GetMaxPower(power) == 0)
1906 return;
1907
1908 // Some level depends spells
1909 int level_multiplier = 0;
1910 int level_diff = 0;
1911 switch (m_spellInfo->Id)
1912 {
1913 case 9512: // Restore Energy
1914 level_diff = m_caster->GetLevel() - 40;
1915 level_multiplier = 2;
1916 break;
1917 case 24571: // Blood Fury
1918 level_diff = m_caster->GetLevel() - 60;
1919 level_multiplier = 10;
1920 break;
1921 case 24532: // Burst of Energy
1922 level_diff = m_caster->GetLevel() - 60;
1923 level_multiplier = 4;
1924 break;
1925 case 31930: // Judgements of the Wise
1926 case 63375: // Improved Stormstrike
1927 case 68082: // Glyph of Seal of Command
1929 break;
1930 case 48542: // Revitalize
1932 break;
1933 case 67490: // Runic Mana Injector (mana gain increased by 25% for engineers - 3.2.0 patch change)
1934 {
1935 if (Player* player = m_caster->ToPlayer())
1936 if (player->HasSkill(SKILL_ENGINEERING))
1937 AddPct(damage, 25);
1938 break;
1939 }
1940 case 71132: // Glyph of Shadow Word: Pain
1941 damage = int32(CalculatePct(unitTarget->GetCreateMana(), 1)); // set 1 as value, missing in dbc
1942 break;
1943 default:
1944 break;
1945 }
1946
1947 if (level_diff > 0)
1948 damage -= level_multiplier * level_diff;
1949
1950 if (damage < 0)
1951 return;
1952
1954
1955 // Mad Alchemist's Potion
1956 if (m_spellInfo->Id == 45051)
1957 {
1958 // find elixirs on target
1959 bool guardianFound = false;
1960 bool battleFound = false;
1962 for (Unit::AuraApplicationMap::iterator itr = Auras.begin(); itr != Auras.end(); ++itr)
1963 {
1964 SpellGroupSpecialFlags sFlag = sSpellMgr->GetSpellGroupSpecialFlags(itr->second->GetBase()->GetId());
1965 if (!guardianFound)
1967 guardianFound = true;
1968 if (!battleFound)
1970 battleFound = true;
1971 if (battleFound && guardianFound)
1972 break;
1973 }
1974
1975 // get all available elixirs by mask and spell level
1976 std::set<uint32> availableElixirs;
1977 if (!guardianFound)
1978 sSpellMgr->GetSetOfSpellsInSpellGroupWithFlag(1, SPELL_GROUP_SPECIAL_FLAG_ELIXIR_GUARDIAN, availableElixirs);
1979 if (!battleFound)
1980 sSpellMgr->GetSetOfSpellsInSpellGroupWithFlag(1, SPELL_GROUP_SPECIAL_FLAG_ELIXIR_BATTLE, availableElixirs);
1981 for (std::set<uint32>::iterator itr = availableElixirs.begin(); itr != availableElixirs.end();)
1982 {
1983 SpellInfo const* spellInfo = sSpellMgr->AssertSpellInfo(*itr);
1984 if (spellInfo->SpellLevel < m_spellInfo->SpellLevel || spellInfo->SpellLevel > unitTarget->GetLevel())
1985 availableElixirs.erase(itr++);
1986 else
1987 ++itr;
1988 }
1989
1990 if (!availableElixirs.empty())
1991 {
1992 // cast random elixir on target
1994 }
1995 }
1996}
SpellGroupSpecialFlags
Definition: SpellMgr.h:327
@ SPELL_GROUP_SPECIAL_FLAG_ELIXIR_BATTLE
Definition: SpellMgr.h:329
@ SPELL_GROUP_SPECIAL_FLAG_ELIXIR_GUARDIAN
Definition: SpellMgr.h:330
@ SPELL_ATTR7_ONLY_IN_SPELLBOOK_UNTIL_LEARNED
Definition: SharedDefines.h:629
@ SPELLFAMILY_POTION
Definition: SharedDefines.h:3513
@ SKILL_ENGINEERING
Definition: SharedDefines.h:2895
auto SelectRandomContainerElement(C const &container) -> typename std::add_const< decltype(*std::begin(container))>::type &
Definition: Containers.h:135
void EnergizeBySpell(Unit *victim, uint32 SpellID, uint32 Damage, Powers powertype)
Definition: Unit.cpp:11222

References AddPct(), CalculatePct(), Unit::CastSpell(), damage, effectHandleMode, SpellInfo::Effects, Unit::EnergizeBySpell(), Unit::GetAppliedAuras(), Unit::GetCreateMana(), Unit::GetLevel(), Unit::GetMaxPower(), Unit::getPowerType(), Object::GetTypeId(), SpellInfo::HasAttribute(), SpellInfo::Id, Unit::IsAlive(), m_caster, m_CastItem, m_spellInfo, MAX_POWERS, Acore::Containers::SelectRandomContainerElement(), SKILL_ENGINEERING, 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, Object::ToPlayer(), TYPEID_PLAYER, and unitTarget.

◆ EffectEnergizePct()

void Spell::EffectEnergizePct ( SpellEffIndex  effIndex)
1999{
2001 return;
2002
2003 if (!unitTarget)
2004 return;
2005 if (!unitTarget->IsAlive())
2006 return;
2007
2008 if (m_spellInfo->Effects[effIndex].MiscValue < 0 || m_spellInfo->Effects[effIndex].MiscValue >= int8(MAX_POWERS))
2009 return;
2010
2011 Powers power = Powers(m_spellInfo->Effects[effIndex].MiscValue);
2012
2014 return;
2015
2016 uint32 maxPower = unitTarget->GetMaxPower(power);
2017 if (maxPower == 0)
2018 return;
2019
2020 uint32 gain = CalculatePct(maxPower, damage);
2022}

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

◆ EffectEnvironmentalDMG()

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

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
4538{
4540 return;
4541
4542 Player* player = m_caster->ToPlayer();
4543 if (!player)
4544 return;
4545
4546 Item* foodItem = itemTarget;
4547 if (!foodItem)
4548 return;
4549
4550 Pet* pet = player->GetPet();
4551 if (!pet)
4552 return;
4553
4554 if (!pet->IsAlive())
4555 return;
4556
4557 int32 benefit = pet->GetCurrentFoodBenefitLevel(foodItem->GetTemplate()->ItemLevel);
4558 if (benefit <= 0)
4559 return;
4560
4561 ExecuteLogEffectDestroyItem(effIndex, foodItem->GetEntry());
4562
4563 uint32 count = 1;
4564 player->DestroyItemCount(foodItem, count, true);
4566
4567 m_caster->CastCustomSpell(pet, m_spellInfo->Effects[effIndex].TriggerSpell, &benefit, nullptr, nullptr, true);
4568}
void ExecuteLogEffectDestroyItem(uint8 effIndex, uint32 entry)
Definition: Spell.cpp:5112

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)
1021{
1023 return;
1024
1025 if (!unitTarget)
1026 return;
1027
1028 uint32 triggered_spell_id = m_spellInfo->Effects[effIndex].TriggerSpell;
1029
1030 // normal case
1031 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(triggered_spell_id);
1032
1033 if (!spellInfo)
1034 {
1035 LOG_ERROR("spells.effect", "Spell::EffectForceCast of spell {}: triggering unknown spell id {}", m_spellInfo->Id, triggered_spell_id);
1036 return;
1037 }
1038
1039 if (m_spellInfo->Effects[effIndex].Effect == SPELL_EFFECT_FORCE_CAST && damage)
1040 {
1041 switch (m_spellInfo->Id)
1042 {
1043 case 52588: // Skeletal Gryphon Escape
1044 case 48598: // Ride Flamebringer Cue
1046 break;
1047 case 52463: // Hide In Mine Car
1048 case 52349: // Overtake
1049 unitTarget->CastCustomSpell(unitTarget, spellInfo->Id, &damage, nullptr, nullptr, true, nullptr, nullptr, m_originalCasterGUID);
1050 return;
1051 case 72378: // Blood Nova
1052 case 73058: // Blood Nova
1053 m_caster->CastSpell(unitTarget, damage, true); // additional spell cast
1054 break;
1055 }
1056 }
1057
1058 CustomSpellValues values;
1059 // set basepoints for trigger with value effect
1061 {
1062 // maybe need to set value only when basepoints == 0?
1066 }
1067
1068 SpellCastTargets targets;
1069 targets.SetUnitTarget(m_caster);
1070
1071 unitTarget->CastSpell(targets, spellInfo, &values, TRIGGERED_FULL_MASK);
1072}
@ SPELLVALUE_BASE_POINT1
Definition: SpellDefines.h:115
@ SPELLVALUE_BASE_POINT2
Definition: SpellDefines.h:116
@ SPELLVALUE_BASE_POINT0
Definition: SpellDefines.h:114
@ SPELL_EFFECT_FORCE_CAST
Definition: SharedDefines.h:890
@ SPELL_EFFECT_FORCE_CAST_WITH_VALUE
Definition: SharedDefines.h:891
Definition: SpellDefines.h:162
void AddSpellMod(SpellValueMod mod, int32 value)
Definition: SpellDefines.h:164

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)
4794{
4796 return;
4797
4798 // xinef: clear focus
4800
4802 data << m_caster->GetGUID();
4803
4805 Acore::MessageDistDelivererToHostile notifier(m_caster, &data, dist);
4806 Cell::VisitWorldObjects(m_caster, notifier, dist);
4807
4808 // xinef: we should also force pets to remove us from current target
4809 Unit::AttackerSet attackerSet;
4810 for (Unit::AttackerSet::const_iterator itr = m_caster->getAttackers().begin(); itr != m_caster->getAttackers().end(); ++itr)
4811 if ((*itr)->GetTypeId() == TYPEID_UNIT && !(*itr)->CanHaveThreatList())
4812 attackerSet.insert(*itr);
4813
4814 for (Unit::AttackerSet::const_iterator itr = attackerSet.begin(); itr != attackerSet.end(); ++itr)
4815 (*itr)->AttackStop();
4816
4817 // Xinef: Mirror images code Initialize Images
4818 if (m_spellInfo->Id == 58836)
4819 {
4820 std::vector<Unit*> images;
4821 for (Unit::ControlSet::const_iterator itr = m_caster->m_Controlled.begin(); itr != m_caster->m_Controlled.end(); ++itr)
4822 if ((*itr)->GetEntry() == 31216 /*NPC_MIRROR_IMAGE*/)
4823 images.push_back(*itr);
4824
4825 if (images.empty())
4826 return;
4827
4828 UnitList targets;
4829 Acore::AnyUnfriendlyUnitInObjectRangeCheck u_check(m_caster, m_caster, m_caster->GetVisibilityRange()); // no VISIBILITY_COMPENSATION, distance is enough
4832 for (UnitList::iterator iter = targets.begin(); iter != targets.end(); ++iter)
4833 {
4834 if (!(*iter)->HasUnitState(UNIT_STATE_CASTING))
4835 continue;
4836
4837 if (Spell* spell = (*iter)->GetCurrentSpell(CURRENT_GENERIC_SPELL))
4838 {
4839 if (spell->m_targets.GetUnitTargetGUID() == m_caster->GetGUID())
4840 {
4841 SpellInfo const* si = spell->GetSpellInfo();
4842 if (si->HasAttribute(SPELL_ATTR6_IGNORE_PHASE_SHIFT) && (*iter)->GetTypeId() == TYPEID_UNIT)
4843 {
4844 Creature* c = (*iter)->ToCreature();
4845 if ((!c->IsPet() && c->GetCreatureTemplate()->rank == CREATURE_ELITE_WORLDBOSS) || c->isWorldBoss() || c->IsDungeonBoss())
4846 continue;
4847 }
4848
4849 bool interrupt = false; // pussywizard: skip spells that don't target units, but casted on unit (eg. TARGET_DEST_TARGET_ENEMY)
4850 for (uint8 j = 0; j < MAX_SPELL_EFFECTS; ++j)
4851 if (si->Effects[j].Effect && (si->Effects[j].GetUsedTargetObjectType() == TARGET_OBJECT_TYPE_UNIT || si->Effects[j].GetUsedTargetObjectType() == TARGET_OBJECT_TYPE_UNIT_AND_DEST))
4852 {
4853 // at least one effect truly targets an unit, interrupt the spell
4854 interrupt = true;
4855 break;
4856 }
4857
4858 if (interrupt)
4859 spell->m_targets.SetUnitTarget(images.at(urand(0, images.size() - 1)));
4860 }
4861 }
4862 }
4863 }
4864}
#define VISIBILITY_COMPENSATION
Definition: ObjectDefines.h:26
std::list< Unit * > UnitList
Definition: Unit.h:240
@ TARGET_OBJECT_TYPE_UNIT
Definition: SpellInfo.h:101
@ TARGET_OBJECT_TYPE_UNIT_AND_DEST
Definition: SpellInfo.h:102
@ CREATURE_ELITE_WORLDBOSS
Definition: SharedDefines.h:2706
@ SPELL_ATTR6_IGNORE_PHASE_SHIFT
Definition: SharedDefines.h:589
@ SMSG_CLEAR_TARGET
Definition: Opcodes.h:989
bool IsDungeonBoss() const
Definition: Creature.cpp:3063
uint32 rank
Definition: CreatureData.h:199
ControlSet m_Controlled
Definition: Unit.h:1867
void SendClearTarget()
Definition: Unit.cpp:20479
static void VisitAllObjects(WorldObject const *obj, T &visitor, float radius, bool dont_load=true)
Definition: CellImpl.h:207
static void VisitWorldObjects(WorldObject const *obj, T &visitor, float radius, bool dont_load=true)
Definition: CellImpl.h:193
Definition: GridNotifiers.h:130
Definition: GridNotifiers.h:420
Definition: GridNotifiers.h:858

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(), TYPEID_UNIT, UNIT_STATE_CASTING, urand(), VISIBILITY_COMPENSATION, Cell::VisitAllObjects(), and Cell::VisitWorldObjects().

◆ EffectGameObjectDamage()

void Spell::EffectGameObjectDamage ( SpellEffIndex  effIndex)
5960{
5962 return;
5963
5964 if (!gameObjTarget)
5965 return;
5966
5967 Unit* caster = m_originalCaster;
5968 if (!caster)
5969 return;
5970
5971 FactionTemplateEntry const* casterFaction = caster->GetFactionTemplateEntry();
5973 // Do not allow to damage GO's of friendly factions (ie: Wintergrasp Walls/Ulduar Storm Beacons)
5974 if ((casterFaction && targetFaction && !casterFaction->IsFriendlyTo(*targetFaction)) || !targetFaction)
5976}
DBCStorage< FactionTemplateEntry > sFactionTemplateStore(FactionTemplateEntryfmt)
void ModifyHealth(int32 change, Unit *attackerOrHealer=nullptr, uint32 spellId=0)
Definition: GameObject.cpp:2274
FactionTemplateEntry const * GetFactionTemplateEntry() const
Definition: Unit.cpp:10007
Definition: DBCStructure.h:930
bool IsFriendlyTo(FactionTemplateEntry const &entry) const
Definition: DBCStructure.h:942

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)
5990{
5992 return;
5993
5995 return;
5996
5999}
GameObjectDestructibleState
Definition: SharedDefines.h:1598
void SetDestructibleState(GameObjectDestructibleState state, Player *eventInvoker=nullptr, bool setHealth=false)
Definition: GameObject.cpp:2330

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

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)
3697{
3699 return;
3700
3701 if (!unitTarget || !unitTarget->IsAlive())
3702 return;
3703
3704 int32 addhealth = 0;
3705
3706 // damage == 0 - heal for caster max health
3707 if (damage == 0)
3708 addhealth = m_caster->GetMaxHealth();
3709 else
3710 addhealth = unitTarget->GetMaxHealth() - unitTarget->GetHealth();
3711
3712 m_healing += addhealth;
3713}
uint32 GetMaxHealth() const
Definition: Unit.h:1441

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

◆ EffectHealMechanical()

void Spell::EffectHealMechanical ( SpellEffIndex  effIndex)

◆ EffectHealPct()

void Spell::EffectHealPct ( SpellEffIndex  effIndex)

◆ EffectHealthLeech()

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

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)
4510{
4512 return;
4513
4514 if (!unitTarget)
4515 return;
4516
4517 Player* player = unitTarget->ToPlayer();
4518 if (!player)
4519 {
4520 return;
4521 }
4522
4523 uint8 currentDrunk = player->GetDrunkValue();
4524 uint8 drunkMod = damage;
4525 if (currentDrunk + drunkMod > 100)
4526 {
4527 currentDrunk = 100;
4528 if (rand_chance() < 25.0f)
4529 player->CastSpell(player, 67468, false); // Drunken Vomit
4530 }
4531 else
4532 currentDrunk += drunkMod;
4533
4534 player->SetDrunkValue(currentDrunk, m_CastItem ? m_CastItem->GetEntry() : 0);
4535}
double rand_chance()
Definition: Random.cpp:83
uint8 GetDrunkValue() const
Definition: Player.h:2122
void SetDrunkValue(uint8 newDrunkValue, uint32 itemId=0)
Definition: Player.cpp:971

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

◆ EffectInstaKill()

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

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

◆ EffectInterruptCast()

void Spell::EffectInterruptCast ( SpellEffIndex  effIndex)
Todo:
: not all spells that used this effect apply cooldown at school spells
3716{
3718 return;
3719
3720 if (!unitTarget || !unitTarget->IsAlive())
3721 return;
3722
3724 // also exist case: apply cooldown to interrupted cast only and to all spells
3725 // there is no CURRENT_AUTOREPEAT_SPELL spells that can be interrupted
3727 {
3729 {
3730 SpellInfo const* curSpellInfo = spell->m_spellInfo;
3731 // check if we can interrupt spell
3732 if ((spell->getState() == SPELL_STATE_CASTING
3733 || (spell->getState() == SPELL_STATE_PREPARING && spell->GetCastTime() > 0.0f))
3737 {
3738 if (m_originalCaster)
3739 {
3741 unitTarget->ProhibitSpellSchool(curSpellInfo->GetSchoolMask(), duration/*spellInfo->GetDuration()*/);
3742 }
3743 ExecuteLogEffectInterruptCast(effIndex, unitTarget, curSpellInfo->Id);
3745 }
3746 }
3747 }
3748}
#define CURRENT_FIRST_NON_MELEE_SPELL
Definition: Unit.h:984
CurrentSpellTypes
Definition: Unit.h:977
@ CURRENT_CHANNELED_SPELL
Definition: Unit.h:980
@ CURRENT_AUTOREPEAT_SPELL
Definition: Unit.h:981
@ CHANNEL_INTERRUPT_FLAG_INTERRUPT
Definition: SpellDefines.h:38
@ SPELL_INTERRUPT_FLAG_INTERRUPT
Definition: SpellDefines.h:30
void InterruptSpell(CurrentSpellTypes spellType, bool withDelayed=true, bool withInstant=true, bool bySelf=false)
Definition: Unit.cpp:4002
int32 CalcSpellDuration(SpellInfo const *spellProto)
Definition: Unit.cpp:14748
virtual void ProhibitSpellSchool(SpellSchoolMask, uint32)
Definition: Unit.h:2048
void ExecuteLogEffectInterruptCast(uint8 effIndex, Unit *victim, uint32 spellId)
Definition: Spell.cpp:5085
uint32 ChannelInterruptFlags
Definition: SpellInfo.h:352
uint32 InterruptFlags
Definition: SpellInfo.h:350

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)
1094{
1096 return;
1097
1098 if (m_caster->IsInFlight())
1099 return;
1100
1101 if (!unitTarget)
1102 return;
1103
1104 float speedXY, speedZ;
1105 CalculateJumpSpeeds(effIndex, m_caster->GetExactDist2d(unitTarget), speedXY, speedZ);
1106 m_caster->GetMotionMaster()->MoveJump(*unitTarget, speedXY, speedZ);
1107
1109 {
1110 sScriptMgr->AnticheatSetUnderACKmount(m_caster->ToPlayer());
1111 }
1112}
float GetExactDist2d(const float x, const float y) const
Definition: Position.h:166
void MoveJump(Position const &pos, float speedXY, float speedZ, uint32 id=0)
Definition: MotionMaster.h:225
void CalculateJumpSpeeds(uint8 i, float dist, float &speedxy, float &speedz)
Definition: SpellEffects.cpp:1177

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

◆ EffectJumpDest()

void Spell::EffectJumpDest ( SpellEffIndex  effIndex)
1115{
1117 return;
1118
1119 if (m_caster->IsInFlight())
1120 return;
1121
1122 if (!m_targets.HasDst() || m_caster->GetVehicle())
1123 return;
1124
1125 // Init dest coordinates
1126 float x, y, z;
1127 destTarget->GetPosition(x, y, z);
1128 // xinef: this can happen if MovePositionToFirstCollision detects that X, Y cords are invalid and returns prematurely
1129 if (!Acore::IsValidMapCoord(x, y, z) || z <= INVALID_HEIGHT)
1130 return;
1131
1132 float speedXY, speedZ;
1133 float dist = m_caster->GetExactDist2d(x, y);
1134 CalculateJumpSpeeds(effIndex, dist, speedXY, speedZ);
1135
1136 // Override, calculations are incorrect
1137 if (m_spellInfo->Id == 49376) // feral charge
1138 {
1139 speedXY = pow(speedZ * 10, 8);
1141
1142 if (Player* player = m_caster->ToPlayer())
1143 {
1144 player->SetCanTeleport(true);
1145 }
1146
1148 {
1149 sScriptMgr->AnticheatSetUnderACKmount(m_caster->ToPlayer());
1150 }
1151
1152 return;
1153 }
1154
1155 if (m_spellInfo->Id == 57604) // death grip
1156 {
1157 speedZ = 3.0f;
1158 speedXY = 50.0f;
1159 }
1160
1161 // crash fix?
1162 if (speedXY < 1.0f)
1163 speedXY = 1.0f;
1164
1165 if (Player* player = m_caster->ToPlayer())
1166 {
1167 player->SetCanTeleport(true);
1168 }
1169 m_caster->GetMotionMaster()->MoveJump(x, y, z, speedXY, speedZ);
1170
1172 {
1173 sScriptMgr->AnticheatSetUnderACKmount(m_caster->ToPlayer());
1174 }
1175}
@ UNIT_FIELD_TARGET
Definition: UpdateFields.h:92
#define INVALID_HEIGHT
Definition: Map.h:164
bool IsValidMapCoord(float c)
Definition: GridDefines.h:216
ObjectGuid GetGuidValue(uint16 index) const
Definition: Object.cpp:337

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

◆ EffectKillCredit()

void Spell::EffectKillCredit ( SpellEffIndex  effIndex)
5749{
5751 return;
5752
5753 if (!unitTarget)
5754 return;
5755
5757 if (!player)
5758 {
5759 return;
5760 }
5761
5762 int32 creatureEntry = m_spellInfo->Effects[effIndex].MiscValue;
5763 if (!creatureEntry)
5764 {
5765 if (m_spellInfo->Id == 42793) // Burn Body
5766 creatureEntry = 24008; // Fallen Combatant
5767 }
5768
5769 if (creatureEntry)
5770 player->RewardPlayerAndGroupAtEvent(creatureEntry, unitTarget);
5771}
void RewardPlayerAndGroupAtEvent(uint32 creature_id, WorldObject *pRewardSource)
Definition: Player.cpp:12627

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)
5732{
5734 return;
5735
5736 if (!unitTarget)
5737 return;
5738
5740 if (!player)
5741 {
5742 return;
5743 }
5744
5745 player->KilledMonsterCredit(m_spellInfo->Effects[effIndex].MiscValue);
5746}
void KilledMonsterCredit(uint32 entry, ObjectGuid guid=ObjectGuid::Empty)
Definition: PlayerQuest.cpp:1911

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

◆ EffectKnockBack()

void Spell::EffectKnockBack ( SpellEffIndex  effIndex)
5016{
5018 return;
5019
5020 if (!unitTarget)
5021 return;
5022
5023 // Xinef: allow entry specific spells to skip those checks
5024 if (m_spellInfo->Effects[effIndex].TargetA.GetCheckType() != TARGET_CHECK_ENTRY && m_spellInfo->Effects[effIndex].TargetB.GetCheckType() != TARGET_CHECK_ENTRY)
5025 {
5027 return;
5028
5029 if (unitTarget->GetVehicle())
5030 return;
5031
5032 if (Creature* creatureTarget = unitTarget->ToCreature())
5033 if (creatureTarget->isWorldBoss() || creatureTarget->IsDungeonBoss() || creatureTarget->IsImmuneToKnockback() || unitTarget->ToCreature()->GetCreatureType() == CREATURE_TYPE_GIANT)
5034 return;
5035 }
5036
5037 // Spells with SPELL_EFFECT_KNOCK_BACK(like Thunderstorm) can't knoback target if target has ROOT
5039 return;
5040
5041 // Instantly interrupt non melee spells being casted
5044
5045 float ratio = 0.1f;
5046 float speedxy = float(m_spellInfo->Effects[effIndex].MiscValue) * ratio;
5047 float speedz = float(damage) * ratio;
5048 if (speedxy <= 0.1f && speedz <= 0.1f)
5049 return;
5050
5051 float x, y;
5052 if (m_spellInfo->Effects[effIndex].Effect == SPELL_EFFECT_KNOCK_BACK_DEST)
5053 {
5054 if (m_targets.HasDst())
5055 destTarget->GetPosition(x, y);
5056 else
5057 return;
5058 }
5059 else //if (m_spellInfo->Effects[i].Effect == SPELL_EFFECT_KNOCK_BACK)
5060 {
5061 m_caster->GetPosition(x, y);
5062 }
5063
5064 unitTarget->KnockbackFrom(x, y, speedxy, speedz);
5065
5067 {
5068 sScriptMgr->AnticheatSetUnderACKmount(unitTarget->ToPlayer());
5069 }
5070}
@ SPELL_EFFECT_KNOCK_BACK_DEST
Definition: SharedDefines.h:894
@ CREATURE_TYPE_GIANT
Definition: SharedDefines.h:2604
@ CREATURE_TYPE_BEAST
Definition: SharedDefines.h:2600
void InterruptNonMeleeSpells(bool withDelayed, uint32 spellid=0, bool withInstant=true, bool bySelf=false)
Definition: Unit.cpp:4069
uint32 GetCreatureType() const
Definition: Unit.cpp:15074
void KnockbackFrom(float x, float y, float speedXY, float speedZ)
Definition: Unit.cpp:19311

References CREATURE_TYPE_BEAST, CREATURE_TYPE_GIANT, damage, destTarget, effectHandleMode, SpellInfo::Effects, Unit::GetCreatureType(), Position::GetPosition(), Object::GetTypeId(), Unit::GetVehicle(), SpellCastTargets::HasDst(), Unit::HasUnitState(), Unit::InterruptNonMeleeSpells(), Unit::IsNonMeleeSpellCast(), 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(), TYPEID_PLAYER, UNIT_STATE_ROOT, and unitTarget.

◆ EffectLeap()

void Spell::EffectLeap ( SpellEffIndex  effIndex)
4724{
4726 return;
4727
4728 if (!unitTarget || unitTarget->IsInFlight())
4729 return;
4730
4731 if (!m_targets.HasDst())
4732 return;
4733
4734 Position dstpos = destTarget->GetPosition();
4736}
void NearTeleportTo(Position &pos, bool casting=false, bool vehicleTeleport=false, bool withPet=false, bool removeTransport=false)
Definition: Unit.cpp:20148

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)
5073{
5075 return;
5076
5077 if (!unitTarget)
5078 return;
5079
5080 float speedxy = m_spellInfo->Effects[effIndex].MiscValue / 10.0f;
5081 float speedz = damage / 10.0f;
5082 //1891: Disengage
5084
5086 {
5087 sScriptMgr->AnticheatSetUnderACKmount(m_caster->ToPlayer());
5088 }
5089
5090 // xinef: changes fall time
5093}
@ SPELLFAMILY_HUNTER
Definition: SharedDefines.h:3509
void JumpTo(float speedXY, float speedZ, bool forward=true)
Definition: Unit.cpp:19683

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

◆ EffectLearnPetSpell()

void Spell::EffectLearnPetSpell ( SpellEffIndex  effIndex)
3263{
3265 return;
3266
3267 if (!unitTarget)
3268 return;
3269
3270 if (unitTarget->ToPlayer())
3271 {
3272 EffectLearnSpell(effIndex);
3273 return;
3274 }
3275 Pet* pet = unitTarget->ToPet();
3276 if (!pet)
3277 return;
3278
3279 SpellInfo const* learn_spellproto = sSpellMgr->GetSpellInfo(m_spellInfo->Effects[effIndex].TriggerSpell);
3280 if (!learn_spellproto)
3281 return;
3282
3283 pet->learnSpell(learn_spellproto->Id);
3285 pet->GetOwner()->PetSpellInitialize();
3286}
bool learnSpell(uint32 spell_id)
Definition: Pet.cpp:1874
void EffectLearnSpell(SpellEffIndex effIndex)
Definition: SpellEffects.cpp:2546

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

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

◆ EffectLearnSpell()

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

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

Referenced by EffectLearnPetSpell().

◆ EffectMilling()

void Spell::EffectMilling ( SpellEffIndex  effIndex)
5559{
5561 return;
5562
5564 return;
5565
5566 Player* p_caster = m_caster->ToPlayer();
5568 return;
5569
5570 if (itemTarget->GetCount() < 5)
5571 return;
5572
5573 if (sWorld->getBoolConfig(CONFIG_SKILL_MILLING))
5574 {
5575 uint32 SkillValue = p_caster->GetPureSkillValue(SKILL_INSCRIPTION);
5576 uint32 reqSkillValue = itemTarget->GetTemplate()->RequiredSkillRank;
5577 p_caster->UpdateGatherSkill(SKILL_INSCRIPTION, SkillValue, reqSkillValue);
5578 }
5579
5581}
@ LOOT_MILLING
Definition: LootMgr.h:88
@ CONFIG_SKILL_MILLING
Definition: IWorld.h:96
void SendLoot(ObjectGuid guid, LootType loot_type)
Definition: Player.cpp:7657
bool UpdateGatherSkill(uint32 SkillId, uint32 SkillValue, uint32 RedLevel, uint32 Multiplicator=1)
Definition: PlayerUpdates.cpp:722

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

◆ EffectModifyThreatPercent()

void Spell::EffectModifyThreatPercent ( SpellEffIndex  effIndex)
5389{
5391 return;
5392
5393 if (!unitTarget)
5394 return;
5395
5397}
void ModifyThreatByPercent(Unit *victim, int32 percent)
Definition: ThreatMgr.cpp:509
ThreatMgr & GetThreatMgr()
Definition: Unit.h:2145

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

◆ EffectNULL()

void Spell::EffectNULL ( SpellEffIndex  effIndex)
242{
243 LOG_DEBUG("spells.aura", "WORLD: Spell Effect DUMMY");
244}

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
2091{
2093 return;
2094
2096 {
2097 LOG_DEBUG("spells.aura", "WORLD: Open Lock - No Player Caster!");
2098 return;
2099 }
2100
2101 Player* player = m_caster->ToPlayer();
2102
2103 uint32 lockId = 0;
2104 ObjectGuid guid;
2105
2106 // Get lockId
2107 if (gameObjTarget)
2108 {
2109 GameObjectTemplate const* goInfo = gameObjTarget->GetGOInfo();
2110 // Arathi Basin banner opening. /// @todo: Verify correctness of this check
2111 if ((goInfo->type == GAMEOBJECT_TYPE_BUTTON && goInfo->button.noDamageImmune) ||
2112 (goInfo->type == GAMEOBJECT_TYPE_GOOBER && goInfo->goober.losOK))
2113 {
2114 //CanUseBattlegroundObject() already called in CheckCast()
2115 // in battleground check
2116 if (Battleground* bg = player->GetBattleground())
2117 {
2118 bg->EventPlayerClickedOnFlag(player, gameObjTarget);
2119 return;
2120 }
2121 }
2122 else if (goInfo->type == GAMEOBJECT_TYPE_FLAGSTAND)
2123 {
2124 //CanUseBattlegroundObject() already called in CheckCast()
2125 // in battleground check
2126 if (Battleground* bg = player->GetBattleground())
2127 {
2128 if (bg->GetBgTypeID(true) == BATTLEGROUND_EY)
2129 bg->EventPlayerClickedOnFlag(player, gameObjTarget);
2130 return;
2131 }
2132 }
2133 else if (m_spellInfo->Id == 1842 && gameObjTarget->GetGOInfo()->type == GAMEOBJECT_TYPE_TRAP)
2134 {
2137 {
2139 }
2140 return;
2141 }
2143 // handle outdoor pvp object opening, return true if go was registered for handling
2144 // these objects must have been spawned by outdoorpvp!
2145 else if (gameObjTarget->GetGOInfo()->type == GAMEOBJECT_TYPE_GOOBER && sOutdoorPvPMgr->HandleOpenGo(player, gameObjTarget))
2146 return;
2147 lockId = goInfo->GetLockId();
2148 guid = gameObjTarget->GetGUID();
2149 }
2150 else if (itemTarget)
2151 {
2152 lockId = itemTarget->GetTemplate()->LockID;
2153 guid = itemTarget->GetGUID();
2154 }
2155 else
2156 {
2157 LOG_DEBUG("spells.aura", "WORLD: Open Lock - No GameObject/Item Target!");
2158 return;
2159 }
2160
2161 SkillType skillId = SKILL_NONE;
2162 int32 reqSkillValue = 0;
2163 int32 skillValue;
2164
2165 SpellCastResult res = CanOpenLock(effIndex, lockId, skillId, reqSkillValue, skillValue);
2166 if (res != SPELL_CAST_OK)
2167 {
2168 SendCastResult(res);
2169 return;
2170 }
2171
2172 if (gameObjTarget)
2173 SendLoot(guid, LOOT_SKINNING);
2174 else if (itemTarget)
2175 {
2177 if (Player* itemOwner = itemTarget->GetOwner())
2178 itemTarget->SetState(ITEM_CHANGED, itemOwner);
2179 }
2180
2181 // not allow use skill grow at item base open
2182 if (!m_CastItem && skillId != SKILL_NONE)
2183 {
2184 // update skill if really known
2185 if (uint32 pureSkillValue = player->GetPureSkillValue(skillId))
2186 {
2187 if (gameObjTarget)
2188 {
2189 // Allow one skill-up until respawned
2190 if (!gameObjTarget->IsInSkillupList(player->GetGUID()))
2191 {
2193 player->UpdateGatherSkill(skillId, pureSkillValue, reqSkillValue);
2194 }
2195
2196 }
2197 else if (itemTarget)
2198 {
2199 // Do one skill-up
2200 player->UpdateGatherSkill(skillId, pureSkillValue, reqSkillValue);
2201 }
2202 }
2203 }
2205}
@ GO_JUST_DEACTIVATED
Definition: GameObject.h:115
@ ITEM_CHANGED
Definition: Item.h:204
@ ITEM_FIELD_FLAG_UNLOCKED
Definition: ItemTemplate.h:112
@ ITEM_FIELD_FLAGS
Definition: UpdateFields.h:42
@ LOOT_SKINNING
Definition: LootMgr.h:86
#define sOutdoorPvPMgr
Definition: OutdoorPvPMgr.h:106
@ GAMEOBJECT_TYPE_BUTTON
Definition: SharedDefines.h:1533
@ GAMEOBJECT_TYPE_FLAGSTAND
Definition: SharedDefines.h:1556
@ GAMEOBJECT_TYPE_GOOBER
Definition: SharedDefines.h:1542
@ BATTLEGROUND_EY
Definition: SharedDefines.h:3459
Unit * GetOwner() const
Definition: GameObject.cpp:1236
void AddToSkillupList(ObjectGuid playerGuid)
Definition: GameObject.cpp:3113
bool IsInSkillupList(ObjectGuid playerGuid) const
Definition: GameObject.cpp:3119
LootState getLootState() const
Definition: GameObject.h:226
void SetLootState(LootState s, Unit *unit=nullptr)
Definition: GameObject.cpp:2432
Definition: GameObjectData.h:32
uint32 GetAutoCloseTime() const
Definition: GameObjectData.h:511
struct GameObjectTemplate::@215::@226 goober
uint32 noDamageImmune
Definition: GameObjectData.h:49
uint32 losOK
Definition: GameObjectData.h:65
struct GameObjectTemplate::@215::@218 button
uint32 GetLockId() const
Definition: GameObjectData.h:428
void SetState(ItemUpdateState state, Player *forplayer=nullptr)
Definition: Item.cpp:716
Definition: Object.h:97
void ExecuteLogEffectOpenLock(uint8 effIndex, Object *obj)
Definition: Spell.cpp:5100
void SendLoot(ObjectGuid guid, LootType loottype)
Definition: SpellEffects.cpp:2024

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(), Object::GetTypeId(), GO_JUST_DEACTIVATED, GameObjectTemplate::goober, SpellInfo::Id, IN_MILLISECONDS, GameObject::IsInSkillupList(), 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, TYPEID_PLAYER, and Player::UpdateGatherSkill().

◆ EffectParry()

void Spell::EffectParry ( SpellEffIndex  effIndex)
4706{
4708 return;
4709
4711 m_caster->ToPlayer()->SetCanParry(true);
4712}
void SetCanParry(bool value)
Definition: Player.cpp:13018

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

◆ EffectPersistentAA()

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

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

◆ EffectPickPocket()

void Spell::EffectPickPocket ( SpellEffIndex  effIndex)

◆ EffectPlayMusic()

void Spell::EffectPlayMusic ( SpellEffIndex  effIndex)
6165{
6167 return;
6168
6169 if (!unitTarget)
6170 return;
6171
6172 Player* player = unitTarget->ToPlayer();
6173 if (!player)
6174 {
6175 return;
6176 }
6177
6178 uint32 soundid = m_spellInfo->Effects[effIndex].MiscValue;
6179
6180 if (!sSoundEntriesStore.LookupEntry(soundid))
6181 {
6182 LOG_ERROR("spells.effect", "EffectPlayMusic: Sound (Id: {}) not exist in spell {}.", soundid, m_spellInfo->Id);
6183 return;
6184 }
6185
6187}
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)
6224{
6226 return;
6227
6228 if (!unitTarget)
6229 return;
6230
6231 Player* player = unitTarget->ToPlayer();
6232 if (!player)
6233 {
6234 return;
6235 }
6236
6237 switch (m_spellInfo->Id)
6238 {
6239 case 58730: // Restricted Flight Area
6240 case 58600: // Restricted Flight Area
6242 break;
6243 default:
6244 break;
6245 }
6246
6247 uint32 soundId = m_spellInfo->Effects[effIndex].MiscValue;
6248
6249 if (!sSoundEntriesStore.LookupEntry(soundId))
6250 {
6251 LOG_ERROR("spells.effect", "EffectPlayerSound: Sound (Id: {}) not exist in spell {}.", soundId, m_spellInfo->Id);
6252 return;
6253 }
6254
6255 player->PlayDirectSound(soundId, player);
6256}
@ LANG_ZONE_NOFLYZONE
Definition: Language.h:727
void PlayDirectSound(uint32 sound_id, Player *target=nullptr)
Definition: Object.cpp:2853
void SendNotification(const char *format,...) ATTR_PRINTF(2
Definition: WorldSession.cpp:787

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

◆ EffectPowerBurn()

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

References CalculatePct(), damage, effectHandleMode, SpellInfo::Effects, ExecuteLogEffectTakeTargetPower(), Unit::GetMaxPower(), Unit::getPowerType(), Unit::GetSpellCritDamageReduction(), 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)
1360{
1362 return;
1363
1364 if (m_spellInfo->Effects[effIndex].MiscValue < 0 || m_spellInfo->Effects[effIndex].MiscValue >= int8(MAX_POWERS))
1365 return;
1366
1367 Powers PowerType = Powers(m_spellInfo->Effects[effIndex].MiscValue);
1368
1370 return;
1371
1372 // add spell damage bonus
1375
1376 // resilience reduce mana draining effect at spell crit damage reduction (added in 2.4)
1377 int32 power = damage;
1378 if (PowerType == POWER_MANA)
1379 power -= unitTarget->GetSpellCritDamageReduction(power);
1380
1381 int32 newDamage = -(unitTarget->ModifyPower(PowerType, -int32(power)));
1382
1383 float gainMultiplier = 0.0f;
1384
1385 // Don`t restore from self drain
1386 if (m_caster != unitTarget)
1387 {
1388 gainMultiplier = m_spellInfo->Effects[effIndex].CalcValueMultiplier(m_originalCaster, this);
1389
1390 int32 gain = int32(newDamage * gainMultiplier);
1391
1393 }
1394 ExecuteLogEffectTakeTargetPower(effIndex, unitTarget, PowerType, newDamage, gainMultiplier);
1395}

References damage, effectHandleMode, SpellInfo::Effects, Unit::EnergizeBySpell(), ExecuteLogEffectTakeTargetPower(), Unit::getPowerType(), Unit::GetSpellCritDamageReduction(), 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)
2317{
2319 return;
2320
2322 return;
2323 Player* p_target = m_caster->ToPlayer();
2324
2326 if (m_spellInfo->EquippedItemClass == ITEM_CLASS_WEAPON && !(p_target->GetWeaponProficiency() & subClassMask))
2327 {
2328 p_target->AddWeaponProficiency(subClassMask);
2330 }
2331 if (m_spellInfo->EquippedItemClass == ITEM_CLASS_ARMOR && !(p_target->GetArmorProficiency() & subClassMask))
2332 {
2333 p_target->AddArmorProficiency(subClassMask);
2335 }
2336}
uint32 GetArmorProficiency() const
Definition: Player.h:1329
void SendProficiency(ItemClass itemClass, uint32 itemSubclassMask)
Definition: Player.cpp:9999
uint32 GetWeaponProficiency() const
Definition: Player.h:1328
void AddArmorProficiency(uint32 newflag)
Definition: Player.h:1327
void AddWeaponProficiency(uint32 newflag)
Definition: Player.h:1326
int32 EquippedItemSubClassMask
Definition: SpellInfo.h:374

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

◆ EffectProspecting()

void Spell::EffectProspecting ( SpellEffIndex  effIndex)

◆ EffectPull()

void Spell::EffectPull ( SpellEffIndex  effIndex)
Todo:
: create a proper pull towards distract spell center for distract
2689{
2691 EffectNULL(effIndex);
2692}
void EffectNULL(SpellEffIndex effIndex)
Definition: SpellEffects.cpp:241

References EffectNULL().

◆ EffectPullTowards()

void Spell::EffectPullTowards ( SpellEffIndex  effIndex)
5161{
5163 return;
5164
5165 if (!unitTarget)
5166 return;
5167
5168 Position pos;
5169 if (m_spellInfo->Effects[effIndex].Effect == SPELL_EFFECT_PULL_TOWARDS_DEST)
5170 {
5171 if (m_targets.HasDst())
5172 pos.Relocate(*destTarget);
5173 else
5174 return;
5175 }
5176 else //if (m_spellInfo->Effects[i].Effect == SPELL_EFFECT_PULL_TOWARDS)
5177 {
5178 // Xinef: Increase Z position a little bit, should protect from falling through textures
5180 }
5181
5182 float speedXY = float(m_spellInfo->Effects[effIndex].MiscValue) ? float(m_spellInfo->Effects[effIndex].MiscValue) * 0.1f : 30.f;
5183 float speedZ = unitTarget->GetDistance(pos) / speedXY * 0.5f * Movement::gravity;
5184
5185 unitTarget->GetMotionMaster()->MoveJump(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), speedXY, speedZ);
5186
5188 {
5189 sScriptMgr->AnticheatSetSkipOnePacketForASH(unitTarget->ToPlayer(), true);
5190 sScriptMgr->AnticheatSetUnderACKmount(unitTarget->ToPlayer());
5191 }
5192}
@ SPELL_EFFECT_PULL_TOWARDS_DEST
Definition: SharedDefines.h:895
double gravity
Definition: MovementUtil.cpp:24
void Relocate(float x, float y)
Definition: Position.h:73

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

◆ EffectQuestClear()

void Spell::EffectQuestClear ( SpellEffIndex  effIndex)
5096{
5098 return;
5099
5100 if (!unitTarget)
5101 return;
5102
5103 Player* player = unitTarget->ToPlayer();
5104 if (!player)
5105 {
5106 return;
5107 }
5108
5109 uint32 quest_id = m_spellInfo->Effects[effIndex].MiscValue;
5110
5111 Quest const* quest = sObjectMgr->GetQuestTemplate(quest_id);
5112
5113 if (!quest)
5114 return;
5115
5116 // Player has never done this quest
5117 if (player->GetQuestStatus(quest_id) == QUEST_STATUS_NONE)
5118 return;
5119
5120 // remove all quest entries for 'entry' from quest log
5121 for (uint8 slot = 0; slot < MAX_QUEST_LOG_SIZE; ++slot)
5122 {
5123 uint32 logQuest = player->GetQuestSlotQuestId(slot);
5124 if (logQuest == quest_id)
5125 {
5126 player->SetQuestSlot(slot, 0);
5127
5128 // we ignore unequippable quest items in this case, it's still be equipped
5129 player->TakeQuestSourceItem(logQuest, false);
5130
5131 if (quest->HasFlag(QUEST_FLAGS_FLAGS_PVP))
5132 {
5133 player->pvpInfo.IsHostile = player->pvpInfo.IsInHostileArea || player->HasPvPForcingQuest();
5134 player->UpdatePvPState();
5135 }
5136 }
5137 }
5138
5139 player->RemoveRewardedQuest(quest_id);
5140 player->RemoveActiveQuest(quest_id, false);
5141}
@ QUEST_FLAGS_FLAGS_PVP
Definition: QuestDef.h:145
#define MAX_QUEST_LOG_SIZE
Definition: QuestDef.h:33
@ QUEST_STATUS_NONE
Definition: QuestDef.h:100
bool IsHostile
Definition: Player.h:361
bool IsInHostileArea
Definition: Player.h:362
bool HasPvPForcingQuest() const
Definition: PlayerQuest.cpp:2479
void UpdatePvPState()
Definition: PlayerUpdates.cpp:1391
uint32 GetQuestSlotQuestId(uint16 slot) const
Definition: Player.h:1449
void SetQuestSlot(uint16 slot, uint32 quest_id, uint32 timer=0)
Definition: Player.h:1453
PvPInfo pvpInfo
Definition: Player.h:1797
bool TakeQuestSourceItem(uint32 questId, bool msg)
Definition: PlayerQuest.cpp:1360
void RemoveActiveQuest(uint32 questId, bool update=true)
Definition: PlayerQuest.cpp:1479
QuestStatus GetQuestStatus(uint32 quest_id) const
Definition: PlayerQuest.cpp:1414
void RemoveRewardedQuest(uint32 questId, bool update=true)
Definition: PlayerQuest.cpp:1497
Definition: QuestDef.h:207
bool HasFlag(uint32 flag) const
Definition: QuestDef.h:218

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)
4765{
4767 return;
4768
4769 if (!unitTarget)
4770 return;
4771
4772 Player* player = unitTarget->ToPlayer();
4773 if (!player)
4774 {
4775 return;
4776 }
4777
4778 uint32 questId = m_spellInfo->Effects[effIndex].MiscValue;
4779 if (questId)
4780 {
4781 Quest const* quest = sObjectMgr->GetQuestTemplate(questId);
4782 if (!quest)
4783 return;
4784
4785 uint16 logSlot = player->FindQuestSlot(questId);
4786 if (logSlot < MAX_QUEST_LOG_SIZE)
4787 player->AreaExploredOrEventHappens(questId);
4788 else if (player->CanTakeQuest(quest, false)) // never rewarded before
4789 player->CompleteQuest(questId); // quest not in log - for internal use
4790 }
4791}
uint16 FindQuestSlot(uint32 quest_id) const
Definition: PlayerQuest.cpp:1766
bool CanTakeQuest(Quest const *quest, bool msg)
Definition: PlayerQuest.cpp:250
void CompleteQuest(uint32 quest_id)
Definition: PlayerQuest.cpp:596
void AreaExploredOrEventHappens(uint32 questId)
Definition: PlayerQuest.cpp:1775

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

◆ EffectQuestFail()

void Spell::EffectQuestFail ( SpellEffIndex  effIndex)
5774{
5776 return;
5777
5778 if (!unitTarget)
5779 return;
5780
5781 Player* player = unitTarget->ToPlayer();
5782 if (!player)
5783 {
5784 return;
5785 }
5786
5787 player->FailQuest(m_spellInfo->Effects[effIndex].MiscValue);
5788}
void FailQuest(uint32 quest_id)
Definition: PlayerQuest.cpp:883

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

◆ EffectQuestStart()

void Spell::EffectQuestStart ( SpellEffIndex  effIndex)
5791{
5793 return;
5794
5795 if (!unitTarget)
5796 return;
5797
5798 Player* player = unitTarget->ToPlayer();
5799 if (!player)
5800 return;
5801
5802 if (Quest const* quest = sObjectMgr->GetQuestTemplate(m_spellInfo->Effects[effIndex].MiscValue))
5803 {
5804 if (!player->CanTakeQuest(quest, false))
5805 return;
5806
5807 if (quest->IsAutoAccept() && player->CanAddQuest(quest, false))
5808 player->AddQuestAndCheckCompletion(quest, player);
5809
5810 player->PlayerTalkClass->SendQuestGiverQuestDetails(quest, player->GetGUID(), true);
5811 }
5812}
void SendQuestGiverQuestDetails(Quest const *quest, ObjectGuid npcGUID, bool activateAccept) const
Definition: GossipDef.cpp:385
bool CanAddQuest(Quest const *quest, bool msg)
Definition: PlayerQuest.cpp:263
void AddQuestAndCheckCompletion(Quest const *quest, Object *questGiver)
Definition: PlayerQuest.cpp:419
PlayerMenu * PlayerTalkClass
Definition: Player.h:2188

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)
6313{
6315 return;
6316
6318 return;
6319
6320 Player* player = m_caster->ToPlayer();
6321
6322 if (!player)
6323 return;
6324
6325 uint32 item_id = m_spellInfo->Effects[EFFECT_0].ItemType;
6326
6327 ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(item_id);
6328 if (!pProto)
6329 {
6330 player->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, nullptr, nullptr);
6331 return;
6332 }
6333
6334 if (Item* pItem = player->GetItemByEntry(item_id))
6335 {
6336 for (int x = 0; x < MAX_ITEM_PROTO_SPELLS; ++x)
6337 pItem->SetSpellCharges(x, pProto->Spells[x].SpellCharges);
6338 pItem->SetState(ITEM_CHANGED, player);
6339 }
6340}

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

◆ EffectRedirectThreat()

void Spell::EffectRedirectThreat ( SpellEffIndex  effIndex)
5951{
5953 return;
5954
5955 if (unitTarget)
5957}
void SetRedirectThreat(ObjectGuid guid, uint32 pct)
Definition: Unit.h:2344

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

◆ EffectRemoveAura()

void Spell::EffectRemoveAura ( SpellEffIndex  effIndex)
6259{
6261 return;
6262
6263 if (!unitTarget)
6264 return;
6265 // there may be need of specifying casterguid of removed auras
6266 unitTarget->RemoveAurasDueToSpell(m_spellInfo->Effects[effIndex].TriggerSpell);
6267}

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

◆ EffectRenamePet()

void Spell::EffectRenamePet ( SpellEffIndex  effIndex)
6153{
6155 return;
6156
6159 return;
6160
6162}
@ UNIT_FIELD_BYTES_2
Definition: UpdateFields.h:161
@ UNIT_CAN_BE_RENAMED
Definition: Unit.h:149
void SetByteFlag(uint16 index, uint8 offset, uint8 newFlag)
Definition: Object.cpp:911
PetType getPetType() const
Definition: Pet.h:51

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

◆ EffectReputation()

void Spell::EffectReputation ( SpellEffIndex  effIndex)
4739{
4741 return;
4742
4743 if (!unitTarget)
4744 return;
4745
4746 Player* player = unitTarget->ToPlayer();
4747 if (!player)
4748 {
4749 return;
4750 }
4751
4752 float repChange = static_cast<float>(damage);
4753
4754 uint32 factionId = m_spellInfo->Effects[effIndex].MiscValue;
4755
4756 FactionEntry const* factionEntry = sFactionStore.LookupEntry(factionId);
4757 if (!factionEntry)
4758 return;
4759
4760 repChange = player->CalculateReputationGain(REPUTATION_SOURCE_SPELL, 0, repChange, factionId);
4761 player->GetReputationMgr().ModifyReputation(factionEntry, repChange);
4762}
DBCStorage< FactionEntry > sFactionStore(FactionEntryfmt)
@ REPUTATION_SOURCE_SPELL
Definition: Player.h:246
float CalculateReputationGain(ReputationSource source, uint32 creatureOrQuestLevel, float rep, int32 faction, bool noQuestBonus=false)
Definition: Player.cpp:5770
ReputationMgr & GetReputationMgr()
Definition: Player.h:2076
bool ModifyReputation(FactionEntry const *factionEntry, float standing, bool noSpillOver=false, Optional< ReputationRank > repMaxCap={})
Definition: ReputationMgr.h:118
Definition: DBCStructure.h:898

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)
4657{
4659 return;
4660
4661 if (!unitTarget)
4662 return;
4663
4664 if (!unitTarget)
4665 return;
4666
4667 Player* target = unitTarget->ToPlayer();
4668 if (!target)
4669 {
4670 return;
4671 }
4672
4673 if (unitTarget->IsAlive() || !unitTarget->IsInWorld())
4674 return;
4675
4676 if (target->isResurrectRequested()) // already have one active request
4677 return;
4678
4679 uint32 health = target->CountPctFromMaxHealth(damage);
4681
4682 ExecuteLogEffectResurrect(effIndex, target);
4683
4685 SendResurrectRequest(target);
4686}
void setResurrectRequestData(ObjectGuid guid, uint32 mapId, float X, float Y, float Z, uint32 health, uint32 mana)
Definition: Player.h:1766
bool isResurrectRequested() const
Definition: Player.h:1778
void ExecuteLogEffectResurrect(uint8 effIndex, Unit *target)
Definition: Spell.cpp:5130
void SendResurrectRequest(Player *target)
Definition: Spell.cpp:5192

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
5238{
5240 return;
5241
5242 if (damage < 0)
5243 return;
5244
5245 Player* player = m_caster->ToPlayer();
5246 if (!player)
5247 {
5248 return;
5249 }
5250
5251 Pet* pet = player->GetPet();
5252 if (!pet)
5253 {
5254 // Position passed to SummonPet is irrelevant with current implementation,
5255 // pet will be relocated without using these coords in Pet::LoadPetFromDB
5256 player->SummonPet(0, 0.0f, 0.0f, 0.0f, 0.0f, SUMMON_PET, 0s, damage);
5257 return;
5258 }
5259
5261 if (pet->IsAlive())
5262 {
5263 return;
5264 }
5265
5266 // Reposition the pet's corpse before reviving so as not to grab aggro
5267 // We can use a different, more accurate version of GetClosePoint() since we have a pet
5268 float x, y, z; // Will be used later to reposition the pet if we have one
5269 player->GetClosePoint(x, y, z, pet->GetCombatReach(), PET_FOLLOW_DIST, pet->GetFollowAngle());
5270 pet->NearTeleportTo(x, y, z, player->GetOrientation());
5271 pet->Relocate(x, y, z, player->GetOrientation()); // This is needed so SaveStayPosition() will get the proper coords.
5274 pet->setDeathState(ALIVE);
5275 pet->ClearUnitState(uint32(UNIT_STATE_ALL_STATE & ~(UNIT_STATE_POSSESSED))); // xinef: just in case
5277 pet->SetDisplayId(pet->GetNativeDisplayId());
5278
5279 // xinef: restore movement
5280 if (auto ci = pet->GetCharmInfo())
5281 {
5282 ci->SetIsAtStay(false);
5283 ci->SetIsFollowing(false);
5284 }
5285
5287}
#define PET_FOLLOW_DIST
Definition: PetDefines.h:193
@ SUMMON_PET
Definition: PetDefines.h:31
@ ALIVE
Definition: Unit.h:316
@ UNIT_STATE_POSSESSED
Definition: Unit.h:341
@ UNIT_STATE_ALL_STATE
Definition: Unit.h:373
@ UNIT_DYNFLAG_NONE
Definition: SharedDefines.h:3092
float GetFollowAngle() const override
Definition: TemporarySummon.h:82
bool GetClosePoint(float &x, float &y, float &z, float size, float distance2d=0, float angle=0, WorldObject const *forWho=nullptr, bool force=false) const
Definition: Object.cpp:2662
void setDeathState(DeathState s, bool despawn=false) override
Definition: Pet.cpp:618
void SetDisplayId(uint32 modelId) override
Definition: Pet.cpp:2364
Pet * SummonPet(uint32 entry, float x, float y, float z, float ang, PetType petType, Milliseconds duration=0s, uint32 healthPct=0)
Definition: Player.cpp:8807
void ReplaceAllDynamicFlags(uint32 flag) override
Definition: Unit.h:1326
void SetHealth(uint32 val)
Definition: Unit.cpp:15370
uint32 GetNativeDisplayId() const
Definition: Unit.h:2170
void RemoveUnitFlag(UnitFlags flags)
Definition: Unit.h:1482

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)
4037{
4039 return;
4040
4041 if (!unitTarget)
4042 return;
4043
4045 {
4047 // Xinef: replaced with CombatStop(false)
4050
4051 // Night Elf: Shadowmeld only resets threat temporarily
4052 if (m_spellInfo->Id != 59646)
4054
4056 unitTarget->ToPlayer()->SendAttackSwingCancelAttack(); // melee and ranged forced attack cancel
4057 }
4058 else
4059 {
4060 unitTarget->getHostileRefMgr().UpdateVisibility(m_spellInfo->Id == 59646); // Night Elf: Shadowmeld
4061 unitTarget->CombatStop(true);
4062 }
4063
4064 UnitList targets;
4065 Acore::AnyUnfriendlyUnitInObjectRangeCheck u_check(unitTarget, unitTarget, unitTarget->GetVisibilityRange()); // no VISIBILITY_COMPENSATION, distance is enough
4068 for (UnitList::iterator iter = targets.begin(); iter != targets.end(); ++iter)
4069 {
4070 if (!(*iter)->HasUnitState(UNIT_STATE_CASTING))
4071 continue;
4072
4074 {
4075 if ((*iter)->GetCurrentSpell(i) && (*iter)->GetCurrentSpell(i)->m_targets.GetUnitTargetGUID() == unitTarget->GetGUID())
4076 {
4077 SpellInfo const* si = (*iter)->GetCurrentSpell(i)->GetSpellInfo();
4078 if (si->HasAttribute(SPELL_ATTR6_IGNORE_PHASE_SHIFT) && (*iter)->GetTypeId() == TYPEID_UNIT)
4079 {
4080 Creature* c = (*iter)->ToCreature();
4081 if ((!c->IsPet() && c->GetCreatureTemplate()->rank == CREATURE_ELITE_WORLDBOSS) || c->isWorldBoss() || c->IsDungeonBoss())
4082 continue;
4083 }
4084 bool interrupt = false; // pussywizard: skip spells that don't target units, but casted on unit (eg. TARGET_DEST_TARGET_ENEMY)
4085 for (uint8 j = 0; j < MAX_SPELL_EFFECTS; ++j)
4086 if (si->Effects[j].Effect && (si->Effects[j].GetUsedTargetObjectType() == TARGET_OBJECT_TYPE_UNIT || si->Effects[j].GetUsedTargetObjectType() == TARGET_OBJECT_TYPE_UNIT_AND_DEST))
4087 {
4088 // at least one effect truly targets an unit, interrupt the spell
4089 interrupt = true;
4090 break;
4091 }
4092 if (interrupt)
4093 (*iter)->InterruptSpell(CurrentSpellTypes(i), false);
4094 }
4095 }
4096 }
4097
4098 // Xinef: Set last sanctuary time
4100
4101 // Vanish allows to remove all threat and cast regular stealth so other spells can be used
4105 {
4107
4108 //Clean Escape
4109 if (m_caster->HasAura(23582))
4110 m_caster->CastSpell(m_caster, 23583, true);
4111 }
4112}
#define CURRENT_MAX_SPELL
Definition: Unit.h:985
@ SPELL_AURA_MOD_ROOT
Definition: SpellAuraDefines.h:89
@ SPELLFAMILYFLAG_ROGUE_VANISH
Definition: SpellMgr.h:54
void UpdateVisibility(bool checkThreat)
Definition: HostileRefMgr.cpp:236
void addThreatPercent(int32 percent)
Definition: HostileRefMgr.cpp:85
void SendAttackSwingCancelAttack()
Definition: PlayerMisc.cpp:140
void CombatStop(bool includingCast=false)
Definition: Unit.cpp:10401
void RemoveAllAttackers()
Definition: Unit.cpp:10444
bool AttackStop()
Definition: Unit.cpp:10368
virtual bool IsEncounterInProgress() const
Definition: InstanceScript.cpp:121

References HostileRefMgr::addThreatPercent(), Unit::AttackStop(), Unit::CastSpell(), 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(), Object::GetTypeId(), WorldObject::GetVisibilityRange(), SpellInfo::HasAttribute(), Unit::HasAura(), SpellInfo::Id, Unit::InterruptSpell(), Creature::IsDungeonBoss(), InstanceScript::IsEncounterInProgress(), Unit::IsPet(), Creature::isWorldBoss(), m_caster, Unit::m_lastSanctuaryTime, m_spellInfo, MAX_SPELL_EFFECTS, CreatureTemplate::rank, Unit::RemoveAllAttackers(), Unit::RemoveAurasByType(), Player::SendAttackSwingCancelAttack(), SPELL_ATTR6_IGNORE_PHASE_SHIFT, SPELL_AURA_MOD_ROOT, SPELL_EFFECT_HANDLE_HIT_TARGET, SPELLFAMILY_ROGUE, SPELLFAMILYFLAG_ROGUE_VANISH, SpellInfo::SpellFamilyFlags, SpellInfo::SpellFamilyName, TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT_AND_DEST, Object::ToCreature(), Object::ToPlayer(), TYPEID_PLAYER, TYPEID_UNIT, UNIT_STATE_CASTING, unitTarget, HostileRefMgr::UpdateVisibility(), and Cell::VisitAllObjects().

◆ EffectSchoolDMG()

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

References AddPct(), Unit::ApplyEffectModifiers(), ApplyPct(), AURA_STATE_CONFLAGRATE, BASE_ATTACK, Unit::CalcSpellDuration(), CalculatePct(), Unit::CalculateSpellDamage(), Unit::CastCustomSpell(), Unit::CastSpell(), damage, DOT, EFFECT_0, EFFECT_1, EFFECT_2, SpellValue::EffectBasePoints, effectHandleMode, SpellInfo::Effects, FORM_SHADOW, AuraEffect::GetAmount(), Unit::GetAttackTime(), Unit::GetAuraEffect(), Unit::GetAuraEffectsByType(), AuraEffect::GetBase(), SpellInfo::GetCategory(), Unit::GetComboPoints(), Unit::GetDummyAuraEffect(), Object::GetGUID(), AuraEffect::GetId(), Unit::GetLevel(), Unit::GetOwner(), Unit::GetShapeshiftForm(), Unit::GetShieldBlockValue(), AuraEffect::GetSpellInfo(), Aura::GetStackAmount(), Unit::GetTotalAttackPowerValue(), Object::GetTypeId(), SpellInfo::HasAttribute(), Unit::HasAura(), Unit::HasAuraState(), SpellInfo::Id, IN_MILLISECONDS, irand(), Unit::IsAlive(), Unit::IsPet(), 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(), TYPEID_PLAYER, TYPEID_UNIT, and unitTarget.

◆ EffectScriptEffect()

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

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(), Object::GetTypeId(), Unit::HasAura(), SpellInfo::Id, Unit::IsAlive(), Unit::IsSummon(), Unit::IsTotem(), LOG_DEBUG, m_caster, m_spellInfo, Unit::m_SummonSlot, MAX_TOTEM_SLOT, QUEST_STATUS_COMPLETE, Map::ScriptsStart(), Aura::SetDuration(), Aura::SetMaxDuration(), SPELL_EFFECT_HANDLE_HIT_TARGET, SPELLFAMILY_GENERIC, SPELLFAMILY_ROGUE, SpellInfo::SpellFamilyName, sSpellScripts, SUMMON_SLOT_TOTEM, Unit::TextEmote(), Object::ToCreature(), Object::ToPlayer(), Unit::ToTempSummon(), TYPEID_PLAYER, TYPEID_UNIT, unitTarget, TempSummon::UnSummon(), and urand().

◆ EffectSelfResurrect()

void Spell::EffectSelfResurrect ( SpellEffIndex  effIndex)
4867{
4869 return;
4870
4871 if (!m_caster || m_caster->IsAlive())
4872 return;
4874 return;
4875 if (!m_caster->IsInWorld())
4876 return;
4877
4878 uint32 health = 0;
4879 uint32 mana = 0;
4880
4881 // flat case
4882 if (damage < 0)
4883 {
4884 health = uint32(-damage);
4885 mana = m_spellInfo->Effects[effIndex].MiscValue;
4886 }
4887 // percent case
4888 else
4889 {
4893 }
4894
4895 Player* player = m_caster->ToPlayer();
4896 player->ResurrectPlayer(0.0f);
4897
4898 player->SetHealth(health);
4899 player->SetPower(POWER_MANA, mana);
4900 player->SetPower(POWER_RAGE, 0);
4901 player->SetPower(POWER_ENERGY, player->GetMaxPower(POWER_ENERGY));
4902
4903 player->SpawnCorpseBones();
4904}
@ POWER_RAGE
Definition: SharedDefines.h:242
void SpawnCorpseBones(bool triggerSave=true)
Definition: Player.cpp:4587
void ResurrectPlayer(float restore_percent, bool applySickness=false)
Definition: Player.cpp:4375
void SetPower(Powers power, uint32 val, bool withPowerUpdate=true, bool fromRegenerate=false)
Definition: Unit.cpp:15458

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

◆ EffectSendEvent()

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

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)
5144{
5146 return;
5147
5148 if (!unitTarget)
5149 return;
5150
5151 Player* player = unitTarget->ToPlayer();
5152 if (!player)
5153 {
5154 return;
5155 }
5156
5157 player->ActivateTaxiPathTo(m_spellInfo->Effects[effIndex].MiscValue, m_spellInfo->Id);
5158}
bool ActivateTaxiPathTo(std::vector< uint32 > const &nodes, Creature *npc=nullptr, uint32 spellid=1)
Definition: Player.cpp:10128

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

◆ EffectSkill()

void Spell::EffectSkill ( SpellEffIndex  effIndex)
5584{
5586 return;
5587
5588 LOG_DEBUG("spells.aura", "WORLD: SkillEFFECT");
5589}

References effectHandleMode, LOG_DEBUG, and SPELL_EFFECT_HANDLE_HIT.

◆ EffectSkinning()

void Spell::EffectSkinning ( SpellEffIndex  effIndex)
4907{
4909 return;
4910
4912 return;
4914 return;
4915
4916 Creature* creature = unitTarget->ToCreature();
4917 int32 targetLevel = creature->GetLevel();
4918
4919 uint32 skill = creature->GetCreatureTemplate()->GetRequiredLootSkill();
4920
4924
4925 int32 reqValue = targetLevel < 10 ? 0 : targetLevel < 20 ? (targetLevel - 10) * 10 : targetLevel * 5;
4926
4927 int32 skillValue = m_caster->ToPlayer()->GetPureSkillValue(skill);
4928
4929 // Double chances for elites
4930 m_caster->ToPlayer()->UpdateGatherSkill(skill, skillValue, reqValue, creature->isElite() ? 2 : 1);
4931}
@ UNIT_DYNFLAG_LOOTABLE
Definition: SharedDefines.h:3093
bool isElite() const
Definition: Creature.h:106
virtual void SetDynamicFlag(uint32 flag)
Definition: Object.h:117

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

◆ EffectSkinPlayerCorpse()

void Spell::EffectSkinPlayerCorpse ( SpellEffIndex  effIndex)
5615{
5617 return;
5618
5619 LOG_DEBUG("spells.aura", "Effect: SkinPlayerCorpse");
5621 return;
5622
5624}
void RemovedInsignia(Player *looterPlr)
Definition: Player.cpp:7618

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

◆ EffectSpecCount()

void Spell::EffectSpecCount ( SpellEffIndex  effIndex)
6190{
6192 return;
6193
6194 if (!unitTarget)
6195 return;
6196
6197 Player* player = unitTarget->ToPlayer();
6198 if (!player)
6199 {
6200 return;
6201 }
6202
6203 player->UpdateSpecCount(damage);
6204}
void UpdateSpecCount(uint8 count)
Definition: PlayerUpdates.cpp:2145

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

◆ EffectSpiritHeal()

void Spell::EffectSpiritHeal ( SpellEffIndex  effIndex)
5596{
5598 return;
5599
5600 /*
5601 if (unitTarget->GetTypeId() != TYPEID_PLAYER)
5602 return;
5603 if (!unitTarget->IsInWorld())
5604 return;
5605
5606 //m_spellInfo->Effects[i].BasePoints; == 99 (percent?)
5607 //unitTarget->ToPlayer()->setResurrect(m_caster->GetGUID(), unitTarget->GetPositionX(), unitTarget->GetPositionY(), unitTarget->GetPositionZ(), unitTarget->GetMaxHealth(), unitTarget->GetMaxPower(POWER_MANA));
5608 unitTarget->ToPlayer()->ResurrectPlayer(1.0f);
5609 unitTarget->ToPlayer()->SpawnCorpseBones();
5610 */
5611}

References effectHandleMode, and SPELL_EFFECT_HANDLE_HIT_TARGET.

◆ EffectStealBeneficialBuff()

void Spell::EffectStealBeneficialBuff ( SpellEffIndex  effIndex)
5627{
5629 return;
5630
5631 LOG_DEBUG("spells.aura", "Effect: StealBeneficialBuff");
5632
5633 if (!unitTarget || unitTarget == m_caster) // can't steal from self
5634 return;
5635
5636 DispelChargesList steal_list;
5637
5638 // Create dispel mask by dispel type
5639 uint32 dispelMask = SpellInfo::GetDispelMask(DispelType(m_spellInfo->Effects[effIndex].MiscValue));
5640 Unit::AuraMap const& auras = unitTarget->GetOwnedAuras();
5641 for (Unit::AuraMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
5642 {
5643 Aura* aura = itr->second;
5645 if (!aurApp)
5646 continue;
5647
5648 if ((aura->GetSpellInfo()->GetDispelMask()) & dispelMask)
5649 {
5650 // Need check for passive? this
5651 if (!aurApp->IsPositive() || aura->IsPassive() || aura->GetSpellInfo()->HasAttribute(SPELL_ATTR4_CANNOT_BE_STOLEN))
5652 continue;
5653
5654 // The charges / stack amounts don't count towards the total number of auras that can be dispelled.
5655 // Ie: A dispel on a target with 5 stacks of Winters Chill and a Polymorph has 1 / (1 + 1) -> 50% chance to dispell
5656 // Polymorph instead of 1 / (5 + 1) -> 16%.
5657 bool dispel_charges = aura->GetSpellInfo()->HasAttribute(SPELL_ATTR7_DISPEL_REMOVES_CHARGES);
5658 uint8 charges = dispel_charges ? aura->GetCharges() : aura->GetStackAmount();
5659 if (charges > 0)
5660 steal_list.push_back(std::make_pair(aura, charges));
5661 }
5662 }
5663
5664 if (steal_list.empty())
5665 return;
5666
5667 // Ok if exist some buffs for dispel try dispel it
5668 uint32 failCount = 0;
5669 DispelList success_list;
5670 WorldPacket dataFail(SMSG_DISPEL_FAILED, 8 + 8 + 4 + 4 + damage * 4);
5671 // dispel N = damage buffs (or while exist buffs for dispel)
5672 for (int32 count = 0; count < damage && !steal_list.empty();)
5673 {
5674 // Random select buff for dispel
5675 DispelChargesList::iterator itr = steal_list.begin();
5676 std::advance(itr, urand(0, steal_list.size() - 1));
5677
5678 int32 chance = itr->first->CalcDispelChance(unitTarget, !unitTarget->IsFriendlyTo(m_caster));
5679 // 2.4.3 Patch Notes: "Dispel effects will no longer attempt to remove effects that have 100% dispel resistance."
5680 if (!chance)
5681 {
5682 steal_list.erase(itr);
5683 continue;
5684 }
5685 else
5686 {
5687 if (roll_chance_i(chance))
5688 {
5689 success_list.push_back(std::make_pair(itr->first->GetId(), itr->first->GetCasterGUID()));
5690 --itr->second;
5691 if (itr->second <= 0)
5692 steal_list.erase(itr);
5693 }
5694 else
5695 {
5696 if (!failCount)
5697 {
5698 // Failed to dispell
5699 dataFail << m_caster->GetGUID(); // Caster GUID
5700 dataFail << unitTarget->GetGUID(); // Victim GUID
5701 dataFail << uint32(m_spellInfo->Id); // dispel spell id
5702 }
5703 ++failCount;
5704 dataFail << uint32(itr->first->GetId()); // Spell Id
5705 }
5706 ++count;
5707 }
5708 }
5709
5710 if (failCount)
5711 m_caster->SendMessageToSet(&dataFail, true);
5712
5713 if (success_list.empty())
5714 return;
5715
5716 WorldPacket dataSuccess(SMSG_SPELLSTEALLOG, 8 + 8 + 4 + 1 + 4 + damage * 5);
5717 dataSuccess << unitTarget->GetPackGUID(); // Victim GUID
5718 dataSuccess << m_caster->GetPackGUID(); // Caster GUID
5719 dataSuccess << uint32(m_spellInfo->Id); // dispel spell id
5720 dataSuccess << uint8(0); // not used
5721 dataSuccess << uint32(success_list.size()); // count
5722 for (DispelList::iterator itr = success_list.begin(); itr != success_list.end(); ++itr)
5723 {
5724 dataSuccess << uint32(itr->first); // Spell Id
5725 dataSuccess << uint8(0); // 0 - steals !=0 transfers
5726 unitTarget->RemoveAurasDueToSpellBySteal(itr->first, itr->second, m_caster);
5727 }
5728 m_caster->SendMessageToSet(&dataSuccess, true);
5729}
std::list< std::pair< uint32, ObjectGuid > > DispelList
Definition: SpellEffects.cpp:2570
@ SPELL_ATTR7_DISPEL_REMOVES_CHARGES
Definition: SharedDefines.h:623
@ SPELL_ATTR4_CANNOT_BE_STOLEN
Definition: SharedDefines.h:508
@ SMSG_SPELLSTEALLOG
Definition: Opcodes.h:849
void RemoveAurasDueToSpellBySteal(uint32 spellId, ObjectGuid casterGUID, Unit *stealer)
Definition: Unit.cpp:4932
bool IsPositive() const
Definition: SpellAuras.h:68
uint8 GetCharges() const
Definition: SpellAuras.h:141
bool IsPassive() const
Definition: SpellAuras.cpp:1096

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)
4206{
4208 return;
4209
4211 return;
4212
4213 Player* target = m_caster->ToPlayer();
4214 if (target->IsInFlight())
4215 return;
4216
4217 // xinef: if player is dead - teleport to graveyard
4218 if (!target->IsAlive())
4219 {
4221 return;
4222
4223 // xinef: player is in corpse
4224 if (!target->HasPlayerFlag(PLAYER_FLAGS_GHOST))
4225 target->BuildPlayerRepop();
4226 target->RepopAtGraveyard();
4227 return;
4228 }
4229
4230 // xinef: no hearthstone in bag or on cooldown
4231 Item* hearthStone = target->GetItemByEntry(6948);
4232 if (!hearthStone || target->HasSpellCooldown(8690))
4233 {
4234 float o = rand_norm() * 2 * M_PI;
4235 Position pos = *target;
4236 target->MovePositionToFirstCollision(pos, 5.0f, o);
4237 target->NearTeleportTo(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), target->GetOrientation());
4238 return;
4239 }
4240
4241 // xinef: we have hearthstone not on cooldown, just use it
4243}
double rand_norm()
Definition: Random.cpp:77
@ PLAYER_FLAGS_GHOST
Definition: Player.h:479
@ SPELL_AURA_PREVENT_RESURRECTION
Definition: SpellAuraDefines.h:377
void MovePositionToFirstCollision(Position &pos, float dist, float angle)
Definition: Object.cpp:2821
void RepopAtGraveyard()
Definition: Player.cpp:4821
void BuildPlayerRepop()
Definition: Player.cpp:4326

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

◆ EffectSummonChangeItem()

void Spell::EffectSummonChangeItem ( SpellEffIndex  effIndex)
2208{
2210 return;
2211
2213 return;
2214
2215 Player* player = m_caster->ToPlayer();
2216
2217 // applied only to using item
2218 if (!m_CastItem)
2219 return;
2220
2221 // ... only to item in own inventory/bank/equip_slot
2222 if (m_CastItem->GetOwnerGUID() != player->GetGUID())
2223 return;
2224
2225 uint32 newitemid = m_spellInfo->Effects[effIndex].ItemType;
2226 if (!newitemid)
2227 return;
2228
2229 uint16 pos = m_CastItem->GetPos();
2230
2231 Item* pNewItem = Item::CreateItem(newitemid, 1, player);
2232 if (!pNewItem)
2233 return;
2234
2235 // Client-side enchantment durations update
2237
2241
2243 {
2245 player->DurabilityLoss(pNewItem, lossPercent);
2246 }
2247
2248 if (player->IsInventoryPos(pos))
2249 {
2250 ItemPosCountVec dest;
2251 InventoryResult msg = player->CanStoreItem(m_CastItem->GetBagSlot(), m_CastItem->GetSlot(), dest, pNewItem, true);
2252 if (msg == EQUIP_ERR_OK)
2253 {
2254 player->DestroyItem(m_CastItem->GetBagSlot(), m_CastItem->GetSlot(), true);
2255
2256 // prevent crash at access and unexpected charges counting with item update queue corrupt
2258 m_targets.SetItemTarget(nullptr);
2259
2260 m_CastItem = nullptr;
2262
2263 player->StoreItem(dest, pNewItem, true);
2264 player->ItemAddedQuestCheck(pNewItem->GetEntry(), 1);
2265 return;
2266 }
2267 }
2268 else if (player->IsBankPos(pos))
2269 {
2270 ItemPosCountVec dest;
2271 uint8 msg = player->CanBankItem(m_CastItem->GetBagSlot(), m_CastItem->GetSlot(), dest, pNewItem, true);
2272 if (msg == EQUIP_ERR_OK)
2273 {
2274 player->DestroyItem(m_CastItem->GetBagSlot(), m_CastItem->GetSlot(), true);
2275
2276 // prevent crash at access and unexpected charges counting with item update queue corrupt
2278 m_targets.SetItemTarget(nullptr);
2279
2280 m_CastItem = nullptr;
2282
2283 player->BankItem(dest, pNewItem, true);
2284 return;
2285 }
2286 }
2287 else if (player->IsEquipmentPos(pos))
2288 {
2289 uint16 dest;
2290
2291 player->DestroyItem(m_CastItem->GetBagSlot(), m_CastItem->GetSlot(), true);
2292
2293 uint8 msg = player->CanEquipItem(m_CastItem->GetSlot(), dest, pNewItem, true);
2294
2295 if (msg == EQUIP_ERR_OK || msg == EQUIP_ERR_CANT_DO_RIGHT_NOW)
2296 {
2298
2299 // prevent crash at access and unexpected charges counting with item update queue corrupt
2301 m_targets.SetItemTarget(nullptr);
2302
2303 m_CastItem = nullptr;
2305
2306 player->EquipItem(dest, pNewItem, true);
2307 player->AutoUnequipOffhandIfNeed();
2308 return;
2309 }
2310 }
2311
2312 // fail
2313 delete pNewItem;
2314}
@ EQUIP_ERR_CANT_DO_RIGHT_NOW
Definition: Item.h:80
@ ITEM_FIELD_DURABILITY
Definition: UpdateFields.h:69
@ ITEM_FIELD_MAXDURABILITY
Definition: UpdateFields.h:70
uint8 GetSlot() const
Definition: Item.h:272
static Item * CreateItem(uint32 item, uint32 count, Player const *player=nullptr, bool clone=false, uint32 randomPropertyId=0)
Definition: Item.cpp:1089
uint32 GetEnchantmentDuration(EnchantmentSlot slot) const
Definition: Item.h:296
uint16 GetPos() const
Definition: Item.h:276
uint32 GetEnchantmentCharges(EnchantmentSlot slot) const
Definition: Item.h:297
uint8 GetBagSlot() const
Definition: Item.cpp:786
void Clear()
Definition: ObjectGuid.h:140
static bool IsEquipmentPos(uint16 pos)
Definition: Player.h:1232
InventoryResult CanEquipItem(uint8 slot, uint16 &dest, Item *pItem, bool swap, bool not_loading=true) const
Definition: PlayerStorage.cpp:1839
Item * BankItem(ItemPosCountVec const &dest, Item *pItem, bool update)
Definition: Player.h:1301
InventoryResult CanStoreItem(uint8 bag, uint8 slot, ItemPosCountVec &dest, Item *pItem, bool swap=false) const
Definition: Player.h:1252
void UpdateEnchantmentDurations()
Definition: PlayerStorage.cpp:4760
Item * StoreItem(ItemPosCountVec const &pos, Item *pItem, bool update)
Definition: PlayerStorage.cpp:2602
void DestroyItem(uint8 bag, uint8 slot, bool update)
Definition: PlayerStorage.cpp:3051
static bool IsInventoryPos(uint16 pos)
Definition: Player.h:1230
void AutoUnequipOffhandIfNeed(bool force=false)
Definition: Player.cpp:12364
Item * EquipItem(uint16 pos, Item *pItem, bool update)
Definition: PlayerStorage.cpp:2755
InventoryResult CanBankItem(uint8 bag, uint8 slot, ItemPosCountVec &dest, Item *pItem, bool swap, bool not_loading=true) const
Definition: PlayerStorage.cpp:2058
void ItemAddedQuestCheck(uint32 entry, uint32 count)
Definition: PlayerQuest.cpp:1819
static bool IsBankPos(uint16 pos)
Definition: Player.h:1235

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::GetTypeId(), Object::GetUInt32Value(), Player::IsBankPos(), Player::IsEquipmentPos(), Player::IsInventoryPos(), 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(), TYPEID_PLAYER, and Player::UpdateEnchantmentDurations().

◆ EffectSummonCritter()

void Spell::EffectSummonCritter ( SpellEffIndex  effIndex)

◆ EffectSummonObject()

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

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

◆ EffectSummonObjectWild()

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

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

◆ EffectSummonPet()

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

References ASSERT, Aura::CanBeSentToClient(), CLASS_HUNTER, effectHandleMode, SpellInfo::Effects, Unit::GetAppliedAuras(), Unit::GetCharmerOrOwnerPlayerOrPlayerItself(), Unit::getClass(), WorldObject::GetClosePoint(), SpellInfo::GetDuration(), Object::GetEntry(), Unit::GetGuardianPet(), WorldObject::GetMap(), Unit::GetMaxHealth(), Unit::GetMaxPower(), WorldObject::GetObjectSize(), Position::GetOrientation(), Player::GetPet(), Unit::getPowerType(), Unit::GetSpellModOwner(), Object::GetTypeId(), SpellInfo::Id, Unit::isDead(), Aura::IsPassive(), Unit::IsPetAura(), 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(), Object::SetUInt32Value(), sObjectMgr, SPELL_EFFECT_HANDLE_HIT, SPELLMOD_DURATION, sSummonPropertiesStore, SUMMON_PET, SummonGuardian(), Player::SummonPet(), Object::ToCreature(), Object::ToPlayer(), TYPEID_PLAYER, TYPEID_UNIT, UNIT_CREATED_BY_SPELL, and Unit::UpdateObjectVisibility().

◆ EffectSummonPlayer()

void Spell::EffectSummonPlayer ( SpellEffIndex  effIndex)
4246{
4247 // workaround - this effect should not use target map
4249 return;
4250
4251 if (!unitTarget)
4252 return;
4253
4254 Player* player = unitTarget->ToPlayer();
4255 if (!player)
4256 {
4257 return;
4258 }
4259
4260 // Evil Twin (ignore player summon, but hide this for summoner)
4261 // Xinef: Unit Target may be on other map!!!, Need workaround
4262 if (unitTarget->HasAura(23445))
4263 return;
4264
4265 float x, y, z;
4266 m_caster->GetPosition(x, y, z);
4267
4268 player->SetSummonPoint(m_caster->GetMapId(), x, y, z);
4269
4270 WorldPacket data(SMSG_SUMMON_REQUEST, 8 + 4 + 4);
4271 data << m_caster->GetGUID(); // summoner guid
4272 data << uint32(m_caster->GetZoneId()); // summoner zone
4273 data << uint32(MAX_PLAYER_SUMMON_DELAY * IN_MILLISECONDS); // auto decline after msecs
4274 player->GetSession()->SendPacket(&data);
4275}
#define MAX_PLAYER_SUMMON_DELAY
Definition: Player.h:921
@ SMSG_SUMMON_REQUEST
Definition: Opcodes.h:713
void SetSummonPoint(uint32 mapid, float x, float y, float z, uint32 delay=0, bool asSpectator=false)
Definition: Player.cpp:16199

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

◆ EffectSummonRaFFriend()

void Spell::EffectSummonRaFFriend ( SpellEffIndex  effIndex)
6390{
6392 return;
6393
6395 return;
6396
6397 if (!unitTarget)
6398 return;
6399
6400 Player* player = unitTarget->ToPlayer();
6401 if (!player)
6402 {
6403 return;
6404 }
6405
6406 float x, y, z;
6407 m_caster->GetPosition(x, y, z);
6409 WorldPacket data(SMSG_SUMMON_REQUEST, 8 + 4 + 4);
6410 data << m_caster->GetGUID();
6411 data << uint32(m_caster->GetZoneId());
6412 data << uint32(MAX_PLAYER_SUMMON_DELAY * IN_MILLISECONDS); // auto decline after msecs
6413 player->GetSession()->SendPacket(&data);
6414}

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

◆ EffectSummonType()

void Spell::EffectSummonType ( SpellEffIndex  effIndex)
2339{
2341 return;
2342
2343 uint32 entry = m_spellInfo->Effects[effIndex].MiscValue;
2344 if (!entry)
2345 return;
2346
2347 SummonPropertiesEntry const* properties = sSummonPropertiesStore.LookupEntry(m_spellInfo->Effects[effIndex].MiscValueB);
2348 if (!properties)
2349 {
2350 LOG_ERROR("spells.effect", "EffectSummonType: Unhandled summon type {}", m_spellInfo->Effects[effIndex].MiscValueB);
2351 return;
2352 }
2353
2354 if (!m_originalCaster)
2355 return;
2356
2357 bool personalSpawn = (properties->Flags & SUMMON_PROP_FLAG_ONLY_VISIBLE_TO_SUMMONER) != 0;
2358 int32 duration = m_spellInfo->GetDuration();
2359 if (Player* modOwner = m_originalCaster->GetSpellModOwner())
2360 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_DURATION, duration);
2361
2362 TempSummon* summon = nullptr;
2363
2364 // determine how many units should be summoned
2365 uint32 numSummons;
2366
2367 // some spells need to summon many units, for those spells number of summons is stored in effect value
2368 // however so far noone found a generic check to find all of those (there's no related data in summonproperties.dbc
2369 // and in spell attributes, possibly we need to add a table for those)
2370 // so here's a list of MiscValueB values, which is currently most generic check
2371 switch (properties->Id)
2372 {
2373 case 64:
2374 case 61:
2375 case 1101:
2376 case 66:
2377 case 648:
2378 case 2301:
2379 case 1061:
2380 case 1261:
2381 case 629:
2382 case 181:
2383 case 715:
2384 case 1562:
2385 case 833:
2386 case 1161:
2387 case 713: // xinef, bloodworms
2388 numSummons = (damage > 0) ? damage : 1;
2389 break;
2390 default:
2391 numSummons = 1;
2392 break;
2393 }
2394
2395 switch (properties->Category)
2396 {
2400 if (properties->Flags & 512)
2401 {
2402 SummonGuardian(effIndex, entry, properties, numSummons, personalSpawn);
2403 break;
2404 }
2405 switch (properties->Type)
2406 {
2407 case SUMMON_TYPE_PET:
2410 case SUMMON_TYPE_MINION:
2411 SummonGuardian(effIndex, entry, properties, numSummons, personalSpawn);
2412 break;
2413 // Summons a vehicle, but doesn't force anyone to enter it (see SUMMON_CATEGORY_VEHICLE)
2416 summon = m_caster->GetMap()->SummonCreature(entry, *destTarget, properties, duration, m_originalCaster, m_spellInfo->Id, 0, personalSpawn);
2417 break;
2419 case SUMMON_TYPE_TOTEM:
2420 {
2421 // protection code
2422 summon = m_caster->GetMap()->SummonCreature(entry, *destTarget, properties, duration, m_originalCaster, m_spellInfo->Id, 0, personalSpawn);
2423 if (!summon || !summon->IsTotem())
2424 return;
2425
2426 // Mana Tide Totem
2427 if (m_spellInfo->Id == 16190)
2429
2430 if (damage && properties->Type != SUMMON_TYPE_LIGHTWELL) // Health set in script for lightwell
2431 {
2432 summon->SetMaxHealth(damage);
2433 summon->SetHealth(damage);
2434 }
2435 break;
2436 }
2437 case SUMMON_TYPE_JEEVES:
2439 {
2440 summon = m_caster->GetMap()->SummonCreature(entry, *destTarget, properties, duration, m_originalCaster, m_spellInfo->Id, 0, personalSpawn);
2441 if (!summon || !summon->HasUnitTypeMask(UNIT_MASK_MINION))
2442 return;
2443
2444 summon->SelectLevel(); // some summoned creaters have different from 1 DB data for level/hp
2446
2447 summon->SetImmuneToAll(true);
2449
2450 // Xinef: Pet can have some auras in creature_addon or in scripts, do not remove them instantly
2451 //summon->AI()->EnterEvadeMode();
2452 if (properties->Type != SUMMON_TYPE_JEEVES)
2453 {
2454 summon->GetMotionMaster()->Clear(false);
2456 }
2457 break;
2458 }
2459 default:
2460 {
2461 float radius = m_spellInfo->Effects[effIndex].CalcRadius();
2462
2463 TempSummonType summonType = (duration <= 0) ? TEMPSUMMON_DEAD_DESPAWN : TEMPSUMMON_TIMED_DESPAWN;
2464
2465 for (uint32 count = 0; count < numSummons; ++count)
2466 {
2467 Position pos;
2468 if (count == 0)
2469 pos = *destTarget;
2470 else
2471 // randomize position for multiple summons
2472 pos = m_caster->GetRandomPoint(*destTarget, radius);
2473
2474 summon = m_originalCaster->SummonCreature(entry, pos, summonType, duration, 0, nullptr, personalSpawn);
2475 if (!summon)
2476 continue;
2477
2478 summon->SetTempSummonType(summonType);
2479
2480 if (properties->Category == SUMMON_CATEGORY_ALLY)
2481 {
2484 }
2485
2486 ExecuteLogEffectSummonObject(effIndex, summon);
2487 }
2488 return;
2489 }
2490 }//switch
2491 break;
2493 // Xinef: SummonGuardian function can summon a few npcs of same type, remove old summons with same entry here
2494 if (m_originalCaster)
2496 SummonGuardian(effIndex, entry, properties, numSummons, personalSpawn);
2497 break;
2499 summon = m_caster->GetMap()->SummonCreature(entry, *destTarget, properties, duration, m_originalCaster, m_spellInfo->Id, 0, personalSpawn);
2500 break;
2502 // Summoning spells (usually triggered by npc_spellclick) that spawn a vehicle and that cause the clicker
2503 // to cast a ride vehicle spell on the summoned unit.
2504 //float x, y, z;
2505 //m_caster->GetClosePoint(x, y, z, DEFAULT_WORLD_OBJECT_SIZE);
2506 // xinef: vehicles summoned in air, eg. Cold Hearted quest
2507 if (std::fabs(m_caster->GetPositionZ() - destTarget->GetPositionZ()) > 6.0f)
2509
2510 summon = m_originalCaster->GetMap()->SummonCreature(entry, *destTarget, properties, duration, m_caster, m_spellInfo->Id, 0, personalSpawn);
2511 if (!summon || !summon->IsVehicle())
2512 return;
2513
2514 // The spell that this effect will trigger. It has SPELL_AURA_CONTROL_VEHICLE
2516 int32 basePoints = m_spellInfo->Effects[effIndex].CalcValue();
2517 if (basePoints > 1) // xinef: some summoning spells have value 1 - indicates vehicle seat
2518 {
2519 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(basePoints);
2520 if (spellInfo && spellInfo->HasAura(SPELL_AURA_CONTROL_VEHICLE))
2521 spellId = spellInfo->Id;
2522 }
2523
2524 // xinef: if we have small value, it indicates seat position
2525 if (basePoints > 0 && basePoints < MAX_VEHICLE_SEATS)
2526 m_originalCaster->CastCustomSpell(spellId, SPELLVALUE_BASE_POINT0, basePoints, summon, true);
2527 else
2528 m_originalCaster->CastSpell(summon, spellId, true);
2529
2530 // xinef: i think this is wrong, found only 2 vehicles with faction override and one of them should inherit caster faction...
2531 //uint32 faction = properties->Faction;
2532 //if (!faction)
2533 uint32 faction = m_originalCaster->GetFaction();
2534
2535 summon->SetFaction(faction);
2536 break;
2537 }
2538
2539 if (summon)
2540 {
2542 ExecuteLogEffectSummonObject(effIndex, summon);
2543 }
2544}
TempSummonType
Definition: Object.h:41
@ TEMPSUMMON_DEAD_DESPAWN
Definition: Object.h:48
@ UNIT_MASK_MINION
Definition: Unit.h:676
@ REACT_PASSIVE
Definition: Unit.h:1023
NPCFlags
Non Player Character flags.
Definition: Unit.h:514
@ VEHICLE_SPELL_RIDE_HARDCODED
Definition: VehicleDefines.h:53
@ MOTION_SLOT_ACTIVE
Definition: MotionMaster.h:62
@ SPELL_AURA_CONTROL_VEHICLE
Definition: SpellAuraDefines.h:299
@ SUMMON_PROP_FLAG_ONLY_VISIBLE_TO_SUMMONER
Definition: DBCEnums.h:433
#define MAX_VEHICLE_SEATS
Definition: DBCStructure.h:2000
@ SUMMON_TYPE_VEHICLE2
Definition: SharedDefines.h:3276
@ SUMMON_TYPE_LIGHTWELL
Definition: SharedDefines.h:3277
@ SUMMON_TYPE_MINION
Definition: SharedDefines.h:3269
@ SUMMON_TYPE_GUARDIAN
Definition: SharedDefines.h:3268
@ SUMMON_TYPE_JEEVES
Definition: SharedDefines.h:3278
@ SUMMON_TYPE_PET
Definition: SharedDefines.h:3267
@ SUMMON_TYPE_TOTEM
Definition: SharedDefines.h:3270
@ SUMMON_TYPE_VEHICLE
Definition: SharedDefines.h:3275
@ SUMMON_TYPE_MINIPET
Definition: SharedDefines.h:3271
@ SUMMON_TYPE_GUARDIAN2
Definition: SharedDefines.h:3272
@ SUMMON_CATEGORY_VEHICLE
Definition: SharedDefines.h:3259
@ SUMMON_CATEGORY_ALLY
Definition: SharedDefines.h:3256
@ SUMMON_CATEGORY_WILD
Definition: SharedDefines.h:3255
@ SUMMON_CATEGORY_UNK
Definition: SharedDefines.h:3260
void SelectLevel(bool changelevel=true)
Definition: Creature.cpp:1482
uint32 npcflag
Definition: CreatureData.h:192
void SetTempSummonType(TempSummonType type)
Definition: TemporarySummon.cpp:278
void GetRandomPoint(const Position &srcPos, float distance, float &rand_x, float &rand_y, float &rand_z) const
Definition: Object.cpp:1502
void SetFaction(uint32 faction)
Definition: Unit.cpp:10029
virtual float GetFollowAngle() const
Definition: Unit.h:2392
void SetOwnerGUID(ObjectGuid owner)
Definition: Unit.cpp:10533
uint32 HasUnitTypeMask(uint32 mask) const
Definition: Unit.h:1407
void SetMaxHealth(uint32 val)
Definition: Unit.cpp:15420
void SetCreatorGUID(ObjectGuid creator)
Definition: Unit.h:1817
void ReplaceAllNpcFlags(NPCFlags flags)
Definition: Unit.h:1649
void RemoveAllMinionsByEntry(uint32 entry)
Definition: Unit.cpp:10818
void SetImmuneToAll(bool apply, bool keepCombat=false)
Definition: Unit.h:1678
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:2129
void MoveFollow(Unit *target, float dist, float angle, MovementSlot slot=MOTION_SLOT_ACTIVE)
Definition: MotionMaster.cpp:367
void Clear(bool reset=true)
Definition: MotionMaster.h:165
uint32 Flags
Definition: DBCStructure.h:1891
uint32 Type
Definition: DBCStructure.h:1889
uint32 Id
Definition: DBCStructure.h:1886

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

◆ EffectTameCreature()

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

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

◆ EffectTaunt()

void Spell::EffectTaunt ( SpellEffIndex  effIndex)
3289{
3291 return;
3292
3293 if (!unitTarget)
3294 return;
3295
3296 // xinef: Hand of Reckoning, cast before checing canhavethreatlist. fixes damage against pets
3297 if (m_spellInfo->Id == 62124 && unitTarget->GetVictim() != m_caster)
3298 {
3299 m_caster->CastSpell(unitTarget, 67485, true);
3301 }
3302
3303 // this effect use before aura Taunt apply for prevent taunt already attacking target
3304 // for spell as marked "non effective at already attacking target"
3306 {
3308 return;
3309 }
3310
3312 {
3313 // Also use this effect to set the taunter's threat to the taunted creature's highest value
3314 float myThreat = unitTarget->GetThreatMgr().GetThreat(m_caster);
3316 if (topThreat > myThreat)
3317 unitTarget->GetThreatMgr().DoAddThreat(m_caster, topThreat - myThreat);
3318
3319 //Set aggro victim to caster
3321 unitTarget->GetThreatMgr().setCurrentVictim(forcedVictim);
3322 }
3323
3326}
@ SPELL_AURA_MOD_TAUNT
Definition: SpellAuraDefines.h:74
Definition: ThreatMgr.h:49
float GetThreat() const
Definition: ThreatMgr.h:63
HostileReference * getMostHated() const
Definition: ThreatMgr.h:169
HostileReference * getReferenceByTarget(Unit const *victim) const
Definition: ThreatMgr.cpp:262
bool empty() const
Definition: ThreatMgr.h:164
void setCurrentVictim(HostileReference *hostileRef)
Definition: ThreatMgr.cpp:573
void DoAddThreat(Unit *victim, float threat)
Definition: ThreatMgr.cpp:454
float GetThreat(Unit *victim, bool alsoSearchOfflineList=false)
Definition: ThreatMgr.cpp:526
ThreatContainer & GetOnlineContainer()
Definition: ThreatMgr.h:276
bool HasReactState(ReactStates state) const
Definition: Creature.h:91
bool CanHaveThreatList() const
Definition: Unit.cpp:14509

References Creature::AI(), UnitAI::AttackStart(), 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(), Creature::HasReactState(), SpellInfo::Id, Unit::IsAIEnabled, m_caster, m_spellInfo, REACT_PASSIVE, SendCastResult(), ThreatMgr::setCurrentVictim(), SPELL_AURA_MOD_TAUNT, SPELL_EFFECT_HANDLE_HIT_TARGET, SPELL_FAILED_DONT_REPORT, Object::ToCreature(), and unitTarget.

◆ EffectTeleportUnits()

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

References Unit::CastSpell(), destTarget, effectHandleMode, Position::GetExactDist(), WorldObject::GetMap(), WorldLocation::GetMapId(), Position::GetOrientation(), Position::GetPosition(), Player::GetTeamId(), Object::GetTypeId(), SpellCastTargets::GetUnitTarget(), Unit::GetVehicleKit(), SpellCastTargets::HasDst(), SpellInfo::Id, irand(), Map::IsDungeon(), Unit::IsInFlight(), 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(), TYPEID_PLAYER, unitTarget, Unit::UpdateObjectVisibility(), and urand().

◆ EffectTeleUnitsFaceCaster()

◆ EffectThreat()

void Spell::EffectThreat ( SpellEffIndex  effIndex)
3682{
3684 return;
3685
3686 if (!unitTarget || !unitTarget->IsAlive() || !m_caster->IsAlive())
3687 return;
3688
3689 // xinef: skip if target cannot have threat list or caster is friendly (ghoul leap)
3691 return;
3692
3694}
void AddThreat(Unit *victim, float fThreat, SpellSchoolMask schoolMask=SPELL_SCHOOL_MASK_NORMAL, SpellInfo const *threatSpell=nullptr)
Definition: Unit.cpp:14548

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)
5935{
5937 return;
5938
5940 {
5941 if (Aura* aur = m_caster->GetAura(49152))
5942 aur->RecalculateAmountOfEffects();
5943 else
5944 m_caster->CastSpell(unitTarget, 49152, true); // damage reduction
5945
5947 }
5948}
void SetCanTitanGrip(bool value)
Definition: Player.cpp:13036

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

◆ EffectTradeSkill()

void Spell::EffectTradeSkill ( SpellEffIndex  effIndex)
2830{
2832 return;
2833
2835 return;
2836 // uint32 skillid = m_spellInfo->Effects[i].MiscValue;
2837 // uint16 skillmax = unitTarget->ToPlayer()->(skillid);
2838 // m_caster->ToPlayer()->SetSkill(skillid, skillval?skillval:1, skillmax+75);
2839}

References effectHandleMode, Object::GetTypeId(), m_caster, SPELL_EFFECT_HANDLE_HIT, and TYPEID_PLAYER.

◆ EffectTransmitted()

void Spell::EffectTransmitted ( SpellEffIndex  effIndex)
5400{
5402 return;
5403
5404 uint32 name_id = m_spellInfo->Effects[effIndex].MiscValue;
5405
5406 GameObjectTemplate const* goinfo = sObjectMgr->GetGameObjectTemplate(name_id);
5407
5408 if (!goinfo)
5409 {
5410 LOG_ERROR("sql.sql", "Gameobject (Entry: {}) not exist and not created at spell (ID: {}) cast", name_id, m_spellInfo->Id);
5411 return;
5412 }
5413
5414 float fx, fy, fz;
5415
5416 if (m_targets.HasDst())
5417 destTarget->GetPosition(fx, fy, fz);
5418 //FIXME: this can be better check for most objects but still hack
5419 else if (m_spellInfo->Effects[effIndex].HasRadius() && m_spellInfo->Speed == 0)
5420 {
5421 float dis = m_spellInfo->Effects[effIndex].CalcRadius(m_originalCaster);
5423 }
5424 else
5425 {
5426 //GO is always friendly to it's creator, get range for friends
5427 float min_dis = m_spellInfo->GetMinRange(true);
5428 float max_dis = m_spellInfo->GetMaxRange(true);
5429 float dis = (float)rand_norm() * (max_dis - min_dis) + min_dis;
5430
5432 }
5433
5434 // Seaforium charge
5435 if (m_spellInfo->Id == 52410 || m_spellInfo->Id == 66268 || m_spellInfo->Id == 66674) // SotA / IoC / IoC Huge
5436 {
5437 fx = m_caster->GetPositionX();
5438 fy = m_caster->GetPositionY();
5439 fz = m_caster->GetPositionZ();
5440 }
5441
5442 Map* cMap = m_caster->GetMap();
5443 // if gameobject is summoning object, it should be spawned right on caster's position
5445 m_caster->GetPosition(fx, fy, fz);
5446
5447 GameObject* pGameObj = sObjectMgr->IsGameObjectStaticTransport(name_id) ? new StaticTransport() : new GameObject();
5448
5449 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))
5450 {
5451 delete pGameObj;
5452 return;
5453 }
5454
5455 int32 duration = m_spellInfo->GetDuration();
5456
5457 switch (goinfo->type)
5458 {
5460 {
5462 m_caster->AddGameObject(pGameObj); // will removed at spell cancel
5463
5464 // end time of range when possible catch fish (FISHING_BOBBER_READY_TIME..GetDuration(m_spellInfo))
5465 // start time == fish-FISHING_BOBBER_READY_TIME (0..GetDuration(m_spellInfo)-FISHING_BOBBER_READY_TIME)
5466 int32 lastSec = 0;
5467 switch (urand(0, 2))
5468 {
5469 case 0:
5470 lastSec = 3;
5471 break;
5472 case 1:
5473 lastSec = 7;
5474 break;
5475 case 2:
5476 lastSec = 13;
5477 break;
5478 }
5479
5480 // Duration of the fishing bobber can't be higher than the Fishing channeling duration
5481 duration = std::min(duration, duration - lastSec*IN_MILLISECONDS + FISHING_BOBBER_READY_TIME*IN_MILLISECONDS);
5482
5483 break;
5484 }
5486 {
5488 {
5489 pGameObj->AddUniqueUse(m_caster->ToPlayer());
5490 m_caster->AddGameObject(pGameObj); // will be removed at spell cancel
5491 }
5492 break;
5493 }
5494 case GAMEOBJECT_TYPE_DUEL_ARBITER: // 52991
5495 m_caster->AddGameObject(pGameObj);
5496 break;
5499 default:
5500 break;
5501 }
5502
5503 pGameObj->SetRespawnTime(duration > 0 ? duration / IN_MILLISECONDS : 0);
5504
5505 pGameObj->SetOwnerGUID(m_caster->GetGUID());
5506
5507 //pGameObj->SetUInt32Value(GAMEOBJECT_LEVEL, m_caster->GetLevel());
5508 pGameObj->SetSpellId(m_spellInfo->Id);
5509
5510 ExecuteLogEffectSummonObject(effIndex, pGameObj);
5511
5512 LOG_DEBUG("spells.effect", "AddObject at SpellEfects.cpp EffectTransmitted");
5513 //m_caster->AddGameObject(pGameObj);
5514 //m_ObjToDel.push_back(pGameObj);
5515
5516 cMap->AddToMap(pGameObj, true);
5517
5518 if (GameObject* linkedTrap = pGameObj->GetLinkedTrap())
5519 {
5520 linkedTrap->SetRespawnTime(duration > 0 ? duration / IN_MILLISECONDS : 0);
5521 linkedTrap->SetSpellId(m_spellInfo->Id);
5522 linkedTrap->SetOwnerGUID(m_caster->GetGUID());
5523
5524 ExecuteLogEffectSummonObject(effIndex, linkedTrap);
5525 }
5526
5527 if (Player* player = m_caster->ToPlayer())
5528 {
5529 player->SetCanTeleport(true);
5530 }
5531}
#define FISHING_BOBBER_READY_TIME
Definition: GameObject.h:119
@ UNIT_FIELD_CHANNEL_OBJECT
Definition: UpdateFields.h:93
@ GAMEOBJECT_TYPE_DUEL_ARBITER
Definition: SharedDefines.h:1548
@ GAMEOBJECT_TYPE_SUMMONING_RITUAL
Definition: SharedDefines.h:1550
@ GAMEOBJECT_TYPE_CHEST
Definition: SharedDefines.h:1535
@ GAMEOBJECT_TYPE_FISHINGHOLE
Definition: SharedDefines.h:1557
@ GAMEOBJECT_TYPE_FISHINGNODE
Definition: SharedDefines.h:1549
void SetOwnerGUID(ObjectGuid owner)
Definition: GameObject.h:165
void AddUniqueUse(Player *player)
Definition: GameObject.cpp:924
float GetMinRange(bool positive=false) const
Definition: SpellInfo.cpp:2297

References Unit::AddGameObject(), Map::AddToMap(), GameObject::AddUniqueUse(), GameObject::Create(), DEFAULT_WORLD_OBJECT_SIZE, destTarget, effectHandleMode, SpellInfo::Effects, ExecuteLogEffectSummonObject(), FISHING_BOBBER_READY_TIME, GAMEOBJECT_TYPE_CHEST, GAMEOBJECT_TYPE_DUEL_ARBITER, GAMEOBJECT_TYPE_FISHINGHOLE, GAMEOBJECT_TYPE_FISHINGNODE, GAMEOBJECT_TYPE_SUMMONING_RITUAL, Map::GenerateLowGuid(), WorldObject::GetClosePoint(), SpellInfo::GetDuration(), Object::GetGUID(), GameObject::GetLinkedTrap(), WorldObject::GetMap(), SpellInfo::GetMaxRange(), SpellInfo::GetMinRange(), Position::GetOrientation(), WorldObject::GetPhaseMask(), Position::GetPosition(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), Object::GetTypeId(), GO_STATE_READY, SpellCastTargets::HasDst(), SpellInfo::Id, IN_MILLISECONDS, 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, TYPEID_PLAYER, UNIT_FIELD_CHANNEL_OBJECT, and urand().

◆ EffectTriggerMissileSpell()

void Spell::EffectTriggerMissileSpell ( SpellEffIndex  effIndex)
967{
970 return;
971
972 uint32 triggered_spell_id = m_spellInfo->Effects[effIndex].TriggerSpell;
973
974 // normal case
975 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(triggered_spell_id);
976 if (!spellInfo)
977 {
978 LOG_DEBUG("spells.aura", "Spell::EffectTriggerMissileSpell spell {} tried to trigger unknown spell {}", m_spellInfo->Id, triggered_spell_id);
979 return;
980 }
981
982 SpellCastTargets targets;
984 {
985 if (!spellInfo->NeedsToBeTriggeredByCaster(m_spellInfo, effIndex))
986 return;
987 targets.SetUnitTarget(unitTarget);
988 }
989 else //if (effectHandleMode == SPELL_EFFECT_HANDLE_HIT)
990 {
991 if (spellInfo->NeedsToBeTriggeredByCaster(m_spellInfo, effIndex) && (m_spellInfo->Effects[effIndex].GetProvidedTargetMask() & TARGET_FLAG_UNIT_MASK))
992 return;
993
995 targets.SetDst(m_targets);
996
997 targets.SetUnitTarget(m_caster);
998 }
999
1000 CustomSpellValues values;
1001 // set basepoints for trigger with value effect
1003 {
1004 // maybe need to set value only when basepoints == 0?
1008 }
1009
1010 // Remove spell cooldown (not category) if spell triggering spell with cooldown and same category
1011 if (m_caster->GetTypeId() == TYPEID_PLAYER && spellInfo->CategoryRecoveryTime && m_spellInfo->GetCategory() == spellInfo->GetCategory())
1012 {
1013 m_caster->ToPlayer()->RemoveSpellCooldown(spellInfo->Id);
1014 }
1015
1016 // original caster guid only for GO cast
1017 m_caster->CastSpell(targets, spellInfo, &values, TRIGGERED_FULL_MASK, nullptr, nullptr, m_originalCasterGUID);
1018}
@ TARGET_FLAG_DEST_LOCATION
Definition: SpellInfo.h:52
@ SPELL_EFFECT_TRIGGER_MISSILE_SPELL_WITH_VALUE
Definition: SharedDefines.h:898
bool NeedsToBeTriggeredByCaster(SpellInfo const *triggeringSpell, uint8 effIndex=MAX_SPELL_EFFECTS) const
Definition: SpellInfo.cpp:1022
uint32 CategoryRecoveryTime
Definition: SpellInfo.h:347

References CustomSpellValues::AddSpellMod(), Unit::CastSpell(), SpellInfo::CategoryRecoveryTime, damage, effectHandleMode, SpellInfo::Effects, SpellInfo::GetCategory(), SpellInfo::GetExplicitTargetMask(), Object::GetTypeId(), SpellInfo::Id, 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, TYPEID_PLAYER, and unitTarget.

◆ EffectTriggerRitualOfSummoning()

void Spell::EffectTriggerRitualOfSummoning ( SpellEffIndex  effIndex)
1075{
1077 return;
1078
1079 uint32 triggered_spell_id = m_spellInfo->Effects[effIndex].TriggerSpell;
1080 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(triggered_spell_id);
1081
1082 if (!spellInfo)
1083 {
1084 LOG_ERROR("spells.effect", "EffectTriggerRitualOfSummoning of spell {}: triggering unknown spell id {}", m_spellInfo->Id, triggered_spell_id);
1085 return;
1086 }
1087
1088 finish();
1089
1090 m_caster->CastSpell((Unit*)nullptr, spellInfo, false);
1091}

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
793{
796 return;
797
798 uint32 triggered_spell_id = m_spellInfo->Effects[effIndex].TriggerSpell;
799
801 if (m_spellInfo->Effects[effIndex].Effect == SPELL_EFFECT_TRIGGER_SPELL
803 {
804 // special cases
805 switch (triggered_spell_id)
806 {
807 // Mirror Image
808 case 58832:
809 {
810 // Glyph of Mirror Image
811 if (m_caster->HasAura(63093))
812 m_caster->CastSpell(m_caster, 65047, true); // Mirror Image
813
814 break;
815 }
816 // Vanish (not exist)
817 case 18461:
818 {
821
822 // See if we already are stealthed. If so, we're done.
823 if (unitTarget->HasAura(1784))
824 return;
825
826 // Reset cooldown on stealth if needed
829
830 unitTarget->CastSpell(unitTarget, 1784, true);
831 return;
832 }
833 // Demonic Empowerment -- succubus
834 case 54437:
835 {
839
840 // Cast Lesser Invisibility
841 unitTarget->CastSpell(unitTarget, 7870, true);
842 return;
843 }
844 // just skip
845 case 23770: // Sayge's Dark Fortune of *
846 // not exist, common cooldown can be implemented in scripts if need.
847 return;
848 // Brittle Armor - (need add max stack of 24575 Brittle Armor)
849 case 29284:
850 {
851 // Brittle Armor
852 SpellInfo const* spell = sSpellMgr->GetSpellInfo(24575);
853 if (!spell)
854 return;
855
856 for (uint32 j = 0; j < spell->StackAmount; ++j)
857 m_caster->CastSpell(unitTarget, spell->Id, true);
858 return;
859 }
860 // Mercurial Shield - (need add max stack of 26464 Mercurial Shield)
861 case 29286:
862 {
863 // Mercurial Shield
864 SpellInfo const* spell = sSpellMgr->GetSpellInfo(26464);
865 if (!spell)
866 return;
867
868 for (uint32 j = 0; j < spell->StackAmount; ++j)
869 m_caster->CastSpell(unitTarget, spell->Id, true);
870 return;
871 }
872 // Cloak of Shadows
873 case 35729:
874 {
877 for (Unit::AuraApplicationMap::iterator iter = Auras.begin(); iter != Auras.end();)
878 {
879 // remove all harmful spells on you...
880 SpellInfo const* spell = iter->second->GetBase()->GetSpellInfo();
881
882 // Pounce Bleed shouldn't be removed by Cloak of Shadows.
883 if (spell->GetAllEffectsMechanicMask() & 1 << MECHANIC_BLEED)
884 return;
885
886 bool dmgClassNone = false;
888 for (uint8 i = EFFECT_0; i < MAX_SPELL_EFFECTS; ++i)
889 {
890 if ((iter->second->GetEffectMask() & (1 << i)) &&
891 spell->Effects[i].ApplyAuraName != SPELL_AURA_PERIODIC_DAMAGE &&
892 spell->Effects[i].ApplyAuraName != SPELL_AURA_PERIODIC_TRIGGER_SPELL &&
893 spell->Effects[i].ApplyAuraName != SPELL_AURA_DUMMY)
894 {
895 dmgClassNone = false;
896 break;
897 }
898 dmgClassNone = true;
899 }
900
901 if ((spell->DmgClass == SPELL_DAMAGE_CLASS_MAGIC || (spell->GetDispelMask() & dispelMask) || dmgClassNone) &&
902 // ignore positive and passive auras
903 !iter->second->IsPositive() && !iter->second->GetBase()->IsPassive() &&
904 // Xinef: Ignore NPC spells having INVULNERABILITY attribute
906 {
907 m_caster->RemoveAura(iter);
908 }
909 else
910 ++iter;
911 }
912 return;
913 }
914 }
915 }
916
917 // normal case
918 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(triggered_spell_id);
919 if (!spellInfo)
920 {
921 LOG_DEBUG("spells.aura", "Spell::EffectTriggerSpell spell {} tried to trigger unknown spell {}", m_spellInfo->Id, triggered_spell_id);
922 return;
923 }
924
925 SpellCastTargets targets;
927 {
928 if (!spellInfo->NeedsToBeTriggeredByCaster(m_spellInfo, effIndex))
929 return;
930 targets.SetUnitTarget(unitTarget);
931 }
932 else //if (effectHandleMode == SPELL_EFFECT_HANDLE_LAUNCH)
933 {
934 if (spellInfo->NeedsToBeTriggeredByCaster(m_spellInfo, effIndex) && (m_spellInfo->Effects[effIndex].GetProvidedTargetMask() & TARGET_FLAG_UNIT_MASK))
935 return;
936
938 targets.SetDst(m_targets);
939
940 if (Unit* target = m_targets.GetUnitTarget())
941 targets.SetUnitTarget(target);
942 else
943 targets.SetUnitTarget(m_caster);
944 }
945
946 CustomSpellValues values;
947 // set basepoints for trigger with value effect
949 {
950 // maybe need to set value only when basepoints == 0?
954 }
955
956 // Remove spell cooldown (not category) if spell triggering spell with cooldown and same category
957 if (m_caster->GetTypeId() == TYPEID_PLAYER && spellInfo->CategoryRecoveryTime && m_spellInfo->GetCategory() == spellInfo->GetCategory())
958 {
959 m_caster->ToPlayer()->RemoveSpellCooldown(spellInfo->Id);
960 }
961
962 // original caster guid only for GO cast
964}
@ SPELL_AURA_MOD_STALKED
Definition: SpellAuraDefines.h:131
@ SPELL_AURA_PERIODIC_TRIGGER_SPELL
Definition: SpellAuraDefines.h:86
@ SPELL_EFFECT_TRIGGER_SPELL_WITH_VALUE
Definition: SharedDefines.h:892
@ SPELL_EFFECT_TRIGGER_SPELL
Definition: SharedDefines.h:814
@ MECHANIC_BLEED
Definition: SharedDefines.h:1312
@ DISPEL_ALL
Definition: SharedDefines.h:1351

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(), Object::GetTypeId(), SpellCastTargets::GetUnitTarget(), SpellInfo::HasAttribute(), Unit::HasAura(), Player::HasSpellCooldown(), SpellInfo::Id, 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, TYPEID_PLAYER, and unitTarget.

◆ EffectUnlearnSpecialization()

void Spell::EffectUnlearnSpecialization ( SpellEffIndex  effIndex)
1339{
1341 return;
1342
1343 if (!unitTarget)
1344 return;
1345
1346 Player* player = unitTarget->ToPlayer();
1347 if (!player)
1348 {
1349 return;
1350 }
1351
1352 uint32 spellToUnlearn = m_spellInfo->Effects[effIndex].TriggerSpell;
1353
1354 player->removeSpell(spellToUnlearn, SPEC_MASK_ALL, false);
1355 LOG_DEBUG("spells.aura", "Spell: Player {} has unlearned spell {} from Npc: {}",
1356 player->GetGUID().ToString(), spellToUnlearn, m_caster->GetGUID().ToString());
1357}
#define SPEC_MASK_ALL
Definition: Player.h:178
void removeSpell(uint32 spellId, uint8 removeSpecMask, bool onlyTemporary)
Definition: Player.cpp:3271

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)
2754{
2756 return;
2757
2759 return;
2760
2761 if (ObjectGuid guid = m_caster->GetGUID()) // the trainer is the caster
2763}
void SendTalentWipeConfirm(ObjectGuid guid)
Definition: Player.cpp:8756

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

◆ EffectUnused()

void Spell::EffectUnused ( SpellEffIndex  effIndex)
247{
248 // NOT USED BY ANY SPELL OR USELESS OR IMPLEMENTED IN DIFFERENT WAY IN TRINITY
249}

◆ EffectWeaponDmg()

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

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(), Object::GetTypeId(), Player::GetWeaponForAttack(), SpellInfo::HasAttribute(), Unit::HasAura(), Unit::HasAuraState(), Unit::HasAuraType(), SpellInfo::Id, Unit::IsAlive(), 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_AURA_MOD_DECREASE_SPEED, 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, TYPEID_PLAYER, UNIT_MOD_DAMAGE_MAINHAND, UNIT_MOD_DAMAGE_OFFHAND, UNIT_MOD_DAMAGE_RANGED, and unitTarget.

◆ ExecuteLogEffectCreateItem()

void Spell::ExecuteLogEffectCreateItem ( uint8  effIndex,
uint32  entry 
)
5107{
5108 InitEffectExecuteData(effIndex);
5109 *m_effectExecuteData[effIndex] << uint32(entry);
5110}
void InitEffectExecuteData(uint8 effIndex)
Definition: Spell.cpp:8433

References InitEffectExecuteData(), and m_effectExecuteData.

Referenced by EffectCreateItem().

◆ ExecuteLogEffectDestroyItem()

void Spell::ExecuteLogEffectDestroyItem ( uint8  effIndex,
uint32  entry 
)
5113{
5114 InitEffectExecuteData(effIndex);
5115 *m_effectExecuteData[effIndex] << uint32(entry);
5116}

References InitEffectExecuteData(), and m_effectExecuteData.

Referenced by EffectFeedPet().

◆ ExecuteLogEffectDurabilityDamage()

void Spell::ExecuteLogEffectDurabilityDamage ( uint8  effIndex,
Unit victim,
int32  itemId,
int32  slot 
)
5093{
5094 InitEffectExecuteData(effIndex);
5095 *m_effectExecuteData[effIndex] << victim->GetPackGUID();
5096 *m_effectExecuteData[effIndex] << int32(itemId);
5097 *m_effectExecuteData[effIndex] << int32(slot);
5098}

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

Referenced by EffectDurabilityDamage().

◆ ExecuteLogEffectExtraAttacks()

void Spell::ExecuteLogEffectExtraAttacks ( uint8  effIndex,
Unit victim,
uint32  attCount 
)
5079{
5080 InitEffectExecuteData(effIndex);
5081 *m_effectExecuteData[effIndex] << victim->GetPackGUID();
5082 *m_effectExecuteData[effIndex] << uint32(attCount);
5083}

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

Referenced by EffectAddExtraAttacks().

◆ ExecuteLogEffectInterruptCast()

void Spell::ExecuteLogEffectInterruptCast ( uint8  effIndex,
Unit victim,
uint32  spellId 
)
5086{
5087 InitEffectExecuteData(effIndex);
5088 *m_effectExecuteData[effIndex] << victim->GetPackGUID();
5089 *m_effectExecuteData[effIndex] << uint32(spellId);
5090}

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

Referenced by EffectInterruptCast().

◆ ExecuteLogEffectOpenLock()

void Spell::ExecuteLogEffectOpenLock ( uint8  effIndex,
Object obj 
)
5101{
5102 InitEffectExecuteData(effIndex);
5103 *m_effectExecuteData[effIndex] << obj->GetPackGUID();
5104}

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

Referenced by EffectOpenLock().

◆ ExecuteLogEffectResurrect()

void Spell::ExecuteLogEffectResurrect ( uint8  effIndex,
Unit target 
)
5131{
5132 InitEffectExecuteData(effIndex);
5133 *m_effectExecuteData[effIndex] << target->GetPackGUID();
5134}

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 
)
5070{
5071 InitEffectExecuteData(effIndex);
5072 *m_effectExecuteData[effIndex] << target->GetPackGUID();
5073 *m_effectExecuteData[effIndex] << uint32(powerTaken);
5074 *m_effectExecuteData[effIndex] << uint32(PowerType);
5075 *m_effectExecuteData[effIndex] << float(gainMultiplier);
5076}

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 
)
5125{
5126 InitEffectExecuteData(effIndex);
5127 *m_effectExecuteData[effIndex] << obj->GetPackGUID();
5128}

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

Referenced by EffectDismissPet().

◆ finish()

void Spell::finish ( bool  ok = true)
4450{
4451 if (!m_caster)
4452 return;
4453
4455 return;
4457
4458 if (m_spellInfo->IsChanneled())
4460
4463
4464 // Unsummon summon as possessed creatures on spell cancel
4466 {
4467 if (Unit* charm = m_caster->GetCharm())
4468 if (charm->GetTypeId() == TYPEID_UNIT
4469 && charm->ToCreature()->HasUnitTypeMask(UNIT_MASK_PUPPET)
4470 && charm->GetUInt32Value(UNIT_CREATED_BY_SPELL) == m_spellInfo->Id)
4471 ((Puppet*)charm)->UnSummon();
4472 }
4473
4474 if (Creature* creatureCaster = m_caster->ToCreature())
4475 creatureCaster->ReleaseFocus(this);
4476
4477 if (!ok)
4478 {
4480 {
4481 // Xinef: Restore spell mods in case of fail cast
4483
4484 // Xinef: Reset cooldown event in case of fail cast
4487 }
4488 return;
4489 }
4490
4491 // pussywizard:
4494
4496 {
4497 // Unsummon statue
4499 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spell);
4500 if (spellInfo && spellInfo->SpellIconID == 2056)
4501 {
4502 LOG_DEBUG("spells.aura", "Statue {} is unsummoned in spell {} finish", m_caster->GetGUID().ToString(), m_spellInfo->Id);
4504 return;
4505 }
4506 }
4507
4508 // potions disabled by client, send event "not in combat" if need
4511
4512 // Take mods after trigger spell (needed for 14177 to affect 48664)
4513 // mods are taken only on succesfull cast and independantly from targets of the spell
4514 if (Player* player = m_caster->GetSpellModOwner())
4515 player->RemoveSpellMods(this);
4516
4517 // xinef: clear reactive auras states after spell cast
4520
4521 // Stop Attack for some spells
4524}
@ UNIT_MASK_PUPPET
Definition: Unit.h:681
@ JUST_DIED
Definition: Unit.h:317
@ ENCOUNTER_CREDIT_CAST_SPELL
Definition: Map.h:308
@ SPELL_ATTR0_CU_ENCOUNTER_REWARD
Definition: SpellInfo.h:206
@ AURA_STATE_DEFENSE
Definition: SharedDefines.h:1264
@ AURA_STATE_HUNTER_PARRY
Definition: SharedDefines.h:1270
Definition: TemporarySummon.h:114
void UpdatePotionCooldown(Spell *spell=nullptr)
Definition: PlayerUpdates.cpp:1498
virtual void setDeathState(DeathState s, bool despawn=false)
Definition: Unit.cpp:14447
void UpdateInterruptMask()
Definition: Unit.cpp:759
void ModifyAuraState(AuraStateType flag, bool apply)
Definition: Unit.cpp:10457
void UpdateEncounterState(EncounterCreditType type, uint32 creditEntry, Unit *source)
Definition: Map.cpp:3450

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::GetTypeId(), Object::GetUInt32Value(), SpellInfo::HasAttribute(), Unit::HasUnitState(), SpellInfo::Id, SpellInfo::IsChanneled(), SpellInfo::IsCooldownStartedOnEvent(), Unit::IsNonMeleeSpellCast(), Unit::IsSummon(), JUST_DIED, LOG_DEBUG, m_caster, m_spellInfo, m_spellState, m_triggeredByAuraSpell, Unit::ModifyAuraState(), 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(), TYPEID_PLAYER, TYPEID_UNIT, 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::HandlePetActionHelper(), WorldSession::HandlePetCastSpellOpcode(), prepare(), SelectImplicitCasterDestTargets(), SelectSpellTargets(), and update().

◆ FinishTargetProcessing()

void Spell::FinishTargetProcessing ( )
protected
8429{
8431}
void SendLogExecute()
Definition: Spell.cpp:5035

References SendLogExecute().

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

◆ GetCaster()

Unit * Spell::GetCaster ( ) const
inline

◆ GetCastTime()

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

References m_casttime.

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

◆ GetCurrentContainer()

CurrentSpellTypes Spell::GetCurrentContainer ( ) const

◆ GetDebugInfo()

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

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

◆ GetDelayMoment()

uint64 Spell::GetDelayMoment ( ) const
inline

◆ GetDelayStart()

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

References m_delayStart.

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

◆ GetDelayTrajectory()

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

References m_delayTrajectory.

◆ GetOriginalCaster()

Unit * Spell::GetOriginalCaster ( ) const
inline

◆ GetPowerCost()

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

References m_powerCost.

Referenced by Unit::HandleDummyAuraProc().

◆ GetSearcherTypeMask()

uint32 Spell::GetSearcherTypeMask ( SpellTargetObjectTypes  objType,
ConditionList condList 
)
2095{
2096 // this function selects which containers need to be searched for spell target
2098
2099 // filter searchers based on searched object type
2100 switch (objType)
2101 {
2108 break;
2112 break;
2113 default:
2114 break;
2115 }
2117 retMask &= ~GRID_MAP_TYPE_MASK_CORPSE;
2121 retMask &= GRID_MAP_TYPE_MASK_PLAYER;
2122
2123 if (condList)
2124 retMask &= sConditionMgr->GetSearcherTypeMaskForConditionList(*condList);
2125 return retMask;
2126}
@ GRID_MAP_TYPE_MASK_PLAYER
Definition: GridDefines.h:73
@ GRID_MAP_TYPE_MASK_CREATURE
Definition: GridDefines.h:70
@ GRID_MAP_TYPE_MASK_ALL
Definition: GridDefines.h:74
@ GRID_MAP_TYPE_MASK_GAMEOBJECT
Definition: GridDefines.h:72
@ GRID_MAP_TYPE_MASK_CORPSE
Definition: GridDefines.h:69
@ 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
@ SPELL_ATTR2_ALLOW_DEAD_TARGET
Definition: SharedDefines.h:428
@ SPELL_ATTR3_ONLY_ON_GHOSTS
Definition: SharedDefines.h:477
@ SPELL_ATTR3_ONLY_ON_PLAYER
Definition: SharedDefines.h:473

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

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

◆ GetSpellInfo()

◆ GetSpellSchoolMask()

SpellSchoolMask Spell::GetSpellSchoolMask ( ) const
inline

◆ GetSpellValue()

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

References m_spellValue.

Referenced by DoAllEffectOnTarget().

◆ getState()

◆ GetTriggeredByAuraTickNumber()

uint32 Spell::GetTriggeredByAuraTickNumber ( ) const
inline

◆ GetTriggeredCastFlags()

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

References _triggeredCastFlags.

◆ GetUniqueTargetInfo()

◆ handle_delayed()

uint64 Spell::handle_delayed ( uint64  t_offset)
4147{
4148 if (!UpdatePointers())
4149 {
4150 // finish the spell if UpdatePointers() returned false, something wrong happened there
4151 finish(false);
4152 return 0;
4153 }
4154
4155 Player* modOwner = m_caster->GetSpellModOwner();
4156 if (modOwner)
4157 modOwner->SetSpellModTakingSpell(this, true);
4158
4159 uint64 next_time = m_delayTrajectory;
4160
4162
4163 if (!m_immediateHandled && m_delayTrajectory <= t_offset)
4164 {
4166 m_immediateHandled = true;
4168 next_time = 0;
4169 }
4170
4171 bool single_missile = (m_targets.HasDst());
4172
4173 // 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)
4174 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
4175 {
4176 if (ihit->processed == false)
4177 {
4178 if (single_missile || ihit->timeDelay <= t_offset)
4179 {
4180 ihit->timeDelay = t_offset;
4181 DoAllEffectOnTarget(&(*ihit));
4182 }
4183 else if (next_time == 0 || ihit->timeDelay < next_time)
4184 next_time = ihit->timeDelay;
4185 }
4186 }
4187
4188 // now recheck gameobject targeting correctness
4189 for (std::list<GOTargetInfo>::iterator ighit = m_UniqueGOTargetInfo.begin(); ighit != m_UniqueGOTargetInfo.end(); ++ighit)
4190 {
4191 if (ighit->processed == false)
4192 {
4193 if (single_missile || ighit->timeDelay <= t_offset)
4194 DoAllEffectOnTarget(&(*ighit));
4195 else if (next_time == 0 || ighit->timeDelay < next_time)
4196 next_time = ighit->timeDelay;
4197 }
4198 }
4199
4201
4202 if (modOwner)
4203 modOwner->SetSpellModTakingSpell(this, false);
4204
4205 // All targets passed - need finish phase
4206 if (next_time == 0)
4207 {
4208 // spell is finished, perform some last features of the spell here
4210
4211 finish(true); // successfully finish spell cast
4212
4213 // return zero, spell is finished now
4214 return 0;
4215 }
4216 else
4217 {
4218 // spell is unfinished, return next execution time
4219 return next_time;
4220 }
4221}
void _handle_finish_phase()
Definition: Spell.cpp:4251
void PrepareTargetProcessing()
Definition: Spell.cpp:8423
void _handle_immediate_phase()
Definition: Spell.cpp:4223
void FinishTargetProcessing()
Definition: Spell.cpp:8428

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 ( )
4090{
4091 // start channeling if applicable
4092 if (m_spellInfo->IsChanneled())
4093 {
4094 int32 duration = m_spellInfo->GetDuration();
4095 if (duration > 0)
4096 {
4097 // First mod_duration then haste - see Missile Barrage
4098 // Apply duration mod
4099 if (Player* modOwner = m_caster->GetSpellModOwner())
4100 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_DURATION, duration);
4101
4102 // Apply haste mods
4104 duration = int32(duration * m_caster->GetFloatValue(UNIT_MOD_CAST_SPEED));
4105
4108 m_channeledDuration = duration;
4109 SendChannelStart(duration);
4110 }
4111 else if (duration == -1)
4112 {
4115 SendChannelStart(duration);
4116 }
4117 }
4118
4120
4121 // process immediate effects (items, ground, etc.) also initialize some variables
4123
4124 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
4125 DoAllEffectOnTarget(&(*ihit));
4126
4127 for (std::list<GOTargetInfo>::iterator ihit = m_UniqueGOTargetInfo.begin(); ihit != m_UniqueGOTargetInfo.end(); ++ihit)
4128 DoAllEffectOnTarget(&(*ihit));
4129
4131
4132 // spell is finished, perform some last features of the spell here
4134
4135 // Remove used for cast item if need (it can be already nullptr after TakeReagents call
4136 TakeCastItem();
4137
4138 // handle ammo consumption for Hunter's volley spell
4140 TakeAmmo();
4141
4143 finish(true); // successfully finish spell cast (not last in case autorepeat or channel spell)
4144}
void AddInterruptMask(uint32 mask)
Definition: Unit.h:2163
void SendChannelStart(uint32 duration)
Definition: Spell.cpp:5168
void TakeAmmo()
Definition: Spell.cpp:5341

References _handle_finish_phase(), _handle_immediate_phase(), Unit::AddInterruptMask(), SpellInfo::ChannelInterruptFlags, DoAllEffectOnTarget(), finish(), FinishTargetProcessing(), SpellInfo::GetDuration(), Object::GetFloatValue(), Unit::GetSpellModOwner(), SpellInfo::HasAttribute(), Unit::HasAuraTypeWithAffectMask(), 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(), and UNIT_MOD_CAST_SPEED.

Referenced by _cast().

◆ HandleEffects()

void Spell::HandleEffects ( Unit pUnitTarget,
Item pItemTarget,
GameObject pGOTarget,
uint32  i,
SpellEffectHandleMode  mode 
)
5590{
5591 effectHandleMode = mode;
5592 unitTarget = pUnitTarget;
5593 itemTarget = pItemTarget;
5594 gameObjTarget = pGOTarget;
5596
5597 uint8 eff = m_spellInfo->Effects[i].Effect;
5598
5599 LOG_DEBUG("spells.aura", "Spell: {} Effect : {}", m_spellInfo->Id, eff);
5600
5601 // we do not need DamageMultiplier here.
5602 damage = CalculateSpellDamage(i, nullptr);
5603
5604 bool preventDefault = CallScriptEffectHandlers((SpellEffIndex)i, mode);
5605
5606 if (!preventDefault && eff < TOTAL_SPELL_EFFECTS)
5607 {
5608 (this->*SpellEffects[eff])((SpellEffIndex)i);
5609 }
5610}
SpellEffIndex
Definition: SharedDefines.h:29
SpellEffects
Definition: SharedDefines.h:750
@ TOTAL_SPELL_EFFECTS
Definition: SharedDefines.h:915
WorldLocation _position
Definition: Spell.h:103
bool CallScriptEffectHandlers(SpellEffIndex effIndex, SpellEffectHandleMode mode)
Definition: Spell.cpp:8542

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

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

◆ HandleLaunchPhase()

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

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 ( )
5543{
5544 if (m_UniqueTargetInfo.empty())
5545 return;
5546
5548 return;
5549
5550 float threat = 0.0f;
5551 if (SpellThreatEntry const* threatEntry = sSpellMgr->GetSpellThreatEntry(m_spellInfo->Id))
5552 {
5553 if (threatEntry->apPctMod != 0.0f)
5554 threat += threatEntry->apPctMod * m_caster->GetTotalAttackPowerValue(BASE_ATTACK);
5555
5556 threat += threatEntry->flatMod;
5557 }
5559 threat += m_spellInfo->SpellLevel;
5560
5561 // past this point only multiplicative effects occur
5562 if (threat == 0.0f)
5563 return;
5564
5565 // 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
5566 threat /= m_UniqueTargetInfo.size();
5567
5568 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
5569 {
5570 float threatToAdd = threat;
5571 if (ihit->missCondition != SPELL_MISS_NONE)
5572 threatToAdd = 0.0f;
5573
5574 Unit* target = ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID);
5575 if (!target)
5576 continue;
5577
5578 bool IsFriendly = m_caster->IsFriendlyTo(target);
5579 // positive spells distribute threat among all units that are in combat with target, like healing
5581 target->getHostileRefMgr().threatAssist(m_caster, threatToAdd, m_spellInfo);
5582 // for negative spells threat gets distributed among affected targets
5583 else if (!m_spellInfo->_IsPositiveSpell() && !IsFriendly && target->CanHaveThreatList())
5584 target->AddThreat(m_caster, threatToAdd, m_spellInfo->GetSchoolMask(), m_spellInfo);
5585 }
5586 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()));
5587}
@ SPELL_ATTR0_CU_NO_INITIAL_THREAT
Definition: SpellInfo.h:180
static bool IsFriendly(Creature *piece, Creature *target)
Definition: boss_chess_event.cpp:181
bool _IsPositiveSpell() const
Definition: SpellInfo.cpp:2823
Definition: SpellMgr.h:378

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_SUPRESS_TARGET_PROCS, SPELL_MISS_NONE, SpellInfo::SpellLevel, sSpellMgr, and HostileRefMgr::threatAssist().

Referenced by _handle_immediate_phase().

◆ HasGlobalCooldown()

bool Spell::HasGlobalCooldown ( ) const
protected

◆ HaveTargetsForEffect()

bool Spell::HaveTargetsForEffect ( uint8  effect) const
8062{
8063 for (std::list<TargetInfo>::const_iterator itr = m_UniqueTargetInfo.begin(); itr != m_UniqueTargetInfo.end(); ++itr)
8064 if (itr->effectMask & (1 << effect))
8065 return true;
8066
8067 for (std::list<GOTargetInfo>::const_iterator itr = m_UniqueGOTargetInfo.begin(); itr != m_UniqueGOTargetInfo.end(); ++itr)
8068 if (itr->effectMask & (1 << effect))
8069 return true;
8070
8071 for (std::list<ItemTargetInfo>::const_iterator itr = m_UniqueItemInfo.begin(); itr != m_UniqueItemInfo.end(); ++itr)
8072 if (itr->effectMask & (1 << effect))
8073 return true;
8074
8075 return false;
8076}

References m_UniqueGOTargetInfo, m_UniqueItemInfo, and m_UniqueTargetInfo.

◆ InitEffectExecuteData()

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

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

References SpellInfo::CheckExplicitTarget(), SpellInfo::GetExplicitTargetMask(), SpellCastTargets::GetObjectTarget(), Unit::GetTarget(), Object::GetTypeId(), ObjectAccessor::GetUnit(), Unit::GetVictim(), SpellCastTargets::HasDst(), SpellCastTargets::HasSrc(), 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, Object::ToPlayer(), and TYPEID_UNIT.

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?
8039{
8042 {
8043 return false;
8044 }
8045
8047 {
8048 return false;
8049 }
8050
8051 return true;
8052}
@ SPELL_ATTR6_DOESNT_RESET_SWING_TIMER_IF_INSTANT
Definition: SharedDefines.h:601

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
628 {
629 if (m_delayAtDamageCount >= 2)
630 return true;
631
633 return false;
634 }

References m_delayAtDamageCount.

Referenced by Delayed(), and DelayedChannel().

◆ IsDeletable()

◆ IsIgnoringCooldowns()

bool Spell::IsIgnoringCooldowns ( ) const

◆ IsInterruptable()

bool Spell::IsInterruptable ( ) const
inline
559{ 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
8184{
8185 if (target->IsAlive())
8187
8189}
bool IsRequiringDeadTarget() const
Definition: SpellInfo.cpp:1206
bool IsAllowingDeadTarget() const
Definition: SpellInfo.cpp:1211

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

Referenced by UpdateChanneledTargetList().

◆ LoadScripts()

void Spell::LoadScripts ( )
8457{
8458 if (_scriptsLoaded)
8459 return;
8460 _scriptsLoaded = true;
8461 sScriptMgr->CreateSpellScripts(m_spellInfo->Id, m_loadedScripts);
8462 for (std::list<SpellScript*>::iterator itr = m_loadedScripts.begin(); itr != m_loadedScripts.end();)
8463 {
8464 if (!(*itr)->_Load(this))
8465 {
8466 std::list<SpellScript*>::iterator bitr = itr;
8467 ++itr;
8468 delete (*bitr);
8469 m_loadedScripts.erase(bitr);
8470 continue;
8471 }
8472 LOG_DEBUG("spells.aura", "Spell::LoadScripts: Script `{}` for spell `{}` is loaded now", (*itr)->_GetScriptName()->c_str(), m_spellInfo->Id);
8473 (*itr)->Register();
8474 ++itr;
8475 }
8476}

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

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 &&

3451{
3452 if (m_CastItem)
3453 {
3455 }
3456 else
3457 {
3459 }
3460
3461 InitExplicitTargets(*targets);
3462
3463 if (!sScriptMgr->CanPrepare(this, targets, triggeredByAura))
3464 {
3465 finish(false);
3466 return SPELL_FAILED_UNKNOWN;
3467 }
3468
3469 // Fill aura scaling information
3471 {
3472 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
3473 {
3474 if (m_spellInfo->Effects[i].Effect == SPELL_EFFECT_APPLY_AURA ||
3477 {
3478 // Change aura with ranks only if basepoints are taken from spellInfo and aura is positive
3480 {
3481 m_auraScaleMask |= (1 << i);
3482 if (m_spellValue->EffectBasePoints[i] != m_spellInfo->Effects[i].BasePoints)
3483 {
3484 m_auraScaleMask = 0;
3485 break;
3486 }
3487 }
3488 }
3489 }
3490 }
3491
3493
3494 if (triggeredByAura)
3495 {
3496 m_triggeredByAuraSpell.Init(triggeredByAura);
3497 }
3498
3499 // create and add update event for this spell
3500 _spellEvent = new SpellEvent(this);
3502
3504 {
3506 finish(false);
3508 }
3509
3510 //Prevent casting at cast another spell (ServerSide check)
3512 {
3514 finish(false);
3516 }
3517
3518 LoadScripts();
3519
3520 OnSpellLaunch();
3521
3523
3524 // Set combo point requirement
3526 m_needComboPoints = false;
3527
3528 SpellCastResult result = CheckCast(true);
3529 if (result != SPELL_CAST_OK && !IsAutoRepeat()) //always cast autorepeat dummy for triggering
3530 {
3531 // Periodic auras should be interrupted when aura triggers a spell which can't be cast
3532 // for example bladestorm aura should be removed on disarm as of patch 3.3.5
3533 // channeled periodic spells should be affected by this (arcane missiles, penance, etc)
3534 // a possible alternative sollution for those would be validating aura target on unit state change
3535 if (m_caster->GetTypeId() == TYPEID_PLAYER && triggeredByAura && triggeredByAura->IsPeriodic() && !triggeredByAura->GetBase()->IsPassive())
3536 {
3538 triggeredByAura->GetBase()->SetDuration(0);
3539 }
3540
3541 // Allows to cast melee attack spell if result is SPELL_FAILED_OUT_OF_RANGE
3543 {
3544 SendCastResult(result);
3545
3546 finish(false);
3547 return result;
3548 }
3549 }
3550
3551 // Prepare data for triggers
3552 prepareDataForTriggerSystem(triggeredByAura);
3553
3554 // calculate cast time (calculated after first CheckCast check to prevent charge counting for first CheckCast fail)
3556
3559 m_casttime = 0;
3560
3561 // don't allow channeled spells / spells with cast time to be casted while moving
3562 // (even if they are interrupted on moving, spells with almost immediate effect get to have their effect processed before movement interrupter kicks in)
3564 {
3565 // 1. Has casttime, 2. Or doesn't have flag to allow action during channel
3567 {
3569 finish(false);
3570 return SPELL_FAILED_MOVING;
3571 }
3572 }
3573
3574 // xinef: if spell have nearby target entry only, do not allow to cast if no targets are found
3575 if (m_CastItem)
3576 {
3577 bool selectTargets = false;
3578 bool nearbyDest = false;
3579
3580 for (uint8 i = EFFECT_0; i < MAX_SPELL_EFFECTS; ++i)
3581 {
3582 if (!m_spellInfo->Effects[i].IsEffect())
3583 continue;
3584
3585 if (m_spellInfo->Effects[i].TargetA.GetSelectionCategory() != TARGET_SELECT_CATEGORY_NEARBY || m_spellInfo->Effects[i].TargetA.GetCheckType() != TARGET_CHECK_ENTRY)
3586 {
3587 selectTargets = false;
3588 break;
3589 }
3590
3591 if (m_spellInfo->Effects[i].TargetA.GetObjectType() == TARGET_OBJECT_TYPE_DEST)
3592 {
3593 nearbyDest = true;
3594 }
3595
3596 // xinef: by default set it to false, and to true if any valid target is found
3597 selectTargets = true;
3598 }
3599
3600 if (selectTargets)
3601 {
3603 _spellTargetsSelected = true;
3604 bool spellFailed = false;
3605
3606 if (m_UniqueTargetInfo.empty() && m_UniqueGOTargetInfo.empty())
3607 {
3608 // no valid nearby target unit or game object found; check if nearby destination type
3609 if (nearbyDest)
3610 {
3611 if (!m_targets.HasDst())
3612 {
3613 // no valid target destination
3614 spellFailed = true;
3615 }
3616 }
3617 else
3618 {
3619 spellFailed = true;
3620 }
3621 }
3622
3623 if (spellFailed)
3624 {
3626 finish(false);
3628 }
3629 }
3630 }
3631
3632 // set timer base at cast time
3633 ReSetTimer();
3634
3635 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());
3636
3638 {
3640 }
3641
3642 //Containers for channeled spells have to be set
3643 //TODO:Apply this to all casted spells if needed
3644 // Why check duration? 29350: channelled triggers channelled
3646 cast(true);
3647 else
3648 {
3649 // stealth must be removed at cast starting (at show channel bar)
3650 // skip triggered spell (item equip spell casting and other not explicit character casts/item uses)
3652 {
3653 // Farsight spells exception
3654 uint32 exceptSpellId = 0;
3656 {
3657 exceptSpellId = m_spellInfo->Id;
3658 }
3659
3662 }
3663
3666
3667 // set target for proper facing
3669 {
3672 {
3673 // Xinef: Creature should focus to cast target if there is explicit target or self if casting positive spell
3674 // Xinef: Creature should not rotate when casting spell... based on halion behavior
3676 }
3677 }
3678
3679 //item: first cast may destroy item and second cast causes crash
3680 // xinef: removed !m_spellInfo->StartRecoveryTime
3681 // second los check failed in events
3682 // xinef: removed itemguid check, currently there is no such item in database
3684 cast(true);
3685
3688 }
3689
3690 return SPELL_CAST_OK;
3691}
@ CHEAT_CASTTIME
Definition: Player.h:992
@ AURA_INTERRUPT_FLAG_SPELL_ATTACK
Definition: SpellDefines.h:57
@ AURA_INTERRUPT_FLAG_CAST
Definition: SpellDefines.h:46
@ TRIGGERED_IGNORE_AURA_SCALING
Will not take away cast item or update related achievement criteria.
Definition: SpellDefines.h:136
@ TRIGGERED_IGNORE_AURA_INTERRUPT_FLAGS
In Spell::prepare, will be cast directly without setting containers for executed spell.
Definition: SpellDefines.h:140
@ TRIGGERED_IGNORE_COMBO_POINTS
Will not check if a current cast is in progress.
Definition: SpellDefines.h:138
@ SPELL_INTERRUPT_FLAG_MOVEMENT
Definition: SpellDefines.h:27
@ TARGET_SELECT_CATEGORY_NEARBY
Definition: SpellInfo.h:80
@ TARGET_OBJECT_TYPE_DEST
Definition: SpellInfo.h:100
@ SPELL_EFFECT_APPLY_AREA_AURA_PARTY
Definition: SharedDefines.h:785
@ SPELL_EFFECT_APPLY_AREA_AURA_RAID
Definition: SharedDefines.h:815
@ SPELL_ATTR0_ALLOW_WHILE_SITTING
Definition: SharedDefines.h:381
void FocusTarget(Spell const *focusSpell, WorldObject const *target)
Definition: Creature.cpp:3430
void SetCurrentCastedSpell(Spell *pSpell)
Definition: Unit.cpp:3909
bool IsSitState() const
Definition: Unit.cpp:16885
Definition: Spell.cpp:513
void Init(AuraEffect const *aurEff)
Definition: Spell.cpp:8884
void LoadScripts()
Definition: Spell.cpp:8456
void cast(bool skipCheck=false)
Definition: Spell.cpp:3765
void prepareDataForTriggerSystem(AuraEffect const *triggeredByAura)
Definition: Spell.cpp:2276
void SendSpellStart()
Definition: Spell.cpp:4679
void TriggerGlobalCooldown()
Definition: Spell.cpp:8800
void OnSpellLaunch()
Definition: Spell.cpp:8861
CurrentSpellTypes GetCurrentContainer() const
Definition: Spell.cpp:7874
void ReSetTimer()
Definition: Spell.h:550
void InitExplicitTargets(SpellCastTargets const &targets)
Definition: Spell.cpp:707
bool IsActionAllowedChannel() const
Definition: SpellInfo.cpp:1245
int32 GetMaxDuration() const
Definition: SpellInfo.cpp:2328
uint32 Attributes
Definition: SpellInfo.h:322
bool IsBreakingStealth() const
Definition: SpellInfo.cpp:1255

References _spellEvent, _spellTargetsSelected, _triggeredCastFlags, EventProcessor::AddEvent(), SpellInfo::Attributes, AURA_INTERRUPT_FLAG_CAST, AURA_INTERRUPT_FLAG_NOT_SEATED, AURA_INTERRUPT_FLAG_SPELL_ATTACK, SpellInfo::AuraInterruptFlags, SpellInfo::CalcCastTime(), SpellInfo::CalcPowerCost(), EventProcessor::CalculateTime(), cast(), CHEAT_CASTTIME, CheckCast(), CURRENT_GENERIC_SPELL, DISABLE_TYPE_SPELL, EFFECT_0, SpellValue::EffectBasePoints, SpellInfo::Effects, ObjectGuid::Empty, finish(), Creature::FocusTarget(), AuraEffect::GetBase(), Player::GetCommandStatus(), GetCurrentContainer(), Object::GetEntry(), Object::GetGUID(), SpellInfo::GetMaxDuration(), SpellCastTargets::GetObjectTarget(), SpellCastTargets::GetTargetMask(), Object::GetTypeId(), SpellCastTargets::HasDst(), SpellInfo::HasEffect(), SpellInfo::Id, TriggeredByAuraSpellData::Init(), InitExplicitTargets(), SpellInfo::InterruptFlags, SpellInfo::IsActionAllowedChannel(), IsAutoRepeat(), SpellInfo::IsBreakingStealth(), SpellInfo::IsChanneled(), Unit::IsControlledByPlayer(), DisableMgr::IsDisabledFor(), Creature::IsInEvadeMode(), Unit::isMoving(), IsNextMeleeSwingSpell(), Unit::IsNonMeleeSpellCast(), Aura::IsPassive(), SpellInfo::IsPassive(), AuraEffect::IsPeriodic(), 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, Unit::m_Events, m_needComboPoints, m_originalCaster, m_powerCost, m_spellInfo, m_spellSchoolMask, m_spellState, m_spellValue, m_targets, m_triggeredByAuraSpell, m_UniqueGOTargetInfo, m_UniqueTargetInfo, MAX_SPELL_EFFECTS, OnSpellLaunch(), prepareDataForTriggerSystem(), Unit::RemoveAurasWithInterruptFlags(), ReSetTimer(), SelectSpellTargets(), SendCastResult(), SendChannelUpdate(), SendSpellStart(), Unit::SetCurrentCastedSpell(), Aura::SetDuration(), Unit::SetStandState(), SPELL_ATTR0_ALLOW_WHILE_SITTING, SPELL_CAST_OK, SPELL_EFFECT_ADD_FARSIGHT, SPELL_EFFECT_APPLY_AREA_AURA_PARTY, SPELL_EFFECT_APPLY_AREA_AURA_RAID, SPELL_EFFECT_APPLY_AURA, SPELL_FAILED_CASTER_AURASTATE, SPELL_FAILED_MOVING, SPELL_FAILED_OUT_OF_RANGE, SPELL_FAILED_SPELL_IN_PROGRESS, SPELL_FAILED_SPELL_UNAVAILABLE, SPELL_FAILED_UNKNOWN, SPELL_INTERRUPT_FLAG_MOVEMENT, SPELL_STATE_PREPARING, SpellInfo::SpellLevel, sScriptMgr, TARGET_CHECK_ENTRY, TARGET_OBJECT_TYPE_DEST, TARGET_SELECT_CATEGORY_NEARBY, Object::ToCreature(), Object::ToPlayer(), TRIGGERED_CAST_DIRECTLY, TRIGGERED_IGNORE_AURA_INTERRUPT_FLAGS, TRIGGERED_IGNORE_AURA_SCALING, TRIGGERED_IGNORE_CAST_IN_PROGRESS, TRIGGERED_IGNORE_COMBO_POINTS, TRIGGERED_IGNORE_GCD, TRIGGERED_IGNORE_SET_FACING, TriggerGlobalCooldown(), TYPEID_PLAYER, TYPEID_UNIT, 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
2277{
2278 //==========================================================================================
2279 // Now fill data for trigger system, need know:
2280 // can spell trigger another or not (m_canTrigger)
2281 // Create base triggers flags for Attacker and Victim (m_procAttacker, m_procVictim and m_procEx)
2282 //==========================================================================================
2283
2285 // Get data for type of attack and fill base info for trigger
2286 switch (m_spellInfo->DmgClass)
2287 {
2290 if (m_attackType == OFF_ATTACK)
2292 else
2295 break;
2297 // Auto attack
2299 {
2302 }
2303 else // Ranged spell attack
2304 {
2307 }
2308 break;
2309 default:
2312 && m_spellInfo->HasAttribute(SPELL_ATTR2_AUTO_REPEAT)) // Wands auto attack
2313 {
2316 }
2317 // For other spells trigger procflags are set in Spell::DoAllEffectOnTarget
2318 // Because spell positivity is dependant on target
2319 }
2321
2322 // Hunter trap spells - activation proc for Lock and Load, Entrapment and Misdirection
2324 (m_spellInfo->SpellFamilyFlags[0] & 0x18 || // Freezing and Frost Trap, Freezing Arrow
2325 m_spellInfo->Id == 57879 || m_spellInfo->Id == 45145 || // Snake Trap - done this way to avoid double proc
2326 m_spellInfo->SpellFamilyFlags[2] & 0x00064000)) // Explosive and Immolation Trap
2327 {
2329 }
2330
2331 /* Effects which are result of aura proc from triggered spell cannot proc
2332 to prevent chain proc of these spells */
2333
2334 // Hellfire Effect - trigger as DOT
2336 {
2339 }
2340
2341 // Ranged autorepeat attack is set as triggered spell - ignore it
2343 {
2350 }
2351 // Totem casts require spellfamilymask defined in spell_proc_event to proc
2354}
@ TRIGGERED_DISALLOW_PROC_EVENTS
Will ignore caster aura restrictions or requirements.
Definition: SpellDefines.h:146
@ 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
@ SPELL_ATTR2_ACTIVE_THREAT
Definition: SharedDefines.h:458
@ SPELL_ATTR3_NOT_A_PROC
Definition: SharedDefines.h:474

References _triggeredCastFlags, SpellInfo::DmgClass, SpellInfo::EquippedItemClass, SpellInfo::EquippedItemSubClassMask, Object::GetTypeId(), SpellInfo::HasAttribute(), SpellInfo::Id, Unit::IsControlledByPlayer(), 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(), TRIGGERED_DISALLOW_PROC_EVENTS, and TYPEID_UNIT.

Referenced by prepare().

◆ PrepareScriptHitHandlers()

void Spell::PrepareScriptHitHandlers ( )
protected
8537{
8538 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8539 (*scritr)->_InitHit();
8540}

References m_loadedScripts.

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

◆ PrepareTargetProcessing()

void Spell::PrepareTargetProcessing ( )
protected

◆ PrepareTriggersExecutedOnHit()

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

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 ( )
911{
914}
std::chrono::milliseconds Milliseconds
Milliseconds shorthand typedef.
Definition: Duration.h:27
void ModifyEventTime(BasicEvent *event, Milliseconds newTime)
Definition: EventProcessor.cpp:144
uint64 CalculateDelayMomentForDst() const
Definition: Spell.cpp:889
uint64 GetDelayStart() const
Definition: Spell.h:561

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

◆ ReSetTimer()

void Spell::ReSetTimer ( )
inline
550{ 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 
)
2171{
2172 uint32 containerTypeMask = GetSearcherTypeMask(objectType, condList);
2173 if (!containerTypeMask)
2174 return;
2175 Acore::WorldObjectSpellAreaTargetCheck check(range, position, m_caster, referer, m_spellInfo, selectionType, condList);
2176 Acore::WorldObjectListSearcher<Acore::WorldObjectSpellAreaTargetCheck> searcher(m_caster, targets, check, containerTypeMask);
2177 SearchTargets<Acore::WorldObjectListSearcher<Acore::WorldObjectSpellAreaTargetCheck> > (searcher, containerTypeMask, m_caster, position, range);
2178}
Definition: GridNotifiers.h:236
uint32 GetSearcherTypeMask(SpellTargetObjectTypes objType, ConditionList *condList)
Definition: Spell.cpp:2094

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

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

Referenced by SelectImplicitChainTargets().

◆ SearchNearbyTarget()

WorldObject * Spell::SearchNearbyTarget ( float  range,
SpellTargetObjectTypes  objectType,
SpellTargetCheckTypes  selectionType,
ConditionList condList = nullptr 
)
2159{
2160 WorldObject* target = nullptr;
2161 uint32 containerTypeMask = GetSearcherTypeMask(objectType, condList);
2162 if (!containerTypeMask)
2163 return nullptr;
2164 Acore::WorldObjectSpellNearbyTargetCheck check(range, m_caster, m_spellInfo, selectionType, condList);
2166 SearchTargets<Acore::WorldObjectLastSearcher<Acore::WorldObjectSpellNearbyTargetCheck> > (searcher, containerTypeMask, m_caster, m_caster, range);
2167 return target;
2168}
Definition: GridNotifiers.h:216

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 
)
2130{
2131 if (!containerMask)
2132 return;
2133
2134 // search world and grid for possible targets
2135 bool searchInGrid = containerMask & (GRID_MAP_TYPE_MASK_CREATURE | GRID_MAP_TYPE_MASK_GAMEOBJECT);
2136 bool searchInWorld = containerMask & (GRID_MAP_TYPE_MASK_CREATURE | GRID_MAP_TYPE_MASK_PLAYER | GRID_MAP_TYPE_MASK_CORPSE);
2137
2138 if (searchInGrid || searchInWorld)
2139 {
2140 float x, y;
2141 x = pos->GetPositionX();
2142 y = pos->GetPositionY();
2143
2145 Cell cell(p);
2146 cell.SetNoCreate();
2147
2148 Map* map = referer->GetMap();
2149
2150 if (searchInWorld)
2151 Cell::VisitWorldObjects(x, y, map, searcher, radius);
2152
2153 if (searchInGrid)
2154 Cell::VisitGridObjects(x, y, map, searcher, radius);
2155 }
2156}
static void VisitGridObjects(WorldObject const *obj, T &visitor, float radius, bool dont_load=true)
Definition: CellImpl.h:179

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

◆ SelectEffectImplicitTargets()

void Spell::SelectEffectImplicitTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType,
uint32 processedEffectMask 
)
917{
918 if (!targetType.GetTarget())
919 return;
920
921 uint32 effectMask = 1 << effIndex;
922 // set the same target list for all effects
923 // some spells appear to need this, however this requires more research
924 switch (targetType.GetSelectionCategory())
925 {
929 {
930 // targets for effect already selected
931 if (effectMask & processedEffectMask)
932 {
933 return;
934 }
935
936 auto const& effects = GetSpellInfo()->Effects;
937
938 // choose which targets we can select at once
939 for (uint32 j = effIndex + 1; j < MAX_SPELL_EFFECTS; ++j)
940 {
941 if (effects[j].IsEffect() &&
942 effects[effIndex].TargetA.GetTarget() == effects[j].TargetA.GetTarget() &&
943 effects[effIndex].TargetB.GetTarget() == effects[j].TargetB.GetTarget() &&
944 effects[effIndex].ImplicitTargetConditions == effects[j].ImplicitTargetConditions &&
945 effects[effIndex].CalcRadius(m_caster) == effects[j].CalcRadius(m_caster) &&
947 {
948 effectMask |= 1 << j;
949 }
950 }
951 processedEffectMask |= effectMask;
952 break;
953 }
954 default:
955 break;
956 }
957
958 switch (targetType.GetSelectionCategory())
959 {
961 SelectImplicitChannelTargets(effIndex, targetType);
962 break;
964 SelectImplicitNearbyTargets(effIndex, targetType, effectMask);
965 break;
967 SelectImplicitConeTargets(effIndex, targetType, effectMask);
968 break;
970 SelectImplicitAreaTargets(effIndex, targetType, effectMask);
971 break;
973 // just in case there is no dest, explanation in SelectImplicitDestDestTargets
974 CheckDst();
975
976 SelectImplicitTrajTargets(effIndex, targetType);
977 break;
979 switch (targetType.GetObjectType())
980 {
982 switch (targetType.GetReferenceType())
983 {
986 break;
987 default:
988 ASSERT(false && "Spell::SelectEffectImplicitTargets: received not implemented select target reference type for TARGET_TYPE_OBJECT_SRC");
989 break;
990 }
991 break;
993 switch (targetType.GetReferenceType())
994 {
996 SelectImplicitCasterDestTargets(effIndex, targetType);
997 break;
999 SelectImplicitTargetDestTargets(effIndex, targetType);
1000 break;
1002 SelectImplicitDestDestTargets(effIndex, targetType);
1003 break;
1004 default:
1005 ASSERT(false && "Spell::SelectEffectImplicitTargets: received not implemented select target reference type for TARGET_TYPE_OBJECT_DEST");
1006 break;
1007 }
1008 break;
1009 default:
1010 switch (targetType.GetReferenceType())
1011 {
1013 SelectImplicitCasterObjectTargets(effIndex, targetType);
1014 break;
1016 SelectImplicitTargetObjectTargets(effIndex, targetType);
1017 break;
1018 default:
1019 ASSERT(false && "Spell::SelectEffectImplicitTargets: received not implemented select target reference type for TARGET_TYPE_OBJECT");
1020 break;
1021 }
1022 break;
1023 }
1024 break;
1026 LOG_DEBUG("spells.aura", "SPELL: target type {}, found in spellID {}, effect {} is not implemented yet!", m_spellInfo->Id, effIndex, targetType.GetTarget());
1027 break;
1028 default:
1029 ASSERT(false && "Spell::SelectEffectImplicitTargets: received not implemented select target category");
1030 break;
1031 }
1032}
@ 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:1702
void CheckDst()
Definition: Spell.h:492
void SelectImplicitTrajTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition: Spell.cpp:1851
void SelectImplicitConeTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType, uint32 effMask)
Definition: Spell.cpp:1204
void SelectImplicitTargetDestTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition: Spell.cpp:1665
void SelectImplicitAreaTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType, uint32 effMask)
Definition: Spell.cpp:1254
void SelectImplicitChannelTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition: Spell.cpp:1034
void SelectImplicitTargetObjectTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition: Spell.cpp:1788
void SelectImplicitCasterObjectTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition: Spell.cpp:1741
void SelectImplicitNearbyTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType, uint32 effMask)
Definition: Spell.cpp:1090
bool CheckScriptEffectImplicitTargets(uint32 effIndex, uint32 effIndexToCheck)
Definition: Spell.cpp:8671
void SelectImplicitCasterDestTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition: Spell.cpp:1336

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
2012{
2013 // special case for SPELL_EFFECT_SUMMON_RAF_FRIEND and SPELL_EFFECT_SUMMON_PLAYER
2015 switch (m_spellInfo->Effects[effIndex].Effect)
2016 {
2020 {
2022
2024
2025 if (target && target->ToPlayer())
2026 AddUnitTarget(target->ToUnit(), 1 << effIndex, false);
2027 }
2028 return;
2029 default:
2030 break;
2031 }
2032
2033 // select spell implicit targets based on effect type
2034 if (!m_spellInfo->Effects[effIndex].GetImplicitTargetType())
2035 return;
2036
2037 uint32 targetMask = m_spellInfo->Effects[effIndex].GetMissingTargetMask();
2038
2039 if (!targetMask)
2040 return;
2041
2042 WorldObject* target = nullptr;
2043
2044 switch (m_spellInfo->Effects[effIndex].GetImplicitTargetType())
2045 {
2046 // add explicit object target or self to the target map
2048 // player which not released his spirit is Unit, but target flag for it is TARGET_FLAG_CORPSE_MASK
2050 {
2052 target = unitTarget;
2053 else if (targetMask & TARGET_FLAG_CORPSE_MASK)
2054 {
2055 if (Corpse* corpseTarget = m_targets.GetCorpseTarget())
2056 {
2058 if (Player* owner = ObjectAccessor::FindPlayer(corpseTarget->GetOwnerGUID()))
2059 target = owner;
2060 }
2061 }
2062 else //if (targetMask & TARGET_FLAG_UNIT_MASK)
2063 target = m_caster;
2064 }
2065 if (targetMask & TARGET_FLAG_ITEM_MASK)
2066 {
2068 AddItemTarget(itemTarget, 1 << effIndex);
2069 return;
2070 }
2071 if (targetMask & TARGET_FLAG_GAMEOBJECT_MASK)
2072 target = m_targets.GetGOTarget();
2073 break;
2074 // add self to the target map
2076 if (targetMask & TARGET_FLAG_UNIT_MASK)
2077 target = m_caster;
2078 break;
2079 default:
2080 break;
2081 }
2082
2084
2085 if (target)
2086 {
2087 if (target->ToUnit())
2088 AddUnitTarget(target->ToUnit(), 1 << effIndex, false);
2089 else if (target->ToGameObject())
2090 AddGOTarget(target->ToGameObject(), 1 << effIndex);
2091 }
2092}
@ 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:202
Corpse * GetCorpseTarget() const
Definition: Spell.cpp:288
void AddGOTarget(GameObject *target, uint32 effectMask)
Definition: Spell.cpp:2498
void AddUnitTarget(Unit *target, uint32 effectMask, bool checkIfValid=true, bool implicit=true)
Definition: Spell.cpp:2365
void AddItemTarget(Item *item, uint32 effectMask)
Definition: Spell.cpp:2560
void CallScriptObjectTargetSelectHandlers(WorldObject *&target, SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition: Spell.cpp:8643
Definition: SpellInfo.h:215

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(), Object::GetTypeId(), SpellCastTargets::GetUnitTarget(), 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(), TYPEID_PLAYER, and unitTarget.

Referenced by SelectSpellTargets().

◆ SelectExplicitTargets()

void Spell::SelectExplicitTargets ( )
777{
778 // here go all explicit target changes made to explicit targets after spell prepare phase is finished
779 if (Unit* target = m_targets.GetUnitTarget())
780 {
781 // check for explicit target redirection, for Grounding Totem for example
785 {
786 Unit* redirect;
787 switch (m_spellInfo->DmgClass)
788 {
791 break;
795 break;
796 default:
797 redirect = nullptr;
798 break;
799 }
800 if (redirect && (redirect != target))
801 {
802 m_targets.SetUnitTarget(redirect);
804 }
805 }
806 }
807}
Unit * GetMeleeHitRedirectTarget(Unit *victim, SpellInfo const *spellInfo=nullptr)
Definition: Unit.cpp:11012
Unit * GetMagicHitRedirectTarget(Unit *victim, SpellInfo const *spellInfo)
Definition: Unit.cpp:10974

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 
)
1255{
1256 Unit* referer = nullptr;
1257 switch (targetType.GetReferenceType())
1258 {
1262 referer = m_caster;
1263 break;
1265 referer = m_targets.GetUnitTarget();
1266 break;
1268 {
1269 // find last added target for this effect
1270 for (std::list<TargetInfo>::reverse_iterator ihit = m_UniqueTargetInfo.rbegin(); ihit != m_UniqueTargetInfo.rend(); ++ihit)
1271 {
1272 if (ihit->effectMask & (1 << effIndex))
1273 {
1274 referer = ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID);
1275 break;
1276 }
1277 }
1278 break;
1279 }
1280 default:
1281 ASSERT(false && "Spell::SelectImplicitAreaTargets: received not implemented target reference type");
1282 return;
1283 }
1284 if (!referer)
1285 return;
1286
1287 Position const* center = nullptr;
1288 switch (targetType.GetReferenceType())
1289 {
1291 center = m_targets.GetSrcPos();
1292 break;
1294 center = m_targets.GetDstPos();
1295 break;
1299 center = referer;
1300 break;
1301 default:
1302 ASSERT(false && "Spell::SelectImplicitAreaTargets: received not implemented target reference type");
1303 return;
1304 }
1305
1306 // Xinef: the distance should be increased by caster size, it is neglected in latter calculations
1307 std::list<WorldObject*> targets;
1308 float radius = m_spellInfo->Effects[effIndex].CalcRadius(m_caster) * m_spellValue->RadiusMod;
1309 SearchAreaTargets(targets, radius, center, referer, targetType.GetObjectType(), targetType.GetCheckType(), m_spellInfo->Effects[effIndex].ImplicitTargetConditions);
1310
1311 CallScriptObjectAreaTargetSelectHandlers(targets, effIndex, targetType);
1312
1313 if (!targets.empty())
1314 {
1315 // Other special target selection goes here
1316 if (uint32 maxTargets = m_spellValue->MaxAffectedTargets)
1317 {
1319 for (Unit::AuraEffectList::const_iterator j = Auras.begin(); j != Auras.end(); ++j)
1320 if ((*j)->IsAffectedOnSpell(m_spellInfo))
1321 maxTargets += (*j)->GetAmount();
1322
1323 Acore::Containers::RandomResize(targets, maxTargets);
1324 }
1325
1326 for (std::list<WorldObject*>::iterator itr = targets.begin(); itr != targets.end(); ++itr)
1327 {
1328 if (Unit* unitTarget = (*itr)->ToUnit())
1329 AddUnitTarget(unitTarget, effMask, false);
1330 else if (GameObject* gObjTarget = (*itr)->ToGameObject())
1331 AddGOTarget(gObjTarget, effMask);
1332 }
1333 }
1334}
@ 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
void RandomResize(C &container, std::size_t requestedSize)
Definition: Containers.h:81
Position const * GetSrcPos() const
Definition: Spell.cpp:356
float RadiusMod
Definition: Spell.h:215
uint32 MaxAffectedTargets
Definition: Spell.h:214
void CallScriptObjectAreaTargetSelectHandlers(std::list< WorldObject * > &targets, SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition: Spell.cpp:8629

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

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

Referenced by SelectEffectImplicitTargets().

◆ SelectImplicitCasterObjectTargets()

void Spell::SelectImplicitCasterObjectTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType 
)
1742{
1743 WorldObject* target = nullptr;
1744 bool checkIfValid = true;
1745
1746 switch (targetType.GetTarget())
1747 {
1748 case TARGET_UNIT_CASTER:
1749 target = m_caster;
1750 checkIfValid = false;
1751 break;
1752 case TARGET_UNIT_MASTER:
1753 target = m_caster->GetCharmerOrOwner();
1754 break;
1755 case TARGET_UNIT_PET:
1756 target = m_caster->GetGuardianPet();
1757 if (!target)
1758 target = m_caster->GetCharm();
1759 break;
1761 if (m_caster->IsSummon())
1762 target = m_caster->ToTempSummon()->GetSummonerUnit();
1763 break;
1765 target = m_caster->GetVehicleBase();
1766 break;
1776 target = m_caster->GetVehicleKit()->GetPassenger(targetType.GetTarget() - TARGET_UNIT_PASSENGER_0);
1777 break;
1778 default:
1779 break;
1780 }
1781
1782 CallScriptObjectTargetSelectHandlers(target, effIndex, targetType);
1783
1784 if (target && target->ToUnit())
1785 AddUnitTarget(target->ToUnit(), 1 << effIndex, checkIfValid);
1786}
@ TARGET_UNIT_PASSENGER_1
Definition: SharedDefines.h:1473
@ TARGET_UNIT_PASSENGER_6
Definition: SharedDefines.h:1478
@ TARGET_UNIT_VEHICLE
Definition: SharedDefines.h:1470
@ TARGET_UNIT_PASSENGER_2
Definition: SharedDefines.h:1474
@ TARGET_UNIT_PASSENGER_4
Definition: SharedDefines.h:1476
@ TARGET_UNIT_PASSENGER_7
Definition: SharedDefines.h:1479
@ TARGET_UNIT_MASTER
Definition: SharedDefines.h:1403
@ TARGET_UNIT_PASSENGER_5
Definition: SharedDefines.h:1477
@ TARGET_UNIT_PASSENGER_3
Definition: SharedDefines.h:1475
@ TARGET_UNIT_SUMMONER
Definition: SharedDefines.h:1468
@ TARGET_UNIT_PASSENGER_0
Definition: SharedDefines.h:1472
Unit * GetSummonerUnit() const
Definition: TemporarySummon.cpp:45
Unit * GetVehicleBase() const
Definition: Unit.cpp:18910
Unit * GetPassenger(int8 seatId) const
Definition: Vehicle.cpp:226

References AddUnitTarget(), CallScriptObjectTargetSelectHandlers(), Unit::GetCharm(), Unit::GetCharmerOrOwner(), Unit::GetGuardianPet(), Vehicle::GetPassenger(), TempSummon::GetSummonerUnit(), SpellImplicitTargetInfo::GetTarget(), Object::GetTypeId(), Unit::GetVehicleBase(), Unit::GetVehicleKit(), 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(), Object::ToUnit(), and TYPEID_UNIT.

Referenced by SelectEffectImplicitTargets().

◆ SelectImplicitChainTargets()

void Spell::SelectImplicitChainTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType,
WorldObject target,
uint32  effMask 
)
1811{
1812 uint32 maxTargets = m_spellInfo->Effects[effIndex].ChainTarget;
1813 if (Player* modOwner = m_caster->GetSpellModOwner())
1814 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_JUMP_TARGETS, maxTargets, this);
1815
1816 if (maxTargets > 1)
1817 {
1818 // mark damage multipliers as used
1819 for (uint32 k = effIndex; k < MAX_SPELL_EFFECTS; ++k)
1820 if (effMask & (1 << k))
1821 m_damageMultipliers[k] = 1.0f;
1822 m_applyMultiplierMask |= effMask;
1823
1824 std::list<WorldObject*> targets;
1825 SearchChainTargets(targets, maxTargets - 1, target, targetType.GetObjectType(), targetType.GetCheckType(), targetType.GetSelectionCategory()
1826 , m_spellInfo->Effects[effIndex].ImplicitTargetConditions, targetType.GetTarget() == TARGET_UNIT_TARGET_CHAINHEAL_ALLY);
1827
1828 // Chain primary target is added earlier
1829 CallScriptObjectAreaTargetSelectHandlers(targets, effIndex, targetType);
1830
1831 for (std::list<WorldObject*>::iterator itr = targets.begin(); itr != targets.end(); ++itr)
1832 if (Unit* unitTarget = (*itr)->ToUnit())
1833 AddUnitTarget(unitTarget, effMask, false);
1834 }
1835}
@ SPELLMOD_JUMP_TARGETS
Definition: SpellDefines.h:94
@ TARGET_UNIT_TARGET_CHAINHEAL_ALLY
Definition: SharedDefines.h:1421
void SearchChainTargets(std::list< WorldObject * > &targets, uint32 chainTargets, WorldObject *target, SpellTargetObjectTypes objectType, SpellTargetCheckTypes selectType, SpellTargetSelectionCategories selectCategory, ConditionList *condList, bool isChainHeal)
Definition: Spell.cpp:2180

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 
)
1035{
1036 if (targetType.GetReferenceType() != TARGET_REFERENCE_TYPE_CASTER)
1037 {
1038 ASSERT(false && "Spell::SelectImplicitChannelTargets: received not implemented target reference type");
1039 return;
1040 }
1041
1042 switch (targetType.GetTarget())
1043 {
1045 {
1046 // Xinef: All channel selectors have needed data passed in m_targets structure
1048 if (target)
1049 {
1050 CallScriptObjectTargetSelectHandlers(target, effIndex, targetType);
1051 // unit target may be no longer avalible - teleported out of map for example
1052 if (target && target->ToUnit())
1053 AddUnitTarget(target->ToUnit(), 1 << effIndex);
1054 }
1055 else
1056 {
1057 LOG_DEBUG("spells.aura", "SPELL: cannot find channel spell target for spell ID {}, effect {}", m_spellInfo->Id, effIndex);
1058 }
1059 break;
1060 }
1065 {
1066 CallScriptObjectTargetSelectHandlers(target, effIndex, targetType);
1067 if (target)
1068 m_targets.SetDst(*target);
1069 }
1071 {
1072 if (channeledSpell->m_targets.GetUnitTarget())
1073 m_targets.SetDst(*channeledSpell->m_targets.GetUnitTarget());
1074 }
1075 else //if (!m_targets.HasDst())
1076 {
1077 LOG_DEBUG("spells.aura", "SPELL: cannot find channel spell destination for spell ID {}, effect {}", m_spellInfo->Id, effIndex);
1078 }
1079 break;
1081 if (GetOriginalCaster())
1083 break;
1084 default:
1085 ASSERT(false && "Spell::SelectImplicitChannelTargets: received not implemented target type");
1086 break;
1087 }
1088}
@ TARGET_DEST_CHANNEL_TARGET
Definition: SharedDefines.h:1452
@ TARGET_UNIT_CHANNEL_TARGET
Definition: SharedDefines.h:1453
@ TARGET_DEST_CHANNEL_CASTER
Definition: SharedDefines.h:1482
WorldObject * GetObjectTargetChannel(Unit *caster) const
Definition: Spell.cpp:458
SpellDestination const * GetDstChannel() const
Definition: Spell.cpp:468
bool HasDstChannel() const
Definition: Spell.cpp:463

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 
)
1205{
1206 if (targetType.GetReferenceType() != TARGET_REFERENCE_TYPE_CASTER)
1207 {
1208 ASSERT(false && "Spell::SelectImplicitConeTargets: received not implemented target reference type");
1209 return;
1210 }
1211 std::list<WorldObject*> targets;
1212 SpellTargetObjectTypes objectType = targetType.GetObjectType();
1213 SpellTargetCheckTypes selectionType = targetType.GetCheckType();
1214 ConditionList* condList = m_spellInfo->Effects[effIndex].ImplicitTargetConditions;
1215 float coneAngle = M_PI / 2;
1216 float radius = m_spellInfo->Effects[effIndex].CalcRadius(m_caster) * m_spellValue->RadiusMod;
1217
1218 if (uint32 containerTypeMask = GetSearcherTypeMask(objectType, condList))
1219 {
1220 Acore::WorldObjectSpellConeTargetCheck check(coneAngle, radius, m_caster, m_spellInfo, selectionType, condList);
1221 Acore::WorldObjectListSearcher<Acore::WorldObjectSpellConeTargetCheck> searcher(m_caster, targets, check, containerTypeMask);
1222 SearchTargets<Acore::WorldObjectListSearcher<Acore::WorldObjectSpellConeTargetCheck> >(searcher, containerTypeMask, m_caster, m_caster, radius);
1223
1224 CallScriptObjectAreaTargetSelectHandlers(targets, effIndex, targetType);
1225
1226 if (!targets.empty())
1227 {
1228 // Other special target selection goes here
1229 if (uint32 maxTargets = m_spellValue->MaxAffectedTargets)
1230 {
1232 for (Unit::AuraEffectList::const_iterator j = Auras.begin(); j != Auras.end(); ++j)
1233 if ((*j)->IsAffectedOnSpell(m_spellInfo))
1234 maxTargets += (*j)->GetAmount();
1235
1236 Acore::Containers::RandomResize(targets, maxTargets);
1237 }
1238
1239 for (std::list<WorldObject*>::iterator itr = targets.begin(); itr != targets.end(); ++itr)
1240 {
1241 if (Unit* unit = (*itr)->ToUnit())
1242 {
1243 AddUnitTarget(unit, effMask, false);
1244 }
1245 else if (GameObject* gObjTarget = (*itr)->ToGameObject())
1246 {
1247 AddGOTarget(gObjTarget, effMask);
1248 }
1249 }
1250 }
1251 }
1252}
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 
)
1703{
1704 // set destination to caster if no dest provided
1705 // can only happen if previous destination target could not be set for some reason
1706 // (not found nearby target, or channel target for example
1707 // maybe we should abort the spell in such case?
1708 CheckDst();
1709
1711
1712 switch (targetType.GetTarget())
1713 {
1717 case TARGET_DEST_DEST:
1718 return;
1719 case TARGET_DEST_TRAJ:
1720 SelectImplicitTrajTargets(effIndex, targetType);
1721 return;
1722 default:
1723 {
1724 float angle = targetType.CalcDirectionAngle();
1725 float dist = m_spellInfo->Effects[effIndex].CalcRadius(m_caster);
1726 if (targetType.GetTarget() == TARGET_DEST_DEST_RANDOM)
1727 dist *= float(rand_norm());
1728
1729 Position pos = dest._position;
1730 m_caster->MovePosition(pos, dist, angle);
1731
1732 dest.Relocate(pos);
1733 break;
1734 }
1735 }
1736
1737 CallScriptDestinationTargetSelectHandlers(dest, effIndex, targetType);
1738 m_targets.ModDst(dest);
1739}
@ TARGET_DEST_DYNOBJ_ENEMY
Definition: SharedDefines.h:1404
@ TARGET_DEST_DEST_RANDOM
Definition: SharedDefines.h:1462
@ TARGET_DEST_DEST
Definition: SharedDefines.h:1463
@ TARGET_DEST_DYNOBJ_NONE
Definition: SharedDefines.h:1464
@ TARGET_DEST_DYNOBJ_ALLY
Definition: SharedDefines.h:1405
@ TARGET_DEST_TRAJ
Definition: SharedDefines.h:1465
void MovePosition(Position &pos, float dist, float angle)
Definition: Object.cpp:2739
void ModDst(Position const &pos)
Definition: Spell.cpp:430
SpellDestination const * GetDst() const
Definition: Spell.cpp:390

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

Referenced by SelectEffectImplicitTargets().

◆ SelectImplicitNearbyTargets()

void Spell::SelectImplicitNearbyTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType,
uint32  effMask 
)
1091{
1092 if (targetType.GetReferenceType() != TARGET_REFERENCE_TYPE_CASTER)
1093 {
1094 ASSERT(false && "Spell::SelectImplicitNearbyTargets: received not implemented target reference type");
1095 return;
1096 }
1097
1098 float range = 0.0f;
1099 switch (targetType.GetCheckType())
1100 {
1101 case TARGET_CHECK_ENEMY:
1102 range = m_spellInfo->GetMaxRange(false, m_caster, this);
1103 break;
1104 case TARGET_CHECK_ALLY:
1105 case TARGET_CHECK_PARTY:
1106 case TARGET_CHECK_RAID:
1108 range = m_spellInfo->GetMaxRange(true, m_caster, this);
1109 break;
1110 case TARGET_CHECK_ENTRY:
1113 break;
1114 default:
1115 ASSERT(false && "Spell::SelectImplicitNearbyTargets: received not implemented selection check type");
1116 break;
1117 }
1118
1119 ConditionList* condList = m_spellInfo->Effects[effIndex].ImplicitTargetConditions;
1120
1121 // handle emergency case - try to use other provided targets if no conditions provided
1122 if (targetType.GetCheckType() == TARGET_CHECK_ENTRY && (!condList || condList->empty()))
1123 {
1124 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);
1125 switch (targetType.GetObjectType())
1126 {
1129 {
1130 if (focusObject)
1131 AddGOTarget(focusObject, effMask);
1132 return;
1133 }
1134 break;
1137 {
1138 if (focusObject)
1140 return;
1141 }
1142 break;
1143 default:
1144 break;
1145 }
1146 }
1147
1148 WorldObject* target = SearchNearbyTarget(range, targetType.GetObjectType(), targetType.GetCheckType(), condList);
1149 if (!target)
1150 {
1151 LOG_DEBUG("spells.aura", "Spell::SelectImplicitNearbyTargets: cannot find nearby target for spell ID {}, effect {}", m_spellInfo->Id, effIndex);
1152 return;
1153 }
1154
1155 CallScriptObjectTargetSelectHandlers(target, effIndex, targetType);
1156 if (!target)
1157 {
1158 //LOG_DEBUG("spells", "Spell::SelectImplicitNearbyTargets: OnObjectTargetSelect script hook for spell Id {} set nullptr target, effect {}", m_spellInfo->Id, effIndex);
1159 return;
1160 }
1161
1162 switch (targetType.GetObjectType())
1163 {
1165 {
1166 if (Unit* unit = target->ToUnit())
1167 {
1168 AddUnitTarget(unit, effMask, true, false);
1169 // xinef: important! if channeling spell have nearby entry, it has no unitTarget by default
1170 // and if channeled spell has target 77, it requires unitTarget, set it here!
1171 // xinef: if we have NO unit target
1172 if (!m_targets.GetUnitTarget())
1173 {
1175 }
1176 }
1177 else
1178 {
1179 //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);
1180 return;
1181 }
1182 break;
1183 }
1185 if (GameObject* gobjTarget = target->ToGameObject())
1186 AddGOTarget(gobjTarget, effMask);
1187 else
1188 {
1189 //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);
1190 return;
1191 }
1192 break;
1194 m_targets.SetDst(*target);
1195 break;
1196 default:
1197 ASSERT(false && "Spell::SelectImplicitNearbyTargets: received not implemented target object type");
1198 break;
1199 }
1200
1201 SelectImplicitChainTargets(effIndex, targetType, target, effMask);
1202}
@ 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:2158
void SelectImplicitChainTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType, WorldObject *target, uint32 effMask)
Definition: Spell.cpp:1810

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 
)
1666{
1668
1669 SpellDestination dest(*target);
1670
1671 switch (targetType.GetTarget())
1672 {
1675 break;
1676 default:
1677 {
1678 float angle = targetType.CalcDirectionAngle();
1679 float dist = m_spellInfo->Effects[effIndex].CalcRadius(nullptr);
1680 if (targetType.GetTarget() == TARGET_DEST_TARGET_RANDOM)
1681 {
1682 dist *= float(rand_norm());
1683 }
1684
1685 if (targetType.GetTarget() == TARGET_DEST_TARGET_BACK)
1686 {
1688 }
1689
1690 Position pos = dest._position;
1691 target->MovePositionToFirstCollision(pos, dist, angle);
1692
1693 dest.Relocate(pos);
1694 break;
1695 }
1696 }
1697
1698 CallScriptDestinationTargetSelectHandlers(dest, effIndex, targetType);
1699 m_targets.SetDst(dest);
1700}
@ UNIT_FIELD_BOUNDINGRADIUS
Definition: UpdateFields.h:122
@ TARGET_DEST_TARGET_ANY
Definition: SharedDefines.h:1439
@ TARGET_DEST_TARGET_BACK
Definition: SharedDefines.h:1441
@ TARGET_DEST_TARGET_RANDOM
Definition: SharedDefines.h:1450
@ TARGET_DEST_TARGET_ENEMY
Definition: SharedDefines.h:1429

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 
)
1789{
1790 ASSERT((m_targets.GetObjectTarget() || m_targets.GetItemTarget()) && "Spell::SelectImplicitTargetObjectTargets - no explicit object or item target available!");
1791
1793
1794 CallScriptObjectTargetSelectHandlers(target, effIndex, targetType);
1795
1796 if (target)
1797 {
1798 if (Unit* unit = target->ToUnit())
1799 AddUnitTarget(unit, 1 << effIndex, true, false);
1800 else if (GameObject* gobj = target->ToGameObject())
1801 AddGOTarget(gobj, 1 << effIndex);
1802
1803 SelectImplicitChainTargets(effIndex, targetType, target, 1 << effIndex);
1804 }
1805 // Script hook can remove object target and we would wrongly land here
1806 else if (Item* item = m_targets.GetItemTarget())
1807 AddItemTarget(item, 1 << effIndex);
1808}

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

Referenced by SelectEffectImplicitTargets().

◆ SelectImplicitTrajTargets()

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

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

Referenced by SelectEffectImplicitTargets(), and SelectImplicitDestDestTargets().

◆ SelectSpellTargets()

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

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
4632{
4633 if (result == SPELL_CAST_OK)
4634 return;
4635
4636 WorldPacket data(SMSG_CAST_FAILED, 1 + 4 + 1);
4637 WriteCastResultInfo(data, caster, spellInfo, castCount, result, customError);
4638
4639 caster->GetSession()->SendPacket(&data);
4640}
@ SMSG_CAST_FAILED
Definition: Opcodes.h:334
static void WriteCastResultInfo(WorldPacket &data, Player *caster, SpellInfo const *spellInfo, uint8 castCount, SpellCastResult result, SpellCustomErrors customError)
Definition: Spell.cpp:4526

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

Referenced by _cast(), Unit::AttackerStateUpdate(), cancel(), Player::CastItemUseSpell(), spell_q12237_rescue_villager::CheckCast(), spell_q12237_drop_off_villager::CheckCast(), spell_dk_raise_dead::CheckReagents(), spell_putricide_mutation_init::spell_putricide_mutation_init_SpellScript::CheckRequirement(), EffectApplyGlyph(), EffectDuel(), EffectOpenLock(), EffectTaunt(), SpellScript::FinishCast(), go_soulwell::go_soulwellAI::GossipHello(), WorldSession::HandleAcceptTradeOpcode(), spell_the_flag_of_ownership::HandleFinish(), WorldSession::HandlePetActionHelper(), spell_putricide_mutated_transformation::spell_putricide_mutated_transformation_SpellScript::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)
4643{
4644 if (result == SPELL_CAST_OK)
4645 return;
4646
4648 return;
4649
4650 if (m_caster->ToPlayer()->GetSession()->PlayerLoading()) // don't send cast results at loading time
4651 return;
4652
4653 // 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
4655 result = SPELL_FAILED_DONT_REPORT;
4656
4658}
@ TRIGGERED_DONT_REPORT_CAST_ERROR
Disallows proc events from triggered spell (default)
Definition: SpellDefines.h:147
@ SPELL_FAILED_BM_OR_INVISGOD
Definition: SharedDefines.h:1080
bool IsCharmed() const
Definition: Unit.h:1871

References _triggeredCastFlags, Player::GetSession(), Object::GetTypeId(), Unit::IsCharmed(), 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(), TRIGGERED_DONT_REPORT_CAST_ERROR, and TYPEID_PLAYER.

◆ SendChannelStart()

void Spell::SendChannelStart ( uint32  duration)
5169{
5170 ObjectGuid channelTarget = m_targets.GetObjectTargetGUID();
5171 if (!channelTarget && !m_spellInfo->NeedsExplicitUnitTarget())
5172 if (m_UniqueTargetInfo.size() + m_UniqueGOTargetInfo.size() == 1) // this is for TARGET_SELECT_CATEGORY_NEARBY
5173 channelTarget = !m_UniqueTargetInfo.empty() ? m_UniqueTargetInfo.front().targetGUID : m_UniqueGOTargetInfo.front().targetGUID;
5174
5175 WorldPacket data(MSG_CHANNEL_START, (8 + 4 + 4));
5176 data << m_caster->GetPackGUID();
5177 data << uint32(m_spellInfo->Id);
5178 data << uint32(duration);
5179
5180 m_caster->SendMessageToSet(&data, true);
5181
5184
5185 m_timer = duration;
5186 if (channelTarget)
5188
5190}
@ MSG_CHANNEL_START
Definition: Opcodes.h:343

References WorldObject::FindMap(), Object::GetGUID(), SpellCastTargets::GetObjectTargetGUID(), Object::GetPackGUID(), Object::GetTypeId(), SpellInfo::Id, 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(), Object::SetUInt32Value(), Object::ToPlayer(), TYPEID_PLAYER, UNIT_CHANNEL_SPELL, and UNIT_FIELD_CHANNEL_OBJECT.

Referenced by handle_immediate().

◆ SendChannelUpdate()

◆ SendInterrupted()

void Spell::SendInterrupted ( uint8  result)
5137{
5138 WorldPacket data(SMSG_SPELL_FAILURE, (8 + 1 + 4 + 1));
5139 data << m_caster->GetPackGUID();
5140 data << uint8(m_cast_count);
5141 data << uint32(m_spellInfo->Id);
5142 data << uint8(result);
5143 m_caster->SendMessageToSet(&data, true);
5144
5145 data.Initialize(SMSG_SPELL_FAILED_OTHER, (8 + 1 + 4 + 1));
5146 data << m_caster->GetPackGUID();
5147 data << uint8(m_cast_count);
5148 data << uint32(m_spellInfo->Id);
5149 data << uint8(result);
5150 m_caster->SendMessageToSet(&data, true);
5151}
@ 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 ( )
5036{
5037 WorldPacket data(SMSG_SPELLLOGEXECUTE, (8 + 4 + 4 + 4 + 4 + 8));
5038
5039 data << m_caster->GetPackGUID();
5040
5041 data << uint32(m_spellInfo->Id);
5042
5043 uint8 effCount = 0;
5044 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
5045 {
5046 if (m_effectExecuteData[i])
5047 ++effCount;
5048 }
5049
5050 if (!effCount)
5051 return;
5052
5053 data << uint32(effCount);
5054 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
5055 {
5056 if (!m_effectExecuteData[i])
5057 continue;
5058
5059 data << uint32(m_spellInfo->Effects[i].Effect); // spell effect
5060
5061 data.append(*m_effectExecuteData[i]);
5062
5063 delete m_effectExecuteData[i];
5064 m_effectExecuteData[i] = nullptr;
5065 }
5066 m_caster->SendMessageToSet(&data, true);
5067}
@ 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
2025{
2026 Player* player = m_caster->ToPlayer();
2027 if (!player)
2028 return;
2029
2030 if (gameObjTarget)
2031 {
2032 // Players shouldn't be able to loot gameobjects that are currently despawned
2033 if (!gameObjTarget->isSpawned() && !player->IsGameMaster())
2034 {
2035 LOG_ERROR("spells.effect", "Possible hacking attempt: Player {} [{}] tried to loot a gameobject [{}] which is on respawn time without being in GM mode!",
2036 player->GetName(), player->GetGUID().ToString(), gameObjTarget->GetGUID().ToString());
2037 return;
2038 }
2039 // special case, already has GossipHello inside so return and avoid calling twice
2041 {
2043 return;
2044 }
2045
2046 if (sScriptMgr->OnGossipHello(player, gameObjTarget))
2047 return;
2048
2049 if (gameObjTarget->AI()->GossipHello(player, false))
2050 return;
2051
2052 switch (gameObjTarget->GetGoType())
2053 {
2055 gameObjTarget->UseDoorOrButton(0, false, player);
2056 return;
2058 gameObjTarget->UseDoorOrButton(0, false, player);
2059
2060 // Xinef: properly link possible traps
2061 if (uint32 trapEntry = gameObjTarget->GetGOInfo()->button.linkedTrap)
2062 gameObjTarget->TriggeringLinkedGameObject(trapEntry, player);
2063 return;
2067 return;
2068
2070 // triggering linked GO
2073 return;
2074
2076 // triggering linked GO
2077 if (uint32 trapEntry = gameObjTarget->GetGOInfo()->chest.linkedTrapId)
2079
2080 // Don't return, let loots been taken
2081 default:
2082 break;
2083 }
2084 }
2085
2086 // Send loot
2087 player->SendLoot(guid, loottype);
2088}
@ GAMEOBJECT_TYPE_SPELL_FOCUS
Definition: SharedDefines.h:1540
@ GAMEOBJECT_TYPE_QUESTGIVER
Definition: SharedDefines.h:1534
virtual bool GossipHello(Player *, bool)
Definition: GameObjectAI.h:55
bool isSpawned() const
Definition: GameObject.h:191
void TriggeringLinkedGameObject(uint32 trapEntry, Unit *target)
Definition: GameObject.cpp:1383
uint32 gossipID
Definition: GameObjectData.h:73
uint32 linkedTrap
Definition: GameObjectData.h:60
struct GameObjectTemplate::@215::@220 chest
struct GameObjectTemplate::@215::@219 questgiver
struct GameObjectTemplate::@215::@224 spellFocus
uint32 linkedTrapId
Definition: GameObjectData.h:91
void SendPreparedGossip(WorldObject *source)
Definition: PlayerGossip.cpp:210
void PrepareGossipMenu(WorldObject *source, uint32 menuId=0, bool showQuests=false)
Definition: PlayerGossip.cpp:31

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)
4661{
4662 if (result == SPELL_CAST_OK)
4663 return;
4664
4665 Unit* owner = m_caster->GetCharmerOrOwner();
4666 if (!owner)
4667 return;
4668
4669 Player* player = owner->ToPlayer();
4670 if (!player)
4671 return;
4672
4673 WorldPacket data(SMSG_PET_CAST_FAILED, 1 + 4 + 1);
4675
4676 player->GetSession()->SendPacket(&data);
4677}
@ SMSG_PET_CAST_FAILED
Definition: Opcodes.h:342

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

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

◆ SendResurrectRequest()

void Spell::SendResurrectRequest ( Player target)
5193{
5194 // get resurrector name for creature resurrections, otherwise packet will be not accepted
5195 // for player resurrections the name is looked up by guid
5196 std::string const sentName(m_caster->GetTypeId() == TYPEID_PLAYER
5197 ? ""
5199
5200 WorldPacket data(SMSG_RESURRECT_REQUEST, (8 + 4 + sentName.size() + 1 + 1 + 1 + 4));
5201 data << m_caster->GetGUID();
5202 data << uint32(sentName.size() + 1);
5203
5204 data << sentName;
5205 data << uint8(0); // null terminator
5206
5207 data << uint8(m_caster->GetTypeId() == TYPEID_PLAYER ? 0 : 1); // "you'll be afflicted with resurrection sickness"
5208 // override delay sent with SMSG_CORPSE_RECLAIM_DELAY, set instant resurrection for spells with this attribute
5210 data << uint32(0);
5211 target->GetSession()->SendPacket(&data);
5212}
@ SPELL_ATTR3_NO_RES_TIMER
Definition: SharedDefines.h:469
@ SMSG_RESURRECT_REQUEST
Definition: Opcodes.h:377
virtual std::string const & GetNameForLocaleIdx(LocaleConstant) const
Definition: Object.h:449
LocaleConstant GetSessionDbLocaleIndex() const
Definition: WorldSession.h:497

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

Referenced by EffectResurrect(), and EffectResurrectNew().

◆ SendSpellCooldown()

void Spell::SendSpellCooldown ( )
4327{
4328 // xinef: properly add creature cooldowns
4330 {
4332 {
4333 // xinef: this should be added here
4334 //m_caster->AddSpellCooldown(m_spellInfo->Id, 0, 0);
4335
4336 // xinef: this adds cooldowns to vehicle spells which misses them client-side (when we overwrote dbc info in eg.)
4339 {
4340 WorldPacket data(SMSG_SPELL_COOLDOWN, 8 + 1 + 4 + 4);
4341 data << m_caster->GetGUID();
4343 data << uint32(m_spellInfo->Id);
4345 player->SendDirectMessage(&data);
4346 }
4347 }
4348 return;
4349 }
4350
4351 Player* _player = m_caster->ToPlayer();
4352
4353 // mana/health/etc potions, disabled by client (until combat out as declarate)
4355 {
4356 // need in some way provided data for Spell::finish SendCooldownEvent
4357 _player->SetLastPotionId(m_CastItem->GetEntry());
4358 return;
4359 }
4360
4361 // have infinity cooldown but set at aura apply // do not set cooldown for triggered spells (needed by reincarnation)
4363 return;
4364
4366}
@ SPELL_COOLDOWN_FLAG_INCLUDE_GCD
Starts GCD in addition to normal cooldown specified in the packet.
Definition: Unit.h:1231
@ SMSG_SPELL_COOLDOWN
Definition: Opcodes.h:338
void SetLastPotionId(uint32 item_id)
Definition: Player.h:1763
void AddSpellAndCategoryCooldowns(SpellInfo const *spellInfo, uint32 itemId, Spell *spell=nullptr, bool infinityCooldown=false)
Definition: Player.cpp:10805
uint32 RecoveryTime
Definition: SpellInfo.h:346
bool RequireCooldownInfo() const
Definition: SpellInfo.cpp:1166

References _triggeredCastFlags, Player::AddSpellAndCategoryCooldowns(), Unit::GetCharmerOrOwnerPlayerOrPlayerItself(), Object::GetEntry(), Object::GetGUID(), Object::GetTypeId(), SpellInfo::Id, SpellInfo::IsCooldownStartedOnEvent(), SpellInfo::IsPassive(), 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_SPELL_AND_CATEGORY_CD, and TYPEID_PLAYER.

Referenced by _cast().

◆ SendSpellGo()

void Spell::SendSpellGo ( )
4760{
4761 // not send invisible spell casting
4762 if (!IsNeedSendToClient(true))
4763 return;
4764
4765 //LOG_DEBUG("spells.aura", "Sending SMSG_SPELL_GO id={}", m_spellInfo->Id);
4766
4767 uint32 castFlags = CAST_FLAG_UNKNOWN_9;
4768
4769 // triggered spells with spell visual != 0
4771 castFlags |= CAST_FLAG_PENDING;
4772
4774 castFlags |= CAST_FLAG_PROJECTILE; // arrows/bullets visual
4775
4776 // should only be sent to self, but the current messaging doesn't make that possible
4778 {
4779 switch (m_spellInfo->PowerType)
4780 {
4781 case POWER_HEALTH:
4782 break;
4783 case POWER_RUNE:
4784 castFlags |= CAST_FLAG_POWER_LEFT_SELF;
4785 break;
4786 default:
4787 if (m_powerCost != 0)
4788 {
4789 castFlags |= CAST_FLAG_POWER_LEFT_SELF;
4790 }
4791 break;
4792 }
4793 }
4794
4795 if ((m_caster->GetTypeId() == TYPEID_PLAYER)
4799 {
4800 castFlags |= CAST_FLAG_NO_GCD; // not needed, but Blizzard sends it
4801 castFlags |= CAST_FLAG_RUNE_LIST; // rune cooldowns list
4802 }
4803
4805 castFlags |= CAST_FLAG_RUNE_LIST; // rune cooldowns list
4806
4807 if (m_targets.HasTraj())
4808 castFlags |= CAST_FLAG_ADJUST_MISSILE;
4809
4811 castFlags |= CAST_FLAG_NO_GCD;
4812
4813 PackedGuid realCasterGUID = m_caster->GetPackGUID();
4814 if (TempSummon const* tempSummon = m_caster->ToTempSummon())
4815 {
4816 if (tempSummon->GetEntry() == WORLD_TRIGGER)
4817 {
4818 if (GameObject* casterGameobject = tempSummon->GetSummonerGameObject())
4819 {
4820 realCasterGUID = casterGameobject->GetPackGUID();
4821 }
4822 }
4823 }
4824
4825 WorldPacket data(SMSG_SPELL_GO, 150); // guess size
4826
4827 if (m_CastItem)
4828 data << m_CastItem->GetPackGUID();
4829 else
4830 data << realCasterGUID;
4831
4832 data << realCasterGUID;
4833 data << uint8(m_cast_count); // pending spell cast?
4834 data << uint32(m_spellInfo->Id); // spellId
4835 data << uint32(castFlags); // cast flags
4836 data << uint32(GameTime::GetGameTimeMS().count()); // timestamp
4837
4838 WriteSpellGoTargets(&data);
4839
4840 m_targets.Write(data);
4841
4842 if (castFlags & CAST_FLAG_POWER_LEFT_SELF)
4844
4845 if (castFlags & CAST_FLAG_RUNE_LIST) // rune cooldowns list
4846 {
4847 //TODO: There is a crash caused by a spell with CAST_FLAG_RUNE_LIST casted by a creature
4848 //The creature is the mover of a player, so HandleCastSpellOpcode uses it as the caster
4849 if (Player* player = m_caster->ToPlayer())
4850 {
4851 uint8 runeMaskInitial = m_runesState;
4852 uint8 runeMaskAfterCast = player->GetRunesState();
4853 data << uint8(runeMaskInitial); // runes state before
4854 data << uint8(runeMaskAfterCast); // runes state after
4855 for (uint8 i = 0; i < MAX_RUNES; ++i)
4856 {
4857 uint8 mask = (1 << i);
4858 if (mask & runeMaskInitial && !(mask & runeMaskAfterCast)) // usable before andon cooldown now...
4859 {
4860 // float casts ensure the division is performed on floats as we need float result
4861 float baseCd = float(player->GetRuneBaseCooldown(i, true));
4862 data << uint8((baseCd - float(player->GetRuneCooldown(i))) / baseCd * 255); // rune cooldown passed
4863 }
4864 }
4865 }
4866 }
4867 if (castFlags & CAST_FLAG_ADJUST_MISSILE)
4868 {
4869 data << m_targets.GetElevation();
4871 }
4872
4873 if (castFlags & CAST_FLAG_PROJECTILE)
4874 WriteAmmoToPacket(&data);
4875
4876 if (castFlags & CAST_FLAG_VISUAL_CHAIN)
4877 {
4878 data << uint32(0);
4879 data << uint32(0);
4880 }
4881
4883 {
4884 data << uint8(0);
4885 }
4886
4887 m_caster->SendMessageToSet(&data, true);
4888}
@ CAST_FLAG_VISUAL_CHAIN
Definition: Spell.h:63
@ CAST_FLAG_ADJUST_MISSILE
Definition: Spell.h:61
@ CAST_FLAG_UNKNOWN_9
Definition: Spell.h:52
@ CAST_FLAG_NO_GCD
Definition: Spell.h:62
@ CAST_FLAG_PROJECTILE
Definition: Spell.h:49
@ CAST_FLAG_POWER_LEFT_SELF
Definition: Spell.h:55
@ CAST_FLAG_RUNE_LIST
Definition: Spell.h:65
@ CAST_FLAG_PENDING
Definition: Spell.h:44
@ SPELL_ATTR0_CU_NEEDS_AMMO_DATA
Definition: SpellInfo.h:195
@ SPELL_EFFECT_ACTIVATE_RUNE
Definition: SharedDefines.h:896
@ SPELL_ATTR0_USES_RANGED_SLOT
Definition: SharedDefines.h:355
@ SMSG_SPELL_GO
Definition: Opcodes.h:336
Definition: ObjectGuid.h:265
void Write(ByteBuffer &data)
Definition: Spell.cpp:173
void WriteSpellGoTargets(WorldPacket *data)
Writes miss and hit targets for a SMSG_SPELL_GO packet.
Definition: Spell.cpp:4975
void WriteAmmoToPacket(WorldPacket *data)
Definition: Spell.cpp:4890
bool IsNeedSendToClient(bool go) const
Definition: Spell.cpp:8054

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, CLASS_DEATH_KNIGHT, Unit::getClass(), SpellCastTargets::GetElevation(), GameTime::GetGameTimeMS(), Object::GetPackGUID(), Unit::GetPower(), SpellCastTargets::GetTargetMask(), Object::GetTypeId(), SpellInfo::HasAttribute(), SpellInfo::HasEffect(), SpellCastTargets::HasTraj(), SpellInfo::Id, SpellInfo::IsAutoRepeatRangedSpell(), SpellInfo::IsChanneled(), IsNeedSendToClient(), Unit::IsPet(), 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(), TYPEID_PLAYER, WORLD_TRIGGER, SpellCastTargets::Write(), WriteAmmoToPacket(), and WriteSpellGoTargets().

Referenced by _cast().

◆ SendSpellStart()

void Spell::SendSpellStart ( )
4680{
4681 if (!IsNeedSendToClient(false))
4682 return;
4683
4684 //LOG_DEBUG("spells.aura", "Sending SMSG_SPELL_START id={}", m_spellInfo->Id);
4685
4686 uint32 castFlags = CAST_FLAG_HAS_TRAJECTORY;
4687
4689 castFlags |= CAST_FLAG_PENDING;
4690
4692 castFlags |= CAST_FLAG_PROJECTILE;
4693
4695 {
4696 switch (m_spellInfo->PowerType)
4697 {
4698 case POWER_HEALTH:
4699 break;
4700 case POWER_RUNE:
4701 castFlags |= CAST_FLAG_POWER_LEFT_SELF;
4702 break;
4703 default:
4704 if (m_powerCost != 0)
4705 {
4706 castFlags |= CAST_FLAG_POWER_LEFT_SELF;
4707 }
4708 break;
4709 }
4710 }
4711
4713 castFlags |= CAST_FLAG_NO_GCD; // not needed, but Blizzard sends it
4714
4715 PackedGuid realCasterGUID = m_caster->GetPackGUID();
4716 if (TempSummon const* tempSummon = m_caster->ToTempSummon())
4717 {
4718 if (tempSummon->GetEntry() == WORLD_TRIGGER)
4719 {
4720 if (GameObject* casterGameobject = tempSummon->GetSummonerGameObject())
4721 {
4722 realCasterGUID = casterGameobject->GetPackGUID();
4723 }
4724 }
4725 }
4726
4727 WorldPacket data(SMSG_SPELL_START, (8 + 8 + 4 + 4 + 2));
4728 if (m_CastItem)
4729 data << m_CastItem->GetPackGUID();
4730 else
4731 data << realCasterGUID;
4732
4733 data << realCasterGUID;
4734 data << uint8(m_cast_count); // pending spell cast?
4735 data << uint32(m_spellInfo->Id); // spellId
4736 data << uint32(castFlags); // cast flags
4737 data << int32(m_timer); // delay?
4738
4739 m_targets.Write(data);
4740
4741 if (castFlags & CAST_FLAG_POWER_LEFT_SELF)
4743
4744 if (castFlags & CAST_FLAG_PROJECTILE)
4745 WriteAmmoToPacket(&data);
4746
4747 if (castFlags & CAST_FLAG_UNKNOWN_23)
4748 {
4749 data << uint32(0);
4750 data << uint32(0);
4751 }
4752
4753 m_caster->SendMessageToSet(&data, true);
4754
4757}
@ CAST_FLAG_UNKNOWN_23
Definition: Spell.h:66
@ CAST_FLAG_HAS_TRAJECTORY
Definition: Spell.h:45
@ 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, WorldObject::FindMap(), Object::GetGUID(), Object::GetPackGUID(), Unit::GetPower(), Object::GetTypeId(), SpellInfo::HasAttribute(), SpellInfo::Id, SpellInfo::IsAutoRepeatRangedSpell(), SpellInfo::IsChanneled(), IsNeedSendToClient(), Unit::IsPet(), 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(), TYPEID_PLAYER, WORLD_TRIGGER, SpellCastTargets::Write(), and WriteAmmoToPacket().

Referenced by prepare().

◆ SetAutoRepeat()

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

References m_autoRepeat.

◆ SetDelayStart()

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

References m_delayStart.

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

◆ SetExecutedCurrently()

void Spell::SetExecutedCurrently ( bool  yes)
inline
560{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 
)
8393{
8394 switch (mod)
8395 {
8397 m_spellValue->EffectBasePoints[0] = m_spellInfo->Effects[EFFECT_0].CalcBaseValue(value);
8398 break;
8400 m_spellValue->EffectBasePoints[1] = m_spellInfo->Effects[EFFECT_1].CalcBaseValue(value);
8401 break;
8403 m_spellValue->EffectBasePoints[2] = m_spellInfo->Effects[EFFECT_2].CalcBaseValue(value);
8404 break;
8406 m_spellValue->RadiusMod = (float)value / 10000;
8407 break;
8410 break;
8413 break;
8415 m_spellValue->AuraDuration = value;
8416 break;
8418 m_spellValue->ForcedCritResult = (bool)value;
8419 break;
8420 }
8421}
@ SPELLVALUE_AURA_STACK
Definition: SpellDefines.h:119
@ SPELLVALUE_AURA_DURATION
Definition: SpellDefines.h:120
@ SPELLVALUE_RADIUS_MOD
Definition: SpellDefines.h:117
@ SPELLVALUE_MAX_TARGETS
Definition: SpellDefines.h:118
@ SPELLVALUE_FORCED_CRIT_RESULT
Definition: SpellDefines.h:121
bool ForcedCritResult
Definition: Spell.h:218

References SpellValue::AuraDuration, SpellValue::AuraStackAmount, EFFECT_0, EFFECT_1, EFFECT_2, SpellValue::EffectBasePoints, SpellInfo::Effects, SpellValue::ForcedCritResult, m_spellInfo, m_spellValue, SpellValue::MaxAffectedTargets, SpellValue::RadiusMod, SPELLVALUE_AURA_DURATION, SPELLVALUE_AURA_STACK, SPELLVALUE_BASE_POINT0, SPELLVALUE_BASE_POINT1, SPELLVALUE_BASE_POINT2, SPELLVALUE_FORCED_CRIT_RESULT, SPELLVALUE_MAX_TARGETS, 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
483{ m_spellState = state; }

References m_spellState.

◆ SummonGuardian()

void Spell::SummonGuardian ( uint32  i,
uint32  entry,
SummonPropertiesEntry const *  properties,
uint32  numSummons,
bool  personalSpawn 
)
protected
6002{
6003 Unit* caster = m_originalCaster;
6004 if (!caster)
6005 return;
6006
6007 if (caster->IsTotem())
6008 caster = caster->ToTotem()->GetOwner();
6009
6010 // in another case summon new
6011 uint8 summonLevel = caster->GetLevel();
6012
6013 // level of pet summoned using engineering item based at engineering skill level
6014 if (m_CastItem && caster->GetTypeId() == TYPEID_PLAYER)
6015 if (ItemTemplate const* proto = m_CastItem->GetTemplate())
6016 {
6017 // xinef: few special cases
6018 if (proto->RequiredSkill == SKILL_ENGINEERING)
6019 {
6020 if (uint16 skill202 = caster->ToPlayer()->GetSkillValue(SKILL_ENGINEERING))
6021 summonLevel = skill202 / 5;
6022 }
6023
6024 switch (m_spellInfo->Id)
6025 {
6026 // Dragon's Call
6027 case 13049:
6028 summonLevel = 55;
6029 break;
6030
6031 // Cleansed Timberling Heart: Summon Timberling
6032 case 5666:
6033 summonLevel = 7;
6034 break;
6035
6036 // Glowing Cat Figurine: Summon Ghost Saber
6037 case 6084:
6038 // minLevel 19, maxLevel 20
6039 summonLevel = 20;
6040 break;
6041
6042 // Spiked Collar: Summon Felhunter
6043 case 8176:
6044 summonLevel = 30;
6045 break;
6046
6047 // Dog Whistle: Summon Tracking Hound
6048 case 9515:
6049 summonLevel = 30;
6050 break;
6051
6052 // Barov Peasant Caller: Death by Peasant
6053 case 18307:
6054 case 18308:
6055 summonLevel = 60;
6056 break;
6057
6058 // Thornling Seed: Plant Thornling
6059 case 22792:
6060 summonLevel = 60;
6061 break;
6062
6063 // Cannonball Runner: Summon Crimson Cannon
6064 case 6251:
6065 summonLevel = 61;
6066 break;
6067 }
6068 }
6069
6070 summonLevel = std::min<uint8>(sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL) + sWorld->getIntConfig(CONFIG_WORLD_BOSS_LEVEL_DIFF), std::max<uint8>(1U, summonLevel));
6071
6072 float radius = 5.0f;
6073 int32 duration = m_spellInfo->GetDuration();
6074
6075 if (Player* modOwner = m_originalCaster->GetSpellModOwner())
6076 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_DURATION, duration);
6077
6078 //TempSummonType summonType = (duration == 0) ? TEMPSUMMON_DEAD_DESPAWN : TEMPSUMMON_TIMED_DESPAWN;
6079 Map* map = caster->GetMap();
6080 TempSummon* summon = nullptr;
6081
6082 uint32 currMinionsCount = m_caster->m_Controlled.size();
6083 uint32 totalNumGuardians = numGuardians + currMinionsCount;
6084
6085 for (uint32 count = 0; count < numGuardians; ++count)
6086 {
6087 Position pos;
6088
6089 // xinef: do not use precalculated position for effect summon pet in this function
6090 // it means it was cast by NPC and should have its position overridden
6091 if (totalNumGuardians == 1 && GetSpellInfo()->Effects[i].Effect != SPELL_EFFECT_SUMMON_PET)
6092 {
6093 pos = *destTarget;
6094 }
6095 else
6096 {
6097 // randomize position
6098 pos = m_caster->GetRandomPoint(*destTarget, radius);
6099 }
6100
6101 summon = map->SummonCreature(entry, pos, properties, duration, caster, m_spellInfo->Id, 0, personalSpawn);
6102 if (!summon)
6103 return;
6104
6105 // xinef: set calculated level
6106 summon->SetLevel(summonLevel);
6107
6108 // if summonLevel changed, set stats for calculated level
6109 if (summonLevel != caster->GetLevel())
6110 {
6111 ((Guardian*)summon)->InitStatsForLevel(summonLevel);
6112 }
6113
6114 // xinef: if we have more than one guardian, change follow angle
6115 if (summon->HasUnitTypeMask(UNIT_MASK_MINION) && totalNumGuardians > 1)
6116 ((Minion*)summon)->SetFollowAngle(m_caster->GetAbsoluteAngle(pos.GetPositionX(), pos.GetPositionY()));
6117 //else if (summon->HasUnitTypeMask(UNIT_MASK_MINION) && m_targets.HasDst())
6118 // ((Minion*)summon)->SetFollowAngle(m_caster->GetAngle(summon));
6119
6120 // xinef: move this here, some auras are added in initstatsforlevel!
6121 if (!summon->IsInCombat() && !summon->IsTrigger())
6122 {
6123 // summon->AI()->EnterEvadeMode();
6124 summon->GetMotionMaster()->Clear(false);
6126 }
6127
6128 if (properties && properties->Category == SUMMON_CATEGORY_ALLY)
6129 summon->SetFaction(caster->GetFaction());
6130
6132 }
6133
6134 // Summon infernal, cast enslave demon
6135 // xinef: have to do it here because in Pet init stats infernal is not in world, imo this should be changed...
6136 if (summon)
6137 {
6138 switch (m_spellInfo->Id)
6139 {
6140 // Inferno, Warlock summon spell
6141 case 1122:
6142 caster->AddAura(61191, summon);
6143 break;
6144 // Ritual of Doom, Warlock summon spell
6145 case 60478:
6146 caster->AddAura(SPELL_RITUAL_ENSLAVEMENT, summon);
6147 break;
6148 }
6149 }
6150}
@ SPELL_RITUAL_ENSLAVEMENT
Definition: PetDefines.h:150
@ CONFIG_MAX_PLAYER_LEVEL
Definition: IWorld.h:234
@ CONFIG_WORLD_BOSS_LEVEL_DIFF
Definition: IWorld.h:284
bool IsTrigger() const
Definition: Creature.h:77
Definition: TemporarySummon.h:76
Unit * GetOwner() const
Definition: TemporarySummon.cpp:386
void SetLevel(uint8 lvl, bool showLevelChange=true)
Definition: Unit.cpp:15352

References Unit::AddAura(), 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(), Object::GetTypeId(), Unit::HasUnitTypeMask(), SpellInfo::Id, Unit::IsInCombat(), 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, SPELL_RITUAL_ENSLAVEMENT, SPELLMOD_DURATION, SUMMON_CATEGORY_ALLY, Map::SummonCreature(), sWorld, Object::ToPlayer(), Unit::ToTotem(), TYPEID_PLAYER, and UNIT_MASK_MINION.

Referenced by EffectSummonPet(), and EffectSummonType().

◆ TakeAmmo()

void Spell::TakeAmmo ( )
5342{
5344 {
5346
5347 // wands don't have ammo
5348 if (!pItem || pItem->IsBroken() || pItem->GetTemplate()->SubClass == ITEM_SUBCLASS_WEAPON_WAND)
5349 return;
5350
5351 if (pItem->GetTemplate()->InventoryType == INVTYPE_THROWN)
5352 {
5353 if (pItem->GetMaxStackCount() == 1)
5354 {
5355 // decrease durability for non-stackable throw weapon
5357 }
5358 else
5359 {
5360 // decrease items amount for stackable throw weapon
5361 uint32 count = 1;
5362 m_caster->ToPlayer()->DestroyItemCount(pItem, count, true);
5363 }
5364 }
5366 m_caster->ToPlayer()->DestroyItemCount(ammo, 1, true);
5367 }
5368}
@ INVTYPE_THROWN
Definition: ItemTemplate.h:290
@ EQUIPMENT_SLOT_RANGED
Definition: Player.h:693
uint32 GetMaxStackCount() const
Definition: Item.h:265
void DurabilityPointLossForEquipSlot(EquipmentSlots slot)
Definition: Player.cpp:4719

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

Referenced by handle_immediate(), and HandleLaunchPhase().

◆ TakeCastItem()

void Spell::TakeCastItem ( )
5215{
5217 return;
5218
5219 // not remove cast item at triggered spell (equipping, weapon damage, etc)
5221 return;
5222
5223 ItemTemplate const* proto = m_CastItem->GetTemplate();
5224
5225 if (!proto)
5226 {
5227 // This code is to avoid a crash
5228 // I'm not sure, if this is really an error, but I guess every item needs a prototype
5229 LOG_ERROR("spells", "Cast item has no item prototype {}", m_CastItem->GetGUID().ToString());
5230 return;
5231 }
5232
5233 bool expendable = false;
5234 bool withoutCharges = false;
5235
5236 for (int i = 0; i < MAX_ITEM_PROTO_SPELLS; ++i)
5237 {
5238 if (proto->Spells[i].SpellId)
5239 {
5240 // item has limited charges
5241 if (proto->Spells[i].SpellCharges)
5242 {
5243 if (proto->Spells[i].SpellCharges < 0)
5244 expendable = true;
5245
5246 int32 charges = m_CastItem->GetSpellCharges(i);
5247
5248 // item has charges left
5249 if (charges)
5250 {
5251 (charges > 0) ? --charges : ++charges; // std::abs(charges) less at 1 after use
5252 if (proto->Stackable == 1)
5253 m_CastItem->SetSpellCharges(i, charges);
5255 }
5256
5257 // all charges used
5258 withoutCharges = (charges == 0);
5259 }
5260 }
5261 }
5262
5263 if (expendable && withoutCharges)
5264 {
5265 uint32 count = 1;
5266 m_caster->ToPlayer()->DestroyItemCount(m_CastItem, count, true);
5267
5268 // prevent crash at access to deleted m_targets.GetItemTarget
5270 m_targets.SetItemTarget(nullptr);
5271
5272 m_CastItem = nullptr;
5274 }
5275}
void SetSpellCharges(uint8 index, int32 value)
Definition: Item.h:309
int32 Stackable
Definition: ItemTemplate.h:654

References _triggeredCastFlags, ObjectGuid::Clear(), Player::DestroyItemCount(), Object::GetGUID(), SpellCastTargets::GetItemTarget(), Item::GetSpellCharges(), Item::GetTemplate(), Object::GetTypeId(), 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(), TRIGGERED_IGNORE_CAST_ITEM, and TYPEID_PLAYER.

Referenced by _cast(), and handle_immediate().

◆ TakePower()

void Spell::TakePower ( )
5278{
5280 return;
5281
5282 //Don't take power if the spell is cast while .cheat power is enabled.
5285 return;
5286
5288 bool hit = true;
5290 {
5292 if (ObjectGuid targetGUID = m_targets.GetUnitTargetGUID())
5293 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
5294 if (ihit->targetGUID == targetGUID)
5295 {
5296 if (ihit->missCondition != SPELL_MISS_NONE && ihit->missCondition != SPELL_MISS_BLOCK && ihit->missCondition != SPELL_MISS_ABSORB && ihit->missCondition != SPELL_MISS_REFLECT)
5297 {
5298 hit = false;
5299 //lower spell cost on fail (by talent aura)
5300 if (Player* modOwner = m_caster->ToPlayer()->GetSpellModOwner())
5301 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_SPELL_COST_REFUND_ON_FAIL, m_powerCost, this);
5302 }
5303 break;
5304 }
5305 }
5306
5307 if (PowerType == POWER_RUNE)
5308 {
5309 TakeRunePower(hit);
5310 return;
5311 }
5312
5313 if (!m_powerCost)
5314 return;
5315
5316 // health as power used
5317 if (PowerType == POWER_HEALTH)
5318 {
5320 return;
5321 }
5322
5323 if (PowerType >= MAX_POWERS)
5324 {
5325 LOG_ERROR("spells", "Spell::TakePower: Unknown power type '{}'", PowerType);
5326 return;
5327 }
5328
5329 if (hit)
5331 else
5333
5334 // Set the five second timer
5335 if (PowerType == POWER_MANA && m_powerCost > 0)
5336 {
5338 }
5339}
@ SPELLMOD_SPELL_COST_REFUND_ON_FAIL
Definition: SpellDefines.h:107
@ SPELL_MISS_ABSORB
Definition: SharedDefines.h:1501
int32 ModifyHealth(int32 val)
Definition: Unit.cpp:13993
void SetLastManaUse(uint32 spellCastTime)
Definition: Unit.h:2217
void TakeRunePower(bool didHit)
Definition: Spell.cpp:5424

References CHEAT_POWER, Player::GetCommandStatus(), GameTime::GetGameTimeMS(), Unit::GetSpellModOwner(), Object::GetTypeId(), SpellCastTargets::GetUnitTargetGUID(), SpellInfo::Id, irand(), 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(), Object::ToPlayer(), and TYPEID_PLAYER.

Referenced by _cast().

◆ TakeReagents()

void Spell::TakeReagents ( )
5494{
5496 return;
5497
5498 ItemTemplate const* castItemTemplate = m_CastItem ? m_CastItem->GetTemplate() : nullptr;
5499
5500 // do not take reagents for these item casts
5501 if (castItemTemplate && castItemTemplate->Flags & ITEM_FLAG_NO_REAGENT_COST)
5502 return;
5503
5504 Player* p_caster = m_caster->ToPlayer();
5505 if (p_caster->CanNoReagentCast(m_spellInfo))
5506 return;
5507
5508 for (uint32 x = 0; x < MAX_SPELL_REAGENTS; ++x)
5509 {
5510 if (m_spellInfo->Reagent[x] <= 0)
5511 continue;
5512
5513 uint32 itemid = m_spellInfo->Reagent[x];
5514 uint32 itemcount = m_spellInfo->ReagentCount[x];
5515
5516 // if CastItem is also spell reagent
5517 if (castItemTemplate && castItemTemplate->ItemId == itemid)
5518 {
5519 for (int s = 0; s < MAX_ITEM_PROTO_SPELLS; ++s)
5520 {
5521 // CastItem will be used up and does not count as reagent
5522 int32 charges = m_CastItem->GetSpellCharges(s);
5523 if (castItemTemplate->Spells[s].SpellCharges < 0 && std::abs(charges) < 2)
5524 {
5525 ++itemcount;
5526 break;
5527 }
5528 }
5529
5530 m_CastItem = nullptr;
5532 }
5533
5534 // if GetItemTarget is also spell reagent
5535 if (m_targets.GetItemTargetEntry() == itemid)
5536 m_targets.SetItemTarget(nullptr);
5537
5538 p_caster->DestroyItemCount(itemid, itemcount, true);
5539 }
5540}
uint32 ItemId
Definition: ItemTemplate.h:629

References Player::CanNoReagentCast(), ObjectGuid::Clear(), Player::DestroyItemCount(), ItemTemplate::Flags, SpellCastTargets::GetItemTargetEntry(), Item::GetSpellCharges(), Item::GetTemplate(), Object::GetTypeId(), 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, Object::ToPlayer(), and TYPEID_PLAYER.

Referenced by _cast().

◆ TakeRunePower()

void Spell::TakeRunePower ( bool  didHit)
5425{
5427 return;
5428
5429 SpellRuneCostEntry const* runeCostData = sSpellRuneCostStore.LookupEntry(m_spellInfo->RuneCostID);
5430 if (!runeCostData || (runeCostData->NoRuneCost() && runeCostData->NoRunicPowerGain()))
5431 return;
5432
5433 Player* player = m_caster->ToPlayer();
5434 m_runesState = player->GetRunesState(); // store previous state
5435
5436 int32 runeCost[NUM_RUNE_TYPES]; // blood, frost, unholy, death
5437
5438 for (uint32 i = 0; i < RUNE_DEATH; ++i)
5439 {
5440 runeCost[i] = runeCostData->RuneCost[i];
5441 if (Player* modOwner = m_caster->GetSpellModOwner())
5442 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_COST, runeCost[i], this);
5443 }
5444
5445 runeCost[RUNE_DEATH] = 0; // calculated later
5446
5447 for (uint32 i = 0; i < MAX_RUNES; ++i)
5448 {
5449 RuneType rune = player->GetCurrentRune(i);
5450 if (!player->GetRuneCooldown(i) && runeCost[rune] > 0)
5451 {
5452 player->SetRuneCooldown(i, didHit ? player->GetRuneBaseCooldown(i, false) : uint32(RUNE_MISS_COOLDOWN));
5453 player->SetLastUsedRune(rune);
5454 runeCost[rune]--;
5455 }
5456 }
5457
5458 // Xinef: firstly consume death runes of base type
5459 // Xinef: in second loop consume all available
5460 for (uint8 loop = 0; loop < 2; ++loop)
5461 {
5462 runeCost[RUNE_DEATH] = runeCost[RUNE_BLOOD] + runeCost[RUNE_UNHOLY] + runeCost[RUNE_FROST];
5463 if (runeCost[RUNE_DEATH] > 0)
5464 {
5465 for (uint8 i = 0; i < MAX_RUNES; ++i)
5466 {
5467 RuneType rune = player->GetCurrentRune(i);
5468 if (!player->GetRuneCooldown(i) && rune == RUNE_DEATH && (loop ? true : (runeCost[player->GetBaseRune(i)] > 0)))
5469 {
5470 player->SetRuneCooldown(i, didHit ? player->GetRuneBaseCooldown(i, false) : uint32(RUNE_MISS_COOLDOWN));
5471 player->SetLastUsedRune(rune);
5472 runeCost[rune]--;
5473 if (!loop)
5474 runeCost[player->GetBaseRune(i)]--;
5475
5476 // keep Death Rune type if missed
5477 if (didHit)
5478 player->RestoreBaseRune(i);
5479
5480 if (runeCost[RUNE_DEATH] == 0)
5481 break;
5482 }
5483 }
5484 }
5485 }
5486
5487 // you can gain some runic power when use runes
5488 if (didHit)
5489 if (int32 rp = int32(runeCostData->runePowerGain * sWorld->getRate(RATE_POWER_RUNICPOWER_INCOME)))
5490 player->ModifyPower(POWER_RUNIC_POWER, int32(rp));
5491}
@ RUNE_UNHOLY
Definition: Player.h:411
@ RUNE_BLOOD
Definition: Player.h:410
@ RUNE_MISS_COOLDOWN
Definition: Player.h:405
@ RATE_POWER_RUNICPOWER_INCOME
Definition: IWorld.h:425
void SetLastUsedRune(RuneType type)
Definition: Player.h:2463
uint32 GetRuneBaseCooldown(uint8 index, bool skipGrace)
Definition: Player.cpp:13260
void RestoreBaseRune(uint8 index)
Definition: Player.cpp:13289
bool NoRunicPowerGain() const
Definition: DBCStructure.h:1786
uint32 runePowerGain
Definition: DBCStructure.h:1783

References CLASS_DEATH_KNIGHT, Player::GetBaseRune(), Unit::getClass(), Player::GetCurrentRune(), Player::GetRuneBaseCooldown(), Player::GetRuneCooldown(), Player::GetRunesState(), Unit::GetSpellModOwner(), Object::GetTypeId(), SpellInfo::Id, 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, Object::ToPlayer(), and TYPEID_PLAYER.

Referenced by TakePower().

◆ TriggerGlobalCooldown()

void Spell::TriggerGlobalCooldown ( )
protected
8801{
8803 if (!gcd)
8804 {
8805 // Xinef: fix for charmed pet spells with no cooldown info
8807 gcd = MIN_GCD;
8808 else
8809 return;
8810 }
8811
8814 return;
8815
8816 // Global cooldown can't leave range 1..1.5 secs
8817 // There are some spells (mostly not casted directly by player) that have < 1 sec and > 1.5 sec global cooldowns
8818 // but as tests show are not affected by any spell mods.
8820 {
8821 // gcd modifier auras are applied only to own spells and only players have such mods
8824
8825 // Apply haste rating
8828 {
8829 gcd = int32(float(gcd) * m_caster->GetFloatValue(UNIT_MOD_CAST_SPEED));
8830 }
8831
8832 if (gcd < MIN_GCD)
8833 gcd = MIN_GCD;
8834 else if (gcd > MAX_GCD)
8835 gcd = MAX_GCD;
8836 }
8837
8838 // Only players or controlled units have global cooldown
8839 if (m_caster->GetCharmInfo())
8841 else if (m_caster->GetTypeId() == TYPEID_PLAYER)
8843}
@ MIN_GCD
Definition: Spell.cpp:8785
@ MAX_GCD
Definition: Spell.cpp:8786
@ SPELLMOD_GLOBAL_COOLDOWN
Definition: SpellDefines.h:98
void AddGlobalCooldown(SpellInfo const *spellInfo, uint32 gcd)
Definition: Unit.cpp:347

References GlobalCooldownMgr::AddGlobalCooldown(), Player::ApplySpellMod(), SpellInfo::CategoryRecoveryTime, CHEAT_COOLDOWN, SpellInfo::DmgClass, Unit::GetCharmInfo(), Player::GetCommandStatus(), Object::GetFloatValue(), Player::GetGlobalCooldownMgr(), CharmInfo::GetGlobalCooldownMgr(), Object::GetTypeId(), SpellInfo::HasAttribute(), SpellInfo::Id, 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(), TYPEID_PLAYER, and UNIT_MOD_CAST_SPEED.

Referenced by prepare().

◆ update()

void Spell::update ( uint32  difftime)
4369{
4370 // update pointers based at it's GUIDs
4371 if (!UpdatePointers())
4372 {
4373 // cancel the spell if UpdatePointers() returned false, something wrong happened there
4374 cancel();
4375 return;
4376 }
4377
4379 {
4380 LOG_DEBUG("spells.aura", "Spell {} is cancelled due to removal of target.", m_spellInfo->Id);
4381 cancel();
4382 return;
4383 }
4384
4385 // check if the player caster has moved before the spell finished
4386 // xinef: added preparing state (real cast, skip channels as they have other flags for this)
4387 if ((m_caster->GetTypeId() == TYPEID_PLAYER && m_timer != 0) &&
4390 {
4391 // don't cancel for melee, autorepeat, triggered and instant spells
4393 cancel(true);
4394 }
4395
4396 switch (m_spellState)
4397 {
4399 {
4400 if (m_timer > 0)
4401 {
4402 if (difftime >= (uint32)m_timer)
4403 m_timer = 0;
4404 else
4405 m_timer -= difftime;
4406 }
4407
4408 if (m_timer == 0 && !IsNextMeleeSwingSpell() && !IsAutoRepeat())
4409 // don't CheckCast for instant spells - done in spell::prepare, skip duplicate checks, needed for range checks for example
4410 cast(!m_casttime);
4411 break;
4412 }
4414 {
4415 if (m_timer)
4416 {
4417 if (m_timer > 0)
4418 {
4419 if (difftime >= (uint32)m_timer)
4420 m_timer = 0;
4421 else
4422 m_timer -= difftime;
4423 }
4424 }
4425
4426 if (m_timer == 0)
4427 {
4429
4430 finish();
4431 }
4432 // Xinef: Dont update channeled target list on last tick, allow auras to update duration properly
4433 // Xinef: Added this strange check because of diffrent update routines for players / creatures
4434 // Xinef: If creature gets new aura in 800ms and in 840ms its updated with diff 270, not 40 is removed from duration but 270
4435 // Xinef: so the aura can be removed in different updates for all units
4436 else if ((m_timer < 0 || m_timer > 300) && !UpdateChanneledTargetList())
4437 {
4438 LOG_DEBUG("spells.aura", "Channeled spell {} is removed due to lack of targets", m_spellInfo->Id);
4440 finish();
4441 }
4442 break;
4443 }
4444 default:
4445 break;
4446 }
4447}
bool UpdateChanneledTargetList()
Definition: Spell.cpp:3362

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

Referenced by SpellEvent::Execute().

◆ UpdateChanneledTargetList()

bool Spell::UpdateChanneledTargetList ( )
protected
3363{
3364 // Not need check return true
3366 return true;
3367
3368 uint8 channelTargetEffectMask = m_channelTargetEffectMask;
3369 uint8 channelAuraMask = 0;
3370 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
3372 channelAuraMask |= 1 << i;
3373
3374 channelAuraMask &= channelTargetEffectMask;
3375
3376 float range = 0;
3377 if (channelAuraMask)
3378 {
3380 if (range == 0)
3381 for(int i = EFFECT_0; i <= EFFECT_2; ++i)
3382 if (channelAuraMask & (1 << i) && m_spellInfo->Effects[i].RadiusEntry)
3383 {
3384 range = m_spellInfo->Effects[i].CalcRadius(nullptr, nullptr);
3385 break;
3386 }
3387
3388 if (Player* modOwner = m_caster->GetSpellModOwner())
3389 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_RANGE, range, this);
3390
3391 // xinef: add little tolerance level
3392 range += std::min(3.0f, range * 0.1f); // 10% but no more than 3yd
3393 }
3394
3395 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
3396 {
3397 if (ihit->missCondition == SPELL_MISS_NONE && (channelTargetEffectMask & ihit->effectMask))
3398 {
3399 Unit* unit = m_caster->GetGUID() == ihit->targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID);
3400
3401 if (!unit)
3402 continue;
3403
3404 if (IsValidDeadOrAliveTarget(unit))
3405 {
3406 if (channelAuraMask & ihit->effectMask)
3407 {
3409 {
3410 if (m_caster != unit)
3411 {
3412 if (!m_caster->IsWithinDistInMap(unit, range))
3413 {
3414 ihit->effectMask &= ~aurApp->GetEffectMask();
3415 unit->RemoveAura(aurApp);
3416 continue;
3417 }
3418 // Xinef: Update Orientation server side (non players wont sent appropriate packets)
3421 }
3422 }
3423 else // aura is dispelled
3424 continue;
3425 }
3426
3427 channelTargetEffectMask &= ~ihit->effectMask; // remove from need alive mask effect that have alive target
3428 }
3429 }
3430 }
3431
3432 // Xinef: not all effects are covered, remove applications from all targets
3433 if (channelTargetEffectMask != 0)
3434 {
3435 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
3436 if (ihit->missCondition == SPELL_MISS_NONE && (channelAuraMask & ihit->effectMask))
3437 if (Unit* unit = m_caster->GetGUID() == ihit->targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID))
3438 if (IsValidDeadOrAliveTarget(unit))
3440 {
3441 ihit->effectMask &= ~aurApp->GetEffectMask();
3442 unit->RemoveAura(aurApp);
3443 }
3444 }
3445
3446 // is all effects from m_needAliveTargetMask have alive targets
3447 return channelTargetEffectMask == 0;
3448}
@ SPELL_ATTR1_TRACK_TARGET_IN_CHANNEL
Definition: SharedDefines.h:405
bool IsWithinDistInMap(WorldObject const *obj, float dist2compare, bool is3D=true, bool useBoundingRadius=true) const
Definition: Object.cpp:1321
AuraApplication * GetAuraApplication(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemCasterGUID=ObjectGuid::Empty, uint8 reqEffMask=0, AuraApplication *except=nullptr) const
Definition: Unit.cpp:5480
void UpdateOrientation(float orientation)
Only server-side orientation update, does not broadcast to client.
Definition: Unit.cpp:20232
bool IsValidDeadOrAliveTarget(Unit const *target) const
Definition: Spell.cpp:8183

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

Referenced by update().

◆ UpdatePointers()

bool Spell::UpdatePointers ( )
7825{
7828 else
7829 {
7832 m_originalCaster = nullptr;
7833 }
7834
7836 {
7838 // cast item not found, somehow the item is no longer where we expected
7839 if (!m_CastItem)
7840 return false;
7841 }
7842 else
7843 m_CastItem = nullptr;
7844
7846
7847 // further actions done only for dest targets
7848 if (!m_targets.HasDst())
7849 return true;
7850
7851 // cache last transport
7852 WorldObject* transport = nullptr;
7853
7854 // update effect destinations (in case of moved transport dest target)
7855 for (uint8 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
7856 {
7857 SpellDestination& dest = m_destTargets[effIndex];
7858 if (!dest._transportGUID)
7859 continue;
7860
7861 if (!transport || transport->GetGUID() != dest._transportGUID)
7863
7864 if (transport)
7865 {
7866 dest._position.Relocate(transport);
7868 }
7869 }
7870
7871 return true;
7872}
WorldObject * GetWorldObject(WorldObject const &, ObjectGuid const guid)
Definition: ObjectAccessor.cpp:120
void RelocateOffset(const Position &offset)
Definition: Position.cpp:58
Position _transportOffset
Definition: Spell.h:105
ObjectGuid _transportGUID
Definition: Spell.h:104
void Update(Unit *caster)
Definition: Spell.cpp:473

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

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

◆ WriteAmmoToPacket()

void Spell::WriteAmmoToPacket ( WorldPacket data)
4891{
4892 uint32 ammoInventoryType = 0;
4893 uint32 ammoDisplayID = 0;
4894
4896 {
4898 if (pItem)
4899 {
4900 ammoInventoryType = pItem->GetTemplate()->InventoryType;
4901 if (ammoInventoryType == INVTYPE_THROWN)
4902 ammoDisplayID = pItem->GetTemplate()->DisplayInfoID;
4903 else
4904 {
4906 if (ammoID)
4907 {
4908 ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(ammoID);
4909 if (pProto)
4910 {
4911 ammoDisplayID = pProto->DisplayInfoID;
4912 ammoInventoryType = pProto->InventoryType;
4913 }
4914 }
4915 else if (m_caster->HasAura(46699)) // Requires No Ammo
4916 {
4917 ammoDisplayID = 5996; // normal arrow
4918 ammoInventoryType = INVTYPE_AMMO;
4919 }
4920 }
4921 }
4922 }
4923 else
4924 {
4925 uint32 nonRangedAmmoDisplayID = 0;
4926 uint32 nonRangedAmmoInventoryType = 0;
4927 for (uint8 i = 0; i < 3; ++i)
4928 {
4930 {
4931 if (ItemTemplate const* itemEntry = sObjectMgr->GetItemTemplate(item_id))
4932 {
4933 if (itemEntry->Class == ITEM_CLASS_WEAPON)
4934 {
4935 switch (itemEntry->SubClass)
4936 {
4938 ammoDisplayID = itemEntry->DisplayInfoID;
4939 ammoInventoryType = itemEntry->InventoryType;
4940 break;
4943 ammoDisplayID = 5996; // is this need fixing?
4944 ammoInventoryType = INVTYPE_AMMO;
4945 break;
4947 ammoDisplayID = 5998; // is this need fixing?
4948 ammoInventoryType = INVTYPE_AMMO;
4949 break;
4950 default:
4951 nonRangedAmmoDisplayID = itemEntry->DisplayInfoID;
4952 nonRangedAmmoInventoryType = itemEntry->InventoryType;
4953 break;
4954 }
4955
4956 if (ammoDisplayID)
4957 break;
4958 }
4959 }
4960 }
4961 }
4962
4963 if (!ammoDisplayID && !ammoInventoryType)
4964 {
4965 ammoDisplayID = nonRangedAmmoDisplayID;
4966 ammoInventoryType = nonRangedAmmoInventoryType;
4967 }
4968 }
4969
4970 *data << uint32(ammoDisplayID);
4971 *data << uint32(ammoInventoryType);
4972}
@ INVTYPE_AMMO
Definition: ItemTemplate.h:289
@ UNIT_VIRTUAL_ITEM_SLOT_ID
Definition: UpdateFields.h:116
uint32 DisplayInfoID
Definition: ItemTemplate.h:634

References ItemTemplate::DisplayInfoID, Item::GetTemplate(), Object::GetTypeId(), Object::GetUInt32Value(), Player::GetWeaponForAttack(), Unit::HasAura(), ItemTemplate::InventoryType, INVTYPE_AMMO, INVTYPE_THROWN, 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, sObjectMgr, Object::ToPlayer(), TYPEID_PLAYER, 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
4527{
4528 data << uint8(castCount); // single cast or multi 2.3 (0/1)
4529 data << uint32(spellInfo->Id);
4530 data << uint8(result); // problem
4531 switch (result)
4532 {
4534 data << uint32(spellInfo->RequiresSpellFocus); // SpellFocusObject.dbc id
4535 break;
4536 case SPELL_FAILED_REQUIRES_AREA: // AreaTable.dbc id
4537 // hardcode areas limitation case
4538 switch (spellInfo->Id)
4539 {
4540 case 41617: // Cenarion Mana Salve
4541 case 41619: // Cenarion Healing Salve
4542 data << uint32(3905);
4543 break;
4544 case 41618: // Bottled Nethergon Energy
4545 case 41620: // Bottled Nethergon Vapor
4546 data << uint32(3842);
4547 break;
4548 case 45373: // Bloodberry Elixir
4549 data << uint32(4075);
4550 break;
4551 default: // default case (don't must be)
4552 data << uint32(0);
4553 break;
4554 }
4555 break;
4557 if (spellInfo->Totem[0])
4558 data << uint32(spellInfo->Totem[0]);
4559 if (spellInfo->Totem[1])
4560 data << uint32(spellInfo->Totem[1]);
4561 break;
4563 if (spellInfo->TotemCategory[0])
4564 data << uint32(spellInfo->TotemCategory[0]);
4565 if (spellInfo->TotemCategory[1])
4566 data << uint32(spellInfo->TotemCategory[1]);
4567 break;
4571 data << uint32(spellInfo->EquippedItemClass);
4572 data << uint32(spellInfo->EquippedItemSubClassMask);
4573 break;
4575 {
4576 uint32 item = 0;
4577 for (int8 eff = 0; eff < MAX_SPELL_EFFECTS; eff++)
4578 if (spellInfo->Effects[eff].ItemType)
4579 item = spellInfo->Effects[eff].ItemType;
4580 ItemTemplate const* proto = sObjectMgr->GetItemTemplate(item);
4581 if (proto && proto->ItemLimitCategory)
4582 data << uint32(proto->ItemLimitCategory);
4583 break;
4584 }
4586 data << uint32(customError);
4587 break;
4589 {
4590 uint32 missingItem = 0;
4591 for (uint32 i = 0; i < MAX_SPELL_REAGENTS; i++)
4592 {
4593 if (spellInfo->Reagent[i] <= 0)
4594 continue;
4595
4596 uint32 itemid = spellInfo->Reagent[i];
4597 uint32 itemcount = spellInfo->ReagentCount[i];
4598
4599 if (!caster->HasItemCount(itemid, itemcount))
4600 {
4601 missingItem = itemid;
4602 break;
4603 }
4604 }
4605
4606 data << uint32(missingItem); // first missing item
4607 break;
4608 }
4610 data << uint32(spellInfo->Mechanic);
4611 break;
4613 data << uint32(spellInfo->EquippedItemSubClassMask);
4614 break;
4616 data << uint32(0); // Item entry
4617 data << uint32(0); // Count
4618 break;
4620 data << uint32(0); // SkillLine.dbc Id
4621 data << uint32(0); // Amount
4622 break;
4624 data << uint32(0); // Skill level
4625 break;
4626 default:
4627 break;
4628 }
4629}
@ SPELL_FAILED_NEED_EXOTIC_AMMO
Definition: SharedDefines.h:975
@ SPELL_FAILED_FISHING_TOO_LOW
Definition: SharedDefines.h:1102
@ SPELL_FAILED_MIN_SKILL
Definition: SharedDefines.h:1071
@ SPELL_FAILED_PREVENTED_BY_MECHANIC
Definition: SharedDefines.h:1068
@ SPELL_FAILED_REQUIRES_AREA
Definition: SharedDefines.h:1022

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.

4976{
4977 // This function also fill data for channeled spells:
4978 // m_needAliveTargetMask req for stop channelig if one target die
4979 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
4980 {
4981 if ((*ihit).effectMask == 0) // No effect apply - all immuned add state
4982 // possibly SPELL_MISS_IMMUNE2 for this??
4983 ihit->missCondition = SPELL_MISS_IMMUNE2;
4984 }
4985
4986 // Hit and miss target counts are both uint8, that limits us to 255 targets for each
4987 // sending more than 255 targets crashes the client (since count sent would be wrong)
4988 // Spells like 40647 (with a huge radius) can easily reach this limit (spell might need
4989 // target conditions but we still need to limit the number of targets sent and keeping
4990 // correct count for both hit and miss).
4991
4992 uint32 hit = 0;
4993 size_t hitPos = data->wpos();
4994 *data << (uint8)0; // placeholder
4995 for (std::list<TargetInfo>::const_iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end() && hit < 255; ++ihit)
4996 {
4997 if ((*ihit).missCondition == SPELL_MISS_NONE) // Add only hits
4998 {
4999 *data << ihit->targetGUID;
5000 // Xinef: No channeled spell checked, no anything
5001 //m_channelTargetEffectMask |=ihit->effectMask;
5002 ++hit;
5003 }
5004 }
5005
5006 for (std::list<GOTargetInfo>::const_iterator ighit = m_UniqueGOTargetInfo.begin(); ighit != m_UniqueGOTargetInfo.end() && hit < 255; ++ighit)
5007 {
5008 *data << ighit->targetGUID; // Always hits
5009 ++hit;
5010 }
5011
5012 uint32 miss = 0;
5013 size_t missPos = data->wpos();
5014 *data << (uint8)0; // placeholder
5015 for (std::list<TargetInfo>::const_iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end() && miss < 255; ++ihit)
5016 {
5017 if (ihit->missCondition != SPELL_MISS_NONE) // Add only miss
5018 {
5019 *data << ihit->targetGUID;
5020 *data << uint8(ihit->missCondition);
5021 if (ihit->missCondition == SPELL_MISS_REFLECT)
5022 *data << uint8(ihit->reflectResult);
5023 ++miss;
5024 }
5025 }
5026 // Reset m_needAliveTargetMask for non channeled spell
5027 // Xinef: Why do we reset something that is not set??????
5028 //if (!m_spellInfo->IsChanneled())
5029 // m_channelTargetEffectMask = 0;
5030
5031 data->put<uint8>(hitPos, (uint8)hit);
5032 data->put<uint8>(missPos, (uint8)miss);
5033}
size_t wpos() const
Definition: ByteBuffer.h:330
void put(std::size_t pos, T value)
Definition: ByteBuffer.h:137

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

Referenced by SendSpellGo().

Friends And Related Function Documentation

◆ SpellScript

friend class SpellScript
friend

◆ Unit::SetCurrentCastedSpell

void Unit::SetCurrentCastedSpell ( Spell pSpell)
friend

Member Data Documentation

◆ _scriptsLoaded

bool Spell::_scriptsLoaded
protected

Referenced by LoadScripts(), and Spell().

◆ _spellEvent

SpellEvent* Spell::_spellEvent
protected

◆ _spellTargetsSelected

bool Spell::_spellTargetsSelected
protected

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

◆ _triggeredCastFlags

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

◆ m_CastItem

◆ m_castItemGUID

◆ m_casttime

◆ m_channeledDuration

int32 Spell::m_channeledDuration
protected

◆ m_channelTargetEffectMask

uint8 Spell::m_channelTargetEffectMask
protected

◆ m_comboPointGain

int8 Spell::m_comboPointGain

◆ m_comboTarget

Unit* Spell::m_comboTarget

◆ m_customError

◆ m_damage

◆ m_damageMultipliers

float Spell::m_damageMultipliers[3]
protected

◆ m_delayAtDamageCount

uint8 Spell::m_delayAtDamageCount
protected

Referenced by isDelayableNoMore(), and Spell().

◆ m_delayMoment

◆ m_delayStart

uint64 Spell::m_delayStart
protected

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

◆ m_delayTrajectory

uint64 Spell::m_delayTrajectory
protected

◆ m_destTargets

SpellDestination Spell::m_destTargets[MAX_SPELL_EFFECTS]
protected

◆ m_diminishGroup

DiminishingGroup Spell::m_diminishGroup
protected

◆ m_diminishLevel

DiminishingLevels Spell::m_diminishLevel
protected

◆ m_effectExecuteData

◆ m_executedCurrently

bool Spell::m_executedCurrently
protected

◆ m_glyphIndex

uint32 Spell::m_glyphIndex

◆ m_healing

◆ m_hitTriggerSpells

HitTriggerSpellList Spell::m_hitTriggerSpells
protected

◆ m_immediateHandled

bool Spell::m_immediateHandled
protected

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

◆ m_loadedScripts

◆ m_needComboPoints

bool Spell::m_needComboPoints
protected

◆ m_originalCaster

◆ m_originalCasterGUID

◆ m_powerCost

◆ m_preCastSpell

uint32 Spell::m_preCastSpell

◆ m_preGeneratedPath

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

Referenced by CheckCast(), and EffectCharge().

◆ m_procAttacker

uint32 Spell::m_procAttacker
protected

◆ m_procEx

uint32 Spell::m_procEx
protected

◆ m_procVictim

uint32 Spell::m_procVictim
protected

◆ m_referencedFromCurrentSpell

bool Spell::m_referencedFromCurrentSpell
protected

◆ m_runesState

uint8 Spell::m_runesState
protected

◆ m_selfContainer

Spell** Spell::m_selfContainer
protected

◆ m_skipCheck

bool Spell::m_skipCheck
protected

Referenced by AddUnitTarget(), and Spell().

◆ m_spellAura

◆ m_spellFlags

◆ m_spellInfo

SpellInfo const* const Spell::m_spellInfo

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

◆ m_spellSchoolMask

◆ m_spellState

uint32 Spell::m_spellState
protected

◆ m_spellValue

◆ m_targets

SpellCastTargets Spell::m_targets

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

◆ m_timer

◆ m_triggeredByAuraSpell

◆ m_UniqueGOTargetInfo

◆ m_UniqueItemInfo

◆ m_UniqueTargetInfo

◆ m_weaponItem

Item* Spell::m_weaponItem

◆ unitTarget

Unit* Spell::unitTarget
protected

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