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

#include "Spell.h"

Classes

struct  GOTargetInfo
 
struct  HitTriggerSpell
 
struct  ItemTargetInfo
 

Public Types

typedef std::set< Aura * > UsedSpellMods
 

Public Member Functions

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

Static Public Member Functions

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

Public Attributes

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

Protected Types

typedef std::list< HitTriggerSpellHitTriggerSpellList
 

Protected Member Functions

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

Protected Attributes

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

Friends

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

Detailed Description

Member Typedef Documentation

◆ HitTriggerSpellList

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

◆ UsedSpellMods

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

Constructor & Destructor Documentation

◆ Spell()

Spell::Spell ( Unit caster,
SpellInfo const *  info,
TriggerCastFlags  triggerFlags,
ObjectGuid  originalCasterGUID = ObjectGuid::Empty,
bool  skipCheck = false 
)
568 :
569 m_spellInfo(sSpellMgr->GetSpellForDifficultyFromSpell(info, caster)),
570 m_caster((info->HasAttribute(SPELL_ATTR6_ORIGINATE_FROM_CONTROLLER) && caster->GetCharmerOrOwner()) ? caster->GetCharmerOrOwner() : caster)
572{
574 m_skipCheck = skipCheck;
575 m_selfContainer = nullptr;
577 m_executedCurrently = false;
580 m_comboTarget = nullptr;
581 m_delayStart = 0;
583
585 m_auraScaleMask = 0;
586 memset(m_damageMultipliers, 0, sizeof(m_damageMultipliers));
587
588 // Get data for type of attack
589 switch (m_spellInfo->DmgClass)
590 {
594 else
596 break;
599 break;
600 default:
601 // Wands
604 else
606 break;
607 }
608
609 m_spellSchoolMask = info->GetSchoolMask(); // Can be override for some spell (wand shoot for example)
610
612 // wand case
615 m_spellSchoolMask = SpellSchoolMask(1 << pItem->GetTemplate()->Damage[0].DamageType);
616
617 if (originalCasterGUID)
618 m_originalCasterGUID = originalCasterGUID;
619 else
621
624 else
625 {
628 m_originalCaster = nullptr;
629 }
630
632 _triggeredCastFlags = triggerFlags;
633 if (info->HasAttribute(SPELL_ATTR4_ALLOW_CAST_WHILE_CASTING))
635
636 m_CastItem = nullptr;
637
638 unitTarget = nullptr;
639 itemTarget = nullptr;
640 gameObjTarget = nullptr;
641 destTarget = nullptr;
642 damage = 0;
646 m_damage = 0;
647 m_healing = 0;
648 m_procAttacker = 0;
649 m_procVictim = 0;
650 m_procEx = 0;
651 focusObject = nullptr;
652 m_cast_count = 0;
653 m_glyphIndex = 0;
654 m_preCastSpell = 0;
655 m_spellAura = nullptr;
656 _scriptsLoaded = false;
657
658 //Auto Shot & Shoot (wand)
660
661 m_runesState = 0;
662 m_powerCost = 0; // setup to correct value in Spell::prepare, must not be used before.
663 m_casttime = 0; // setup to correct value in Spell::prepare, must not be used before.
664 m_timer = 0; // will set to castime in prepare
665 m_channeledDuration = 0; // will be setup in Spell::handle_immediate
666 m_immediateHandled = false;
667
669
671
672 // Determine if spell can be reflected back to the caster
673 // Patch 1.2 notes: Spell Reflection no longer reflects abilities
677
679 memset(m_effectExecuteData, 0, MAX_SPELL_EFFECTS * sizeof(ByteBuffer*));
680
681 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
683
684 // xinef:
685 _spellTargetsSelected = false;
686
687 m_weaponItem = nullptr;
688}
std::uint8_t uint8
Definition: Define.h:109
std::uint32_t uint32
Definition: Define.h:107
@ OFF_ATTACK
Definition: Unit.h:210
@ BASE_ATTACK
Definition: Unit.h:209
@ RANGED_ATTACK
Definition: Unit.h:211
@ DIMINISHING_LEVEL_1
Definition: Unit.h:263
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:825
@ SPELL_EFFECT_HANDLE_LAUNCH
Definition: Spell.h:233
@ SPELL_FLAG_NORMAL
Definition: Spell.h:81
@ SPELL_STATE_NULL
Definition: Spell.h:223
@ DIMINISHING_NONE
Definition: SharedDefines.h:3258
@ SPELL_EFFECT_DISPEL
Definition: SharedDefines.h:816
#define CLASSMASK_WAND_USERS
Definition: SharedDefines.h:174
@ SPELL_ATTR2_AUTO_REPEAT
Definition: SharedDefines.h:461
@ SPELL_ATTR1_NO_REFLECTION
Definition: SharedDefines.h:426
@ SPELL_ATTR3_REQUIRES_OFF_HAND_WEAPON
Definition: SharedDefines.h:517
@ SPELL_DAMAGE_CLASS_RANGED
Definition: SharedDefines.h:1548
@ SPELL_DAMAGE_CLASS_MAGIC
Definition: SharedDefines.h:1546
@ SPELL_DAMAGE_CLASS_MELEE
Definition: SharedDefines.h:1547
@ SPELL_CUSTOM_ERROR_NONE
Definition: SharedDefines.h:1143
@ SPELL_ATTR0_IS_ABILITY
Definition: SharedDefines.h:386
@ SPELL_ATTR0_NO_IMMUNITIES
Definition: SharedDefines.h:411
@ SPELL_ATTR4_ALLOW_CAST_WHILE_CASTING
Definition: SharedDefines.h:537
@ SPELL_ATTR6_ORIGINATE_FROM_CONTROLLER
Definition: SharedDefines.h:622
SpellSchoolMask
Definition: SharedDefines.h:295
#define MAX_SPELL_EFFECTS
Definition: DBCStructure.h:1637
Unit * GetUnit(WorldObject const &, ObjectGuid const guid)
Definition: ObjectAccessor.cpp:202
Definition: Item.h:220
bool IsPlayer() const
Definition: Object.h:197
Player * ToPlayer()
Definition: Object.h:198
bool IsInWorld() const
Definition: Object.h:104
static ObjectGuid GetGUID(Object const *o)
Definition: Object.h:109
Item * GetWeaponForAttack(WeaponAttackType attackType, bool useable=false) const
Definition: PlayerStorage.cpp:494
Unit * GetCharmerOrOwner() const
Definition: Unit.h:1243
uint32 getClassMask() const
Definition: Unit.h:749
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:653
bool m_referencedFromCurrentSpell
Definition: Spell.h:644
bool m_canReflect
Definition: Spell.h:620
uint32 m_procVictim
Definition: Spell.h:675
Unit * m_originalCaster
Definition: Spell.h:608
bool m_needComboPoints
Definition: Spell.h:646
uint64 m_delayStart
Definition: Spell.h:638
bool _scriptsLoaded
Definition: Spell.h:726
TriggerCastFlags _triggeredCastFlags
Definition: Spell.h:767
int32 damage
Definition: Spell.h:655
SpellEffectHandleMode effectHandleMode
Definition: Spell.h:656
int32 m_channeledDuration
Definition: Spell.h:619
Aura * m_spellAura
Definition: Spell.h:658
SpellDestination m_destTargets[MAX_SPELL_EFFECTS]
Definition: Spell.h:701
Unit *const m_caster
Definition: Spell.h:602
uint8 m_delayAtDamageCount
Definition: Spell.h:627
WeaponAttackType m_attackType
Definition: Spell.h:616
bool m_immediateHandled
Definition: Spell.h:641
uint32 m_spellState
Definition: Spell.h:763
ObjectGuid m_originalCasterGUID
Definition: Spell.h:606
void CleanupTargetList()
Definition: Spell.cpp:2372
int32 m_timer
Definition: Spell.h:764
int32 m_casttime
Definition: Spell.h:618
Item * itemTarget
Definition: Spell.h:652
uint8 m_cast_count
Definition: Spell.h:524
int32 m_damage
Definition: Spell.h:668
bool m_executedCurrently
Definition: Spell.h:645
DiminishingLevels m_diminishLevel
Definition: Spell.h:661
float m_damageMultipliers[3]
Definition: Spell.h:648
ByteBuffer * m_effectExecuteData[MAX_SPELL_EFFECTS]
Definition: Spell.h:781
uint8 m_auraScaleMask
Definition: Spell.h:775
SpellCustomErrors m_customError
Definition: Spell.h:528
uint8 m_spellFlags
Definition: Spell.h:622
bool m_skipCheck
Definition: Spell.h:774
int32 m_healing
Definition: Spell.h:669
uint32 m_glyphIndex
Definition: Spell.h:525
uint8 m_channelTargetEffectMask
Definition: Spell.h:683
Item * m_weaponItem
Definition: Spell.h:522
Unit * unitTarget
Definition: Spell.h:651
SpellSchoolMask m_spellSchoolMask
Definition: Spell.h:615
SpellEvent * _spellEvent
Definition: Spell.h:766
bool _spellTargetsSelected
Definition: Spell.h:779
uint32 m_preCastSpell
Definition: Spell.h:526
WorldLocation * destTarget
Definition: Spell.h:654
Spell ** m_selfContainer
Definition: Spell.h:610
uint8 m_applyMultiplierMask
Definition: Spell.h:647
DiminishingGroup m_diminishGroup
Definition: Spell.h:662
uint32 m_procEx
Definition: Spell.h:676
Item * m_CastItem
Definition: Spell.h:521
SpellValue *const m_spellValue
Definition: Spell.h:604
int32 m_powerCost
Definition: Spell.h:617
uint32 m_procAttacker
Definition: Spell.h:674
GameObject * focusObject
Definition: Spell.h:665
SpellInfo const *const m_spellInfo
Definition: Spell.h:520
uint8 m_runesState
Definition: Spell.h:625
bool m_autoRepeat
Definition: Spell.h:624
bool IsPassive() const
Definition: SpellInfo.cpp:1097
bool NeedsComboPoints() const
Definition: SpellInfo.cpp:1265
bool HasAttribute(SpellAttr0 attribute) const
Definition: SpellInfo.h:415
bool HasEffect(SpellEffects effect) const
Definition: SpellInfo.cpp:875
bool IsPositive() const
Definition: SpellInfo.cpp:1236
bool IsAutoRepeatRangedSpell() const
Definition: SpellInfo.cpp:1282
uint32 DmgClass
Definition: SpellInfo.h:389
bool IsRangedWeaponSpell() const
Definition: SpellInfo.cpp:1275
Definition: ByteBuffer.h:70

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

◆ ~Spell()

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

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

Member Function Documentation

◆ _cast()

void Spell::_cast ( bool  skipCheck)

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

3801{
3802 // update pointers base at GUIDs to prevent access to non-existed already object
3803 if (!UpdatePointers())
3804 {
3805 // cancel the spell if UpdatePointers() returned false, something wrong happened there
3806 cancel();
3807 return;
3808 }
3809
3810 // cancel at lost explicit target during cast
3812 {
3813 cancel();
3814 return;
3815 }
3816
3817 // Xinef: implement attribute SPELL_ATTR1_DISMISS_PET_FIRST, on spell cast current pet is dismissed and charms are removed
3819 {
3821 if (Pet* pet = m_caster->ToPlayer()->GetPet())
3823
3824 if (Unit* charm = m_caster->GetCharm())
3825 charm->RemoveAurasByType(SPELL_AURA_MOD_CHARM, m_caster->GetGUID());
3826 }
3827
3828 if (Player* playerCaster = m_caster->ToPlayer())
3829 {
3830 // now that we've done the basic check, now run the scripts
3831 // should be done before the spell is actually executed
3832 sScriptMgr->OnPlayerSpellCast(playerCaster, this, skipCheck);
3833
3834 // As of 3.0.2 pets begin attacking their owner's target immediately
3835 // Let any pets know we've attacked something. Check DmgClass for harmful spells only
3836 // This prevents spells such as Hunter's Mark from triggering pet attack
3837 // xinef: take into account SPELL_ATTR3_SUPRESS_TARGET_PROCS
3839 if (!playerCaster->m_Controlled.empty())
3840 for (Unit::ControlSet::iterator itr = playerCaster->m_Controlled.begin(); itr != playerCaster->m_Controlled.end(); ++itr)
3841 if (Unit* pet = *itr)
3842 if (pet->IsAlive() && pet->IsCreature())
3843 pet->ToCreature()->AI()->OwnerAttacked(m_targets.GetUnitTarget());
3844 }
3845
3847
3851
3853
3854 Player* modOwner = m_caster->GetSpellModOwner();
3855 // skip check if done already (for instant cast spells for example)
3856 if (!skipCheck)
3857 {
3858 SpellCastResult castResult = CheckCast(false);
3859 if (castResult != SPELL_CAST_OK)
3860 {
3861 SendCastResult(castResult);
3862 SendInterrupted(0);
3863
3864 finish(false);
3865 SetExecutedCurrently(false);
3866 return;
3867 }
3868
3869 // additional check after cast bar completes (must not be in CheckCast)
3870 // if trade not complete then remember it in trade data
3872 {
3873 if (m_caster->IsPlayer())
3874 {
3875 if (TradeData* my_trade = m_caster->ToPlayer()->GetTradeData())
3876 {
3877 if (!my_trade->IsInAcceptProcess())
3878 {
3879 // Spell will be casted at completing the trade. Silently ignore at this place
3880 my_trade->SetSpell(m_spellInfo->Id, m_CastItem);
3882 SendInterrupted(0);
3883
3884 finish(false);
3885 SetExecutedCurrently(false);
3886 return;
3887 }
3888 }
3889 }
3890 }
3891 }
3892
3893 if (modOwner)
3894 modOwner->SetSpellModTakingSpell(this, true);
3895
3898
3899 if (modOwner)
3900 modOwner->SetSpellModTakingSpell(this, false);
3901
3902 // Spell may be finished after target map check
3904 {
3905 SendInterrupted(0);
3906 finish(false);
3907 SetExecutedCurrently(false);
3908 return;
3909 }
3910
3911 if (modOwner)
3912 modOwner->SetSpellModTakingSpell(this, true);
3913
3915
3917
3918 if (modOwner)
3919 modOwner->SetSpellModTakingSpell(this, false);
3920
3921 // traded items have trade slot instead of guid in m_itemTargetGUID
3922 // set to real guid to be sent later to the client
3924
3925 if (m_caster->IsPlayer())
3926 {
3928 {
3931 }
3932
3934 }
3935
3937 {
3938 // Powers have to be taken before SendSpellGo
3939 TakePower();
3940 TakeReagents(); // we must remove reagents before HandleEffects to allow place crafted item in same slot
3941 }
3942 else if (Item* targetItem = m_targets.GetItemTarget())
3943 {
3945 if (targetItem->GetOwnerGUID() != m_caster->GetGUID())
3946 TakeReagents();
3947 }
3948
3950
3951 // CAST SPELL
3952 if (modOwner)
3953 modOwner->SetSpellModTakingSpell(this, true);
3954
3956
3958
3959 // we must send smsg_spell_go packet before m_castItem delete in TakeCastItem()...
3960 SendSpellGo();
3961
3962 if (modOwner)
3963 modOwner->SetSpellModTakingSpell(this, false);
3964
3965 if (m_originalCaster)
3966 {
3967 // Handle procs on cast
3968 uint32 procAttacker = m_procAttacker;
3969 if (!procAttacker)
3970 {
3971 bool IsPositive = m_spellInfo->IsPositive();
3973 {
3975 }
3976 else
3977 {
3979 }
3980 }
3981
3982 uint32 procEx = PROC_EX_NORMAL_HIT;
3983
3984 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
3985 {
3986 if (ihit->missCondition != SPELL_MISS_NONE)
3987 {
3988 continue;
3989 }
3990
3991 if (!ihit->crit)
3992 {
3993 continue;
3994 }
3995
3996 procEx |= PROC_EX_CRITICAL_HIT;
3997 break;
3998 }
3999
4002 }
4003
4004 if (modOwner)
4005 modOwner->SetSpellModTakingSpell(this, true);
4006
4008 if (resetAttackTimers)
4009 {
4011 for (Unit::AuraEffectList::const_iterator i = vIgnoreReset.begin(); i != vIgnoreReset.end(); ++i)
4012 {
4013 if ((*i)->IsAffectedOnSpell(m_spellInfo))
4014 {
4015 resetAttackTimers = false;
4016 break;
4017 }
4018 }
4019 }
4020
4021 // Okay, everything is prepared. Now we need to distinguish between immediate and evented delayed spells
4022 if ((m_spellInfo->Speed > 0.0f && !m_spellInfo->IsChanneled())/* xinef: we dont need this || m_spellInfo->Id == 14157*/)
4023 {
4024 // Remove used for cast item if need (it can be already nullptr after TakeReagents call
4025 // in case delayed spell remove item at cast delay start
4026 TakeCastItem();
4027
4028 // Okay, maps created, now prepare flags
4029 m_immediateHandled = false;
4031 SetDelayStart(0);
4032
4035
4036 // remove all applied mods at this point
4037 // dont allow user to use them twice in case spell did not reach current target
4038 if (modOwner)
4039 modOwner->RemoveSpellMods(this);
4040
4041 // Xinef: why do we keep focus after spell is sent to air?
4042 // Xinef: Because of this, in the middle of some animation after setting targetguid to 0 etc
4043 // Xinef: we get focused to it out of nowhere...
4044 if (Creature* creatureCaster = m_caster->ToCreature())
4045 creatureCaster->ReleaseFocus(this);
4046 }
4047 else
4048 {
4049 // Immediate spell, no big deal
4051 }
4052
4053 if (resetAttackTimers)
4054 {
4055 if (m_casttime == 0 && m_spellInfo->CalcCastTime())
4056 {
4057 resetAttackTimers = false;
4058 }
4059
4060 if (resetAttackTimers)
4061 {
4063
4065 {
4067 }
4068
4070 }
4071 }
4072
4074
4075 if (modOwner)
4076 modOwner->SetSpellModTakingSpell(this, false);
4077
4078 if (const std::vector<int32>* spell_triggered = sSpellMgr->GetSpellLinked(m_spellInfo->Id))
4079 {
4080 for (std::vector<int32>::const_iterator i = spell_triggered->begin(); i != spell_triggered->end(); ++i)
4081 if (*i < 0)
4083 else
4085 }
4086
4087 // Interrupt Spell casting
4088 // handle this here, in other places SpellHitTarget can be set to nullptr, if there is an error in this function
4090 if (Unit* target = m_targets.GetUnitTarget())
4091 if (target->IsCreature())
4092 m_caster->CastSpell(target, 32747, true);
4093
4094 // xinef: start combat at cast for delayed spells, only for explicit target
4095 if (Unit* target = m_targets.GetUnitTarget())
4098 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
4099
4100 if (m_caster->IsPlayer())
4103
4104 SetExecutedCurrently(false);
4105}
#define sScriptMgr
Definition: ScriptMgr.h:708
@ UNIT_STATE_CASTING
Definition: UnitDefines.h:164
@ CHEAT_COOLDOWN
Definition: Player.h:1001
@ PET_SAVE_AS_CURRENT
Definition: PetDefines.h:42
@ SPELL_AURA_MOD_CHARM
Definition: SpellAuraDefines.h:69
@ SPELL_AURA_IGNORE_MELEE_RESET
Definition: SpellAuraDefines.h:335
@ SPELL_AURA_BIND_SIGHT
Definition: SpellAuraDefines.h:64
@ TRIGGERED_IGNORE_POWER_AND_REAGENT_COST
Will ignore Spell and Category cooldowns.
Definition: SpellDefines.h: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
@ 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
@ TARGET_FLAG_TRADE_ITEM
Definition: SpellInfo.h:58
@ TARGET_FLAG_UNIT
Definition: SpellInfo.h:47
@ SPELL_STATE_DELAYED
Definition: Spell.h:228
@ SPELL_STATE_FINISHED
Definition: Spell.h:226
@ SPELL_ATTR7_CAN_CAUSE_INTERRUPT
Definition: SharedDefines.h:652
@ SPELL_EFFECT_SUMMON_PET
Definition: SharedDefines.h:834
@ SPELL_ATTR2_DO_NOT_RESET_COMBAT_TIMERS
Definition: SharedDefines.h:473
@ SPELL_ATTR1_DISMISS_PET_FIRST
Definition: SharedDefines.h:419
@ SPELL_ATTR3_SUPRESS_TARGET_PROCS
Definition: SharedDefines.h:510
@ SPELL_DAMAGE_CLASS_NONE
Definition: SharedDefines.h:1545
@ SPELL_MISS_NONE
Definition: SharedDefines.h:1519
SpellCastResult
Definition: SharedDefines.h:948
@ SPELL_FAILED_DONT_REPORT
Definition: SharedDefines.h:976
@ SPELL_CAST_OK
Definition: SharedDefines.h:1138
@ ACHIEVEMENT_TIMED_TYPE_ITEM
Definition: DBCEnums.h:115
@ ACHIEVEMENT_CRITERIA_TYPE_USE_ITEM
Definition: DBCEnums.h:155
@ ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL
Definition: DBCEnums.h:143
Definition: Creature.h:46
uint32 GetEntry() const
Definition: Object.h:112
bool IsCreature() const
Definition: Object.h:201
Creature * ToCreature()
Definition: Object.h:202
Definition: Pet.h:41
Definition: Player.h:1064
void UpdateAchievementCriteria(AchievementCriteriaTypes type, uint32 miscValue1=0, uint32 miscValue2=0, Unit *unit=nullptr)
Definition: PlayerUpdates.cpp:2127
void SetSpellModTakingSpell(Spell *spell, bool apply)
Definition: Player.cpp:10077
void StartTimedAchievement(AchievementCriteriaTimedTypes type, uint32 entry, uint32 timeLost=0)
Definition: Player.cpp:13920
void RemoveSpellMods(Spell *spell)
Definition: Player.cpp:10009
Pet * GetPet() const
Definition: Player.cpp:8906
bool GetCommandStatus(uint32 command) const
Definition: Player.h:1178
void RemovePet(Pet *pet, PetSaveMode mode, bool returnreagent=false)
Definition: Player.cpp:9057
TradeData * GetTradeData() const
Definition: Player.h:1368
void RemoveSpellCooldown(uint32 spell_id, bool update=false)
Definition: Player.cpp:3503
Definition: TradeData.h:36
Definition: Unit.h:630
void ClearUnitState(uint32 f)
Definition: Unit.h:674
AuraEffectList const & GetAuraEffectsByType(AuraType type) const
Definition: Unit.h:1362
Unit * GetCharm() const
Definition: Unit.cpp:10628
Player * GetSpellModOwner() const
Definition: Unit.cpp:16533
void CombatStartOnCast(Unit *target, bool initialAggro=true, uint32 duration=0)
Definition: Unit.cpp:13662
bool haveOffhandWeapon() const
Definition: Unit.cpp:522
bool IsPet() const
Definition: Unit.h:710
bool IsNonMeleeSpellCast(bool withDelayed, bool skipChanneled=false, bool skipAutorepeat=false, bool isAutoshoot=false, bool skipInstant=true) const
Definition: Unit.cpp:4081
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:1168
void RemoveAurasDueToSpell(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, uint8 reqEffMask=0, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition: Unit.cpp:4891
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:6349
bool HasUnitState(const uint32 f) const
Definition: Unit.h:673
bool IsFriendlyTo(Unit const *unit) const
Definition: Unit.cpp:10203
bool IsControlledByPlayer() const
Definition: Unit.h:1224
std::list< AuraEffect * > AuraEffectList
Definition: Unit.h:646
void SetInFront(WorldObject const *target)
Definition: Unit.cpp:20477
void resetAttackTimer(WeaponAttackType type=BASE_ATTACK)
Definition: Unit.cpp:643
WorldObject * GetObjectTarget() const
Definition: Spell.cpp:312
void UpdateTradeSlotItem()
Definition: Spell.cpp:349
ObjectGuid GetObjectTargetGUID() const
Definition: Spell.cpp:317
Item * GetItemTarget() const
Definition: Spell.h:139
uint32 GetTargetMask() const
Definition: Spell.h:117
Unit * GetUnitTarget() const
Definition: Spell.cpp:233
int8 effectIndex
Definition: Spell.h:279
SpellInfo const * spellInfo
Definition: Spell.h:278
SpellInfo const * GetSpellInfo() const
Definition: Spell.h:575
void CallScriptAfterCastHandlers()
Definition: Spell.cpp:8536
void PrepareTriggersExecutedOnHit()
Definition: Spell.cpp:8742
bool HasTriggeredCastFlag(TriggerCastFlags flag) const
Definition: Spell.h:553
SpellCastTargets m_targets
Definition: Spell.h:527
TriggeredByAuraSpellData m_triggeredByAuraSpell
Definition: Spell.h:772
void handle_immediate()
Definition: Spell.cpp:4107
void SendSpellGo()
Definition: Spell.cpp:4789
void TakeReagents()
Definition: Spell.cpp:5523
void SetExecutedCurrently(bool yes)
Definition: Spell.h:561
void SendInterrupted(uint8 result)
Definition: Spell.cpp:5166
void PrepareScriptHitHandlers()
Definition: Spell.cpp:8568
void CallScriptOnCastHandlers()
Definition: Spell.cpp:8523
void cancel(bool bySelf=false)
Definition: Spell.cpp:3712
void SendSpellCooldown()
Definition: Spell.cpp:4347
void CallScriptBeforeCastHandlers()
Definition: Spell.cpp:8510
void HandleLaunchPhase()
Definition: Spell.cpp:8223
bool UpdatePointers()
Definition: Spell.cpp:7853
void SetDelayStart(uint64 m_time)
Definition: Spell.h:563
std::list< TargetInfo > m_UniqueTargetInfo
Definition: Spell.h:682
void SelectSpellTargets()
Definition: Spell.cpp:816
void TakePower()
Definition: Spell.cpp:5307
SpellCastResult CheckCast(bool strict)
Definition: Spell.cpp:5645
static void SendCastResult(Player *caster, SpellInfo const *spellInfo, uint8 castCount, SpellCastResult result, SpellCustomErrors customError=SPELL_CUSTOM_ERROR_NONE)
Definition: Spell.cpp:4661
uint64 GetDelayMoment() const
Definition: Spell.h:564
void TakeCastItem()
Definition: Spell.cpp:5244
bool IsAutoActionResetSpell() const
Definition: Spell.cpp:8067
void finish(bool ok=true)
Definition: Spell.cpp:4474
float Speed
Definition: SpellInfo.h:370
bool IsChanneled() const
Definition: SpellInfo.cpp:1255
uint32 CalcCastTime(Unit *caster=nullptr, Spell *spell=nullptr) const
Definition: SpellInfo.cpp:2351
bool HasAura(AuraType aura) const
Definition: SpellInfo.cpp:892

References _spellTargetsSelected, ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL, ACHIEVEMENT_CRITERIA_TYPE_USE_ITEM, ACHIEVEMENT_TIMED_TYPE_ITEM, BASE_ATTACK, SpellInfo::CalcCastTime(), CallScriptAfterCastHandlers(), CallScriptBeforeCastHandlers(), CallScriptOnCastHandlers(), cancel(), Unit::CastSpell(), CHEAT_COOLDOWN, CheckCast(), Unit::ClearUnitState(), Unit::CombatStartOnCast(), SpellInfo::DmgClass, TriggeredByAuraSpellData::effectIndex, finish(), Unit::GetAuraEffectsByType(), Unit::GetCharm(), Player::GetCommandStatus(), GetDelayMoment(), Object::GetEntry(), Object::GetGUID(), SpellCastTargets::GetItemTarget(), SpellCastTargets::GetObjectTarget(), SpellCastTargets::GetObjectTargetGUID(), Player::GetPet(), GetSpellInfo(), Unit::GetSpellModOwner(), SpellCastTargets::GetTargetMask(), Player::GetTradeData(), SpellCastTargets::GetUnitTarget(), handle_immediate(), HandleLaunchPhase(), SpellInfo::HasAttribute(), SpellInfo::HasAura(), SpellInfo::HasEffect(), HasTriggeredCastFlag(), Unit::HasUnitState(), Unit::haveOffhandWeapon(), SpellInfo::Id, IsAutoActionResetSpell(), SpellInfo::IsChanneled(), Unit::IsControlledByPlayer(), Object::IsCreature(), Unit::IsFriendlyTo(), Unit::IsNonMeleeSpellCast(), Unit::IsPet(), Object::IsPlayer(), SpellInfo::IsPositive(), m_caster, m_CastItem, m_casttime, m_immediateHandled, m_originalCaster, m_procAttacker, m_spellInfo, m_spellState, m_targets, m_triggeredByAuraSpell, m_UniqueTargetInfo, OFF_ATTACK, PET_SAVE_AS_CURRENT, PrepareScriptHitHandlers(), PrepareTriggersExecutedOnHit(), PROC_EX_CRITICAL_HIT, PROC_EX_NORMAL_HIT, PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG, PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_POS, PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_NEG, PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_POS, PROC_FLAG_NONE, PROC_SPELL_PHASE_CAST, Unit::ProcDamageAndSpell(), RANGED_ATTACK, Unit::RemoveAurasDueToSpell(), Player::RemovePet(), Player::RemoveSpellCooldown(), Player::RemoveSpellMods(), Unit::resetAttackTimer(), SelectSpellTargets(), SendCastResult(), SendInterrupted(), SendSpellCooldown(), SendSpellGo(), SetDelayStart(), SetExecutedCurrently(), Unit::SetInFront(), Player::SetSpellModTakingSpell(), SpellInfo::Speed, SPELL_ATTR1_DISMISS_PET_FIRST, SPELL_ATTR2_DO_NOT_RESET_COMBAT_TIMERS, SPELL_ATTR3_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, UNIT_STATE_CASTING, Player::UpdateAchievementCriteria(), UpdatePointers(), and SpellCastTargets::UpdateTradeSlotItem().

Referenced by cast().

◆ _handle_finish_phase()

void Spell::_handle_finish_phase ( )
4273{
4274 // Take for real after all targets are processed
4276 {
4278 }
4279
4280 // Real add combo points from effects
4282 {
4283 // remove Premed-like effects unless they were caused by ourselves
4284 // (this Aura removes the already-added CP when it expires from duration - now that we've added CP, this shouldn't happen anymore!)
4286 {
4288 }
4289
4291 }
4292
4294 {
4296 }
4297
4300 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
4301 {
4302 // Xinef: Properly clear infinite cooldowns in some cases
4303 if (ihit->targetGUID == m_caster->GetGUID() && ihit->missCondition != SPELL_MISS_NONE)
4306 }
4307
4308 // Handle procs on finish
4309 if (m_originalCaster)
4310 {
4311 uint32 procAttacker = m_procAttacker;
4312 if (!procAttacker)
4313 {
4314 bool IsPositive = m_spellInfo->IsPositive();
4316 {
4318 }
4319 else
4320 {
4322 }
4323 }
4324
4325 uint32 procEx = PROC_EX_NORMAL_HIT;
4326 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
4327 {
4328 if (ihit->missCondition != SPELL_MISS_NONE)
4329 {
4330 continue;
4331 }
4332
4333 if (!ihit->crit)
4334 {
4335 continue;
4336 }
4337
4338 procEx |= PROC_EX_CRITICAL_HIT;
4339 break;
4340 }
4341
4344 }
4345}
@ 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:797
void SendCooldownEvent(SpellInfo const *spellInfo, uint32 itemId=0, Spell *spell=nullptr, bool setCooldown=true)
Definition: Player.cpp:11105
void SetLastExtraAttackSpell(uint32 spellId)
Definition: Unit.h:1017
Player * GetCharmerOrOwnerPlayerOrPlayerItself() const
Definition: Unit.cpp:10578
void ClearComboPoints()
Definition: Unit.cpp:16820
void AddComboPoints(Unit *target, int8 count)
Definition: Unit.cpp:16794
void RemoveAurasByType(AuraType auraType, ObjectGuid casterGUID=ObjectGuid::Empty, Aura *except=nullptr, bool negative=true, bool positive=true)
Definition: Unit.cpp:5081
bool IsAutoRepeat() const
Definition: Spell.h:548
bool IsNextMeleeSwingSpell() const
Definition: Spell.cpp:8057
bool IsCooldownStartedOnEvent() const
Definition: SpellInfo.cpp:1211

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

Referenced by handle_delayed(), and handle_immediate().

◆ _handle_immediate_phase()

void Spell::_handle_immediate_phase ( )
4245{
4246 m_spellAura = nullptr;
4247 // initialize Diminishing Returns Data
4250
4251 // handle some immediate features of the spell here
4253
4255
4256 // handle effects with SPELL_EFFECT_HANDLE_HIT mode
4257 for (uint32 j = 0; j < MAX_SPELL_EFFECTS; ++j)
4258 {
4259 // don't do anything for empty effect
4260 if (!m_spellInfo->Effects[j].IsEffect())
4261 continue;
4262
4263 // call effect handlers to handle destination hit
4264 HandleEffects(nullptr, nullptr, nullptr, j, SPELL_EFFECT_HANDLE_HIT);
4265 }
4266
4267 // process items
4268 for (std::list<ItemTargetInfo>::iterator ihit = m_UniqueItemInfo.begin(); ihit != m_UniqueItemInfo.end(); ++ihit)
4269 DoAllEffectOnTarget(&(*ihit));
4270}
@ SPELL_EFFECT_HANDLE_HIT
Definition: Spell.h:235
void HandleThreatSpells()
Definition: Spell.cpp:5572
void HandleEffects(Unit *pUnitTarget, Item *pItemTarget, GameObject *pGOTarget, uint32 i, SpellEffectHandleMode mode)
Definition: Spell.cpp:5619
std::list< ItemTargetInfo > m_UniqueItemInfo
Definition: Spell.h:699
void DoAllEffectOnTarget(TargetInfo *target)
Definition: Spell.cpp:2610
std::array< SpellEffectInfo, MAX_SPELL_EFFECTS > Effects
Definition: SpellInfo.h:393

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

Referenced by handle_delayed(), and handle_immediate().

◆ AddComboPointGain()

void Spell::AddComboPointGain ( Unit target,
int8  amount 
)
inline
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
2606{
2607 m_destTargets[effIndex] = dest;
2608}

References m_destTargets.

Referenced by SelectSpellTargets().

◆ AddGOTarget()

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

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

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

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
897{
898 if (m_targets.HasDst())
899 {
900 if (m_targets.HasTraj())
901 {
902 float speed = m_targets.GetSpeedXY();
903 if (speed > 0.0f)
904 return (uint64)std::floor(m_targets.GetDist2d() / speed * 1000.0f);
905 }
906 else if (m_spellInfo->Speed > 0.0f)
907 {
908 // We should not subtract caster size from dist calculation (fixes execution time desync with animation on client, eg. Malleable Goo cast by PP)
909 float dist = m_caster->GetExactDist(*m_targets.GetDstPos());
910 return (uint64)std::floor(dist / m_spellInfo->Speed * 1000.0f);
911 }
912 }
913
914 return 0;
915}
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:402

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
1158{
1159 if (m_spellInfo->Effects[i].MiscValue)
1160 speedZ = float(m_spellInfo->Effects[i].MiscValue) / 10;
1161 else if (m_spellInfo->Effects[i].MiscValueB)
1162 speedZ = float(m_spellInfo->Effects[i].MiscValueB) / 10;
1163 else
1164 speedZ = 10.0f;
1165 speedXY = dist * 10.0f / speedZ;
1166}

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:14806
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
8537{
8538 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8539 {
8540 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_AFTER_CAST);
8541 std::list<SpellScript::CastHandler>::iterator hookItrEnd = (*scritr)->AfterCast.end(), hookItr = (*scritr)->AfterCast.begin();
8542 for (; hookItr != hookItrEnd; ++hookItr)
8543 (*hookItr).Call(*scritr);
8544
8545 (*scritr)->_FinishScriptCall();
8546 }
8547}
@ 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
8649{
8650 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8651 {
8652 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_AFTER_HIT);
8653 std::list<SpellScript::HitHandler>::iterator hookItrEnd = (*scritr)->AfterHit.end(), hookItr = (*scritr)->AfterHit.begin();
8654 for (; hookItr != hookItrEnd; ++hookItr)
8655 (*hookItr).Call(*scritr);
8656
8657 (*scritr)->_FinishScriptCall();
8658 }
8659}
@ 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
8511{
8512 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8513 {
8514 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_BEFORE_CAST);
8515 std::list<SpellScript::CastHandler>::iterator hookItrEnd = (*scritr)->BeforeCast.end(), hookItr = (*scritr)->BeforeCast.begin();
8516 for (; hookItr != hookItrEnd; ++hookItr)
8517 (*hookItr).Call(*scritr);
8518
8519 (*scritr)->_FinishScriptCall();
8520 }
8521}
@ 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
8623{
8624 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8625 {
8626 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_BEFORE_HIT);
8627 std::list<SpellScript::BeforeHitHandler>::iterator hookItrEnd = (*scritr)->BeforeHit.end(), hookItr = (*scritr)->BeforeHit.begin();
8628 for (; hookItr != hookItrEnd; ++hookItr)
8629 (*hookItr).Call(*scritr, missInfo);
8630
8631 (*scritr)->_FinishScriptCall();
8632 }
8633}
@ 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
8550{
8552 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8553 {
8554 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_CHECK_CAST);
8555 std::list<SpellScript::CheckCastHandler>::iterator hookItrEnd = (*scritr)->OnCheckCast.end(), hookItr = (*scritr)->OnCheckCast.begin();
8556 for (; hookItr != hookItrEnd; ++hookItr)
8557 {
8558 SpellCastResult tempResult = (*hookItr).Call(*scritr);
8559 if (retVal == SPELL_CAST_OK)
8560 retVal = tempResult;
8561 }
8562
8563 (*scritr)->_FinishScriptCall();
8564 }
8565 return retVal;
8566}
@ 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
8690{
8691 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8692 {
8693 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_DESTINATION_TARGET_SELECT);
8694 std::list<SpellScript::DestinationTargetSelectHandler>::iterator hookItrEnd = (*scritr)->OnDestinationTargetSelect.end(), hookItr = (*scritr)->OnDestinationTargetSelect.begin();
8695 for (; hookItr != hookItrEnd; ++hookItr)
8696 if (hookItr->IsEffectAffected(m_spellInfo, effIndex) && targetType.GetTarget() == hookItr->GetTarget())
8697 hookItr->Call(*scritr, target);
8698
8699 (*scritr)->_FinishScriptCall();
8700 }
8701}
@ 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
8575{
8576 // execute script effect handler hooks and check if effects was prevented
8577 bool preventDefault = false;
8578 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8579 {
8580 std::list<SpellScript::EffectHandler>::iterator effItr, effEndItr;
8581 SpellScriptHookType hookType;
8582 switch (mode)
8583 {
8585 effItr = (*scritr)->OnEffectLaunch.begin();
8586 effEndItr = (*scritr)->OnEffectLaunch.end();
8588 break;
8590 effItr = (*scritr)->OnEffectLaunchTarget.begin();
8591 effEndItr = (*scritr)->OnEffectLaunchTarget.end();
8593 break;
8595 effItr = (*scritr)->OnEffectHit.begin();
8596 effEndItr = (*scritr)->OnEffectHit.end();
8598 break;
8600 effItr = (*scritr)->OnEffectHitTarget.begin();
8601 effEndItr = (*scritr)->OnEffectHitTarget.end();
8603 break;
8604 default:
8605 ABORT();
8606 return false;
8607 }
8608 (*scritr)->_PrepareScriptCall(hookType);
8609 for (; effItr != effEndItr; ++effItr)
8610 // effect execution can be prevented
8611 if (!(*scritr)->_IsEffectPrevented(effIndex) && (*effItr).IsEffectAffected(m_spellInfo, effIndex))
8612 (*effItr).Call(*scritr, effIndex);
8613
8614 if (!preventDefault)
8615 preventDefault = (*scritr)->_IsDefaultEffectPrevented(effIndex);
8616
8617 (*scritr)->_FinishScriptCall();
8618 }
8619 return preventDefault;
8620}
#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
8662{
8663 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8664 {
8665 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_OBJECT_AREA_TARGET_SELECT);
8666 std::list<SpellScript::ObjectAreaTargetSelectHandler>::iterator hookItrEnd = (*scritr)->OnObjectAreaTargetSelect.end(), hookItr = (*scritr)->OnObjectAreaTargetSelect.begin();
8667 for (; hookItr != hookItrEnd; ++hookItr)
8668 if (hookItr->IsEffectAffected(m_spellInfo, effIndex) && targetType.GetTarget() == hookItr->GetTarget())
8669 hookItr->Call(*scritr, targets);
8670
8671 (*scritr)->_FinishScriptCall();
8672 }
8673}
@ 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
8676{
8677 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8678 {
8679 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_OBJECT_TARGET_SELECT);
8680 std::list<SpellScript::ObjectTargetSelectHandler>::iterator hookItrEnd = (*scritr)->OnObjectTargetSelect.end(), hookItr = (*scritr)->OnObjectTargetSelect.begin();
8681 for (; hookItr != hookItrEnd; ++hookItr)
8682 if (hookItr->IsEffectAffected(m_spellInfo, effIndex) && targetType.GetTarget() == hookItr->GetTarget())
8683 hookItr->Call(*scritr, target);
8684
8685 (*scritr)->_FinishScriptCall();
8686 }
8687}
@ 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
8524{
8525 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8526 {
8527 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_ON_CAST);
8528 std::list<SpellScript::CastHandler>::iterator hookItrEnd = (*scritr)->OnCast.end(), hookItr = (*scritr)->OnCast.begin();
8529 for (; hookItr != hookItrEnd; ++hookItr)
8530 (*hookItr).Call(*scritr);
8531
8532 (*scritr)->_FinishScriptCall();
8533 }
8534}
@ 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
8636{
8637 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8638 {
8639 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_HIT);
8640 std::list<SpellScript::HitHandler>::iterator hookItrEnd = (*scritr)->OnHit.end(), hookItr = (*scritr)->OnHit.begin();
8641 for (; hookItr != hookItrEnd; ++hookItr)
8642 (*hookItr).Call(*scritr);
8643
8644 (*scritr)->_FinishScriptCall();
8645 }
8646}
@ 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)
7000{
7001 ObjectGuid targetguid = target->GetGUID();
7002
7003 for (uint32 j = 0; j < MAX_SPELL_EFFECTS; ++j)
7004 {
7006 {
7007 if (m_spellInfo->StackAmount <= 1)
7008 {
7009 if (target->HasAuraEffect(m_spellInfo->Id, j))
7010 return false;
7011 }
7012 else
7013 {
7014 if (AuraEffect* aureff = target->GetAuraEffect(m_spellInfo->Id, j))
7015 if (aureff->GetBase()->GetStackAmount() >= m_spellInfo->StackAmount)
7016 return false;
7017 }
7018 }
7019 else if (m_spellInfo->Effects[j].IsAreaAuraEffect())
7020 {
7021 if (target->HasAuraEffect(m_spellInfo->Id, j))
7022 return false;
7023 }
7024 }
7025
7026 SpellCastResult result = CheckPetCast(target);
7027
7028 if (result == SPELL_CAST_OK || result == SPELL_FAILED_UNIT_NOT_INFRONT)
7029 {
7031 //check if among target units, our WANTED target is as well (->only self cast spells return false)
7032 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
7033 if (ihit->targetGUID == targetguid)
7034 return true;
7035 }
7036 return false; //target invalid
7037}
@ SPELL_EFFECT_APPLY_AURA
Definition: SharedDefines.h:784
@ SPELL_FAILED_UNIT_NOT_INFRONT
Definition: SharedDefines.h:1083
AuraEffect * GetAuraEffect(uint32 spellId, uint8 effIndex, ObjectGuid casterGUID=ObjectGuid::Empty) const
Definition: Unit.cpp:5465
bool HasAuraEffect(uint32 spellId, uint8 effIndex, ObjectGuid caster=ObjectGuid::Empty) const
Definition: Unit.cpp:5639
Definition: SpellAuraEffects.h:39
SpellCastResult CheckPetCast(Unit *target)
Definition: Spell.cpp:6806
uint32 StackAmount
Definition: SpellInfo.h:371

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

Referenced by PetAI::UpdateAI().

◆ cancel()

void Spell::cancel ( bool  bySelf = false)
3713{
3715 return;
3716
3717 uint32 oldState = m_spellState;
3719
3720 m_autoRepeat = false;
3721 switch (oldState)
3722 {
3726
3727 if (m_caster->IsPlayer())
3728 {
3730 ArenaSpectator::SendCommand_Spell(m_caster->FindMap(), m_caster->GetGUID(), "SPE", m_spellInfo->Id, bySelf ? 99998 : 99999);
3731 }
3732 [[fallthrough]];
3735 break;
3737 if (!bySelf)
3738 {
3739 for (std::list<TargetInfo>::const_iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
3740 if ((*ihit).missCondition == SPELL_MISS_NONE)
3741 if (Unit* unit = m_caster->GetGUID() == ihit->targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID))
3742 unit->RemoveOwnedAura(m_spellInfo->Id, m_originalCasterGUID, 0, AURA_REMOVE_BY_CANCEL);
3743
3746
3749 }
3750
3752 ArenaSpectator::SendCommand_Spell(m_caster->FindMap(), m_caster->GetGUID(), "SPE", m_spellInfo->Id, bySelf ? 99998 : 99999);
3753
3754 // spell is canceled-take mods and clear list
3755 if (Player* player = m_caster->GetSpellModOwner())
3756 player->RemoveSpellMods(this);
3757
3758 m_appliedMods.clear();
3759 break;
3760 default:
3761 break;
3762 }
3763
3765 if (m_selfContainer && *m_selfContainer == this)
3766 *m_selfContainer = nullptr;
3767
3768 // Do not remove current far sight object (already done in Spell::EffectAddFarsight) to prevent from reset viewpoint to player
3770 {
3772 }
3773
3774 if (m_spellInfo->IsChanneled()) // if not channeled then the object for the current cast wasn't summoned yet
3776
3777 //set state back so finish will be processed
3778 m_spellState = oldState;
3779
3780 finish(false);
3781}
@ 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:850
@ SPELL_FAILED_INTERRUPTED
Definition: SharedDefines.h:989
void SendCommand_Spell(T *o, ObjectGuid targetGUID, const char *prefix, uint32 id, int32 casttime)
Definition: ArenaSpectator.h:80
Map * FindMap() const
Definition: Object.h:532
bool NeedSendSpectatorData() const
Definition: Player.cpp:15402
void RemoveGameObject(GameObject *gameObj, bool del)
Definition: Unit.cpp:6168
bool RemoveDynObject(uint32 spellId)
Definition: Unit.cpp:6112
void SendChannelUpdate(uint32 time)
Definition: Spell.cpp:5183
void CancelGlobalCooldown()
Definition: Spell.cpp:8877
void SetReferencedFromCurrent(bool yes)
Definition: Spell.h:559
UsedSpellMods m_appliedMods
Definition: Spell.h:545

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

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

◆ CancelGlobalCooldown()

void Spell::CancelGlobalCooldown ( )
protected
8878{
8880 return;
8881
8882 // Cancel global cooldown when interrupting current cast
8884 return;
8885
8886 // Only players or controlled units have global cooldown
8887 if (m_caster->GetCharmInfo())
8889 else if (m_caster->IsPlayer())
8891}
@ CURRENT_GENERIC_SPELL
Definition: Unit.h:538
GlobalCooldownMgr & GetGlobalCooldownMgr()
Definition: Player.h:1785
void CancelGlobalCooldown(SpellInfo const *spellInfo)
Definition: CharmInfo.cpp:415
GlobalCooldownMgr & GetGlobalCooldownMgr()
Definition: CharmInfo.h:158
CharmInfo * GetCharmInfo()
Definition: Unit.h:1278
Spell * GetCurrentSpell(CurrentSpellTypes spellType) const
Definition: Unit.h:1456
uint32 StartRecoveryTime
Definition: SpellInfo.h:351

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

Referenced by cancel().

◆ CanExecuteTriggersOnHit()

bool Spell::CanExecuteTriggersOnHit ( uint8  effMask,
SpellInfo const *  triggeredByAura = nullptr 
) const
protected
8727{
8728 // Relentless strikes, proc only from first effect
8729 if (triggeredByAura && triggeredByAura->SpellIconID == 559)
8730 return effMask & (1 << EFFECT_0);
8731
8732 bool only_on_caster = (triggeredByAura && triggeredByAura->HasAttribute(SPELL_ATTR4_CLASS_TRIGGER_ONLY_ON_TARGET));
8733 // If triggeredByAura has SPELL_ATTR4_CLASS_TRIGGER_ONLY_ON_TARGET then it can only proc on a casted spell with TARGET_UNIT_CASTER
8734 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
8735 {
8736 if ((effMask & (1 << i)) && (!only_on_caster || (m_spellInfo->Effects[i].TargetA.GetTarget() == TARGET_UNIT_CASTER)))
8737 return true;
8738 }
8739 return effMask;
8740}
@ EFFECT_0
Definition: SharedDefines.h:31
@ TARGET_UNIT_CASTER
Definition: SharedDefines.h:1410
@ SPELL_ATTR4_CLASS_TRIGGER_ONLY_ON_TARGET
Definition: SharedDefines.h:531

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

Referenced by DoAllEffectOnTarget(), and DoTriggersOnSpellHit().

◆ CanOpenLock()

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

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

Referenced by CheckCast(), and EffectOpenLock().

◆ cast()

void Spell::cast ( bool  skipCheck = false)
3784{
3785 Player* modOwner = m_caster->GetSpellModOwner();
3786 Spell* lastMod = nullptr;
3787 if (modOwner)
3788 {
3789 lastMod = modOwner->m_spellModTakingSpell;
3790 if (lastMod)
3791 modOwner->SetSpellModTakingSpell(lastMod, false);
3792 }
3793
3794 _cast(skipCheck);
3795
3796 if (lastMod)
3797 modOwner->SetSpellModTakingSpell(lastMod, true);
3798}
Spell * m_spellModTakingSpell
Definition: Player.h:2532
Definition: Spell.h:284
void _cast(bool skipCheck)
Definition: Spell.cpp:3800

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
5646{
5647 // check death state
5650
5651 // Spectator check
5652 if (m_caster->IsPlayer())
5653 if (((Player const*)m_caster)->IsSpectator() && m_spellInfo->Id != SPECTATOR_SPELL_BINDSIGHT)
5654 return SPELL_FAILED_NOT_HERE;
5655
5657
5658 sScriptMgr->OnSpellCheckCast(this, strict, res);
5659
5660 if (res != SPELL_CAST_OK)
5661 return res;
5662
5663 // check cooldowns to prevent cheating
5665 {
5666 if (m_caster->IsPlayer())
5667 {
5668 //can cast triggered (by aura only?) spells while have this flag
5671
5673 {
5676 else
5678 }
5679
5680 // check if we are using a potion in combat for the 2nd+ time. Cooldown is added only after caster gets out of combat
5683 }
5686 }
5687
5689 {
5692 }
5693
5694 // Check global cooldown
5697
5698 // only triggered spells can be processed an ended battleground
5699 if (!IsTriggered() && m_caster->IsPlayer())
5701 if (bg->GetStatus() == STATUS_WAIT_LEAVE)
5703
5704 if (m_caster->IsPlayer() /*&& VMAP::VMapFactory::createOrGetVMapMgr()->isLineOfSightCalcEnabled()*/) // pussywizard: optimization (commented)
5705 {
5707 !m_caster->IsOutdoors())
5709
5713 }
5714
5715 // only check at first call, Stealth auras are already removed at second call
5716 // for now, ignore triggered spells
5718 {
5719 bool checkForm = true;
5720 // Ignore form req aura
5722 for (Unit::AuraEffectList::const_iterator i = ignore.begin(); i != ignore.end(); ++i)
5723 {
5724 if (!(*i)->IsAffectedOnSpell(m_spellInfo))
5725 continue;
5726 checkForm = false;
5727 break;
5728 }
5729 if (checkForm)
5730 {
5731 // Cannot be used in this stance/form
5733 if (shapeError != SPELL_CAST_OK)
5734 return shapeError;
5735
5738 }
5739 }
5740
5742 for (Unit::AuraEffectList::const_iterator blockItr = blockSpells.begin(); blockItr != blockSpells.end(); ++blockItr)
5743 if (uint32((*blockItr)->GetMiscValue()) == m_spellInfo->SpellFamilyName)
5745
5746 bool reqCombat = true;
5748 for (Unit::AuraEffectList::const_iterator j = stateAuras.begin(); j != stateAuras.end(); ++j)
5749 {
5750 if ((*j)->IsAffectedOnSpell(m_spellInfo))
5751 {
5752 m_needComboPoints = false;
5753 if ((*j)->GetMiscValue() == 1)
5754 {
5755 reqCombat = false;
5756 break;
5757 }
5758 }
5759 }
5760
5761 // caster state requirements
5762 // not for triggered spells (needed by execute)
5764 {
5769
5770 // Note: spell 62473 requres CasterAuraSpell = triggering spell
5775
5776 if (reqCombat && m_caster->IsInCombat() && !m_spellInfo->CanBeUsedInCombat())
5778 }
5779
5780 // Xinef: exploit protection
5782 {
5783 if (m_caster->IsPlayer() && m_caster->GetMap()->IsDungeon())
5784 if (InstanceScript* instanceScript = m_caster->GetInstanceScript())
5785 if (instanceScript->IsEncounterInProgress())
5786 {
5787 if (Group* group = m_caster->ToPlayer()->GetGroup())
5788 for (GroupReference* itr = group->GetFirstMember(); itr != nullptr; itr = itr->next())
5789 if (Player* member = itr->GetSource())
5790 if (member->IsInMap(m_caster))
5791 if (Unit* victim = member->GetVictim())
5792 if (victim->IsInCombat() && m_caster->GetDistance(victim) < m_caster->GetVisibilityRange())
5793 {
5794 m_caster->CombatStart(victim);
5795 victim->AddThreat(m_caster, 1.0f);
5796 break;
5797 }
5799 }
5800 }
5801
5802 // cancel autorepeat spells if cast start when moving
5803 // (not wand currently autorepeat cast delayed to moving stop anyway in spell update code)
5804 if (m_caster->IsPlayer() && m_caster->ToPlayer()->isMoving() && !IsTriggered())
5805 {
5806 // skip stuck spell to allow use it in falling case and apply spell limitations at movement
5809 return SPELL_FAILED_MOVING;
5810 }
5811
5812 Vehicle* vehicle = m_caster->GetVehicle();
5814 {
5815 uint16 checkMask = 0;
5816 for (uint8 effIndex = EFFECT_0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
5817 {
5818 SpellEffectInfo const* effInfo = &m_spellInfo->Effects[effIndex];
5820 {
5821 SpellShapeshiftFormEntry const* shapeShiftEntry = sSpellShapeshiftFormStore.LookupEntry(effInfo->MiscValue);
5822 if (shapeShiftEntry && (shapeShiftEntry->flags1 & 1) == 0) // unk flag
5823 checkMask |= VEHICLE_SEAT_FLAG_UNCONTROLLED;
5824 break;
5825 }
5826 }
5827
5830
5831 if (!checkMask)
5832 checkMask = VEHICLE_SEAT_FLAG_CAN_ATTACK;
5833
5834 // All creatures should be able to cast as passengers freely, restriction and attribute are only for players
5835 VehicleSeatEntry const* vehicleSeat = vehicle->GetSeatForPassenger(m_caster);
5837 && (vehicleSeat->m_flags & checkMask) != checkMask && m_caster->IsPlayer())
5839 }
5840
5841 // check spell cast conditions from database
5842 {
5845 ConditionList conditions = sConditionMgr->GetConditionsForNotGroupedEntry(CONDITION_SOURCE_TYPE_SPELL, m_spellInfo->Id);
5846 if (!conditions.empty() && !sConditionMgr->IsObjectMeetToConditions(condInfo, conditions))
5847 {
5848 // mLastFailedCondition can be nullptr if there was an error processing the condition in Condition::Meets (i.e. wrong data for ConditionTarget or others)
5849 if (condInfo.mLastFailedCondition && condInfo.mLastFailedCondition->ErrorType)
5850 {
5854 }
5855 if (!condInfo.mLastFailedCondition || !condInfo.mLastFailedCondition->ConditionTarget)
5858 }
5859 }
5860
5861 // Don't check explicit target for passive spells (workaround) (check should be skipped only for learn case)
5862 // those spells may have incorrect target entries or not filled at all (for example 15332)
5863 // such spells when learned are not targeting anyone using targeting system, they should apply directly to caster instead
5864 // also, such casts shouldn't be sent to client
5865 // Xinef: do not check explicit casts for self cast of triggered spells (eg. reflect case)
5867 {
5868 // Check explicit target for m_originalCaster - todo: get rid of such workarounds
5869 // Xinef: do not check explicit target for triggered spell casted on self with targetflag enemy
5871 {
5873 if (castResult != SPELL_CAST_OK)
5874 return castResult;
5875 }
5876 }
5877
5878 if (Unit* target = m_targets.GetUnitTarget())
5879 {
5880 SpellCastResult castResult = m_spellInfo->CheckTarget(m_caster, target, false);
5881 if (castResult != SPELL_CAST_OK)
5882 return castResult;
5883
5884 if (target != m_caster)
5885 {
5886 // Must be behind the target
5887 if (m_spellInfo->HasAttribute(SPELL_ATTR0_CU_REQ_CASTER_BEHIND_TARGET) && target->HasInArc(static_cast<float>(M_PI), m_caster))
5889
5890 // Target must be facing you
5891 if (m_spellInfo->HasAttribute(SPELL_ATTR0_CU_REQ_TARGET_FACING_CASTER) && !target->HasInArc(static_cast<float>(M_PI), m_caster))
5893
5896 {
5897 bool castedByGameobject = false;
5898 uint32 losChecks = LINEOFSIGHT_ALL_CHECKS;
5900 {
5901 castedByGameobject = m_caster->GetMap()->GetGameObject(m_originalCasterGUID) != nullptr;
5902 }
5903 else if (m_caster->GetEntry() == WORLD_TRIGGER)
5904 {
5905 if (TempSummon* tempSummon = m_caster->ToTempSummon())
5906 {
5907 castedByGameobject = tempSummon->GetSummonerGameObject() != nullptr;
5908 }
5909 }
5910
5911 if (castedByGameobject)
5912 {
5913 // If spell casted by gameobject then ignore M2 models
5914 losChecks &= ~LINEOFSIGHT_CHECK_GOBJECT_M2;
5915 }
5916
5918 {
5920 }
5921 }
5922 }
5923 }
5924
5925 // Check for line of sight for spells with dest
5926 if (m_targets.HasDst())
5927 {
5928 float x, y, z;
5929 m_targets.GetDstPos()->GetPosition(x, y, z);
5930
5933 {
5934 bool castedByGameobject = false;
5935 uint32 losChecks = LINEOFSIGHT_ALL_CHECKS;
5937 {
5938 castedByGameobject = m_caster->GetMap()->GetGameObject(m_originalCasterGUID) != nullptr;
5939 }
5940 else if (m_caster->GetEntry() == WORLD_TRIGGER)
5941 {
5942 if (TempSummon* tempSummon = m_caster->ToTempSummon())
5943 {
5944 castedByGameobject = tempSummon->GetSummonerGameObject() != nullptr;
5945 }
5946 }
5947
5948 if (castedByGameobject)
5949 {
5950 // If spell casted by gameobject then ignore M2 models
5951 losChecks &= ~LINEOFSIGHT_CHECK_GOBJECT_M2;
5952 }
5953
5955 {
5957 }
5958 }
5959 }
5960
5961 // check pet presence
5962 for (int j = 0; j < MAX_SPELL_EFFECTS; ++j)
5963 {
5964 if (m_spellInfo->Effects[j].TargetA.GetTarget() == TARGET_UNIT_PET)
5965 {
5967 {
5968 if (m_triggeredByAuraSpell.spellInfo) // not report pet not existence for triggered spells
5970 else
5971 return SPELL_FAILED_NO_PET;
5972 }
5973 break;
5974 }
5975 }
5976 // Spell casted only on battleground
5978 if (!m_caster->ToPlayer()->InBattleground())
5980
5981 // do not allow spells to be cast in arenas
5982 // - with greater than 10 min CD without SPELL_ATTR4_IGNORE_DEFAULT_ARENA_RESTRICTIONS flag
5983 // - with SPELL_ATTR4_NOT_IN_ARENA_OR_RATED_BATTLEGROUND flag
5986 if (MapEntry const* mapEntry = sMapStore.LookupEntry(m_caster->GetMapId()))
5987 if (mapEntry->IsBattleArena())
5989
5990 // zone check
5992 {
5993 uint32 zone, area;
5994 m_caster->GetZoneAndAreaId(zone, area);
5995
5997 m_caster->IsPlayer() ? m_caster->ToPlayer() : nullptr);
5998 if (locRes != SPELL_CAST_OK)
5999 return locRes;
6000 }
6001
6002 // not let players cast spells at mount (and let do it to creatures)
6005 {
6006 if (m_caster->IsInFlight())
6008 else
6010 }
6011
6012 SpellCastResult castResult = SPELL_CAST_OK;
6013
6014 // always (except passive spells) check items (focus object can be required for any type casts)
6015 if (!m_spellInfo->IsPassive())
6016 {
6017 // spell focus needs to be checked not only for players! there are vehicle spells that require spell focus
6018 castResult = CheckSpellFocus();
6019 if (castResult != SPELL_CAST_OK)
6020 return castResult;
6021
6022 castResult = CheckItems();
6023 if (castResult != SPELL_CAST_OK)
6024 return castResult;
6025 }
6026
6027 // Triggered spells also have range check
6029 castResult = CheckRange(strict);
6030 if (castResult != SPELL_CAST_OK)
6031 return castResult;
6032
6034 {
6035 castResult = CheckPower();
6036 if (castResult != SPELL_CAST_OK)
6037 return castResult;
6038 }
6039
6041 {
6042 return SPELL_CAST_OK;
6043 }
6044
6045 // xinef: do not skip triggered spells if they posses prevention type (eg. Bladestorm vs Hand of Protection)
6047 {
6049 if (castResult != SPELL_CAST_OK)
6050 return castResult;
6051
6052 // 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).
6054 {
6056 for (SpellImmuneList::const_iterator itr = mechanicList.begin(); itr != mechanicList.end(); ++itr)
6057 if (itr->type == m_spellInfo->Mechanic)
6059 }
6060 }
6061
6062 // script hook
6063 castResult = CallScriptCheckCastHandlers();
6064 if (castResult != SPELL_CAST_OK)
6065 return castResult;
6066
6067 bool hasDispellableAura = false;
6068 bool hasNonDispelEffect = false;
6069 uint32 dispelMask = 0;
6070 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
6071 if (m_spellInfo->Effects[i].Effect == SPELL_EFFECT_DISPEL)
6072 {
6074 {
6075 hasDispellableAura = true;
6076 break;
6077 }
6078
6079 dispelMask |= SpellInfo::GetDispelMask(DispelType(m_spellInfo->Effects[i].MiscValue));
6080 }
6081 else if (m_spellInfo->Effects[i].IsEffect())
6082 {
6083 hasNonDispelEffect = true;
6084 break;
6085 }
6086
6087 if (!hasNonDispelEffect && !hasDispellableAura && dispelMask && !IsTriggered())
6088 {
6089 if (Unit* target = m_targets.GetUnitTarget())
6090 {
6091 // Xinef: do not allow to cast on hostile targets in sanctuary
6092 if (!m_caster->IsFriendlyTo(target))
6093 {
6094 if (m_caster->IsInSanctuary() || target->IsInSanctuary())
6095 {
6096 // Xinef: fix for duels
6097 Player* player = m_caster->ToPlayer();
6098 if (!player || !player->duel || target != player->duel->Opponent)
6100 }
6101 }
6102
6103 DispelChargesList dispelList;
6104 target->GetDispellableAuraList(m_caster, dispelMask, dispelList, m_spellInfo);
6105
6106 if (dispelList.empty())
6108 }
6109 }
6110
6111 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
6112 {
6113 // for effects of spells that have only one target
6114 switch (m_spellInfo->Effects[i].Effect)
6115 {
6117 {
6118 if (!m_caster->IsPlayer())
6120
6121 if (m_spellInfo->Effects[i].TargetA.GetTarget() != TARGET_UNIT_PET)
6122 break;
6123
6124 Pet* pet = m_caster->ToPlayer()->GetPet();
6125
6126 if (!pet)
6127 return SPELL_FAILED_NO_PET;
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 // check target only for unit target case
6143 {
6144 if (!m_caster->IsPlayer())
6146
6147 Pet* pet = unitTarget->ToPet();
6148 if (!pet || pet->GetOwner() != m_caster)
6150
6151 SpellInfo const* learn_spellproto = sSpellMgr->GetSpellInfo(m_spellInfo->Effects[i].TriggerSpell);
6152
6153 if (!learn_spellproto)
6155
6156 if (m_spellInfo->SpellLevel > pet->GetLevel())
6157 return SPELL_FAILED_LOWLEVEL;
6158 }
6159 break;
6160 }
6162 {
6163 uint32 glyphId = m_spellInfo->Effects[i].MiscValue;
6164 if (GlyphPropertiesEntry const* gp = sGlyphPropertiesStore.LookupEntry(glyphId))
6165 if (m_caster->HasAura(gp->SpellId))
6167 break;
6168 }
6170 {
6171 if (!m_caster->IsPlayer())
6173
6174 Item* foodItem = m_targets.GetItemTarget();
6175 if (!foodItem)
6177
6178 Pet* pet = m_caster->ToPlayer()->GetPet();
6179
6180 if (!pet)
6181 return SPELL_FAILED_NO_PET;
6182
6183 if (!pet->HaveInDiet(foodItem->GetTemplate()))
6185
6186 if (!pet->GetCurrentFoodBenefitLevel(foodItem->GetTemplate()->ItemLevel))
6188
6189 if (m_caster->IsInCombat() || pet->IsInCombat())
6191
6192 break;
6193 }
6196 {
6197 // Can be area effect, Check only for players and not check if target - caster (spell can have multiply drain/burn effects)
6198 if (m_caster->IsPlayer())
6199 if (Unit* target = m_targets.GetUnitTarget())
6200 if (target != m_caster && !target->HasActivePowerType(Powers(m_spellInfo->Effects[i].MiscValue)))
6202 break;
6203 }
6205 {
6207 {
6209 }
6210
6212 {
6213 // Warbringer - can't be handled in proc system - should be done before checkcast root check and charge effect process
6214 if (strict && m_caster->IsScriptOverriden(m_spellInfo, 6953))
6216 }
6218 {
6219 // Exception for Master's Call
6220 if (m_spellInfo->Id != 54216)
6221 {
6222 return SPELL_FAILED_ROOTED;
6223 }
6224 }
6225 if (m_caster->IsPlayer())
6226 if (Unit* target = m_targets.GetUnitTarget())
6227 if (!target->IsAlive())
6229 // Xinef: Pass only explicit unit target spells
6230 // pussywizard:
6232 {
6233 Unit* target = m_targets.GetUnitTarget();
6234 if (!target)
6236
6237 // first we must check to see if the target is in LoS. A path can usually be built but LoS matters for charge spells
6238 if (!target->IsWithinLOSInMap(m_caster)) //Do full LoS/Path check. Don't exclude m2
6240
6241 float objSize = target->GetCombatReach();
6242 float range = m_spellInfo->GetMaxRange(true, m_caster, this) * 1.5f + objSize; // can't be overly strict
6243
6244 m_preGeneratedPath = std::make_unique<PathGenerator>(m_caster);
6245 m_preGeneratedPath->SetPathLengthLimit(range);
6246
6247 // first try with raycast, if it fails fall back to normal path
6248 bool result = m_preGeneratedPath->CalculatePath(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), false);
6249 if (m_preGeneratedPath->GetPathType() & PATHFIND_SHORT)
6250 return SPELL_FAILED_NOPATH;
6251 else if (!result || m_preGeneratedPath->GetPathType() & (PATHFIND_NOPATH | PATHFIND_INCOMPLETE))
6252 return SPELL_FAILED_NOPATH;
6253 else if (m_preGeneratedPath->IsInvalidDestinationZ(target)) // Check position z, if not in a straight line
6254 return SPELL_FAILED_NOPATH;
6255
6256 m_preGeneratedPath->ShortenPathUntilDist(G3D::Vector3(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ()), objSize); // move back
6257 }
6258 if (Player* player = m_caster->ToPlayer())
6259 player->SetCanTeleport(true);
6260 break;
6261 }
6263 {
6266
6269
6270 Creature* creature = m_targets.GetUnitTarget()->ToCreature();
6271 if (!creature->IsCritter() && !creature->loot.isLooted())
6273
6274 uint32 skill = creature->GetCreatureTemplate()->GetRequiredLootSkill();
6275
6276 int32 skillValue = m_caster->ToPlayer()->GetSkillValue(skill);
6277 int32 TargetLevel = m_targets.GetUnitTarget()->GetLevel();
6278 int32 ReqValue = (skillValue < 100 ? (TargetLevel - 10) * 10 : TargetLevel * 5);
6279 if (ReqValue > skillValue)
6281
6282 break;
6283 }
6285 {
6286 if (m_spellInfo->Effects[i].TargetA.GetTarget() != TARGET_GAMEOBJECT_TARGET &&
6287 m_spellInfo->Effects[i].TargetA.GetTarget() != TARGET_GAMEOBJECT_ITEM_TARGET)
6288 break;
6289
6290 if (!m_caster->IsPlayer() // only players can open locks, gather etc.
6291 // we need a go target in case of TARGET_GAMEOBJECT_TARGET
6292 || (m_spellInfo->Effects[i].TargetA.GetTarget() == TARGET_GAMEOBJECT_TARGET && !m_targets.GetGOTarget()))
6294
6295 Item* pTempItem = nullptr;
6297 {
6298 if (TradeData* pTrade = m_caster->ToPlayer()->GetTradeData())
6299 pTempItem = pTrade->GetTraderData()->GetItem(TradeSlots(m_targets.GetItemTargetGUID().GetRawValue()));
6300 }
6303
6304 // we need a go target, or an openable item target in case of TARGET_GAMEOBJECT_ITEM_TARGET
6305 if (m_spellInfo->Effects[i].TargetA.GetTarget() == TARGET_GAMEOBJECT_ITEM_TARGET &&
6307 (!pTempItem || !pTempItem->GetTemplate()->LockID || !pTempItem->IsLocked()))
6309
6310 // We must also ensure the gameobject we are opening is still closed by the time the spell finishes.
6311 if (GameObject* go = m_targets.GetGOTarget())
6312 {
6313 if (go->GetGoType() == GAMEOBJECT_TYPE_DOOR && go->GetGoState() != GO_STATE_READY)
6314 {
6316 }
6317 }
6318 if (m_spellInfo->Id != 1842 || (m_targets.GetGOTarget() &&
6320 {
6321 if (m_targets.GetGOTarget() && m_targets.GetGOTarget()->GetEntry() == 179697)
6322 {
6323 if (!m_caster->ToPlayer()->CanUseBattlegroundObject(nullptr))
6325 }
6326 else if (m_caster->ToPlayer()->InBattleground() && // In Battleground players can use only flags and banners, or Gurubashi chest
6329 }
6330
6331 // get the lock entry
6332 uint32 lockId = 0;
6333 if (GameObject* go = m_targets.GetGOTarget())
6334 {
6335 lockId = go->GetGOInfo()->GetLockId();
6336 if (!lockId)
6338 }
6339 else if (Item* itm = m_targets.GetItemTarget())
6340 lockId = itm->GetTemplate()->LockID;
6341
6342 SkillType skillId = SKILL_NONE;
6343 int32 reqSkillValue = 0;
6344 int32 skillValue = 0;
6345
6346 // check lock compatibility
6347 SpellCastResult res = CanOpenLock(i, lockId, skillId, reqSkillValue, skillValue);
6348 if (res != SPELL_CAST_OK)
6349 return res;
6350
6351 // chance for fail at lockpicking attempt
6352 // second check prevent fail at rechecks
6353 // herbalism and mining cannot fail as of patch 3.1.0
6354 if (skillId != SKILL_NONE && skillId != SKILL_HERBALISM && skillId != SKILL_MINING && (!m_selfContainer || ((*m_selfContainer) != this)))
6355 {
6356 // chance for failure in orange lockpick
6357 if (skillId == SKILL_LOCKPICKING && reqSkillValue > irand(skillValue - 25, skillValue + 37))
6358 {
6360 }
6361 }
6362 break;
6363 }
6365 {
6366 Unit* unitCaster = m_caster->ToUnit();
6367 if (!unitCaster)
6368 {
6370 }
6371
6372 Creature* pet = unitCaster->GetGuardianPet();
6373 if (pet)
6374 {
6375 if (pet->IsAlive())
6376 {
6378 }
6379 }
6380 else if (Player* playerCaster = m_caster->ToPlayer())
6381 {
6382 PetStable& petStable = playerCaster->GetOrInitPetStable();
6383 if (!petStable.CurrentPet && petStable.UnslottedPets.empty())
6384 {
6385 return SPELL_FAILED_NO_PET;
6386 }
6387 }
6388
6389 break;
6390 }
6391 // This is generic summon effect
6393 {
6394 SummonPropertiesEntry const* SummonProperties = sSummonPropertiesStore.LookupEntry(m_spellInfo->Effects[i].MiscValueB);
6395 if (!SummonProperties || m_spellInfo->HasAttribute(SPELL_ATTR1_DISMISS_PET_FIRST))
6396 break;
6397 switch (SummonProperties->Category)
6398 {
6400 if (m_caster->GetPetGUID())
6402 [[fallthrough]];
6404 if (m_caster->GetCharmGUID())
6406 break;
6407 }
6408 break;
6409 }
6411 {
6413 {
6418 }
6419 break;
6420 }
6422 {
6423 Unit* unitCaster = m_caster->ToUnit();
6424 if (!unitCaster)
6426
6428 {
6429 if (m_caster->GetPetGUID())
6431 if (m_caster->GetCharmGUID())
6433 }
6434
6436 if (Pet* pet = m_caster->ToPlayer()->GetPet())
6437 pet->CastSpell(pet, 32752, true, nullptr, nullptr, pet->GetGUID()); //starting cast, trigger pet stun (cast by pet so it doesn't attack player)
6438
6439 Player* playerCaster = unitCaster->ToPlayer();
6440 if (playerCaster && playerCaster->GetPetStable())
6441 {
6442 std::pair<PetStable::PetInfo const*, PetSaveMode> info = Pet::GetLoadPetInfo(*playerCaster->GetPetStable(), m_spellInfo->Effects[i].MiscValue, 0, false);
6443 if (info.first)
6444 {
6445 if (info.first->Type == HUNTER_PET)
6446 {
6447 if (!info.first->Health)
6448 {
6449 playerCaster->SendTameFailure(PET_TAME_DEAD);
6451 }
6452
6453 CreatureTemplate const* creatureInfo = sObjectMgr->GetCreatureTemplate(info.first->CreatureId);
6454 if (!creatureInfo || !creatureInfo->IsTameable(playerCaster->CanTameExoticPets()))
6455 {
6456 // if problem in exotic pet
6457 if (creatureInfo && creatureInfo->IsTameable(true))
6459 else
6461
6463 }
6464 }
6465 }
6466 else if (!m_spellInfo->Effects[i].MiscValue) // when miscvalue is present it is allowed to create new pets
6467 {
6470 }
6471 }
6472 break;
6473 }
6475 {
6476 if (!m_caster->IsPlayer())
6478 if (!m_caster->GetTarget())
6480
6482 if (!target || (!target->IsInSameRaidWith(m_caster->ToPlayer()) && m_spellInfo->Id != 48955)) // refer-a-friend spell
6484
6485 // Xinef: Implement summon pending error
6486 if (target->GetSummonExpireTimer() > GameTime::GetGameTime().count())
6488
6489 // check if our map is dungeon
6490 MapEntry const* map = sMapStore.LookupEntry(m_caster->GetMapId());
6491 if (map->IsDungeon())
6492 {
6493 uint32 mapId = m_caster->GetMap()->GetId();
6494 Difficulty difficulty = m_caster->GetMap()->GetDifficulty();
6495 /*if (map->IsRaid())
6496 if (InstancePlayerBind* targetBind = target->GetBoundInstance(mapId, difficulty))
6497 if (targetBind->perm && targetBind != m_caster->ToPlayer()->GetBoundInstance(mapId, difficulty))
6498 return SPELL_FAILED_TARGET_LOCKED_TO_RAID_INSTANCE;*/
6499
6500 InstanceTemplate const* instance = sObjectMgr->GetInstanceTemplate(mapId);
6501 if (!instance)
6503 if (!target->Satisfy(sObjectMgr->GetAccessRequirement(mapId, difficulty), mapId))
6505 }
6506 break;
6507 }
6508 // RETURN HERE
6510 {
6511 if (!m_caster->IsPlayer())
6513
6514 Player* playerCaster = m_caster->ToPlayer();
6515 //
6516 if (!(playerCaster->GetTarget()))
6518
6520
6521 if (!target ||
6522 !(target->GetSession()->GetRecruiterId() == playerCaster->GetSession()->GetAccountId() || target->GetSession()->GetAccountId() == playerCaster->GetSession()->GetRecruiterId()))
6524
6525 // Xinef: Implement summon pending error
6526 if (target->GetSummonExpireTimer() > GameTime::GetGameTime().count())
6528
6529 break;
6530 }
6531 case SPELL_EFFECT_LEAP:
6533 {
6534 //Do not allow to cast it before BG starts.
6535 if (m_caster->IsPlayer())
6536 if (Battleground const* bg = m_caster->ToPlayer()->GetBattleground())
6537 if (bg->GetStatus() != STATUS_IN_PROGRESS)
6539 break;
6540 }
6542 {
6545
6546 bool found = false;
6548 for(Unit::VisibleAuraMap::const_iterator itr = visibleAuras->begin(); itr != visibleAuras->end(); ++itr)
6549 {
6550 if (itr->second->GetBase()->IsPassive())
6551 continue;
6552
6553 if (!itr->second->IsPositive())
6554 continue;
6555
6556 found = true;
6557 break;
6558 }
6559
6560 if (!found)
6562
6563 break;
6564 }
6566 {
6568 {
6569 if (m_caster->IsPlayer())
6570 return SPELL_FAILED_ROOTED;
6571 else
6573 }
6574 break;
6575 }
6576 // xinef: do not allow to use leaps while rooted
6577 case SPELL_EFFECT_JUMP:
6579 {
6581 return SPELL_FAILED_ROOTED;
6582 break;
6583 }
6585 if (!sScriptMgr->CanSelectSpecTalent(this))
6587 // can't change during already started arena/battleground
6588 if (m_caster->IsPlayer())
6589 if (Battleground const* bg = m_caster->ToPlayer()->GetBattleground())
6590 if (bg->GetStatus() == STATUS_IN_PROGRESS)
6592 break;
6593 default:
6594 break;
6595 }
6596 }
6597
6598 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
6599 {
6600 switch (m_spellInfo->Effects[i].ApplyAuraName)
6601 {
6602 case SPELL_AURA_DUMMY:
6603 break;
6605 {
6606 if (!m_caster->IsPlayer())
6607 return SPELL_FAILED_NO_PET;
6608
6609 Pet* pet = m_caster->ToPlayer()->GetPet();
6610 if (!pet)
6611 return SPELL_FAILED_NO_PET;
6612
6613 if (pet->GetCharmerGUID())
6614 return SPELL_FAILED_CHARMED;
6615 break;
6616 }
6620 {
6621 if (m_caster->GetCharmerGUID())
6622 return SPELL_FAILED_CHARMED;
6623
6624 // Xinef: allow SPELL_AURA_MOD_POSSESS to posses target if caster has some pet
6626 {
6627 if (m_caster->GetPetGUID())
6629
6630 if (m_caster->GetCharmGUID())
6632 }
6633 else if (m_spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_MOD_POSSESS)
6634 {
6635 if (m_caster->GetCharmGUID())
6637 }
6638
6639 if (Unit* target = m_targets.GetUnitTarget())
6640 {
6641 if (target->IsCreature() && target->ToCreature()->IsVehicle())
6643
6644 if (target->IsMounted())
6646
6647 if (target->GetCharmerGUID())
6648 return SPELL_FAILED_CHARMED;
6649
6650 if (target->GetOwnerGUID() && target->GetOwnerGUID().IsPlayer())
6652
6653 if (target->IsPet() && (!target->GetOwner() || target->GetOwner()->ToPlayer()))
6655
6656 int32 damage = CalculateSpellDamage(i, target);
6657 if (damage && int32(target->GetLevel()) > damage)
6659 }
6660
6661 break;
6662 }
6663 case SPELL_AURA_MOUNTED:
6664 {
6665 // Disallow casting flying mounts in water
6668
6669 // Ignore map check if spell have AreaId. AreaId already checked and this prevent special mount spells
6670 bool allowMount = !m_caster->GetMap()->IsDungeon() || m_caster->GetMap()->IsBattlegroundOrArena();
6671 InstanceTemplate const* it = sObjectMgr->GetInstanceTemplate(m_caster->GetMapId());
6672 if (it)
6673 allowMount = it->AllowMount;
6674 if (m_caster->IsPlayer() && !allowMount && !m_spellInfo->AreaGroupId)
6676
6679
6680 // xinef: dont allow to cast mounts in specific transforms
6681 if (m_caster->getTransForm())
6682 if (SpellInfo const* transformSpellInfo = sSpellMgr->GetSpellInfo(m_caster->getTransForm()))
6683 if (transformSpellInfo->HasAttribute(SPELL_ATTR0_NO_IMMUNITIES) &&
6684 !transformSpellInfo->HasAttribute(SpellAttr0(SPELL_ATTR0_ALLOW_WHILE_MOUNTED | SPELL_ATTR0_AURA_IS_DEBUFF)))
6686
6687 break;
6688 }
6690 {
6691 if (!m_targets.GetUnitTarget())
6693
6694 // can be casted at non-friendly unit or own pet/charm
6697
6698 break;
6699 }
6700 case SPELL_AURA_FLY:
6702 {
6703 // Xinef: added water check
6704 if (m_caster->IsInWater())
6706
6707 // not allow cast fly spells if not have req. skills (all spells is self target)
6708 // allow always ghost flight spells
6710 {
6711 Battlefield* Bf = sBattlefieldMgr->GetBattlefieldToZoneId(m_originalCaster->GetZoneId());
6712 if (AreaTableEntry const* pArea = sAreaTableStore.LookupEntry(m_originalCaster->GetAreaId()))
6713 if ((pArea->flags & AREA_FLAG_NO_FLY_ZONE) || (Bf && !Bf->CanFlyIn()))
6714 return SPELL_FAILED_NOT_HERE;
6715 }
6716 break;
6717 }
6719 {
6720 if (m_spellInfo->Effects[i].IsTargetingArea())
6721 break;
6722
6723 if (!m_caster->IsPlayer() || m_CastItem)
6724 break;
6725
6726 if (!m_targets.GetUnitTarget())
6728
6731
6732 break;
6733 }
6734 case SPELL_AURA_HOVER:
6735 {
6737 {
6739 }
6740 break;
6741 }
6743 {
6744 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.
6745 {
6747 }
6748 break;
6749 }
6750 default:
6751 break;
6752 }
6753 }
6754
6755 // check trade slot case (last, for allow catch any another cast problems)
6757 {
6758 if (m_CastItem)
6760
6761 if (!m_caster->IsPlayer())
6763
6764 TradeData* my_trade = m_caster->ToPlayer()->GetTradeData();
6765
6766 if (!my_trade)
6768
6770 if (slot != TRADE_SLOT_NONTRADED)
6772
6773 if (!IsTriggered())
6774 if (my_trade->GetSpell())
6776 }
6777
6778 // check if caster has at least 1 combo point on target for spells that require combo points
6780 {
6782 {
6784 {
6786 }
6787 }
6788 else
6789 {
6790 if (!m_caster->GetComboPoints())
6791 {
6793 }
6794 }
6795 }
6796
6797 // xinef: check relic cooldown
6801
6802 // all ok
6803 return SPELL_CAST_OK;
6804}
constexpr auto IN_MILLISECONDS
Definition: Common.h:53
constexpr auto MINUTE
Definition: Common.h:47
int32 irand(int32 min, int32 max)
Definition: Random.cpp:37
std::int32_t int32
Definition: Define.h:103
std::uint16_t uint16
Definition: Define.h:108
#define sConditionMgr
Definition: ConditionMgr.h:289
@ CONDITION_SOURCE_TYPE_SPELL
Definition: ConditionMgr.h:139
std::list< Condition * > ConditionList
Definition: ConditionMgr.h:236
@ STATUS_WAIT_LEAVE
Definition: Battleground.h:198
@ STATUS_IN_PROGRESS
Definition: Battleground.h:197
LineOfSightChecks
Definition: Map.h:191
@ LINEOFSIGHT_ALL_CHECKS
Definition: Map.h:198
#define sBattlefieldMgr
Definition: BattlefieldMgr.h:77
@ PATHFIND_NOPATH
Definition: PathGenerator.h:51
@ PATHFIND_SHORT
Definition: PathGenerator.h:53
@ PATHFIND_INCOMPLETE
Definition: PathGenerator.h:50
DBCStorage< SummonPropertiesEntry > sSummonPropertiesStore(SummonPropertiesfmt)
DBCStorage< SpellShapeshiftFormEntry > sSpellShapeshiftFormStore(SpellShapeshiftFormEntryfmt)
DBCStorage< MapEntry > sMapStore(MapEntryfmt)
DBCStorage< GlyphPropertiesEntry > sGlyphPropertiesStore(GlyphPropertiesfmt)
DBCStorage< AreaTableEntry > sAreaTableStore(AreaTableEntryfmt)
#define SPECTATOR_SPELL_BINDSIGHT
Definition: ArenaSpectator.h:38
#define WORLD_TRIGGER
Definition: Unit.h:37
std::list< std::pair< Aura *, uint8 > > DispelChargesList
Definition: Unit.h:77
@ MOVEMENTFLAG_FALLING_FAR
Definition: UnitDefines.h:357
@ CLASS_CONTEXT_PET
Definition: UnitDefines.h:215
@ UNIT_FLAG2_ALLOW_CHEAT_SPELLS
Definition: UnitDefines.h:285
@ UNIT_STATE_ROOT
Definition: UnitDefines.h:159
@ UNIT_STATE_CHARGING
Definition: UnitDefines.h:166
@ UNIT_FLAG_SKINNABLE
Definition: UnitDefines.h:255
TradeSlots
Definition: TradeData.h:28
@ TRADE_SLOT_NONTRADED
Definition: TradeData.h:31
@ PLAYER_ALLOW_ONLY_ABILITY
Definition: Player.h:497
@ GO_STATE_READY
Definition: GameObjectData.h:691
@ INVTYPE_RELIC
Definition: ItemTemplate.h:284
@ HUNTER_PET
Definition: PetDefines.h:32
@ SPELL_AURA_ABILITY_IGNORE_AURASTATE
Definition: SpellAuraDefines.h:325
@ SPELL_AURA_MOD_SHAPESHIFT
Definition: SpellAuraDefines.h:99
@ SPELL_AURA_MOD_IGNORE_SHAPESHIFT
Definition: SpellAuraDefines.h:338
@ SPELL_AURA_PERIODIC_MANA_LEECH
Definition: SpellAuraDefines.h:127
@ SPELL_AURA_MOD_POSSESS_PET
Definition: SpellAuraDefines.h:191
@ SPELL_AURA_RANGED_ATTACK_POWER_ATTACKER_BONUS
Definition: SpellAuraDefines.h:190
@ SPELL_AURA_DUMMY
Definition: SpellAuraDefines.h:67
@ SPELL_AURA_FLY
Definition: SpellAuraDefines.h:264
@ SPELL_AURA_HOVER
Definition: SpellAuraDefines.h:169
@ SPELL_AURA_MOUNTED
Definition: SpellAuraDefines.h:141
@ SPELL_AURA_AOE_CHARM
Definition: SpellAuraDefines.h:240
@ SPELL_AURA_MOD_POSSESS
Definition: SpellAuraDefines.h:65
@ SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED
Definition: SpellAuraDefines.h:270
@ SPELL_AURA_BLOCK_SPELL_FAMILY
Definition: SpellAuraDefines.h:360
@ AURA_INTERRUPT_FLAG_NOT_SEATED
Definition: SpellDefines.h: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_EFFECTS
Periodic aura tick wont be reset on override.
Definition: SpellDefines.h:151
@ TRIGGERED_IGNORE_CASTER_AURAS
Will ignore mounted/on vehicle restrictions.
Definition: SpellDefines.h:145
std::vector< SpellImmune > SpellImmuneList
Definition: SpellDefines.h:180
#define SPELL_RELIC_COOLDOWN
Definition: SpellMgr.h:34
@ TARGET_FLAG_UNIT_ENEMY
Definition: SpellInfo.h:53
@ TARGET_FLAG_ITEM
Definition: SpellInfo.h:50
@ SPELL_ATTR0_CU_REQ_TARGET_FACING_CASTER
Definition: SpellInfo.h:192
@ SPELL_ATTR0_CU_REQ_CASTER_BEHIND_TARGET
Definition: SpellInfo.h:193
@ SPELL_FLAG_REDIRECTED
Definition: Spell.h:83
@ GAMEOBJECT_TYPE_TRAP
Definition: SharedDefines.h:1566
@ GAMEOBJECT_TYPE_DOOR
Definition: SharedDefines.h:1560
Powers
Definition: SharedDefines.h:268
@ POWER_MANA
Definition: SharedDefines.h:269
@ SPELL_ATTR7_DEBUG_SPELL
Definition: SharedDefines.h:644
@ SPELL_EFFECT_LEAP
Definition: SharedDefines.h:807
@ SPELL_EFFECT_POWER_BURN
Definition: SharedDefines.h:840
@ SPELL_EFFECT_STUCK
Definition: SharedDefines.h:862
@ SPELL_EFFECT_SUMMON_RAF_FRIEND
Definition: SharedDefines.h:930
@ SPELL_EFFECT_APPLY_GLYPH
Definition: SharedDefines.h:852
@ SPELL_EFFECT_FEED_PET
Definition: SharedDefines.h:879
@ SPELL_EFFECT_SUMMON_PLAYER
Definition: SharedDefines.h:863
@ SPELL_EFFECT_JUMP_DEST
Definition: SharedDefines.h:820
@ SPELL_EFFECT_TELEPORT_UNITS_FACE_CASTER
Definition: SharedDefines.h:821
@ SPELL_EFFECT_RESURRECT_PET
Definition: SharedDefines.h:887
@ SPELL_EFFECT_LEAP_BACK
Definition: SharedDefines.h:916
@ SPELL_EFFECT_SUMMON
Definition: SharedDefines.h:806
@ SPELL_EFFECT_POWER_DRAIN
Definition: SharedDefines.h:786
@ SPELL_EFFECT_RESURRECT
Definition: SharedDefines.h:796
@ SPELL_EFFECT_CHARGE
Definition: SharedDefines.h:874
@ SPELL_EFFECT_RESURRECT_NEW
Definition: SharedDefines.h:891
@ SPELL_EFFECT_TALENT_SPEC_SELECT
Definition: SharedDefines.h:940
@ SPELL_EFFECT_LEARN_SPELL
Definition: SharedDefines.h:814
@ SPELL_EFFECT_JUMP
Definition: SharedDefines.h:819
@ SPELL_EFFECT_SKINNING
Definition: SharedDefines.h:873
@ SPELL_EFFECT_CREATE_TAMED_PET
Definition: SharedDefines.h:931
@ SPELL_EFFECT_OPEN_LOCK
Definition: SharedDefines.h:811
@ SPELL_EFFECT_STEAL_BENEFICIAL_BUFF
Definition: SharedDefines.h:904
@ SPELL_EFFECT_LEARN_PET_SPELL
Definition: SharedDefines.h:835
@ SPELL_PREVENTION_TYPE_NONE
Definition: SharedDefines.h:1553
@ SPELL_ATTR5_ALWAYS_AOE_LINE_OF_SIGHT
Definition: SharedDefines.h:593
@ TARGET_UNIT_PET
Definition: SharedDefines.h:1414
@ TARGET_GAMEOBJECT_TARGET
Definition: SharedDefines.h:1427
@ SPELL_ATTR2_IGNORE_LINE_OF_SIGHT
Definition: SharedDefines.h:458
@ SPELL_ATTR1_INITIATE_COMBAT
Definition: SharedDefines.h:428
@ SPELL_ATTR3_ONLY_BATTLEGROUNDS
Definition: SharedDefines.h:504
@ PET_TAME_NOPET_AVAILABLE
Definition: SharedDefines.h:3683
@ PET_TAME_DEAD
Definition: SharedDefines.h:3686
@ PET_TAME_CANT_CONTROL_EXOTIC
Definition: SharedDefines.h:3688
@ CLASS_WARLOCK
Definition: SharedDefines.h:149
@ IMMUNITY_MECHANIC
Definition: SharedDefines.h:1399
@ SPELLFAMILY_WARRIOR
Definition: SharedDefines.h:3532
SpellCustomErrors
Definition: SharedDefines.h:1142
@ SPELL_CUSTOM_ERROR_GM_ONLY
Definition: SharedDefines.h:1208
SpellAttr0
Definition: SharedDefines.h:381
@ SPELL_ATTR0_ONLY_INDOORS
Definition: SharedDefines.h:396
@ SPELL_ATTR0_AURA_IS_DEBUFF
Definition: SharedDefines.h:408
@ SPELL_ATTR0_ONLY_OUTDOORS
Definition: SharedDefines.h:397
@ SPELL_ATTR0_ALLOW_WHILE_MOUNTED
Definition: SharedDefines.h:406
@ SPELL_ATTR0_PASSIVE
Definition: SharedDefines.h:388
@ SPELL_ATTR0_ALLOW_CAST_WHILE_DEAD
Definition: SharedDefines.h:405
@ SPELL_ATTR0_ONLY_STEALTHED
Definition: SharedDefines.h:399
AuraStateType
Definition: SharedDefines.h:1288
DispelType
Definition: SharedDefines.h:1371
@ SPELL_FAILED_TARGET_NOT_LOOTED
Definition: SharedDefines.h:1070
@ SPELL_FAILED_NOT_INFRONT
Definition: SharedDefines.h:1010
@ SPELL_FAILED_MOVING
Definition: SharedDefines.h:1000
@ SPELL_FAILED_NOT_MOUNTED
Definition: SharedDefines.h:1013
@ SPELL_FAILED_AFFECTING_COMBAT
Definition: SharedDefines.h:950
@ SPELL_FAILED_CASTER_AURASTATE
Definition: SharedDefines.h:971
@ SPELL_FAILED_NOTHING_TO_DISPEL
Definition: SharedDefines.h:1035
@ SPELL_FAILED_NOT_KNOWN
Definition: SharedDefines.h:1012
@ SPELL_FAILED_FOOD_LOWLEVEL
Definition: SharedDefines.h:984
@ SPELL_FAILED_NOT_HERE
Definition: SharedDefines.h:1009
@ SPELL_FAILED_ROOTED
Definition: SharedDefines.h:1052
@ SPELL_FAILED_WRONG_PET_FOOD
Definition: SharedDefines.h:1084
@ SPELL_FAILED_CUSTOM_ERROR
Definition: SharedDefines.h:1121
@ SPELL_FAILED_SUMMON_PENDING
Definition: SharedDefines.h:1132
@ SPELL_FAILED_DAMAGE_IMMUNE
Definition: SharedDefines.h:1095
@ SPELL_FAILED_BAD_IMPLICIT_TARGETS
Definition: SharedDefines.h:960
@ SPELL_FAILED_TRY_AGAIN
Definition: SharedDefines.h:1081
@ SPELL_FAILED_NO_COMBO_POINTS
Definition: SharedDefines.h:1027
@ SPELL_FAILED_ALREADY_HAVE_SUMMON
Definition: SharedDefines.h:956
@ SPELL_FAILED_ALREADY_OPEN
Definition: SharedDefines.h:957
@ SPELL_FAILED_NOT_TRADING
Definition: SharedDefines.h:1020
@ SPELL_FAILED_NOTHING_TO_STEAL
Definition: SharedDefines.h:1036
@ SPELL_FAILED_NO_MOUNTS_ALLOWED
Definition: SharedDefines.h:1032
@ SPELL_FAILED_NOT_IN_BATTLEGROUND
Definition: SharedDefines.h:1115
@ SPELL_FAILED_NOT_BEHIND
Definition: SharedDefines.h:1006
@ SPELL_FAILED_ALREADY_HAVE_CHARM
Definition: SharedDefines.h:955
@ SPELL_FAILED_TARGET_NOT_IN_INSTANCE
Definition: SharedDefines.h:1086
@ SPELL_FAILED_HIGHLEVEL
Definition: SharedDefines.h:985
@ SPELL_FAILED_LOWLEVEL
Definition: SharedDefines.h:997
@ SPELL_FAILED_NOT_READY
Definition: SharedDefines.h:1016
@ SPELL_FAILED_ONLY_BATTLEGROUNDS
Definition: SharedDefines.h:1091
@ SPELL_FAILED_NOT_IN_ARENA
Definition: SharedDefines.h:1100
@ SPELL_FAILED_ITEM_ALREADY_ENCHANTED
Definition: SharedDefines.h:991
@ SPELL_FAILED_ONLY_STEALTHED
Definition: SharedDefines.h:1044
@ SPELL_FAILED_TARGET_IS_PLAYER_CONTROLLED
Definition: SharedDefines.h:1067
@ SPELL_FAILED_ONLY_ABOVEWATER
Definition: SharedDefines.h:1037
@ SPELL_FAILED_CANT_BE_CHARMED
Definition: SharedDefines.h:962
@ SPELL_FAILED_CASTER_DEAD
Definition: SharedDefines.h:972
@ SPELL_FAILED_NOT_ON_MOUNTED
Definition: SharedDefines.h:1104
@ SPELL_FAILED_ITEM_ENCHANT_TRADE_WINDOW
Definition: SharedDefines.h:1131
@ SPELL_FAILED_TARGET_CANNOT_BE_RESURRECTED
Definition: SharedDefines.h:1135
@ SPELL_FAILED_TARGET_UNSKINNABLE
Definition: SharedDefines.h:1075
@ SPELL_FAILED_NOT_SHAPESHIFT
Definition: SharedDefines.h:1017
@ SPELL_FAILED_UNIQUE_GLYPH
Definition: SharedDefines.h:1125
@ SPELL_FAILED_ONLY_OUTDOORS
Definition: SharedDefines.h:1042
@ SPELL_FAILED_CHARMED
Definition: SharedDefines.h:973
@ SPELL_FAILED_LINE_OF_SIGHT
Definition: SharedDefines.h:996
@ SPELL_FAILED_SPELL_IN_PROGRESS
Definition: SharedDefines.h:1054
@ SPELL_FAILED_NO_PET
Definition: SharedDefines.h:1033
@ SPELL_FAILED_NOPATH
Definition: SharedDefines.h:1005
@ SPELL_FAILED_SPELL_UNAVAILABLE
Definition: SharedDefines.h:1056
@ SPELL_FAILED_ONLY_INDOORS
Definition: SharedDefines.h:1039
@ SPELL_FAILED_NOT_ON_TAXI
Definition: SharedDefines.h:1014
@ SPELL_FAILED_TARGET_FRIENDLY
Definition: SharedDefines.h:1064
@ SPELL_ATTR4_IGNORE_DEFAULT_ARENA_RESTRICTIONS
Definition: SharedDefines.h:547
@ SPELL_ATTR4_NOT_IN_ARENA_OR_RATED_BATTLEGROUND
Definition: SharedDefines.h:546
@ SUMMON_CATEGORY_PET
Definition: SharedDefines.h:3285
@ SUMMON_CATEGORY_PUPPET
Definition: SharedDefines.h:3286
SkillType
Definition: SharedDefines.h:2863
@ SKILL_MINING
Definition: SharedDefines.h:2919
@ SKILL_HERBALISM
Definition: SharedDefines.h:2915
@ SPELL_ATTR6_ALLOW_WHILE_RIDING_VEHICLE
Definition: SharedDefines.h:616
@ VEHICLE_SEAT_FLAG_CAN_CAST_MOUNT_SPELL
Definition: DBCEnums.h:456
@ VEHICLE_SEAT_FLAG_UNCONTROLLED
Definition: DBCEnums.h:457
@ VEHICLE_SEAT_FLAG_CAN_ATTACK
Definition: DBCEnums.h:458
Difficulty
Definition: DBCEnums.h:266
@ AREA_FLAG_NO_FLY_ZONE
Definition: DBCEnums.h:262
bool IsPathfindingEnabled(const Map *map)
Definition: DisableMgr.cpp:411
Player * FindPlayer(ObjectGuid const guid)
Definition: ObjectAccessor.cpp:248
Seconds GetGameTime()
Definition: GameTime.cpp:38
Definition: Battlefield.h:206
bool CanFlyIn()
Return if we can use mount in battlefield.
Definition: Battlefield.h:342
Definition: Battleground.h:298
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:227
CreatureTemplate const * GetCreatureTemplate() const
Definition: Creature.h:206
bool IsSpellProhibited(SpellSchoolMask idSchoolMask) const
Definition: Creature.cpp:2823
SkillType GetRequiredLootSkill() const
Definition: CreatureData.h:260
bool IsTameable(bool exotic) const
Definition: CreatureData.h:277
Definition: TemporarySummon.h:40
Definition: GameObject.h:121
GameObjectTemplate const * GetGOInfo() const
Definition: GameObject.h:137
uint32 type
Definition: GameObjectData.h:34
bool IsLocked() const
Definition: Item.h:253
ItemTemplate const * GetTemplate() const
Definition: Item.cpp:545
bool IsPotion() const
Definition: Item.h:337
uint32 ItemLevel
Definition: ItemTemplate.h:635
uint32 LockID
Definition: ItemTemplate.h:669
uint32 InventoryType
Definition: ItemTemplate.h:632
Unit * ToUnit()
Definition: Object.h:206
Map * GetMap() const
Definition: Object.h:531
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:3169
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:3152
uint32 GetZoneId() const
Definition: Object.cpp:3144
void GetZoneAndAreaId(uint32 &zoneid, uint32 &areaid) const
Definition: Object.cpp:3160
uint64 GetRawValue() const
Definition: ObjectGuid.h:142
bool IsPlayer() const
Definition: ObjectGuid.h:168
bool IsGameObject() const
Definition: ObjectGuid.h:171
void GetPosition(float &x, float &y) const
Definition: Position.h:122
uint32 GetMapId() const
Definition: Position.h:276
Player * GetOwner() const
Definition: Pet.cpp:2493
bool HaveInDiet(ItemTemplate const *item) const
Definition: Pet.cpp:1439
uint32 GetCurrentFoodBenefitLevel(uint32 itemlevel) const
Definition: Pet.cpp:1457
static std::pair< PetStable::PetInfo const *, PetSaveMode > GetLoadPetInfo(PetStable const &stable, uint32 petEntry, uint32 petnumber, bool current)
Definition: Pet.cpp:170
Definition: PetDefines.h:202
Optional< PetInfo > CurrentPet
Definition: PetDefines.h:225
std::vector< PetInfo > UnslottedPets
Definition: PetDefines.h:228
void SetCanTeleport(bool value)
Definition: Player.h:2478
bool IsInSameRaidWith(Player const *p) const
Definition: Player.h:1866
bool CanTameExoticPets() const
Definition: Player.h:2169
bool CanUseBattlegroundObject(GameObject *gameobject) const
Definition: Player.cpp:13218
bool InBattleground() const
Definition: Player.h:2232
PetStable * GetPetStable()
Definition: Player.h:1202
Battleground * GetBattleground(bool create=false) const
Definition: Player.cpp:12192
WorldSession * GetSession() const
Definition: Player.h:1978
bool HasSpellCooldown(uint32 spell_id) const override
Definition: Player.cpp:16334
uint32 GetLastPotionId()
Definition: Player.h:1792
Group * GetGroup()
Definition: Player.h:2448
bool IsGameMaster() const
Definition: Player.h:1158
time_t GetSummonExpireTimer() const
Definition: Player.h:1101
bool Satisfy(DungeonProgressionRequirements const *ar, uint32 target_map, bool report=false)
Definition: PlayerStorage.cpp:6711
bool HasPlayerFlag(PlayerFlags flags) const
Definition: Player.h:1108
std::unique_ptr< DuelInfo > duel
Definition: Player.h:1858
Item * GetItemByGuid(ObjectGuid guid) const
Definition: PlayerStorage.cpp:413
uint32 GetSpell() const
Definition: TradeData.h:49
bool IsVehicle() const
Definition: Unit.h:713
Vehicle * GetVehicle() const
Definition: Unit.h:1673
Unit * GetOwner() const
Definition: Unit.cpp:10562
Pet * ToPet()
Definition: Unit.h:1714
virtual bool HasSpellCooldown(uint32) const
Definition: Unit.h:1727
ShapeshiftForm GetShapeshiftForm() const
Definition: Unit.h:1463
virtual bool HasSpellItemCooldown(uint32, uint32) const
Definition: Unit.h:1728
bool IsInDisallowedMountForm() const
Definition: Unit.cpp:21201
void CombatStart(Unit *target, bool initialAggro=true)
Definition: Unit.cpp:13586
bool HasUnitFlag2(UnitFlags2 flags) const
Definition: Unit.h:688
bool IsInSanctuary() const
Definition: Unit.h:964
virtual bool IsClass(Classes unitClass, ClassContext context=CLASS_CONTEXT_NONE) const
Definition: Unit.h:748
AuraEffect * IsScriptOverriden(SpellInfo const *spell, int32 script) const
Definition: Unit.cpp:5780
float GetCombatReach() const override
Definition: Unit.h:770
UnitFlags GetUnitFlags() const
Definition: Unit.h:681
TempSummon * ToTempSummon()
Definition: Unit.h:1716
bool HasStealthAura() const
Definition: Unit.h:1103
bool HasAura(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemCasterGUID=ObjectGuid::Empty, uint8 reqEffMask=0) const
Definition: Unit.cpp:5669
std::map< uint8, AuraApplication * > VisibleAuraMap
Definition: Unit.h:652
bool IsInFlight() const
Definition: Unit.h:1096
SpellImmuneList m_spellImmune[MAX_SPELL_IMMUNITY]
Definition: Unit.h:1794
void SendTameFailure(uint8 result)
Definition: Unit.cpp:19957
bool HasUnitMovementFlag(uint32 f) const
Definition: Unit.h:1613
virtual bool IsInWater() const
Definition: Unit.cpp:4321
bool HasAuraState(AuraStateType flag, SpellInfo const *spellProto=nullptr, Unit const *Caster=nullptr) const
Definition: Unit.cpp:10509
bool isMoving() const
Definition: Unit.h:1696
ObjectGuid GetCharmGUID() const
Definition: Unit.h:1218
VisibleAuraMap const * GetVisibleAuras()
Definition: Unit.h:1490
bool IsMounted() const
Definition: Unit.h:990
Unit * GetVictim() const
Definition: Unit.h:789
bool IsCritter() const
Definition: Unit.h:1094
ObjectGuid GetOwnerGUID() const
Definition: Unit.h:1210
uint8 GetComboPoints(Unit const *who=nullptr) const
--------—Combo point system----------------—
Definition: Unit.h:1629
ObjectGuid GetCharmerGUID() const
Definition: Unit.h:1216
uint32 getTransForm() const
Definition: Unit.h:1513
virtual bool HasActivePowerType(Powers power)
Definition: Unit.h:890
void RemoveMovementImpairingAuras(bool withRoot)
Definition: Unit.cpp:5205
bool IsTotem() const
Definition: Unit.h:712
Guardian * GetGuardianPet() const
Definition: Unit.cpp:10613
ObjectGuid GetTarget() const
Definition: Unit.h:1742
bool IsInCombat() const
Definition: Unit.h:820
ObjectGuid GetPetGUID() const
Definition: Unit.h:1220
Definition: Vehicle.h:28
VehicleSeatEntry const * GetSeatForPassenger(Unit const *passenger)
Definition: Vehicle.cpp:580
Definition: Group.h:169
Definition: GroupReference.h:27
GroupReference * next()
Definition: GroupReference.h:36
Definition: InstanceScript.h:142
bool isLooted() const
Definition: LootMgr.h:368
Definition: Map.h:274
bool AllowMount
Definition: Map.h:277
bool IsDungeon() const
Definition: Map.h:448
bool IsBattlegroundOrArena() const
Definition: Map.h:456
GameObject * GetGameObject(ObjectGuid const guid)
Definition: Map.cpp:3319
uint32 GetId() const
Definition: Map.h:379
Difficulty GetDifficulty() const
Definition: Map.h:443
uint32 GetRecruiterId() const
Definition: WorldSession.h:526
uint32 GetAccountId() const
Definition: WorldSession.h:361
GameObject * GetGOTarget() const
Definition: Spell.cpp:265
ObjectGuid GetItemTargetGUID() const
Definition: Spell.h:138
std::unique_ptr< PathGenerator > m_preGeneratedPath
Definition: Spell.h:776
SpellCastResult CheckSpellFocus()
Definition: Spell.cpp:7738
SpellCastResult CanOpenLock(uint32 effIndex, uint32 lockid, SkillType &skillid, int32 &reqSkillValue, int32 &skillValue)
Definition: Spell.cpp:8350
SpellCastResult CheckItems()
Definition: Spell.cpp:7170
int32 CalculateSpellDamage(uint8 i, Unit const *target) const
Definition: Spell.h:477
SpellCastResult CheckPower()
Definition: Spell.cpp:7125
SpellCastResult CheckCasterAuras(bool preventionOnly) const
Definition: Spell.cpp:6842
SpellCastResult CallScriptCheckCastHandlers()
Definition: Spell.cpp:8549
bool IsTriggered() const
Definition: Spell.h:552
SpellCastResult CheckRange(bool strict)
Definition: Spell.cpp:7039
bool HasGlobalCooldown() const
Definition: Spell.cpp:8821
Definition: SpellInfo.h:249
int32 MiscValue
Definition: SpellInfo.h:263
uint32 ApplyAuraName
Definition: SpellInfo.h:254
uint32 PreventionType
Definition: SpellInfo.h:390
uint32 CasterAuraSpell
Definition: SpellInfo.h:343
SpellCastResult CheckShapeshift(uint32 form) const
Definition: SpellInfo.cpp:1433
uint32 Mechanic
Definition: SpellInfo.h:323
uint32 GetDispelMask() const
Definition: SpellInfo.cpp:2040
uint32 GetRecoveryTime() const
Definition: SpellInfo.cpp:2395
bool IsSelfCast() const
Definition: SpellInfo.cpp:1089
uint32 CasterAuraState
Definition: SpellInfo.h:339
bool CanBeUsedInCombat() const
Definition: SpellInfo.cpp:1231
uint32 CasterAuraStateNot
Definition: SpellInfo.h:341
SpellCastResult CheckLocation(uint32 map_id, uint32 zone_id, uint32 area_id, Player *player=nullptr, bool strict=true) const
Definition: SpellInfo.cpp:1488
SpellSchoolMask GetSchoolMask() const
Definition: SpellInfo.cpp:1986
int32 AreaGroupId
Definition: SpellInfo.h:391
float GetMaxRange(bool positive=false, Unit *caster=nullptr, Spell *spell=nullptr) const
Definition: SpellInfo.cpp:2322
uint32 GetExplicitTargetMask() const
Definition: SpellInfo.cpp:2054
bool NeedsExplicitUnitTarget() const
Definition: SpellInfo.cpp:1032
uint32 ExcludeCasterAuraSpell
Definition: SpellInfo.h:345
uint32 SpellFamilyName
Definition: SpellInfo.h:387
uint32 AuraInterruptFlags
Definition: SpellInfo.h:353
SpellCastResult CheckExplicitTarget(Unit const *caster, WorldObject const *target, Item const *itemTarget=nullptr) const
Definition: SpellInfo.cpp:1936
Definition: DBCStructure.h:519
Definition: DBCStructure.h:1021
Definition: DBCStructure.h:1325
bool IsDungeon() const
Definition: DBCStructure.h:1351
Definition: DBCStructure.h:1817
uint32 flags1
Definition: DBCStructure.h:1822
Definition: DBCStructure.h:1909
uint32 Category
Definition: DBCStructure.h:1911
Definition: DBCStructure.h:2064
uint32 m_flags
Definition: DBCStructure.h:2066

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

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

◆ CheckCasterAuras()

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

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

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

Referenced by SelectEffectImplicitTargets(), and SelectImplicitDestDestTargets().

◆ CheckEffectExecuteData()

void Spell::CheckEffectExecuteData ( )
protected
8483{
8484 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
8486}
#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
7916{
7917 switch (m_spellInfo->Effects[eff].ApplyAuraName)
7918 {
7923 if (target->IsCreature() && target->IsVehicle())
7924 return false;
7925 if (target->IsMounted())
7926 return false;
7927 if (target->GetCharmerGUID())
7928 return false;
7929 if (int32 damage = CalculateSpellDamage(eff, target))
7930 if ((int32)target->GetLevel() > damage)
7931 return false;
7932 break;
7933 default:
7934 break;
7935 }
7936
7937 // xinef: skip los checking if spell has appropriate attribute, or target requires specific entry
7938 // 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
7939 if (m_spellInfo->HasAttribute(SPELL_ATTR2_IGNORE_LINE_OF_SIGHT) || (target->IsCreature() && target->HasUnitFlag(UNIT_FLAG_NOT_SELECTABLE) && (m_spellInfo->Effects[eff].TargetA.GetCheckType() == TARGET_CHECK_ENTRY || m_spellInfo->Effects[eff].TargetB.GetCheckType() == TARGET_CHECK_ENTRY)))
7940 return true;
7941
7942 // if spell is triggered, need to check for LOS disable on the aura triggering it and inherit that behaviour
7945 {
7946 return true;
7947 }
7948
7950 //Check targets for LOS visibility (except spells without range limitations)
7951 switch (m_spellInfo->Effects[eff].Effect)
7952 {
7954 // player far away, maybe his corpse near?
7955 if (target != m_caster && !target->IsWithinLOSInMap(m_caster))
7956 {
7958 return false;
7959
7961 if (!corpse)
7962 return false;
7963
7964 if (target->GetGUID() != corpse->GetOwnerGUID())
7965 return false;
7966
7968 return false;
7969 }
7970 break;
7972 {
7974 {
7975 if (target->IsWithinLOSInMap(m_caster, VMAP::ModelIgnoreFlags::M2) && target->HasUnitFlag(UNIT_FLAG_SKINNABLE))
7976 return true;
7977
7978 return false;
7979 }
7980
7982 if (!corpse)
7983 return false;
7984
7985 if (target->GetGUID() != corpse->GetOwnerGUID())
7986 return false;
7987
7989 return false;
7990
7992 return false;
7993 }
7994 break;
7996 if (!m_caster->IsPlayer() || !target->IsPlayer())
7997 return false;
7998 if (m_caster->ToPlayer()->GetSession()->IsARecruiter() && target->ToPlayer()->GetSession()->GetRecruiterId() != m_caster->ToPlayer()->GetSession()->GetAccountId())
7999 return false;
8000 if (m_caster->ToPlayer()->GetSession()->GetRecruiterId() != target->ToPlayer()->GetSession()->GetAccountId() && target->ToPlayer()->GetSession()->IsARecruiter())
8001 return false;
8002 if (target->ToPlayer()->GetLevel() >= sWorld->getIntConfig(CONFIG_MAX_RECRUIT_A_FRIEND_BONUS_PLAYER_LEVEL))
8003 return false;
8004 break;
8005 default: // normal case
8006 {
8007 uint32 losChecks = LINEOFSIGHT_ALL_CHECKS;
8008 GameObject* gobCaster = nullptr;
8010 {
8012 }
8013 else if (m_caster->GetEntry() == WORLD_TRIGGER)
8014 {
8015 if (TempSummon* tempSummon = m_caster->ToTempSummon())
8016 {
8017 gobCaster = tempSummon->GetSummonerGameObject();
8018 }
8019 }
8020
8021 if (gobCaster)
8022 {
8023 if (gobCaster->GetGOInfo()->IsIgnoringLOSChecks())
8024 {
8025 return true;
8026 }
8027
8028 // If spell casted by gameobject then ignore M2 models
8029 losChecks &= ~LINEOFSIGHT_CHECK_GOBJECT_M2;
8030 }
8031
8032 if (target != m_caster)
8033 {
8034 if (m_targets.HasDst())
8035 {
8036 float x = m_targets.GetDstPos()->GetPositionX();
8037 float y = m_targets.GetDstPos()->GetPositionY();
8038 float z = m_targets.GetDstPos()->GetPositionZ();
8039
8040 if (!target->IsWithinLOS(x, y, z, VMAP::ModelIgnoreFlags::M2, LineOfSightChecks(losChecks)))
8041 {
8042 return false;
8043 }
8044 }
8046 {
8047 return false;
8048 }
8049 }
8050 break;
8051 }
8052 }
8053
8054 return true;
8055}
@ SPELL_DISABLE_LOS
Definition: DisableMgr.h:50
@ DISABLE_TYPE_SPELL
Definition: DisableMgr.h:29
@ CONFIG_MAX_RECRUIT_A_FRIEND_BONUS_PLAYER_LEVEL
Definition: IWorld.h:251
@ CORPSE_FLAG_LOOTABLE
Definition: Corpse.h:45
@ UNIT_FLAG_NOT_SELECTABLE
Definition: UnitDefines.h:254
@ CORPSE_FIELD_FLAGS
Definition: UpdateFields.h:427
@ TARGET_CHECK_ENTRY
Definition: SpellInfo.h:115
@ SPELL_EFFECT_SKIN_PLAYER_CORPSE
Definition: SharedDefines.h:894
#define sWorld
Definition: World.h:444
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:182
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:527
ObjectGuid GetCorpseTargetGUID() const
Definition: Spell.cpp:282

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

Referenced by AddUnitTarget().

◆ CheckItems()

SpellCastResult Spell::CheckItems ( )
Todo:
Needs review
Todo:
: Not sure whether the fallthrough was a mistake (forgetting a break) or intended. This should be double-checked.
7171{
7172 Player* player = m_caster->ToPlayer();
7173 if (!player)
7174 {
7175 // Non-player case: Check if creature is disarmed
7177 {
7179 }
7180
7181 return SPELL_CAST_OK;
7182 }
7183
7184 if (!m_CastItem)
7185 {
7186 if (m_castItemGUID)
7188 }
7189 else
7190 {
7191 uint32 itemid = m_CastItem->GetEntry();
7192 if (!player->HasItemCount(itemid))
7194
7195 ItemTemplate const* proto = m_CastItem->GetTemplate();
7196 if (!proto)
7198
7199 for (int i = 0; i < MAX_ITEM_SPELLS; ++i)
7200 if (proto->Spells[i].SpellCharges)
7201 if (m_CastItem->GetSpellCharges(i) == 0)
7203
7204 // consumable cast item checks
7206 {
7207 // such items should only fail if there is no suitable effect at all - see Rejuvenation Potions for example
7208 SpellCastResult failReason = SPELL_CAST_OK;
7209 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; i++)
7210 {
7211 // skip check, pet not required like checks, and for TARGET_UNIT_PET m_targets.GetUnitTarget() is not the real target but the caster
7212 if (m_spellInfo->Effects[i].TargetA.GetTarget() == TARGET_UNIT_PET)
7213 continue;
7214
7215 if (m_spellInfo->Effects[i].Effect == SPELL_EFFECT_HEAL)
7216 {
7218 {
7220 continue;
7221 }
7222 else
7223 {
7224 failReason = SPELL_CAST_OK;
7225 break;
7226 }
7227 }
7228
7229 // Mana Potion, Rage Potion, Thistle Tea(Rogue), ...
7230 if (m_spellInfo->Effects[i].Effect == SPELL_EFFECT_ENERGIZE)
7231 {
7232 if (m_spellInfo->Effects[i].MiscValue < 0 || m_spellInfo->Effects[i].MiscValue >= int8(MAX_POWERS))
7233 {
7235 continue;
7236 }
7237
7238 Powers power = Powers(m_spellInfo->Effects[i].MiscValue);
7240 {
7242 continue;
7243 }
7244 else
7245 {
7246 failReason = SPELL_CAST_OK;
7247 break;
7248 }
7249 }
7250 }
7251 if (failReason != SPELL_CAST_OK)
7252 return failReason;
7253 }
7254 }
7255
7256 // check target item
7258 {
7259 if (!m_caster->IsPlayer())
7261
7262 if (!m_targets.GetItemTarget())
7264
7267 }
7268 // if not item target then required item must be equipped
7269 else
7270 {
7271 // Xinef: this is not true in my opinion, in eg bladestorm will not be canceled after disarm
7272 //if (!HasTriggeredCastFlag(TRIGGERED_IGNORE_EQUIPPED_ITEM_REQUIREMENT))
7275 }
7276
7277 // do not take reagents for these item casts
7279 {
7281 // Not own traded item (in trader trade slot) requires reagents even if triggered spell
7282 if (!checkReagents)
7283 if (Item* targetItem = m_targets.GetItemTarget())
7284 if (targetItem->GetOwnerGUID() != m_caster->GetGUID())
7285 checkReagents = true;
7286
7287 // check reagents (ignore triggered spells with reagents processed by original spell) and special reagent ignore case.
7288 if (checkReagents)
7289 {
7290 for (uint32 i = 0; i < MAX_SPELL_REAGENTS; i++)
7291 {
7292 if (m_spellInfo->Reagent[i] <= 0)
7293 continue;
7294
7295 uint32 itemid = m_spellInfo->Reagent[i];
7296 uint32 itemcount = m_spellInfo->ReagentCount[i];
7297
7298 // if CastItem is also spell reagent
7299 if (m_CastItem && m_CastItem->GetEntry() == itemid)
7300 {
7301 ItemTemplate const* proto = m_CastItem->GetTemplate();
7302 if (!proto)
7304 for (int s = 0; s < MAX_ITEM_PROTO_SPELLS; ++s)
7305 {
7306 // CastItem will be used up and does not count as reagent
7307 int32 charges = m_CastItem->GetSpellCharges(s);
7308 if (proto->Spells[s].SpellCharges < 0 && std::abs(charges) < 2)
7309 {
7310 ++itemcount;
7311 break;
7312 }
7313 }
7314 }
7315 if (!player->HasItemCount(itemid, itemcount))
7316 return SPELL_FAILED_REAGENTS;
7317 }
7318 }
7319
7320 // check totem-item requirements (items presence in inventory)
7321 uint32 totems = 2;
7322 for (int i = 0; i < 2; ++i)
7323 {
7324 if (m_spellInfo->Totem[i] != 0)
7325 {
7326 if (player->HasItemCount(m_spellInfo->Totem[i]))
7327 {
7328 totems -= 1;
7329 continue;
7330 }
7331 }
7332 else
7333 totems -= 1;
7334 }
7335 if (totems != 0)
7336 return SPELL_FAILED_TOTEMS; //0x7C
7337
7338 // Check items for TotemCategory (items presence in inventory)
7340 for (int i = 0; i < 2; ++i)
7341 {
7342 if (m_spellInfo->TotemCategory[i] != 0)
7343 {
7345 {
7346 TotemCategory -= 1;
7347 continue;
7348 }
7349 }
7350 else
7351 TotemCategory -= 1;
7352 }
7353 if (TotemCategory != 0)
7354 return SPELL_FAILED_TOTEM_CATEGORY; //0x7B
7355 }
7356
7357 // special checks for spell effects
7358 for (int i = 0; i < MAX_SPELL_EFFECTS; i++)
7359 {
7360 switch (m_spellInfo->Effects[i].Effect)
7361 {
7364 {
7365 // m_targets.GetUnitTarget() means explicit cast, otherwise we dont check for possible equip error
7366 Unit* target = m_targets.GetUnitTarget() ? m_targets.GetUnitTarget() : player;
7367 if (target->IsPlayer() && !IsTriggered())
7368 {
7369 // 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,
7370 // so we need to make sure there is at least one free space in the player's inventory
7372 if (target->ToPlayer()->GetFreeInventorySpace() == 0)
7373 {
7374 player->SendEquipError(EQUIP_ERR_INVENTORY_FULL, nullptr, nullptr, m_spellInfo->Effects[i].ItemType);
7376 }
7377
7378 if (m_spellInfo->Effects[i].ItemType)
7379 {
7380 ItemTemplate const* itemTemplate = sObjectMgr->GetItemTemplate(m_spellInfo->Effects[i].ItemType);
7381 if (!itemTemplate)
7383
7384 uint32 createCount = std::clamp<uint32>(m_spellInfo->Effects[i].CalcValue(), 1u, itemTemplate->GetMaxStackSize());
7385 ItemPosCountVec dest;
7386 InventoryResult msg = target->ToPlayer()->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, m_spellInfo->Effects[i].ItemType, createCount);
7387 if (msg != EQUIP_ERR_OK)
7388 {
7390 if (!itemTemplate->ItemLimitCategory)
7391 {
7392 player->SendEquipError(msg, nullptr, nullptr, m_spellInfo->Effects[i].ItemType);
7394 }
7395 else
7396 {
7397 // Conjure Food/Water/Refreshment spells
7400 else if (!(target->ToPlayer()->HasItemCount(m_spellInfo->Effects[i].ItemType)))
7401 {
7402 player->SendEquipError(msg, nullptr, nullptr, m_spellInfo->Effects[i].ItemType);
7404 }
7405 else
7406 player->CastSpell(player, m_spellInfo->Effects[EFFECT_1].CalcValue(), false); // move this to anywhere
7407
7409 }
7410 }
7411 }
7412 }
7413 break;
7414 }
7416 {
7417 if (player->GetFreeInventorySpace() == 0)
7418 {
7419 player->SendEquipError(EQUIP_ERR_INVENTORY_FULL, nullptr, nullptr, m_spellInfo->Effects[i].ItemType);
7421 }
7422 break;
7423 }
7425 if (m_spellInfo->Effects[i].ItemType && m_targets.GetItemTarget()
7427 {
7428 // cannot enchant vellum for other player
7431 // do not allow to enchant vellum from scroll made by vellum-prevent exploit
7434 ItemPosCountVec dest;
7435 InventoryResult msg = player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, m_spellInfo->Effects[i].ItemType, 1);
7436 if (msg != EQUIP_ERR_OK)
7437 {
7438 player->SendEquipError(msg, nullptr, nullptr, m_spellInfo->Effects[i].ItemType);
7440 }
7441 }
7442 [[fallthrough]];
7444 {
7445 Item* targetItem = m_targets.GetItemTarget();
7446 if (!targetItem)
7448
7449 // xinef: required level has to be checked also! Exploit fix
7450 if (targetItem->GetTemplate()->ItemLevel < m_spellInfo->BaseLevel || (targetItem->GetTemplate()->RequiredLevel && targetItem->GetTemplate()->RequiredLevel < m_spellInfo->BaseLevel))
7451 return SPELL_FAILED_LOWLEVEL;
7452
7453 bool isItemUsable = false;
7454 for (uint8 e = 0; e < MAX_ITEM_PROTO_SPELLS; ++e)
7455 {
7456 ItemTemplate const* proto = targetItem->GetTemplate();
7457 if (proto->Spells[e].SpellId && (
7460 {
7461 isItemUsable = true;
7462 break;
7463 }
7464 }
7465
7466 SpellItemEnchantmentEntry const* enchantEntry = sSpellItemEnchantmentStore.LookupEntry(m_spellInfo->Effects[i].MiscValue);
7467 // do not allow adding usable enchantments to items that have use effect already
7468 if (enchantEntry)
7469 {
7470 for (uint8 s = 0; s < MAX_SPELL_ITEM_ENCHANTMENT_EFFECTS; ++s)
7471 {
7472 switch (enchantEntry->type[s])
7473 {
7475 if (isItemUsable)
7477 break;
7479 {
7480 uint32 numSockets = 0;
7481 for (uint32 socket = 0; socket < MAX_ITEM_PROTO_SOCKETS; ++socket)
7482 if (targetItem->GetTemplate()->Socket[socket].Color)
7483 ++numSockets;
7484
7485 if (numSockets == MAX_ITEM_PROTO_SOCKETS || targetItem->GetEnchantmentId(PRISMATIC_ENCHANTMENT_SLOT))
7487 break;
7488 }
7489 }
7490 }
7491 }
7492
7493 // Not allow enchant in trade slot for some enchant type
7494 if (targetItem->GetOwner() != m_caster)
7495 {
7496 if (!enchantEntry)
7497 return SPELL_FAILED_ERROR;
7498 if (enchantEntry->slot & ENCHANTMENT_CAN_SOULBOUND)
7500 }
7501 break;
7502 }
7504 {
7505 Item* item = m_targets.GetItemTarget();
7506 if (!item)
7508 // Not allow enchant in trade slot for some enchant type
7509 if (item->GetOwner() != m_caster)
7510 {
7511 uint32 enchant_id = m_spellInfo->Effects[i].MiscValue;
7512 SpellItemEnchantmentEntry const* pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id);
7513 if (!pEnchant)
7514 return SPELL_FAILED_ERROR;
7515 if (pEnchant->slot & ENCHANTMENT_CAN_SOULBOUND)
7517 }
7518
7519 // Xinef: Apply item level restriction if the enchanting spell has max level restrition set
7520 if (m_CastItem && m_spellInfo->MaxLevel > 0)
7521 {
7523 return SPELL_FAILED_LOWLEVEL;
7524 if (item->GetTemplate()->ItemLevel > m_spellInfo->MaxLevel)
7526 }
7527
7528 break;
7529 }
7531 // check item existence in effect code (not output errors at offhand hold item effect to main hand for example
7532 break;
7534 {
7535 if (!m_targets.GetItemTarget())
7537
7538 // prevent disenchanting in trade slot
7541
7542 ItemTemplate const* itemProto = m_targets.GetItemTarget()->GetTemplate();
7543 if (!itemProto)
7545
7546 uint32 item_quality = itemProto->Quality;
7547 // 2.0.x addon: Check player enchanting level against the item disenchanting requirements
7548 uint32 item_disenchantskilllevel = itemProto->RequiredDisenchantSkill;
7549 if (item_disenchantskilllevel == uint32(-1))
7551 if (item_disenchantskilllevel > player->GetSkillValue(SKILL_ENCHANTING))
7553 if (item_quality > 4 || item_quality < 2)
7555 if (itemProto->Class != ITEM_CLASS_WEAPON && itemProto->Class != ITEM_CLASS_ARMOR)
7557 if (!itemProto->DisenchantID)
7559 break;
7560 }
7562 {
7563 if (!m_targets.GetItemTarget())
7565 //ensure item is a prospectable ore
7568 //prevent prospecting in trade slot
7571 //Check for enough skill in jewelcrafting
7572 uint32 item_prospectingskilllevel = m_targets.GetItemTarget()->GetTemplate()->RequiredSkillRank;
7573 if (item_prospectingskilllevel > player->GetSkillValue(SKILL_JEWELCRAFTING))
7575 //make sure the player has the required ores in inventory
7576 if (m_targets.GetItemTarget()->GetCount() < 5)
7578
7581
7582 break;
7583 }
7585 {
7586 if (!m_targets.GetItemTarget())
7588 //ensure item is a millable herb
7591 //prevent milling in trade slot
7594 //Check for enough skill in inscription
7595 uint32 item_millingskilllevel = m_targets.GetItemTarget()->GetTemplate()->RequiredSkillRank;
7596 if (item_millingskilllevel > player->GetSkillValue(SKILL_INSCRIPTION))
7598 //make sure the player has the required herbs in inventory
7599 if (m_targets.GetItemTarget()->GetCount() < 5)
7601
7604
7605 break;
7606 }
7609 {
7610 if (!m_caster->IsPlayer())
7612
7614 break;
7615
7617 if (!pItem || pItem->IsBroken())
7619
7620 switch (pItem->GetTemplate()->SubClass)
7621 {
7623 {
7624 uint32 ammo = pItem->GetEntry();
7625 if (!m_caster->ToPlayer()->HasItemCount(ammo))
7626 return SPELL_FAILED_NO_AMMO;
7627 };
7628 break;
7632 {
7634 if (!ammo)
7635 {
7636 // Requires No Ammo
7637 if (m_caster->HasAura(46699))
7638 break; // skip other checks
7639
7640 return SPELL_FAILED_NO_AMMO;
7641 }
7642
7643 ItemTemplate const* ammoProto = sObjectMgr->GetItemTemplate(ammo);
7644 if (!ammoProto)
7645 return SPELL_FAILED_NO_AMMO;
7646
7647 if (ammoProto->Class != ITEM_CLASS_PROJECTILE)
7648 return SPELL_FAILED_NO_AMMO;
7649
7650 // check ammo ws. weapon compatibility
7651 switch (pItem->GetTemplate()->SubClass)
7652 {
7655 if (ammoProto->SubClass != ITEM_SUBCLASS_ARROW)
7656 return SPELL_FAILED_NO_AMMO;
7657 break;
7659 if (ammoProto->SubClass != ITEM_SUBCLASS_BULLET)
7660 return SPELL_FAILED_NO_AMMO;
7661 break;
7662 default:
7663 return SPELL_FAILED_NO_AMMO;
7664 }
7665
7666 if (!m_caster->ToPlayer()->HasItemCount(ammo))
7667 {
7669 return SPELL_FAILED_NO_AMMO;
7670 }
7671 };
7672 break;
7674 break;
7675 default:
7676 break;
7677 }
7678 break;
7679 }
7681 {
7682 uint32 item_id = m_spellInfo->Effects[i].ItemType;
7683 ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(item_id);
7684
7685 if (!pProto)
7687
7688 if (Item* pitem = player->GetItemByEntry(item_id))
7689 {
7690 for (int x = 0; x < MAX_ITEM_PROTO_SPELLS; ++x)
7691 if (pProto->Spells[x].SpellCharges != 0 && pitem->GetSpellCharges(x) == pProto->Spells[x].SpellCharges)
7693 }
7694 break;
7695 }
7696 default:
7697 break;
7698 }
7699 }
7700
7701 // check weapon presence in slots for main/offhand weapons
7702 if (/*never skip those checks !HasTriggeredCastFlag(TRIGGERED_IGNORE_EQUIPPED_ITEM_REQUIREMENT) &&*/ m_spellInfo->EquippedItemClass >= 0)
7703 {
7704 // main hand weapon required
7706 {
7708
7709 // skip spell if no weapon in slot or broken
7710 if (!item || item->IsBroken())
7712
7713 // skip spell if weapon not fit to triggered spell
7716 }
7717
7718 // offhand hand weapon required
7720 {
7722
7723 // skip spell if no weapon in slot or broken
7724 if (!item || item->IsBroken())
7726
7727 // skip spell if weapon not fit to triggered spell
7730 }
7731
7733 }
7734
7735 return SPELL_CAST_OK;
7736}
std::int8_t int8
Definition: Define.h:105
LootStore LootTemplates_Milling("milling_loot_template", "item entry (herb)", true)
LootStore LootTemplates_Prospecting("prospecting_loot_template", "item entry (ore)", true)
DBCStorage< SpellItemEnchantmentEntry > sSpellItemEnchantmentStore(SpellItemEnchantmentfmt)
@ PLAYER_AMMO_ID
Definition: UpdateFields.h:369
std::vector< ItemPosCount > ItemPosCountVec
Definition: Player.h:771
@ ITEM_SUBCLASS_WEAPON_CROSSBOW
Definition: ItemTemplate.h:362
@ ITEM_SUBCLASS_WEAPON_GUN
Definition: ItemTemplate.h:347
@ ITEM_SUBCLASS_WEAPON_BOW
Definition: ItemTemplate.h:346
@ ITEM_SUBCLASS_WEAPON_WAND
Definition: ItemTemplate.h:363
@ ITEM_SUBCLASS_WEAPON_THROWN
Definition: ItemTemplate.h:360
@ ITEM_SPELLTRIGGER_ON_USE
Definition: ItemTemplate.h:77
@ ITEM_SPELLTRIGGER_ON_NO_DELAY_USE
Definition: ItemTemplate.h:87
@ ITEM_FLAG_IS_MILLABLE
Definition: ItemTemplate.h:176
@ ITEM_FLAG_NO_REAGENT_COST
Definition: ItemTemplate.h:175
@ ITEM_FLAG_IS_PROSPECTABLE
Definition: ItemTemplate.h:165
@ ITEM_SUBCLASS_ARROW
Definition: ItemTemplate.h:416
@ ITEM_SUBCLASS_BULLET
Definition: ItemTemplate.h:417
#define MAX_ITEM_PROTO_SOCKETS
Definition: ItemTemplate.h:614
#define MAX_ITEM_PROTO_SPELLS
Definition: ItemTemplate.h:615
@ ITEM_CLASS_PROJECTILE
Definition: ItemTemplate.h:297
@ ITEM_CLASS_ARMOR
Definition: ItemTemplate.h:295
@ ITEM_CLASS_WEAPON
Definition: ItemTemplate.h:293
@ ITEM_CLASS_CONSUMABLE
Definition: ItemTemplate.h:291
InventoryResult
Definition: Item.h:46
@ EQUIP_ERR_OK
Definition: Item.h:47
@ EQUIP_ERR_INVENTORY_FULL
Definition: Item.h:97
#define MAX_ITEM_SPELLS
Definition: Item.h:215
@ ENCHANTMENT_CAN_SOULBOUND
Definition: Item.h:201
@ NULL_BAG
Definition: Item.h:40
@ NULL_SLOT
Definition: Item.h:41
@ PRISMATIC_ENCHANTMENT_SLOT
Definition: Item.h:175
@ EFFECT_1
Definition: SharedDefines.h:32
@ MAX_POWERS
Definition: SharedDefines.h:276
@ SPELL_EFFECT_DISENCHANT
Definition: SharedDefines.h:877
@ SPELL_EFFECT_PROSPECTING
Definition: SharedDefines.h:905
@ SPELL_EFFECT_ENCHANT_HELD_ITEM
Definition: SharedDefines.h:870
@ SPELL_EFFECT_ENCHANT_ITEM
Definition: SharedDefines.h:831
@ SPELL_EFFECT_WEAPON_DAMAGE
Definition: SharedDefines.h:836
@ SPELL_EFFECT_HEAL
Definition: SharedDefines.h:788
@ SPELL_EFFECT_MILLING
Definition: SharedDefines.h:936
@ SPELL_EFFECT_CREATE_MANA_GEM
Definition: SharedDefines.h:844
@ SPELL_EFFECT_CREATE_ITEM_2
Definition: SharedDefines.h:935
@ SPELL_EFFECT_WEAPON_DAMAGE_NOSCHOOL
Definition: SharedDefines.h:795
@ SPELL_EFFECT_ENERGIZE
Definition: SharedDefines.h:808
@ SPELL_EFFECT_CREATE_RANDOM_ITEM
Definition: SharedDefines.h:837
@ SPELL_EFFECT_ENCHANT_ITEM_PRISMATIC
Definition: SharedDefines.h:934
@ SPELL_EFFECT_ENCHANT_ITEM_TEMPORARY
Definition: SharedDefines.h:832
@ SPELL_EFFECT_CREATE_ITEM
Definition: SharedDefines.h:802
@ SPELL_ATTR3_REQUIRES_MAIN_HAND_WEAPON
Definition: SharedDefines.h:503
@ SPELLFAMILY_MAGE
Definition: SharedDefines.h:3531
TotemCategory
Definition: SharedDefines.h:3083
@ SPELL_FAILED_CANT_BE_MILLED
Definition: SharedDefines.h:965
@ SPELL_FAILED_EQUIPPED_ITEM_CLASS_OFFHAND
Definition: SharedDefines.h:980
@ SPELL_FAILED_EQUIPPED_ITEM_CLASS
Definition: SharedDefines.h:978
@ SPELL_FAILED_ITEM_AT_MAX_CHARGES
Definition: SharedDefines.h:1128
@ SPELL_FAILED_TARGET_NOT_PLAYER
Definition: SharedDefines.h:1071
@ SPELL_FAILED_ALREADY_AT_FULL_POWER
Definition: SharedDefines.h:953
@ SPELL_FAILED_NOT_TRADEABLE
Definition: SharedDefines.h:1019
@ SPELL_FAILED_ITEM_NOT_READY
Definition: SharedDefines.h:994
@ SPELL_FAILED_NO_CHARGES_REMAIN
Definition: SharedDefines.h:1025
@ SPELL_FAILED_ITEM_GONE
Definition: SharedDefines.h:992
@ SPELL_FAILED_NO_AMMO
Definition: SharedDefines.h:1024
@ SPELL_FAILED_ITEM_NOT_FOUND
Definition: SharedDefines.h:993
@ SPELL_FAILED_EQUIPPED_ITEM
Definition: SharedDefines.h:977
@ SPELL_FAILED_ALREADY_AT_FULL_HEALTH
Definition: SharedDefines.h:951
@ SPELL_FAILED_ON_USE_ENCHANT
Definition: SharedDefines.h:1119
@ SPELL_FAILED_TOTEMS
Definition: SharedDefines.h:1080
@ SPELL_FAILED_ERROR
Definition: SharedDefines.h:981
@ SPELL_FAILED_REAGENTS
Definition: SharedDefines.h:1049
@ SPELL_FAILED_MAX_SOCKETS
Definition: SharedDefines.h:1133
@ SPELL_FAILED_CANT_BE_DISENCHANTED
Definition: SharedDefines.h:963
@ SPELL_FAILED_TOO_MANY_OF_ITEM
Definition: SharedDefines.h:1078
@ SPELL_FAILED_NEED_MORE_ITEMS
Definition: SharedDefines.h:1004
@ SPELL_FAILED_CANT_BE_PROSPECTED
Definition: SharedDefines.h:966
@ SPELL_FAILED_EQUIPPED_ITEM_CLASS_MAINHAND
Definition: SharedDefines.h:979
@ SPELL_FAILED_TOTEM_CATEGORY
Definition: SharedDefines.h:1079
@ SKILL_INSCRIPTION
Definition: SharedDefines.h:3002
@ SKILL_ENCHANTING
Definition: SharedDefines.h:2954
@ SKILL_JEWELCRAFTING
Definition: SharedDefines.h:2985
#define MAX_SPELL_REAGENTS
Definition: DBCStructure.h:1639
#define MAX_SPELL_ITEM_ENCHANTMENT_EFFECTS
Definition: DBCStructure.h:1838
@ ITEM_ENCHANTMENT_TYPE_USE_SPELL
Definition: DBCEnums.h:373
@ ITEM_ENCHANTMENT_TYPE_PRISMATIC_SOCKET
Definition: DBCEnums.h:374
uint32 GetEnchantmentId(EnchantmentSlot slot) const
Definition: Item.h:304
int32 GetSpellCharges(uint8 index=0) const
Definition: Item.h:317
bool IsBroken() const
Definition: Item.h:257
bool IsWeaponVellum() const
Definition: Item.h:338
bool IsArmorVellum() const
Definition: Item.h:339
Player * GetOwner() const
Definition: Item.cpp:550
ObjectGuid GetOwnerGUID() const
Definition: Item.h:231
uint32 GetCount() const
Definition: Item.h:272
bool IsFitToSpellRequirements(SpellInfo const *spellInfo) const
Definition: Item.cpp:885
int32 SpellCharges
Definition: ItemTemplate.h:593
uint32 SpellTrigger
Definition: ItemTemplate.h:592
int32 SpellId
Definition: ItemTemplate.h:591
uint32 Color
Definition: ItemTemplate.h:602
Definition: ItemTemplate.h:619
uint32 DisenchantID
Definition: ItemTemplate.h:690
uint32 Quality
Definition: ItemTemplate.h:626
uint32 RequiredSkillRank
Definition: ItemTemplate.h:638
uint32 GetMaxStackSize() const
Definition: ItemTemplate.h:729
_Spell Spells[MAX_ITEM_PROTO_SPELLS]
Definition: ItemTemplate.h:662
uint32 RequiredDisenchantSkill
Definition: ItemTemplate.h:684
uint32 RequiredLevel
Definition: ItemTemplate.h:636
bool HasFlag(ItemFlags flag) const
Definition: ItemTemplate.h:827
uint32 Class
Definition: ItemTemplate.h:621
uint32 ItemLimitCategory
Definition: ItemTemplate.h:687
uint32 SubClass
Definition: ItemTemplate.h:622
_Socket Socket[MAX_ITEM_PROTO_SOCKETS]
Definition: ItemTemplate.h:681
uint32 GetUInt32Value(uint16 index) const
Definition: Object.cpp:305
bool HasItemFitToSpellRequirements(SpellInfo const *spellInfo, Item const *ignoreItem=nullptr) const
Definition: Player.cpp:12514
uint32 GetFreeInventorySpace() const
Definition: PlayerStorage.cpp:472
Item * GetItemByEntry(uint32 entry) const
Definition: PlayerStorage.cpp:3375
bool HasItemCount(uint32 item, uint32 count=1, bool inBankAlso=false) const
Definition: PlayerStorage.cpp:661
bool HasItemTotemCategory(uint32 TotemCategory) const
Definition: PlayerStorage.cpp:857
bool CanNoReagentCast(SpellInfo const *spellInfo) const
Definition: Player.cpp:12559
void SendEquipError(InventoryResult msg, Item *pItem, Item *pItem2=nullptr, uint32 itemid=0)
Definition: PlayerStorage.cpp:4027
InventoryResult CanStoreNewItem(uint8 bag, uint8 slot, ItemPosCountVec &dest, uint32 item, uint32 count, uint32 *no_space_count=nullptr) const
Definition: Player.h:1272
bool CanUseAttackType(uint8 attacktype) const
Definition: Unit.h:1055
bool IsFullHealth() const
Definition: Unit.h:872
uint32 GetMaxPower(Powers power) const
Definition: Unit.h:892
void SetUInt32Value(uint16 index, uint32 value)
Definition: Unit.cpp:21256
uint32 GetPower(Powers power) const
Definition: Unit.h:891
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:359
uint32 MaxLevel
Definition: SpellInfo.h:358
std::array< int32, MAX_SPELL_REAGENTS > Reagent
Definition: SpellInfo.h:373
flag96 SpellFamilyFlags
Definition: SpellInfo.h:388
std::array< uint32, 2 > TotemCategory
Definition: SpellInfo.h:378
int32 EquippedItemClass
Definition: SpellInfo.h:375
std::array< uint32, 2 > Totem
Definition: SpellInfo.h:372
std::array< uint32, MAX_SPELL_REAGENTS > ReagentCount
Definition: SpellInfo.h:374
Definition: DBCStructure.h:1841
uint32 type[MAX_SPELL_ITEM_ENCHANTMENT_EFFECTS]
Definition: DBCStructure.h:1844
uint32 slot
Definition: DBCStructure.h:1851

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

Referenced by CheckCast().

◆ CheckPetCast()

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

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

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

◆ CheckPower()

SpellCastResult Spell::CheckPower ( )
7126{
7127 // item cast not used power
7128 if (m_CastItem)
7129 return SPELL_CAST_OK;
7130
7131 //While .cheat power is enabled dont check if we need power to cast the spell
7132 if (m_caster->IsPlayer())
7133 {
7135 {
7136 return SPELL_CAST_OK;
7137 }
7138 }
7139
7140 // health as power used - need check health amount
7142 {
7145 return SPELL_CAST_OK;
7146 }
7147 // Check valid power type
7149 {
7150 LOG_ERROR("spells", "Spell::CheckPower: Unknown power type '{}'", m_spellInfo->PowerType);
7151 return SPELL_FAILED_UNKNOWN;
7152 }
7153
7154 //check rune cost only if a spell has PowerType == POWER_RUNE
7156 {
7158 if (failReason != SPELL_CAST_OK)
7159 return failReason;
7160 }
7161
7162 // Check power amount
7165 return SPELL_FAILED_NO_POWER;
7166 else
7167 return SPELL_CAST_OK;
7168}
PowerType
Definition: VehicleDefines.h:29
@ CHEAT_POWER
Definition: Player.h:1002
@ POWER_HEALTH
Definition: SharedDefines.h:278
@ POWER_RUNE
Definition: SharedDefines.h:274
@ SPELL_FAILED_NO_POWER
Definition: SharedDefines.h:1034
@ SPELL_FAILED_UNKNOWN
Definition: SharedDefines.h:1136
uint32 GetHealth() const
Definition: Unit.h:869
SpellCastResult CheckRuneCost(uint32 RuneCostID)
Definition: Spell.cpp:5400
uint32 RuneCostID
Definition: SpellInfo.h:368
uint32 PowerType
Definition: SpellInfo.h:362

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

Referenced by CheckCast().

◆ CheckRange()

SpellCastResult Spell::CheckRange ( bool  strict)
7040{
7041 // Don't check for instant cast spells
7042 if (!strict && m_casttime == 0)
7043 return SPELL_CAST_OK;
7044
7045 uint32 range_type = 0;
7046
7048 {
7049 // check needed by 68766 51693 - both spells are cast on enemies and have 0 max range
7050 // these are triggered by other spells - possibly we should omit range check in that case?
7051 if (m_spellInfo->RangeEntry->ID == 1)
7052 return SPELL_CAST_OK;
7053
7054 range_type = m_spellInfo->RangeEntry->Flags;
7055 }
7056
7057 Unit* target = m_targets.GetUnitTarget();
7058 float max_range = m_caster->GetSpellMaxRangeForTarget(target, m_spellInfo);
7059 float min_range = m_caster->GetSpellMinRangeForTarget(target, m_spellInfo);
7060
7061 // xinef: hack for npc shooters
7062 if (min_range && GetCaster()->IsCreature() && !GetCaster()->GetOwnerGUID().IsPlayer() && min_range <= 6.0f)
7063 range_type = SPELL_RANGE_RANGED;
7064
7065 if (Player* modOwner = m_caster->GetSpellModOwner())
7066 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_RANGE, max_range, this);
7067
7068 // xinef: dont check max_range to strictly after cast
7069 if (range_type != SPELL_RANGE_MELEE && !strict)
7070 max_range += std::min(3.0f, max_range * 0.1f); // 10% but no more than 3yd
7071
7072 if (target)
7073 {
7074 if (target != m_caster)
7075 {
7076 // Xinef: Spells with 5yd range can hit target 9yd away?
7077 if (range_type == SPELL_RANGE_MELEE)
7078 {
7079 float real_max_range = max_range;
7080 if (!m_caster->IsCreature() && m_caster->isMoving() && target->isMoving() && !m_caster->IsWalking() && !target->IsWalking())
7081 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)
7082 else
7083 real_max_range -= 2 * MIN_MELEE_REACH;
7084
7085 if (!m_caster->IsWithinMeleeRange(target, std::max(real_max_range, 0.0f)))
7087 }
7088 else if (!m_caster->IsWithinCombatRange(target, max_range))
7089 return SPELL_FAILED_OUT_OF_RANGE; //0x5A;
7090
7092 {
7093 if (m_caster->IsWithinMeleeRange(target))
7095 }
7096
7097 if (m_caster->IsPlayer() && (m_spellInfo->FacingCasterFlags & SPELL_FACING_FLAG_INFRONT) && !m_caster->HasInArc(static_cast<float>(M_PI), target))
7099 }
7100
7101 // Xinef: check min range for self casts
7102 if (min_range && range_type != SPELL_RANGE_RANGED && m_caster->IsWithinCombatRange(target, min_range)) // skip this check if min_range = 0
7104 }
7105
7106 if (GameObject* goTarget = m_targets.GetGOTarget())
7107 {
7108 if (!goTarget->IsAtInteractDistance(m_caster->ToPlayer(), m_spellInfo))
7109 {
7111 }
7112 }
7113
7114 if (m_targets.HasDst() && !m_targets.HasTraj())
7115 {
7116 if (!m_caster->IsWithinDist3d(m_targets.GetDstPos(), max_range))
7118 if (min_range && m_caster->IsWithinDist3d(m_targets.GetDstPos(), min_range))
7120 }
7121
7122 return SPELL_CAST_OK;
7123}
#define MIN_MELEE_REACH
Definition: ObjectDefines.h:47
@ SPELLMOD_RANGE
Definition: SpellDefines.h:82
@ SPELL_FACING_FLAG_INFRONT
Definition: SpellDefines.h:126
@ SPELL_RANGE_MELEE
Definition: Spell.h:89
@ SPELL_RANGE_RANGED
Definition: Spell.h:90
@ SPELL_FAILED_TOO_CLOSE
Definition: SharedDefines.h:1077
@ SPELL_FAILED_OUT_OF_RANGE
Definition: SharedDefines.h:1046
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:649
float GetSpellMinRangeForTarget(Unit const *target, SpellInfo const *spellInfo) const
Definition: Unit.cpp:15122
bool IsWithinMeleeRange(Unit const *obj, float dist=0.f) const
Definition: Unit.cpp:665
float GetSpellMaxRangeForTarget(Unit const *target, SpellInfo const *spellInfo) const
Definition: Unit.cpp:15102
bool IsWalking() const
Definition: Unit.h:1695
Unit * GetCaster() const
Definition: Spell.h:573
SpellRangeEntry const * RangeEntry
Definition: SpellInfo.h:369
uint32 FacingCasterFlags
Definition: SpellInfo.h:338
uint32 Flags
Definition: DBCStructure.h:1797
uint32 ID
Definition: DBCStructure.h:1794

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

Referenced by CheckCast().

◆ CheckRuneCost()

SpellCastResult Spell::CheckRuneCost ( uint32  RuneCostID)
5401{
5402 if (m_spellInfo->PowerType != POWER_RUNE || !RuneCostID)
5403 return SPELL_CAST_OK;
5404
5405 if (!m_caster->IsPlayer())
5406 return SPELL_CAST_OK;
5407
5408 Player* player = m_caster->ToPlayer();
5409 //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)
5410 if (player->GetCommandStatus(CHEAT_POWER))
5411 {
5412 return SPELL_CAST_OK;
5413 }
5414
5416 return SPELL_CAST_OK;
5417
5418 SpellRuneCostEntry const* src = sSpellRuneCostStore.LookupEntry(RuneCostID);
5419
5420 if (!src)
5421 return SPELL_CAST_OK;
5422
5423 if (src->NoRuneCost())
5424 return SPELL_CAST_OK;
5425
5426 int32 runeCost[NUM_RUNE_TYPES]; // blood, frost, unholy, death
5427
5428 for (uint32 i = 0; i < RUNE_DEATH; ++i)
5429 {
5430 runeCost[i] = src->RuneCost[i];
5431 if (Player* modOwner = m_caster->GetSpellModOwner())
5432 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_COST, runeCost[i], this);
5433 }
5434
5435 runeCost[RUNE_DEATH] = MAX_RUNES; // calculated later
5436
5437 for (uint32 i = 0; i < MAX_RUNES; ++i)
5438 {
5439 RuneType rune = player->GetCurrentRune(i);
5440 if ((player->GetRuneCooldown(i) == 0) && (runeCost[rune] > 0))
5441 runeCost[rune]--;
5442 }
5443
5444 for (uint32 i = 0; i < RUNE_DEATH; ++i)
5445 if (runeCost[i] > 0)
5446 runeCost[RUNE_DEATH] += runeCost[i];
5447
5448 if (runeCost[RUNE_DEATH] > MAX_RUNES)
5449 return SPELL_FAILED_NO_POWER; // not sure if result code is correct
5450
5451 return SPELL_CAST_OK;
5452}
DBCStorage< SpellRuneCostEntry > sSpellRuneCostStore(SpellRuneCostfmt)
@ CLASS_CONTEXT_ABILITY
Definition: UnitDefines.h:213
RuneType
Definition: Player.h:408
@ RUNE_DEATH
Definition: Player.h:412
@ NUM_RUNE_TYPES
Definition: Player.h:413
#define MAX_RUNES
Definition: Player.h:398
@ SPELLMOD_COST
Definition: SpellDefines.h:91
@ CLASS_DEATH_KNIGHT
Definition: SharedDefines.h:146
uint32 GetRuneCooldown(uint8 index) const
Definition: Player.h:2488
bool IsClass(Classes playerClass, ClassContext context=CLASS_CONTEXT_NONE) const override
Definition: Player.cpp:1280
RuneType GetCurrentRune(uint8 index) const
Definition: Player.h:2487
Definition: DBCStructure.h:1805
uint32 RuneCost[3]
Definition: DBCStructure.h:1807
bool NoRuneCost() const
Definition: DBCStructure.h:1810

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

Referenced by CheckPower().

◆ CheckScriptEffectImplicitTargets()

bool Spell::CheckScriptEffectImplicitTargets ( uint32  effIndex,
uint32  effIndexToCheck 
)
protected
8704{
8705 // Skip if there are not any script
8706 if (!m_loadedScripts.size())
8707 return true;
8708
8709 for (std::list<SpellScript*>::iterator itr = m_loadedScripts.begin(); itr != m_loadedScripts.end(); ++itr)
8710 {
8711 std::list<SpellScript::ObjectTargetSelectHandler>::iterator targetSelectHookEnd = (*itr)->OnObjectTargetSelect.end(), targetSelectHookItr = (*itr)->OnObjectTargetSelect.begin();
8712 for (; targetSelectHookItr != targetSelectHookEnd; ++targetSelectHookItr)
8713 if (((*targetSelectHookItr).IsEffectAffected(m_spellInfo, effIndex) && !(*targetSelectHookItr).IsEffectAffected(m_spellInfo, effIndexToCheck)) ||
8714 (!(*targetSelectHookItr).IsEffectAffected(m_spellInfo, effIndex) && (*targetSelectHookItr).IsEffectAffected(m_spellInfo, effIndexToCheck)))
8715 return false;
8716
8717 std::list<SpellScript::ObjectAreaTargetSelectHandler>::iterator areaTargetSelectHookEnd = (*itr)->OnObjectAreaTargetSelect.end(), areaTargetSelectHookItr = (*itr)->OnObjectAreaTargetSelect.begin();
8718 for (; areaTargetSelectHookItr != areaTargetSelectHookEnd; ++areaTargetSelectHookItr)
8719 if (((*areaTargetSelectHookItr).IsEffectAffected(m_spellInfo, effIndex) && !(*areaTargetSelectHookItr).IsEffectAffected(m_spellInfo, effIndexToCheck)) ||
8720 (!(*areaTargetSelectHookItr).IsEffectAffected(m_spellInfo, effIndex) && (*areaTargetSelectHookItr).IsEffectAffected(m_spellInfo, effIndexToCheck)))
8721 return false;
8722 }
8723 return true;
8724}

References m_loadedScripts, and m_spellInfo.

Referenced by SelectEffectImplicitTargets().

◆ CheckSpellFocus()

SpellCastResult Spell::CheckSpellFocus ( )
7739{
7740 // check spell focus object
7742 {
7744 Cell cell(p);
7745
7746 GameObject* ok = nullptr;
7749
7751 Map& map = *m_caster->GetMap();
7752 cell.Visit(p, object_checker, map, *m_caster, m_caster->GetVisibilityRange());
7753
7754 if (!ok)
7756
7757 focusObject = ok; // game object found in range
7758 }
7759 return SPELL_CAST_OK;
7760}
@ SPELL_FAILED_REQUIRES_SPELL_FOCUS
Definition: SharedDefines.h:1051
CellCoord ComputeCellCoord(float x, float y)
Definition: GridDefines.h:191
Definition: TypeContainer.h:101
Definition: TypeContainerVisitor.h:84
Definition: Cell.h:46
Definition: GridNotifiers.h:319
Definition: GridNotifiers.h:657
Definition: Map.h:313
void Visit(const Cell &cell, TypeContainerVisitor< T, CONTAINER > &visitor)
Definition: Map.h:873
uint32 RequiresSpellFocus
Definition: SpellInfo.h:337

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

Referenced by CheckCast().

◆ CheckSrc()

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

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

◆ CleanupTargetList()

void Spell::CleanupTargetList ( )
2373{
2374 m_UniqueTargetInfo.clear();
2375 m_UniqueGOTargetInfo.clear();
2376 m_UniqueItemInfo.clear();
2377 m_delayMoment = 0;
2379}
uint64 m_delayTrajectory
Definition: Spell.h:640

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 ( )
7763{
7764 if (!m_caster)// || !m_caster->IsPlayer())
7765 return;
7766
7767 //if (m_spellState == SPELL_STATE_DELAYED)
7768 // return; // spell is active and can't be time-backed
7769
7770 if (isDelayableNoMore()) // Spells may only be delayed twice
7771 return;
7772
7774 return;
7775
7776 // spells not loosing casting time (slam, dynamites, bombs..)
7777 //if (!(m_spellInfo->InterruptFlags & SPELL_INTERRUPT_FLAG_DAMAGE))
7778 // return;
7779
7780 //check pushback reduce
7781 int32 delaytime = 500; // spellcasting delay is normally 500ms
7782 int32 delayReduce = 100; // must be initialized to 100 for percent modifiers
7785 if (delayReduce >= 100)
7786 return;
7787
7788 AddPct(delaytime, -delayReduce);
7789
7790 if (m_timer + delaytime > m_casttime)
7791 {
7792 delaytime = m_casttime - m_timer;
7794 }
7795 else
7796 m_timer += delaytime;
7797
7798 LOG_DEBUG("spells", "Spell {} partially interrupted for ({}) ms at damage", m_spellInfo->Id, delaytime);
7799
7800 WorldPacket data(SMSG_SPELL_DELAYED, 8 + 4);
7801 data << m_caster->GetPackGUID();
7802 data << uint32(delaytime);
7803
7804 m_caster->SendMessageToSet(&data, true);
7805}
#define LOG_DEBUG(filterType__,...)
Definition: Log.h:168
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
@ SPELL_ATTR6_NO_PUSHBACK
Definition: SharedDefines.h:619
@ SMSG_SPELL_DELAYED
Definition: Opcodes.h:512
PackedGuid const & GetPackGUID() const
Definition: Object.h:111
virtual void SendMessageToSet(WorldPacket const *data, bool self) const
Definition: Object.cpp:2080
void ApplySpellMod(uint32 spellId, SpellModOp op, T &basevalue, Spell *spell=nullptr, bool temporaryPet=false)
Definition: Player.cpp:9729
int32 GetTotalAuraModifier(AuraType auratype) const
Definition: Unit.cpp:5881
Definition: WorldPacket.h:27
bool isDelayableNoMore()
Definition: Spell.h:628

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

◆ DelayedChannel()

void Spell::DelayedChannel ( )
7808{
7810 return;
7811
7812 if (isDelayableNoMore()) // Spells may only be delayed twice
7813 return;
7814
7816 return;
7817
7818 //check pushback reduce
7819 // should be affected by modifiers, not take the dbc duration.
7821
7822 int32 delaytime = CalculatePct(duration, 25); // channeling delay is normally 25% of its time per hit
7823 int32 delayReduce = 100; // must be initialized to 100 for percent modifiers
7826 if (delayReduce >= 100)
7827 return;
7828
7829 AddPct(delaytime, -delayReduce);
7830
7831 if (m_timer <= delaytime)
7832 {
7833 delaytime = m_timer;
7834 m_timer = 0;
7835 }
7836 else
7837 m_timer -= delaytime;
7838
7839 LOG_DEBUG("spells.aura", "Spell {} partially interrupted for {} ms, new duration: {} ms", m_spellInfo->Id, delaytime, m_timer);
7840
7841 for (std::list<TargetInfo>::const_iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
7842 if ((*ihit).missCondition == SPELL_MISS_NONE)
7843 if (Unit* unit = (m_caster->GetGUID() == ihit->targetGUID) ? m_caster : ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID))
7844 unit->DelayOwnedAuras(m_spellInfo->Id, m_originalCasterGUID, delaytime);
7845
7846 // partially interrupt persistent area auras
7848 dynObj->Delay(delaytime);
7849
7851}
T CalculatePct(T base, U pct)
Definition: Util.h:61
Definition: DynamicObject.h:35
DynamicObject * GetDynObject(uint32 spellId)
Definition: Unit.cpp:6099
uint32 getState() const
Definition: Spell.h:482
int32 GetDuration() const
Definition: SpellInfo.cpp:2337

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

◆ DoAllEffectOnLaunchTarget()

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

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

Referenced by HandleLaunchPhase().

◆ DoAllEffectOnTarget() [1/3]

void Spell::DoAllEffectOnTarget ( GOTargetInfo target)
protected
3335{
3336 if (target->processed) // Check target
3337 return;
3338 target->processed = true; // Target checked in apply effects procedure
3339
3340 uint32 effectMask = target->effectMask;
3341 if (!effectMask)
3342 return;
3343
3344 GameObject* go = m_caster->GetMap()->GetGameObject(target->targetGUID);
3345 if (!go)
3346 return;
3347
3350
3351 for (uint32 effectNumber = 0; effectNumber < MAX_SPELL_EFFECTS; ++effectNumber)
3352 if (effectMask & (1 << effectNumber))
3353 HandleEffects(nullptr, nullptr, go, effectNumber, SPELL_EFFECT_HANDLE_HIT_TARGET);
3354
3355 // xinef: inform ai about spellhit
3357
3359
3361}
virtual void SpellHit(Unit *, SpellInfo const *)
Definition: GameObjectAI.h:67
GameObjectAI * AI() const
Definition: GameObject.h:307
void CallScriptBeforeHitHandlers(SpellMissInfo missInfo)
Definition: Spell.cpp:8622
void CallScriptOnHitHandlers()
Definition: Spell.cpp:8635
void CallScriptAfterHitHandlers()
Definition: Spell.cpp:8648

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
3364{
3365 uint32 effectMask = target->effectMask;
3366 if (!target->item || !effectMask)
3367 return;
3368
3371
3372 for (uint32 effectNumber = 0; effectNumber < MAX_SPELL_EFFECTS; ++effectNumber)
3373 if (effectMask & (1 << effectNumber))
3374 HandleEffects(nullptr, target->item, nullptr, effectNumber, SPELL_EFFECT_HANDLE_HIT_TARGET);
3375
3377
3379}

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

References SpellNonMeleeDamage::absorb, Creature::AI(), TargetInfo::alive, UnitAI::AttackStart(), SpellInfo::AttributesEx3, AURA_INTERRUPT_FLAG_TALK, SpellNonMeleeDamage::blocked, Unit::CalculateSpellDamageTaken(), CallScriptAfterHitHandlers(), CallScriptBeforeHitHandlers(), CallScriptOnHitHandlers(), CanExecuteTriggersOnHit(), Unit::CanProc(), Player::CastItemCombatSpell(), Unit::CastSpell(), Unit::CombatStart(), createProcExtendMask(), TargetInfo::crit, SpellNonMeleeDamage::damage, TargetInfo::damage, Unit::DealDamageMods(), Unit::DealSpellDamage(), SpellInfo::DmgClass, DoSpellHitOnUnit(), DoTriggersOnSpellHit(), EFFECT_0, TriggeredByAuraSpellData::effectIndex, TargetInfo::effectMask, SpellInfo::Effects, WorldObject::FindMap(), ObjectAccessor::FindPlayer(), Object::GetEntry(), GameTime::GetGameTimeMS(), Object::GetGUID(), Unit::GetHealthGain(), Unit::getHostileRefMgr(), Unit::GetOwner(), Unit::GetOwnerGUID(), SpellInfo::GetSchoolMask(), GetSpellValue(), getState(), ObjectAccessor::GetUnit(), SpellCastTargets::GetUnitTargetGUID(), HandleEffects(), SpellInfo::HasAttribute(), SpellInfo::HasEffect(), HEAL, Unit::HealBySpell(), SpellNonMeleeDamage::HitInfo, SpellInfo::Id, Unit::IsAIEnabled, Unit::IsAlive(), SpellInfo::IsAuraEffectEqual(), Object::IsCreature(), Map::IsDungeon(), Unit::IsFriendlyTo(), Unit::IsInCombat(), Unit::IsInCombatWith(), Object::IsPlayer(), ObjectGuid::IsPlayer(), SpellInfo::IsPositive(), SpellInfo::IsPositiveEffect(), Unit::IsPvP(), Unit::IsStandState(), SpellInfo::IsTargetingArea(), Creature::LowerPlayerDamageReq(), m_attackType, m_caster, m_damage, m_healing, Unit::m_lastSanctuaryTime, m_needComboPoints, m_originalCaster, m_procAttacker, m_procEx, m_procVictim, m_spellAura, m_spellInfo, m_spellSchoolMask, m_targets, m_triggeredByAuraSpell, MAX_SPELL_EFFECTS, TargetInfo::missCondition, NODAMAGE, PrepareScriptHitHandlers(), PROC_EX_CRITICAL_HIT, PROC_EX_NO_OVERHEAL, PROC_EX_NORMAL_HIT, PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG, PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_POS, PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_NEG, PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_POS, PROC_FLAG_TAKEN_DAMAGE, PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_NEG, PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_POS, PROC_FLAG_TAKEN_SPELL_NONE_DMG_CLASS_NEG, PROC_FLAG_TAKEN_SPELL_NONE_DMG_CLASS_POS, Unit::ProcDamageAndSpell(), TargetInfo::processed, TargetInfo::reflectResult, Unit::RemoveAurasWithInterruptFlags(), Player::RestoreSpellMods(), TargetInfo::scaleAura, Unit::SendSpellMiss(), Unit::SendSpellNonMeleeDamageLog(), Unit::SendSpellNonMeleeReflectLog(), Unit::SetInCombatWith(), Unit::SetLastDamagedTargetGuid(), Unit::SetStandState(), SPELL_ATTR0_CANCELS_AUTO_ATTACK_COMBAT, SPELL_ATTR0_CU_NO_PVP_FLAG, SPELL_ATTR0_CU_PICKPOCKET, SPELL_ATTR1_NO_THREAT, SPELL_ATTR3_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(), 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 
)
1636{
1637 if (!unitTarget)
1638 return;
1639
1640 Player* player = unitTarget->ToPlayer();
1641 if (!player)
1642 {
1643 return;
1644 }
1645
1646 uint32 newitemid = itemId;
1647
1648 ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(newitemid);
1649 if (!pProto)
1650 {
1651 player->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, nullptr, nullptr);
1652 return;
1653 }
1654
1655 uint32 addNumber = damage;
1656
1657 // bg reward have some special in code work
1658 bool SelfCast = true;
1659 switch (m_spellInfo->Id)
1660 {
1665 case SPELL_WS_MARK_TIE:
1668 SelfCast = true;
1669 break;
1671 if (player->HasAura(55629 /*SPELL_LIEUTENANT*/))
1672 addNumber = 3;
1673 else if (player->HasAura(33280 /*SPELL_CORPORAL*/))
1674 addNumber = 2;
1675 else
1676 addNumber = 1;
1677 SelfCast = true;
1678 break;
1679 }
1680
1681 if (addNumber < 1)
1682 addNumber = 1;
1683 if (addNumber > pProto->GetMaxStackSize())
1684 addNumber = pProto->GetMaxStackSize();
1685
1686 /* == gem perfection handling == */
1687
1688 // the chance of getting a perfect result
1689 float perfectCreateChance = 0.0f;
1690
1691 // the resulting perfect item if successful
1692 uint32 perfectItemType = itemId;
1693
1694 // get perfection capability and chance
1695 if (CanCreatePerfectItem(player, m_spellInfo->Id, perfectCreateChance, perfectItemType))
1696 if (roll_chance_f(perfectCreateChance)) // if the roll succeeds...
1697 newitemid = perfectItemType; // the perfect item replaces the regular one
1698
1699 /* == gem perfection handling over == */
1700
1701 /* == profession specialization handling == */
1702
1703 // init items_count to 1, since 1 item will be created regardless of specialization
1704 int32 itemsCount = 1;
1705 float additionalCreateChance = 0.0f;
1706 int32 additionalMaxNum = 0;
1707 // get the chance and maximum number for creating extra items
1708 if (canCreateExtraItems(player, m_spellInfo->Id, additionalCreateChance, additionalMaxNum))
1709 {
1710 // roll with this chance till we roll not to create or we create the max num
1711 while (roll_chance_f(additionalCreateChance) && itemsCount <= additionalMaxNum)
1712 ++itemsCount;
1713 }
1714
1715 // really will be created more items
1716 addNumber *= itemsCount;
1717
1718 /* == profession specialization handling over == */
1719
1720 // can the player store the new item?
1721 ItemPosCountVec dest;
1722 uint32 no_space = 0;
1723 InventoryResult msg = player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, newitemid, addNumber, &no_space);
1724 if (msg != EQUIP_ERR_OK)
1725 {
1726 // convert to possible store amount
1728 addNumber -= no_space;
1729 else
1730 {
1731 // if not created by another reason from full inventory or unique items amount limitation
1732 player->SendEquipError(msg, nullptr, nullptr, newitemid);
1733 return;
1734 }
1735 }
1736
1737 if (addNumber)
1738 {
1739 // create the new item and store it
1740 Item* pItem = player->StoreNewItem(dest, newitemid, true);
1741
1742 // was it successful? return error if not
1743 if (!pItem)
1744 {
1745 player->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, nullptr, nullptr);
1746 return;
1747 }
1748
1749 // set the "Crafted by ..." property of the item
1750 if (pItem->GetTemplate()->HasSignature())
1751 pItem->SetGuidValue(ITEM_FIELD_CREATOR, player->GetGUID());
1752
1753 // send info to the client
1754 player->SendNewItem(pItem, addNumber, true, SelfCast);
1755
1756 sScriptMgr->OnCreateItem(player, pItem, addNumber);
1757
1758 // we succeeded in creating at least one item, so a levelup is possible
1759 if (SelfCast)
1761 }
1762}
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
@ 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
@ ITEM_FIELD_CREATOR
Definition: UpdateFields.h:37
@ EQUIP_ERR_ITEM_NOT_FOUND
Definition: Item.h:70
@ EQUIP_ERR_CANT_CARRY_MORE_OF_THIS
Definition: Item.h:64
bool HasSignature() const
Definition: ItemTemplate.h:698
void SetGuidValue(uint16 index, ObjectGuid value)
Definition: Object.cpp:723
bool UpdateCraftSkill(uint32 spellid)
Definition: PlayerUpdates.cpp:781
void SendNewItem(Item *item, uint32 count, bool received, bool created, bool broadcast=false, bool sendChatMessage=true)
Definition: PlayerStorage.cpp:4756
Item * StoreNewItem(ItemPosCountVec const &pos, uint32 item, bool update, int32 randomPropertyId=0)
Definition: PlayerStorage.cpp:2530

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
3000{
3001 if (!unit || !effectMask)
3002 return SPELL_MISS_EVADE;
3003
3004 // For delayed spells immunity may be applied between missile launch and hit - check immunity for that case
3005 if (m_spellInfo->Speed && ((m_damage > 0 && unit->IsImmunedToDamage(this)) || unit->IsImmunedToSchool(this) || unit->IsImmunedToSpell(m_spellInfo, this)))
3006 {
3007 return SPELL_MISS_IMMUNE;
3008 }
3009
3010 // disable effects to which unit is immune
3011 SpellMissInfo returnVal = SPELL_MISS_IMMUNE;
3012 for (uint32 effectNumber = 0; effectNumber < MAX_SPELL_EFFECTS; ++effectNumber)
3013 {
3014 if (effectMask & (1 << effectNumber))
3015 {
3016 if (unit->IsImmunedToSpellEffect(m_spellInfo, effectNumber))
3017 effectMask &= ~(1 << effectNumber);
3018 // Xinef: Buggs out polymorph
3019 // Xinef: And this is checked in MagicSpellHitResult, why we check resistance twice?
3020 // Xinef: And why we check every spell effect basing on rand and generic dispel info? some effects will be appliend and some wont?
3021 /*else if (m_spellInfo->Effects[effectNumber].IsAura() && !m_spellInfo->IsPositiveEffect(effectNumber))
3022 {
3023 int32 debuff_resist_chance = unit->GetMaxPositiveAuraModifierByMiscValue(SPELL_AURA_MOD_DEBUFF_RESISTANCE, int32(m_spellInfo->Dispel));
3024 debuff_resist_chance += unit->GetMaxNegativeAuraModifierByMiscValue(SPELL_AURA_MOD_DEBUFF_RESISTANCE, int32(m_spellInfo->Dispel));
3025
3026 if (debuff_resist_chance > 0)
3027 if (irand(0,10000) <= (debuff_resist_chance * 100))
3028 {
3029 effectMask &= ~(1 << effectNumber);
3030 returnVal = SPELL_MISS_RESIST;
3031 }
3032 }*/
3033 }
3034 }
3035 if (!effectMask)
3036 return returnVal;
3037
3038 if (unit->IsPlayer())
3039 {
3043 }
3044
3045 if (m_caster->IsPlayer())
3046 {
3049 }
3050
3051 if (m_caster != unit)
3052 {
3053 // Recheck UNIT_FLAG_NON_ATTACKABLE for delayed spells
3054 // Xinef: Also check evade state
3055 if (m_spellInfo->Speed > 0.0f)
3056 {
3057 if (unit->IsCreature() && unit->ToCreature()->IsInEvadeMode())
3058 return SPELL_MISS_EVADE;
3059
3061 return SPELL_MISS_EVADE;
3062 }
3063
3064 if (m_caster->_IsValidAttackTarget(unit, m_spellInfo) && /*Intervene Trigger*/ m_spellInfo->Id != 59667)
3065 {
3067 }
3068 else if (m_caster->IsFriendlyTo(unit))
3069 {
3070 // for delayed spells ignore negative spells (after duel end) for friendly targets
3072 if (!IsTriggered() && m_spellInfo->Speed > 0.0f && unit->IsPlayer() && !m_spellInfo->IsPositive())
3073 return SPELL_MISS_EVADE;
3074
3075 // assisting case, healing and resurrection
3077 {
3080 m_caster->ToPlayer()->UpdatePvP(true);
3081 }
3082
3083 // xinef: triggered spells should not prolong combat
3085 {
3086 m_caster->SetInCombatState(unit->GetCombatTimer() > 0, unit);
3087 unit->getHostileRefMgr().threatAssist(m_caster, 0.0f);
3088 }
3089 }
3090 }
3091
3092 uint8 aura_effmask = 0;
3093 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
3094 if (effectMask & (1 << i) && m_spellInfo->Effects[i].IsUnitOwnedAuraEffect())
3095 aura_effmask |= 1 << i;
3096
3097 Unit* originalCaster = GetOriginalCaster();
3098 if (!originalCaster)
3099 originalCaster = m_caster;
3100
3101 // Get Data Needed for Diminishing Returns, some effects may have multiple auras, so this must be done on spell hit, not aura add
3102 // Xinef: Do not increase diminishing level for self cast
3104 // xinef: do not increase diminish level for bosses (eg. Void Reaver silence is never diminished)
3106 {
3109
3110 uint32 flagsExtra = unit->IsCreature() ? unit->ToCreature()->GetCreatureTemplate()->flags_extra : 0;
3111
3112 // Increase Diminishing on unit, current informations for actually casts will use values above
3113 if ((type == DRTYPE_PLAYER && (unit->IsCharmedOwnedByPlayerOrPlayer() || flagsExtra & CREATURE_FLAG_EXTRA_ALL_DIMINISH ||
3115 {
3116 // Do not apply diminish return if caster is NPC
3118 {
3120 }
3121 }
3122 }
3123
3125 {
3127 }
3128
3129 if (aura_effmask)
3130 {
3131 // Select rank for aura with level requirements only in specific cases
3132 // 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
3133 SpellInfo const* aurSpellInfo = m_spellInfo;
3134 int32 basePoints[3];
3135 if (scaleAura)
3136 {
3138 ASSERT(aurSpellInfo);
3139 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
3140 {
3141 basePoints[i] = aurSpellInfo->Effects[i].BasePoints;
3142 if (m_spellInfo->Effects[i].Effect != aurSpellInfo->Effects[i].Effect)
3143 {
3144 aurSpellInfo = m_spellInfo;
3145 break;
3146 }
3147 }
3148 }
3149
3150 if (m_originalCaster)
3151 {
3152 bool refresh = false;
3154 m_spellAura = Aura::TryRefreshStackOrCreate(aurSpellInfo, effectMask, unit, m_originalCaster,
3155 (aurSpellInfo == m_spellInfo) ? &m_spellValue->EffectBasePoints[0] : &basePoints[0], m_CastItem, ObjectGuid::Empty, &refresh, refreshPeriodic);
3156
3157 // xinef: if aura was not refreshed, add proc ex
3158 if (!refresh)
3160
3161 if (m_spellAura)
3162 {
3163 // Set aura stack amount to desired value
3165 {
3166 if (!refresh)
3168 else
3170 }
3171
3172 // Now Reduce spell duration using data received at spell hit
3173 int32 duration = m_spellAura->GetMaxDuration();
3174 int32 limitduration = GetDiminishingReturnsLimitDuration(m_diminishGroup, aurSpellInfo);
3175
3176 // Xinef: if unit == caster - test versus original unit if available
3177 float diminishMod = 1.0f;
3178 if (unit == m_caster && m_targets.GetUnitTarget())
3180 else
3181 diminishMod = unit->ApplyDiminishingToDuration(m_diminishGroup, duration, m_originalCaster, m_diminishLevel, limitduration);
3182
3183 // unit is immune to aura if it was diminished to 0 duration
3184 if (diminishMod == 0.0f)
3185 {
3188 return SPELL_MISS_IMMUNE;
3189 bool found = false;
3190 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
3191 if (effectMask & (1 << i) && m_spellInfo->Effects[i].Effect != SPELL_EFFECT_APPLY_AURA)
3192 found = true;
3193 if (!found)
3194 return SPELL_MISS_IMMUNE;
3195 }
3196 else
3197 {
3198 ((UnitAura*)m_spellAura)->SetDiminishGroup(m_diminishGroup);
3199
3200 bool positive = m_spellAura->GetSpellInfo()->IsPositive();
3202 positive = aurApp->IsPositive();
3203
3204 duration = m_originalCaster->ModSpellDuration(aurSpellInfo, unit, duration, positive, effectMask);
3205
3206 // xinef: haste affects duration of those spells twice
3209
3210 if (m_spellValue->AuraDuration != 0)
3211 {
3212 if (m_spellAura->GetMaxDuration() != -1)
3213 {
3215 }
3216
3218 }
3219 else if (duration != m_spellAura->GetMaxDuration())
3220 {
3221 m_spellAura->SetMaxDuration(duration);
3222 m_spellAura->SetDuration(duration);
3223 }
3224
3225 // xinef: apply relic cooldown, imo best place to add this
3228
3231 }
3232 }
3233 }
3234 }
3235
3236 int8 sanct_effect = -1;
3237
3238 for (uint32 effectNumber = 0; effectNumber < MAX_SPELL_EFFECTS; ++effectNumber)
3239 {
3240 // handle sanctuary effects after aura apply!
3241 if (m_spellInfo->Effects[effectNumber].Effect == SPELL_EFFECT_SANCTUARY)
3242 {
3243 sanct_effect = effectNumber;
3244 continue;
3245 }
3246
3247 if (effectMask & (1 << effectNumber))
3248 HandleEffects(unit, nullptr, nullptr, effectNumber, SPELL_EFFECT_HANDLE_HIT_TARGET);
3249 }
3250
3251 if (sanct_effect >= 0 && (effectMask & (1 << sanct_effect)))
3252 HandleEffects(unit, nullptr, nullptr, sanct_effect, SPELL_EFFECT_HANDLE_HIT_TARGET);
3253
3254 return SPELL_MISS_NONE;
3255}
@ UNIT_STATE_ATTACK_PLAYER
Definition: UnitDefines.h:163
@ UNIT_FLAG_NON_ATTACKABLE
Definition: UnitDefines.h:230
@ UNIT_MOD_CAST_SPEED
Definition: UpdateFields.h:137
@ CREATURE_FLAG_EXTRA_OBEYS_TAUNT_DIMINISHING_RETURNS
Definition: CreatureData.h:65
@ CREATURE_FLAG_EXTRA_ALL_DIMINISH
Definition: CreatureData.h:66
@ 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
@ PROC_EX_NO_AURA_REFRESH
Definition: SpellMgr.h:214
@ 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
@ DIMINISHING_TAUNT
Definition: SharedDefines.h:3276
@ SPELL_EFFECT_SANCTUARY
Definition: SharedDefines.h:857
@ SPELL_ATTR5_SPELL_HASTE_AFFECTS_PERIODIC
Definition: SharedDefines.h:580
DiminishingReturnsType
Definition: SharedDefines.h:3249
@ DRTYPE_PLAYER
Definition: SharedDefines.h:3251
@ DRTYPE_ALL
Definition: SharedDefines.h:3252
@ ACHIEVEMENT_TIMED_TYPE_SPELL_CASTER
Definition: DBCEnums.h:112
@ ACHIEVEMENT_TIMED_TYPE_SPELL_TARGET
Definition: DBCEnums.h:113
@ ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET2
Definition: DBCEnums.h:181
@ ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET
Definition: DBCEnums.h:142
@ ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL2
Definition: DBCEnums.h:217
bool isWorldBoss() const
Definition: Creature.h:123
bool IsInEvadeMode() const
Definition: Creature.h:137
uint32 flags_extra
Definition: CreatureData.h:249
float GetFloatValue(uint16 index) const
Definition: Object.cpp:317
static ObjectGuid const Empty
Definition: ObjectGuid.h:120
bool HasAuraTypeWithAffectMask(AuraType auratype, SpellInfo const *affectedSpell) const
Definition: Unit.cpp:5709
DiminishingLevels GetDiminishing(DiminishingGroup group)
Definition: Unit.cpp:14962
void IncrDiminishing(DiminishingGroup group)
Definition: Unit.cpp:14988
uint32 GetCombatTimer() const
Definition: Unit.h:830
bool IsImmunedToSchool(SpellSchoolMask meleeSchoolMask) const
Definition: Unit.cpp:12789
void SetContestedPvP(Player *attackedPlayer=nullptr, bool lookForNearContestedGuards=true)
Definition: Unit.cpp:17204
bool HasUnitFlag(UnitFlags flags) const
Definition: Unit.h:682
float ApplyDiminishingToDuration(DiminishingGroup group, int32 &duration, Unit *caster, DiminishingLevels Level, int32 limitduration)
Definition: Unit.cpp:15002
int32 ModSpellDuration(SpellInfo const *spellProto, Unit const *target, int32 duration, bool positive, uint32 effectMask)
Definition: Unit.cpp:14828
virtual void AddSpellCooldown(uint32, uint32, uint32, bool needSendToClient=false, bool forceSendToSpectator=false)
Definition: Unit.h:1729
void SetInCombatState(bool PvP, Unit *enemy=nullptr, uint32 duration=0)
Definition: Unit.cpp:13689
bool IsCharmedOwnedByPlayerOrPlayer() const
Definition: Unit.h:1234
bool HasAuraType(AuraType auraType) const
Definition: Unit.cpp:5676
bool IsImmunedToDamage(SpellSchoolMask meleeSchoolMask) const
Definition: Unit.cpp:12704
virtual bool IsImmunedToSpell(SpellInfo const *spellInfo, Spell const *spell=nullptr)
Definition: Unit.cpp:12873
bool IsHostileTo(Unit const *unit) const
Definition: Unit.cpp:10198
bool _IsValidAttackTarget(Unit const *target, SpellInfo const *bySpell, WorldObject const *obj=nullptr) const
Definition: Unit.cpp:13834
ObjectGuid GetCharmerOrOwnerGUID() const
Definition: Unit.h:1226
Definition: SpellAuras.h:37
int32 GetMaxDuration() const
Definition: SpellAuras.h:129
void SetStackAmount(uint8 num)
Definition: SpellAuras.cpp:995
void SetTriggeredByAuraSpellInfo(SpellInfo const *triggeredByAuraSpellInfo)
Definition: SpellAuras.cpp:2747
void _RegisterForTargets()
Definition: SpellAuras.h:121
bool ModStackAmount(int32 num, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT, bool periodicReset=false)
Definition: SpellAuras.cpp:1021
static Aura * TryRefreshStackOrCreate(SpellInfo const *spellproto, uint8 tryEffMask, WorldObject *owner, Unit *caster, int32 *baseAmount=nullptr, Item *castItem=nullptr, ObjectGuid casterGUID=ObjectGuid::Empty, bool *refresh=nullptr, bool periodicReset=false)
Definition: SpellAuras.cpp:326
void SetDuration(int32 duration, bool withMods=false)
Definition: SpellAuras.cpp:868
const AuraApplication * GetApplicationOfTarget(ObjectGuid guid) const
Definition: SpellAuras.h:183
void SetMaxDuration(int32 duration)
Definition: SpellAuras.h:130
virtual void Remove(AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)=0
Definition: SpellAuras.h:279
int32 AuraDuration
Definition: Spell.h:217
uint8 AuraStackAmount
Definition: Spell.h:216
Unit * GetOriginalCaster() const
Definition: Spell.h:574
SpellInfo const * GetAuraRankForLevel(uint8 level) const
Definition: SpellInfo.cpp:2525

References Unit::_IsValidAttackTarget(), Aura::_RegisterForTargets(), ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET, ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET2, ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL2, ACHIEVEMENT_TIMED_TYPE_SPELL_CASTER, ACHIEVEMENT_TIMED_TYPE_SPELL_TARGET, Unit::AddSpellCooldown(), Unit::ApplyDiminishingToDuration(), ASSERT, AURA_INTERRUPT_FLAG_HITBYSPELL, SpellValue::AuraDuration, SpellValue::AuraStackAmount, CREATURE_FLAG_EXTRA_ALL_DIMINISH, CREATURE_FLAG_EXTRA_OBEYS_TAUNT_DIMINISHING_RETURNS, DIMINISHING_TAUNT, DRTYPE_ALL, DRTYPE_PLAYER, SpellValue::EffectBasePoints, SpellInfo::Effects, ObjectGuid::Empty, CreatureTemplate::flags_extra, Aura::GetApplicationOfTarget(), SpellInfo::GetAuraRankForLevel(), Unit::GetCharmerOrOwnerGUID(), Unit::GetCombatTimer(), Creature::GetCreatureTemplate(), Unit::GetDiminishing(), GetDiminishingReturnsGroupForSpell(), GetDiminishingReturnsGroupType(), GetDiminishingReturnsLimitDuration(), Object::GetEntry(), Object::GetFloatValue(), Object::GetGUID(), Unit::getHostileRefMgr(), Unit::GetLevel(), Aura::GetMaxDuration(), GetOriginalCaster(), Aura::GetSpellInfo(), Item::GetTemplate(), SpellCastTargets::GetUnitTarget(), HandleEffects(), SpellInfo::HasAttribute(), Unit::HasAuraType(), Unit::HasAuraTypeWithAffectMask(), HasTriggeredCastFlag(), Unit::HasUnitFlag(), Unit::HasUnitState(), SpellInfo::Id, Unit::IncrDiminishing(), ItemTemplate::InventoryType, INVTYPE_RELIC, Unit::IsCharmedOwnedByPlayerOrPlayer(), Object::IsCreature(), Unit::IsFriendlyTo(), Unit::IsHostileTo(), Unit::IsImmunedToDamage(), Unit::IsImmunedToSchool(), Unit::IsImmunedToSpell(), Unit::IsImmunedToSpellEffect(), Unit::IsInCombat(), Creature::IsInEvadeMode(), Object::IsPlayer(), SpellInfo::IsPositive(), IsTriggered(), Creature::isWorldBoss(), m_caster, m_CastItem, m_damage, m_diminishGroup, m_diminishLevel, m_originalCaster, m_procEx, m_spellAura, m_spellFlags, m_spellInfo, m_spellValue, m_targets, m_triggeredByAuraSpell, MAX_SPELL_EFFECTS, Unit::ModSpellDuration(), Aura::ModStackAmount(), PROC_EX_NO_AURA_REFRESH, Aura::Remove(), Unit::RemoveAurasByType(), Unit::RemoveAurasWithInterruptFlags(), Unit::SetContestedPvP(), Aura::SetDuration(), Unit::SetInCombatState(), Aura::SetMaxDuration(), Aura::SetStackAmount(), Aura::SetTriggeredByAuraSpellInfo(), SpellInfo::Speed, SPELL_ATTR0_CU_DONT_BREAK_STEALTH, SPELL_ATTR0_CU_NO_PVP_FLAG, SPELL_ATTR3_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(), 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
3258{
3259 // Apply additional spell effects to target
3261 if (m_preCastSpell)
3262 {
3263 // Paladin immunity shields
3264 if (m_preCastSpell == 61988)
3265 {
3266 // Cast Forbearance
3267 m_caster->CastSpell(unit, 25771, true);
3268 // Cast Avenging Wrath Marker
3269 unit->CastSpell(unit, 61987, true);
3270 }
3271
3272 // Avenging Wrath
3273 if (m_preCastSpell == 61987)
3274 // Cast the serverside immunity shield marker
3275 m_caster->CastSpell(unit, 61988, true);
3276
3277 // Fearie Fire (Feral) - damage
3278 if (m_preCastSpell == 60089)
3279 m_caster->CastSpell(unit, m_preCastSpell, true);
3280 else if (sSpellMgr->GetSpellInfo(m_preCastSpell))
3281 // Blizz seems to just apply aura without bothering to cast
3283 }
3284
3285 // handle SPELL_AURA_ADD_TARGET_TRIGGER auras
3286 // this is executed after spell proc spells on target hit
3287 // spells are triggered for each hit spell target
3288 // info confirmed with retail sniffs of permafrost and shadow weaving
3289 if (!m_hitTriggerSpells.empty())
3290 {
3291 int _duration = 0;
3292 for (HitTriggerSpellList::const_iterator i = m_hitTriggerSpells.begin(); i != m_hitTriggerSpells.end(); ++i)
3293 {
3294 if (CanExecuteTriggersOnHit(effMask, i->triggeredByAura) && roll_chance_i(i->chance))
3295 {
3296 m_caster->CastSpell(unit, i->triggeredSpell->Id, true);
3297 LOG_DEBUG("spells.aura", "Spell {} triggered spell {} by SPELL_AURA_ADD_TARGET_TRIGGER aura", m_spellInfo->Id, i->triggeredSpell->Id);
3298
3299 // SPELL_AURA_ADD_TARGET_TRIGGER auras shouldn't trigger auras without duration
3300 // set duration of current aura to the triggered spell
3301 if (i->triggeredSpell->GetDuration() == -1)
3302 {
3303 if (Aura* triggeredAur = unit->GetAura(i->triggeredSpell->Id, m_caster->GetGUID()))
3304 {
3305 // get duration from aura-only once
3306 if (!_duration)
3307 {
3308 Aura* aur = unit->GetAura(m_spellInfo->Id, m_caster->GetGUID());
3309 _duration = aur ? aur->GetDuration() : -1;
3310 }
3311 triggeredAur->SetDuration(_duration);
3312 }
3313 }
3314 }
3315 }
3316 }
3317
3318 // trigger linked auras remove/apply
3320 if (std::vector<int32> const* spellTriggered = sSpellMgr->GetSpellLinked(m_spellInfo->Id + SPELL_LINK_HIT))
3321 {
3322 for (std::vector<int32>::const_iterator i = spellTriggered->begin(); i != spellTriggered->end(); ++i)
3323 if (*i < 0)
3324 {
3325 unit->RemoveAurasDueToSpell(-(*i));
3326 }
3327 else
3328 {
3329 unit->CastSpell(unit, *i, true, 0, 0, m_caster->GetGUID());
3330 }
3331 }
3332}
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:5552
Aura * AddAura(uint32 spellId, Unit *target)
Definition: Unit.cpp:18819
int32 GetDuration() const
Definition: SpellAuras.h:133
HitTriggerSpellList m_hitTriggerSpells
Definition: Spell.h:754

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)
4232{
4234 return;
4235
4236 if (!gameObjTarget)
4237 return;
4238
4239 GameObjectActions action = GameObjectActions(m_spellInfo->Effects[effIndex].MiscValue);
4240 switch (action)
4241 {
4242 case GameObjectActions::AnimateCustom0:
4243 case GameObjectActions::AnimateCustom1:
4244 case GameObjectActions::AnimateCustom2:
4245 case GameObjectActions::AnimateCustom3:
4246 gameObjTarget->SendCustomAnim(uint32(action) - uint32(GameObjectActions::AnimateCustom0));
4247 break;
4248 case GameObjectActions::Disturb: // What's the difference with Open?
4249 case GameObjectActions::Open:
4250 if (Unit* unitCaster = m_caster->ToUnit())
4251 gameObjTarget->Use(unitCaster);
4252 break;
4253 case GameObjectActions::OpenAndUnlock:
4254 if (Unit* unitCaster = m_caster->ToUnit())
4255 gameObjTarget->UseDoorOrButton(0, false, unitCaster);
4256 [[fallthrough]];
4257 case GameObjectActions::Unlock:
4258 case GameObjectActions::Lock:
4259 gameObjTarget->ApplyModFlag(GAMEOBJECT_FLAGS, GO_FLAG_LOCKED, action == GameObjectActions::Lock);
4260 break;
4261 case GameObjectActions::Close:
4262 case GameObjectActions::Rebuild:
4264 break;
4265 case GameObjectActions::Despawn:
4267 break;
4268 case GameObjectActions::MakeInert:
4269 case GameObjectActions::MakeActive:
4270 gameObjTarget->ApplyModFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE, action == GameObjectActions::MakeInert);
4271 break;
4272 case GameObjectActions::CloseAndLock:
4275 break;
4276 case GameObjectActions::Destroy:
4277 if (Unit* unitCaster = m_caster->ToUnit())
4278 gameObjTarget->UseDoorOrButton(0, true, unitCaster);
4279 break;
4280 case GameObjectActions::UseArtKit0:
4281 case GameObjectActions::UseArtKit1:
4282 case GameObjectActions::UseArtKit2:
4283 case GameObjectActions::UseArtKit3:
4284 {
4285 GameObjectTemplateAddon const* templateAddon = gameObjTarget->GetTemplateAddon();
4286
4287 uint32 artKitIndex = uint32(action) - uint32(GameObjectActions::UseArtKit0);
4288
4289 uint32 artKitValue = 0;
4290 if (templateAddon)
4291 artKitValue = templateAddon->artKits[artKitIndex];
4292
4293 if (artKitValue == 0)
4294 LOG_ERROR("sql.sql", "GameObject {} hit by spell {} needs `artkit{}` in `gameobject_template_addon`", gameObjTarget->GetEntry(), m_spellInfo->Id, artKitIndex);
4295 else
4296 gameObjTarget->SetGoArtKit(artKitValue);
4297
4298 break;
4299 }
4300 case GameObjectActions::None:
4301 LOG_FATAL("spell", "Spell {} has action type NONE in effect {}", m_spellInfo->Id, int32(effIndex));
4302 break;
4303 default:
4304 LOG_ERROR("spell", "Spell {} has unhandled action {} in effect {}", m_spellInfo->Id, int32(action), int32(effIndex));
4305 break;
4306 }
4307}
#define LOG_FATAL(filterType__,...)
Definition: Log.h:152
@ GAMEOBJECT_FLAGS
Definition: UpdateFields.h:399
GameObjectActions
Definition: GameObject.h:77
@ GO_FLAG_NOT_SELECTABLE
Definition: SharedDefines.h:1607
@ GO_FLAG_LOCKED
Definition: SharedDefines.h:1604
void UseDoorOrButton(uint32 time_to_restore=0, bool alternative=false, Unit *user=nullptr)
Definition: GameObject.cpp:1429
void SetGoArtKit(uint8 artkit)
Definition: GameObject.cpp:1443
void SendCustomAnim(uint32 anim)
Definition: GameObject.cpp:2150
void ResetDoorOrButton()
Definition: GameObject.cpp:1419
void DespawnOrUnsummon(Milliseconds delay=0ms, Seconds forcedRespawnTime=0s)
Definition: GameObject.cpp:933
GameObjectTemplateAddon const * GetTemplateAddon() const
Definition: GameObject.cpp:912
void Use(Unit *user)
Definition: GameObject.cpp:1479
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)
5746{
5748 return;
5749
5750 if (!m_caster->IsPlayer())
5751 return;
5752
5753 Player* player = m_caster->ToPlayer();
5754
5756 return;
5757
5758 // needed later
5760
5761 uint32 count = damage;
5762 if (count == 0) count = 1;
5763 for (uint32 j = 0; j < MAX_RUNES && count > 0; ++j)
5764 {
5765 if (player->GetRuneCooldown(j) && player->GetCurrentRune(j) == RuneType(m_spellInfo->Effects[effIndex].MiscValue))
5766 {
5767 if (m_spellInfo->Id == 45529)
5768 if (player->GetBaseRune(j) != RuneType(m_spellInfo->Effects[effIndex].MiscValueB))
5769 continue;
5770 player->SetRuneCooldown(j, 0);
5771 player->SetGracePeriod(j, player->IsInCombat()); // xinef: reset grace period
5772 --count;
5773 }
5774 }
5775
5776 // Blood Tap
5777 if (m_spellInfo->Id == 45529 && count > 0)
5778 {
5779 for (uint32 l = 0; l < MAX_RUNES && count > 0; ++l)
5780 {
5781 // Check if both runes are on cd as that is the only time when this needs to come into effect
5782 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)))
5783 {
5784 // Should always update the rune with the lowest cd
5785 if (player->GetRuneCooldown(l) >= player->GetRuneCooldown(l + 1))
5786 l++;
5787 player->SetRuneCooldown(l, 0);
5788 player->SetGracePeriod(l, player->IsInCombat()); // xinef: reset grace period
5789 --count;
5790 }
5791 else
5792 break;
5793 }
5794 }
5795
5796 // Empower rune weapon
5797 if (m_spellInfo->Id == 47568)
5798 {
5799 // Need to do this just once
5800 if (effIndex != 0)
5801 return;
5802
5803 for (uint32 i = 0; i < MAX_RUNES; ++i)
5804 {
5805 if (player->GetRuneCooldown(i) && (player->GetCurrentRune(i) == RUNE_FROST || player->GetCurrentRune(i) == RUNE_DEATH))
5806 {
5807 player->SetRuneCooldown(i, 0);
5808 player->SetGracePeriod(i, player->IsInCombat()); // xinef: reset grace period
5809 }
5810 }
5811 }
5812
5813 // is needed to push through to the client that the rune is active
5814 //player->ResyncRunes(MAX_RUNES);
5815 m_caster->CastSpell(m_caster, 47804, true);
5816}
@ RUNE_FROST
Definition: Player.h:411
void SetRuneCooldown(uint8 index, uint32 cooldown)
Definition: Player.h:2496
uint8 GetRunesState() const
Definition: Player.h:2485
void SetGracePeriod(uint8 index, uint32 period)
Definition: Player.h:2497
RuneType GetBaseRune(uint8 index) const
Definition: Player.h:2486

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

◆ EffectActivateSpec()

void Spell::EffectActivateSpec ( SpellEffIndex  effIndex)
6121{
6123 return;
6124
6125 if (!unitTarget)
6126 return;
6127
6128 if (Player* player = unitTarget->ToPlayer())
6129 {
6130 player->ActivateSpec(damage - 1); // damage is 1 or 2, spec is 0 or 1
6131 }
6132}

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

◆ EffectAddComboPoints()

void Spell::EffectAddComboPoints ( SpellEffIndex  effIndex)
4069{
4071 {
4072 return;
4073 }
4074
4075 if (!unitTarget || damage <= 0)
4076 {
4077 return;
4078 }
4079
4081}
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)
4651{
4653 {
4654 return;
4655 }
4656
4657 if (!unitTarget || !unitTarget->IsAlive())
4658 {
4659 return;
4660 }
4661
4663
4665}
void AddExtraAttacks(uint32 count)
Definition: Unit.cpp:2749
void ExecuteLogEffectExtraAttacks(uint8 effIndex, Unit *victim, uint32 attCount)
Definition: Spell.cpp:5108

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

◆ EffectAddFarsight()

void Spell::EffectAddFarsight ( SpellEffIndex  effIndex)
2696{
2698 return;
2699
2700 if (!m_caster->IsPlayer())
2701 return;
2702
2703 float radius = m_spellInfo->Effects[effIndex].CalcRadius();
2704 int32 duration = m_spellInfo->GetDuration();
2705 // Caster not in world, might be spell triggered from aura removal
2706 if (!m_caster->IsInWorld())
2707 return;
2708
2709 // Remove old farsight if exist
2710 bool updateViewerVisibility = m_caster->RemoveDynObject(m_spellInfo->Id);
2711
2712 DynamicObject* dynObj = new DynamicObject(true);
2713 if (!dynObj->CreateDynamicObject(m_caster->GetMap()->GenerateLowGuid<HighGuid::DynamicObject>(), m_caster, m_spellInfo->Id, *destTarget, radius, DYNAMIC_OBJECT_FARSIGHT_FOCUS))
2714 {
2715 delete dynObj;
2716 return;
2717 }
2718
2719 dynObj->SetDuration(duration);
2720 dynObj->SetCasterViewpoint(updateViewerVisibility);
2721}
@ DYNAMIC_OBJECT_FARSIGHT_FOCUS
Definition: DynamicObject.h:31
void SetDuration(int32 newDuration)
Definition: DynamicObject.cpp:205
void SetCasterViewpoint(bool updateViewerVisibility)
Definition: DynamicObject.cpp:233
bool CreateDynamicObject(ObjectGuid::LowType guidlow, Unit *caster, uint32 spellId, Position const &pos, float radius, DynamicObjectType type)
Definition: DynamicObject.cpp:99
ObjectGuid::LowType GenerateLowGuid()
Definition: Map.h:638

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

◆ EffectAddHonor()

void Spell::EffectAddHonor ( SpellEffIndex  effIndex)
2766{
2768 return;
2769
2770 if (!unitTarget->IsPlayer())
2771 return;
2772
2773 // not scale value for item based reward (/10 value expected)
2774 if (m_CastItem)
2775 {
2776 unitTarget->ToPlayer()->RewardHonor(nullptr, 1, damage / 10, false);
2777 LOG_DEBUG("spells.aura", "SpellEffect::AddHonor (spell_id {}) rewards {} honor points (item {}) for player: {}",
2779 return;
2780 }
2781
2782 // do not allow to add too many honor for player (50 * 21) = 1040 at level 70, or (50 * 31) = 1550 at level 80
2783 if (damage <= 50)
2784 {
2786 unitTarget->ToPlayer()->RewardHonor(nullptr, 1, honor_reward, false);
2787 LOG_DEBUG("spells.aura", "SpellEffect::AddHonor (spell_id {}) rewards {} honor points (scale) to player: {}",
2788 m_spellInfo->Id, honor_reward, unitTarget->ToPlayer()->GetGUID().ToString());
2789 }
2790 else
2791 {
2792 //maybe we have correct honor_gain in damage already
2793 unitTarget->ToPlayer()->RewardHonor(nullptr, 1, damage, false);
2794 LOG_DEBUG("spells.aura", "SpellEffect::AddHonor (spell_id {}) rewards {} honor points (non scale) for player: {}",
2796 }
2797}
uint32 hk_honor_at_level(uint8 level, float multiplier=1.0f)
Definition: Formulas.h:38
std::string ToString() const
Definition: ObjectGuid.cpp:47
bool RewardHonor(Unit *victim, uint32 groupsize, int32 honor=-1, bool awardXP=true)
Definition: Player.cpp:6064

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

◆ EffectApplyAreaAura()

void Spell::EffectApplyAreaAura ( SpellEffIndex  effIndex)
1308{
1310 return;
1311
1312 if (!m_spellAura || !unitTarget)
1313 return;
1316}
WorldObject * GetOwner() const
Definition: SpellAuras.h:107
void _ApplyEffectForTargets(uint8 effIndex)
Definition: SpellAuras.cpp:735

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

◆ EffectApplyAura()

void Spell::EffectApplyAura ( SpellEffIndex  effIndex)

◆ EffectApplyGlyph()

void Spell::EffectApplyGlyph ( SpellEffIndex  effIndex)
4310{
4312 return;
4313
4315 return;
4316
4317 Player* player = m_caster->ToPlayer();
4318
4319 // glyph sockets level requirement
4320 uint8 minLevel = 0;
4321 switch (m_glyphIndex)
4322 {
4323 case 0:
4324 case 1:
4325 minLevel = 15;
4326 break;
4327 case 2:
4328 minLevel = 50;
4329 break;
4330 case 3:
4331 minLevel = 30;
4332 break;
4333 case 4:
4334 minLevel = 70;
4335 break;
4336 case 5:
4337 minLevel = 80;
4338 break;
4339 }
4340 if (minLevel && m_caster->GetLevel() < minLevel)
4341 {
4343 return;
4344 }
4345
4346 // apply new one
4347 if (uint32 glyph = m_spellInfo->Effects[effIndex].MiscValue)
4348 {
4349 if (GlyphPropertiesEntry const* glyphEntry = sGlyphPropertiesStore.LookupEntry(glyph))
4350 {
4351 if (GlyphSlotEntry const* glyphSlotEntry = sGlyphSlotStore.LookupEntry(player->GetGlyphSlot(m_glyphIndex)))
4352 {
4353 if (glyphEntry->TypeFlags != glyphSlotEntry->TypeFlags)
4354 {
4356 return; // glyph slot mismatch
4357 }
4358 }
4359
4360 // remove old glyph aura
4361 if (uint32 oldGlyph = player->GetGlyph(m_glyphIndex))
4362 if (GlyphPropertiesEntry const* oldGlyphEntry = sGlyphPropertiesStore.LookupEntry(oldGlyph))
4363 {
4364 player->RemoveAurasDueToSpell(oldGlyphEntry->SpellId);
4365
4366 // Removed any triggered auras
4367 Unit::AuraMap& ownedAuras = player->GetOwnedAuras();
4368 for (Unit::AuraMap::iterator iter = ownedAuras.begin(); iter != ownedAuras.end();)
4369 {
4370 Aura* aura = iter->second;
4371 if (SpellInfo const* triggeredByAuraSpellInfo = aura->GetTriggeredByAuraSpellInfo())
4372 {
4373 if (triggeredByAuraSpellInfo->Id == oldGlyphEntry->SpellId)
4374 {
4375 player->RemoveOwnedAura(iter);
4376 continue;
4377 }
4378 }
4379 ++iter;
4380 }
4381
4382 player->SendLearnPacket(oldGlyphEntry->SpellId, false); // Send packet to properly handle client-side spell tooltips
4383 }
4384
4385 player->SendLearnPacket(glyphEntry->SpellId, true); // Send packet to properly handle client-side spell tooltips
4387 player->SetGlyph(m_glyphIndex, glyph, !player->GetSession()->PlayerLoading());
4388 player->SendTalentsInfoData(false);
4389 }
4390 }
4391}
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:676
@ SPELL_FAILED_GLYPH_SOCKET_LOCKED
Definition: SharedDefines.h:1126
@ SPELL_FAILED_INVALID_GLYPH
Definition: SharedDefines.h:1124
void SendTalentsInfoData(bool pet)
Definition: Player.cpp:14421
void SendLearnPacket(uint32 spellId, bool learn)
Definition: Player.cpp:3019
uint32 GetGlyph(uint8 slot) const
Definition: Player.h:1750
uint32 GetGlyphSlot(uint8 slot) const
Definition: Player.h:1741
void SetGlyph(uint8 slot, uint32 glyph, bool save)
Definition: Player.h:1742
void RemoveOwnedAura(AuraMap::iterator &i, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition: Unit.cpp:4687
std::multimap< uint32, Aura * > AuraMap
Definition: Unit.h:635
AuraMap & GetOwnedAuras()
Definition: Unit.h:1309
bool PlayerLoading() const
Definition: WorldSession.h:337
SpellInfo const * GetTriggeredByAuraSpellInfo() const
Definition: SpellAuras.cpp:2761
Definition: DBCStructure.h:1029

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

◆ EffectBind()

void Spell::EffectBind ( SpellEffIndex  effIndex)
6254{
6256 return;
6257
6258 if (!unitTarget)
6259 return;
6260
6261 Player* player = unitTarget->ToPlayer();
6262 if (!player)
6263 {
6264 return;
6265 }
6266
6267 WorldLocation homeLoc;
6268 uint32 areaId = player->GetAreaId();
6269
6270 if (m_spellInfo->Effects[effIndex].MiscValue)
6271 areaId = m_spellInfo->Effects[effIndex].MiscValue;
6272
6273 if (m_targets.HasDst())
6274 homeLoc.WorldRelocate(*destTarget);
6275 else
6276 {
6277 homeLoc = player->GetWorldLocation();
6278 }
6279
6280 player->SetHomebind(homeLoc, areaId);
6281
6282 // binding
6283 WorldPacket data(SMSG_BINDPOINTUPDATE, 4 + 4 + 4 + 4 + 4);
6284 data << float(homeLoc.GetPositionX());
6285 data << float(homeLoc.GetPositionY());
6286 data << float(homeLoc.GetPositionZ());
6287 data << uint32(homeLoc.GetMapId());
6288 data << uint32(areaId);
6289 player->SendDirectMessage(&data);
6290
6291 LOG_DEBUG("spells.aura", "EffectBind: New homebind X: {}, Y: {}, Z: {}, MapId: {}, AreaId: {}",
6292 homeLoc.GetPositionX(), homeLoc.GetPositionY(), homeLoc.GetPositionZ(), homeLoc.GetMapId(), areaId);
6293 // zone update
6294 data.Initialize(SMSG_PLAYERBOUND, 8 + 4);
6295 data << m_caster->GetGUID();
6296 data << uint32(areaId);
6297 player->SendDirectMessage(&data);
6298}
@ 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:5692
void SetHomebind(WorldLocation const &loc, uint32 areaId)
Definition: PlayerStorage.cpp:4902

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)
4677{
4679 return;
4680
4681 if (m_caster->IsPlayer())
4682 m_caster->ToPlayer()->SetCanBlock(true);
4683}
void SetCanBlock(bool value)
Definition: Player.cpp:13133

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

◆ EffectCastButtons()

void Spell::EffectCastButtons ( SpellEffIndex  effIndex)

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

6181{
6183 return;
6184
6185 if (!m_caster->IsPlayer())
6186 return;
6187
6188 Player* p_caster = m_caster->ToPlayer();
6189 uint32 button_id = m_spellInfo->Effects[effIndex].MiscValue + 132;
6190 uint32 n_buttons = m_spellInfo->Effects[effIndex].MiscValueB;
6191
6192 for (; n_buttons; --n_buttons, ++button_id)
6193 {
6194 ActionButton const* ab = p_caster->GetActionButton(button_id);
6195 if (!ab || ab->GetType() != ACTION_BUTTON_SPELL)
6196 continue;
6197
6200 uint32 spell_id = ab->GetAction();
6201 if (!spell_id)
6202 continue;
6203
6204 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spell_id);
6205 if (!spellInfo)
6206 continue;
6207
6208 if (!p_caster->HasSpell(spell_id) || p_caster->HasSpellCooldown(spell_id))
6209 continue;
6210
6212 continue;
6213
6214 uint32 cost = spellInfo->CalcPowerCost(m_caster, spellInfo->GetSchoolMask(), this);
6215 if (m_caster->GetPower(POWER_MANA) < cost)
6216 continue;
6217
6219 m_caster->CastSpell(m_caster, spell_id, triggerFlags);
6220 }
6221}
@ ACTION_BUTTON_SPELL
Definition: Player.h:229
@ SPELL_ATTR7_CAN_BE_MULTI_CAST
Definition: SharedDefines.h:646
Definition: Player.h:253
uint32 GetAction() const
Definition: Player.h:261
ActionButtonType GetType() const
Definition: Player.h:260
ActionButton const * GetActionButton(uint8 button)
Definition: Player.cpp:5638
bool HasSpell(uint32 spell) const override
Definition: Player.cpp:3859

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

◆ EffectCharge()

void Spell::EffectCharge ( SpellEffIndex  effIndex)
4896{
4898 {
4899 if (!unitTarget)
4900 return;
4901
4902 ObjectGuid targetGUID = ObjectGuid::Empty;
4903 Player* player = m_caster->ToPlayer();
4904 if (player)
4905 {
4906 // charge changes fall time
4908
4910 {
4911 targetGUID = unitTarget->GetGUID();
4912 }
4913 }
4914
4915 float speed = G3D::fuzzyGt(m_spellInfo->Speed, 0.0f) ? m_spellInfo->Speed : SPEED_CHARGE;
4916 // Spell is not using explicit target - no generated path
4917 if (!m_preGeneratedPath)
4918 {
4920 m_caster->GetMotionMaster()->MoveCharge(pos.m_positionX, pos.m_positionY, pos.m_positionZ, speed, EVENT_CHARGE, nullptr, false, 0.0f, targetGUID);
4921 }
4922 else
4923 {
4924 m_caster->GetMotionMaster()->MoveCharge(*m_preGeneratedPath, speed, targetGUID);
4925 }
4926
4927 if (player)
4928 {
4929 sScriptMgr->AnticheatSetUnderACKmount(player);
4930 }
4931 }
4932}
#define SPEED_CHARGE
Definition: MotionMaster.h:107
@ EVENT_CHARGE
Definition: SharedDefines.h:3311
Position GetFirstCollisionPosition(float startX, float startY, float startZ, float destX, float destY)
Definition: Object.cpp:2821
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:2316
MotionMaster * GetMotionMaster()
Definition: Unit.h:1601
void MoveCharge(float x, float y, float z, float speed=SPEED_CHARGE, uint32 id=EVENT_CHARGE, const Movement::PointsArray *path=nullptr, bool generatePath=false, float orientation=0.0f, ObjectGuid targetGUID=ObjectGuid::Empty)
The unit will charge the target. Doesn't work with UNIT_FLAG_DISABLE_MOVE.
Definition: MotionMaster.cpp:667

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

◆ EffectChargeDest()

◆ EffectCreateItem()

void Spell::EffectCreateItem ( SpellEffIndex  effIndex)
1765{
1767 return;
1768
1769 DoCreateItem(effIndex, m_spellInfo->Effects[effIndex].ItemType);
1770 ExecuteLogEffectCreateItem(effIndex, m_spellInfo->Effects[effIndex].ItemType);
1771}
void ExecuteLogEffectCreateItem(uint8 effIndex, uint32 entry)
Definition: Spell.cpp:5136
void DoCreateItem(uint8 effIndex, uint32 itemId)
Definition: SpellEffects.cpp:1635

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);
1774{
1776 return;
1777
1778 if (!unitTarget)
1779 return;
1780
1781 Player* player = unitTarget->ToPlayer();
1782 if (!player)
1783 {
1784 return;
1785 }
1786
1787 uint32 itemId = m_spellInfo->Effects[effIndex].ItemType;
1788
1789 if (itemId)
1790 DoCreateItem(effIndex, itemId);
1791
1792 // special case: fake item replaced by generate using spell_loot_template
1794 {
1795 if (itemId)
1796 {
1797 if (!player->HasItemCount(itemId))
1798 return;
1799
1800 // remove reagent
1801 uint32 count = 1;
1802 player->DestroyItemCount(itemId, count, true);
1803
1804 // create some random items
1806 }
1807 else
1808 player->AutoStoreLoot(m_spellInfo->Id, LootTemplates_Spell); // create some random items
1809 }
1811}
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:13488
void DestroyItemCount(uint32 item, uint32 count, bool update, bool unequip_check=false)
Definition: PlayerStorage.cpp:3127
bool IsLootCrafting() const
Definition: SpellInfo.cpp:924

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);
1814{
1816 return;
1817
1818 if (!unitTarget)
1819 return;
1820
1821 Player* player = unitTarget->ToPlayer();
1822 if (!player)
1823 {
1824 return;
1825 }
1826
1827 // create some random items
1830}

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)
5819{
5821 return;
5822
5824 return;
5825
5826 uint32 creatureEntry = m_spellInfo->Effects[effIndex].MiscValue;
5827 Pet* pet = unitTarget->CreateTamedPetFrom(creatureEntry, m_spellInfo->Id);
5828 if (!pet)
5829 return;
5830
5831 // add to world
5832 pet->GetMap()->AddToMap(pet->ToCreature(), true);
5833
5834 // unitTarget has pet now
5835 unitTarget->SetMinion(pet, true);
5836
5837 pet->InitTalentForLevel();
5838
5839 if (unitTarget->IsPlayer())
5840 {
5843 }
5844}
@ CLASS_HUNTER
Definition: SharedDefines.h:143
void InitTalentForLevel()
Definition: Pet.cpp:2225
void SavePetToDB(PetSaveMode mode)
Definition: Pet.cpp:507
void PetSpellInitialize()
Definition: Player.cpp:9468
void SetMinion(Minion *minion, bool apply)
Definition: Unit.cpp:10642
Pet * CreateTamedPetFrom(Creature *creatureTarget, uint32 spell_id=0)
Definition: Unit.cpp:17307
bool AddToMap(T *, bool checkTransport=false)
Definition: Map.cpp:555

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

◆ EffectDestroyAllTotems()

void Spell::EffectDestroyAllTotems ( SpellEffIndex  effIndex)
5230{
5232 return;
5233
5234 int32 mana = 0;
5235 for (uint8 slot = SUMMON_SLOT_TOTEM; slot < MAX_TOTEM_SLOT; ++slot)
5236 {
5237 if (!m_caster->m_SummonSlot[slot])
5238 continue;
5239
5241 if (totem && totem->IsTotem())
5242 {
5243 uint32 spell_id = totem->GetUInt32Value(UNIT_CREATED_BY_SPELL);
5244 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spell_id);
5245 if (spellInfo)
5246 {
5247 mana += spellInfo->ManaCost;
5249 }
5250 totem->ToTotem()->UnSummon();
5251 }
5252 }
5253 ApplyPct(mana, damage);
5254 if (mana)
5255 m_caster->CastCustomSpell(m_caster, 39104, &mana, nullptr, nullptr, true);
5256}
T ApplyPct(T &base, U pct)
Definition: Util.h:73
#define SUMMON_SLOT_TOTEM
Definition: Unit.h:597
#define MAX_TOTEM_SLOT
Definition: Unit.h:598
@ UNIT_CREATED_BY_SPELL
Definition: UpdateFields.h:138
void UnSummon(uint32 msTime=0) override
Definition: Totem.cpp:122
Totem * ToTotem()
Definition: Unit.h:1715
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:1225
uint32 GetCreateMana() const
Definition: Unit.h:1436
ObjectGuid m_SummonSlot[MAX_SUMMON_SLOT]
Definition: Unit.h:1780
Creature * GetCreature(ObjectGuid const guid)
Definition: Map.cpp:3314
uint32 ManaCostPercentage
Definition: SpellInfo.h:367
uint32 ManaCost
Definition: SpellInfo.h:363

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

◆ EffectDiscoverTaxi()

void Spell::EffectDiscoverTaxi ( SpellEffIndex  effIndex)
5847{
5849 return;
5850
5851 if (!unitTarget)
5852 return;
5853
5854 Player* player = unitTarget->ToPlayer();
5855 if (!player)
5856 {
5857 return;
5858 }
5859
5860 uint32 nodeid = m_spellInfo->Effects[effIndex].MiscValue;
5861 if (sTaxiNodesStore.LookupEntry(nodeid))
5862 player->GetSession()->SendDiscoverNewTaxiNode(nodeid);
5863}
DBCStorage< TaxiNodesEntry > sTaxiNodesStore(TaxiNodesEntryfmt)
void SendDiscoverNewTaxiNode(uint32 nodeid)
Definition: TaxiHandler.cpp:152

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)
4447{
4449 return;
4450
4452 return;
4453
4454 if (Player* caster = m_caster->ToPlayer())
4455 {
4456 caster->UpdateCraftSkill(m_spellInfo->Id);
4457 caster->SendLoot(itemTarget->GetGUID(), LOOT_DISENCHANTING);
4458 }
4459
4460 // item will be removed at disenchanting end
4461}
@ 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)
4533{
4535 return;
4536
4537 if (!unitTarget || !unitTarget->IsPet())
4538 return;
4539
4540 Pet* pet = unitTarget->ToPet();
4541
4542 ExecuteLogEffectUnsummonObject(effIndex, pet);
4544}
@ PET_SAVE_NOT_IN_SLOT
Definition: PetDefines.h:45
void Remove(PetSaveMode mode, bool returnreagent=false)
Definition: Pet.cpp:884
void ExecuteLogEffectUnsummonObject(uint8 effIndex, WorldObject *obj)
Definition: Spell.cpp:5154

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

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)
5135{
5137 return;
5138
5139 if (!unitTarget)
5140 return;
5141
5142 uint32 mechanic = m_spellInfo->Effects[effIndex].MiscValue;
5143
5144 std::queue<std::pair<uint32, ObjectGuid>> dispel_list;
5145
5146 Unit::AuraMap const& auras = unitTarget->GetOwnedAuras();
5147 for (Unit::AuraMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
5148 {
5149 Aura* aura = itr->second;
5151 continue;
5153 {
5154 if ((aura->GetSpellInfo()->GetAllEffectsMechanicMask() & (1 << mechanic)))
5155 {
5156 dispel_list.push(std::make_pair(aura->GetId(), aura->GetCasterGUID()));
5157
5158 // spell only removes 1 bleed effect do not continue
5159 if (m_spellInfo->Effects[effIndex].BasePoints == 1)
5160 {
5161 break;
5162 }
5163 }
5164 }
5165 }
5166
5167 for (; dispel_list.size(); dispel_list.pop())
5168 {
5169 unitTarget->RemoveAura(dispel_list.front().first, dispel_list.front().second, 0, AURA_REMOVE_BY_ENEMY_SPELL);
5170 }
5171
5172 // put in combat
5175}
@ AURA_REMOVE_BY_ENEMY_SPELL
Definition: SpellAuraDefines.h:394
void RemoveAura(AuraApplicationMap::iterator &i, AuraRemoveMode mode=AURA_REMOVE_BY_DEFAULT)
Definition: Unit.cpp:4758
ObjectGuid GetCasterGUID() const
Definition: SpellAuras.h:105
uint32 GetId() const
Definition: SpellAuras.cpp:466
int32 CalcDispelChance(Unit *auraTarget, bool offensive) const
Definition: SpellAuras.cpp:1182

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

◆ EffectDistract()

void Spell::EffectDistract ( SpellEffIndex  effIndex)

@BUG Causes the player to stop moving.

2668{
2670 return;
2671
2672 // Check for possible target
2673 if (!unitTarget || unitTarget->IsEngaged())
2674 return;
2675
2676 // target must be OK to do this
2678 return;
2679
2682}
@ UNIT_STATE_CONFUSED
Definition: UnitDefines.h:160
@ UNIT_STATE_FLEEING
Definition: UnitDefines.h:156
@ UNIT_STATE_STUNNED
Definition: UnitDefines.h:152
float GetAngle(const Position *pos) const
Definition: Position.cpp:77
void SetFacingTo(float ori)
Definition: Unit.cpp:20483
bool IsEngaged() const
Definition: Unit.h:817
void MoveDistract(uint32 time)
Enable the target's distract movement. Doesn't work with UNIT_FLAG_DISABLE_MOVE and if the unit has M...
Definition: MotionMaster.cpp:795

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

◆ EffectDualWield()

void Spell::EffectDualWield ( SpellEffIndex  effIndex)
2654{
2656 return;
2657
2659}
virtual void SetCanDualWield(bool value)
Definition: Unit.h:769

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

◆ EffectDuel()

void Spell::EffectDuel ( SpellEffIndex  effIndex)
4084{
4086 return;
4087
4088 if (!unitTarget || !m_caster->IsPlayer() || !unitTarget->IsPlayer())
4089 return;
4090
4091 Player* caster = m_caster->ToPlayer();
4092 Player* target = unitTarget->ToPlayer();
4093
4094 // caster or target already have requested duel
4095 if (caster->duel || target->duel || !target->GetSocial() || target->GetSocial()->HasIgnore(caster->GetGUID()))
4096 return;
4097
4098 // Players can only fight a duel in zones with this flag
4099 AreaTableEntry const* casterAreaEntry = sAreaTableStore.LookupEntry(caster->GetAreaId());
4100 if (casterAreaEntry && !(casterAreaEntry->flags & AREA_FLAG_ALLOW_DUELS))
4101 {
4102 SendCastResult(SPELL_FAILED_NO_DUELING); // Dueling isn't allowed here
4103 return;
4104 }
4105
4106 AreaTableEntry const* targetAreaEntry = sAreaTableStore.LookupEntry(target->GetAreaId());
4107 if (targetAreaEntry && !(targetAreaEntry->flags & AREA_FLAG_ALLOW_DUELS))
4108 {
4109 SendCastResult(SPELL_FAILED_NO_DUELING); // Dueling isn't allowed here
4110 return;
4111 }
4112
4113 //CREATE DUEL FLAG OBJECT
4114 uint32 gameobject_id = m_spellInfo->Effects[effIndex].MiscValue;
4115 GameObject* pGameObj = sObjectMgr->IsGameObjectStaticTransport(gameobject_id) ? new StaticTransport() : new GameObject();
4116
4117 Map* map = m_caster->GetMap();
4118 if (!pGameObj->Create(map->GenerateLowGuid<HighGuid::GameObject>(), gameobject_id,
4119 map, m_caster->GetPhaseMask(),
4123 m_caster->GetOrientation(), G3D::Quat(), 0, GO_STATE_READY))
4124 {
4125 delete pGameObj;
4126 return;
4127 }
4128
4131 int32 duration = m_spellInfo->GetDuration();
4132 pGameObj->SetRespawnTime(duration > 0 ? duration / IN_MILLISECONDS : 0);
4133 pGameObj->SetSpellId(m_spellInfo->Id);
4134
4135 ExecuteLogEffectSummonObject(effIndex, pGameObj);
4136
4137 m_caster->AddGameObject(pGameObj);
4138 map->AddToMap(pGameObj, true);
4139 //END
4140
4141 // Send request
4142 WorldPacket data(SMSG_DUEL_REQUESTED, 8 + 8);
4143 data << pGameObj->GetGUID();
4144 data << caster->GetGUID();
4145 caster->GetSession()->SendPacket(&data);
4146 target->GetSession()->SendPacket(&data);
4147
4148 // create duel-info
4149 bool isMounted = (GetSpellInfo()->Id == 62875);
4150 caster->duel = std::make_unique<DuelInfo>(target, caster, isMounted);
4151 target->duel = std::make_unique<DuelInfo>(caster, caster, isMounted);
4152
4153 caster->SetGuidValue(PLAYER_DUEL_ARBITER, pGameObj->GetGUID());
4154 target->SetGuidValue(PLAYER_DUEL_ARBITER, pGameObj->GetGUID());
4155
4156 sScriptMgr->OnPlayerDuelRequest(target, caster);
4157}
@ PLAYER_DUEL_ARBITER
Definition: UpdateFields.h:177
@ GAMEOBJECT_LEVEL
Definition: UpdateFields.h:403
@ GAMEOBJECT_FACTION
Definition: UpdateFields.h:402
@ SPELL_FAILED_NO_DUELING
Definition: SharedDefines.h:1028
@ AREA_FLAG_ALLOW_DUELS
Definition: DBCEnums.h:240
@ SMSG_DUEL_REQUESTED
Definition: Opcodes.h:389
virtual bool Create(ObjectGuid::LowType guidlow, uint32 name_id, Map *map, uint32 phaseMask, float x, float y, float z, float ang, G3D::Quat const &rotation, uint32 animprogress, GOState go_state, uint32 artKit=0)
Definition: GameObject.cpp:254
void SetRespawnTime(int32 respawn)
Definition: GameObject.cpp:1303
void SetSpellId(uint32 id)
Definition: GameObject.h:177
void SetUInt32Value(uint16 index, uint32 value)
Definition: Object.cpp:650
uint32 GetPhaseMask() const
Definition: Object.h:446
float GetOrientation() const
Definition: Position.h:120
PlayerSocial * GetSocial()
Definition: Player.h:1141
bool HasIgnore(ObjectGuid ignore_guid) const
Definition: SocialMgr.cpp:193
Definition: Transport.h:112
uint32 GetFaction() const
Definition: Unit.h:755
void AddGameObject(GameObject *gameObj)
Definition: Unit.cpp:6150
void SendPacket(WorldPacket const *packet)
Send a packet to the client.
Definition: WorldSession.cpp:214
void ExecuteLogEffectSummonObject(uint8 effIndex, WorldObject *obj)
Definition: Spell.cpp:5148
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(), GO_STATE_READY, PlayerSocial::HasIgnore(), SpellInfo::Id, IN_MILLISECONDS, Object::IsPlayer(), m_caster, m_spellInfo, PLAYER_DUEL_ARBITER, sAreaTableStore, SendCastResult(), WorldSession::SendPacket(), Object::SetGuidValue(), GameObject::SetRespawnTime(), GameObject::SetSpellId(), Object::SetUInt32Value(), SMSG_DUEL_REQUESTED, sObjectMgr, SPELL_EFFECT_HANDLE_HIT_TARGET, SPELL_FAILED_NO_DUELING, sScriptMgr, Object::ToPlayer(), and unitTarget.

◆ EffectDummy()

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

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

◆ EffectDurabilityDamage()

void Spell::EffectDurabilityDamage ( SpellEffIndex  effIndex)
5259{
5261 return;
5262
5263 if (!unitTarget)
5264 return;
5265
5266 Player* player = unitTarget->ToPlayer();
5267 if (!player)
5268 {
5269 return;
5270 }
5271
5272 int32 slot = m_spellInfo->Effects[effIndex].MiscValue;
5273
5274 // -1 means all player equipped items and -2 all items
5275 if (slot < 0)
5276 {
5277 player->DurabilityPointsLossAll(damage, (slot < -1));
5279 return;
5280 }
5281
5282 // invalid slot value
5283 if (slot >= INVENTORY_SLOT_BAG_END)
5284 return;
5285
5286 if (Item* item = player->GetItemByPos(INVENTORY_SLOT_BAG_0, slot))
5287 {
5288 player->DurabilityPointsLoss(item, damage);
5289 ExecuteLogEffectDurabilityDamage(effIndex, unitTarget, item->GetEntry(), slot);
5290 }
5291}
@ INVENTORY_SLOT_BAG_END
Definition: Player.h:700
#define INVENTORY_SLOT_BAG_0
Definition: Player.h:670
Item * GetItemByPos(uint16 pos) const
Definition: PlayerStorage.cpp:447
void DurabilityPointsLossAll(int32 points, bool inventory)
Definition: Player.cpp:4746
void DurabilityPointsLoss(Item *item, int32 points)
Definition: Player.cpp:4772
void ExecuteLogEffectDurabilityDamage(uint8 effIndex, Unit *victim, int32 itemId, int32 slot)
Definition: Spell.cpp:5122

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)
5294{
5296 return;
5297
5298 if (!unitTarget)
5299 return;
5300
5301 Player* player = unitTarget->ToPlayer();
5302 if (!player)
5303 {
5304 return;
5305 }
5306
5307 int32 slot = m_spellInfo->Effects[effIndex].MiscValue;
5308
5309 // FIXME: some spells effects have value -1/-2
5310 // Possibly its mean -1 all player equipped items and -2 all items
5311 if (slot < 0)
5312 {
5313 player->DurabilityLossAll(float(damage) / 100.0f, (slot < -1));
5314 return;
5315 }
5316
5317 // invalid slot value
5318 if (slot >= INVENTORY_SLOT_BAG_END)
5319 return;
5320
5321 if (damage <= 0)
5322 return;
5323
5324 if (Item* item = player->GetItemByPos(INVENTORY_SLOT_BAG_0, slot))
5325 player->DurabilityLoss(item, float(damage) / 100.0f);
5326}
void DurabilityLossAll(double percent, bool inventory)
Definition: Player.cpp:4702
void DurabilityLoss(Item *item, double percent)
Definition: Player.cpp:4728

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)
4394{
4396 return;
4397
4398 // this is only item spell effect applied to main-hand weapon of target player (players in area)
4399 if (!unitTarget)
4400 return;
4401
4402 Player* item_owner = unitTarget->ToPlayer();
4403 if (!item_owner)
4404 {
4405 return;
4406 }
4407
4409 if (!item)
4410 return;
4411
4412 // must be equipped
4413 if (!item->IsEquipped())
4414 return;
4415
4416 if (m_spellInfo->Effects[effIndex].MiscValue)
4417 {
4418 uint32 enchant_id = m_spellInfo->Effects[effIndex].MiscValue;
4419 int32 duration = m_spellInfo->GetDuration(); //Try duration index first ..
4420 if (!duration)
4421 duration = damage * IN_MILLISECONDS; //+1; //Base points after ..
4422 if (!duration)
4423 duration = 10 * IN_MILLISECONDS; //10 seconds for enchants which don't have listed duration
4424
4425 // Xinef: Venomhide poison, no other spell uses this effect...
4426 if (m_spellInfo->Id == 14792)
4427 duration = 5 * MINUTE * IN_MILLISECONDS;
4428
4429 SpellItemEnchantmentEntry const* pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id);
4430 if (!pEnchant)
4431 return;
4432
4433 // Always go to temp enchantment slot
4435
4436 // Enchantment will not be applied if a different one already exists
4437 if (item->GetEnchantmentId(slot) && item->GetEnchantmentId(slot) != enchant_id)
4438 return;
4439
4440 // Apply the temporary enchantment
4441 item->SetEnchantment(slot, enchant_id, duration, pEnchant->charges, m_caster->GetGUID());
4442 item_owner->ApplyEnchantment(item, slot, true);
4443 }
4444}
@ EQUIPMENT_SLOT_MAINHAND
Definition: Player.h:690
EnchantmentSlot
Definition: Item.h:168
@ TEMP_ENCHANTMENT_SLOT
Definition: Item.h:170
bool IsEquipped() const
Definition: Item.cpp:790
void SetEnchantment(EnchantmentSlot slot, uint32 id, uint32 duration, uint32 charges, ObjectGuid caster=ObjectGuid::Empty)
Definition: Item.cpp:921
void ApplyEnchantment(Item *item, EnchantmentSlot slot, bool apply, bool apply_dur=true, bool ignore_condition=false)
Definition: PlayerStorage.cpp:4310
uint32 charges
Definition: DBCStructure.h:1843

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)
2812{
2814 return;
2815
2816 if (!m_caster->IsPlayer())
2817 return;
2818 if (!itemTarget)
2819 return;
2820
2821 Player* p_caster = m_caster->ToPlayer();
2822
2823 // Handle vellums
2825 {
2826 // destroy one vellum from stack
2827 uint32 count = 1;
2828 p_caster->DestroyItemCount(itemTarget, count, true);
2829 unitTarget = p_caster;
2830 // and add a scroll
2831 DoCreateItem(effIndex, m_spellInfo->Effects[effIndex].ItemType);
2832 itemTarget = nullptr;
2833 m_targets.SetItemTarget(nullptr);
2834 }
2835 else
2836 {
2837 // do not increase skill if vellum used
2839 p_caster->UpdateCraftSkill(m_spellInfo->Id);
2840
2841 uint32 enchant_id = m_spellInfo->Effects[effIndex].MiscValue;
2842 if (!enchant_id)
2843 return;
2844
2845 SpellItemEnchantmentEntry const* pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id);
2846 if (!pEnchant)
2847 return;
2848
2849 // item can be in trade slot and have owner diff. from caster
2850 Player* item_owner = itemTarget->GetOwner();
2851 if (!item_owner)
2852 return;
2853
2854 // remove old enchanting before applying new if equipped
2856
2858
2859 // add new enchanting if equipped
2861
2862 item_owner->RemoveTradeableItem(itemTarget);
2864 }
2865}
@ PERM_ENCHANTMENT_SLOT
Definition: Item.h:169
void ClearSoulboundTradeable(Player *currentOwner)
Definition: Item.cpp:1265
void RemoveTradeableItem(Item *item)
Definition: PlayerStorage.cpp:4145
void SetItemTarget(Item *item)
Definition: Spell.cpp:329

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

◆ EffectEnchantItemPrismatic()

void Spell::EffectEnchantItemPrismatic ( SpellEffIndex  effIndex)
2868{
2870 return;
2871
2872 if (!m_caster->IsPlayer())
2873 return;
2874 if (!itemTarget)
2875 return;
2876
2877 uint32 enchant_id = m_spellInfo->Effects[effIndex].MiscValue;
2878 if (!enchant_id)
2879 return;
2880
2881 SpellItemEnchantmentEntry const* pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id);
2882 if (!pEnchant)
2883 return;
2884
2885 // support only enchantings with add socket in this slot
2886 {
2887 bool add_socket = false;
2888 for (uint8 i = 0; i < MAX_SPELL_ITEM_ENCHANTMENT_EFFECTS; ++i)
2889 {
2890 if (pEnchant->type[i] == ITEM_ENCHANTMENT_TYPE_PRISMATIC_SOCKET)
2891 {
2892 add_socket = true;
2893 break;
2894 }
2895 }
2896 if (!add_socket)
2897 {
2898 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.",
2900 return;
2901 }
2902 }
2903
2904 // item can be in trade slot and have owner diff. from caster
2905 Player* item_owner = itemTarget->GetOwner();
2906 if (!item_owner)
2907 return;
2908
2909 // remove old enchanting before applying new if equipped
2911
2913
2914 // add new enchanting if equipped
2916
2917 item_owner->RemoveTradeableItem(itemTarget);
2919}

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

◆ EffectEnchantItemTmp()

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

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

◆ EffectEnergize()

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

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

◆ EffectEnergizePct()

void Spell::EffectEnergizePct ( SpellEffIndex  effIndex)
1972{
1974 return;
1975
1976 if (!unitTarget)
1977 return;
1978 if (!unitTarget->IsAlive())
1979 return;
1980
1981 if (m_spellInfo->Effects[effIndex].MiscValue < 0 || m_spellInfo->Effects[effIndex].MiscValue >= int8(MAX_POWERS))
1982 return;
1983
1984 Powers power = Powers(m_spellInfo->Effects[effIndex].MiscValue);
1985
1987 return;
1988
1989 uint32 maxPower = unitTarget->GetMaxPower(power);
1990 if (maxPower == 0)
1991 return;
1992
1993 uint32 gain = CalculatePct(maxPower, damage);
1995}

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

◆ EffectEnvironmentalDMG()

void Spell::EffectEnvironmentalDMG ( SpellEffIndex  effIndex)
303{
305 return;
306
307 if (!unitTarget || !unitTarget->IsAlive())
308 return;
309
310 if (unitTarget->IsPlayer())
312 else
313 {
315
316 uint32 absorb = dmgInfo.GetAbsorb();
317 uint32 resist = dmgInfo.GetResist();
318 uint32 envDamage = dmgInfo.GetDamage();
319
320 Unit::DealDamageMods(unitTarget, envDamage, &absorb);
321 damage = envDamage;
322
324 }
325}
@ DAMAGE_FIRE
Definition: Player.h:839
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
4500{
4502 return;
4503
4504 Player* player = m_caster->ToPlayer();
4505 if (!player)
4506 return;
4507
4508 Item* foodItem = itemTarget;
4509 if (!foodItem)
4510 return;
4511
4512 Pet* pet = player->GetPet();
4513 if (!pet)
4514 return;
4515
4516 if (!pet->IsAlive())
4517 return;
4518
4519 int32 benefit = pet->GetCurrentFoodBenefitLevel(foodItem->GetTemplate()->ItemLevel);
4520 if (benefit <= 0)
4521 return;
4522
4523 ExecuteLogEffectDestroyItem(effIndex, foodItem->GetEntry());
4524
4525 uint32 count = 1;
4526 player->DestroyItemCount(foodItem, count, true);
4528
4529 m_caster->CastCustomSpell(pet, m_spellInfo->Effects[effIndex].TriggerSpell, &benefit, nullptr, nullptr, true);
4530}
void ExecuteLogEffectDestroyItem(uint8 effIndex, uint32 entry)
Definition: Spell.cpp:5142

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

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)
4756{
4758 return;
4759
4760 // xinef: clear focus
4762
4764 data << m_caster->GetGUID();
4765
4767 Acore::MessageDistDelivererToHostile notifier(m_caster, &data, dist);
4768 Cell::VisitWorldObjects(m_caster, notifier, dist);
4769
4770 // xinef: we should also force pets to remove us from current target
4771 Unit::AttackerSet attackerSet;
4772 for (Unit::AttackerSet::const_iterator itr = m_caster->getAttackers().begin(); itr != m_caster->getAttackers().end(); ++itr)
4773 if ((*itr)->IsCreature() && !(*itr)->CanHaveThreatList())
4774 attackerSet.insert(*itr);
4775
4776 for (Unit::AttackerSet::const_iterator itr = attackerSet.begin(); itr != attackerSet.end(); ++itr)
4777 (*itr)->AttackStop();
4778
4779 // Xinef: Mirror images code Initialize Images
4780 if (m_spellInfo->Id == 58836)
4781 {
4782 std::vector<Unit*> images;
4783 for (Unit::ControlSet::const_iterator itr = m_caster->m_Controlled.begin(); itr != m_caster->m_Controlled.end(); ++itr)
4784 if ((*itr)->GetEntry() == 31216 /*NPC_MIRROR_IMAGE*/)
4785 images.push_back(*itr);
4786
4787 if (images.empty())
4788 return;
4789
4790 UnitList targets;
4791 Acore::AnyUnfriendlyUnitInObjectRangeCheck u_check(m_caster, m_caster, m_caster->GetVisibilityRange()); // no VISIBILITY_COMPENSATION, distance is enough
4794 for (UnitList::iterator iter = targets.begin(); iter != targets.end(); ++iter)
4795 {
4796 if (!(*iter)->HasUnitState(UNIT_STATE_CASTING))
4797 continue;
4798
4799 if (Spell* spell = (*iter)->GetCurrentSpell(CURRENT_GENERIC_SPELL))
4800 {
4801 if (spell->m_targets.GetUnitTargetGUID() == m_caster->GetGUID())
4802 {
4803 SpellInfo const* si = spell->GetSpellInfo();
4804 if (si->HasAttribute(SPELL_ATTR6_IGNORE_PHASE_SHIFT) && (*iter)->IsCreature())
4805 {
4806 Creature* c = (*iter)->ToCreature();
4807 if ((!c->IsPet() && c->GetCreatureTemplate()->rank == CREATURE_ELITE_WORLDBOSS) || c->isWorldBoss() || c->IsDungeonBoss())
4808 continue;
4809 }
4810
4811 bool interrupt = false; // pussywizard: skip spells that don't target units, but casted on unit (eg. TARGET_DEST_TARGET_ENEMY)
4812 for (uint8 j = 0; j < MAX_SPELL_EFFECTS; ++j)
4813 if (si->Effects[j].Effect && (si->Effects[j].GetUsedTargetObjectType() == TARGET_OBJECT_TYPE_UNIT || si->Effects[j].GetUsedTargetObjectType() == TARGET_OBJECT_TYPE_UNIT_AND_DEST))
4814 {
4815 // at least one effect truly targets an unit, interrupt the spell
4816 interrupt = true;
4817 break;
4818 }
4819
4820 if (interrupt)
4821 spell->m_targets.SetUnitTarget(images.at(urand(0, images.size() - 1)));
4822 }
4823 }
4824 }
4825 }
4826}
std::list< Unit * > UnitList
Definition: Unit.h:76
#define VISIBILITY_COMPENSATION
Definition: ObjectDefines.h:26
@ TARGET_OBJECT_TYPE_UNIT
Definition: SpellInfo.h:101
@ TARGET_OBJECT_TYPE_UNIT_AND_DEST
Definition: SpellInfo.h:102
@ CREATURE_ELITE_WORLDBOSS
Definition: SharedDefines.h:2734
@ SPELL_ATTR6_IGNORE_PHASE_SHIFT
Definition: SharedDefines.h:617
@ SMSG_CLEAR_TARGET
Definition: Opcodes.h:989
bool IsDungeonBoss() const
Definition: Creature.cpp:3157
uint32 rank
Definition: CreatureData.h:209
ControlSet m_Controlled
Definition: Unit.h:1776
void SendClearTarget()
Definition: Unit.cpp:20282
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:133
Definition: GridNotifiers.h:423
Definition: GridNotifiers.h:861

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

◆ EffectGameObjectDamage()

void Spell::EffectGameObjectDamage ( SpellEffIndex  effIndex)
5891{
5893 return;
5894
5895 if (!gameObjTarget)
5896 return;
5897
5898 Unit* caster = m_originalCaster;
5899 if (!caster)
5900 return;
5901
5902 FactionTemplateEntry const* casterFaction = caster->GetFactionTemplateEntry();
5904 // Do not allow to damage GO's of friendly factions (ie: Wintergrasp Walls/Ulduar Storm Beacons)
5905 if ((casterFaction && targetFaction && !casterFaction->IsFriendlyTo(*targetFaction)) || !targetFaction)
5907}
DBCStorage< FactionTemplateEntry > sFactionTemplateStore(FactionTemplateEntryfmt)
void ModifyHealth(int32 change, Unit *attackerOrHealer=nullptr, uint32 spellId=0)
Definition: GameObject.cpp:2277
FactionTemplateEntry const * GetFactionTemplateEntry() const
Definition: Unit.cpp:9996
Definition: DBCStructure.h:939
bool IsFriendlyTo(FactionTemplateEntry const &entry) const
Definition: DBCStructure.h:951

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

◆ EffectGameObjectRepair()

void Spell::EffectGameObjectRepair ( SpellEffIndex  effIndex)

◆ EffectGameObjectSetDestructionState()

void Spell::EffectGameObjectSetDestructionState ( SpellEffIndex  effIndex)
5921{
5923 return;
5924
5926 return;
5927
5930}
GameObjectDestructibleState
Definition: SharedDefines.h:1626
void SetDestructibleState(GameObjectDestructibleState state, Player *eventInvoker=nullptr, bool setHealth=false)
Definition: GameObject.cpp:2340

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

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

◆ EffectHealMaxHealth()

void Spell::EffectHealMaxHealth ( SpellEffIndex  effIndex)
3663{
3665 return;
3666
3667 if (!unitTarget || !unitTarget->IsAlive())
3668 return;
3669
3670 int32 addhealth = 0;
3671
3672 // damage == 0 - heal for caster max health
3673 if (damage == 0)
3674 addhealth = m_caster->GetMaxHealth();
3675 else
3676 addhealth = unitTarget->GetMaxHealth() - unitTarget->GetHealth();
3677
3678 m_healing += addhealth;
3679}
uint32 GetMaxHealth() const
Definition: Unit.h:870

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)
1607{
1609 return;
1610
1611 if (!unitTarget || !unitTarget->IsAlive() || damage < 0)
1612 return;
1613
1616
1617 LOG_DEBUG("spells.aura", "HealthLeech :{}", damage);
1618
1619 // xinef: handled in spell.cpp
1620 //float healMultiplier = m_spellInfo->Effects[effIndex].CalcValueMultiplier(m_originalCaster, this);
1621
1622 m_damage += damage;
1623 // get max possible damage, don't count overkill for heal
1624 //uint32 healthGain = uint32(-unitTarget->GetHealthGain(-damage) * healMultiplier);
1625
1626 //if (m_caster->IsAlive())
1627 //{
1628 // healthGain = m_caster->SpellHealingBonusDone(m_caster, m_spellInfo, healthGain, HEAL);
1629 // healthGain = m_caster->SpellHealingBonusTaken(m_caster, m_spellInfo, healthGain, HEAL);
1630
1631 // m_caster->HealBySpell(m_caster, m_spellInfo, uint32(healthGain));
1632 //}
1633}
uint32 SpellDamageBonusTaken(Unit *caster, SpellInfo const *spellProto, uint32 pdamage, DamageEffectType damagetype, uint32 stack=1)
Definition: Unit.cpp:11748
uint32 SpellDamageBonusDone(Unit *victim, SpellInfo const *spellProto, uint32 pdamage, DamageEffectType damagetype, uint8 effIndex, float TotalMod=0.0f, uint32 stack=1)
Definition: Unit.cpp:11572

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)
4464{
4466 return;
4467
4468 if (!unitTarget)
4469 return;
4470
4471 Player* player = unitTarget->ToPlayer();
4472 if (!player)
4473 {
4474 return;
4475 }
4476
4477 uint8 currentDrunk = player->GetDrunkValue();
4478 int32 drunkMod = damage;
4479
4480 if (drunkMod == 0)
4481 return;
4482
4483 // drunkMod may contain values ​​that are guaranteed to cause uint8 overflow/underflow (examples: 29690, 46874)
4484 // In addition, we would not want currentDrunk to become more than 100.
4485 // So before adding the values, let's check that everything is fine.
4486 if (drunkMod > 0 && drunkMod > static_cast<int32>(100 - currentDrunk))
4487 currentDrunk = 100;
4488 else if (drunkMod < 0 && drunkMod < static_cast<int32>(0 - currentDrunk))
4489 currentDrunk = 0;
4490 else
4491 currentDrunk += drunkMod; // Due to previous checks we can be sure that currentDrunk will not go beyond [0-100] range.
4492
4493 player->SetDrunkValue(currentDrunk, m_CastItem ? m_CastItem->GetEntry() : 0);
4494
4495 if (currentDrunk == 100 && roll_chance_i(25))
4496 player->CastSpell(player, 67468, false); // Drunken Vomit
4497}
uint8 GetDrunkValue() const
Definition: Player.h:2151
void SetDrunkValue(uint8 newDrunkValue, uint32 itemId=0)
Definition: Player.cpp:971

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

◆ EffectInstaKill()

void Spell::EffectInstaKill ( SpellEffIndex  effIndex)
279{
281 return;
282
283 if (!unitTarget || !unitTarget->IsAlive() || unitTarget->HasAura(27827)) // Spirit of redemption doesn't make you death, but can cause infinite loops
284 return;
285
286 if (unitTarget->IsPlayer())
288 return;
289
290 if (m_caster == unitTarget) // prevent interrupt message
291 finish();
292
293 WorldPacket data(SMSG_SPELLINSTAKILLLOG, 8 + 8 + 4);
294 data << m_caster->GetGUID();
295 data << unitTarget->GetGUID();
296 data << uint32(m_spellInfo->Id);
297 m_caster->SendMessageToSet(&data, true);
298
300}
@ CHEAT_GOD
Definition: Player.h:999
@ SPELL_SCHOOL_MASK_NORMAL
Definition: SharedDefines.h:297
@ 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:811

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

◆ EffectInterruptCast()

void Spell::EffectInterruptCast ( SpellEffIndex  effIndex)
Todo:
: not all spells that used this effect apply cooldown at school spells
3682{
3684 return;
3685
3686 if (!unitTarget || !unitTarget->IsAlive())
3687 return;
3688
3690 // also exist case: apply cooldown to interrupted cast only and to all spells
3691 // there is no CURRENT_AUTOREPEAT_SPELL spells that can be interrupted
3693 {
3695 {
3696 SpellInfo const* curSpellInfo = spell->m_spellInfo;
3697 // check if we can interrupt spell
3698 if ((spell->getState() == SPELL_STATE_CASTING
3699 || (spell->getState() == SPELL_STATE_PREPARING && spell->GetCastTime() > 0.0f))
3703 {
3704 if (m_originalCaster)
3705 {
3707 unitTarget->ProhibitSpellSchool(curSpellInfo->GetSchoolMask(), duration/*spellInfo->GetDuration()*/);
3708 }
3709 ExecuteLogEffectInterruptCast(effIndex, unitTarget, curSpellInfo->Id);
3711 }
3712 }
3713 }
3714}
#define CURRENT_FIRST_NON_MELEE_SPELL
Definition: Unit.h:543
CurrentSpellTypes
Definition: Unit.h:536
@ CURRENT_CHANNELED_SPELL
Definition: Unit.h:539
@ CURRENT_AUTOREPEAT_SPELL
Definition: Unit.h:540
@ 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:4044
int32 CalcSpellDuration(SpellInfo const *spellProto)
Definition: Unit.cpp:14811
virtual void ProhibitSpellSchool(SpellSchoolMask, uint32)
Definition: Unit.h:1443
void ExecuteLogEffectInterruptCast(uint8 effIndex, Unit *victim, uint32 spellId)
Definition: Spell.cpp:5115
uint32 ChannelInterruptFlags
Definition: SpellInfo.h:354
uint32 InterruptFlags
Definition: SpellInfo.h:352

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

◆ EffectJump()

void Spell::EffectJump ( SpellEffIndex  effIndex)
1074{
1076 return;
1077
1078 if (m_caster->IsInFlight())
1079 return;
1080
1081 if (!unitTarget)
1082 return;
1083
1084 float speedXY, speedZ;
1085 CalculateJumpSpeeds(effIndex, m_caster->GetExactDist2d(unitTarget), speedXY, speedZ);
1086 m_caster->GetMotionMaster()->MoveJump(*unitTarget, speedXY, speedZ);
1087
1088 if (m_caster->IsPlayer())
1089 {
1090 sScriptMgr->AnticheatSetUnderACKmount(m_caster->ToPlayer());
1091 }
1092}
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:227
void CalculateJumpSpeeds(uint8 i, float dist, float &speedxy, float &speedz)
Definition: SpellEffects.cpp:1157

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

◆ EffectJumpDest()

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

◆ EffectKillCredit()

void Spell::EffectKillCredit ( SpellEffIndex  effIndex)
5683{
5685 return;
5686
5687 if (!unitTarget)
5688 return;
5689
5691 if (!player)
5692 {
5693 return;
5694 }
5695
5696 int32 creatureEntry = m_spellInfo->Effects[effIndex].MiscValue;
5697 if (!creatureEntry)
5698 {
5699 if (m_spellInfo->Id == 42793) // Burn Body
5700 creatureEntry = 24008; // Fallen Combatant
5701 }
5702
5703 if (creatureEntry)
5704 player->RewardPlayerAndGroupAtEvent(creatureEntry, unitTarget);
5705}
void RewardPlayerAndGroupAtEvent(uint32 creature_id, WorldObject *pRewardSource)
Definition: Player.cpp:12733

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)
5669{
5671 return;
5672
5673 if (!unitTarget)
5674 return;
5675
5677 {
5678 player->KilledMonsterCredit(m_spellInfo->Effects[effIndex].MiscValue);
5679 }
5680}

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

◆ EffectKnockBack()

void Spell::EffectKnockBack ( SpellEffIndex  effIndex)
4960{
4962 return;
4963
4964 if (!unitTarget)
4965 return;
4966
4967 // Xinef: allow entry specific spells to skip those checks
4968 if (m_spellInfo->Effects[effIndex].TargetA.GetCheckType() != TARGET_CHECK_ENTRY && m_spellInfo->Effects[effIndex].TargetB.GetCheckType() != TARGET_CHECK_ENTRY)
4969 {
4971 return;
4972
4973 if (unitTarget->GetVehicle())
4974 return;
4975
4976 if (Creature* creatureTarget = unitTarget->ToCreature())
4977 if (creatureTarget->isWorldBoss() || creatureTarget->IsDungeonBoss() || creatureTarget->IsImmuneToKnockback() || unitTarget->ToCreature()->GetCreatureType() == CREATURE_TYPE_GIANT)
4978 return;
4979 }
4980
4981 // Spells with SPELL_EFFECT_KNOCK_BACK(like Thunderstorm) can't knoback target if target has ROOT
4983 return;
4984
4985 // Instantly interrupt non melee spells being casted
4988
4989 float ratio = 0.1f;
4990 float speedxy = float(m_spellInfo->Effects[effIndex].MiscValue) * ratio;
4991 float speedz = float(damage) * ratio;
4992 if (speedxy <= 0.1f && speedz <= 0.1f)
4993 return;
4994
4995 float x, y;
4996 if (m_spellInfo->Effects[effIndex].Effect == SPELL_EFFECT_KNOCK_BACK_DEST)
4997 {
4998 if (m_targets.HasDst())
4999 destTarget->GetPosition(x, y);
5000 else
5001 return;
5002 }
5003 else //if (m_spellInfo->Effects[i].Effect == SPELL_EFFECT_KNOCK_BACK)
5004 {
5005 m_caster->GetPosition(x, y);
5006 }
5007
5008 unitTarget->KnockbackFrom(x, y, speedxy, speedz);
5009
5010 if (unitTarget->IsPlayer())
5011 {
5012 sScriptMgr->AnticheatSetUnderACKmount(unitTarget->ToPlayer());
5013 }
5014}
@ SPELL_EFFECT_KNOCK_BACK_DEST
Definition: SharedDefines.h:922
@ CREATURE_TYPE_GIANT
Definition: SharedDefines.h:2632
@ CREATURE_TYPE_BEAST
Definition: SharedDefines.h:2628
void InterruptNonMeleeSpells(bool withDelayed, uint32 spellid=0, bool withInstant=true, bool bySelf=false)
Definition: Unit.cpp:4111
uint32 GetCreatureType() const
Definition: Unit.cpp:15137
void KnockbackFrom(float x, float y, float speedXY, float speedZ)
Definition: Unit.cpp:19099

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

◆ EffectLeap()

void Spell::EffectLeap ( SpellEffIndex  effIndex)
4686{
4688 return;
4689
4690 if (!unitTarget || unitTarget->IsInFlight())
4691 return;
4692
4693 if (!m_targets.HasDst())
4694 return;
4695
4696 Position dstpos = destTarget->GetPosition();
4698}
void NearTeleportTo(Position &pos, bool casting=false, bool vehicleTeleport=false, bool withPet=false, bool removeTransport=false)
Definition: Unit.cpp:19937

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)
5017{
5019 return;
5020
5021 if (!unitTarget)
5022 return;
5023
5024 float speedxy = m_spellInfo->Effects[effIndex].MiscValue / 10.0f;
5025 float speedz = damage / 10.0f;
5026 //1891: Disengage
5028
5029 if (m_caster->IsPlayer())
5030 {
5031 sScriptMgr->AnticheatSetUnderACKmount(m_caster->ToPlayer());
5032 }
5033
5034 // xinef: changes fall time
5035 if (m_caster->IsPlayer())
5037}
@ SPELLFAMILY_HUNTER
Definition: SharedDefines.h:3537
void JumpTo(float speedXY, float speedZ, bool forward=true)
Definition: Unit.cpp:19470

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

◆ EffectLearnPetSpell()

void Spell::EffectLearnPetSpell ( SpellEffIndex  effIndex)
3233{
3235 return;
3236
3237 if (!unitTarget)
3238 return;
3239
3240 if (unitTarget->ToPlayer())
3241 {
3242 EffectLearnSpell(effIndex);
3243 return;
3244 }
3245 Pet* pet = unitTarget->ToPet();
3246 if (!pet)
3247 return;
3248
3249 SpellInfo const* learn_spellproto = sSpellMgr->GetSpellInfo(m_spellInfo->Effects[effIndex].TriggerSpell);
3250 if (!learn_spellproto)
3251 return;
3252
3253 pet->learnSpell(learn_spellproto->Id);
3255 pet->GetOwner()->PetSpellInitialize();
3256}
bool learnSpell(uint32 spell_id)
Definition: Pet.cpp:1912
void EffectLearnSpell(SpellEffIndex effIndex)
Definition: SpellEffects.cpp:2519

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)
2750{
2752 return;
2753
2754 if (!unitTarget->IsPlayer())
2755 return;
2756
2757 if (damage < 0)
2758 return;
2759
2760 uint32 skillid = m_spellInfo->Effects[effIndex].MiscValue;
2761 uint16 skillval = unitTarget->ToPlayer()->GetPureSkillValue(skillid);
2762 unitTarget->ToPlayer()->SetSkill(skillid, m_spellInfo->Effects[effIndex].CalcValue(), skillval ? skillval : 1, damage * 75);
2763}
uint16 GetPureSkillValue(uint32 skill) const
Definition: Player.cpp:5502
void SetSkill(uint16 id, uint16 step, uint16 currVal, uint16 maxVal)
Definition: Player.cpp:5316

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

◆ EffectLearnSpell()

void Spell::EffectLearnSpell ( SpellEffIndex  effIndex)
2520{
2522 return;
2523
2524 if (!unitTarget)
2525 return;
2526
2527 if (!unitTarget->IsPlayer())
2528 {
2529 if (unitTarget->ToPet())
2530 EffectLearnPetSpell(effIndex);
2531 return;
2532 }
2533
2534 Player* player = unitTarget->ToPlayer();
2535
2536 uint32 spellToLearn = (m_spellInfo->Id == 483 || m_spellInfo->Id == 55884) ? damage : m_spellInfo->Effects[effIndex].TriggerSpell;
2537 player->learnSpell(spellToLearn);
2538
2539 LOG_DEBUG("spells.aura", "Spell: Player {} has learned spell {} from Npc {}",
2540 player->GetGUID().ToString(), spellToLearn, m_caster->GetGUID().ToString());
2541}
void learnSpell(uint32 spellId, bool temporary=false, bool learnFromSkill=false)
Definition: Player.cpp:3271
void EffectLearnPetSpell(SpellEffIndex effIndex)
Definition: SpellEffects.cpp:3232

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

Referenced by EffectLearnPetSpell().

◆ EffectMilling()

void Spell::EffectMilling ( SpellEffIndex  effIndex)
5496{
5498 return;
5499
5500 if (!m_caster->IsPlayer())
5501 return;
5502
5503 Player* p_caster = m_caster->ToPlayer();
5505 return;
5506
5507 if (itemTarget->GetCount() < 5)
5508 return;
5509
5510 if (sWorld->getBoolConfig(CONFIG_SKILL_MILLING))
5511 {
5512 uint32 SkillValue = p_caster->GetPureSkillValue(SKILL_INSCRIPTION);
5513 uint32 reqSkillValue = itemTarget->GetTemplate()->RequiredSkillRank;
5514 p_caster->UpdateGatherSkill(SKILL_INSCRIPTION, SkillValue, reqSkillValue);
5515 }
5516
5518}
@ LOOT_MILLING
Definition: LootMgr.h:88
@ CONFIG_SKILL_MILLING
Definition: IWorld.h:97
void SendLoot(ObjectGuid guid, LootType loot_type)
Definition: Player.cpp:7773
bool UpdateGatherSkill(uint32 SkillId, uint32 SkillValue, uint32 RedLevel, uint32 Multiplicator=1)
Definition: PlayerUpdates.cpp:719

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

◆ EffectModifyThreatPercent()

void Spell::EffectModifyThreatPercent ( SpellEffIndex  effIndex)
5329{
5331 return;
5332
5333 if (!unitTarget)
5334 return;
5335
5337}
void ModifyThreatByPercent(Unit *victim, int32 percent)
Definition: ThreatMgr.cpp:508
ThreatMgr & GetThreatMgr()
Definition: Unit.h:839

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

◆ EffectNULL()

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

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
2064{
2066 return;
2067
2068 if (!m_caster->IsPlayer())
2069 {
2070 LOG_DEBUG("spells.aura", "WORLD: Open Lock - No Player Caster!");
2071 return;
2072 }
2073
2074 Player* player = m_caster->ToPlayer();
2075
2076 uint32 lockId = 0;
2077 ObjectGuid guid;
2078
2079 // Get lockId
2080 if (gameObjTarget)
2081 {
2082 GameObjectTemplate const* goInfo = gameObjTarget->GetGOInfo();
2083 // Arathi Basin banner opening. /// @todo: Verify correctness of this check
2084 if ((goInfo->type == GAMEOBJECT_TYPE_BUTTON && goInfo->button.noDamageImmune) ||
2085 (goInfo->type == GAMEOBJECT_TYPE_GOOBER && goInfo->goober.losOK))
2086 {
2087 //CanUseBattlegroundObject() already called in CheckCast()
2088 // in battleground check
2089 if (Battleground* bg = player->GetBattleground())
2090 {
2091 bg->EventPlayerClickedOnFlag(player, gameObjTarget);
2092 return;
2093 }
2094 }
2095 else if (goInfo->type == GAMEOBJECT_TYPE_FLAGSTAND)
2096 {
2097 //CanUseBattlegroundObject() already called in CheckCast()
2098 // in battleground check
2099 if (Battleground* bg = player->GetBattleground())
2100 {
2101 if (bg->GetBgTypeID(true) == BATTLEGROUND_EY)
2102 bg->EventPlayerClickedOnFlag(player, gameObjTarget);
2103 return;
2104 }
2105 }
2106 else if (m_spellInfo->Id == 1842 && gameObjTarget->GetGOInfo()->type == GAMEOBJECT_TYPE_TRAP)
2107 {
2110 {
2112 }
2113 return;
2114 }
2116 // handle outdoor pvp object opening, return true if go was registered for handling
2117 // these objects must have been spawned by outdoorpvp!
2118 else if (gameObjTarget->GetGOInfo()->type == GAMEOBJECT_TYPE_GOOBER && sOutdoorPvPMgr->HandleOpenGo(player, gameObjTarget))
2119 return;
2120 lockId = goInfo->GetLockId();
2121 guid = gameObjTarget->GetGUID();
2122 }
2123 else if (itemTarget)
2124 {
2125 lockId = itemTarget->GetTemplate()->LockID;
2126 guid = itemTarget->GetGUID();
2127 }
2128 else
2129 {
2130 LOG_DEBUG("spells.aura", "WORLD: Open Lock - No GameObject/Item Target!");
2131 return;
2132 }
2133
2134 SkillType skillId = SKILL_NONE;
2135 int32 reqSkillValue = 0;
2136 int32 skillValue;
2137
2138 SpellCastResult res = CanOpenLock(effIndex, lockId, skillId, reqSkillValue, skillValue);
2139 if (res != SPELL_CAST_OK)
2140 {
2141 SendCastResult(res);
2142 return;
2143 }
2144
2145 if (gameObjTarget)
2146 SendLoot(guid, LOOT_SKINNING);
2147 else if (itemTarget)
2148 {
2150 if (Player* itemOwner = itemTarget->GetOwner())
2151 itemTarget->SetState(ITEM_CHANGED, itemOwner);
2152 }
2153
2154 // not allow use skill grow at item base open
2155 if (!m_CastItem && skillId != SKILL_NONE)
2156 {
2157 // update skill if really known
2158 if (uint32 pureSkillValue = player->GetPureSkillValue(skillId))
2159 {
2160 if (gameObjTarget)
2161 {
2162 // Allow one skill-up until respawned
2163 if (!gameObjTarget->IsInSkillupList(player->GetGUID()))
2164 {
2166 player->UpdateGatherSkill(skillId, pureSkillValue, reqSkillValue);
2167 }
2168
2169 }
2170 else if (itemTarget)
2171 {
2172 // Do one skill-up
2173 player->UpdateGatherSkill(skillId, pureSkillValue, reqSkillValue);
2174 }
2175 }
2176 }
2178}
#define sOutdoorPvPMgr
Definition: OutdoorPvPMgr.h:103
@ LOOT_SKINNING
Definition: LootMgr.h:86
@ ITEM_FIELD_FLAGS
Definition: UpdateFields.h:42
@ GO_JUST_DEACTIVATED
Definition: GameObject.h:114
@ ITEM_FIELD_FLAG_UNLOCKED
Definition: ItemTemplate.h:111
@ ITEM_CHANGED
Definition: Item.h:210
@ GAMEOBJECT_TYPE_BUTTON
Definition: SharedDefines.h:1561
@ GAMEOBJECT_TYPE_FLAGSTAND
Definition: SharedDefines.h:1584
@ GAMEOBJECT_TYPE_GOOBER
Definition: SharedDefines.h:1570
@ BATTLEGROUND_EY
Definition: SharedDefines.h:3487
Unit * GetOwner() const
Definition: GameObject.cpp:1238
void AddToSkillupList(ObjectGuid playerGuid)
Definition: GameObject.cpp:3068
bool IsInSkillupList(ObjectGuid playerGuid) const
Definition: GameObject.cpp:3074
LootState getLootState() const
Definition: GameObject.h:225
void SetLootState(LootState s, Unit *unit=nullptr)
Definition: GameObject.cpp:2442
Definition: GameObjectData.h:32
uint32 GetAutoCloseTime() const
Definition: GameObjectData.h:511
uint32 noDamageImmune
Definition: GameObjectData.h:49
struct GameObjectTemplate::@227::@230 button
uint32 losOK
Definition: GameObjectData.h:65
struct GameObjectTemplate::@227::@238 goober
uint32 GetLockId() const
Definition: GameObjectData.h:428
void SetState(ItemUpdateState state, Player *forplayer=nullptr)
Definition: Item.cpp:715
Definition: Object.h:100
void ExecuteLogEffectOpenLock(uint8 effIndex, Object *obj)
Definition: Spell.cpp:5130
void SendLoot(ObjectGuid guid, LootType loottype)
Definition: SpellEffects.cpp:1997

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

◆ EffectParry()

void Spell::EffectParry ( SpellEffIndex  effIndex)
4668{
4670 return;
4671
4672 if (m_caster->IsPlayer())
4673 m_caster->ToPlayer()->SetCanParry(true);
4674}
void SetCanParry(bool value)
Definition: Player.cpp:13124

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

◆ EffectPersistentAA()

void Spell::EffectPersistentAA ( SpellEffIndex  effIndex)
1833{
1835 return;
1836
1837 if (!m_spellAura)
1838 {
1840 float radius = m_spellInfo->Effects[effIndex].CalcRadius(caster);
1841
1842 // Caster not in world, might be spell triggered from aura removal
1843 if (!caster->IsInWorld() || !caster->FindMap() || !ObjectAccessor::GetUnit(*caster, caster->GetGUID())) // pussywizard: temporary crash fix (FindMap and GetUnit are mine)
1844 return;
1845 DynamicObject* dynObj = new DynamicObject(false);
1846 if (!dynObj->CreateDynamicObject(caster->GetMap()->GenerateLowGuid<HighGuid::DynamicObject>(), caster, m_spellInfo->Id, *destTarget, radius, DYNAMIC_OBJECT_AREA_SPELL))
1847 {
1848 delete dynObj;
1849 return;
1850 }
1851
1853 {
1854 m_spellAura = aura;
1857 }
1858 else
1859 return;
1860 }
1861
1864}
@ DYNAMIC_OBJECT_AREA_SPELL
Definition: DynamicObject.h:30
#define MAX_EFFECT_MASK
Definition: DBCStructure.h:1638
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)
6082{
6084 return;
6085
6086 if (!unitTarget)
6087 return;
6088
6089 Player* player = unitTarget->ToPlayer();
6090 if (!player)
6091 {
6092 return;
6093 }
6094
6095 uint32 soundid = m_spellInfo->Effects[effIndex].MiscValue;
6096
6097 if (!sSoundEntriesStore.LookupEntry(soundid))
6098 {
6099 LOG_ERROR("spells.effect", "EffectPlayMusic: Sound (Id: {}) not exist in spell {}.", soundid, m_spellInfo->Id);
6100 return;
6101 }
6102
6104}
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)
6135{
6137 return;
6138
6139 if (!unitTarget)
6140 return;
6141
6142 Player* player = unitTarget->ToPlayer();
6143 if (!player)
6144 {
6145 return;
6146 }
6147
6148 switch (m_spellInfo->Id)
6149 {
6150 case 58730: // Restricted Flight Area
6151 case 58600: // Restricted Flight Area
6153 break;
6154 default:
6155 break;
6156 }
6157
6158 uint32 soundId = m_spellInfo->Effects[effIndex].MiscValue;
6159
6160 if (!sSoundEntriesStore.LookupEntry(soundId))
6161 {
6162 LOG_ERROR("spells.effect", "EffectPlayerSound: Sound (Id: {}) not exist in spell {}.", soundId, m_spellInfo->Id);
6163 return;
6164 }
6165
6166 player->PlayDirectSound(soundId, player);
6167}
@ LANG_ZONE_NOFLYZONE
Definition: Language.h:753
Definition: Chat.h:39
void SendNotification(std::string_view str)
Definition: Chat.cpp:107
void PlayDirectSound(uint32 sound_id, Player *target=nullptr)
Definition: Object.cpp:2890

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

◆ EffectPowerBurn()

void Spell::EffectPowerBurn ( SpellEffIndex  effIndex)
1419{
1421 return;
1422
1423 if (m_spellInfo->Effects[effIndex].MiscValue < 0 || m_spellInfo->Effects[effIndex].MiscValue >= int8(MAX_POWERS))
1424 return;
1425
1426 Powers PowerType = Powers(m_spellInfo->Effects[effIndex].MiscValue);
1427
1429 return;
1430
1431 // burn x% of target's mana, up to maximum of 2x% of caster's mana (Mana Burn)
1432 if (m_spellInfo->Id == 8129)
1433 {
1436 damage = std::min(damage, maxDamage);
1437
1438 // Remove fear
1440 }
1441
1442 int32 power = damage;
1443 // resilience reduce mana draining effect at spell crit damage reduction (added in 2.4)
1444 if (PowerType == POWER_MANA)
1445 power -= unitTarget->GetSpellCritDamageReduction(power);
1446
1447 int32 newDamage = -(unitTarget->ModifyPower(PowerType, -power));
1448
1449 // NO - Not a typo - EffectPowerBurn uses effect value multiplier - not effect damage multiplier
1450 float dmgMultiplier = m_spellInfo->Effects[effIndex].CalcValueMultiplier(m_originalCaster, this);
1451
1452 // add log data before multiplication (need power amount, not damage)
1453 ExecuteLogEffectTakeTargetPower(effIndex, unitTarget, PowerType, newDamage, 0.0f);
1454
1455 newDamage = int32(newDamage * dmgMultiplier);
1456
1457 m_damage += newDamage;
1458}
int32 ModifyPower(Powers power, int32 val, bool withPowerUpdate=true)
Definition: Unit.cpp:14106
uint32 GetSpellCritDamageReduction(uint32 damage) const
Definition: Unit.h:1034
void ExecuteLogEffectTakeTargetPower(uint8 effIndex, Unit *target, uint32 PowerType, uint32 powerTaken, float gainMultiplier)
Definition: Spell.cpp:5099

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

◆ EffectPowerDrain()

void Spell::EffectPowerDrain ( SpellEffIndex  effIndex)
1340{
1342 return;
1343
1344 if (m_spellInfo->Effects[effIndex].MiscValue < 0 || m_spellInfo->Effects[effIndex].MiscValue >= int8(MAX_POWERS))
1345 return;
1346
1347 Powers PowerType = Powers(m_spellInfo->Effects[effIndex].MiscValue);
1348
1350 return;
1351
1352 // add spell damage bonus
1355
1356 // resilience reduce mana draining effect at spell crit damage reduction (added in 2.4)
1357 int32 power = damage;
1358 if (PowerType == POWER_MANA)
1359 power -= unitTarget->GetSpellCritDamageReduction(power);
1360
1361 int32 newDamage = -(unitTarget->ModifyPower(PowerType, -int32(power)));
1362
1363 float gainMultiplier = 0.0f;
1364
1365 // Don`t restore from self drain
1366 if (m_caster != unitTarget)
1367 {
1368 gainMultiplier = m_spellInfo->Effects[effIndex].CalcValueMultiplier(m_originalCaster, this);
1369
1370 int32 gain = int32(newDamage * gainMultiplier);
1371
1373 }
1374 ExecuteLogEffectTakeTargetPower(effIndex, unitTarget, PowerType, newDamage, gainMultiplier);
1375}

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

◆ EffectProficiency()

void Spell::EffectProficiency ( SpellEffIndex  effIndex)
2290{
2292 return;
2293
2294 if (!m_caster->IsPlayer())
2295 return;
2296 Player* p_target = m_caster->ToPlayer();
2297
2299 if (m_spellInfo->EquippedItemClass == ITEM_CLASS_WEAPON && !(p_target->GetWeaponProficiency() & subClassMask))
2300 {
2301 p_target->AddWeaponProficiency(subClassMask);
2303 }
2304 if (m_spellInfo->EquippedItemClass == ITEM_CLASS_ARMOR && !(p_target->GetArmorProficiency() & subClassMask))
2305 {
2306 p_target->AddArmorProficiency(subClassMask);
2308 }
2309}
uint32 GetArmorProficiency() const
Definition: Player.h:1353
void SendProficiency(ItemClass itemClass, uint32 itemSubclassMask)
Definition: Player.cpp:10101
uint32 GetWeaponProficiency() const
Definition: Player.h:1352
void AddArmorProficiency(uint32 newflag)
Definition: Player.h:1351
void AddWeaponProficiency(uint32 newflag)
Definition: Player.h:1350
int32 EquippedItemSubClassMask
Definition: SpellInfo.h:376

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

◆ EffectProspecting()

void Spell::EffectProspecting ( SpellEffIndex  effIndex)

◆ EffectPull()

void Spell::EffectPull ( SpellEffIndex  effIndex)
Todo:
: create a proper pull towards distract spell center for distract
2662{
2664 EffectNULL(effIndex);
2665}
void EffectNULL(SpellEffIndex effIndex)
Definition: SpellEffects.cpp:242

References EffectNULL().

◆ EffectPullTowards()

void Spell::EffectPullTowards ( SpellEffIndex  effIndex)
5102{
5104 return;
5105
5106 if (!unitTarget)
5107 return;
5108
5109 Position pos;
5110 if (m_spellInfo->Effects[effIndex].Effect == SPELL_EFFECT_PULL_TOWARDS_DEST)
5111 {
5112 if (m_targets.HasDst())
5113 pos.Relocate(*destTarget);
5114 else
5115 return;
5116 }
5117 else //if (m_spellInfo->Effects[i].Effect == SPELL_EFFECT_PULL_TOWARDS)
5118 {
5119 // Xinef: Increase Z position a little bit, should protect from falling through textures
5121 }
5122
5123 float speedXY = float(m_spellInfo->Effects[effIndex].MiscValue) ? float(m_spellInfo->Effects[effIndex].MiscValue) * 0.1f : 30.f;
5124 float speedZ = unitTarget->GetDistance(pos) / speedXY * 0.5f * Movement::gravity;
5125
5126 unitTarget->GetMotionMaster()->MoveJump(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), speedXY, speedZ);
5127
5128 if (unitTarget->IsPlayer())
5129 {
5130 sScriptMgr->AnticheatSetUnderACKmount(unitTarget->ToPlayer());
5131 }
5132}
@ SPELL_EFFECT_PULL_TOWARDS_DEST
Definition: SharedDefines.h:923
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(), Movement::gravity, SpellCastTargets::HasDst(), Object::IsPlayer(), m_caster, m_spellInfo, m_targets, MotionMaster::MoveJump(), Position::Relocate(), SPELL_EFFECT_HANDLE_HIT_TARGET, SPELL_EFFECT_PULL_TOWARDS_DEST, sScriptMgr, Object::ToPlayer(), and unitTarget.

◆ EffectQuestClear()

void Spell::EffectQuestClear ( SpellEffIndex  effIndex)
5040{
5042 return;
5043
5044 if (!unitTarget)
5045 return;
5046
5047 Player* player = unitTarget->ToPlayer();
5048 if (!player)
5049 {
5050 return;
5051 }
5052
5053 uint32 quest_id = m_spellInfo->Effects[effIndex].MiscValue;
5054
5055 Quest const* quest = sObjectMgr->GetQuestTemplate(quest_id);
5056
5057 if (!quest)
5058 return;
5059
5060 // Player has never done this quest
5061 if (player->GetQuestStatus(quest_id) == QUEST_STATUS_NONE)
5062 return;
5063
5064 // remove all quest entries for 'entry' from quest log
5065 for (uint8 slot = 0; slot < MAX_QUEST_LOG_SIZE; ++slot)
5066 {
5067 uint32 logQuest = player->GetQuestSlotQuestId(slot);
5068 if (logQuest == quest_id)
5069 {
5070 player->SetQuestSlot(slot, 0);
5071
5072 // we ignore unequippable quest items in this case, it's still be equipped
5073 player->TakeQuestSourceItem(logQuest, false);
5074
5075 if (quest->HasFlag(QUEST_FLAGS_FLAGS_PVP))
5076 {
5077 player->pvpInfo.IsHostile = player->pvpInfo.IsInHostileArea || player->HasPvPForcingQuest();
5078 player->UpdatePvPState();
5079 }
5080 }
5081 }
5082
5083 player->RemoveRewardedQuest(quest_id);
5084 player->RemoveActiveQuest(quest_id, false);
5085}
@ 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:360
bool IsInHostileArea
Definition: Player.h:361
bool HasPvPForcingQuest() const
Definition: PlayerQuest.cpp:2489
void UpdatePvPState()
Definition: PlayerUpdates.cpp:1390
uint32 GetQuestSlotQuestId(uint16 slot) const
Definition: Player.h:1474
void SetQuestSlot(uint16 slot, uint32 quest_id, uint32 timer=0)
Definition: Player.h:1478
PvPInfo pvpInfo
Definition: Player.h:1827
bool TakeQuestSourceItem(uint32 questId, bool msg)
Definition: PlayerQuest.cpp:1357
void RemoveActiveQuest(uint32 questId, bool update=true)
Definition: PlayerQuest.cpp:1489
QuestStatus GetQuestStatus(uint32 quest_id) const
Definition: PlayerQuest.cpp:1424
void RemoveRewardedQuest(uint32 questId, bool update=true)
Definition: PlayerQuest.cpp:1507
Definition: QuestDef.h:210
bool HasFlag(uint32 flag) const
Definition: QuestDef.h:221

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

◆ EffectQuestComplete()

void Spell::EffectQuestComplete ( SpellEffIndex  effIndex)
4727{
4729 return;
4730
4731 if (!unitTarget)
4732 return;
4733
4734 Player* player = unitTarget->ToPlayer();
4735 if (!player)
4736 {
4737 return;
4738 }
4739
4740 uint32 questId = m_spellInfo->Effects[effIndex].MiscValue;
4741 if (questId)
4742 {
4743 Quest const* quest = sObjectMgr->GetQuestTemplate(questId);
4744 if (!quest)
4745 return;
4746
4747 uint16 logSlot = player->FindQuestSlot(questId);
4748 if (logSlot < MAX_QUEST_LOG_SIZE)
4749 player->AreaExploredOrEventHappens(questId);
4750 else if (player->CanTakeQuest(quest, false)) // never rewarded before
4751 player->CompleteQuest(questId); // quest not in log - for internal use
4752 }
4753}
uint16 FindQuestSlot(uint32 quest_id) const
Definition: PlayerQuest.cpp:1776
bool CanTakeQuest(Quest const *quest, bool msg)
Definition: PlayerQuest.cpp:251
void CompleteQuest(uint32 quest_id)
Definition: PlayerQuest.cpp:597
void AreaExploredOrEventHappens(uint32 questId)
Definition: PlayerQuest.cpp:1785

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)
5708{
5710 return;
5711
5712 if (!unitTarget)
5713 return;
5714
5715 if (Player* player = unitTarget->ToPlayer())
5716 {
5717 player->FailQuest(m_spellInfo->Effects[effIndex].MiscValue);
5718 }
5719}

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

◆ EffectQuestStart()

void Spell::EffectQuestStart ( SpellEffIndex  effIndex)
5722{
5724 return;
5725
5726 if (!unitTarget)
5727 return;
5728
5729 Player* player = unitTarget->ToPlayer();
5730 if (!player)
5731 return;
5732
5733 if (Quest const* quest = sObjectMgr->GetQuestTemplate(m_spellInfo->Effects[effIndex].MiscValue))
5734 {
5735 if (!player->CanTakeQuest(quest, false))
5736 return;
5737
5738 if (quest->IsAutoAccept() && player->CanAddQuest(quest, false))
5739 player->AddQuestAndCheckCompletion(quest, player);
5740
5741 player->PlayerTalkClass->SendQuestGiverQuestDetails(quest, player->GetGUID(), true);
5742 }
5743}
void SendQuestGiverQuestDetails(Quest const *quest, ObjectGuid npcGUID, bool activateAccept) const
Definition: GossipDef.cpp:388
bool CanAddQuest(Quest const *quest, bool msg)
Definition: PlayerQuest.cpp:264
void AddQuestAndCheckCompletion(Quest const *quest, Object *questGiver)
Definition: PlayerQuest.cpp:420
PlayerMenu * PlayerTalkClass
Definition: Player.h:2219

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)
6224{
6226 return;
6227
6228 if (!unitTarget || !unitTarget->IsPlayer())
6229 return;
6230
6231 Player* player = m_caster->ToPlayer();
6232
6233 if (!player)
6234 return;
6235
6236 uint32 item_id = m_spellInfo->Effects[EFFECT_0].ItemType;
6237
6238 ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(item_id);
6239 if (!pProto)
6240 {
6241 player->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, nullptr, nullptr);
6242 return;
6243 }
6244
6245 if (Item* pItem = player->GetItemByEntry(item_id))
6246 {
6247 for (int x = 0; x < MAX_ITEM_PROTO_SPELLS; ++x)
6248 pItem->SetSpellCharges(x, pProto->Spells[x].SpellCharges);
6249 pItem->SetState(ITEM_CHANGED, player);
6250 }
6251}

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

◆ EffectRedirectThreat()

void Spell::EffectRedirectThreat ( SpellEffIndex  effIndex)
5882{
5884 return;
5885
5886 if (unitTarget)
5888}
void SetRedirectThreat(ObjectGuid guid, uint32 pct)
Definition: Unit.h:846

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

◆ EffectRemoveAura()

void Spell::EffectRemoveAura ( SpellEffIndex  effIndex)
6170{
6172 return;
6173
6174 if (!unitTarget)
6175 return;
6176 // there may be need of specifying casterguid of removed auras
6177 unitTarget->RemoveAurasDueToSpell(m_spellInfo->Effects[effIndex].TriggerSpell);
6178}

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

◆ EffectRenamePet()

void Spell::EffectRenamePet ( SpellEffIndex  effIndex)
6070{
6072 return;
6073
6074 if (!unitTarget || !unitTarget->IsCreature() ||
6076 return;
6077
6079}
@ UNIT_CAN_BE_RENAMED
Definition: UnitDefines.h:128
@ UNIT_FIELD_BYTES_2
Definition: UpdateFields.h:161
void SetByteFlag(uint16 index, uint8 offset, uint8 newFlag)
Definition: Object.cpp:911
PetType getPetType() const
Definition: Pet.h:52

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

◆ EffectReputation()

void Spell::EffectReputation ( SpellEffIndex  effIndex)
4701{
4703 return;
4704
4705 if (!unitTarget)
4706 return;
4707
4708 Player* player = unitTarget->ToPlayer();
4709 if (!player)
4710 {
4711 return;
4712 }
4713
4714 float repChange = static_cast<float>(damage);
4715
4716 uint32 factionId = m_spellInfo->Effects[effIndex].MiscValue;
4717
4718 FactionEntry const* factionEntry = sFactionStore.LookupEntry(factionId);
4719 if (!factionEntry)
4720 return;
4721
4722 repChange = player->CalculateReputationGain(REPUTATION_SOURCE_SPELL, 0, repChange, factionId);
4723 player->GetReputationMgr().ModifyReputation(factionEntry, repChange);
4724}
DBCStorage< FactionEntry > sFactionStore(FactionEntryfmt)
@ REPUTATION_SOURCE_SPELL
Definition: Player.h:245
float CalculateReputationGain(ReputationSource source, uint32 creatureOrQuestLevel, float rep, int32 faction, bool noQuestBonus=false)
Definition: Player.cpp:5869
ReputationMgr & GetReputationMgr()
Definition: Player.h:2105
bool ModifyReputation(FactionEntry const *factionEntry, float standing, bool noSpillOver=false, Optional< ReputationRank > repMaxCap={})
Definition: ReputationMgr.h:118
Definition: DBCStructure.h:907

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

◆ EffectResurrect()

void Spell::EffectResurrect ( SpellEffIndex  effIndex)
4619{
4621 return;
4622
4623 if (!unitTarget)
4624 return;
4625
4626 if (!unitTarget)
4627 return;
4628
4629 Player* target = unitTarget->ToPlayer();
4630 if (!target)
4631 {
4632 return;
4633 }
4634
4635 if (unitTarget->IsAlive() || !unitTarget->IsInWorld())
4636 return;
4637
4638 if (target->isResurrectRequested()) // already have one active request
4639 return;
4640
4641 uint32 health = target->CountPctFromMaxHealth(damage);
4643
4644 ExecuteLogEffectResurrect(effIndex, target);
4645
4647 SendResurrectRequest(target);
4648}
void setResurrectRequestData(ObjectGuid guid, uint32 mapId, float X, float Y, float Z, uint32 health, uint32 mana)
Definition: Player.h:1796
bool isResurrectRequested() const
Definition: Player.h:1808
void ExecuteLogEffectResurrect(uint8 effIndex, Unit *target)
Definition: Spell.cpp:5160
void SendResurrectRequest(Player *target)
Definition: Spell.cpp:5222

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
5178{
5180 return;
5181
5182 if (damage < 0)
5183 return;
5184
5185 Player* player = m_caster->ToPlayer();
5186 if (!player)
5187 {
5188 return;
5189 }
5190
5191 Pet* pet = player->GetPet();
5192 if (!pet)
5193 {
5194 // Position passed to SummonPet is irrelevant with current implementation,
5195 // pet will be relocated without using these coords in Pet::LoadPetFromDB
5196 player->SummonPet(0, 0.0f, 0.0f, 0.0f, 0.0f, SUMMON_PET, 0s, damage);
5197 return;
5198 }
5199
5201 if (pet->IsAlive())
5202 {
5203 return;
5204 }
5205
5206 // Reposition the pet's corpse before reviving so as not to grab aggro
5207 // We can use a different, more accurate version of GetClosePoint() since we have a pet
5208 float x, y, z; // Will be used later to reposition the pet if we have one
5209 player->GetClosePoint(x, y, z, pet->GetCombatReach(), PET_FOLLOW_DIST, pet->GetFollowAngle());
5210 pet->NearTeleportTo(x, y, z, player->GetOrientation());
5211 pet->Relocate(x, y, z, player->GetOrientation()); // This is needed so SaveStayPosition() will get the proper coords.
5214 pet->setDeathState(DeathState::Alive);
5215 pet->ClearUnitState(uint32(UNIT_STATE_ALL_STATE & ~(UNIT_STATE_POSSESSED))); // xinef: just in case
5217 pet->SetDisplayId(pet->GetNativeDisplayId());
5218
5219 // xinef: restore movement
5220 if (auto ci = pet->GetCharmInfo())
5221 {
5222 ci->SetIsAtStay(false);
5223 ci->SetIsFollowing(false);
5224 }
5225
5227}
@ UNIT_STATE_POSSESSED
Definition: UnitDefines.h:165
@ UNIT_STATE_ALL_STATE
Definition: UnitDefines.h:199
#define PET_FOLLOW_DIST
Definition: PetDefines.h:198
@ SUMMON_PET
Definition: PetDefines.h:31
@ UNIT_DYNFLAG_NONE
Definition: SharedDefines.h:3120
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:2699
void setDeathState(DeathState s, bool despawn=false) override
A creature can be in 4 different states: Alive, JustDied, Corpse, and JustRespawned....
Definition: Pet.cpp:631
void SetDisplayId(uint32 modelId, float displayScale=1.f) override
Definition: Pet.cpp:2421
Pet * SummonPet(uint32 entry, float x, float y, float z, float ang, PetType petType, Milliseconds duration=0s, uint32 healthPct=0)
Definition: Player.cpp:8929
void ReplaceAllDynamicFlags(uint32 flag) override
Definition: Unit.h:700
void SetHealth(uint32 val)
Definition: Unit.cpp:15433
uint32 GetNativeDisplayId() const
Definition: Unit.h:1509
void RemoveUnitFlag(UnitFlags flags)
UnitFlags available in UnitDefines.h.
Definition: Unit.h:684

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

◆ EffectSanctuary()

void Spell::EffectSanctuary ( SpellEffIndex  effIndex)
4003{
4005 return;
4006
4007 if (!unitTarget)
4008 return;
4009
4011 {
4013 // Xinef: replaced with CombatStop(false)
4016
4017 // Night Elf: Shadowmeld only resets threat temporarily
4018 if (m_spellInfo->Id != 59646)
4020
4021 if (unitTarget->IsPlayer())
4022 unitTarget->ToPlayer()->SendAttackSwingCancelAttack(); // melee and ranged forced attack cancel
4023 }
4024 else
4025 {
4026 unitTarget->getHostileRefMgr().UpdateVisibility(m_spellInfo->Id == 59646); // Night Elf: Shadowmeld
4027 unitTarget->CombatStop(true);
4028 }
4029
4030 UnitList targets;
4031 Acore::AnyUnfriendlyUnitInObjectRangeCheck u_check(unitTarget, unitTarget, unitTarget->GetVisibilityRange()); // no VISIBILITY_COMPENSATION, distance is enough
4034 for (UnitList::iterator iter = targets.begin(); iter != targets.end(); ++iter)
4035 {
4036 if (!(*iter)->HasUnitState(UNIT_STATE_CASTING))
4037 continue;
4038
4040 {
4041 if ((*iter)->GetCurrentSpell(i) && (*iter)->GetCurrentSpell(i)->m_targets.GetUnitTargetGUID() == unitTarget->GetGUID())
4042 {
4043 SpellInfo const* si = (*iter)->GetCurrentSpell(i)->GetSpellInfo();
4044 if (si->HasAttribute(SPELL_ATTR6_IGNORE_PHASE_SHIFT) && (*iter)->IsCreature())
4045 {
4046 Creature* c = (*iter)->ToCreature();
4047 if ((!c->IsPet() && c->GetCreatureTemplate()->rank == CREATURE_ELITE_WORLDBOSS) || c->isWorldBoss() || c->IsDungeonBoss())
4048 continue;
4049 }
4050 bool interrupt = false; // pussywizard: skip spells that don't target units, but casted on unit (eg. TARGET_DEST_TARGET_ENEMY)
4051 for (uint8 j = 0; j < MAX_SPELL_EFFECTS; ++j)
4052 if (si->Effects[j].Effect && (si->Effects[j].GetUsedTargetObjectType() == TARGET_OBJECT_TYPE_UNIT || si->Effects[j].GetUsedTargetObjectType() == TARGET_OBJECT_TYPE_UNIT_AND_DEST))
4053 {
4054 // at least one effect truly targets an unit, interrupt the spell
4055 interrupt = true;
4056 break;
4057 }
4058 if (interrupt)
4059 (*iter)->InterruptSpell(CurrentSpellTypes(i), false);
4060 }
4061 }
4062 }
4063
4064 // Xinef: Set last sanctuary time
4066}
#define CURRENT_MAX_SPELL
Definition: Unit.h:544
void UpdateVisibility(bool checkThreat)
Definition: HostileRefMgr.cpp:236
void addThreatPercent(int32 percent)
Definition: HostileRefMgr.cpp:85
void SendAttackSwingCancelAttack()
Definition: PlayerMisc.cpp:140
void CombatStop(bool includingCast=false)
Definition: Unit.cpp:10398
void RemoveAllAttackers()
Remove all units in m_attackers list and send them AttackStop()
Definition: Unit.cpp:10446
bool AttackStop()
Force the unit to stop attacking. This will clear UNIT_STATE_MELEE_ATTACKING, Interrupt current spell...
Definition: Unit.cpp:10365
virtual bool IsEncounterInProgress() const
Definition: InstanceScript.cpp:122

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

◆ EffectSchoolDMG()

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

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

◆ EffectScriptEffect()

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

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

◆ EffectSelfResurrect()

void Spell::EffectSelfResurrect ( SpellEffIndex  effIndex)
4829{
4831 return;
4832
4833 if (!m_caster || m_caster->IsAlive())
4834 return;
4835 if (!m_caster->IsPlayer())
4836 return;
4837 if (!m_caster->IsInWorld())
4838 return;
4839
4840 uint32 health = 0;
4841 uint32 mana = 0;
4842
4843 // flat case
4844 if (damage < 0)
4845 {
4846 health = uint32(-damage);
4847 mana = m_spellInfo->Effects[effIndex].MiscValue;
4848 }
4849 // percent case
4850 else
4851 {
4855 }
4856
4857 Player* player = m_caster->ToPlayer();
4858 player->ResurrectPlayer(0.0f);
4859
4860 player->SetHealth(health);
4861 player->SetPower(POWER_MANA, mana);
4862 player->SetPower(POWER_RAGE, 0);
4863 player->SetPower(POWER_ENERGY, player->GetMaxPower(POWER_ENERGY));
4864
4865 player->SpawnCorpseBones();
4866}
@ POWER_RAGE
Definition: SharedDefines.h:270
void SpawnCorpseBones(bool triggerSave=true)
Definition: Player.cpp:4672
void ResurrectPlayer(float restore_percent, bool applySickness=false)
Definition: Player.cpp:4459
void SetPower(Powers power, uint32 val, bool withPowerUpdate=true, bool fromRegenerate=false)
Definition: Unit.cpp:15521

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

◆ EffectSendEvent()

void Spell::EffectSendEvent ( SpellEffIndex  effIndex)
Todo:
: there should be a possibility to pass dest target to event script
1378{
1379 // we do not handle a flag dropping or clicking on flag in battleground by sendevent system
1382 return;
1383
1384 WorldObject* target = nullptr;
1385
1386 // call events for object target if present
1388 {
1389 if (unitTarget)
1390 target = unitTarget;
1391 else if (gameObjTarget)
1392 target = gameObjTarget;
1393 }
1394 else // if (effectHandleMode == SPELL_EFFECT_HANDLE_HIT)
1395 {
1396 // let's prevent executing effect handler twice in case when spell effect is capable of targeting an object
1397 // this check was requested by scripters, but it has some downsides:
1398 // now it's impossible to script (using sEventScripts) a cast which misses all targets
1399 // or to have an ability to script the moment spell hits dest (in a case when there are object targets present)
1400 if (m_spellInfo->Effects[effIndex].GetProvidedTargetMask() & (TARGET_FLAG_UNIT_MASK | TARGET_FLAG_GAMEOBJECT_MASK))
1401 return;
1402 // some spells have no target entries in dbc and they use focus target
1403 if (focusObject)
1404 target = focusObject;
1406 }
1407
1408 LOG_DEBUG("spells.aura", "Spell ScriptStart {} for spellid {} in EffectSendEvent ", m_spellInfo->Effects[effIndex].MiscValue, m_spellInfo->Id);
1409
1410 if (ZoneScript* zoneScript = m_caster->GetZoneScript())
1411 zoneScript->ProcessEvent(target, m_spellInfo->Effects[effIndex].MiscValue);
1412 else if (InstanceScript* instanceScript = m_caster->GetInstanceScript()) // needed in case Player is the caster
1413 instanceScript->ProcessEvent(target, m_spellInfo->Effects[effIndex].MiscValue);
1414
1415 m_caster->GetMap()->ScriptsStart(sEventScripts, m_spellInfo->Effects[effIndex].MiscValue, m_caster, target);
1416}
ScriptMapMap sEventScripts
Definition: ObjectMgr.cpp:58
@ TARGET_FLAG_UNIT_MASK
Definition: SpellInfo.h:68
@ TARGET_FLAG_GAMEOBJECT_MASK
Definition: SpellInfo.h:70
Definition: Object.h:405
ZoneScript * GetZoneScript() const
Definition: Object.h:537
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)
5088{
5090 return;
5091
5092 if (!unitTarget)
5093 return;
5094
5095 if (Player* player = unitTarget->ToPlayer())
5096 {
5097 player->ActivateTaxiPathTo(m_spellInfo->Effects[effIndex].MiscValue, m_spellInfo->Id);
5098 }
5099}

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

◆ EffectSkill()

void Spell::EffectSkill ( SpellEffIndex  effIndex)
5521{
5523 return;
5524
5525 LOG_DEBUG("spells.aura", "WORLD: SkillEFFECT");
5526}

References effectHandleMode, LOG_DEBUG, and SPELL_EFFECT_HANDLE_HIT.

◆ EffectSkinning()

void Spell::EffectSkinning ( SpellEffIndex  effIndex)
4869{
4871 return;
4872
4873 if (!unitTarget->IsCreature())
4874 return;
4875 if (!m_caster->IsPlayer())
4876 return;
4877
4878 Creature* creature = unitTarget->ToCreature();
4879 int32 targetLevel = creature->GetLevel();
4880
4881 uint32 skill = creature->GetCreatureTemplate()->GetRequiredLootSkill();
4882
4886
4887 int32 reqValue = targetLevel < 10 ? 0 : targetLevel < 20 ? (targetLevel - 10) * 10 : targetLevel * 5;
4888
4889 int32 skillValue = m_caster->ToPlayer()->GetPureSkillValue(skill);
4890
4891 // Double chances for elites
4892 m_caster->ToPlayer()->UpdateGatherSkill(skill, skillValue, reqValue, creature->isElite() ? 2 : 1);
4893}
@ UNIT_DYNFLAG_LOOTABLE
Definition: SharedDefines.h:3121
bool isElite() const
Definition: Creature.h:114
virtual void SetDynamicFlag(uint32 flag)
Definition: Object.h:120

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

◆ EffectSkinPlayerCorpse()

void Spell::EffectSkinPlayerCorpse ( SpellEffIndex  effIndex)
5552{
5554 return;
5555
5556 LOG_DEBUG("spells.aura", "Effect: SkinPlayerCorpse");
5557 if ((!m_caster->IsPlayer()) || (!unitTarget->IsPlayer()) || (unitTarget->IsAlive()))
5558 return;
5559
5561}
void RemovedInsignia(Player *looterPlr)
Definition: Player.cpp:7734

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

◆ EffectSpecCount()

void Spell::EffectSpecCount ( SpellEffIndex  effIndex)
6107{
6109 return;
6110
6111 if (!unitTarget)
6112 return;
6113
6114 if (Player* player = unitTarget->ToPlayer())
6115 {
6116 player->UpdateSpecCount(damage);
6117 }
6118}

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

◆ EffectSpiritHeal()

void Spell::EffectSpiritHeal ( SpellEffIndex  effIndex)
5533{
5535 return;
5536
5537 /*
5538 if (!unitTarget->IsPlayer())
5539 return;
5540 if (!unitTarget->IsInWorld())
5541 return;
5542
5543 //m_spellInfo->Effects[i].BasePoints; == 99 (percent?)
5544 //unitTarget->ToPlayer()->setResurrect(m_caster->GetGUID(), unitTarget->GetPositionX(), unitTarget->GetPositionY(), unitTarget->GetPositionZ(), unitTarget->GetMaxHealth(), unitTarget->GetMaxPower(POWER_MANA));
5545 unitTarget->ToPlayer()->ResurrectPlayer(1.0f);
5546 unitTarget->ToPlayer()->SpawnCorpseBones();
5547 */
5548}

References effectHandleMode, and SPELL_EFFECT_HANDLE_HIT_TARGET.

◆ EffectStealBeneficialBuff()

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

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

◆ EffectStuck()

void Spell::EffectStuck ( SpellEffIndex  effIndex)
4160{
4162 return;
4163
4164 if (!m_caster->IsPlayer())
4165 return;
4166
4167 Player* target = m_caster->ToPlayer();
4168 if (target->IsInFlight())
4169 return;
4170
4171 // xinef: if player is dead - teleport to graveyard
4172 if (!target->IsAlive())
4173 {
4175 return;
4176
4177 // xinef: player is in corpse
4178 if (!target->HasPlayerFlag(PLAYER_FLAGS_GHOST))
4179 target->BuildPlayerRepop();
4180 target->RepopAtGraveyard();
4181 return;
4182 }
4183
4184 // xinef: no hearthstone in bag or on cooldown
4185 Item* hearthStone = target->GetItemByEntry(6948);
4186 if (!hearthStone || target->HasSpellCooldown(8690))
4187 {
4188 float o = rand_norm() * 2 * M_PI;
4189 Position pos = *target;
4190 target->MovePositionToFirstCollision(pos, 5.0f, o);
4191 target->NearTeleportTo(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), target->GetOrientation());
4192 return;
4193 }
4194
4195 // xinef: we have hearthstone not on cooldown, just use it
4197}
double rand_norm()
Definition: Random.cpp:77
@ PLAYER_FLAGS_GHOST
Definition: Player.h:478
@ SPELL_AURA_PREVENT_RESURRECTION
Definition: SpellAuraDefines.h:377
void MovePositionToFirstCollision(Position &pos, float dist, float angle)
Definition: Object.cpp:2858
void RepopAtGraveyard()
Definition: Player.cpp:4906
void BuildPlayerRepop()
Definition: Player.cpp:4410

References Player::BuildPlayerRepop(), Unit::CastSpell(), effectHandleMode, Player::GetItemByEntry(), Position::GetOrientation(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), Unit::HasAuraType(), Player::HasPlayerFlag(), Player::HasSpellCooldown(), Unit::IsAlive(), Unit::IsInFlight(), Object::IsPlayer(), 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, and TRIGGERED_IGNORE_SPELL_AND_CATEGORY_CD.

◆ EffectSummonChangeItem()

void Spell::EffectSummonChangeItem ( SpellEffIndex  effIndex)
2181{
2183 return;
2184
2185 if (!m_caster->IsPlayer())
2186 return;
2187
2188 Player* player = m_caster->ToPlayer();
2189
2190 // applied only to using item
2191 if (!m_CastItem)
2192 return;
2193
2194 // ... only to item in own inventory/bank/equip_slot
2195 if (m_CastItem->GetOwnerGUID() != player->GetGUID())
2196 return;
2197
2198 uint32 newitemid = m_spellInfo->Effects[effIndex].ItemType;
2199 if (!newitemid)
2200 return;
2201
2202 uint16 pos = m_CastItem->GetPos();
2203
2204 Item* pNewItem = Item::CreateItem(newitemid, 1, player);
2205 if (!pNewItem)
2206 return;
2207
2208 // Client-side enchantment durations update
2210
2214
2216 {
2218 player->DurabilityLoss(pNewItem, lossPercent);
2219 }
2220
2221 if (player->IsInventoryPos(pos))
2222 {
2223 ItemPosCountVec dest;
2224 InventoryResult msg = player->CanStoreItem(m_CastItem->GetBagSlot(), m_CastItem->GetSlot(), dest, pNewItem, true);
2225 if (msg == EQUIP_ERR_OK)
2226 {
2227 player->DestroyItem(m_CastItem->GetBagSlot(), m_CastItem->GetSlot(), true);
2228
2229 // prevent crash at access and unexpected charges counting with item update queue corrupt
2231 m_targets.SetItemTarget(nullptr);
2232
2233 m_CastItem = nullptr;
2235
2236 player->StoreItem(dest, pNewItem, true);
2237 player->ItemAddedQuestCheck(pNewItem->GetEntry(), 1);
2238 return;
2239 }
2240 }
2241 else if (player->IsBankPos(pos))
2242 {
2243 ItemPosCountVec dest;
2244 uint8 msg = player->CanBankItem(m_CastItem->GetBagSlot(), m_CastItem->GetSlot(), dest, pNewItem, true);
2245 if (msg == EQUIP_ERR_OK)
2246 {
2247 player->DestroyItem(m_CastItem->GetBagSlot(), m_CastItem->GetSlot(), true);
2248
2249 // prevent crash at access and unexpected charges counting with item update queue corrupt
2251 m_targets.SetItemTarget(nullptr);
2252
2253 m_CastItem = nullptr;
2255
2256 player->BankItem(dest, pNewItem, true);
2257 return;
2258 }
2259 }
2260 else if (player->IsEquipmentPos(pos))
2261 {
2262 uint16 dest;
2263
2264 player->DestroyItem(m_CastItem->GetBagSlot(), m_CastItem->GetSlot(), true);
2265
2266 uint8 msg = player->CanEquipItem(m_CastItem->GetSlot(), dest, pNewItem, true);
2267
2268 if (msg == EQUIP_ERR_OK || msg == EQUIP_ERR_CANT_DO_RIGHT_NOW)
2269 {
2271
2272 // prevent crash at access and unexpected charges counting with item update queue corrupt
2274 m_targets.SetItemTarget(nullptr);
2275
2276 m_CastItem = nullptr;
2278
2279 player->EquipItem(dest, pNewItem, true);
2280 player->AutoUnequipOffhandIfNeed();
2281 return;
2282 }
2283 }
2284
2285 // fail
2286 delete pNewItem;
2287}
@ ITEM_FIELD_DURABILITY
Definition: UpdateFields.h:69
@ ITEM_FIELD_MAXDURABILITY
Definition: UpdateFields.h:70
@ EQUIP_ERR_CANT_DO_RIGHT_NOW
Definition: Item.h:86
uint8 GetSlot() const
Definition: Item.h:281
static Item * CreateItem(uint32 item, uint32 count, Player const *player=nullptr, bool clone=false, uint32 randomPropertyId=0)
Definition: Item.cpp:1088
uint32 GetEnchantmentDuration(EnchantmentSlot slot) const
Definition: Item.h:305
uint16 GetPos() const
Definition: Item.h:285
uint32 GetEnchantmentCharges(EnchantmentSlot slot) const
Definition: Item.h:306
uint8 GetBagSlot() const
Definition: Item.cpp:785
void Clear()
Definition: ObjectGuid.h:138
static bool IsEquipmentPos(uint16 pos)
Definition: Player.h:1256
InventoryResult CanEquipItem(uint8 slot, uint16 &dest, Item *pItem, bool swap, bool not_loading=true) const
Definition: PlayerStorage.cpp:1811
Item * BankItem(ItemPosCountVec const &dest, Item *pItem, bool update)
Definition: Player.h:1325
InventoryResult CanStoreItem(uint8 bag, uint8 slot, ItemPosCountVec &dest, Item *pItem, bool swap=false) const
Definition: Player.h:1276
void UpdateEnchantmentDurations()
Definition: PlayerStorage.cpp:4740
Item * StoreItem(ItemPosCountVec const &pos, Item *pItem, bool update)
Definition: PlayerStorage.cpp:2580
void DestroyItem(uint8 bag, uint8 slot, bool update)
Definition: PlayerStorage.cpp:3029
static bool IsInventoryPos(uint16 pos)
Definition: Player.h:1254
void AutoUnequipOffhandIfNeed(bool force=false)
Definition: Player.cpp:12459
Item * EquipItem(uint16 pos, Item *pItem, bool update)
Definition: PlayerStorage.cpp:2733
InventoryResult CanBankItem(uint8 bag, uint8 slot, ItemPosCountVec &dest, Item *pItem, bool swap, bool not_loading=true) const
Definition: PlayerStorage.cpp:2038
void ItemAddedQuestCheck(uint32 entry, uint32 count)
Definition: PlayerQuest.cpp:1829
static bool IsBankPos(uint16 pos)
Definition: Player.h:1259

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

◆ EffectSummonCritter()

void Spell::EffectSummonCritter ( SpellEffIndex  effIndex)

◆ EffectSummonObject()

void Spell::EffectSummonObject ( SpellEffIndex  effIndex)
4547{
4549 return;
4550
4551 uint32 gameobjectId = m_spellInfo->Effects[effIndex].MiscValue;
4552
4553 uint8 slot = 0;
4554 switch (m_spellInfo->Effects[effIndex].Effect)
4555 {
4557 slot = 0;
4558 break;
4560 slot = 1;
4561 break;
4563 slot = 2;
4564 break;
4566 slot = 3;
4567 break;
4568 default:
4569 return;
4570 }
4571
4572 if (m_caster)
4573 {
4574 ObjectGuid guid = m_caster->m_ObjectSlot[slot];
4575 if (guid)
4576 {
4577 if (GameObject* gameObject = m_caster->GetMap()->GetGameObject(guid))
4578 {
4579 // Recast case - null spell id to make auras not be removed on object remove from world
4580 if (m_spellInfo->Id == gameObject->GetSpellId())
4581 gameObject->SetSpellId(0);
4582 m_caster->RemoveGameObject(gameObject, true);
4583 }
4584 m_caster->m_ObjectSlot[slot].Clear();
4585 }
4586 }
4587
4588 GameObject* pGameObj = sObjectMgr->IsGameObjectStaticTransport(gameobjectId) ? new StaticTransport() : new GameObject();
4589
4590 float x, y, z;
4591 // If dest location if present
4592 if (m_targets.HasDst())
4593 destTarget->GetPosition(x, y, z);
4594 // Summon in random point all other units if location present
4595 else
4597
4598 Map* map = m_caster->GetMap();
4599 if (!pGameObj->Create(map->GenerateLowGuid<HighGuid::GameObject>(), gameobjectId, map, m_caster->GetPhaseMask(), x, y, z, m_caster->GetOrientation(), G3D::Quat(), 0, GO_STATE_READY))
4600 {
4601 delete pGameObj;
4602 return;
4603 }
4604
4605 //pGameObj->SetUInt32Value(GAMEOBJECT_LEVEL, m_caster->GetLevel());
4606 int32 duration = m_spellInfo->GetDuration();
4607 pGameObj->SetRespawnTime(duration > 0 ? duration / IN_MILLISECONDS : 0);
4608 pGameObj->SetSpellId(m_spellInfo->Id);
4609 m_caster->AddGameObject(pGameObj);
4610
4611 ExecuteLogEffectSummonObject(effIndex, pGameObj);
4612
4613 map->AddToMap(pGameObj, true);
4614
4615 m_caster->m_ObjectSlot[slot] = pGameObj->GetGUID();
4616}
#define DEFAULT_WORLD_OBJECT_SIZE
Definition: ObjectDefines.h:45
@ SPELL_EFFECT_SUMMON_OBJECT_SLOT4
Definition: SharedDefines.h:885
@ SPELL_EFFECT_SUMMON_OBJECT_SLOT1
Definition: SharedDefines.h:882
@ SPELL_EFFECT_SUMMON_OBJECT_SLOT3
Definition: SharedDefines.h:884
@ SPELL_EFFECT_SUMMON_OBJECT_SLOT2
Definition: SharedDefines.h:883
ObjectGuid m_ObjectSlot[MAX_GAMEOBJECT_SLOT]
Definition: Unit.h:1781

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)
3717{
3719 return;
3720
3721 uint32 gameobject_id = m_spellInfo->Effects[effIndex].MiscValue;
3722
3723 GameObject* pGameObj = sObjectMgr->IsGameObjectStaticTransport(gameobject_id) ? new StaticTransport() : new GameObject();
3724
3725 WorldObject* target = focusObject;
3726 if (!target)
3727 target = m_caster;
3728
3729 float x, y, z;
3730 if (m_targets.HasDst())
3731 destTarget->GetPosition(x, y, z);
3732 else
3734
3735 Map* map = target->GetMap();
3736
3737 if (!pGameObj->Create(map->GenerateLowGuid<HighGuid::GameObject>(), gameobject_id, map, m_caster->GetPhaseMask(), x, y, z, target->GetOrientation(), G3D::Quat(), 100, GO_STATE_READY))
3738 {
3739 delete pGameObj;
3740 return;
3741 }
3742
3743 int32 duration = m_spellInfo->GetDuration();
3744
3745 pGameObj->SetRespawnTime(duration > 0 ? duration / IN_MILLISECONDS : 0);
3746 pGameObj->SetSpellId(m_spellInfo->Id);
3747
3748 ExecuteLogEffectSummonObject(effIndex, pGameObj);
3749
3750 // Wild object not have owner and check clickable by players
3751 map->AddToMap(pGameObj, true);
3752
3753 if (pGameObj->GetGoType() == GAMEOBJECT_TYPE_FLAGDROP)
3754 if (Player* player = m_caster->ToPlayer())
3755 if (Battleground* bg = player->GetBattleground())
3756 bg->SetDroppedFlagGUID(pGameObj->GetGUID(), player->GetTeamId() == TEAM_ALLIANCE ? TEAM_HORDE : TEAM_ALLIANCE);
3757
3758 if (GameObject* linkedTrap = pGameObj->GetLinkedTrap())
3759 {
3760 linkedTrap->SetRespawnTime(duration > 0 ? duration/IN_MILLISECONDS :0);
3761 linkedTrap->SetSpellId(m_spellInfo->Id);
3762 ExecuteLogEffectSummonObject(effIndex, linkedTrap);
3763 }
3764}
@ GAMEOBJECT_TYPE_FLAGDROP
Definition: SharedDefines.h:1586
@ TEAM_ALLIANCE
Definition: SharedDefines.h:760
@ TEAM_HORDE
Definition: SharedDefines.h:761
GameObject * GetLinkedTrap()
Definition: GameObject.cpp:2735
GameobjectTypes GetGoType() const
Definition: GameObject.h:204

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)
3119{
3121 return;
3122
3123 if (!m_originalCaster)
3124 return;
3125
3126 uint32 petentry = m_spellInfo->Effects[effIndex].MiscValue;
3127 int32 duration = m_spellInfo->GetDuration();
3128
3129 if (Player* modOwner = m_originalCaster->GetSpellModOwner())
3130 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_DURATION, duration);
3131
3132 Player* owner = m_originalCaster->ToPlayer();
3133 if (!owner && m_originalCaster->ToCreature()->IsTotem())
3135
3136 if (!owner)
3137 {
3138 SummonPropertiesEntry const* properties = sSummonPropertiesStore.LookupEntry(67);
3139 if (properties)
3140 {
3141 // Xinef: unsummon old guardian
3142 if (Guardian* oldPet = m_originalCaster->GetGuardianPet())
3143 oldPet->UnSummon();
3144 SummonGuardian(effIndex, petentry, properties, 1, false);
3145 }
3146 return;
3147 }
3148
3149 Pet* OldSummon = owner->GetPet();
3150
3151 // if pet requested type already exist
3152 if (OldSummon)
3153 {
3154 if (petentry == 0 || OldSummon->GetEntry() == petentry)
3155 {
3156 // pet in corpse state can't be summoned
3157 if (OldSummon->isDead())
3158 return;
3159
3160 ASSERT(OldSummon->GetMap() == owner->GetMap());
3161
3162 //OldSummon->GetMap()->Remove(OldSummon->ToCreature(), false);
3163
3164 float px, py, pz;
3165 owner->GetClosePoint(px, py, pz, OldSummon->GetObjectSize());
3166
3167 OldSummon->NearTeleportTo(px, py, pz, OldSummon->GetOrientation());
3168 OldSummon->UpdateObjectVisibility();
3169
3170 OldSummon->SetHealth(OldSummon->GetMaxHealth());
3171 OldSummon->SetPower(OldSummon->getPowerType(), OldSummon->GetMaxPower(OldSummon->getPowerType()));
3172 // notify player
3173 for (CreatureSpellCooldowns::const_iterator itr = OldSummon->m_CreatureSpellCooldowns.begin(); itr != OldSummon->m_CreatureSpellCooldowns.end(); ++itr)
3174 owner->SendClearCooldown(itr->first, OldSummon);
3175
3176 // actually clear cooldowns
3177 OldSummon->m_CreatureSpellCooldowns.clear();
3178 Unit::AuraApplicationMap& myAuras = OldSummon->GetAppliedAuras();
3179 for (Unit::AuraApplicationMap::iterator i = myAuras.begin(); i != myAuras.end();)
3180 {
3181 Aura const* aura = i->second->GetBase();
3182 if (!aura->IsPassive() && !OldSummon->IsPetAura(aura) && aura->CanBeSentToClient())
3183 OldSummon->RemoveAura(i);
3184 else
3185 ++i;
3186 }
3187 return;
3188 }
3189
3190 if (owner->IsPlayer())
3191 owner->ToPlayer()->RemovePet(OldSummon, PET_SAVE_NOT_IN_SLOT, false);
3192 else
3193 return;
3194 }
3195
3196 float x, y, z;
3197 owner->GetClosePoint(x, y, z, owner->GetObjectSize());
3198 Pet* pet = owner->SummonPet(petentry, x, y, z, owner->GetOrientation(), SUMMON_PET);
3199 if (!pet)
3200 return;
3201
3202 if (m_caster->IsCreature())
3203 {
3204 if (m_caster->ToCreature()->IsTotem())
3206 else
3208 }
3209
3211
3212 // Reset cooldowns
3214 {
3215 pet->m_CreatureSpellCooldowns.clear();
3216 owner->PetSpellInitialize();
3217 }
3218
3219 // Set health to max if new pet is summoned
3220 // in this function old pet is saved with current health eg. 20% and new one is loaded from db with same amount
3221 // pet should have full health
3222 pet->SetHealth(pet->GetMaxHealth());
3223
3224 // generate new name for summon pet
3225 std::string new_name = sObjectMgr->GeneratePetName(petentry);
3226 if (!new_name.empty())
3227 pet->SetName(new_name);
3228
3229 // ExecuteLogEffectSummonObject(effectInfo->EffectIndex, pet);
3230}
@ REACT_DEFENSIVE
Definition: Unit.h:549
@ REACT_AGGRESSIVE
Definition: Unit.h:550
@ SPELLMOD_DURATION
Definition: SpellDefines.h:78
CreatureSpellCooldowns m_CreatureSpellCooldowns
Definition: Creature.h:252
void SetReactState(ReactStates state)
A creature can have 3 ReactStates : Agressive, Passive, Neutral.
Definition: Creature.h:97
Definition: TemporarySummon.h:95
void SetName(std::string const &newname)
Definition: Object.h:459
float GetObjectSize() const
Definition: Object.cpp:2771
void SendClearCooldown(uint32 spell_id, Unit *target)
Definition: Player.cpp:14651
bool IsPetAura(Aura const *aura)
Definition: Unit.cpp:17292
void UpdateObjectVisibility(bool forced=true, bool fromUpdate=false) override
Definition: Unit.cpp:19086
Powers getPowerType() const
Definition: Unit.h:888
bool isDead() const
Definition: Unit.h:1206
bool CanBeSentToClient() const
Definition: SpellAuras.cpp:1137
void SummonGuardian(uint32 i, uint32 entry, SummonPropertiesEntry const *properties, uint32 numSummons, bool personalSpawn)
Definition: SpellEffects.cpp:5932

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

◆ EffectSummonPlayer()

void Spell::EffectSummonPlayer ( SpellEffIndex  effIndex)
4200{
4201 // workaround - this effect should not use target map
4203 return;
4204
4205 if (!unitTarget)
4206 return;
4207
4208 Player* player = unitTarget->ToPlayer();
4209 if (!player)
4210 {
4211 return;
4212 }
4213
4214 // Evil Twin (ignore player summon, but hide this for summoner)
4215 // Xinef: Unit Target may be on other map!!!, Need workaround
4216 if (unitTarget->HasAura(23445))
4217 return;
4218
4219 float x, y, z;
4220 m_caster->GetPosition(x, y, z);
4221
4222 player->SetSummonPoint(m_caster->GetMapId(), x, y, z);
4223
4224 WorldPacket data(SMSG_SUMMON_REQUEST, 8 + 4 + 4);
4225 data << m_caster->GetGUID(); // summoner guid
4226 data << uint32(m_caster->GetZoneId()); // summoner zone
4227 data << uint32(MAX_PLAYER_SUMMON_DELAY * IN_MILLISECONDS); // auto decline after msecs
4228 player->GetSession()->SendPacket(&data);
4229}
#define MAX_PLAYER_SUMMON_DELAY
Definition: Player.h:929
@ 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:16319

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)
6301{
6303 return;
6304
6305 if (!m_caster->IsPlayer())
6306 return;
6307
6308 if (!unitTarget)
6309 return;
6310
6311 Player* player = unitTarget->ToPlayer();
6312 if (!player)
6313 {
6314 return;
6315 }
6316
6317 float x, y, z;
6318 m_caster->GetPosition(x, y, z);
6320 WorldPacket data(SMSG_SUMMON_REQUEST, 8 + 4 + 4);
6321 data << m_caster->GetGUID();
6322 data << uint32(m_caster->GetZoneId());
6323 data << uint32(MAX_PLAYER_SUMMON_DELAY * IN_MILLISECONDS); // auto decline after msecs
6324 player->GetSession()->SendPacket(&data);
6325}

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

◆ EffectSummonType()

void Spell::EffectSummonType ( SpellEffIndex  effIndex)
2312{
2314 return;
2315
2316 uint32 entry = m_spellInfo->Effects[effIndex].MiscValue;
2317 if (!entry)
2318 return;
2319
2320 SummonPropertiesEntry const* properties = sSummonPropertiesStore.LookupEntry(m_spellInfo->Effects[effIndex].MiscValueB);
2321 if (!properties)
2322 {
2323 LOG_ERROR("spells.effect", "EffectSummonType: Unhandled summon type {}", m_spellInfo->Effects[effIndex].MiscValueB);
2324 return;
2325 }
2326
2327 if (!m_originalCaster)
2328 return;
2329
2330 bool personalSpawn = (properties->Flags & SUMMON_PROP_FLAG_ONLY_VISIBLE_TO_SUMMONER) != 0;
2331 int32 duration = m_spellInfo->GetDuration();
2332 if (Player* modOwner = m_originalCaster->GetSpellModOwner())
2333 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_DURATION, duration);
2334
2335 TempSummon* summon = nullptr;
2336
2337 // determine how many units should be summoned
2338 uint32 numSummons;
2339
2340 // some spells need to summon many units, for those spells number of summons is stored in effect value
2341 // however so far noone found a generic check to find all of those (there's no related data in summonproperties.dbc
2342 // and in spell attributes, possibly we need to add a table for those)
2343 // so here's a list of MiscValueB values, which is currently most generic check
2344 switch (properties->Id)
2345 {
2346 case 64:
2347 case 61:
2348 case 1101:
2349 case 66:
2350 case 648:
2351 case 2301:
2352 case 1061:
2353 case 1261:
2354 case 629:
2355 case 181:
2356 case 715:
2357 case 1562:
2358 case 833:
2359 case 1161:
2360 case 713: // xinef, bloodworms
2361 numSummons = (damage > 0) ? damage : 1;
2362 break;
2363 default:
2364 numSummons = 1;
2365 break;
2366 }
2367
2368 switch (properties->Category)
2369 {
2373 if (properties->Flags & 512)
2374 {
2375 SummonGuardian(effIndex, entry, properties, numSummons, personalSpawn);
2376 break;
2377 }
2378 switch (properties->Type)
2379 {
2380 case SUMMON_TYPE_PET:
2383 case SUMMON_TYPE_MINION:
2384 SummonGuardian(effIndex, entry, properties, numSummons, personalSpawn);
2385 break;
2386 // Summons a vehicle, but doesn't force anyone to enter it (see SUMMON_CATEGORY_VEHICLE)
2389 summon = m_caster->GetMap()->SummonCreature(entry, *destTarget, properties, duration, m_originalCaster, m_spellInfo->Id, 0, personalSpawn);
2390 break;
2392 case SUMMON_TYPE_TOTEM:
2393 {
2394 // protection code
2395 summon = m_caster->GetMap()->SummonCreature(entry, *destTarget, properties, duration, m_originalCaster, m_spellInfo->Id, 0, personalSpawn);
2396 if (!summon || !summon->IsTotem())
2397 return;
2398
2399 // Mana Tide Totem
2400 if (m_spellInfo->Id == 16190)
2402
2403 if (damage && properties->Type != SUMMON_TYPE_LIGHTWELL) // Health set in script for lightwell
2404 {
2405 summon->SetMaxHealth(damage);
2406 summon->SetHealth(damage);
2407 }
2408 break;
2409 }
2410 case SUMMON_TYPE_JEEVES:
2412 {
2413 summon = m_caster->GetMap()->SummonCreature(entry, *destTarget, properties, duration, m_originalCaster, m_spellInfo->Id, 0, personalSpawn);
2414 if (!summon || !summon->HasUnitTypeMask(UNIT_MASK_MINION))
2415 return;
2416
2417 summon->SelectLevel(); // some summoned creaters have different from 1 DB data for level/hp
2419
2420 summon->SetImmuneToAll(true);
2422
2423 // Xinef: Pet can have some auras in creature_addon or in scripts, do not remove them instantly
2424 //summon->AI()->EnterEvadeMode();
2425 if (properties->Type != SUMMON_TYPE_JEEVES)
2426 {
2427 summon->GetMotionMaster()->Clear(false);
2429 }
2430 break;
2431 }
2432 default:
2433 {
2434 float radius = m_spellInfo->Effects[effIndex].CalcRadius();
2435
2436 TempSummonType summonType = (duration <= 0) ? TEMPSUMMON_DEAD_DESPAWN : TEMPSUMMON_TIMED_DESPAWN;
2437
2438 for (uint32 count = 0; count < numSummons; ++count)
2439 {
2440 Position pos;
2441 if (count == 0)
2442 pos = *destTarget;
2443 else
2444 // randomize position for multiple summons
2445 pos = m_caster->GetRandomPoint(*destTarget, radius);
2446
2447 summon = m_originalCaster->SummonCreature(entry, pos, summonType, duration, 0, nullptr, personalSpawn);
2448 if (!summon)
2449 continue;
2450
2451 summon->SetTempSummonType(summonType);
2452
2453 if (properties->Category == SUMMON_CATEGORY_ALLY)
2454 {
2457 }
2458
2459 ExecuteLogEffectSummonObject(effIndex, summon);
2460 }
2461 return;
2462 }
2463 }//switch
2464 break;
2466 // Xinef: SummonGuardian function can summon a few npcs of same type, remove old summons with same entry here
2467 if (m_originalCaster)
2469 SummonGuardian(effIndex, entry, properties, numSummons, personalSpawn);
2470 break;
2472 summon = m_caster->GetMap()->SummonCreature(entry, *destTarget, properties, duration, m_originalCaster, m_spellInfo->Id, 0, personalSpawn);
2473 break;
2475 // Summoning spells (usually triggered by npc_spellclick) that spawn a vehicle and that cause the clicker
2476 // to cast a ride vehicle spell on the summoned unit.
2477 //float x, y, z;
2478 //m_caster->GetClosePoint(x, y, z, DEFAULT_WORLD_OBJECT_SIZE);
2479 // xinef: vehicles summoned in air, eg. Cold Hearted quest
2480 if (std::fabs(m_caster->GetPositionZ() - destTarget->GetPositionZ()) > 6.0f)
2482
2483 summon = m_originalCaster->GetMap()->SummonCreature(entry, *destTarget, properties, duration, m_caster, m_spellInfo->Id, 0, personalSpawn);
2484 if (!summon || !summon->IsVehicle())
2485 return;
2486
2487 // The spell that this effect will trigger. It has SPELL_AURA_CONTROL_VEHICLE
2489 int32 basePoints = m_spellInfo->Effects[effIndex].CalcValue();
2490 if (basePoints > 1) // xinef: some summoning spells have value 1 - indicates vehicle seat
2491 {
2492 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(basePoints);
2493 if (spellInfo && spellInfo->HasAura(SPELL_AURA_CONTROL_VEHICLE))
2494 spellId = spellInfo->Id;
2495 }
2496
2497 // xinef: if we have small value, it indicates seat position
2498 if (basePoints > 0 && basePoints < MAX_VEHICLE_SEATS)
2499 m_originalCaster->CastCustomSpell(spellId, SPELLVALUE_BASE_POINT0, basePoints, summon, true);
2500 else
2501 m_originalCaster->CastSpell(summon, spellId, true);
2502
2503 // xinef: i think this is wrong, found only 2 vehicles with faction override and one of them should inherit caster faction...
2504 //uint32 faction = properties->Faction;
2505 //if (!faction)
2506 uint32 faction = m_originalCaster->GetFaction();
2507
2508 summon->SetFaction(faction);
2509 break;
2510 }
2511
2512 if (summon)
2513 {
2515 ExecuteLogEffectSummonObject(effIndex, summon);
2516 }
2517}
@ MOTION_SLOT_ACTIVE
Definition: MotionMaster.h:62
@ VEHICLE_SPELL_RIDE_HARDCODED
Definition: VehicleDefines.h:52
@ REACT_PASSIVE
Definition: Unit.h:548
@ UNIT_MASK_MINION
Definition: UnitDefines.h:136
NPCFlags
Non Player Character flags.
Definition: UnitDefines.h:292
TempSummonType
Definition: Object.h:44
@ TEMPSUMMON_DEAD_DESPAWN
Definition: Object.h:51
@ SPELL_AURA_CONTROL_VEHICLE
Definition: SpellAuraDefines.h:299
@ SUMMON_TYPE_VEHICLE2
Definition: SharedDefines.h:3304
@ SUMMON_TYPE_LIGHTWELL
Definition: SharedDefines.h:3305
@ SUMMON_TYPE_MINION
Definition: SharedDefines.h:3297
@ SUMMON_TYPE_GUARDIAN
Definition: SharedDefines.h:3296
@ SUMMON_TYPE_JEEVES
Definition: SharedDefines.h:3306
@ SUMMON_TYPE_PET
Definition: SharedDefines.h:3295
@ SUMMON_TYPE_TOTEM
Definition: SharedDefines.h:3298
@ SUMMON_TYPE_VEHICLE
Definition: SharedDefines.h:3303
@ SUMMON_TYPE_MINIPET
Definition: SharedDefines.h:3299
@ SUMMON_TYPE_GUARDIAN2
Definition: SharedDefines.h:3300
@ SUMMON_CATEGORY_VEHICLE
Definition: SharedDefines.h:3287
@ SUMMON_CATEGORY_ALLY
Definition: SharedDefines.h:3284
@ SUMMON_CATEGORY_WILD
Definition: SharedDefines.h:3283
@ SUMMON_CATEGORY_UNK
Definition: SharedDefines.h:3288
#define MAX_VEHICLE_SEATS
Definition: DBCStructure.h:2024
@ SUMMON_PROP_FLAG_ONLY_VISIBLE_TO_SUMMONER
Definition: DBCEnums.h:428
void SelectLevel(bool changelevel=true)
Definition: Creature.cpp:1505
uint32 npcflag
Definition: CreatureData.h:202
void SetTempSummonType(TempSummonType type)
Definition: TemporarySummon.cpp:277
void GetRandomPoint(const Position &srcPos, float distance, float &rand_x, float &rand_y, float &rand_z) const
Definition: Object.cpp:1502
void SetFaction(uint32 faction)
Definition: Unit.cpp:10018
virtual float GetFollowAngle() const
Definition: Unit.h:1708
void SetOwnerGUID(ObjectGuid owner)
Definition: Unit.cpp:10535
uint32 HasUnitTypeMask(uint32 mask) const
Definition: Unit.h:677
void SetMaxHealth(uint32 val)
Definition: Unit.cpp:15483
void SetCreatorGUID(ObjectGuid creator)
Definition: Unit.h:1213
void ReplaceAllNpcFlags(NPCFlags flags)
Definition: Unit.h:697
void RemoveAllMinionsByEntry(uint32 entry)
Definition: Unit.cpp:10820
void SetImmuneToAll(bool apply, bool keepCombat=false)
Definition: Unit.h:810
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:2163
void MoveFollow(Unit *target, float dist, float angle, MovementSlot slot=MOTION_SLOT_ACTIVE, bool inheritWalkState=true)
The unit will follow this target. Doesn't work with UNIT_FLAG_DISABLE_MOVE.
Definition: MotionMaster.cpp:409
void Clear(bool reset=true)
Definition: MotionMaster.h:165
uint32 Flags
Definition: DBCStructure.h:1915
uint32 Type
Definition: DBCStructure.h:1913
uint32 Id
Definition: DBCStructure.h:1910

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)
3063{
3065 return;
3066
3067 if (m_caster->GetPetGUID())
3068 return;
3069
3070 if (!unitTarget)
3071 return;
3072
3073 if (!unitTarget->IsCreature())
3074 return;
3075
3076 Creature* creatureTarget = unitTarget->ToCreature();
3077
3078 if (creatureTarget->IsPet())
3079 return;
3080
3082 return;
3083
3084 // cast finish successfully
3085 //SendChannelUpdate(0);
3086 finish();
3087
3088 Pet* pet = m_caster->CreateTamedPetFrom(creatureTarget, m_spellInfo->Id);
3089 if (!pet) // in very specific state like near world end/etc.
3090 return;
3091
3092 // "kill" original creature
3093 creatureTarget->DespawnOrUnsummon();
3094
3095 uint8 level = (creatureTarget->GetLevel() < (m_caster->GetLevel() - 5)) ? (m_caster->GetLevel() - 5) : creatureTarget->GetLevel();
3096
3097 // prepare visual effect for levelup
3098 pet->SetUInt32Value(UNIT_FIELD_LEVEL, level - 1);
3099
3100 // add to world
3101 pet->GetMap()->AddToMap(pet->ToCreature(), true);
3102
3103 // visual effect for levelup
3104 pet->SetUInt32Value(UNIT_FIELD_LEVEL, level);
3105
3106 // caster have pet now
3107 m_caster->SetMinion(pet, true);
3108
3109 pet->InitTalentForLevel();
3110
3111 if (m_caster->IsPlayer())
3112 {
3115 }
3116}
@ UNIT_FIELD_LEVEL
Definition: UpdateFields.h:114

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

◆ EffectTaunt()

void Spell::EffectTaunt ( SpellEffIndex  effIndex)
3259{
3261 return;
3262
3263 if (!unitTarget)
3264 return;
3265
3266 // xinef: Hand of Reckoning, cast before checing canhavethreatlist. fixes damage against pets
3267 if (m_spellInfo->Id == 62124 && unitTarget->GetVictim() != m_caster)
3268 {
3269 m_caster->CastSpell(unitTarget, 67485, true);
3271 }
3272
3273 // this effect use before aura Taunt apply for prevent taunt already attacking target
3274 // for spell as marked "non effective at already attacking target"
3276 {
3278 return;
3279 }
3280
3282 {
3283 // Also use this effect to set the taunter's threat to the taunted creature's highest value
3284 float myThreat = unitTarget->GetThreatMgr().GetThreat(m_caster);
3286 if (topThreat > myThreat)
3287 unitTarget->GetThreatMgr().DoAddThreat(m_caster, topThreat - myThreat);
3288
3289 //Set aggro victim to caster
3291 unitTarget->GetThreatMgr().setCurrentVictim(forcedVictim);
3292 }
3293}
@ 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:261
bool empty() const
Definition: ThreatMgr.h:164
void setCurrentVictim(HostileReference *hostileRef)
Definition: ThreatMgr.cpp:572
void DoAddThreat(Unit *victim, float threat)
Definition: ThreatMgr.cpp:453
float GetThreat(Unit *victim, bool alsoSearchOfflineList=false)
Definition: ThreatMgr.cpp:525
ThreatContainer & GetOnlineContainer()
Definition: ThreatMgr.h:276
bool CanHaveThreatList() const
Definition: Unit.cpp:14569

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

◆ EffectTeleportUnits()

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

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

◆ EffectTeleUnitsFaceCaster()

◆ EffectThreat()

void Spell::EffectThreat ( SpellEffIndex  effIndex)
3648{
3650 return;
3651
3652 if (!unitTarget || !unitTarget->IsAlive() || !m_caster->IsAlive())
3653 return;
3654
3655 // xinef: skip if target cannot have threat list or caster is friendly (ghoul leap)
3657 return;
3658
3660}
void AddThreat(Unit *victim, float fThreat, SpellSchoolMask schoolMask=SPELL_SCHOOL_MASK_NORMAL, SpellInfo const *threatSpell=nullptr)
Definition: Unit.cpp:14608

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)
5866{
5868 return;
5869
5870 if (m_caster->IsPlayer())
5871 {
5872 if (Aura* aur = m_caster->GetAura(49152))
5873 aur->RecalculateAmountOfEffects();
5874 else
5875 m_caster->CastSpell(unitTarget, 49152, true); // damage reduction
5876
5878 }
5879}
void SetCanTitanGrip(bool value)
Definition: Player.cpp:13142

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

◆ EffectTradeSkill()

void Spell::EffectTradeSkill ( SpellEffIndex  effIndex)
2800{
2802 return;
2803
2804 if (!m_caster->IsPlayer())
2805 return;
2806 // uint32 skillid = m_spellInfo->Effects[i].MiscValue;
2807 // uint16 skillmax = unitTarget->ToPlayer()->(skillid);
2808 // m_caster->ToPlayer()->SetSkill(skillid, skillval?skillval:1, skillmax+75);
2809}

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

◆ EffectTransmitted()

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

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

◆ EffectTriggerMissileSpell()

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

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

◆ EffectTriggerRitualOfSummoning()

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

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

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

◆ EffectUnlearnSpecialization()

void Spell::EffectUnlearnSpecialization ( SpellEffIndex  effIndex)
1319{
1321 return;
1322
1323 if (!unitTarget)
1324 return;
1325
1326 Player* player = unitTarget->ToPlayer();
1327 if (!player)
1328 {
1329 return;
1330 }
1331
1332 uint32 spellToUnlearn = m_spellInfo->Effects[effIndex].TriggerSpell;
1333
1334 player->removeSpell(spellToUnlearn, SPEC_MASK_ALL, false);
1335 LOG_DEBUG("spells.aura", "Spell: Player {} has unlearned spell {} from Npc: {}",
1336 player->GetGUID().ToString(), spellToUnlearn, m_caster->GetGUID().ToString());
1337}
#define SPEC_MASK_ALL
Definition: Player.h:177
void removeSpell(uint32 spellId, uint8 removeSpecMask, bool onlyTemporary)
Definition: Player.cpp:3312

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)
2724{
2726 return;
2727
2728 if (!unitTarget || m_caster->IsPlayer())
2729 return;
2730
2731 if (ObjectGuid guid = m_caster->GetGUID()) // the trainer is the caster
2733}
void SendTalentWipeConfirm(ObjectGuid guid)
Definition: Player.cpp:8878

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

◆ EffectUnused()

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

◆ EffectWeaponDmg()

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

References AddComboPointGain(), AddPct(), ApplyPct(), AURA_STATE_BLEEDING, AURA_STATE_DEADLY_POISON, BASE_ATTACK, Unit::CalculateDamage(), CalculateSpellDamage(), Unit::CastSpell(), DISPEL_POISON, EFFECT_0, EFFECT_1, EFFECT_2, effectHandleMode, SpellInfo::Effects, Unit::GetAppliedAuras(), Unit::GetAura(), Unit::GetAuraEffect(), Unit::GetAuraEffectDummy(), Unit::GetDiseasesByCaster(), Unit::GetDummyAuraEffect(), Object::GetEntry(), Object::GetGUID(), Unit::GetModifierValue(), Unit::GetOwner(), Unit::GetPower(), SpellInfo::GetSchoolMask(), Unit::GetTotalAttackPowerValue(), Player::GetWeaponForAttack(), SpellInfo::HasAttribute(), Unit::HasAura(), Unit::HasAuraState(), Unit::HasAuraType(), SpellInfo::Id, Unit::IsAlive(), Object::IsPlayer(), Unit::IsScriptOverriden(), ITEM_SUBCLASS_WEAPON_DAGGER, m_attackType, m_caster, m_damage, m_spellInfo, m_spellSchoolMask, m_UniqueTargetInfo, MAX_SPELL_EFFECTS, Unit::MeleeDamageBonusDone(), Unit::MeleeDamageBonusTaken(), OFF_ATTACK, POWER_RUNIC_POWER, RANGED_ATTACK, roll_chance_i(), SPELL_ATTR0_CU_SHARE_DAMAGE, SPELL_AURA_ADD_PCT_MODIFIER, SPELL_AURA_DUMMY, SPELL_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, UNIT_MOD_DAMAGE_MAINHAND, UNIT_MOD_DAMAGE_OFFHAND, UNIT_MOD_DAMAGE_RANGED, and unitTarget.

◆ ExecuteLogEffectCreateItem()

void Spell::ExecuteLogEffectCreateItem ( uint8  effIndex,
uint32  entry 
)
5137{
5138 InitEffectExecuteData(effIndex);
5139 *m_effectExecuteData[effIndex] << uint32(entry);
5140}
void InitEffectExecuteData(uint8 effIndex)
Definition: Spell.cpp:8465

References InitEffectExecuteData(), and m_effectExecuteData.

Referenced by EffectCreateItem().

◆ ExecuteLogEffectDestroyItem()

void Spell::ExecuteLogEffectDestroyItem ( uint8  effIndex,
uint32  entry 
)
5143{
5144 InitEffectExecuteData(effIndex);
5145 *m_effectExecuteData[effIndex] << uint32(entry);
5146}

References InitEffectExecuteData(), and m_effectExecuteData.

Referenced by EffectFeedPet().

◆ ExecuteLogEffectDurabilityDamage()

void Spell::ExecuteLogEffectDurabilityDamage ( uint8  effIndex,
Unit victim,
int32  itemId,
int32  slot 
)
5123{
5124 InitEffectExecuteData(effIndex);
5125 *m_effectExecuteData[effIndex] << victim->GetPackGUID();
5126 *m_effectExecuteData[effIndex] << int32(itemId);
5127 *m_effectExecuteData[effIndex] << int32(slot);
5128}

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

Referenced by EffectDurabilityDamage().

◆ ExecuteLogEffectExtraAttacks()

void Spell::ExecuteLogEffectExtraAttacks ( uint8  effIndex,
Unit victim,
uint32  attCount 
)
5109{
5110 InitEffectExecuteData(effIndex);
5111 *m_effectExecuteData[effIndex] << victim->GetPackGUID();
5112 *m_effectExecuteData[effIndex] << uint32(attCount);
5113}

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

Referenced by EffectAddExtraAttacks().

◆ ExecuteLogEffectInterruptCast()

void Spell::ExecuteLogEffectInterruptCast ( uint8  effIndex,
Unit victim,
uint32  spellId 
)
5116{
5117 InitEffectExecuteData(effIndex);
5118 *m_effectExecuteData[effIndex] << victim->GetPackGUID();
5119 *m_effectExecuteData[effIndex] << uint32(spellId);
5120}

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

Referenced by EffectInterruptCast().

◆ ExecuteLogEffectOpenLock()

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

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

Referenced by EffectOpenLock().

◆ ExecuteLogEffectResurrect()

void Spell::ExecuteLogEffectResurrect ( uint8  effIndex,
Unit target 
)
5161{
5162 InitEffectExecuteData(effIndex);
5163 *m_effectExecuteData[effIndex] << target->GetPackGUID();
5164}

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 
)
5100{
5101 InitEffectExecuteData(effIndex);
5102 *m_effectExecuteData[effIndex] << target->GetPackGUID();
5103 *m_effectExecuteData[effIndex] << uint32(powerTaken);
5104 *m_effectExecuteData[effIndex] << uint32(PowerType);
5105 *m_effectExecuteData[effIndex] << float(gainMultiplier);
5106}

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 
)
5155{
5156 InitEffectExecuteData(effIndex);
5157 *m_effectExecuteData[effIndex] << obj->GetPackGUID();
5158}

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

Referenced by EffectDismissPet().

◆ finish()

void Spell::finish ( bool  ok = true)
4475{
4476 if (!m_caster)
4477 return;
4478
4480 return;
4482
4483 if (m_spellInfo->IsChanneled())
4485
4488
4489 // Unsummon summon as possessed creatures on spell cancel
4491 {
4492 if (Unit* charm = m_caster->GetCharm())
4493 if (charm->IsCreature()
4494 && charm->ToCreature()->HasUnitTypeMask(UNIT_MASK_PUPPET)
4495 && charm->GetUInt32Value(UNIT_CREATED_BY_SPELL) == m_spellInfo->Id)
4496 ((Puppet*)charm)->UnSummon();
4497 }
4498
4499 if (Creature* creatureCaster = m_caster->ToCreature())
4500 creatureCaster->ReleaseFocus(this);
4501
4502 if (ok)
4503 {
4506 }
4507 else
4508 {
4509 if (m_caster->IsPlayer())
4510 {
4511 // Xinef: Restore spell mods in case of fail cast
4513
4514 // Xinef: Reset cooldown event in case of fail cast
4517 }
4518 return;
4519 }
4520
4521 // pussywizard:
4524
4526 {
4527 // Unsummon statue
4529 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spell);
4530 if (spellInfo && spellInfo->SpellIconID == 2056)
4531 {
4532 LOG_DEBUG("spells.aura", "Statue {} is unsummoned in spell {} finish", m_caster->GetGUID().ToString(), m_spellInfo->Id);
4533 m_caster->setDeathState(DeathState::JustDied);
4534 return;
4535 }
4536 }
4537
4538 // potions disabled by client, send event "not in combat" if need
4541
4542 // Take mods after trigger spell (needed for 14177 to affect 48664)
4543 // mods are taken only on succesfull cast and independantly from targets of the spell
4544 if (Player* player = m_caster->GetSpellModOwner())
4545 player->RemoveSpellMods(this);
4546
4547 // xinef: clear reactive auras states after spell cast
4550
4551 // Stop Attack for some spells
4554}
@ ENCOUNTER_CREDIT_CAST_SPELL
Definition: Map.h:309
@ UNIT_MASK_PUPPET
Definition: UnitDefines.h:141
@ SPELL_ATTR0_CU_ENCOUNTER_REWARD
Definition: SpellInfo.h:207
@ AURA_STATE_DEFENSE
Definition: SharedDefines.h:1292
@ AURA_STATE_HUNTER_PARRY
Definition: SharedDefines.h:1298
Definition: TemporarySummon.h:114
void UpdatePotionCooldown(Spell *spell=nullptr)
Definition: PlayerUpdates.cpp:1497
virtual void setDeathState(DeathState s, bool despawn=false)
Definition: Unit.cpp:14507
void UpdateInterruptMask()
Definition: Unit.cpp:755
void ModifyAuraState(AuraStateType flag, bool apply)
Definition: Unit.cpp:10459
void UpdateEncounterState(EncounterCreditType type, uint32 creditEntry, Unit *source)
Definition: Map.cpp:3471

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

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

◆ FinishTargetProcessing()

void Spell::FinishTargetProcessing ( )
protected
8461{
8463}
void SendLogExecute()
Definition: Spell.cpp:5065

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
8924{
8925 std::stringstream sstr;
8926 sstr << std::boolalpha
8927 << "Id: " << GetSpellInfo()->Id << " OriginalCaster: " << m_originalCasterGUID.ToString()
8928 << " State: " << getState();
8929 return sstr.str();
8930}

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

◆ GetDelayMoment()

uint64 Spell::GetDelayMoment ( ) const
inline

◆ GetDelayStart()

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

References m_delayStart.

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

◆ GetDelayTrajectory()

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

References m_delayTrajectory.

◆ GetOriginalCaster()

Unit * Spell::GetOriginalCaster ( ) const
inline

◆ GetPowerCost()

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

References m_powerCost.

Referenced by Unit::HandleDummyAuraProc().

◆ GetSearcherTypeMask()

uint32 Spell::GetSearcherTypeMask ( SpellTargetObjectTypes  objType,
ConditionList condList 
)
2111{
2112 // this function selects which containers need to be searched for spell target
2114
2115 // filter searchers based on searched object type
2116 switch (objType)
2117 {
2124 break;
2128 break;
2129 default:
2130 break;
2131 }
2133 retMask &= ~GRID_MAP_TYPE_MASK_CORPSE;
2137 retMask &= GRID_MAP_TYPE_MASK_PLAYER;
2138
2139 if (condList)
2140 retMask &= sConditionMgr->GetSearcherTypeMaskForConditionList(*condList);
2141 return retMask;
2142}
@ 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:456
@ SPELL_ATTR3_ONLY_ON_GHOSTS
Definition: SharedDefines.h:505
@ SPELL_ATTR3_ONLY_ON_PLAYER
Definition: SharedDefines.h:501

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
583{ return m_spellValue; }

References m_spellValue.

Referenced by DoAllEffectOnTarget().

◆ getState()

◆ GetTriggeredByAuraTickNumber()

uint32 Spell::GetTriggeredByAuraTickNumber ( ) const
inline

◆ GetTriggeredCastFlags()

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

References _triggeredCastFlags.

◆ GetUniqueTargetInfo()

◆ handle_delayed()

uint64 Spell::handle_delayed ( uint64  t_offset)
4168{
4169 if (!UpdatePointers())
4170 {
4171 // finish the spell if UpdatePointers() returned false, something wrong happened there
4172 finish(false);
4173 return 0;
4174 }
4175
4176 Player* modOwner = m_caster->GetSpellModOwner();
4177 if (modOwner)
4178 modOwner->SetSpellModTakingSpell(this, true);
4179
4180 uint64 next_time = m_delayTrajectory;
4181
4183
4184 if (!m_immediateHandled && m_delayTrajectory <= t_offset)
4185 {
4187 m_immediateHandled = true;
4189 next_time = 0;
4190 }
4191
4192 bool single_missile = (m_targets.HasDst());
4193
4194 // 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)
4195 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
4196 {
4197 if (ihit->processed == false)
4198 {
4199 if (single_missile || ihit->timeDelay <= t_offset)
4200 {
4201 ihit->timeDelay = t_offset;
4202 DoAllEffectOnTarget(&(*ihit));
4203 }
4204 else if (next_time == 0 || ihit->timeDelay < next_time)
4205 next_time = ihit->timeDelay;
4206 }
4207 }
4208
4209 // now recheck gameobject targeting correctness
4210 for (std::list<GOTargetInfo>::iterator ighit = m_UniqueGOTargetInfo.begin(); ighit != m_UniqueGOTargetInfo.end(); ++ighit)
4211 {
4212 if (ighit->processed == false)
4213 {
4214 if (single_missile || ighit->timeDelay <= t_offset)
4215 DoAllEffectOnTarget(&(*ighit));
4216 else if (next_time == 0 || ighit->timeDelay < next_time)
4217 next_time = ighit->timeDelay;
4218 }
4219 }
4220
4222
4223 if (modOwner)
4224 modOwner->SetSpellModTakingSpell(this, false);
4225
4226 // All targets passed - need finish phase
4227 if (next_time == 0)
4228 {
4229 // spell is finished, perform some last features of the spell here
4231
4232 finish(true); // successfully finish spell cast
4233
4234 // return zero, spell is finished now
4235 return 0;
4236 }
4237 else
4238 {
4239 // spell is unfinished, return next execution time
4240 return next_time;
4241 }
4242}
void _handle_finish_phase()
Definition: Spell.cpp:4272
void PrepareTargetProcessing()
Definition: Spell.cpp:8455
void _handle_immediate_phase()
Definition: Spell.cpp:4244
void FinishTargetProcessing()
Definition: Spell.cpp:8460

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 ( )
4108{
4109 // start channeling if applicable
4110 if (m_spellInfo->IsChanneled())
4111 {
4112 int32 duration = m_spellInfo->GetDuration();
4114 duration = -1;
4115
4116 if (duration > 0)
4117 {
4118 // First mod_duration then haste - see Missile Barrage
4119 // Apply duration mod
4120 if (Player* modOwner = m_caster->GetSpellModOwner())
4121 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_DURATION, duration);
4122
4123 // Apply haste mods
4125 duration = int32(duration * m_caster->GetFloatValue(UNIT_MOD_CAST_SPEED));
4126
4129 m_channeledDuration = duration;
4130 SendChannelStart(duration);
4131 }
4132 else if (duration == -1)
4133 {
4136 SendChannelStart(duration);
4137 }
4138 }
4139
4141
4142 // process immediate effects (items, ground, etc.) also initialize some variables
4144
4145 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
4146 DoAllEffectOnTarget(&(*ihit));
4147
4148 for (std::list<GOTargetInfo>::iterator ihit = m_UniqueGOTargetInfo.begin(); ihit != m_UniqueGOTargetInfo.end(); ++ihit)
4149 DoAllEffectOnTarget(&(*ihit));
4150
4152
4153 // spell is finished, perform some last features of the spell here
4155
4156 // Remove used for cast item if need (it can be already nullptr after TakeReagents call
4157 TakeCastItem();
4158
4159 // handle ammo consumption for Hunter's volley spell
4161 TakeAmmo();
4162
4164 finish(true); // successfully finish spell cast (not last in case autorepeat or channel spell)
4165}
void AddInterruptMask(uint32 mask)
Definition: Unit.h:1502
void SendChannelStart(uint32 duration)
Definition: Spell.cpp:5198
void TakeAmmo()
Definition: Spell.cpp:5371

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

Referenced by _cast().

◆ HandleEffects()

void Spell::HandleEffects ( Unit pUnitTarget,
Item pItemTarget,
GameObject pGOTarget,
uint32  i,
SpellEffectHandleMode  mode 
)
5620{
5622 return;
5623
5624 effectHandleMode = mode;
5625 unitTarget = pUnitTarget;
5626 itemTarget = pItemTarget;
5627 gameObjTarget = pGOTarget;
5629
5630 uint8 eff = m_spellInfo->Effects[i].Effect;
5631
5632 LOG_DEBUG("spells.aura", "Spell: {} Effect : {}", m_spellInfo->Id, eff);
5633
5634 // we do not need DamageMultiplier here.
5635 damage = CalculateSpellDamage(i, nullptr);
5636
5637 bool preventDefault = CallScriptEffectHandlers((SpellEffIndex)i, mode);
5638
5639 if (!preventDefault && eff < TOTAL_SPELL_EFFECTS)
5640 {
5641 (this->*SpellEffects[eff])((SpellEffIndex)i);
5642 }
5643}
SpellEffIndex
Definition: SharedDefines.h:30
SpellEffects
Definition: SharedDefines.h:778
@ TOTAL_SPELL_EFFECTS
Definition: SharedDefines.h:943
WorldLocation _position
Definition: Spell.h:103
bool CallScriptEffectHandlers(SpellEffIndex effIndex, SpellEffectHandleMode mode)
Definition: Spell.cpp:8574

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

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

◆ HandleLaunchPhase()

void Spell::HandleLaunchPhase ( )
protected
8224{
8225 // handle effects with SPELL_EFFECT_HANDLE_LAUNCH mode
8226 for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i)
8227 {
8228 // don't do anything for empty effect
8229 if (!m_spellInfo->Effects[i].IsEffect())
8230 continue;
8231
8232 HandleEffects(nullptr, nullptr, nullptr, i, SPELL_EFFECT_HANDLE_LAUNCH);
8233 }
8234
8235 float multiplier[MAX_SPELL_EFFECTS];
8236 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
8237 if (m_applyMultiplierMask & (1 << i))
8238 multiplier[i] = m_spellInfo->Effects[i].CalcDamageMultiplier(m_originalCaster, this);
8239
8242 for (Unit::AuraEffectList::const_iterator j = Auras.begin(); j != Auras.end(); ++j)
8243 {
8244 if ((*j)->IsAffectedOnSpell(m_spellInfo))
8245 usesAmmo = false;
8246 }
8247
8249
8250 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
8251 {
8252 TargetInfo& target = *ihit;
8253
8254 uint32 mask = target.effectMask;
8255 if (!mask)
8256 continue;
8257
8258 // do not consume ammo anymore for Hunter's volley spell
8260 usesAmmo = false;
8261
8262 if (usesAmmo)
8263 {
8264 bool ammoTaken = false;
8265 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; i++)
8266 {
8267 if (!(mask & 1 << i))
8268 continue;
8269 switch (m_spellInfo->Effects[i].Effect)
8270 {
8276 ammoTaken = true;
8277 TakeAmmo();
8278 }
8279 if (ammoTaken)
8280 break;
8281 }
8282 }
8283
8284 DoAllEffectOnLaunchTarget(target, multiplier);
8285 }
8286
8288}
@ 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:780
void DoAllEffectOnLaunchTarget(TargetInfo &targetInfo, float *multiplier)
Definition: Spell.cpp:8290

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 ( )
5573{
5574 if (m_UniqueTargetInfo.empty())
5575 return;
5576
5578 return;
5579
5580 float threat = 0.0f;
5581 if (SpellThreatEntry const* threatEntry = sSpellMgr->GetSpellThreatEntry(m_spellInfo->Id))
5582 {
5583 if (threatEntry->apPctMod != 0.0f)
5584 threat += threatEntry->apPctMod * m_caster->GetTotalAttackPowerValue(BASE_ATTACK);
5585
5586 threat += threatEntry->flatMod;
5587 }
5589 threat += m_spellInfo->SpellLevel;
5590
5591 // past this point only multiplicative effects occur
5592 if (threat == 0.0f)
5593 return;
5594
5595 // 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
5596 threat /= m_UniqueTargetInfo.size();
5597
5598 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
5599 {
5600 float threatToAdd = threat;
5601 if (ihit->missCondition != SPELL_MISS_NONE)
5602 threatToAdd = 0.0f;
5603
5604 Unit* target = ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID);
5605 if (!target)
5606 continue;
5607
5608 bool IsFriendly = m_caster->IsFriendlyTo(target);
5609 // positive spells distribute threat among all units that are in combat with target, like healing
5611 target->getHostileRefMgr().threatAssist(m_caster, threatToAdd, m_spellInfo);
5612 // for negative spells threat gets distributed among affected targets
5613 else if (!m_spellInfo->_IsPositiveSpell() && !IsFriendly && target->CanHaveThreatList())
5614 target->AddThreat(m_caster, threatToAdd, m_spellInfo->GetSchoolMask(), m_spellInfo);
5615 }
5616 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()));
5617}
@ SPELL_ATTR0_CU_NO_INITIAL_THREAT
Definition: SpellInfo.h:180
static bool IsFriendly(Creature *piece, Creature *target)
Definition: boss_chess_event.cpp:178
bool _IsPositiveSpell() const
Definition: SpellInfo.cpp:2839
Definition: SpellMgr.h:385

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

Referenced by _handle_immediate_phase().

◆ HasGlobalCooldown()

bool Spell::HasGlobalCooldown ( ) const
protected

◆ HasTriggeredCastFlag()

◆ HaveTargetsForEffect()

bool Spell::HaveTargetsForEffect ( uint8  effect) const
8094{
8095 for (std::list<TargetInfo>::const_iterator itr = m_UniqueTargetInfo.begin(); itr != m_UniqueTargetInfo.end(); ++itr)
8096 if (itr->effectMask & (1 << effect))
8097 return true;
8098
8099 for (std::list<GOTargetInfo>::const_iterator itr = m_UniqueGOTargetInfo.begin(); itr != m_UniqueGOTargetInfo.end(); ++itr)
8100 if (itr->effectMask & (1 << effect))
8101 return true;
8102
8103 for (std::list<ItemTargetInfo>::const_iterator itr = m_UniqueItemInfo.begin(); itr != m_UniqueItemInfo.end(); ++itr)
8104 if (itr->effectMask & (1 << effect))
8105 return true;
8106
8107 return false;
8108}

References m_UniqueGOTargetInfo, m_UniqueItemInfo, and m_UniqueTargetInfo.

◆ InitEffectExecuteData()

void Spell::InitEffectExecuteData ( uint8  effIndex)
protected
8466{
8467 ASSERT(effIndex < MAX_SPELL_EFFECTS);
8468 if (!m_effectExecuteData[effIndex])
8469 {
8470 m_effectExecuteData[effIndex] = new ByteBuffer(0x20);
8471 // first dword - target counter
8472 *m_effectExecuteData[effIndex] << uint32(1);
8473 }
8474 else
8475 {
8476 // increase target counter by one
8477 uint32 count = (*m_effectExecuteData[effIndex]).read<uint32>(0);
8478 (*m_effectExecuteData[effIndex]).put<uint32>(0, ++count);
8479 }
8480}

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

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

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

◆ IsAutoActionResetSpell()

bool Spell::IsAutoActionResetSpell ( ) const
Todo:
changed SPELL_INTERRUPT_FLAG_AUTOATTACK -> SPELL_INTERRUPT_FLAG_INTERRUPT to fix compile - is this check correct at all?
8068{
8071 {
8072 return false;
8073 }
8074
8076 {
8077 return false;
8078 }
8079
8080 return true;
8081}
@ SPELL_ATTR6_DOESNT_RESET_SWING_TIMER_IF_INSTANT
Definition: SharedDefines.h:629

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

Referenced by _cast().

◆ IsAutoRepeat()

bool Spell::IsAutoRepeat ( ) const
inline

◆ IsChannelActive()

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

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

Referenced by Creature::IsMovementPreventedByCasting().

◆ isDelayableNoMore()

bool Spell::isDelayableNoMore ( )
inlineprotected
629 {
630 if (m_delayAtDamageCount >= 2)
631 return true;
632
634 return false;
635 }

References m_delayAtDamageCount.

Referenced by Delayed(), and DelayedChannel().

◆ IsDeletable()

◆ IsIgnoringCooldowns()

bool Spell::IsIgnoringCooldowns ( ) const

◆ IsInterruptable()

bool Spell::IsInterruptable ( ) const
inline
560{ 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
8216{
8217 if (target->IsAlive())
8219
8221}
bool IsRequiringDeadTarget() const
Definition: SpellInfo.cpp:1221
bool IsAllowingDeadTarget() const
Definition: SpellInfo.cpp:1226

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

Referenced by UpdateChanneledTargetList().

◆ LoadScripts()

void Spell::LoadScripts ( )
8489{
8490 if (_scriptsLoaded)
8491 return;
8492 _scriptsLoaded = true;
8493 sScriptMgr->CreateSpellScripts(m_spellInfo->Id, m_loadedScripts);
8494 for (std::list<SpellScript*>::iterator itr = m_loadedScripts.begin(); itr != m_loadedScripts.end();)
8495 {
8496 if (!(*itr)->_Load(this))
8497 {
8498 std::list<SpellScript*>::iterator bitr = itr;
8499 ++itr;
8500 delete (*bitr);
8501 m_loadedScripts.erase(bitr);
8502 continue;
8503 }
8504 LOG_DEBUG("spells.aura", "Spell::LoadScripts: Script `{}` for spell `{}` is loaded now", (*itr)->_GetScriptName()->c_str(), m_spellInfo->Id);
8505 (*itr)->Register();
8506 ++itr;
8507 }
8508}

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 ( )
8894{
8895 if (!m_caster || !m_caster->IsInWorld())
8896 return;
8897
8898 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(24390);
8899
8900 // Make sure the player is sending a valid GO target and lock ID. SPELL_EFFECT_OPEN_LOCK
8901 // can succeed with a lockId of 0
8902 if (m_spellInfo->Id == 21651)
8903 {
8904 if (GameObject* go = m_targets.GetGOTarget())
8905 {
8906 LockEntry const* lockInfo = sLockStore.LookupEntry(go->GetGOInfo()->GetLockId());
8907 if (lockInfo && lockInfo->Index[1] == LOCKTYPE_SLOW_OPEN)
8908 {
8909 Spell* visual = new Spell(m_caster, spellInfo, TRIGGERED_NONE);
8910 visual->prepare(&m_targets);
8911 }
8912 }
8913 }
8914}
@ TRIGGERED_NONE
Definition: SpellDefines.h:131
@ LOCKTYPE_SLOW_OPEN
Definition: SharedDefines.h:2608

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

3470{
3471 if (m_CastItem)
3472 {
3474 }
3475 else
3476 {
3478 }
3479
3480 InitExplicitTargets(*targets);
3481
3482 if (!sScriptMgr->CanPrepare(this, targets, triggeredByAura))
3483 {
3484 finish(false);
3485 return SPELL_FAILED_UNKNOWN;
3486 }
3487
3488 // Fill aura scaling information
3490 {
3491 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
3492 {
3493 if (m_spellInfo->Effects[i].Effect == SPELL_EFFECT_APPLY_AURA ||
3496 {
3497 // Change aura with ranks only if basepoints are taken from spellInfo and aura is positive
3499 {
3500 m_auraScaleMask |= (1 << i);
3501 if (m_spellValue->EffectBasePoints[i] != m_spellInfo->Effects[i].BasePoints)
3502 {
3503 m_auraScaleMask = 0;
3504 break;
3505 }
3506 }
3507 }
3508 }
3509 }
3510
3512
3513 if (triggeredByAura)
3514 {
3515 m_triggeredByAuraSpell.Init(triggeredByAura);
3516 }
3517
3518 // create and add update event for this spell
3519 _spellEvent = new SpellEvent(this);
3521
3523 {
3525 finish(false);
3527 }
3528
3529 //Prevent casting at cast another spell (ServerSide check)
3531 {
3533 finish(false);
3535 }
3536
3537 LoadScripts();
3538
3539 OnSpellLaunch();
3540
3542
3543 // Set combo point requirement
3545 m_needComboPoints = false;
3546
3547 SpellCastResult result = CheckCast(true);
3548 if (result != SPELL_CAST_OK && !IsAutoRepeat()) //always cast autorepeat dummy for triggering
3549 {
3550 // Periodic auras should be interrupted when aura triggers a spell which can't be cast
3551 // for example bladestorm aura should be removed on disarm as of patch 3.3.5
3552 // channeled periodic spells should be affected by this (arcane missiles, penance, etc)
3553 // a possible alternative sollution for those would be validating aura target on unit state change
3554 if (m_caster->IsPlayer() && triggeredByAura && triggeredByAura->IsPeriodic() && !triggeredByAura->GetBase()->IsPassive())
3555 {
3557 triggeredByAura->GetBase()->SetDuration(0);
3558 }
3559
3560 // Allows to cast melee attack spell if result is SPELL_FAILED_OUT_OF_RANGE
3562 {
3563 SendCastResult(result);
3564
3565 finish(false);
3566 return result;
3567 }
3568 }
3569
3570 // Prepare data for triggers
3571 prepareDataForTriggerSystem(triggeredByAura);
3572
3573 // calculate cast time (calculated after first CheckCast check to prevent charge counting for first CheckCast fail)
3575
3576 if (m_caster->IsPlayer())
3578 m_casttime = 0;
3579
3580 // don't allow channeled spells / spells with cast time to be casted while moving
3581 // (even if they are interrupted on moving, spells with almost immediate effect get to have their effect processed before movement interrupter kicks in)
3583 {
3584 // 1. Has casttime, 2. Or doesn't have flag to allow action during channel
3586 {
3588 finish(false);
3589 return SPELL_FAILED_MOVING;
3590 }
3591 }
3592
3593 // xinef: if spell have nearby target entry only, do not allow to cast if no targets are found
3594 if (m_CastItem)
3595 {
3596 bool selectTargets = false;
3597 bool nearbyDest = false;
3598
3599 for (uint8 i = EFFECT_0; i < MAX_SPELL_EFFECTS; ++i)
3600 {
3601 if (!m_spellInfo->Effects[i].IsEffect())
3602 continue;
3603
3604 if (m_spellInfo->Effects[i].TargetA.GetSelectionCategory() != TARGET_SELECT_CATEGORY_NEARBY || m_spellInfo->Effects[i].TargetA.GetCheckType() != TARGET_CHECK_ENTRY)
3605 {
3606 selectTargets = false;
3607 break;
3608 }
3609
3610 if (m_spellInfo->Effects[i].TargetA.GetObjectType() == TARGET_OBJECT_TYPE_DEST)
3611 {
3612 nearbyDest = true;
3613 }
3614
3615 // xinef: by default set it to false, and to true if any valid target is found
3616 selectTargets = true;
3617 }
3618
3619 if (selectTargets)
3620 {
3622 _spellTargetsSelected = true;
3623 bool spellFailed = false;
3624
3625 if (m_UniqueTargetInfo.empty() && m_UniqueGOTargetInfo.empty())
3626 {
3627 // no valid nearby target unit or game object found; check if nearby destination type
3628 if (nearbyDest)
3629 {
3630 if (!m_targets.HasDst())
3631 {
3632 // no valid target destination
3633 spellFailed = true;
3634 }
3635 }
3636 else
3637 {
3638 spellFailed = true;
3639 }
3640 }
3641
3642 if (spellFailed)
3643 {
3645 finish(false);
3647 }
3648 }
3649 }
3650
3651 // set timer base at cast time
3652 ReSetTimer();
3653
3654 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());
3655
3657 {
3659 }
3660
3661 //Containers for channeled spells have to be set
3662 //TODO:Apply this to all casted spells if needed
3663 // Why check duration? 29350: channelled triggers channelled
3665 cast(true);
3666 else
3667 {
3668 // stealth must be removed at cast starting (at show channel bar)
3669 // skip triggered spell (item equip spell casting and other not explicit character casts/item uses)
3671 {
3672 // Farsight spells exception
3673 uint32 exceptSpellId = 0;
3675 {
3676 exceptSpellId = m_spellInfo->Id;
3677 }
3678
3681 }
3682
3685
3686 // set target for proper facing
3688 {
3691 {
3692 // Xinef: Creature should focus to cast target if there is explicit target or self if casting positive spell
3693 // Xinef: Creature should not rotate when casting spell... based on halion behavior
3695 }
3696 }
3697
3698 //item: first cast may destroy item and second cast causes crash
3699 // xinef: removed !m_spellInfo->StartRecoveryTime
3700 // second los check failed in events
3701 // xinef: removed itemguid check, currently there is no such item in database
3703 cast(true);
3704
3707 }
3708
3709 return SPELL_CAST_OK;
3710}
@ CHEAT_CASTTIME
Definition: Player.h:1000
@ 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:813
@ SPELL_EFFECT_APPLY_AREA_AURA_RAID
Definition: SharedDefines.h:843
@ SPELL_ATTR0_ALLOW_WHILE_SITTING
Definition: SharedDefines.h:409
void FocusTarget(Spell const *focusSpell, WorldObject const *target)
Definition: Creature.cpp:3538
void SetCurrentCastedSpell(Spell *pSpell)
Definition: Unit.cpp:3941
bool IsSitState() const
Definition: Unit.cpp:16667
Definition: Spell.cpp:520
void Init(AuraEffect const *aurEff)
Definition: Spell.cpp:8916
void LoadScripts()
Definition: Spell.cpp:8488
void cast(bool skipCheck=false)
Definition: Spell.cpp:3783
void prepareDataForTriggerSystem(AuraEffect const *triggeredByAura)
Definition: Spell.cpp:2292
void SendSpellStart()
Definition: Spell.cpp:4709
void TriggerGlobalCooldown()
Definition: Spell.cpp:8832
void OnSpellLaunch()
Definition: Spell.cpp:8893
CurrentSpellTypes GetCurrentContainer() const
Definition: Spell.cpp:7903
void ReSetTimer()
Definition: Spell.h:550
void InitExplicitTargets(SpellCastTargets const &targets)
Definition: Spell.cpp:714
bool IsActionAllowedChannel() const
Definition: SpellInfo.cpp:1260
int32 GetMaxDuration() const
Definition: SpellInfo.cpp:2344
uint32 Attributes
Definition: SpellInfo.h:324
bool IsBreakingStealth() const
Definition: SpellInfo.cpp:1270

References _spellEvent, _spellTargetsSelected, _triggeredCastFlags, EventProcessor::AddEvent(), SpellInfo::Attributes, AURA_INTERRUPT_FLAG_CAST, AURA_INTERRUPT_FLAG_NOT_SEATED, AURA_INTERRUPT_FLAG_SPELL_ATTACK, SpellInfo::AuraInterruptFlags, SpellInfo::CalcCastTime(), SpellInfo::CalcPowerCost(), EventProcessor::CalculateTime(), cast(), CHEAT_CASTTIME, CheckCast(), CURRENT_GENERIC_SPELL, DISABLE_TYPE_SPELL, EFFECT_0, SpellValue::EffectBasePoints, SpellInfo::Effects, ObjectGuid::Empty, finish(), Creature::FocusTarget(), AuraEffect::GetBase(), Player::GetCommandStatus(), GetCurrentContainer(), Object::GetEntry(), Object::GetGUID(), SpellInfo::GetMaxDuration(), SpellCastTargets::GetObjectTarget(), SpellCastTargets::GetTargetMask(), SpellCastTargets::HasDst(), SpellInfo::HasEffect(), HasTriggeredCastFlag(), SpellInfo::Id, TriggeredByAuraSpellData::Init(), InitExplicitTargets(), SpellInfo::InterruptFlags, SpellInfo::IsActionAllowedChannel(), IsAutoRepeat(), SpellInfo::IsBreakingStealth(), SpellInfo::IsChanneled(), Unit::IsControlledByPlayer(), Object::IsCreature(), DisableMgr::IsDisabledFor(), Creature::IsInEvadeMode(), Unit::isMoving(), IsNextMeleeSwingSpell(), Unit::IsNonMeleeSpellCast(), Aura::IsPassive(), SpellInfo::IsPassive(), AuraEffect::IsPeriodic(), Object::IsPlayer(), SpellInfo::IsPositive(), SpellInfo::IsPositiveEffect(), Unit::IsSitState(), Unit::IsTotem(), IsTriggered(), LoadScripts(), LOG_DEBUG, m_auraScaleMask, m_cast_count, m_caster, m_CastItem, m_castItemGUID, m_casttime, 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(), 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
2293{
2294 //==========================================================================================
2295 // Now fill data for trigger system, need know:
2296 // can spell trigger another or not (m_canTrigger)
2297 // Create base triggers flags for Attacker and Victim (m_procAttacker, m_procVictim and m_procEx)
2298 //==========================================================================================
2299
2301 // Get data for type of attack and fill base info for trigger
2302 switch (m_spellInfo->DmgClass)
2303 {
2306 if (m_attackType == OFF_ATTACK)
2308 else
2311 break;
2313 // Auto attack
2315 {
2318 }
2319 else // Ranged spell attack
2320 {
2323 }
2324 break;
2325 default:
2328 && m_spellInfo->HasAttribute(SPELL_ATTR2_AUTO_REPEAT)) // Wands auto attack
2329 {
2332 }
2333 // For other spells trigger procflags are set in Spell::DoAllEffectOnTarget
2334 // Because spell positivity is dependant on target
2335 }
2337
2338 // Hunter trap spells - activation proc for Lock and Load, Entrapment and Misdirection
2340 (m_spellInfo->SpellFamilyFlags[0] & 0x18 || // Freezing and Frost Trap, Freezing Arrow
2341 m_spellInfo->Id == 57879 || m_spellInfo->Id == 45145 || // Snake Trap - done this way to avoid double proc
2342 m_spellInfo->SpellFamilyFlags[2] & 0x00064000)) // Explosive and Immolation Trap
2343 {
2345 }
2346
2347 /* Effects which are result of aura proc from triggered spell cannot proc
2348 to prevent chain proc of these spells */
2349
2350 // Hellfire Effect - trigger as DOT
2352 {
2355 }
2356
2357 // Ranged autorepeat attack is set as triggered spell - ignore it
2359 {
2366 }
2367 // Totem casts require spellfamilymask defined in spell_proc_event to proc
2370}
@ 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:486
@ SPELL_ATTR3_NOT_A_PROC
Definition: SharedDefines.h:502

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

Referenced by prepare().

◆ PrepareScriptHitHandlers()

void Spell::PrepareScriptHitHandlers ( )
protected
8569{
8570 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8571 (*scritr)->_InitHit();
8572}

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
8743{
8746 {
8747 SpellInfo const* excludeCasterSpellInfo = sSpellMgr->GetSpellInfo(m_spellInfo->ExcludeCasterAuraSpell);
8748 if (excludeCasterSpellInfo && !excludeCasterSpellInfo->IsPositive())
8750 SpellInfo const* excludeTargetSpellInfo = sSpellMgr->GetSpellInfo(m_spellInfo->ExcludeTargetAuraSpell);
8751 if (excludeTargetSpellInfo && !excludeTargetSpellInfo->IsPositive())
8753 }
8754
8757 {
8759 {
8760 if (m_spellInfo->SpellFamilyFlags[1] & 0x40000000)
8761 {
8763 for(Unit::AuraEffectList::const_iterator itr = mVindication.begin(); itr != mVindication.end(); ++itr)
8764 {
8765 if ((*itr)->GetSpellInfo()->Effects[EFFECT_0].TriggerSpell == 26017 )
8766 {
8767 m_preCastSpell = 26017;
8768 break;
8769 }
8770 else if ((*itr)->GetSpellInfo()->Effects[EFFECT_0].TriggerSpell == 67 )
8771 m_preCastSpell = 67;
8772 }
8773 }
8774 break;
8775 }
8776 case SPELLFAMILY_DRUID:
8777 {
8778 // Faerie Fire (Feral)
8780 m_preCastSpell = 60089;
8781
8782 break;
8783 }
8784 }
8785
8786 // handle SPELL_AURA_ADD_TARGET_TRIGGER auras:
8787 // save auras which were present on spell caster on cast, to prevent triggered auras from affecting caster
8788 // and to correctly calculate proc chance when combopoints are present
8790 for (Unit::AuraEffectList::const_iterator i = targetTriggers.begin(); i != targetTriggers.end(); ++i)
8791 {
8792 if (!(*i)->IsAffectedOnSpell(m_spellInfo))
8793 continue;
8794 SpellInfo const* auraSpellInfo = (*i)->GetSpellInfo();
8795 uint32 auraSpellIdx = (*i)->GetEffIndex();
8796 if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(auraSpellInfo->Effects[auraSpellIdx].TriggerSpell))
8797 {
8798 // calculate the chance using spell base amount, because aura amount is not updated on combo-points change
8799 // this possibly needs fixing
8800 int32 auraBaseAmount = (*i)->GetBaseAmount();
8801 // proc chance is stored in effect amount
8802 int32 chance = m_caster->CalculateSpellDamage(nullptr, auraSpellInfo, auraSpellIdx, &auraBaseAmount);
8803 // build trigger and add to the list
8804 HitTriggerSpell spellTriggerInfo;
8805 spellTriggerInfo.triggeredSpell = spellInfo;
8806 spellTriggerInfo.triggeredByAura = auraSpellInfo;
8807 spellTriggerInfo.triggeredByEffIdx = (*i)->GetEffIndex();
8808 spellTriggerInfo.chance = chance * (*i)->GetBase()->GetStackAmount();
8809 m_hitTriggerSpells.push_back(spellTriggerInfo);
8810 }
8811 }
8812}
@ FORM_DIREBEAR
Definition: UnitDefines.h:77
@ FORM_BEAR
Definition: UnitDefines.h:74
@ SPELL_AURA_PROC_TRIGGER_SPELL
Definition: SpellAuraDefines.h:105
@ SPELL_AURA_ADD_TARGET_TRIGGER
Definition: SpellAuraDefines.h:172
uint32 ExcludeTargetAuraSpell
Definition: SpellInfo.h:346

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

Referenced by _cast().

◆ RecalculateDelayMomentForDst()

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

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 
)
2187{
2188 uint32 containerTypeMask = GetSearcherTypeMask(objectType, condList);
2189 if (!containerTypeMask)
2190 return;
2191 Acore::WorldObjectSpellAreaTargetCheck check(range, position, m_caster, referer, m_spellInfo, selectionType, condList);
2192 Acore::WorldObjectListSearcher<Acore::WorldObjectSpellAreaTargetCheck> searcher(m_caster, targets, check, containerTypeMask);
2193 SearchTargets<Acore::WorldObjectListSearcher<Acore::WorldObjectSpellAreaTargetCheck> > (searcher, containerTypeMask, m_caster, position, range);
2194}
Definition: GridNotifiers.h:239
uint32 GetSearcherTypeMask(SpellTargetObjectTypes objType, ConditionList *condList)
Definition: Spell.cpp:2110

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

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 
)
2175{
2176 WorldObject* target = nullptr;
2177 uint32 containerTypeMask = GetSearcherTypeMask(objectType, condList);
2178 if (!containerTypeMask)
2179 return nullptr;
2180 Acore::WorldObjectSpellNearbyTargetCheck check(range, m_caster, m_spellInfo, selectionType, condList);
2182 SearchTargets<Acore::WorldObjectLastSearcher<Acore::WorldObjectSpellNearbyTargetCheck> > (searcher, containerTypeMask, m_caster, m_caster, range);
2183 return target;
2184}
Definition: GridNotifiers.h:219

References GetSearcherTypeMask(), m_caster, and m_spellInfo.

Referenced by SelectImplicitNearbyTargets().

◆ SearchTargets()

template<class SEARCHER >
void Spell::SearchTargets ( SEARCHER &  searcher,
uint32  containerMask,
Unit referer,
Position const *  pos,
float  radius 
)
2146{
2147 if (!containerMask)
2148 return;
2149
2150 // search world and grid for possible targets
2151 bool searchInGrid = containerMask & (GRID_MAP_TYPE_MASK_CREATURE | GRID_MAP_TYPE_MASK_GAMEOBJECT);
2152 bool searchInWorld = containerMask & (GRID_MAP_TYPE_MASK_CREATURE | GRID_MAP_TYPE_MASK_PLAYER | GRID_MAP_TYPE_MASK_CORPSE);
2153
2154 if (searchInGrid || searchInWorld)
2155 {
2156 float x, y;
2157 x = pos->GetPositionX();
2158 y = pos->GetPositionY();
2159
2161 Cell cell(p);
2162 cell.SetNoCreate();
2163
2164 Map* map = referer->GetMap();
2165
2166 if (searchInWorld)
2167 Cell::VisitWorldObjects(x, y, map, searcher, radius);
2168
2169 if (searchInGrid)
2170 Cell::VisitGridObjects(x, y, map, searcher, radius);
2171 }
2172}
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 
)
924{
925 if (!targetType.GetTarget())
926 return;
927
928 uint32 effectMask = 1 << effIndex;
929 // set the same target list for all effects
930 // some spells appear to need this, however this requires more research
931 switch (targetType.GetSelectionCategory())
932 {
936 {
937 // targets for effect already selected
938 if (effectMask & processedEffectMask)
939 {
940 return;
941 }
942
943 auto const& effects = GetSpellInfo()->Effects;
944
945 // choose which targets we can select at once
946 for (uint32 j = effIndex + 1; j < MAX_SPELL_EFFECTS; ++j)
947 {
948 if (effects[j].IsEffect() &&
949 effects[effIndex].TargetA.GetTarget() == effects[j].TargetA.GetTarget() &&
950 effects[effIndex].TargetB.GetTarget() == effects[j].TargetB.GetTarget() &&
951 effects[effIndex].ImplicitTargetConditions == effects[j].ImplicitTargetConditions &&
952 effects[effIndex].CalcRadius(m_caster) == effects[j].CalcRadius(m_caster) &&
954 {
955 effectMask |= 1 << j;
956 }
957 }
958 processedEffectMask |= effectMask;
959 break;
960 }
961 default:
962 break;
963 }
964
965 switch (targetType.GetSelectionCategory())
966 {
968 SelectImplicitChannelTargets(effIndex, targetType);
969 break;
971 SelectImplicitNearbyTargets(effIndex, targetType, effectMask);
972 break;
974 SelectImplicitConeTargets(effIndex, targetType, effectMask);
975 break;
977 SelectImplicitAreaTargets(effIndex, targetType, effectMask);
978 break;
980 // just in case there is no dest, explanation in SelectImplicitDestDestTargets
981 CheckDst();
982
983 SelectImplicitTrajTargets(effIndex, targetType);
984 break;
986 switch (targetType.GetObjectType())
987 {
989 switch (targetType.GetReferenceType())
990 {
993 break;
994 default:
995 ASSERT(false && "Spell::SelectEffectImplicitTargets: received not implemented select target reference type for TARGET_TYPE_OBJECT_SRC");
996 break;
997 }
998 break;
1000 switch (targetType.GetReferenceType())
1001 {
1003 SelectImplicitCasterDestTargets(effIndex, targetType);
1004 break;
1006 SelectImplicitTargetDestTargets(effIndex, targetType);
1007 break;
1009 SelectImplicitDestDestTargets(effIndex, targetType);
1010 break;
1011 default:
1012 ASSERT(false && "Spell::SelectEffectImplicitTargets: received not implemented select target reference type for TARGET_TYPE_OBJECT_DEST");
1013 break;
1014 }
1015 break;
1016 default:
1017 switch (targetType.GetReferenceType())
1018 {
1020 SelectImplicitCasterObjectTargets(effIndex, targetType);
1021 break;
1023 SelectImplicitTargetObjectTargets(effIndex, targetType);
1024 break;
1025 default:
1026 ASSERT(false && "Spell::SelectEffectImplicitTargets: received not implemented select target reference type for TARGET_TYPE_OBJECT");
1027 break;
1028 }
1029 break;
1030 }
1031 break;
1033 LOG_DEBUG("spells.aura", "SPELL: target type {}, found in spellID {}, effect {} is not implemented yet!", m_spellInfo->Id, effIndex, targetType.GetTarget());
1034 break;
1035 default:
1036 ASSERT(false && "Spell::SelectEffectImplicitTargets: received not implemented select target category");
1037 break;
1038 }
1039}
@ 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:1718
void CheckDst()
Definition: Spell.h:492
void SelectImplicitTrajTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition: Spell.cpp:1867
void SelectImplicitConeTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType, uint32 effMask)
Definition: Spell.cpp:1211
void SelectImplicitTargetDestTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition: Spell.cpp:1681
void SelectImplicitAreaTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType, uint32 effMask)
Definition: Spell.cpp:1261
void SelectImplicitChannelTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition: Spell.cpp:1041
void SelectImplicitTargetObjectTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition: Spell.cpp:1804
void SelectImplicitCasterObjectTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition: Spell.cpp:1757
void SelectImplicitNearbyTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType, uint32 effMask)
Definition: Spell.cpp:1097
bool CheckScriptEffectImplicitTargets(uint32 effIndex, uint32 effIndexToCheck)
Definition: Spell.cpp:8703
void SelectImplicitCasterDestTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition: Spell.cpp:1343

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
2028{
2029 // special case for SPELL_EFFECT_SUMMON_RAF_FRIEND and SPELL_EFFECT_SUMMON_PLAYER
2031 switch (m_spellInfo->Effects[effIndex].Effect)
2032 {
2036 {
2038
2040
2041 if (target && target->ToPlayer())
2042 AddUnitTarget(target->ToUnit(), 1 << effIndex, false);
2043 }
2044 return;
2045 default:
2046 break;
2047 }
2048
2049 // select spell implicit targets based on effect type
2050 if (!m_spellInfo->Effects[effIndex].GetImplicitTargetType())
2051 return;
2052
2053 uint32 targetMask = m_spellInfo->Effects[effIndex].GetMissingTargetMask();
2054
2055 if (!targetMask)
2056 return;
2057
2058 WorldObject* target = nullptr;
2059
2060 switch (m_spellInfo->Effects[effIndex].GetImplicitTargetType())
2061 {
2062 // add explicit object target or self to the target map
2064 // player which not released his spirit is Unit, but target flag for it is TARGET_FLAG_CORPSE_MASK
2066 {
2068 target = unitTarget;
2069 else if (targetMask & TARGET_FLAG_CORPSE_MASK)
2070 {
2071 if (Corpse* corpseTarget = m_targets.GetCorpseTarget())
2072 {
2074 if (Player* owner = ObjectAccessor::FindPlayer(corpseTarget->GetOwnerGUID()))
2075 target = owner;
2076 }
2077 }
2078 else //if (targetMask & TARGET_FLAG_UNIT_MASK)
2079 target = m_caster;
2080 }
2081 if (targetMask & TARGET_FLAG_ITEM_MASK)
2082 {
2084 AddItemTarget(itemTarget, 1 << effIndex);
2085 return;
2086 }
2087 if (targetMask & TARGET_FLAG_GAMEOBJECT_MASK)
2088 target = m_targets.GetGOTarget();
2089 break;
2090 // add self to the target map
2092 if (targetMask & TARGET_FLAG_UNIT_MASK)
2093 target = m_caster;
2094 break;
2095 default:
2096 break;
2097 }
2098
2100
2101 if (target)
2102 {
2103 if (target->ToUnit())
2104 AddUnitTarget(target->ToUnit(), 1 << effIndex, false);
2105 else if (target->ToGameObject())
2106 AddGOTarget(target->ToGameObject(), 1 << effIndex);
2107 }
2108}
@ 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:210
Corpse * GetCorpseTarget() const
Definition: Spell.cpp:295
void AddGOTarget(GameObject *target, uint32 effectMask)
Definition: Spell.cpp:2514
void AddUnitTarget(Unit *target, uint32 effectMask, bool checkIfValid=true, bool implicit=true)
Definition: Spell.cpp:2381
void AddItemTarget(Item *item, uint32 effectMask)
Definition: Spell.cpp:2576
void CallScriptObjectTargetSelectHandlers(WorldObject *&target, SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition: Spell.cpp:8675
Definition: SpellInfo.h:217

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

Referenced by SelectSpellTargets().

◆ SelectExplicitTargets()

void Spell::SelectExplicitTargets ( )
784{
785 // here go all explicit target changes made to explicit targets after spell prepare phase is finished
786 if (Unit* target = m_targets.GetUnitTarget())
787 {
788 // check for explicit target redirection, for Grounding Totem for example
792 {
793 Unit* redirect;
794 switch (m_spellInfo->DmgClass)
795 {
798 break;
802 break;
803 default:
804 redirect = nullptr;
805 break;
806 }
807 if (redirect && (redirect != target))
808 {
809 m_targets.SetUnitTarget(redirect);
811 }
812 }
813 }
814}
Unit * GetMeleeHitRedirectTarget(Unit *victim, SpellInfo const *spellInfo=nullptr)
Definition: Unit.cpp:11014
Unit * GetMagicHitRedirectTarget(Unit *victim, SpellInfo const *spellInfo)
Definition: Unit.cpp:10976

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

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

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

Referenced by SelectEffectImplicitTargets().

◆ SelectImplicitCasterObjectTargets()

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

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

Referenced by SelectEffectImplicitTargets().

◆ SelectImplicitChainTargets()

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

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

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 
)
1212{
1213 if (targetType.GetReferenceType() != TARGET_REFERENCE_TYPE_CASTER)
1214 {
1215 ASSERT(false && "Spell::SelectImplicitConeTargets: received not implemented target reference type");
1216 return;
1217 }
1218 std::list<WorldObject*> targets;
1219 SpellTargetObjectTypes objectType = targetType.GetObjectType();
1220 SpellTargetCheckTypes selectionType = targetType.GetCheckType();
1221 ConditionList* condList = m_spellInfo->Effects[effIndex].ImplicitTargetConditions;
1222 float coneAngle = M_PI / 2;
1223 float radius = m_spellInfo->Effects[effIndex].CalcRadius(m_caster) * m_spellValue->RadiusMod;
1224
1225 if (uint32 containerTypeMask = GetSearcherTypeMask(objectType, condList))
1226 {
1227 Acore::WorldObjectSpellConeTargetCheck check(coneAngle, radius, m_caster, m_spellInfo, selectionType, condList);
1228 Acore::WorldObjectListSearcher<Acore::WorldObjectSpellConeTargetCheck> searcher(m_caster, targets, check, containerTypeMask);
1229 SearchTargets<Acore::WorldObjectListSearcher<Acore::WorldObjectSpellConeTargetCheck> >(searcher, containerTypeMask, m_caster, m_caster, radius);
1230
1231 CallScriptObjectAreaTargetSelectHandlers(targets, effIndex, targetType);
1232
1233 if (!targets.empty())
1234 {
1235 // Other special target selection goes here
1236 if (uint32 maxTargets = m_spellValue->MaxAffectedTargets)
1237 {
1239 for (Unit::AuraEffectList::const_iterator j = Auras.begin(); j != Auras.end(); ++j)
1240 if ((*j)->IsAffectedOnSpell(m_spellInfo))
1241 maxTargets += (*j)->GetAmount();
1242
1243 Acore::Containers::RandomResize(targets, maxTargets);
1244 }
1245
1246 for (std::list<WorldObject*>::iterator itr = targets.begin(); itr != targets.end(); ++itr)
1247 {
1248 if (Unit* unit = (*itr)->ToUnit())
1249 {
1250 AddUnitTarget(unit, effMask, false);
1251 }
1252 else if (GameObject* gObjTarget = (*itr)->ToGameObject())
1253 {
1254 AddGOTarget(gObjTarget, effMask);
1255 }
1256 }
1257 }
1258 }
1259}
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 
)
1719{
1720 // set destination to caster if no dest provided
1721 // can only happen if previous destination target could not be set for some reason
1722 // (not found nearby target, or channel target for example
1723 // maybe we should abort the spell in such case?
1724 CheckDst();
1725
1727
1728 switch (targetType.GetTarget())
1729 {
1733 case TARGET_DEST_DEST:
1734 return;
1735 case TARGET_DEST_TRAJ:
1736 SelectImplicitTrajTargets(effIndex, targetType);
1737 return;
1738 default:
1739 {
1740 float angle = targetType.CalcDirectionAngle();
1741 float dist = m_spellInfo->Effects[effIndex].CalcRadius(m_caster);
1742 if (targetType.GetTarget() == TARGET_DEST_DEST_RANDOM)
1743 dist *= float(rand_norm());
1744
1745 Position pos = dest._position;
1746 m_caster->MovePosition(pos, dist, angle);
1747
1748 dest.Relocate(pos);
1749 break;
1750 }
1751 }
1752
1753 CallScriptDestinationTargetSelectHandlers(dest, effIndex, targetType);
1754 m_targets.ModDst(dest);
1755}
@ TARGET_DEST_DYNOBJ_ENEMY
Definition: SharedDefines.h:1432
@ TARGET_DEST_DEST_RANDOM
Definition: SharedDefines.h:1490
@ TARGET_DEST_DEST
Definition: SharedDefines.h:1491
@ TARGET_DEST_DYNOBJ_NONE
Definition: SharedDefines.h:1492
@ TARGET_DEST_DYNOBJ_ALLY
Definition: SharedDefines.h:1433
@ TARGET_DEST_TRAJ
Definition: SharedDefines.h:1493
void MovePosition(Position &pos, float dist, float angle)
Definition: Object.cpp:2776
void ModDst(Position const &pos)
Definition: Spell.cpp:437
SpellDestination const * GetDst() const
Definition: Spell.cpp:397

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

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 
)
1682{
1684
1685 SpellDestination dest(*target);
1686
1687 switch (targetType.GetTarget())
1688 {
1691 break;
1692 default:
1693 {
1694 float angle = targetType.CalcDirectionAngle();
1695 float dist = m_spellInfo->Effects[effIndex].CalcRadius(nullptr);
1696 if (targetType.GetTarget() == TARGET_DEST_TARGET_RANDOM)
1697 {
1698 dist *= float(rand_norm());
1699 }
1700
1701 if (targetType.GetTarget() == TARGET_DEST_TARGET_BACK)
1702 {
1704 }
1705
1706 Position pos = dest._position;
1707 target->MovePositionToFirstCollision(pos, dist, angle);
1708
1709 dest.Relocate(pos);
1710 break;
1711 }
1712 }
1713
1714 CallScriptDestinationTargetSelectHandlers(dest, effIndex, targetType);
1715 m_targets.SetDst(dest);
1716}
@ UNIT_FIELD_BOUNDINGRADIUS
Definition: UpdateFields.h:122
@ TARGET_DEST_TARGET_ANY
Definition: SharedDefines.h:1467
@ TARGET_DEST_TARGET_BACK
Definition: SharedDefines.h:1469
@ TARGET_DEST_TARGET_RANDOM
Definition: SharedDefines.h:1478
@ TARGET_DEST_TARGET_ENEMY
Definition: SharedDefines.h:1457

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

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
1868{
1869 if (!m_targets.HasTraj())
1870 return;
1871
1872 float dist2d = m_targets.GetDist2d();
1873 if (!dist2d)
1874 return;
1875
1876 float srcToDestDelta = m_targets.GetDstPos()->m_positionZ - m_targets.GetSrcPos()->m_positionZ;
1877
1878 // xinef: supply correct target type, DEST_DEST and similar are ALWAYS undefined
1879 // xinef: correct target is stored in TRIGGERED SPELL, however as far as i noticed, all checks are ENTRY, ENEMY
1880 std::list<WorldObject*> targets;
1881 Acore::WorldObjectSpellTrajTargetCheck check(dist2d, m_targets.GetSrcPos(), m_caster, m_spellInfo, TARGET_CHECK_ENEMY /*targetCheckType*/, m_spellInfo->Effects[effIndex].ImplicitTargetConditions);
1883 SearchTargets<Acore::WorldObjectListSearcher<Acore::WorldObjectSpellTrajTargetCheck> > (searcher, GRID_MAP_TYPE_MASK_ALL, m_caster, m_targets.GetSrcPos(), dist2d);
1884 if (targets.empty())
1885 return;
1886
1888
1889 float b = tangent(m_targets.GetElevation());
1890 float a = (srcToDestDelta - dist2d * b) / (dist2d * dist2d);
1891 if (a > -0.0001f)
1892 a = 0;
1893
1894 LOG_DEBUG("spells", "Spell::SelectTrajTargets: a {} b {}", a, b);
1895
1896 // Xinef: hack for distance, many trajectory spells have RangeEntry 1 (self)
1897 float bestDist = m_spellInfo->GetMaxRange(false) * 2;
1898 if (bestDist < 1.0f)
1899 bestDist = 300.0f;
1900
1901 std::list<WorldObject*>::const_iterator itr = targets.begin();
1902 for (; itr != targets.end(); ++itr)
1903 {
1904 if (Unit* unitTarget = (*itr)->ToUnit())
1905 if (m_caster == *itr || m_caster->IsOnVehicle(unitTarget) || (unitTarget)->GetVehicle())//(*itr)->IsOnVehicle(m_caster))
1906 continue;
1907
1908 const float size = std::max((*itr)->GetObjectSize() * 0.7f, 1.0f); // 1/sqrt(3)
1910 const float objDist2d = std::fabs(m_targets.GetSrcPos()->GetExactDist2d(*itr) * cos(m_targets.GetSrcPos()->GetRelativeAngle(*itr)));
1911 const float dz = std::fabs((*itr)->GetPositionZ() - m_targets.GetSrcPos()->m_positionZ);
1912
1913 LOG_DEBUG("spells", "Spell::SelectTrajTargets: check {}, dist between {} {}, height between {} {}.",
1914 (*itr)->GetEntry(), objDist2d - size, objDist2d + size, dz - size, dz + size);
1915
1916 float dist = objDist2d - size;
1917 float height = dist * (a * dist + b);
1918
1919 LOG_DEBUG("spells", "Spell::SelectTrajTargets: dist {}, height {}.", dist, height);
1920
1921 if (dist < bestDist && height < dz + size && height > dz - size)
1922 {
1923 bestDist = dist > 0 ? dist : 0;
1924 break;
1925 }
1926
1927#define CHECK_DIST {\
1928 LOG_DEBUG("spells", "Spell::SelectTrajTargets: dist {}, height {}.", dist, height);\
1929 if (dist > bestDist)\
1930 continue;\
1931 if (dist < objDist2d + size && dist > objDist2d - size)\
1932 {\
1933 bestDist = dist;\
1934 break;\
1935 }\
1936 }
1937
1938 // RP-GG only, search in straight line, as item have no trajectory
1939 if (m_CastItem)
1940 {
1941 if (dist < bestDist && std::fabs(dz) < 6.0f) // closes target, also check Z difference)
1942 {
1943 bestDist = dist;
1944 break;
1945 }
1946
1947 continue;
1948 }
1949
1950 if (!a)
1951 {
1952 // Xinef: everything remade
1953 dist = m_targets.GetSrcPos()->GetExactDist(*itr);
1954 height = m_targets.GetSrcPos()->GetExactDist2d(*itr) * b;
1955
1956 if (height < dz + size * (b + 1) && height > dz - size * (b + 1) && dist < bestDist)
1957 {
1958 bestDist = dist;
1959 break;
1960 }
1961
1962 continue;
1963 }
1964
1965 height = dz - size;
1966 float sqrt1 = b * b + 4 * a * height;
1967 if (sqrt1 > 0)
1968 {
1969 sqrt1 = std::sqrt(sqrt1);
1970 dist = (sqrt1 - b) / (2 * a);
1971 CHECK_DIST;
1972 }
1973
1974 height = dz + size;
1975 float sqrt2 = b * b + 4 * a * height;
1976 if (sqrt2 > 0)
1977 {
1978 sqrt2 = std::sqrt(sqrt2);
1979 dist = (sqrt2 - b) / (2 * a);
1980 CHECK_DIST;
1981
1982 dist = (-sqrt2 - b) / (2 * a);
1983 CHECK_DIST;
1984 }
1985
1986 if (sqrt1 > 0)
1987 {
1988 dist = (-sqrt1 - b) / (2 * a);
1989 CHECK_DIST;
1990 }
1991 }
1992
1994 {
1995 float x = m_targets.GetSrcPos()->m_positionX + cos(m_caster->GetOrientation()) * bestDist;
1996 float y = m_targets.GetSrcPos()->m_positionY + std::sin(m_caster->GetOrientation()) * bestDist;
1997 float z = m_targets.GetSrcPos()->m_positionZ + bestDist * (a * bestDist + b);
1998
1999 if (itr != targets.end())
2000 {
2001 float distSq = (*itr)->GetExactDistSq(x, y, z);
2002 float sizeSq = (*itr)->GetObjectSize();
2003 sizeSq *= sizeSq;
2004 LOG_DEBUG("spells", "Spell::SelectTrajTargets: Initial {} {} {} {} {}", x, y, z, distSq, sizeSq);
2005 if (distSq > sizeSq)
2006 {
2007 float factor = 1 - std::sqrt(sizeSq / distSq);
2008 x += factor * ((*itr)->GetPositionX() - x);
2009 y += factor * ((*itr)->GetPositionY() - y);
2010 z += factor * ((*itr)->GetPositionZ() - z);
2011
2012 distSq = (*itr)->GetExactDistSq(x, y, z);
2013 LOG_DEBUG("spells", "Spell::SelectTrajTargets: Initial {} {} {} {} {}", x, y, z, distSq, sizeSq);
2014 }
2015 }
2016
2017 Position trajDst;
2018 trajDst.Relocate(x, y, z, m_caster->GetOrientation());
2020 dest.Relocate(trajDst);
2021
2022 CallScriptDestinationTargetSelectHandlers(dest, effIndex, targetType);
2023 m_targets.ModDst(dest);
2024 }
2025}
float tangent(float x)
Definition: Spell.cpp:1853
#define CHECK_DIST
Definition: Object.h:696
bool IsOnVehicle(Unit const *vehicle) const
Definition: Unit.h:1674
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 ( )
817{
818 // select targets for cast phase
820
821 uint32 processedAreaEffectsMask = 0;
822 for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i)
823 {
824 // not call for empty effect.
825 // Also some spells use not used effect targets for store targets for dummy effect in triggered spells
826 if (!m_spellInfo->Effects[i].IsEffect())
827 continue;
828
829 // set expected type of implicit targets to be sent to client
830 uint32 implicitTargetMask = GetTargetFlagMask(m_spellInfo->Effects[i].TargetA.GetObjectType()) | GetTargetFlagMask(m_spellInfo->Effects[i].TargetB.GetObjectType());
831 if (implicitTargetMask & TARGET_FLAG_UNIT)
833 if (implicitTargetMask & (TARGET_FLAG_GAMEOBJECT | TARGET_FLAG_GAMEOBJECT_ITEM))
835
836 SelectEffectImplicitTargets(SpellEffIndex(i), m_spellInfo->Effects[i].TargetA, processedAreaEffectsMask);
837 SelectEffectImplicitTargets(SpellEffIndex(i), m_spellInfo->Effects[i].TargetB, processedAreaEffectsMask);
838
839 // Select targets of effect based on effect type
840 // those are used when no valid target could be added for spell effect based on spell target type
841 // some spell effects use explicit target as a default target added to target map (like SPELL_EFFECT_LEARN_SPELL)
842 // some spell effects add target to target map only when target type specified (like SPELL_EFFECT_WEAPON)
843 // some spell effects don't add anything to target map (confirmed with sniffs) (like SPELL_EFFECT_DESTROY_ALL_TOTEMS)
845
846 if (m_targets.HasDst())
848
850 {
851 // maybe do this for all spells?
852 if (!focusObject && m_UniqueTargetInfo.empty() && m_UniqueGOTargetInfo.empty() && m_UniqueItemInfo.empty() && !m_targets.HasDst())
853 {
855 finish(false);
856 return;
857 }
858
859 uint8 mask = (1 << i);
860 for (auto ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
861 {
862 if (ihit->effectMask & mask)
863 {
865 break;
866 }
867 }
868 }
869 else if (m_auraScaleMask)
870 {
871 bool checkLvl = !m_UniqueTargetInfo.empty();
872 m_UniqueTargetInfo.erase(std::remove_if(std::begin(m_UniqueTargetInfo), std::end(m_UniqueTargetInfo), [&](TargetInfo const& targetInfo) -> bool
873 {
874 // remove targets which did not pass min level check
875 if (m_auraScaleMask && targetInfo.effectMask == m_auraScaleMask)
876 {
877 if (!targetInfo.scaleAura && targetInfo.targetGUID != m_caster->GetGUID())
878 return true;
879 }
880
881 return false;
882 }), std::end(m_UniqueTargetInfo));
883
884 if (checkLvl && m_UniqueTargetInfo.empty())
885 {
887 finish(false);
888 }
889 }
890 }
891
892 if (uint64 dstDelay = CalculateDelayMomentForDst())
893 m_delayMoment = dstDelay;
894}
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:923
void SelectExplicitTargets()
Definition: Spell.cpp:783
void AddDestTarget(SpellDestination const &dest, uint32 effIndex)
Definition: Spell.cpp:2605
void SelectEffectTypeImplicitTargets(uint8 effIndex)
Definition: Spell.cpp:2027

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
4662{
4663 if (result == SPELL_CAST_OK)
4664 return;
4665
4666 WorldPacket data(SMSG_CAST_FAILED, 1 + 4 + 1);
4667 WriteCastResultInfo(data, caster, spellInfo, castCount, result, customError);
4668
4669 caster->GetSession()->SendPacket(&data);
4670}
@ 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:4556

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

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

◆ SendCastResult() [2/2]

void Spell::SendCastResult ( SpellCastResult  result)
4673{
4674 if (result == SPELL_CAST_OK)
4675 return;
4676
4677 if (!m_caster->IsPlayer() || m_caster->IsCharmed())
4678 return;
4679
4680 if (m_caster->ToPlayer()->GetSession()->PlayerLoading()) // don't send cast results at loading time
4681 return;
4682
4683 // 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
4685 result = SPELL_FAILED_DONT_REPORT;
4686
4688}
@ TRIGGERED_DONT_REPORT_CAST_ERROR
Disallows proc events from triggered spell (default)
Definition: SpellDefines.h:147
@ SPELL_FAILED_BM_OR_INVISGOD
Definition: SharedDefines.h:1108
bool IsCharmed() const
Definition: Unit.h:1266

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

◆ SendChannelStart()

void Spell::SendChannelStart ( uint32  duration)
5199{
5200 ObjectGuid channelTarget = m_targets.GetObjectTargetGUID();
5201 if (!channelTarget && !m_spellInfo->NeedsExplicitUnitTarget())
5202 if (m_UniqueTargetInfo.size() + m_UniqueGOTargetInfo.size() == 1) // this is for TARGET_SELECT_CATEGORY_NEARBY
5203 channelTarget = !m_UniqueTargetInfo.empty() ? m_UniqueTargetInfo.front().targetGUID : m_UniqueGOTargetInfo.front().targetGUID;
5204
5205 WorldPacket data(MSG_CHANNEL_START, (8 + 4 + 4));
5206 data << m_caster->GetPackGUID();
5207 data << uint32(m_spellInfo->Id);
5208 data << uint32(duration);
5209
5210 m_caster->SendMessageToSet(&data, true);
5211
5214
5215 m_timer = duration;
5216 if (channelTarget)
5218
5220}
@ MSG_CHANNEL_START
Definition: Opcodes.h:343

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

Referenced by handle_immediate().

◆ SendChannelUpdate()

◆ SendInterrupted()

void Spell::SendInterrupted ( uint8  result)
5167{
5168 WorldPacket data(SMSG_SPELL_FAILURE, (8 + 1 + 4 + 1));
5169 data << m_caster->GetPackGUID();
5170 data << uint8(m_cast_count);
5171 data << uint32(m_spellInfo->Id);
5172 data << uint8(result);
5173 m_caster->SendMessageToSet(&data, true);
5174
5175 data.Initialize(SMSG_SPELL_FAILED_OTHER, (8 + 1 + 4 + 1));
5176 data << m_caster->GetPackGUID();
5177 data << uint8(m_cast_count);
5178 data << uint32(m_spellInfo->Id);
5179 data << uint8(result);
5180 m_caster->SendMessageToSet(&data, true);
5181}
@ 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 ( )
5066{
5067 WorldPacket data(SMSG_SPELLLOGEXECUTE, (8 + 4 + 4 + 4 + 4 + 8));
5068
5069 data << m_caster->GetPackGUID();
5070
5071 data << uint32(m_spellInfo->Id);
5072
5073 uint8 effCount = 0;
5074 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
5075 {
5076 if (m_effectExecuteData[i])
5077 ++effCount;
5078 }
5079
5080 if (!effCount)
5081 return;
5082
5083 data << uint32(effCount);
5084 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
5085 {
5086 if (!m_effectExecuteData[i])
5087 continue;
5088
5089 data << uint32(m_spellInfo->Effects[i].Effect); // spell effect
5090
5091 data.append(*m_effectExecuteData[i]);
5092
5093 delete m_effectExecuteData[i];
5094 m_effectExecuteData[i] = nullptr;
5095 }
5096 m_caster->SendMessageToSet(&data, true);
5097}
@ 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
1998{
1999 Player* player = m_caster->ToPlayer();
2000 if (!player)
2001 return;
2002
2003 if (gameObjTarget)
2004 {
2005 // Players shouldn't be able to loot gameobjects that are currently despawned
2006 if (!gameObjTarget->isSpawned() && !player->IsGameMaster())
2007 {
2008 LOG_ERROR("spells.effect", "Possible hacking attempt: Player {} [{}] tried to loot a gameobject [{}] which is on respawn time without being in GM mode!",
2009 player->GetName(), player->GetGUID().ToString(), gameObjTarget->GetGUID().ToString());
2010 return;
2011 }
2012 // special case, already has GossipHello inside so return and avoid calling twice
2014 {
2016 return;
2017 }
2018
2019 if (sScriptMgr->OnGossipHello(player, gameObjTarget))
2020 return;
2021
2022 if (gameObjTarget->AI()->GossipHello(player, false))
2023 return;
2024
2025 switch (gameObjTarget->GetGoType())
2026 {
2028 gameObjTarget->UseDoorOrButton(0, false, player);
2029 return;
2031 gameObjTarget->UseDoorOrButton(0, false, player);
2032
2033 // Xinef: properly link possible traps
2034 if (uint32 trapEntry = gameObjTarget->GetGOInfo()->button.linkedTrap)
2035 gameObjTarget->TriggeringLinkedGameObject(trapEntry, player);
2036 return;
2040 return;
2041
2043 // triggering linked GO
2046 return;
2047
2049 // triggering linked GO
2050 if (uint32 trapEntry = gameObjTarget->GetGOInfo()->chest.linkedTrapId)
2052
2053 // Don't return, let loots been taken
2054 default:
2055 break;
2056 }
2057 }
2058
2059 // Send loot
2060 player->SendLoot(guid, loottype);
2061}
@ GAMEOBJECT_TYPE_SPELL_FOCUS
Definition: SharedDefines.h:1568
@ GAMEOBJECT_TYPE_QUESTGIVER
Definition: SharedDefines.h:1562
virtual bool GossipHello(Player *, bool)
Definition: GameObjectAI.h:55
bool isSpawned() const
Definition: GameObject.h:190
void TriggeringLinkedGameObject(uint32 trapEntry, Unit *target)
Definition: GameObject.cpp:1385
uint32 gossipID
Definition: GameObjectData.h:73
uint32 linkedTrap
Definition: GameObjectData.h:60
struct GameObjectTemplate::@227::@232 chest
struct GameObjectTemplate::@227::@236 spellFocus
uint32 linkedTrapId
Definition: GameObjectData.h:91
struct GameObjectTemplate::@227::@231 questgiver
void SendPreparedGossip(WorldObject *source)
Definition: PlayerGossip.cpp:209
void PrepareGossipMenu(WorldObject *source, uint32 menuId=0, bool showQuests=false)
Definition: PlayerGossip.cpp:32

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

Referenced by EffectOpenLock().

◆ SendPetCastResult()

void Spell::SendPetCastResult ( SpellCastResult  result)
4691{
4692 if (result == SPELL_CAST_OK)
4693 return;
4694
4695 Unit* owner = m_caster->GetCharmerOrOwner();
4696 if (!owner)
4697 return;
4698
4699 Player* player = owner->ToPlayer();
4700 if (!player)
4701 return;
4702
4703 WorldPacket data(SMSG_PET_CAST_FAILED, 1 + 4 + 1);
4705
4706 player->GetSession()->SendPacket(&data);
4707}
@ 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)
5223{
5224 // get resurrector name for creature resurrections, otherwise packet will be not accepted
5225 // for player resurrections the name is looked up by guid
5226 std::string const sentName(m_caster->IsPlayer()
5227 ? ""
5229
5230 WorldPacket data(SMSG_RESURRECT_REQUEST, (8 + 4 + sentName.size() + 1 + 1 + 1 + 4));
5231 data << m_caster->GetGUID();
5232 data << uint32(sentName.size() + 1);
5233
5234 data << sentName;
5235 data << uint8(0); // null terminator
5236
5237 data << uint8(m_caster->IsPlayer() ? 0 : 1); // "you'll be afflicted with resurrection sickness"
5238 // override delay sent with SMSG_CORPSE_RECLAIM_DELAY, set instant resurrection for spells with this attribute
5240 data << uint32(0);
5241 target->GetSession()->SendPacket(&data);
5242}
@ SPELL_ATTR3_NO_RES_TIMER
Definition: SharedDefines.h:497
@ SMSG_RESURRECT_REQUEST
Definition: Opcodes.h:377
virtual std::string const & GetNameForLocaleIdx(LocaleConstant) const
Definition: Object.h:461
LocaleConstant GetSessionDbLocaleIndex() const
Definition: WorldSession.h:498

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

Referenced by EffectResurrect(), and EffectResurrectNew().

◆ SendSpellCooldown()

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

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

Referenced by _cast().

◆ SendSpellGo()

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

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

Referenced by _cast().

◆ SendSpellStart()

void Spell::SendSpellStart ( )
4710{
4711 if (!IsNeedSendToClient(false))
4712 return;
4713
4714 //LOG_DEBUG("spells.aura", "Sending SMSG_SPELL_START id={}", m_spellInfo->Id);
4715
4716 uint32 castFlags = CAST_FLAG_HAS_TRAJECTORY;
4717
4719 castFlags |= CAST_FLAG_PENDING;
4720
4722 castFlags |= CAST_FLAG_PROJECTILE;
4723
4724 if (m_caster->IsPlayer() || m_caster->IsPet())
4725 {
4726 switch (m_spellInfo->PowerType)
4727 {
4728 case POWER_HEALTH:
4729 break;
4730 case POWER_RUNE:
4731 castFlags |= CAST_FLAG_POWER_LEFT_SELF;
4732 break;
4733 default:
4734 if (m_powerCost != 0)
4735 {
4736 castFlags |= CAST_FLAG_POWER_LEFT_SELF;
4737 }
4738 break;
4739 }
4740 }
4741
4743 castFlags |= CAST_FLAG_NO_GCD; // not needed, but Blizzard sends it
4744
4745 PackedGuid realCasterGUID = m_caster->GetPackGUID();
4746 if (TempSummon const* tempSummon = m_caster->ToTempSummon())
4747 {
4748 if (tempSummon->GetEntry() == WORLD_TRIGGER)
4749 {
4750 if (GameObject* casterGameobject = tempSummon->GetSummonerGameObject())
4751 {
4752 realCasterGUID = casterGameobject->GetPackGUID();
4753 }
4754 }
4755 }
4756
4757 WorldPacket data(SMSG_SPELL_START, (8 + 8 + 4 + 4 + 2));
4758 if (m_CastItem)
4759 data << m_CastItem->GetPackGUID();
4760 else
4761 data << realCasterGUID;
4762
4763 data << realCasterGUID;
4764 data << uint8(m_cast_count); // pending spell cast?
4765 data << uint32(m_spellInfo->Id); // spellId
4766 data << uint32(castFlags); // cast flags
4767 data << int32(m_timer); // delay?
4768
4769 m_targets.Write(data);
4770
4771 if (castFlags & CAST_FLAG_POWER_LEFT_SELF)
4773
4774 if (castFlags & CAST_FLAG_PROJECTILE)
4775 WriteAmmoToPacket(&data);
4776
4777 if (castFlags & CAST_FLAG_UNKNOWN_23)
4778 {
4779 data << uint32(0);
4780 data << uint32(0);
4781 }
4782
4783 m_caster->SendMessageToSet(&data, true);
4784
4787}
@ 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, SpellCastTimesEntry::CastTime, SpellInfo::CastTimeEntry, WorldObject::FindMap(), Object::GetGUID(), Object::GetPackGUID(), Unit::GetPower(), SpellInfo::HasAttribute(), SpellInfo::Id, SpellInfo::IsAutoRepeatRangedSpell(), SpellInfo::IsChanneled(), IsNeedSendToClient(), Unit::IsPet(), Object::IsPlayer(), IsTriggered(), m_cast_count, m_caster, m_CastItem, m_powerCost, m_spellInfo, m_targets, m_timer, m_triggeredByAuraSpell, Player::NeedSendSpectatorData(), POWER_HEALTH, POWER_RUNE, SpellInfo::PowerType, SpellInfo::RuneCostID, ArenaSpectator::SendCommand_Spell(), WorldObject::SendMessageToSet(), SMSG_SPELL_START, SPELL_ATTR0_CU_NEEDS_AMMO_DATA, SPELL_ATTR0_USES_RANGED_SLOT, Object::ToPlayer(), Unit::ToTempSummon(), WORLD_TRIGGER, SpellCastTargets::Write(), and WriteAmmoToPacket().

Referenced by prepare().

◆ SetAutoRepeat()

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

References m_autoRepeat.

◆ SetDelayStart()

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

References m_delayStart.

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

◆ SetExecutedCurrently()

void Spell::SetExecutedCurrently ( bool  yes)
inline
561{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 
)
8425{
8426 switch (mod)
8427 {
8429 m_spellValue->EffectBasePoints[0] = m_spellInfo->Effects[EFFECT_0].CalcBaseValue(value);
8430 break;
8432 m_spellValue->EffectBasePoints[1] = m_spellInfo->Effects[EFFECT_1].CalcBaseValue(value);
8433 break;
8435 m_spellValue->EffectBasePoints[2] = m_spellInfo->Effects[EFFECT_2].CalcBaseValue(value);
8436 break;
8438 m_spellValue->RadiusMod = (float)value / 10000;
8439 break;
8442 break;
8445 break;
8447 m_spellValue->AuraDuration = value;
8448 break;
8450 m_spellValue->ForcedCritResult = (bool)value;
8451 break;
8452 }
8453}
@ 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
5933{
5934 Unit* caster = m_originalCaster;
5935 if (!caster)
5936 return;
5937
5938 if (caster->IsTotem())
5939 caster = caster->ToTotem()->GetOwner();
5940
5941 // in another case summon new
5942 uint8 summonLevel = caster->GetLevel();
5943
5944 // level of pet summoned using engineering item based at engineering skill level
5945 if (m_CastItem && caster->IsPlayer())
5946 if (ItemTemplate const* proto = m_CastItem->GetTemplate())
5947 {
5948 // xinef: few special cases
5949 if (proto->RequiredSkill == SKILL_ENGINEERING)
5950 {
5951 if (uint16 skill202 = caster->ToPlayer()->GetSkillValue(SKILL_ENGINEERING))
5952 summonLevel = skill202 / 5;
5953 }
5954
5955 switch (m_spellInfo->Id)
5956 {
5957 // Dragon's Call
5958 case 13049:
5959 summonLevel = 55;
5960 break;
5961
5962 // Cleansed Timberling Heart: Summon Timberling
5963 case 5666:
5964 summonLevel = 7;
5965 break;
5966
5967 // Glowing Cat Figurine: Summon Ghost Saber
5968 case 6084:
5969 // minLevel 19, maxLevel 20
5970 summonLevel = 20;
5971 break;
5972
5973 // Spiked Collar: Summon Felhunter
5974 case 8176:
5975 summonLevel = 30;
5976 break;
5977
5978 // Dog Whistle: Summon Tracking Hound
5979 case 9515:
5980 summonLevel = 30;
5981 break;
5982
5983 // Barov Peasant Caller: Death by Peasant
5984 case 18307:
5985 case 18308:
5986 summonLevel = 60;
5987 break;
5988
5989 // Thornling Seed: Plant Thornling
5990 case 22792:
5991 summonLevel = 60;
5992 break;
5993
5994 // Cannonball Runner: Summon Crimson Cannon
5995 case 6251:
5996 summonLevel = 61;
5997 break;
5998 }
5999 }
6000
6001 summonLevel = std::min<uint8>(sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL) + sWorld->getIntConfig(CONFIG_WORLD_BOSS_LEVEL_DIFF), std::max<uint8>(1U, summonLevel));
6002
6003 float radius = 5.0f;
6004 int32 duration = m_spellInfo->GetDuration();
6005
6006 if (Player* modOwner = m_originalCaster->GetSpellModOwner())
6007 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_DURATION, duration);
6008
6009 //TempSummonType summonType = (duration == 0) ? TEMPSUMMON_DEAD_DESPAWN : TEMPSUMMON_TIMED_DESPAWN;
6010 Map* map = caster->GetMap();
6011 TempSummon* summon = nullptr;
6012
6013 uint32 currMinionsCount = m_caster->m_Controlled.size();
6014 uint32 totalNumGuardians = numGuardians + currMinionsCount;
6015
6016 for (uint32 count = 0; count < numGuardians; ++count)
6017 {
6018 Position pos;
6019
6020 // xinef: do not use precalculated position for effect summon pet in this function
6021 // it means it was cast by NPC and should have its position overridden unless the
6022 // target position is specified in the DB AND the effect has no or zero radius
6023 if ((totalNumGuardians == 1 && GetSpellInfo()->Effects[i].Effect != SPELL_EFFECT_SUMMON_PET) ||
6024 (GetSpellInfo()->Effects[i].TargetA.GetTarget() == TARGET_DEST_DB &&
6025 (!GetSpellInfo()->Effects[i].HasRadius() || GetSpellInfo()->Effects[i].RadiusEntry->RadiusMax == 0)))
6026 {
6027 pos = *destTarget;
6028 }
6029 else
6030 {
6031 // randomize position
6032 pos = m_caster->GetRandomPoint(*destTarget, radius);
6033 }
6034
6035 summon = map->SummonCreature(entry, pos, properties, duration, caster, m_spellInfo->Id, 0, personalSpawn);
6036 if (!summon)
6037 return;
6038
6039 // xinef: set calculated level
6040 summon->SetLevel(summonLevel);
6041
6042 // if summonLevel changed, set stats for calculated level
6043 if (summonLevel != caster->GetLevel())
6044 {
6045 ((Guardian*)summon)->InitStatsForLevel(summonLevel);
6046 }
6047
6048 // xinef: if we have more than one guardian, change follow angle
6049 if (summon->HasUnitTypeMask(UNIT_MASK_MINION) && totalNumGuardians > 1)
6050 ((Minion*)summon)->SetFollowAngle(m_caster->GetAbsoluteAngle(pos.GetPositionX(), pos.GetPositionY()));
6051 //else if (summon->HasUnitTypeMask(UNIT_MASK_MINION) && m_targets.HasDst())
6052 // ((Minion*)summon)->SetFollowAngle(m_caster->GetAngle(summon));
6053
6054 // xinef: move this here, some auras are added in initstatsforlevel!
6055 if (!summon->IsInCombat() && !summon->IsTrigger())
6056 {
6057 // summon->AI()->EnterEvadeMode();
6058 summon->GetMotionMaster()->Clear(false);
6060 }
6061
6062 if (properties && properties->Category == SUMMON_CATEGORY_ALLY)
6063 summon->SetFaction(caster->GetFaction());
6064
6066 }
6067}
@ CONFIG_MAX_PLAYER_LEVEL
Definition: IWorld.h:240
@ CONFIG_WORLD_BOSS_LEVEL_DIFF
Definition: IWorld.h:290
@ SKILL_ENGINEERING
Definition: SharedDefines.h:2923
bool IsTrigger() const
Definition: Creature.h:78
Definition: TemporarySummon.h:76
Unit * GetOwner() const
Definition: TemporarySummon.cpp:385
void SetLevel(uint8 lvl, bool showLevelChange=true)
Definition: Unit.cpp:15415

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

Referenced by EffectSummonPet(), and EffectSummonType().

◆ TakeAmmo()

void Spell::TakeAmmo ( )
5372{
5374 {
5376
5377 // wands don't have ammo
5378 if (!pItem || pItem->IsBroken() || pItem->GetTemplate()->SubClass == ITEM_SUBCLASS_WEAPON_WAND)
5379 return;
5380
5381 if (pItem->GetTemplate()->InventoryType == INVTYPE_THROWN)
5382 {
5383 if (pItem->GetMaxStackCount() == 1)
5384 {
5385 // decrease durability for non-stackable throw weapon
5387 }
5388 else
5389 {
5390 // decrease items amount for stackable throw weapon
5391 uint32 count = 1;
5392 m_caster->ToPlayer()->DestroyItemCount(pItem, count, true);
5393 }
5394 }
5396 m_caster->ToPlayer()->DestroyItemCount(ammo, 1, true);
5397 }
5398}
@ EQUIPMENT_SLOT_RANGED
Definition: Player.h:692
@ INVTYPE_THROWN
Definition: ItemTemplate.h:281
uint32 GetMaxStackCount() const
Definition: Item.h:274
void DurabilityPointLossForEquipSlot(EquipmentSlots slot)
Definition: Player.cpp:4804

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

Referenced by handle_immediate(), and HandleLaunchPhase().

◆ TakeCastItem()

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

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

Referenced by _cast(), and handle_immediate().

◆ TakePower()

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

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

Referenced by _cast().

◆ TakeReagents()

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

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

Referenced by _cast().

◆ TakeRunePower()

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

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

Referenced by TakePower().

◆ TriggerGlobalCooldown()

void Spell::TriggerGlobalCooldown ( )
protected
8833{
8835 if (!gcd)
8836 {
8837 // Xinef: fix for charmed pet spells with no cooldown info
8839 gcd = MIN_GCD;
8840 else
8841 return;
8842 }
8843
8844 if (m_caster->IsPlayer())
8846 return;
8847
8848 // Global cooldown can't leave range 1..1.5 secs
8849 // There are some spells (mostly not casted directly by player) that have < 1 sec and > 1.5 sec global cooldowns
8850 // but as tests show are not affected by any spell mods.
8852 {
8853 // gcd modifier auras are applied only to own spells and only players have such mods
8854 if (m_caster->IsPlayer())
8856
8857 // Apply haste rating
8860 {
8861 gcd = int32(float(gcd) * m_caster->GetFloatValue(UNIT_MOD_CAST_SPEED));
8862 }
8863
8864 if (gcd < MIN_GCD)
8865 gcd = MIN_GCD;
8866 else if (gcd > MAX_GCD)
8867 gcd = MAX_GCD;
8868 }
8869
8870 // Only players or controlled units have global cooldown
8871 if (m_caster->GetCharmInfo())
8873 else if (m_caster->IsPlayer())
8875}
@ MIN_GCD
Definition: Spell.cpp:8817
@ MAX_GCD
Definition: Spell.cpp:8818
@ SPELLMOD_GLOBAL_COOLDOWN
Definition: SpellDefines.h:98
void AddGlobalCooldown(SpellInfo const *spellInfo, uint32 gcd)
Definition: CharmInfo.cpp:410

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

Referenced by prepare().

◆ update()

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

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

Referenced by SpellEvent::Execute().

◆ UpdateChanneledTargetList()

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

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 ( )
7854{
7857 else
7858 {
7861 m_originalCaster = nullptr;
7862 }
7863
7865 {
7867 // cast item not found, somehow the item is no longer where we expected
7868 if (!m_CastItem)
7869 return false;
7870 }
7871 else
7872 m_CastItem = nullptr;
7873
7875
7876 // further actions done only for dest targets
7877 if (!m_targets.HasDst())
7878 return true;
7879
7880 // cache last transport
7881 WorldObject* transport = nullptr;
7882
7883 // update effect destinations (in case of moved transport dest target)
7884 for (uint8 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
7885 {
7886 SpellDestination& dest = m_destTargets[effIndex];
7887 if (!dest._transportGUID)
7888 continue;
7889
7890 if (!transport || transport->GetGUID() != dest._transportGUID)
7892
7893 if (transport)
7894 {
7895 dest._position.Relocate(transport);
7897 }
7898 }
7899
7900 return true;
7901}
WorldObject * GetWorldObject(WorldObject const &, ObjectGuid const guid)
Definition: ObjectAccessor.cpp:118
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:480

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

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

◆ WriteAmmoToPacket()

void Spell::WriteAmmoToPacket ( WorldPacket data)
4921{
4922 uint32 ammoInventoryType = 0;
4923 uint32 ammoDisplayID = 0;
4924
4925 if (m_caster->IsPlayer())
4926 {
4928 if (pItem)
4929 {
4930 ammoInventoryType = pItem->GetTemplate()->InventoryType;
4931 if (ammoInventoryType == INVTYPE_THROWN)
4932 ammoDisplayID = pItem->GetTemplate()->DisplayInfoID;
4933 else
4934 {
4936 if (ammoID)
4937 {
4938 ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(ammoID);
4939 if (pProto)
4940 {
4941 ammoDisplayID = pProto->DisplayInfoID;
4942 ammoInventoryType = pProto->InventoryType;
4943 }
4944 }
4945 else if (m_caster->HasAura(46699)) // Requires No Ammo
4946 {
4947 ammoDisplayID = 5996; // normal arrow
4948 ammoInventoryType = INVTYPE_AMMO;
4949 }
4950 }
4951 }
4952 }
4953 else
4954 {
4955 uint32 nonRangedAmmoDisplayID = 0;
4956 uint32 nonRangedAmmoInventoryType = 0;
4957 for (uint8 i = 0; i < 3; ++i)
4958 {
4960 {
4961 if (ItemEntry const* itemEntry = sItemStore.LookupEntry(item_id))
4962 {
4963 if (itemEntry->ClassID == ITEM_CLASS_WEAPON)
4964 {
4965 switch (itemEntry->SubclassID)
4966 {
4968 ammoDisplayID = itemEntry->DisplayInfoID;
4969 ammoInventoryType = itemEntry->InventoryType;
4970 break;
4973 ammoDisplayID = 5996; // is this need fixing?
4974 ammoInventoryType = INVTYPE_AMMO;
4975 break;
4977 ammoDisplayID = 5998; // is this need fixing?
4978 ammoInventoryType = INVTYPE_AMMO;
4979 break;
4980 default:
4981 nonRangedAmmoDisplayID = itemEntry->DisplayInfoID;
4982 nonRangedAmmoInventoryType = itemEntry->InventoryType;
4983 break;
4984 }
4985
4986 if (ammoDisplayID)
4987 break;
4988 }
4989 }
4990 }
4991 }
4992
4993 if (!ammoDisplayID && !ammoInventoryType)
4994 {
4995 ammoDisplayID = nonRangedAmmoDisplayID;
4996 ammoInventoryType = nonRangedAmmoInventoryType;
4997 }
4998 }
4999
5000 *data << uint32(ammoDisplayID);
5001 *data << uint32(ammoInventoryType);
5002}
DBCStorage< ItemEntry > sItemStore(Itemfmt)
@ UNIT_VIRTUAL_ITEM_SLOT_ID
Definition: UpdateFields.h:116
@ INVTYPE_AMMO
Definition: ItemTemplate.h:280
uint32 DisplayInfoID
Definition: ItemTemplate.h:625
Definition: DBCStructure.h:1140

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

Referenced by SendSpellGo(), and SendSpellStart().

◆ WriteCastResultInfo()

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

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

Referenced by SendCastResult(), and SendPetCastResult().

◆ WriteSpellGoTargets()

void Spell::WriteSpellGoTargets ( WorldPacket data)

Writes miss and hit targets for a SMSG_SPELL_GO packet.

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

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

Referenced by SendSpellGo().

Friends And Related Function Documentation

◆ SpellScript

friend class SpellScript
friend

◆ Unit::SetCurrentCastedSpell

void Unit::SetCurrentCastedSpell ( Spell pSpell)
friend

Member Data Documentation

◆ _scriptsLoaded

bool Spell::_scriptsLoaded
protected

Referenced by LoadScripts(), and Spell().

◆ _spellEvent

SpellEvent* Spell::_spellEvent
protected

◆ _spellTargetsSelected

bool Spell::_spellTargetsSelected
protected

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

◆ _triggeredCastFlags

TriggerCastFlags Spell::_triggeredCastFlags
protected

◆ damage

◆ destTarget

◆ effectHandleMode

SpellEffectHandleMode Spell::effectHandleMode
protected

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

◆ focusObject

◆ gameObjTarget

◆ itemTarget

◆ m_appliedMods

◆ m_applyMultiplierMask

uint8 Spell::m_applyMultiplierMask
protected

◆ m_attackType

◆ m_auraScaleMask

uint8 Spell::m_auraScaleMask
protected

◆ m_autoRepeat

bool Spell::m_autoRepeat
protected

◆ m_canReflect

bool Spell::m_canReflect
protected

Referenced by AddUnitTarget(), and Spell().

◆ m_cast_count

◆ m_caster

Unit* const Spell::m_caster
protected

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

◆ m_CastItem

◆ m_castItemGUID

◆ m_casttime

◆ m_channeledDuration

int32 Spell::m_channeledDuration
protected

◆ m_channelTargetEffectMask

uint8 Spell::m_channelTargetEffectMask
protected

◆ m_comboPointGain

int8 Spell::m_comboPointGain

◆ m_comboTarget

Unit* Spell::m_comboTarget

◆ m_customError

◆ m_damage

◆ m_damageMultipliers

float Spell::m_damageMultipliers[3]
protected

◆ m_delayAtDamageCount

uint8 Spell::m_delayAtDamageCount
protected

Referenced by isDelayableNoMore(), and Spell().

◆ m_delayMoment

◆ m_delayStart

uint64 Spell::m_delayStart
protected

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

◆ m_delayTrajectory

uint64 Spell::m_delayTrajectory
protected

◆ m_destTargets

SpellDestination Spell::m_destTargets[MAX_SPELL_EFFECTS]
protected

◆ m_diminishGroup

DiminishingGroup Spell::m_diminishGroup
protected

◆ m_diminishLevel

DiminishingLevels Spell::m_diminishLevel
protected

◆ m_effectExecuteData

◆ m_executedCurrently

bool Spell::m_executedCurrently
protected

◆ m_glyphIndex

uint32 Spell::m_glyphIndex

◆ m_healing

◆ m_hitTriggerSpells

HitTriggerSpellList Spell::m_hitTriggerSpells
protected

◆ m_immediateHandled

bool Spell::m_immediateHandled
protected

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

◆ m_loadedScripts

◆ m_needComboPoints

bool Spell::m_needComboPoints
protected

◆ m_originalCaster

◆ m_originalCasterGUID

◆ m_powerCost

◆ m_preCastSpell

uint32 Spell::m_preCastSpell

◆ m_preGeneratedPath

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

Referenced by CheckCast(), and EffectCharge().

◆ m_procAttacker

uint32 Spell::m_procAttacker
protected

◆ m_procEx

uint32 Spell::m_procEx
protected

◆ m_procVictim

uint32 Spell::m_procVictim
protected

◆ m_referencedFromCurrentSpell

bool Spell::m_referencedFromCurrentSpell
protected

◆ m_runesState

uint8 Spell::m_runesState
protected

◆ m_selfContainer

Spell** Spell::m_selfContainer
protected

◆ m_skipCheck

bool Spell::m_skipCheck
protected

Referenced by AddUnitTarget(), and Spell().

◆ m_spellAura

◆ m_spellFlags

◆ m_spellInfo

SpellInfo const* const Spell::m_spellInfo

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

◆ m_spellSchoolMask

◆ m_spellState

uint32 Spell::m_spellState
protected

◆ m_spellValue

◆ m_targets

SpellCastTargets Spell::m_targets

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

◆ m_timer

◆ m_triggeredByAuraSpell

◆ m_UniqueGOTargetInfo

◆ m_UniqueItemInfo

◆ m_UniqueTargetInfo

◆ m_weaponItem

Item* Spell::m_weaponItem

◆ unitTarget

Unit* Spell::unitTarget
protected

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