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

#include "Spell.h"

Classes

struct  GOTargetInfo
 
struct  HitTriggerSpell
 
struct  ItemTargetInfo
 

Public Types

typedef std::set< Aura * > UsedSpellMods
 

Public Member Functions

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

Static Public Member Functions

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

Public Attributes

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

Protected Types

typedef std::list< HitTriggerSpellHitTriggerSpellList
 

Protected Member Functions

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

Protected Attributes

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

Friends

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

Detailed Description

Member Typedef Documentation

◆ HitTriggerSpellList

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

◆ UsedSpellMods

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

Constructor & Destructor Documentation

◆ Spell()

Spell::Spell ( Unit caster,
SpellInfo const *  info,
TriggerCastFlags  triggerFlags,
ObjectGuid  originalCasterGUID = ObjectGuid::Empty,
bool  skipCheck = false 
)
566 :
567 m_spellInfo(sSpellMgr->GetSpellForDifficultyFromSpell(info, caster)),
568 m_caster((info->HasAttribute(SPELL_ATTR6_ORIGINATE_FROM_CONTROLLER) && caster->GetCharmerOrOwner()) ? caster->GetCharmerOrOwner() : caster)
570{
572 m_skipCheck = skipCheck;
573 m_selfContainer = nullptr;
575 m_executedCurrently = false;
578 m_comboTarget = nullptr;
579 m_delayStart = 0;
581
583 m_auraScaleMask = 0;
584 memset(m_damageMultipliers, 0, sizeof(m_damageMultipliers));
585
586 // Get data for type of attack
587 switch (m_spellInfo->DmgClass)
588 {
592 else
594 break;
597 break;
598 default:
599 // Wands
602 else
604 break;
605 }
606
607 m_spellSchoolMask = info->GetSchoolMask(); // Can be override for some spell (wand shoot for example)
608
610 // wand case
613 m_spellSchoolMask = SpellSchoolMask(1 << pItem->GetTemplate()->Damage[0].DamageType);
614
615 if (originalCasterGUID)
616 m_originalCasterGUID = originalCasterGUID;
617 else
619
622 else
623 {
626 m_originalCaster = nullptr;
627 }
628
630 _triggeredCastFlags = triggerFlags;
631 if (info->HasAttribute(SPELL_ATTR4_ALLOW_CAST_WHILE_CASTING))
633
634 m_CastItem = nullptr;
635
636 unitTarget = nullptr;
637 itemTarget = nullptr;
638 gameObjTarget = nullptr;
639 destTarget = nullptr;
640 damage = 0;
644 m_damage = 0;
645 m_healing = 0;
646 m_procAttacker = 0;
647 m_procVictim = 0;
648 m_procEx = 0;
649 focusObject = nullptr;
650 m_cast_count = 0;
651 m_glyphIndex = 0;
652 m_preCastSpell = 0;
653 m_spellAura = nullptr;
654 _scriptsLoaded = false;
655
656 //Auto Shot & Shoot (wand)
658
659 m_runesState = 0;
660 m_powerCost = 0; // setup to correct value in Spell::prepare, must not be used before.
661 m_casttime = 0; // setup to correct value in Spell::prepare, must not be used before.
662 m_timer = 0; // will set to castime in prepare
663 m_channeledDuration = 0; // will be setup in Spell::handle_immediate
664 m_immediateHandled = false;
665
667
669
670 // Determine if spell can be reflected back to the caster
671 // Patch 1.2 notes: Spell Reflection no longer reflects abilities
675
677 memset(m_effectExecuteData, 0, MAX_SPELL_EFFECTS * sizeof(ByteBuffer*));
678
679 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
681
682 // xinef:
683 _spellTargetsSelected = false;
684
685 m_weaponItem = nullptr;
686}
std::uint8_t uint8
Definition: Define.h:110
std::uint32_t uint32
Definition: Define.h:108
@ TYPEID_PLAYER
Definition: ObjectGuid.h:38
@ OFF_ATTACK
Definition: Unit.h:397
@ BASE_ATTACK
Definition: Unit.h:396
@ RANGED_ATTACK
Definition: Unit.h:398
@ DIMINISHING_LEVEL_1
Definition: Unit.h:694
@ SPELL_EFFECT_HANDLE_LAUNCH
Definition: Spell.h:233
@ SPELL_FLAG_NORMAL
Definition: Spell.h:81
@ SPELL_STATE_NULL
Definition: Spell.h:223
TriggerCastFlags
Definition: SpellDefines.h:130
@ TRIGGERED_CAST_DIRECTLY
Will ignore combo point requirement.
Definition: SpellDefines.h:139
@ TRIGGERED_IGNORE_CAST_IN_PROGRESS
Will ignore aura scaling.
Definition: SpellDefines.h:137
#define sSpellMgr
Definition: SpellMgr.h:825
#define MAX_SPELL_EFFECTS
Definition: DBCStructure.h:1635
@ 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
Unit * GetUnit(WorldObject const &, ObjectGuid const guid)
Definition: ObjectAccessor.cpp:202
Definition: Item.h:214
Player * ToPlayer()
Definition: Object.h:195
bool IsInWorld() const
Definition: Object.h:101
TypeID GetTypeId() const
Definition: Object.h:121
static ObjectGuid GetGUID(Object const *o)
Definition: Object.h:106
Item * GetWeaponForAttack(WeaponAttackType attackType, bool useable=false) const
Definition: PlayerStorage.cpp:516
Unit * GetCharmerOrOwner() const
Definition: Unit.h:1861
uint32 getClassMask() const
Definition: Unit.h:1439
Definition: Spell.h:94
Definition: Spell.h:211
Unit * m_comboTarget
Definition: Spell.h:542
int8 m_comboPointGain
Definition: Spell.h:543
GameObject * gameObjTarget
Definition: Spell.h:652
bool m_referencedFromCurrentSpell
Definition: Spell.h:643
bool m_canReflect
Definition: Spell.h:619
uint32 m_procVictim
Definition: Spell.h:674
Unit * m_originalCaster
Definition: Spell.h:607
bool m_needComboPoints
Definition: Spell.h:645
uint64 m_delayStart
Definition: Spell.h:637
bool _scriptsLoaded
Definition: Spell.h:725
TriggerCastFlags _triggeredCastFlags
Definition: Spell.h:766
int32 damage
Definition: Spell.h:654
SpellEffectHandleMode effectHandleMode
Definition: Spell.h:655
int32 m_channeledDuration
Definition: Spell.h:618
Aura * m_spellAura
Definition: Spell.h:657
SpellDestination m_destTargets[MAX_SPELL_EFFECTS]
Definition: Spell.h:700
Unit *const m_caster
Definition: Spell.h:601
uint8 m_delayAtDamageCount
Definition: Spell.h:626
WeaponAttackType m_attackType
Definition: Spell.h:615
bool m_immediateHandled
Definition: Spell.h:640
uint32 m_spellState
Definition: Spell.h:762
ObjectGuid m_originalCasterGUID
Definition: Spell.h:605
void CleanupTargetList()
Definition: Spell.cpp:2370
int32 m_timer
Definition: Spell.h:763
int32 m_casttime
Definition: Spell.h:617
Item * itemTarget
Definition: Spell.h:651
uint8 m_cast_count
Definition: Spell.h:524
int32 m_damage
Definition: Spell.h:667
bool m_executedCurrently
Definition: Spell.h:644
DiminishingLevels m_diminishLevel
Definition: Spell.h:660
float m_damageMultipliers[3]
Definition: Spell.h:647
ByteBuffer * m_effectExecuteData[MAX_SPELL_EFFECTS]
Definition: Spell.h:780
uint8 m_auraScaleMask
Definition: Spell.h:774
SpellCustomErrors m_customError
Definition: Spell.h:528
uint8 m_spellFlags
Definition: Spell.h:621
bool m_skipCheck
Definition: Spell.h:773
int32 m_healing
Definition: Spell.h:668
uint32 m_glyphIndex
Definition: Spell.h:525
uint8 m_channelTargetEffectMask
Definition: Spell.h:682
Item * m_weaponItem
Definition: Spell.h:522
Unit * unitTarget
Definition: Spell.h:650
SpellSchoolMask m_spellSchoolMask
Definition: Spell.h:614
SpellEvent * _spellEvent
Definition: Spell.h:765
bool _spellTargetsSelected
Definition: Spell.h:778
uint32 m_preCastSpell
Definition: Spell.h:526
WorldLocation * destTarget
Definition: Spell.h:653
Spell ** m_selfContainer
Definition: Spell.h:609
uint8 m_applyMultiplierMask
Definition: Spell.h:646
DiminishingGroup m_diminishGroup
Definition: Spell.h:661
uint32 m_procEx
Definition: Spell.h:675
Item * m_CastItem
Definition: Spell.h:521
SpellValue *const m_spellValue
Definition: Spell.h:603
int32 m_powerCost
Definition: Spell.h:616
uint32 m_procAttacker
Definition: Spell.h:673
GameObject * focusObject
Definition: Spell.h:664
SpellInfo const *const m_spellInfo
Definition: Spell.h:520
uint8 m_runesState
Definition: Spell.h:624
bool m_autoRepeat
Definition: Spell.h:623
bool IsPassive() const
Definition: SpellInfo.cpp:1085
bool NeedsComboPoints() const
Definition: SpellInfo.cpp:1253
bool HasAttribute(SpellAttr0 attribute) const
Definition: SpellInfo.h:412
bool HasEffect(SpellEffects effect) const
Definition: SpellInfo.cpp:872
bool IsPositive() const
Definition: SpellInfo.cpp:1224
bool IsAutoRepeatRangedSpell() const
Definition: SpellInfo.cpp:1270
uint32 DmgClass
Definition: SpellInfo.h:387
bool IsRangedWeaponSpell() const
Definition: SpellInfo.cpp:1263
Definition: ByteBuffer.h:70

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

◆ ~Spell()

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

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

Member Function Documentation

◆ _cast()

void Spell::_cast ( bool  skipCheck)

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

3797{
3798 // update pointers base at GUIDs to prevent access to non-existed already object
3799 if (!UpdatePointers())
3800 {
3801 // cancel the spell if UpdatePointers() returned false, something wrong happened there
3802 cancel();
3803 return;
3804 }
3805
3806 // cancel at lost explicit target during cast
3808 {
3809 cancel();
3810 return;
3811 }
3812
3813 // Xinef: implement attribute SPELL_ATTR1_DISMISS_PET_FIRST, on spell cast current pet is dismissed and charms are removed
3815 {
3817 if (Pet* pet = m_caster->ToPlayer()->GetPet())
3819
3820 if (Unit* charm = m_caster->GetCharm())
3821 charm->RemoveAurasByType(SPELL_AURA_MOD_CHARM, m_caster->GetGUID());
3822 }
3823
3824 if (Player* playerCaster = m_caster->ToPlayer())
3825 {
3826 // now that we've done the basic check, now run the scripts
3827 // should be done before the spell is actually executed
3828 sScriptMgr->OnPlayerSpellCast(playerCaster, this, skipCheck);
3829
3830 // As of 3.0.2 pets begin attacking their owner's target immediately
3831 // Let any pets know we've attacked something. Check DmgClass for harmful spells only
3832 // This prevents spells such as Hunter's Mark from triggering pet attack
3833 // xinef: take into account SPELL_ATTR3_SUPRESS_TARGET_PROCS
3835 if (!playerCaster->m_Controlled.empty())
3836 for (Unit::ControlSet::iterator itr = playerCaster->m_Controlled.begin(); itr != playerCaster->m_Controlled.end(); ++itr)
3837 if (Unit* pet = *itr)
3838 if (pet->IsAlive() && pet->GetTypeId() == TYPEID_UNIT)
3839 pet->ToCreature()->AI()->OwnerAttacked(m_targets.GetUnitTarget());
3840 }
3841
3843
3847
3849
3850 Player* modOwner = m_caster->GetSpellModOwner();
3851 // skip check if done already (for instant cast spells for example)
3852 if (!skipCheck)
3853 {
3854 SpellCastResult castResult = CheckCast(false);
3855 if (castResult != SPELL_CAST_OK)
3856 {
3857 SendCastResult(castResult);
3858 SendInterrupted(0);
3859
3860 finish(false);
3861 SetExecutedCurrently(false);
3862 return;
3863 }
3864
3865 // additional check after cast bar completes (must not be in CheckCast)
3866 // if trade not complete then remember it in trade data
3868 {
3870 {
3871 if (TradeData* my_trade = m_caster->ToPlayer()->GetTradeData())
3872 {
3873 if (!my_trade->IsInAcceptProcess())
3874 {
3875 // Spell will be casted at completing the trade. Silently ignore at this place
3876 my_trade->SetSpell(m_spellInfo->Id, m_CastItem);
3878 SendInterrupted(0);
3879
3880 finish(false);
3881 SetExecutedCurrently(false);
3882 return;
3883 }
3884 }
3885 }
3886 }
3887 }
3888
3889 if (modOwner)
3890 modOwner->SetSpellModTakingSpell(this, true);
3891
3894
3895 if (modOwner)
3896 modOwner->SetSpellModTakingSpell(this, false);
3897
3898 // Spell may be finished after target map check
3900 {
3901 SendInterrupted(0);
3902 finish(false);
3903 SetExecutedCurrently(false);
3904 return;
3905 }
3906
3907 if (modOwner)
3908 modOwner->SetSpellModTakingSpell(this, true);
3909
3911
3913
3914 if (modOwner)
3915 modOwner->SetSpellModTakingSpell(this, false);
3916
3917 // traded items have trade slot instead of guid in m_itemTargetGUID
3918 // set to real guid to be sent later to the client
3920
3922 {
3924 {
3927 }
3928
3930 }
3931
3933 {
3934 // Powers have to be taken before SendSpellGo
3935 TakePower();
3936 TakeReagents(); // we must remove reagents before HandleEffects to allow place crafted item in same slot
3937 }
3938 else if (Item* targetItem = m_targets.GetItemTarget())
3939 {
3941 if (targetItem->GetOwnerGUID() != m_caster->GetGUID())
3942 TakeReagents();
3943 }
3944
3946
3947 // CAST SPELL
3948 if (modOwner)
3949 modOwner->SetSpellModTakingSpell(this, true);
3950
3952
3954
3955 // we must send smsg_spell_go packet before m_castItem delete in TakeCastItem()...
3956 SendSpellGo();
3957
3958 if (modOwner)
3959 modOwner->SetSpellModTakingSpell(this, false);
3960
3961 if (m_originalCaster)
3962 {
3963 // Handle procs on cast
3964 uint32 procAttacker = m_procAttacker;
3965 if (!procAttacker)
3966 {
3967 bool IsPositive = m_spellInfo->IsPositive();
3969 {
3971 }
3972 else
3973 {
3975 }
3976 }
3977
3978 uint32 procEx = PROC_EX_NORMAL_HIT;
3979
3980 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
3981 {
3982 if (ihit->missCondition != SPELL_MISS_NONE)
3983 {
3984 continue;
3985 }
3986
3987 if (!ihit->crit)
3988 {
3989 continue;
3990 }
3991
3992 procEx |= PROC_EX_CRITICAL_HIT;
3993 break;
3994 }
3995
3998 }
3999
4000 if (modOwner)
4001 modOwner->SetSpellModTakingSpell(this, true);
4002
4004 if (resetAttackTimers)
4005 {
4007 for (Unit::AuraEffectList::const_iterator i = vIgnoreReset.begin(); i != vIgnoreReset.end(); ++i)
4008 {
4009 if ((*i)->IsAffectedOnSpell(m_spellInfo))
4010 {
4011 resetAttackTimers = false;
4012 break;
4013 }
4014 }
4015 }
4016
4017 // Okay, everything is prepared. Now we need to distinguish between immediate and evented delayed spells
4018 if ((m_spellInfo->Speed > 0.0f && !m_spellInfo->IsChanneled())/* xinef: we dont need this || m_spellInfo->Id == 14157*/)
4019 {
4020 // Remove used for cast item if need (it can be already nullptr after TakeReagents call
4021 // in case delayed spell remove item at cast delay start
4022 TakeCastItem();
4023
4024 // Okay, maps created, now prepare flags
4025 m_immediateHandled = false;
4027 SetDelayStart(0);
4028
4031
4032 // remove all applied mods at this point
4033 // dont allow user to use them twice in case spell did not reach current target
4034 if (modOwner)
4035 modOwner->RemoveSpellMods(this);
4036
4037 // Xinef: why do we keep focus after spell is sent to air?
4038 // Xinef: Because of this, in the middle of some animation after setting targetguid to 0 etc
4039 // Xinef: we get focused to it out of nowhere...
4040 if (Creature* creatureCaster = m_caster->ToCreature())
4041 creatureCaster->ReleaseFocus(this);
4042 }
4043 else
4044 {
4045 // Immediate spell, no big deal
4047 }
4048
4049 if (resetAttackTimers)
4050 {
4051 if (m_casttime == 0 && m_spellInfo->CalcCastTime())
4052 {
4053 resetAttackTimers = false;
4054 }
4055
4056 if (resetAttackTimers)
4057 {
4059
4061 {
4063 }
4064
4066 }
4067 }
4068
4070
4071 if (modOwner)
4072 modOwner->SetSpellModTakingSpell(this, false);
4073
4074 if (const std::vector<int32>* spell_triggered = sSpellMgr->GetSpellLinked(m_spellInfo->Id))
4075 {
4076 for (std::vector<int32>::const_iterator i = spell_triggered->begin(); i != spell_triggered->end(); ++i)
4077 if (*i < 0)
4079 else
4081 }
4082
4083 // Interrupt Spell casting
4084 // handle this here, in other places SpellHitTarget can be set to nullptr, if there is an error in this function
4086 if (Unit* target = m_targets.GetUnitTarget())
4087 if (target->GetTypeId() == TYPEID_UNIT)
4088 m_caster->CastSpell(target, 32747, true);
4089
4090 // xinef: start combat at cast for delayed spells, only for explicit target
4091 if (Unit* target = m_targets.GetUnitTarget())
4094 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
4095
4099
4100 SetExecutedCurrently(false);
4101}
@ TYPEID_UNIT
Definition: ObjectGuid.h:37
@ PET_SAVE_AS_CURRENT
Definition: PetDefines.h:42
@ CHEAT_COOLDOWN
Definition: Player.h:993
@ UNIT_STATE_CASTING
Definition: Unit.h:340
#define sScriptMgr
Definition: ScriptMgr.h:698
@ SPELL_AURA_MOD_CHARM
Definition: SpellAuraDefines.h:69
@ SPELL_AURA_IGNORE_MELEE_RESET
Definition: SpellAuraDefines.h:335
@ SPELL_AURA_BIND_SIGHT
Definition: SpellAuraDefines.h:64
@ SPELL_STATE_DELAYED
Definition: Spell.h:228
@ SPELL_STATE_FINISHED
Definition: Spell.h:226
@ TRIGGERED_IGNORE_POWER_AND_REAGENT_COST
Will ignore Spell and Category cooldowns.
Definition: SpellDefines.h:134
@ TRIGGERED_IGNORE_CAST_ITEM
Will ignore power and reagent cost.
Definition: SpellDefines.h:135
@ TRIGGERED_IGNORE_SET_FACING
Will ignore interruptible aura's at cast.
Definition: SpellDefines.h:141
@ TARGET_FLAG_TRADE_ITEM
Definition: SpellInfo.h:58
@ TARGET_FLAG_UNIT
Definition: SpellInfo.h:47
@ PROC_EX_CRITICAL_HIT
Definition: SpellMgr.h:195
@ PROC_EX_NORMAL_HIT
Definition: SpellMgr.h:194
@ PROC_SPELL_PHASE_CAST
Definition: SpellMgr.h:243
@ PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_POS
Definition: SpellMgr.h:128
@ PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_POS
Definition: SpellMgr.h:122
@ PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_NEG
Definition: SpellMgr.h:125
@ PROC_FLAG_NONE
Definition: SpellMgr.h:105
@ PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG
Definition: SpellMgr.h:131
@ ACHIEVEMENT_TIMED_TYPE_ITEM
Definition: DBCEnums.h:123
@ ACHIEVEMENT_CRITERIA_TYPE_USE_ITEM
Definition: DBCEnums.h:163
@ ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL
Definition: DBCEnums.h:151
@ 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
Definition: Creature.h:46
uint32 GetEntry() const
Definition: Object.h:109
Creature * ToCreature()
Definition: Object.h:197
Definition: Pet.h:40
Definition: Player.h:1056
void UpdateAchievementCriteria(AchievementCriteriaTypes type, uint32 miscValue1=0, uint32 miscValue2=0, Unit *unit=nullptr)
Definition: PlayerUpdates.cpp:2131
void SetSpellModTakingSpell(Spell *spell, bool apply)
Definition: Player.cpp:9996
void StartTimedAchievement(AchievementCriteriaTimedTypes type, uint32 entry, uint32 timeLost=0)
Definition: Player.cpp:13836
void RemoveSpellMods(Spell *spell)
Definition: Player.cpp:9928
Pet * GetPet() const
Definition: Player.cpp:8819
bool GetCommandStatus(uint32 command) const
Definition: Player.h:1166
void RemovePet(Pet *pet, PetSaveMode mode, bool returnreagent=false)
Definition: Player.cpp:8970
TradeData * GetTradeData() const
Definition: Player.h:1356
void RemoveSpellCooldown(uint32 spell_id, bool update=false)
Definition: Player.cpp:3475
Definition: TradeData.h:36
Definition: Unit.h:1302
void ClearUnitState(uint32 f)
Definition: Unit.h:1411
AuraEffectList const & GetAuraEffectsByType(AuraType type) const
Definition: Unit.h:1981
Unit * GetCharm() const
Definition: Unit.cpp:10665
Player * GetSpellModOwner() const
Definition: Unit.cpp:16845
void CombatStartOnCast(Unit *target, bool initialAggro=true, uint32 duration=0)
Definition: Unit.cpp:13695
bool haveOffhandWeapon() const
Definition: Unit.cpp:540
bool IsPet() const
Definition: Unit.h:1425
bool IsNonMeleeSpellCast(bool withDelayed, bool skipChanneled=false, bool skipAutorepeat=false, bool isAutoshoot=false, bool skipInstant=true) const
Definition: Unit.cpp:4051
SpellCastResult CastSpell(SpellCastTargets const &targets, SpellInfo const *spellInfo, CustomSpellValues const *value, TriggerCastFlags triggerFlags=TRIGGERED_NONE, Item *castItem=nullptr, AuraEffect const *triggeredByAura=nullptr, ObjectGuid originalCaster=ObjectGuid::Empty)
Definition: Unit.cpp:1169
void RemoveAurasDueToSpell(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, uint8 reqEffMask=0, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition: Unit.cpp:4855
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:6316
bool HasUnitState(const uint32 f) const
Definition: Unit.h:1410
bool IsFriendlyTo(Unit const *unit) const
Definition: Unit.cpp:10249
bool IsControlledByPlayer() const
Definition: Unit.h:1842
std::list< AuraEffect * > AuraEffectList
Definition: Unit.h:1318
void SetInFront(WorldObject const *target)
Definition: Unit.cpp:20878
void resetAttackTimer(WeaponAttackType type=BASE_ATTACK)
Definition: Unit.cpp:661
WorldObject * GetObjectTarget() const
Definition: Spell.cpp:310
void UpdateTradeSlotItem()
Definition: Spell.cpp:347
ObjectGuid GetObjectTargetGUID() const
Definition: Spell.cpp:315
Item * GetItemTarget() const
Definition: Spell.h:139
uint32 GetTargetMask() const
Definition: Spell.h:117
Unit * GetUnitTarget() const
Definition: Spell.cpp:231
int8 effectIndex
Definition: Spell.h:279
SpellInfo const * spellInfo
Definition: Spell.h:278
SpellInfo const * GetSpellInfo() const
Definition: Spell.h:574
void CallScriptAfterCastHandlers()
Definition: Spell.cpp:8503
void PrepareTriggersExecutedOnHit()
Definition: Spell.cpp:8709
SpellCastTargets m_targets
Definition: Spell.h:527
TriggeredByAuraSpellData m_triggeredByAuraSpell
Definition: Spell.h:771
void handle_immediate()
Definition: Spell.cpp:4103
void SendSpellGo()
Definition: Spell.cpp:4773
void TakeReagents()
Definition: Spell.cpp:5507
void SetExecutedCurrently(bool yes)
Definition: Spell.h:560
void SendInterrupted(uint8 result)
Definition: Spell.cpp:5150
void PrepareScriptHitHandlers()
Definition: Spell.cpp:8535
void CallScriptOnCastHandlers()
Definition: Spell.cpp:8490
void cancel(bool bySelf=false)
Definition: Spell.cpp:3707
void SendSpellCooldown()
Definition: Spell.cpp:4340
void CallScriptBeforeCastHandlers()
Definition: Spell.cpp:8477
void HandleLaunchPhase()
Definition: Spell.cpp:8190
bool UpdatePointers()
Definition: Spell.cpp:7823
void SetDelayStart(uint64 m_time)
Definition: Spell.h:562
std::list< TargetInfo > m_UniqueTargetInfo
Definition: Spell.h:681
void SelectSpellTargets()
Definition: Spell.cpp:814
void TakePower()
Definition: Spell.cpp:5291
SpellCastResult CheckCast(bool strict)
Definition: Spell.cpp:5626
static void SendCastResult(Player *caster, SpellInfo const *spellInfo, uint8 castCount, SpellCastResult result, SpellCustomErrors customError=SPELL_CUSTOM_ERROR_NONE)
Definition: Spell.cpp:4645
uint64 GetDelayMoment() const
Definition: Spell.h:563
void TakeCastItem()
Definition: Spell.cpp:5228
bool IsAutoActionResetSpell() const
Definition: Spell.cpp:8037
void finish(bool ok=true)
Definition: Spell.cpp:4463
float Speed
Definition: SpellInfo.h:368
bool IsChanneled() const
Definition: SpellInfo.cpp:1243
uint32 CalcCastTime(Unit *caster=nullptr, Spell *spell=nullptr) const
Definition: SpellInfo.cpp:2338
bool HasAura(AuraType aura) const
Definition: SpellInfo.cpp:880

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

Referenced by cast().

◆ _handle_finish_phase()

void Spell::_handle_finish_phase ( )
4266{
4267 // Take for real after all targets are processed
4269 {
4271 }
4272
4273 // Real add combo points from effects
4275 {
4276 // remove Premed-like effects unless they were caused by ourselves
4277 // (this Aura removes the already-added CP when it expires from duration - now that we've added CP, this shouldn't happen anymore!)
4279 {
4281 }
4282
4284 }
4285
4287 {
4289 }
4290
4293 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
4294 {
4295 // Xinef: Properly clear infinite cooldowns in some cases
4296 if (ihit->targetGUID == m_caster->GetGUID() && ihit->missCondition != SPELL_MISS_NONE)
4299 }
4300
4301 // Handle procs on finish
4302 if (m_originalCaster)
4303 {
4304 uint32 procAttacker = m_procAttacker;
4305 if (!procAttacker)
4306 {
4307 bool IsPositive = m_spellInfo->IsPositive();
4309 {
4311 }
4312 else
4313 {
4315 }
4316 }
4317
4318 uint32 procEx = PROC_EX_NORMAL_HIT;
4319 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
4320 {
4321 if (ihit->missCondition != SPELL_MISS_NONE)
4322 {
4323 continue;
4324 }
4325
4326 if (!ihit->crit)
4327 {
4328 continue;
4329 }
4330
4331 procEx |= PROC_EX_CRITICAL_HIT;
4332 break;
4333 }
4334
4337 }
4338}
@ 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:11024
void SetLastExtraAttackSpell(uint32 spellId)
Definition: Unit.h:1583
Player * GetCharmerOrOwnerPlayerOrPlayerItself() const
Definition: Unit.cpp:10615
void ClearComboPoints()
Definition: Unit.cpp:17129
void AddComboPoints(Unit *target, int8 count)
Definition: Unit.cpp:17103
void RemoveAurasByType(AuraType auraType, ObjectGuid casterGUID=ObjectGuid::Empty, Aura *except=nullptr, bool negative=true, bool positive=true)
Definition: Unit.cpp:5045
bool IsAutoRepeat() const
Definition: Spell.h:548
bool IsNextMeleeSwingSpell() const
Definition: Spell.cpp:8027
bool IsCooldownStartedOnEvent() const
Definition: SpellInfo.cpp:1199

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

Referenced by handle_delayed(), and handle_immediate().

◆ _handle_immediate_phase()

void Spell::_handle_immediate_phase ( )
4238{
4239 m_spellAura = nullptr;
4240 // initialize Diminishing Returns Data
4243
4244 // handle some immediate features of the spell here
4246
4248
4249 // handle effects with SPELL_EFFECT_HANDLE_HIT mode
4250 for (uint32 j = 0; j < MAX_SPELL_EFFECTS; ++j)
4251 {
4252 // don't do anything for empty effect
4253 if (!m_spellInfo->Effects[j].IsEffect())
4254 continue;
4255
4256 // call effect handlers to handle destination hit
4257 HandleEffects(nullptr, nullptr, nullptr, j, SPELL_EFFECT_HANDLE_HIT);
4258 }
4259
4260 // process items
4261 for (std::list<ItemTargetInfo>::iterator ihit = m_UniqueItemInfo.begin(); ihit != m_UniqueItemInfo.end(); ++ihit)
4262 DoAllEffectOnTarget(&(*ihit));
4263}
@ SPELL_EFFECT_HANDLE_HIT
Definition: Spell.h:235
void HandleThreatSpells()
Definition: Spell.cpp:5556
void HandleEffects(Unit *pUnitTarget, Item *pItemTarget, GameObject *pGOTarget, uint32 i, SpellEffectHandleMode mode)
Definition: Spell.cpp:5603
std::list< ItemTargetInfo > m_UniqueItemInfo
Definition: Spell.h:698
void DoAllEffectOnTarget(TargetInfo *target)
Definition: Spell.cpp:2608
std::array< SpellEffectInfo, MAX_SPELL_EFFECTS > Effects
Definition: SpellInfo.h:391

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

Referenced by handle_delayed(), and handle_immediate().

◆ AddComboPointGain()

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

References m_comboPointGain, and m_comboTarget.

Referenced by EffectAddComboPoints(), and EffectWeaponDmg().

◆ AddDestTarget()

void Spell::AddDestTarget ( SpellDestination const &  dest,
uint32  effIndex 
)
protected
2604{
2605 m_destTargets[effIndex] = dest;
2606}

References m_destTargets.

Referenced by SelectSpellTargets().

◆ AddGOTarget()

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

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

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

◆ AddItemTarget()

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

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

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

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

Referenced by RecalculateDelayMomentForDst(), and SelectSpellTargets().

◆ CalculateJumpSpeeds()

void Spell::CalculateJumpSpeeds ( uint8  i,
float  dist,
float &  speedxy,
float &  speedz 
)
protected
1178{
1179 if (m_spellInfo->Effects[i].MiscValue)
1180 speedZ = float(m_spellInfo->Effects[i].MiscValue) / 10;
1181 else if (m_spellInfo->Effects[i].MiscValueB)
1182 speedZ = float(m_spellInfo->Effects[i].MiscValueB) / 10;
1183 else
1184 speedZ = 10.0f;
1185 speedXY = dist * 10.0f / speedZ;
1186}

References SpellInfo::Effects, and m_spellInfo.

Referenced by EffectJump(), and EffectJumpDest().

◆ CalculateSpellDamage()

int32 Spell::CalculateSpellDamage ( uint8  i,
Unit const *  target 
) const
inline
int32 CalculateSpellDamage(Unit const *target, SpellInfo const *spellProto, uint8 effect_index, int32 const *basePoints=nullptr) const
Definition: Unit.cpp:14837
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
8504{
8505 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8506 {
8507 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_AFTER_CAST);
8508 std::list<SpellScript::CastHandler>::iterator hookItrEnd = (*scritr)->AfterCast.end(), hookItr = (*scritr)->AfterCast.begin();
8509 for (; hookItr != hookItrEnd; ++hookItr)
8510 (*hookItr).Call(*scritr);
8511
8512 (*scritr)->_FinishScriptCall();
8513 }
8514}
@ 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
8616{
8617 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8618 {
8619 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_AFTER_HIT);
8620 std::list<SpellScript::HitHandler>::iterator hookItrEnd = (*scritr)->AfterHit.end(), hookItr = (*scritr)->AfterHit.begin();
8621 for (; hookItr != hookItrEnd; ++hookItr)
8622 (*hookItr).Call(*scritr);
8623
8624 (*scritr)->_FinishScriptCall();
8625 }
8626}
@ 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
8478{
8479 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8480 {
8481 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_BEFORE_CAST);
8482 std::list<SpellScript::CastHandler>::iterator hookItrEnd = (*scritr)->BeforeCast.end(), hookItr = (*scritr)->BeforeCast.begin();
8483 for (; hookItr != hookItrEnd; ++hookItr)
8484 (*hookItr).Call(*scritr);
8485
8486 (*scritr)->_FinishScriptCall();
8487 }
8488}
@ 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
8590{
8591 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8592 {
8593 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_BEFORE_HIT);
8594 std::list<SpellScript::BeforeHitHandler>::iterator hookItrEnd = (*scritr)->BeforeHit.end(), hookItr = (*scritr)->BeforeHit.begin();
8595 for (; hookItr != hookItrEnd; ++hookItr)
8596 (*hookItr).Call(*scritr, missInfo);
8597
8598 (*scritr)->_FinishScriptCall();
8599 }
8600}
@ 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
8517{
8519 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8520 {
8521 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_CHECK_CAST);
8522 std::list<SpellScript::CheckCastHandler>::iterator hookItrEnd = (*scritr)->OnCheckCast.end(), hookItr = (*scritr)->OnCheckCast.begin();
8523 for (; hookItr != hookItrEnd; ++hookItr)
8524 {
8525 SpellCastResult tempResult = (*hookItr).Call(*scritr);
8526 if (retVal == SPELL_CAST_OK)
8527 retVal = tempResult;
8528 }
8529
8530 (*scritr)->_FinishScriptCall();
8531 }
8532 return retVal;
8533}
@ 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
8657{
8658 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8659 {
8660 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_DESTINATION_TARGET_SELECT);
8661 std::list<SpellScript::DestinationTargetSelectHandler>::iterator hookItrEnd = (*scritr)->OnDestinationTargetSelect.end(), hookItr = (*scritr)->OnDestinationTargetSelect.begin();
8662 for (; hookItr != hookItrEnd; ++hookItr)
8663 if (hookItr->IsEffectAffected(m_spellInfo, effIndex) && targetType.GetTarget() == hookItr->GetTarget())
8664 hookItr->Call(*scritr, target);
8665
8666 (*scritr)->_FinishScriptCall();
8667 }
8668}
@ 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
8542{
8543 // execute script effect handler hooks and check if effects was prevented
8544 bool preventDefault = false;
8545 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8546 {
8547 std::list<SpellScript::EffectHandler>::iterator effItr, effEndItr;
8548 SpellScriptHookType hookType;
8549 switch (mode)
8550 {
8552 effItr = (*scritr)->OnEffectLaunch.begin();
8553 effEndItr = (*scritr)->OnEffectLaunch.end();
8555 break;
8557 effItr = (*scritr)->OnEffectLaunchTarget.begin();
8558 effEndItr = (*scritr)->OnEffectLaunchTarget.end();
8560 break;
8562 effItr = (*scritr)->OnEffectHit.begin();
8563 effEndItr = (*scritr)->OnEffectHit.end();
8565 break;
8567 effItr = (*scritr)->OnEffectHitTarget.begin();
8568 effEndItr = (*scritr)->OnEffectHitTarget.end();
8570 break;
8571 default:
8572 ABORT();
8573 return false;
8574 }
8575 (*scritr)->_PrepareScriptCall(hookType);
8576 for (; effItr != effEndItr; ++effItr)
8577 // effect execution can be prevented
8578 if (!(*scritr)->_IsEffectPrevented(effIndex) && (*effItr).IsEffectAffected(m_spellInfo, effIndex))
8579 (*effItr).Call(*scritr, effIndex);
8580
8581 if (!preventDefault)
8582 preventDefault = (*scritr)->_IsDefaultEffectPrevented(effIndex);
8583
8584 (*scritr)->_FinishScriptCall();
8585 }
8586 return preventDefault;
8587}
#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
8629{
8630 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8631 {
8632 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_OBJECT_AREA_TARGET_SELECT);
8633 std::list<SpellScript::ObjectAreaTargetSelectHandler>::iterator hookItrEnd = (*scritr)->OnObjectAreaTargetSelect.end(), hookItr = (*scritr)->OnObjectAreaTargetSelect.begin();
8634 for (; hookItr != hookItrEnd; ++hookItr)
8635 if (hookItr->IsEffectAffected(m_spellInfo, effIndex) && targetType.GetTarget() == hookItr->GetTarget())
8636 hookItr->Call(*scritr, targets);
8637
8638 (*scritr)->_FinishScriptCall();
8639 }
8640}
@ 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
8643{
8644 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8645 {
8646 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_OBJECT_TARGET_SELECT);
8647 std::list<SpellScript::ObjectTargetSelectHandler>::iterator hookItrEnd = (*scritr)->OnObjectTargetSelect.end(), hookItr = (*scritr)->OnObjectTargetSelect.begin();
8648 for (; hookItr != hookItrEnd; ++hookItr)
8649 if (hookItr->IsEffectAffected(m_spellInfo, effIndex) && targetType.GetTarget() == hookItr->GetTarget())
8650 hookItr->Call(*scritr, target);
8651
8652 (*scritr)->_FinishScriptCall();
8653 }
8654}
@ 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
8491{
8492 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8493 {
8494 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_ON_CAST);
8495 std::list<SpellScript::CastHandler>::iterator hookItrEnd = (*scritr)->OnCast.end(), hookItr = (*scritr)->OnCast.begin();
8496 for (; hookItr != hookItrEnd; ++hookItr)
8497 (*hookItr).Call(*scritr);
8498
8499 (*scritr)->_FinishScriptCall();
8500 }
8501}
@ 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
8603{
8604 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8605 {
8606 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_HIT);
8607 std::list<SpellScript::HitHandler>::iterator hookItrEnd = (*scritr)->OnHit.end(), hookItr = (*scritr)->OnHit.begin();
8608 for (; hookItr != hookItrEnd; ++hookItr)
8609 (*hookItr).Call(*scritr);
8610
8611 (*scritr)->_FinishScriptCall();
8612 }
8613}
@ 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)
6976{
6977 ObjectGuid targetguid = target->GetGUID();
6978
6979 for (uint32 j = 0; j < MAX_SPELL_EFFECTS; ++j)
6980 {
6982 {
6983 if (m_spellInfo->StackAmount <= 1)
6984 {
6985 if (target->HasAuraEffect(m_spellInfo->Id, j))
6986 return false;
6987 }
6988 else
6989 {
6990 if (AuraEffect* aureff = target->GetAuraEffect(m_spellInfo->Id, j))
6991 if (aureff->GetBase()->GetStackAmount() >= m_spellInfo->StackAmount)
6992 return false;
6993 }
6994 }
6995 else if (m_spellInfo->Effects[j].IsAreaAuraEffect())
6996 {
6997 if (target->HasAuraEffect(m_spellInfo->Id, j))
6998 return false;
6999 }
7000 }
7001
7002 SpellCastResult result = CheckPetCast(target);
7003
7004 if (result == SPELL_CAST_OK || result == SPELL_FAILED_UNIT_NOT_INFRONT)
7005 {
7007 //check if among target units, our WANTED target is as well (->only self cast spells return false)
7008 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
7009 if (ihit->targetGUID == targetguid)
7010 return true;
7011 }
7012 return false; //target invalid
7013}
@ 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:5432
bool HasAuraEffect(uint32 spellId, uint8 effIndex, ObjectGuid caster=ObjectGuid::Empty) const
Definition: Unit.cpp:5606
Definition: SpellAuraEffects.h:39
SpellCastResult CheckPetCast(Unit *target)
Definition: Spell.cpp:6782
uint32 StackAmount
Definition: SpellInfo.h:369

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

Referenced by PetAI::UpdateAI().

◆ cancel()

void Spell::cancel ( bool  bySelf = false)
Todo:
: Not sure whether the fallthrough was a mistake (forgetting a break) or intended. This should be double-checked.
3708{
3710 return;
3711
3712 uint32 oldState = m_spellState;
3713 bool autoRepeat = m_autoRepeat;
3715
3716 m_autoRepeat = false;
3717 switch (oldState)
3718 {
3722 {
3724 ArenaSpectator::SendCommand_Spell(m_caster->FindMap(), m_caster->GetGUID(), "SPE", m_spellInfo->Id, bySelf ? 99998 : 99999);
3725 }
3726 [[fallthrough]];
3728 SendInterrupted(0);
3729 // xinef: fixes bugged gcd reset in some cases
3730 if (!autoRepeat)
3732 break;
3733
3735 if (!bySelf)
3736 {
3737 for (std::list<TargetInfo>::const_iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
3738 if ((*ihit).missCondition == SPELL_MISS_NONE)
3739 if (Unit* unit = m_caster->GetGUID() == ihit->targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID))
3740 unit->RemoveOwnedAura(m_spellInfo->Id, m_originalCasterGUID, 0, AURA_REMOVE_BY_CANCEL);
3741
3743 SendInterrupted(0);
3745 }
3746
3748 ArenaSpectator::SendCommand_Spell(m_caster->FindMap(), m_caster->GetGUID(), "SPE", m_spellInfo->Id, bySelf ? 99998 : 99999);
3749
3750 // spell is canceled-take mods and clear list
3751 if (Player* player = m_caster->GetSpellModOwner())
3752 player->RemoveSpellMods(this);
3753
3754 m_appliedMods.clear();
3755 break;
3756 default:
3757 break;
3758 }
3759
3761 if (m_selfContainer && *m_selfContainer == this)
3762 *m_selfContainer = nullptr;
3763
3764 // Do not remove current far sight object (already done in Spell::EffectAddFarsight) to prevent from reset viewpoint to player
3766 {
3768 }
3769
3770 if (m_spellInfo->IsChanneled()) // if not channeled then the object for the current cast wasn't summoned yet
3772
3773 //set state back so finish will be processed
3774 m_spellState = oldState;
3775
3776 finish(false);
3777}
@ 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:518
bool NeedSendSpectatorData() const
Definition: Player.cpp:15319
void RemoveGameObject(GameObject *gameObj, bool del)
Definition: Unit.cpp:6135
bool RemoveDynObject(uint32 spellId)
Definition: Unit.cpp:6079
void SendChannelUpdate(uint32 time)
Definition: Spell.cpp:5167
void CancelGlobalCooldown()
Definition: Spell.cpp:8844
void SetReferencedFromCurrent(bool yes)
Definition: Spell.h:558
UsedSpellMods m_appliedMods
Definition: Spell.h:545

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

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

◆ CancelGlobalCooldown()

void Spell::CancelGlobalCooldown ( )
protected
8845{
8847 return;
8848
8849 // Cancel global cooldown when interrupting current cast
8851 return;
8852
8853 // Only players or controlled units have global cooldown
8854 if (m_caster->GetCharmInfo())
8856 else if (m_caster->GetTypeId() == TYPEID_PLAYER)
8858}
@ CURRENT_GENERIC_SPELL
Definition: Unit.h:991
GlobalCooldownMgr & GetGlobalCooldownMgr()
Definition: Player.h:1768
void CancelGlobalCooldown(SpellInfo const *spellInfo)
Definition: Unit.cpp:352
GlobalCooldownMgr & GetGlobalCooldownMgr()
Definition: Unit.h:1139
CharmInfo * GetCharmInfo()
Definition: Unit.h:1897
Spell * GetCurrentSpell(CurrentSpellTypes spellType) const
Definition: Unit.h:2075
uint32 StartRecoveryTime
Definition: SpellInfo.h:349

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

Referenced by cancel().

◆ CanExecuteTriggersOnHit()

bool Spell::CanExecuteTriggersOnHit ( uint8  effMask,
SpellInfo const *  triggeredByAura = nullptr 
) const
protected
8694{
8695 // Relentless strikes, proc only from first effect
8696 if (triggeredByAura && triggeredByAura->SpellIconID == 559)
8697 return effMask & (1 << EFFECT_0);
8698
8699 bool only_on_caster = (triggeredByAura && triggeredByAura->HasAttribute(SPELL_ATTR4_CLASS_TRIGGER_ONLY_ON_TARGET));
8700 // If triggeredByAura has SPELL_ATTR4_CLASS_TRIGGER_ONLY_ON_TARGET then it can only proc on a casted spell with TARGET_UNIT_CASTER
8701 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
8702 {
8703 if ((effMask & (1 << i)) && (!only_on_caster || (m_spellInfo->Effects[i].TargetA.GetTarget() == TARGET_UNIT_CASTER)))
8704 return true;
8705 }
8706 return effMask;
8707}
@ 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
8318{
8319 if (!lockId) // possible case for GO and maybe for items.
8320 return SPELL_CAST_OK;
8321
8322 // Get LockInfo
8323 LockEntry const* lockInfo = sLockStore.LookupEntry(lockId);
8324
8325 if (!lockInfo)
8327
8328 bool reqKey = false; // some locks not have reqs
8329
8330 for (int j = 0; j < MAX_LOCK_CASE; ++j)
8331 {
8332 switch (lockInfo->Type[j])
8333 {
8334 // check key item (many fit cases can be)
8335 case LOCK_KEY_ITEM:
8336 if (lockInfo->Index[j] && m_CastItem && m_CastItem->GetEntry() == lockInfo->Index[j])
8337 return SPELL_CAST_OK;
8338 reqKey = true;
8339 break;
8340 // check key skill (only single first fit case can be)
8341 case LOCK_KEY_SKILL:
8342 {
8343 reqKey = true;
8344
8345 // wrong locktype, skip
8346 if (uint32(m_spellInfo->Effects[effIndex].MiscValue) != lockInfo->Index[j])
8347 continue;
8348
8349 skillId = SkillByLockType(LockType(lockInfo->Index[j]));
8350
8351 if (skillId != SKILL_NONE)
8352 {
8353 reqSkillValue = lockInfo->Skill[j];
8354
8355 // castitem check: rogue using skeleton keys. the skill values should not be added in this case.
8356 skillValue = m_CastItem || m_caster->GetTypeId() != TYPEID_PLAYER ?
8357 0 : m_caster->ToPlayer()->GetSkillValue(skillId);
8358
8359 // skill bonus provided by casting spell (mostly item spells)
8360 // add the effect base points modifier from the spell casted (cheat lock / skeleton key etc.)
8361 if ((m_spellInfo->Effects[effIndex].TargetA.GetTarget() == TARGET_GAMEOBJECT_ITEM_TARGET || m_spellInfo->Effects[effIndex].TargetB.GetTarget() == TARGET_GAMEOBJECT_ITEM_TARGET)
8363 {
8364 skillValue += m_spellInfo->Effects[effIndex].CalcValue();
8365 }
8366
8367 if (skillValue < reqSkillValue)
8369 }
8370
8371 return SPELL_CAST_OK;
8372 }
8373 case LOCK_KEY_SPELL:
8374 {
8375 if (m_spellInfo->Id == lockInfo->Index[j])
8376 {
8377 return SPELL_CAST_OK;
8378 }
8379 reqKey = true;
8380 break;
8381 }
8382 }
8383 }
8384
8385 if (reqKey)
8387
8388 return SPELL_CAST_OK;
8389}
DBCStorage< LockEntry > sLockStore(LockEntryfmt)
#define MAX_LOCK_CASE
Definition: DBCStructure.h:1303
@ 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
uint16 GetSkillValue(uint32 skill) const
Definition: Player.cpp:5367
bool IsAbilityOfSkillType(uint32 skillType) const
Definition: SpellInfo.cpp:992
Definition: DBCStructure.h:1306
uint32 Type[MAX_LOCK_CASE]
Definition: DBCStructure.h:1308
uint32 Index[MAX_LOCK_CASE]
Definition: DBCStructure.h:1309
uint32 Skill[MAX_LOCK_CASE]
Definition: DBCStructure.h:1310

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

Referenced by CheckCast(), and EffectOpenLock().

◆ cast()

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

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
5627{
5628 // check death state
5631
5632 // Spectator check
5634 if (((Player const*)m_caster)->IsSpectator() && m_spellInfo->Id != SPECTATOR_SPELL_BINDSIGHT)
5635 return SPELL_FAILED_NOT_HERE;
5636
5638
5639 sScriptMgr->OnSpellCheckCast(this, strict, res);
5640
5641 if (res != SPELL_CAST_OK)
5642 return res;
5643
5644 // check cooldowns to prevent cheating
5646 {
5648 {
5649 //can cast triggered (by aura only?) spells while have this flag
5652
5654 {
5657 else
5659 }
5660
5661 // check if we are using a potion in combat for the 2nd+ time. Cooldown is added only after caster gets out of combat
5664 }
5667 }
5668
5670 {
5673 }
5674
5675 // Check global cooldown
5678
5679 // only triggered spells can be processed an ended battleground
5682 if (bg->GetStatus() == STATUS_WAIT_LEAVE)
5684
5685 if (m_caster->GetTypeId() == TYPEID_PLAYER /*&& VMAP::VMapFactory::createOrGetVMapMgr()->isLineOfSightCalcEnabled()*/) // pussywizard: optimization (commented)
5686 {
5688 !m_caster->IsOutdoors())
5690
5694 }
5695
5696 // only check at first call, Stealth auras are already removed at second call
5697 // for now, ignore triggered spells
5699 {
5700 bool checkForm = true;
5701 // Ignore form req aura
5703 for (Unit::AuraEffectList::const_iterator i = ignore.begin(); i != ignore.end(); ++i)
5704 {
5705 if (!(*i)->IsAffectedOnSpell(m_spellInfo))
5706 continue;
5707 checkForm = false;
5708 break;
5709 }
5710 if (checkForm)
5711 {
5712 // Cannot be used in this stance/form
5714 if (shapeError != SPELL_CAST_OK)
5715 return shapeError;
5716
5719 }
5720 }
5721
5723 for (Unit::AuraEffectList::const_iterator blockItr = blockSpells.begin(); blockItr != blockSpells.end(); ++blockItr)
5724 if (uint32((*blockItr)->GetMiscValue()) == m_spellInfo->SpellFamilyName)
5726
5727 bool reqCombat = true;
5729 for (Unit::AuraEffectList::const_iterator j = stateAuras.begin(); j != stateAuras.end(); ++j)
5730 {
5731 if ((*j)->IsAffectedOnSpell(m_spellInfo))
5732 {
5733 m_needComboPoints = false;
5734 if ((*j)->GetMiscValue() == 1)
5735 {
5736 reqCombat = false;
5737 break;
5738 }
5739 }
5740 }
5741
5742 // caster state requirements
5743 // not for triggered spells (needed by execute)
5745 {
5750
5751 // Note: spell 62473 requres CasterAuraSpell = triggering spell
5756
5757 if (reqCombat && m_caster->IsInCombat() && !m_spellInfo->CanBeUsedInCombat())
5759 }
5760
5761 // Xinef: exploit protection
5763 {
5765 if (InstanceScript* instanceScript = m_caster->GetInstanceScript())
5766 if (instanceScript->IsEncounterInProgress())
5767 {
5768 if (Group* group = m_caster->ToPlayer()->GetGroup())
5769 for (GroupReference* itr = group->GetFirstMember(); itr != nullptr; itr = itr->next())
5770 if (Player* member = itr->GetSource())
5771 if (member->IsInMap(m_caster))
5772 if (Unit* victim = member->GetVictim())
5773 if (victim->IsInCombat() && m_caster->GetDistance(victim) < m_caster->GetVisibilityRange())
5774 {
5775 m_caster->CombatStart(victim);
5776 victim->AddThreat(m_caster, 1.0f);
5777 break;
5778 }
5780 }
5781 }
5782
5783 // cancel autorepeat spells if cast start when moving
5784 // (not wand currently autorepeat cast delayed to moving stop anyway in spell update code)
5786 {
5787 // skip stuck spell to allow use it in falling case and apply spell limitations at movement
5790 return SPELL_FAILED_MOVING;
5791 }
5792
5793 Vehicle* vehicle = m_caster->GetVehicle();
5795 {
5796 uint16 checkMask = 0;
5797 for (uint8 effIndex = EFFECT_0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
5798 {
5799 SpellEffectInfo const* effInfo = &m_spellInfo->Effects[effIndex];
5801 {
5802 SpellShapeshiftEntry const* shapeShiftEntry = sSpellShapeshiftStore.LookupEntry(effInfo->MiscValue);
5803 if (shapeShiftEntry && (shapeShiftEntry->flags1 & 1) == 0) // unk flag
5804 checkMask |= VEHICLE_SEAT_FLAG_UNCONTROLLED;
5805 break;
5806 }
5807 }
5808
5811
5812 if (!checkMask)
5813 checkMask = VEHICLE_SEAT_FLAG_CAN_ATTACK;
5814
5815 // All creatures should be able to cast as passengers freely, restriction and attribute are only for players
5816 VehicleSeatEntry const* vehicleSeat = vehicle->GetSeatForPassenger(m_caster);
5818 && (vehicleSeat->m_flags & checkMask) != checkMask && m_caster->GetTypeId() == TYPEID_PLAYER)
5820 }
5821
5822 // check spell cast conditions from database
5823 {
5826 ConditionList conditions = sConditionMgr->GetConditionsForNotGroupedEntry(CONDITION_SOURCE_TYPE_SPELL, m_spellInfo->Id);
5827 if (!conditions.empty() && !sConditionMgr->IsObjectMeetToConditions(condInfo, conditions))
5828 {
5829 // mLastFailedCondition can be nullptr if there was an error processing the condition in Condition::Meets (i.e. wrong data for ConditionTarget or others)
5830 if (condInfo.mLastFailedCondition && condInfo.mLastFailedCondition->ErrorType)
5831 {
5835 }
5836 if (!condInfo.mLastFailedCondition || !condInfo.mLastFailedCondition->ConditionTarget)
5839 }
5840 }
5841
5842 // Don't check explicit target for passive spells (workaround) (check should be skipped only for learn case)
5843 // those spells may have incorrect target entries or not filled at all (for example 15332)
5844 // such spells when learned are not targeting anyone using targeting system, they should apply directly to caster instead
5845 // also, such casts shouldn't be sent to client
5846 // Xinef: do not check explicit casts for self cast of triggered spells (eg. reflect case)
5848 {
5849 // Check explicit target for m_originalCaster - todo: get rid of such workarounds
5850 // Xinef: do not check explicit target for triggered spell casted on self with targetflag enemy
5852 {
5854 if (castResult != SPELL_CAST_OK)
5855 return castResult;
5856 }
5857 }
5858
5859 if (Unit* target = m_targets.GetUnitTarget())
5860 {
5861 SpellCastResult castResult = m_spellInfo->CheckTarget(m_caster, target, false);
5862 if (castResult != SPELL_CAST_OK)
5863 return castResult;
5864
5865 if (target != m_caster)
5866 {
5867 // Must be behind the target
5868 if (m_spellInfo->HasAttribute(SPELL_ATTR0_CU_REQ_CASTER_BEHIND_TARGET) && target->HasInArc(static_cast<float>(M_PI), m_caster))
5870
5871 // Target must be facing you
5872 if (m_spellInfo->HasAttribute(SPELL_ATTR0_CU_REQ_TARGET_FACING_CASTER) && !target->HasInArc(static_cast<float>(M_PI), m_caster))
5874
5877 {
5878 bool castedByGameobject = false;
5879 uint32 losChecks = LINEOFSIGHT_ALL_CHECKS;
5881 {
5882 castedByGameobject = m_caster->GetMap()->GetGameObject(m_originalCasterGUID) != nullptr;
5883 }
5884 else if (m_caster->GetEntry() == WORLD_TRIGGER)
5885 {
5886 if (TempSummon* tempSummon = m_caster->ToTempSummon())
5887 {
5888 castedByGameobject = tempSummon->GetSummonerGameObject() != nullptr;
5889 }
5890 }
5891
5892 if (castedByGameobject)
5893 {
5894 // If spell casted by gameobject then ignore M2 models
5895 losChecks &= ~LINEOFSIGHT_CHECK_GOBJECT_M2;
5896 }
5897
5899 {
5901 }
5902 }
5903 }
5904 }
5905
5906 // Check for line of sight for spells with dest
5907 if (m_targets.HasDst())
5908 {
5909 float x, y, z;
5910 m_targets.GetDstPos()->GetPosition(x, y, z);
5911
5914 {
5915 bool castedByGameobject = false;
5916 uint32 losChecks = LINEOFSIGHT_ALL_CHECKS;
5918 {
5919 castedByGameobject = m_caster->GetMap()->GetGameObject(m_originalCasterGUID) != nullptr;
5920 }
5921 else if (m_caster->GetEntry() == WORLD_TRIGGER)
5922 {
5923 if (TempSummon* tempSummon = m_caster->ToTempSummon())
5924 {
5925 castedByGameobject = tempSummon->GetSummonerGameObject() != nullptr;
5926 }
5927 }
5928
5929 if (castedByGameobject)
5930 {
5931 // If spell casted by gameobject then ignore M2 models
5932 losChecks &= ~LINEOFSIGHT_CHECK_GOBJECT_M2;
5933 }
5934
5936 {
5938 }
5939 }
5940 }
5941
5942 // check pet presence
5943 for (int j = 0; j < MAX_SPELL_EFFECTS; ++j)
5944 {
5945 if (m_spellInfo->Effects[j].TargetA.GetTarget() == TARGET_UNIT_PET)
5946 {
5948 {
5949 if (m_triggeredByAuraSpell.spellInfo) // not report pet not existence for triggered spells
5951 else
5952 return SPELL_FAILED_NO_PET;
5953 }
5954 break;
5955 }
5956 }
5957 // Spell casted only on battleground
5959 if (!m_caster->ToPlayer()->InBattleground())
5961
5962 // do not allow spells to be cast in arenas
5963 // - with greater than 10 min CD without SPELL_ATTR4_IGNORE_DEFAULT_ARENA_RESTRICTIONS flag
5964 // - with SPELL_ATTR4_NOT_IN_ARENA_OR_RATED_BATTLEGROUND flag
5967 if (MapEntry const* mapEntry = sMapStore.LookupEntry(m_caster->GetMapId()))
5968 if (mapEntry->IsBattleArena())
5970
5971 // zone check
5973 {
5974 uint32 zone, area;
5975 m_caster->GetZoneAndAreaId(zone, area);
5976
5978 m_caster->GetTypeId() == TYPEID_PLAYER ? m_caster->ToPlayer() : nullptr);
5979 if (locRes != SPELL_CAST_OK)
5980 return locRes;
5981 }
5982
5983 // not let players cast spells at mount (and let do it to creatures)
5986 {
5987 if (m_caster->IsInFlight())
5989 else
5991 }
5992
5993 SpellCastResult castResult = SPELL_CAST_OK;
5994
5995 // always (except passive spells) check items (focus object can be required for any type casts)
5996 if (!m_spellInfo->IsPassive())
5997 {
5998 // spell focus needs to be checked not only for players! there are vehicle spells that require spell focus
5999 castResult = CheckSpellFocus();
6000 if (castResult != SPELL_CAST_OK)
6001 return castResult;
6002
6003 castResult = CheckItems();
6004 if (castResult != SPELL_CAST_OK)
6005 return castResult;
6006 }
6007
6008 // Triggered spells also have range check
6010 castResult = CheckRange(strict);
6011 if (castResult != SPELL_CAST_OK)
6012 return castResult;
6013
6015 {
6016 castResult = CheckPower();
6017 if (castResult != SPELL_CAST_OK)
6018 return castResult;
6019 }
6020
6021 // xinef: do not skip triggered spells if they posses prevention type (eg. Bladestorm vs Hand of Protection)
6023 {
6025 if (castResult != SPELL_CAST_OK)
6026 return castResult;
6027
6028 // 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).
6030 {
6032 for (SpellImmuneList::const_iterator itr = mechanicList.begin(); itr != mechanicList.end(); ++itr)
6033 if (itr->type == m_spellInfo->Mechanic)
6035 }
6036 }
6037
6038 // script hook
6039 castResult = CallScriptCheckCastHandlers();
6040 if (castResult != SPELL_CAST_OK)
6041 return castResult;
6042
6043 bool hasDispellableAura = false;
6044 bool hasNonDispelEffect = false;
6045 uint32 dispelMask = 0;
6046 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
6047 if (m_spellInfo->Effects[i].Effect == SPELL_EFFECT_DISPEL)
6048 {
6050 {
6051 hasDispellableAura = true;
6052 break;
6053 }
6054
6055 dispelMask |= SpellInfo::GetDispelMask(DispelType(m_spellInfo->Effects[i].MiscValue));
6056 }
6057 else if (m_spellInfo->Effects[i].IsEffect())
6058 {
6059 hasNonDispelEffect = true;
6060 break;
6061 }
6062
6063 if (!hasNonDispelEffect && !hasDispellableAura && dispelMask && !IsTriggered())
6064 {
6065 if (Unit* target = m_targets.GetUnitTarget())
6066 {
6067 // Xinef: do not allow to cast on hostile targets in sanctuary
6068 if (!m_caster->IsFriendlyTo(target))
6069 {
6070 if (m_caster->IsInSanctuary() || target->IsInSanctuary())
6071 {
6072 // Xinef: fix for duels
6073 Player* player = m_caster->ToPlayer();
6074 if (!player || !player->duel || target != player->duel->Opponent)
6076 }
6077 }
6078
6079 DispelChargesList dispelList;
6080 target->GetDispellableAuraList(m_caster, dispelMask, dispelList, m_spellInfo);
6081
6082 if (dispelList.empty())
6084 }
6085 }
6086
6087 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
6088 {
6089 // for effects of spells that have only one target
6090 switch (m_spellInfo->Effects[i].Effect)
6091 {
6093 {
6096
6097 if (m_spellInfo->Effects[i].TargetA.GetTarget() != TARGET_UNIT_PET)
6098 break;
6099
6100 Pet* pet = m_caster->ToPlayer()->GetPet();
6101
6102 if (!pet)
6103 return SPELL_FAILED_NO_PET;
6104
6105 SpellInfo const* learn_spellproto = sSpellMgr->GetSpellInfo(m_spellInfo->Effects[i].TriggerSpell);
6106
6107 if (!learn_spellproto)
6109
6110 if (m_spellInfo->SpellLevel > pet->GetLevel())
6111 return SPELL_FAILED_LOWLEVEL;
6112
6113 break;
6114 }
6116 {
6117 // check target only for unit target case
6119 {
6122
6123 Pet* pet = unitTarget->ToPet();
6124 if (!pet || pet->GetOwner() != m_caster)
6126
6127 SpellInfo const* learn_spellproto = sSpellMgr->GetSpellInfo(m_spellInfo->Effects[i].TriggerSpell);
6128
6129 if (!learn_spellproto)
6131
6132 if (m_spellInfo->SpellLevel > pet->GetLevel())
6133 return SPELL_FAILED_LOWLEVEL;
6134 }
6135 break;
6136 }
6138 {
6139 uint32 glyphId = m_spellInfo->Effects[i].MiscValue;
6140 if (GlyphPropertiesEntry const* gp = sGlyphPropertiesStore.LookupEntry(glyphId))
6141 if (m_caster->HasAura(gp->SpellId))
6143 break;
6144 }
6146 {
6149
6150 Item* foodItem = m_targets.GetItemTarget();
6151 if (!foodItem)
6153
6154 Pet* pet = m_caster->ToPlayer()->GetPet();
6155
6156 if (!pet)
6157 return SPELL_FAILED_NO_PET;
6158
6159 if (!pet->HaveInDiet(foodItem->GetTemplate()))
6161
6162 if (!pet->GetCurrentFoodBenefitLevel(foodItem->GetTemplate()->ItemLevel))
6164
6165 if (m_caster->IsInCombat() || pet->IsInCombat())
6167
6168 break;
6169 }
6172 {
6173 // Can be area effect, Check only for players and not check if target - caster (spell can have multiply drain/burn effects)
6175 if (Unit* target = m_targets.GetUnitTarget())
6176 if (target != m_caster && target->getPowerType() != Powers(m_spellInfo->Effects[i].MiscValue))
6178 break;
6179 }
6181 {
6183 {
6185 }
6186
6188 {
6189 // Warbringer - can't be handled in proc system - should be done before checkcast root check and charge effect process
6190 if (strict && m_caster->IsScriptOverriden(m_spellInfo, 6953))
6192 }
6194 {
6195 // Exception for Master's Call
6196 if (m_spellInfo->Id != 54216)
6197 {
6198 return SPELL_FAILED_ROOTED;
6199 }
6200 }
6202 if (Unit* target = m_targets.GetUnitTarget())
6203 if (!target->IsAlive())
6205 // Xinef: Pass only explicit unit target spells
6206 // pussywizard:
6208 {
6209 Unit* target = m_targets.GetUnitTarget();
6210 if (!target)
6212
6213 // first we must check to see if the target is in LoS. A path can usually be built but LoS matters for charge spells
6214 if (!target->IsWithinLOSInMap(m_caster)) //Do full LoS/Path check. Don't exclude m2
6216
6217 float objSize = target->GetCombatReach();
6218 float range = m_spellInfo->GetMaxRange(true, m_caster, this) * 1.5f + objSize; // can't be overly strict
6219
6220 m_preGeneratedPath = std::make_unique<PathGenerator>(m_caster);
6221 m_preGeneratedPath->SetPathLengthLimit(range);
6222
6223 // first try with raycast, if it fails fall back to normal path
6224 bool result = m_preGeneratedPath->CalculatePath(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), false);
6225 if (m_preGeneratedPath->GetPathType() & PATHFIND_SHORT)
6226 return SPELL_FAILED_NOPATH;
6227 else if (!result || m_preGeneratedPath->GetPathType() & (PATHFIND_NOPATH | PATHFIND_INCOMPLETE))
6228 return SPELL_FAILED_NOPATH;
6229 else if (m_preGeneratedPath->IsInvalidDestinationZ(target)) // Check position z, if not in a straight line
6230 return SPELL_FAILED_NOPATH;
6231
6232 m_preGeneratedPath->ShortenPathUntilDist(G3D::Vector3(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ()), objSize); // move back
6233 }
6234 if (Player* player = m_caster->ToPlayer())
6235 player->SetCanTeleport(true);
6236 break;
6237 }
6239 {
6242
6245
6246 Creature* creature = m_targets.GetUnitTarget()->ToCreature();
6247 if (!creature->IsCritter() && !creature->loot.isLooted())
6249
6250 uint32 skill = creature->GetCreatureTemplate()->GetRequiredLootSkill();
6251
6252 int32 skillValue = m_caster->ToPlayer()->GetSkillValue(skill);
6253 int32 TargetLevel = m_targets.GetUnitTarget()->GetLevel();
6254 int32 ReqValue = (skillValue < 100 ? (TargetLevel - 10) * 10 : TargetLevel * 5);
6255 if (ReqValue > skillValue)
6257
6258 break;
6259 }
6261 {
6262 if (m_spellInfo->Effects[i].TargetA.GetTarget() != TARGET_GAMEOBJECT_TARGET &&
6263 m_spellInfo->Effects[i].TargetA.GetTarget() != TARGET_GAMEOBJECT_ITEM_TARGET)
6264 break;
6265
6266 if (m_caster->GetTypeId() != TYPEID_PLAYER // only players can open locks, gather etc.
6267 // we need a go target in case of TARGET_GAMEOBJECT_TARGET
6268 || (m_spellInfo->Effects[i].TargetA.GetTarget() == TARGET_GAMEOBJECT_TARGET && !m_targets.GetGOTarget()))
6270
6271 Item* pTempItem = nullptr;
6273 {
6274 if (TradeData* pTrade = m_caster->ToPlayer()->GetTradeData())
6275 pTempItem = pTrade->GetTraderData()->GetItem(TradeSlots(m_targets.GetItemTargetGUID().GetRawValue()));
6276 }
6279
6280 // we need a go target, or an openable item target in case of TARGET_GAMEOBJECT_ITEM_TARGET
6281 if (m_spellInfo->Effects[i].TargetA.GetTarget() == TARGET_GAMEOBJECT_ITEM_TARGET &&
6283 (!pTempItem || !pTempItem->GetTemplate()->LockID || !pTempItem->IsLocked()))
6285
6286 // We must also ensure the gameobject we are opening is still closed by the time the spell finishes.
6287 if (GameObject* go = m_targets.GetGOTarget())
6288 {
6289 if (go->GetGoType() == GAMEOBJECT_TYPE_DOOR && go->GetGoState() != GO_STATE_READY)
6290 {
6292 }
6293 }
6294 if (m_spellInfo->Id != 1842 || (m_targets.GetGOTarget() &&
6296 {
6297 if (m_targets.GetGOTarget() && m_targets.GetGOTarget()->GetEntry() == 179697)
6298 {
6299 if (!m_caster->ToPlayer()->CanUseBattlegroundObject(nullptr))
6301 }
6302 else if (m_caster->ToPlayer()->InBattleground() && // In Battleground players can use only flags and banners, or Gurubashi chest
6305 }
6306
6307 // get the lock entry
6308 uint32 lockId = 0;
6309 if (GameObject* go = m_targets.GetGOTarget())
6310 {
6311 lockId = go->GetGOInfo()->GetLockId();
6312 if (!lockId)
6314 }
6315 else if (Item* itm = m_targets.GetItemTarget())
6316 lockId = itm->GetTemplate()->LockID;
6317
6318 SkillType skillId = SKILL_NONE;
6319 int32 reqSkillValue = 0;
6320 int32 skillValue = 0;
6321
6322 // check lock compatibility
6323 SpellCastResult res = CanOpenLock(i, lockId, skillId, reqSkillValue, skillValue);
6324 if (res != SPELL_CAST_OK)
6325 return res;
6326
6327 // chance for fail at lockpicking attempt
6328 // second check prevent fail at rechecks
6329 // herbalism and mining cannot fail as of patch 3.1.0
6330 if (skillId != SKILL_NONE && skillId != SKILL_HERBALISM && skillId != SKILL_MINING && (!m_selfContainer || ((*m_selfContainer) != this)))
6331 {
6332 // chance for failure in orange lockpick
6333 if (skillId == SKILL_LOCKPICKING && reqSkillValue > irand(skillValue - 25, skillValue + 37))
6334 {
6336 }
6337 }
6338 break;
6339 }
6341 {
6342 Unit* unitCaster = m_caster->ToUnit();
6343 if (!unitCaster)
6344 {
6346 }
6347
6348 Creature* pet = unitCaster->GetGuardianPet();
6349 if (pet)
6350 {
6351 if (pet->IsAlive())
6352 {
6354 }
6355 }
6356 else if (Player* playerCaster = m_caster->ToPlayer())
6357 {
6358 PetStable& petStable = playerCaster->GetOrInitPetStable();
6359 if (!petStable.CurrentPet && petStable.UnslottedPets.empty())
6360 {
6361 return SPELL_FAILED_NO_PET;
6362 }
6363 }
6364
6365 break;
6366 }
6367 // This is generic summon effect
6369 {
6370 SummonPropertiesEntry const* SummonProperties = sSummonPropertiesStore.LookupEntry(m_spellInfo->Effects[i].MiscValueB);
6371 if (!SummonProperties || m_spellInfo->HasAttribute(SPELL_ATTR1_DISMISS_PET_FIRST))
6372 break;
6373 switch (SummonProperties->Category)
6374 {
6376 if (m_caster->GetPetGUID())
6378 [[fallthrough]];
6380 if (m_caster->GetCharmGUID())
6382 break;
6383 }
6384 break;
6385 }
6387 {
6389 {
6394 }
6395 break;
6396 }
6398 {
6399 Unit* unitCaster = m_caster->ToUnit();
6400 if (!unitCaster)
6402
6404 {
6405 if (m_caster->GetPetGUID())
6407 if (m_caster->GetCharmGUID())
6409 }
6410
6411 if (m_caster->GetTypeId() == TYPEID_PLAYER && m_caster->getClass() == CLASS_WARLOCK && strict)
6412 if (Pet* pet = m_caster->ToPlayer()->GetPet())
6413 pet->CastSpell(pet, 32752, true, nullptr, nullptr, pet->GetGUID()); //starting cast, trigger pet stun (cast by pet so it doesn't attack player)
6414
6415 Player* playerCaster = unitCaster->ToPlayer();
6416 if (playerCaster && playerCaster->GetPetStable())
6417 {
6418 std::pair<PetStable::PetInfo const*, PetSaveMode> info = Pet::GetLoadPetInfo(*playerCaster->GetPetStable(), m_spellInfo->Effects[i].MiscValue, 0, false);
6419 if (info.first)
6420 {
6421 if (info.first->Type == HUNTER_PET)
6422 {
6423 if (!info.first->Health)
6424 {
6425 playerCaster->SendTameFailure(PET_TAME_DEAD);
6427 }
6428
6429 CreatureTemplate const* creatureInfo = sObjectMgr->GetCreatureTemplate(info.first->CreatureId);
6430 if (!creatureInfo || !creatureInfo->IsTameable(playerCaster->CanTameExoticPets()))
6431 {
6432 // if problem in exotic pet
6433 if (creatureInfo && creatureInfo->IsTameable(true))
6435 else
6437
6439 }
6440 }
6441 }
6442 else if (!m_spellInfo->Effects[i].MiscValue) // when miscvalue is present it is allowed to create new pets
6443 {
6446 }
6447 }
6448 break;
6449 }
6451 {
6454 if (!m_caster->GetTarget())
6456
6458 if (!target || m_caster->ToPlayer() == target || (!target->IsInSameRaidWith(m_caster->ToPlayer()) && m_spellInfo->Id != 48955)) // refer-a-friend spell
6460
6461 // Xinef: Implement summon pending error
6462 if (target->GetSummonExpireTimer() > GameTime::GetGameTime().count())
6464
6465 // check if our map is dungeon
6466 MapEntry const* map = sMapStore.LookupEntry(m_caster->GetMapId());
6467 if (map->IsDungeon())
6468 {
6469 uint32 mapId = m_caster->GetMap()->GetId();
6470 Difficulty difficulty = m_caster->GetMap()->GetDifficulty();
6471 /*if (map->IsRaid())
6472 if (InstancePlayerBind* targetBind = target->GetBoundInstance(mapId, difficulty))
6473 if (targetBind->perm && targetBind != m_caster->ToPlayer()->GetBoundInstance(mapId, difficulty))
6474 return SPELL_FAILED_TARGET_LOCKED_TO_RAID_INSTANCE;*/
6475
6476 InstanceTemplate const* instance = sObjectMgr->GetInstanceTemplate(mapId);
6477 if (!instance)
6479 if (!target->Satisfy(sObjectMgr->GetAccessRequirement(mapId, difficulty), mapId))
6481 }
6482 break;
6483 }
6484 // RETURN HERE
6486 {
6489
6490 Player* playerCaster = m_caster->ToPlayer();
6491 //
6492 if (!(playerCaster->GetTarget()))
6494
6496
6497 if (!target ||
6498 !(target->GetSession()->GetRecruiterId() == playerCaster->GetSession()->GetAccountId() || target->GetSession()->GetAccountId() == playerCaster->GetSession()->GetRecruiterId()))
6500
6501 // Xinef: Implement summon pending error
6502 if (target->GetSummonExpireTimer() > GameTime::GetGameTime().count())
6504
6505 break;
6506 }
6507 case SPELL_EFFECT_LEAP:
6509 {
6510 //Do not allow to cast it before BG starts.
6512 if (Battleground const* bg = m_caster->ToPlayer()->GetBattleground())
6513 if (bg->GetStatus() != STATUS_IN_PROGRESS)
6515 break;
6516 }
6518 {
6521
6522 bool found = false;
6524 for(Unit::VisibleAuraMap::const_iterator itr = visibleAuras->begin(); itr != visibleAuras->end(); ++itr)
6525 {
6526 if( itr->second->GetBase()->IsPassive() )
6527 continue;
6528
6529 if( !itr->second->IsPositive() )
6530 continue;
6531
6532 found = true;
6533 break;
6534 }
6535
6536 if( !found )
6538
6539 break;
6540 }
6542 {
6544 {
6546 return SPELL_FAILED_ROOTED;
6547 else
6549 }
6550 break;
6551 }
6552 // xinef: do not allow to use leaps while rooted
6553 case SPELL_EFFECT_JUMP:
6555 {
6557 return SPELL_FAILED_ROOTED;
6558 break;
6559 }
6561 if (!sScriptMgr->CanSelectSpecTalent(this))
6563 // can't change during already started arena/battleground
6565 if (Battleground const* bg = m_caster->ToPlayer()->GetBattleground())
6566 if (bg->GetStatus() == STATUS_IN_PROGRESS)
6568 break;
6569 default:
6570 break;
6571 }
6572 }
6573
6574 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
6575 {
6576 switch (m_spellInfo->Effects[i].ApplyAuraName)
6577 {
6578 case SPELL_AURA_DUMMY:
6579 break;
6581 {
6583 return SPELL_FAILED_NO_PET;
6584
6585 Pet* pet = m_caster->ToPlayer()->GetPet();
6586 if (!pet)
6587 return SPELL_FAILED_NO_PET;
6588
6589 if (pet->GetCharmerGUID())
6590 return SPELL_FAILED_CHARMED;
6591 break;
6592 }
6596 {
6597 if (m_caster->GetCharmerGUID())
6598 return SPELL_FAILED_CHARMED;
6599
6600 // Xinef: allow SPELL_AURA_MOD_POSSESS to posses target if caster has some pet
6602 {
6603 if (m_caster->GetPetGUID())
6605
6606 if (m_caster->GetCharmGUID())
6608 }
6609 else if (m_spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_MOD_POSSESS)
6610 {
6611 if (m_caster->GetCharmGUID())
6613 }
6614
6615 if (Unit* target = m_targets.GetUnitTarget())
6616 {
6617 if (target->GetTypeId() == TYPEID_UNIT && target->ToCreature()->IsVehicle())
6619
6620 if (target->IsMounted())
6622
6623 if (target->GetCharmerGUID())
6624 return SPELL_FAILED_CHARMED;
6625
6626 if (target->GetOwnerGUID() && target->GetOwnerGUID().IsPlayer())
6628
6629 if (target->IsPet() && (!target->GetOwner() || target->GetOwner()->ToPlayer()))
6631
6632 int32 damage = CalculateSpellDamage(i, target);
6633 if (damage && int32(target->GetLevel()) > damage)
6635 }
6636
6637 break;
6638 }
6639 case SPELL_AURA_MOUNTED:
6640 {
6641 // Disallow casting flying mounts in water
6644
6645 // Ignore map check if spell have AreaId. AreaId already checked and this prevent special mount spells
6646 bool allowMount = !m_caster->GetMap()->IsDungeon() || m_caster->GetMap()->IsBattlegroundOrArena();
6647 InstanceTemplate const* it = sObjectMgr->GetInstanceTemplate(m_caster->GetMapId());
6648 if (it)
6649 allowMount = it->AllowMount;
6650 if (m_caster->GetTypeId() == TYPEID_PLAYER && !allowMount && !m_spellInfo->AreaGroupId)
6652
6655
6656 // xinef: dont allow to cast mounts in specific transforms
6657 if (m_caster->getTransForm())
6658 if (SpellInfo const* transformSpellInfo = sSpellMgr->GetSpellInfo(m_caster->getTransForm()))
6659 if (transformSpellInfo->HasAttribute(SPELL_ATTR0_NO_IMMUNITIES) &&
6660 !transformSpellInfo->HasAttribute(SpellAttr0(SPELL_ATTR0_ALLOW_WHILE_MOUNTED | SPELL_ATTR0_AURA_IS_DEBUFF)))
6662
6663 break;
6664 }
6666 {
6667 if (!m_targets.GetUnitTarget())
6669
6670 // can be casted at non-friendly unit or own pet/charm
6673
6674 break;
6675 }
6676 case SPELL_AURA_FLY:
6678 {
6679 // Xinef: added water check
6680 if (m_caster->IsInWater())
6682
6683 // not allow cast fly spells if not have req. skills (all spells is self target)
6684 // allow always ghost flight spells
6686 {
6687 Battlefield* Bf = sBattlefieldMgr->GetBattlefieldToZoneId(m_originalCaster->GetZoneId());
6688 if (AreaTableEntry const* pArea = sAreaTableStore.LookupEntry(m_originalCaster->GetAreaId()))
6689 if ((pArea->flags & AREA_FLAG_NO_FLY_ZONE) || (Bf && !Bf->CanFlyIn()))
6690 return SPELL_FAILED_NOT_HERE;
6691 }
6692 break;
6693 }
6695 {
6696 if (m_spellInfo->Effects[i].IsTargetingArea())
6697 break;
6698
6700 break;
6701
6702 if (!m_targets.GetUnitTarget())
6704
6707
6708 break;
6709 }
6710 case SPELL_AURA_HOVER:
6711 {
6713 {
6715 }
6716 break;
6717 }
6719 {
6720 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.
6721 {
6723 }
6724 break;
6725 }
6726 default:
6727 break;
6728 }
6729 }
6730
6731 // check trade slot case (last, for allow catch any another cast problems)
6733 {
6734 if (m_CastItem)
6736
6739
6740 TradeData* my_trade = m_caster->ToPlayer()->GetTradeData();
6741
6742 if (!my_trade)
6744
6746 if (slot != TRADE_SLOT_NONTRADED)
6748
6749 if (!IsTriggered())
6750 if (my_trade->GetSpell())
6752 }
6753
6754 // check if caster has at least 1 combo point on target for spells that require combo points
6756 {
6758 {
6760 {
6762 }
6763 }
6764 else
6765 {
6766 if (!m_caster->GetComboPoints())
6767 {
6769 }
6770 }
6771 }
6772
6773 // xinef: check relic cooldown
6777
6778 // all ok
6779 return SPELL_CAST_OK;
6780}
constexpr auto IN_MILLISECONDS
Definition: Common.h:55
constexpr auto MINUTE
Definition: Common.h:49
std::int32_t int32
Definition: Define.h:104
std::uint16_t uint16
Definition: Define.h:109
int32 irand(int32 min, int32 max)
Definition: Random.cpp:37
#define SPECTATOR_SPELL_BINDSIGHT
Definition: ArenaSpectator.h:38
#define sBattlefieldMgr
Definition: BattlefieldMgr.h:77
@ STATUS_WAIT_LEAVE
Definition: Battleground.h:198
@ STATUS_IN_PROGRESS
Definition: Battleground.h:197
#define sConditionMgr
Definition: ConditionMgr.h:289
@ CONDITION_SOURCE_TYPE_SPELL
Definition: ConditionMgr.h:139
std::list< Condition * > ConditionList
Definition: ConditionMgr.h:236
DBCStorage< SpellShapeshiftEntry > sSpellShapeshiftStore(SpellShapeshiftfmt)
DBCStorage< SummonPropertiesEntry > sSummonPropertiesStore(SummonPropertiesfmt)
DBCStorage< MapEntry > sMapStore(MapEntryfmt)
DBCStorage< GlyphPropertiesEntry > sGlyphPropertiesStore(GlyphPropertiesfmt)
DBCStorage< AreaTableEntry > sAreaTableStore(AreaTableEntryfmt)
@ GO_STATE_READY
Definition: GameObjectData.h:691
@ INVTYPE_RELIC
Definition: ItemTemplate.h:293
@ HUNTER_PET
Definition: PetDefines.h:32
@ PLAYER_ALLOW_ONLY_ABILITY
Definition: Player.h:498
TradeSlots
Definition: TradeData.h:28
@ TRADE_SLOT_NONTRADED
Definition: TradeData.h:31
@ MOVEMENTFLAG_FALLING_FAR
Definition: Unit.h:565
#define WORLD_TRIGGER
Definition: Unit.h:36
@ UNIT_FLAG2_ALLOW_CHEAT_SPELLS
Definition: Unit.h:505
std::list< std::pair< Aura *, uint8 > > DispelChargesList
Definition: Unit.h:241
@ UNIT_STATE_ROOT
Definition: Unit.h:335
@ UNIT_STATE_CHARGING
Definition: Unit.h:342
@ UNIT_FLAG_SKINNABLE
Definition: Unit.h:474
LineOfSightChecks
Definition: Map.h:191
@ LINEOFSIGHT_ALL_CHECKS
Definition: Map.h:198
@ PATHFIND_NOPATH
Definition: PathGenerator.h:51
@ PATHFIND_SHORT
Definition: PathGenerator.h:53
@ PATHFIND_INCOMPLETE
Definition: PathGenerator.h:50
@ SPELL_AURA_ABILITY_IGNORE_AURASTATE
Definition: SpellAuraDefines.h:325
@ SPELL_AURA_MOD_SHAPESHIFT
Definition: SpellAuraDefines.h:99
@ SPELL_AURA_MOD_IGNORE_SHAPESHIFT
Definition: SpellAuraDefines.h:338
@ SPELL_AURA_PERIODIC_MANA_LEECH
Definition: SpellAuraDefines.h:127
@ SPELL_AURA_MOD_POSSESS_PET
Definition: SpellAuraDefines.h:191
@ SPELL_AURA_RANGED_ATTACK_POWER_ATTACKER_BONUS
Definition: SpellAuraDefines.h:190
@ SPELL_AURA_DUMMY
Definition: SpellAuraDefines.h:67
@ SPELL_AURA_FLY
Definition: SpellAuraDefines.h:264
@ SPELL_AURA_HOVER
Definition: SpellAuraDefines.h:169
@ SPELL_AURA_MOUNTED
Definition: SpellAuraDefines.h:141
@ SPELL_AURA_AOE_CHARM
Definition: SpellAuraDefines.h:240
@ SPELL_AURA_MOD_POSSESS
Definition: SpellAuraDefines.h:65
@ SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED
Definition: SpellAuraDefines.h:270
@ SPELL_AURA_BLOCK_SPELL_FAMILY
Definition: SpellAuraDefines.h:360
@ SPELL_FLAG_REDIRECTED
Definition: Spell.h:83
@ AURA_INTERRUPT_FLAG_NOT_SEATED
Definition: SpellDefines.h:62
@ AURA_INTERRUPT_FLAG_MOUNT
Definition: SpellDefines.h:61
@ TRIGGERED_IGNORE_SPELL_AND_CATEGORY_CD
Will ignore GCD.
Definition: SpellDefines.h:133
@ TRIGGERED_IGNORE_CASTER_AURASTATE
Will ignore shapeshift checks.
Definition: SpellDefines.h:143
@ TRIGGERED_IGNORE_CASTER_MOUNTED_OR_ON_VEHICLE
Will ignore caster aura states including combat requirements and death state.
Definition: SpellDefines.h:144
@ TRIGGERED_IGNORE_SHAPESHIFT
Will not adjust facing to target (if any)
Definition: SpellDefines.h:142
@ TRIGGERED_IGNORE_GCD
Not triggered.
Definition: SpellDefines.h:132
@ TRIGGERED_IGNORE_CASTER_AURAS
Will ignore mounted/on vehicle restrictions.
Definition: SpellDefines.h:145
std::vector< SpellImmune > SpellImmuneList
Definition: SpellDefines.h:179
@ TARGET_FLAG_UNIT_ENEMY
Definition: SpellInfo.h:53
@ TARGET_FLAG_ITEM
Definition: SpellInfo.h:50
@ SPELL_ATTR0_CU_REQ_TARGET_FACING_CASTER
Definition: SpellInfo.h:192
@ SPELL_ATTR0_CU_REQ_CASTER_BEHIND_TARGET
Definition: SpellInfo.h:193
#define SPELL_RELIC_COOLDOWN
Definition: SpellMgr.h:34
@ VEHICLE_SEAT_FLAG_CAN_CAST_MOUNT_SPELL
Definition: DBCEnums.h:464
@ VEHICLE_SEAT_FLAG_UNCONTROLLED
Definition: DBCEnums.h:465
@ VEHICLE_SEAT_FLAG_CAN_ATTACK
Definition: DBCEnums.h:466
Difficulty
Definition: DBCEnums.h:274
@ AREA_FLAG_NO_FLY_ZONE
Definition: DBCEnums.h:270
@ 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
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:220
CreatureTemplate const * GetCreatureTemplate() const
Definition: Creature.h:199
bool IsSpellProhibited(SpellSchoolMask idSchoolMask) const
Definition: Creature.cpp:2749
SkillType GetRequiredLootSkill() const
Definition: CreatureData.h:246
bool IsTameable(bool exotic) const
Definition: CreatureData.h:263
Definition: TemporarySummon.h:40
Definition: GameObject.h:122
GameObjectTemplate const * GetGOInfo() const
Definition: GameObject.h:138
uint32 type
Definition: GameObjectData.h:34
bool IsLocked() const
Definition: Item.h:247
ItemTemplate const * GetTemplate() const
Definition: Item.cpp:545
bool IsPotion() const
Definition: Item.h:328
uint32 ItemLevel
Definition: ItemTemplate.h:644
uint32 LockID
Definition: ItemTemplate.h:678
uint32 InventoryType
Definition: ItemTemplate.h:641
Unit * ToUnit()
Definition: Object.h:200
Map * GetMap() const
Definition: Object.h:517
InstanceScript * GetInstanceScript() const
Definition: Object.cpp:1192
bool IsWithinLOSInMap(WorldObject const *obj, VMAP::ModelIgnoreFlags ignoreFlags=VMAP::ModelIgnoreFlags::Nothing, LineOfSightChecks checks=LINEOFSIGHT_ALL_CHECKS, Optional< float > collisionHeight={ }, Optional< float > combatReach={ }) const
Definition: Object.cpp:1347
bool IsOutdoors() const
Definition: Object.cpp:3125
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:3108
uint32 GetZoneId() const
Definition: Object.cpp:3100
void GetZoneAndAreaId(uint32 &zoneid, uint32 &areaid) const
Definition: Object.cpp:3116
uint64 GetRawValue() const
Definition: ObjectGuid.h:144
bool IsPlayer() const
Definition: ObjectGuid.h:170
bool IsGameObject() const
Definition: ObjectGuid.h:173
void GetPosition(float &x, float &y) const
Definition: Position.h:122
uint32 GetMapId() const
Definition: Position.h:276
Player * GetOwner() const
Definition: Pet.cpp:2487
bool HaveInDiet(ItemTemplate const *item) const
Definition: Pet.cpp:1430
uint32 GetCurrentFoodBenefitLevel(uint32 itemlevel) const
Definition: Pet.cpp:1448
static std::pair< PetStable::PetInfo const *, PetSaveMode > GetLoadPetInfo(PetStable const &stable, uint32 petEntry, uint32 petnumber, bool current)
Definition: Pet.cpp:161
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:2461
bool IsInSameRaidWith(Player const *p) const
Definition: Player.h:1849
bool CanTameExoticPets() const
Definition: Player.h:2151
bool CanUseBattlegroundObject(GameObject *gameobject) const
Definition: Player.cpp:13135
bool InBattleground() const
Definition: Player.h:2214
PetStable * GetPetStable()
Definition: Player.h:1190
Battleground * GetBattleground(bool create=false) const
Definition: Player.cpp:12117
WorldSession * GetSession() const
Definition: Player.h:1961
bool HasSpellCooldown(uint32 spell_id) const override
Definition: Player.cpp:16251
uint32 GetLastPotionId()
Definition: Player.h:1775
Group * GetGroup()
Definition: Player.h:2431
bool IsGameMaster() const
Definition: Player.h:1148
time_t GetSummonExpireTimer() const
Definition: Player.h:1093
bool Satisfy(DungeonProgressionRequirements const *ar, uint32 target_map, bool report=false)
Definition: PlayerStorage.cpp:6727
bool HasPlayerFlag(PlayerFlags flags) const
Definition: Player.h:1100
std::unique_ptr< DuelInfo > duel
Definition: Player.h:1841
Item * GetItemByGuid(ObjectGuid guid) const
Definition: PlayerStorage.cpp:435
uint32 GetSpell() const
Definition: TradeData.h:49
bool IsVehicle() const
Definition: Unit.h:1428
Vehicle * GetVehicle() const
Definition: Unit.h:2368
Unit * GetOwner() const
Definition: Unit.cpp:10599
Pet * ToPet()
Definition: Unit.h:2412
virtual bool HasSpellCooldown(uint32) const
Definition: Unit.h:2432
ShapeshiftForm GetShapeshiftForm() const
Definition: Unit.h:2085
virtual bool HasSpellItemCooldown(uint32, uint32) const
Definition: Unit.h:2433
bool IsInDisallowedMountForm() const
Definition: Unit.cpp:21526
void CombatStart(Unit *target, bool initialAggro=true)
Definition: Unit.cpp:13619
bool HasUnitFlag2(UnitFlags2 flags) const
Definition: Unit.h:1500
bool IsInSanctuary() const
Definition: Unit.h:1530
uint8 getClass() const
Definition: Unit.h:1438
AuraEffect * IsScriptOverriden(SpellInfo const *spell, int32 script) const
Definition: Unit.cpp:5747
float GetCombatReach() const override
Definition: Unit.h:1359
UnitFlags GetUnitFlags() const
Definition: Unit.h:1493
TempSummon * ToTempSummon()
Definition: Unit.h:2414
bool HasStealthAura() const
Definition: Unit.h:1720
bool HasAura(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemCasterGUID=ObjectGuid::Empty, uint8 reqEffMask=0) const
Definition: Unit.cpp:5636
std::map< uint8, AuraApplication * > VisibleAuraMap
Definition: Unit.h:1324
bool IsInFlight() const
Definition: Unit.h:1690
SpellImmuneList m_spellImmune[MAX_SPELL_IMMUNITY]
Definition: Unit.h:2150
void SendTameFailure(uint8 result)
Definition: Unit.cpp:20270
bool HasUnitMovementFlag(uint32 f) const
Definition: Unit.h:2288
virtual bool IsInWater() const
Definition: Unit.cpp:4291
bool HasAuraState(AuraStateType flag, SpellInfo const *spellProto=nullptr, Unit const *Caster=nullptr) const
Definition: Unit.cpp:10546
bool isMoving() const
Definition: Unit.h:2394
ObjectGuid GetCharmGUID() const
Definition: Unit.h:1836
VisibleAuraMap const * GetVisibleAuras()
Definition: Unit.h:2165
bool IsMounted() const
Definition: Unit.h:1556
Unit * GetVictim() const
Definition: Unit.h:1398
bool IsCritter() const
Definition: Unit.h:1688
ObjectGuid GetOwnerGUID() const
Definition: Unit.h:1828
uint8 GetComboPoints(Unit const *who=nullptr) const
--------—Combo point system----------------—
Definition: Unit.h:2304
ObjectGuid GetCharmerGUID() const
Definition: Unit.h:1834
uint32 getTransForm() const
Definition: Unit.h:2188
Powers getPowerType() const
Definition: Unit.h:1473
void RemoveMovementImpairingAuras(bool withRoot)
Definition: Unit.cpp:5169
bool IsTotem() const
Definition: Unit.h:1427
Guardian * GetGuardianPet() const
Definition: Unit.cpp:10650
ObjectGuid GetTarget() const
Definition: Unit.h:2447
bool IsInCombat() const
Definition: Unit.h:1702
ObjectGuid GetPetGUID() const
Definition: Unit.h:1838
Definition: Vehicle.h:30
VehicleSeatEntry const * GetSeatForPassenger(Unit const *passenger)
Definition: Vehicle.cpp:582
Definition: Group.h:169
Definition: GroupReference.h:27
GroupReference * next()
Definition: GroupReference.h:36
Definition: InstanceScript.h:141
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:3312
uint32 GetId() const
Definition: Map.h:379
Difficulty GetDifficulty() const
Definition: Map.h:443
uint32 GetRecruiterId() const
Definition: WorldSession.h:527
uint32 GetAccountId() const
Definition: WorldSession.h:363
GameObject * GetGOTarget() const
Definition: Spell.cpp:263
ObjectGuid GetItemTargetGUID() const
Definition: Spell.h:138
std::unique_ptr< PathGenerator > m_preGeneratedPath
Definition: Spell.h:775
SpellCastResult CheckSpellFocus()
Definition: Spell.cpp:7714
SpellCastResult CanOpenLock(uint32 effIndex, uint32 lockid, SkillType &skillid, int32 &reqSkillValue, int32 &skillValue)
Definition: Spell.cpp:8317
SpellCastResult CheckItems()
Definition: Spell.cpp:7146
int32 CalculateSpellDamage(uint8 i, Unit const *target) const
Definition: Spell.h:477
SpellCastResult CheckPower()
Definition: Spell.cpp:7101
SpellCastResult CheckCasterAuras(bool preventionOnly) const
Definition: Spell.cpp:6818
SpellCastResult CallScriptCheckCastHandlers()
Definition: Spell.cpp:8516
bool IsTriggered() const
Definition: Spell.h:552
SpellCastResult CheckRange(bool strict)
Definition: Spell.cpp:7015
bool HasGlobalCooldown() const
Definition: Spell.cpp:8788
Definition: SpellInfo.h:247
int32 MiscValue
Definition: SpellInfo.h:261
uint32 ApplyAuraName
Definition: SpellInfo.h:252
uint32 PreventionType
Definition: SpellInfo.h:388
uint32 CasterAuraSpell
Definition: SpellInfo.h:341
SpellCastResult CheckShapeshift(uint32 form) const
Definition: SpellInfo.cpp:1421
uint32 Mechanic
Definition: SpellInfo.h:321
uint32 GetDispelMask() const
Definition: SpellInfo.cpp:2028
uint32 GetRecoveryTime() const
Definition: SpellInfo.cpp:2382
bool IsSelfCast() const
Definition: SpellInfo.cpp:1077
uint32 CasterAuraState
Definition: SpellInfo.h:337
bool CanBeUsedInCombat() const
Definition: SpellInfo.cpp:1219
uint32 CasterAuraStateNot
Definition: SpellInfo.h:339
SpellCastResult CheckLocation(uint32 map_id, uint32 zone_id, uint32 area_id, Player *player=nullptr, bool strict=true) const
Definition: SpellInfo.cpp:1476
SpellSchoolMask GetSchoolMask() const
Definition: SpellInfo.cpp:1974
int32 AreaGroupId
Definition: SpellInfo.h:389
float GetMaxRange(bool positive=false, Unit *caster=nullptr, Spell *spell=nullptr) const
Definition: SpellInfo.cpp:2309
uint32 GetExplicitTargetMask() const
Definition: SpellInfo.cpp:2042
bool NeedsExplicitUnitTarget() const
Definition: SpellInfo.cpp:1020
uint32 ExcludeCasterAuraSpell
Definition: SpellInfo.h:343
uint32 SpellFamilyName
Definition: SpellInfo.h:385
uint32 AuraInterruptFlags
Definition: SpellInfo.h:351
SpellCastResult CheckExplicitTarget(Unit const *caster, WorldObject const *target, Item const *itemTarget=nullptr) const
Definition: SpellInfo.cpp:1924
Definition: DBCStructure.h:519
Definition: DBCStructure.h:1012
Definition: DBCStructure.h:1323
bool IsDungeon() const
Definition: DBCStructure.h:1349
Definition: DBCStructure.h:1817
uint32 flags1
Definition: DBCStructure.h:1822
Definition: DBCStructure.h:1910
uint32 Category
Definition: DBCStructure.h:1912
Definition: DBCStructure.h:2065
uint32 m_flags
Definition: DBCStructure.h:2067

References _triggeredCastFlags, InstanceTemplate::AllowMount, SpellEffectInfo::ApplyAuraName, AREA_FLAG_NO_FLY_ZONE, SpellInfo::AreaGroupId, AURA_INTERRUPT_FLAG_MOUNT, AURA_INTERRUPT_FLAG_NOT_SEATED, SpellInfo::AuraInterruptFlags, CalculateSpellDamage(), CallScriptCheckCastHandlers(), SpellInfo::CanBeUsedInCombat(), Battlefield::CanFlyIn(), CanOpenLock(), Player::CanTameExoticPets(), Player::CanUseBattlegroundObject(), SpellInfo::CasterAuraSpell, SpellInfo::CasterAuraState, SpellInfo::CasterAuraStateNot, SummonPropertiesEntry::Category, CheckCasterAuras(), SpellInfo::CheckExplicitTarget(), CheckItems(), SpellInfo::CheckLocation(), CheckPower(), CheckRange(), SpellInfo::CheckShapeshift(), CheckSpellFocus(), SpellInfo::CheckTarget(), CLASS_WARLOCK, Unit::CombatStart(), CONDITION_SOURCE_TYPE_SPELL, Condition::ConditionTarget, PetStable::CurrentPet, damage, Player::duel, EFFECT_0, SpellInfo::Effects, Condition::ErrorTextId, Condition::ErrorType, SpellInfo::ExcludeCasterAuraSpell, WorldObject::FindMap(), ObjectAccessor::FindPlayer(), SpellShapeshiftEntry::flags1, GAMEOBJECT_TYPE_DOOR, GAMEOBJECT_TYPE_TRAP, WorldSession::GetAccountId(), WorldObject::GetAreaId(), Unit::GetAuraEffectsByType(), Player::GetBattleground(), Unit::GetCharm(), Unit::GetCharmerGUID(), Unit::GetCharmGUID(), Unit::getClass(), Unit::GetCombatReach(), Unit::GetComboPoints(), Creature::GetCreatureTemplate(), Pet::GetCurrentFoodBenefitLevel(), Map::GetDifficulty(), SpellInfo::GetDispelMask(), WorldObject::GetDistance(), SpellCastTargets::GetDstPos(), Object::GetEntry(), SpellInfo::GetExplicitTargetMask(), Map::GetGameObject(), GameTime::GetGameTime(), GameObject::GetGOInfo(), SpellCastTargets::GetGOTarget(), Player::GetGroup(), Unit::GetGuardianPet(), Map::GetId(), WorldObject::GetInstanceScript(), Player::GetItemByGuid(), SpellCastTargets::GetItemTarget(), SpellCastTargets::GetItemTargetGUID(), Player::GetLastPotionId(), Unit::GetLevel(), Pet::GetLoadPetInfo(), WorldObject::GetMap(), WorldLocation::GetMapId(), SpellInfo::GetMaxRange(), SpellCastTargets::GetObjectTarget(), Pet::GetOwner(), Player::GetPet(), Unit::GetPetGUID(), Player::GetPetStable(), Position::GetPosition(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), Unit::getPowerType(), ObjectGuid::GetRawValue(), SpellInfo::GetRecoveryTime(), WorldSession::GetRecruiterId(), CreatureTemplate::GetRequiredLootSkill(), SpellInfo::GetSchoolMask(), Vehicle::GetSeatForPassenger(), Player::GetSession(), Unit::GetShapeshiftForm(), Player::GetSkillValue(), TradeData::GetSpell(), Player::GetSummonExpireTimer(), Unit::GetTarget(), SpellCastTargets::GetTargetMask(), Item::GetTemplate(), Player::GetTradeData(), Unit::getTransForm(), Object::GetTypeId(), Unit::GetUnitFlags(), SpellCastTargets::GetUnitTarget(), Unit::GetVehicle(), Unit::GetVictim(), WorldObject::GetVisibilityRange(), Unit::GetVisibleAuras(), WorldObject::GetZoneAndAreaId(), WorldObject::GetZoneId(), GO_STATE_READY, SpellInfo::HasAttribute(), SpellInfo::HasAura(), Unit::HasAura(), Unit::HasAuraState(), SpellCastTargets::HasDst(), SpellInfo::HasEffect(), HasGlobalCooldown(), Player::HasPlayerFlag(), Player::HasSpellCooldown(), Unit::HasSpellCooldown(), Unit::HasSpellItemCooldown(), Unit::HasStealthAura(), Unit::HasUnitFlag2(), Unit::HasUnitMovementFlag(), Unit::HasUnitState(), Pet::HaveInDiet(), HUNTER_PET, SpellInfo::Id, IMMUNITY_MECHANIC, IN_MILLISECONDS, Player::InBattleground(), ItemTemplate::InventoryType, INVTYPE_RELIC, irand(), Unit::IsAlive(), IsAutoRepeat(), Map::IsBattlegroundOrArena(), SpellInfo::IsCooldownStartedOnEvent(), Unit::IsCritter(), Map::IsDungeon(), MapEntry::IsDungeon(), Unit::IsFriendlyTo(), Player::IsGameMaster(), ObjectGuid::IsGameObject(), Unit::IsInCombat(), Unit::IsInDisallowedMountForm(), Unit::IsInFlight(), Player::IsInSameRaidWith(), Unit::IsInSanctuary(), Unit::IsInWater(), Item::IsLocked(), Loot::isLooted(), Unit::IsMounted(), Unit::isMoving(), WorldObject::IsOutdoors(), SpellInfo::IsPassive(), DisableMgr::IsPathfindingEnabled(), SpellInfo::IsPositive(), Item::IsPotion(), Unit::IsScriptOverriden(), SpellInfo::IsSelfCast(), Creature::IsSpellProhibited(), CreatureTemplate::IsTameable(), Unit::IsTotem(), IsTriggered(), WorldObject::IsWithinLOS(), WorldObject::IsWithinLOSInMap(), ItemTemplate::ItemLevel, LINEOFSIGHT_ALL_CHECKS, ItemTemplate::LockID, Creature::loot, VMAP::M2, m_caster, m_CastItem, m_customError, VehicleSeatEntry::m_flags, m_needComboPoints, m_originalCaster, m_originalCasterGUID, m_preGeneratedPath, m_selfContainer, m_spellFlags, Unit::m_spellImmune, m_spellInfo, m_targets, m_triggeredByAuraSpell, MAX_SPELL_EFFECTS, ConditionSourceInfo::mConditionTargets, SpellInfo::Mechanic, MINUTE, SpellEffectInfo::MiscValue, ConditionSourceInfo::mLastFailedCondition, MOVEMENTFLAG_FALLING_FAR, SpellInfo::NeedsExplicitUnitTarget(), GroupReference::next(), PATHFIND_INCOMPLETE, PATHFIND_NOPATH, PATHFIND_SHORT, PET_TAME_CANT_CONTROL_EXOTIC, PET_TAME_DEAD, PET_TAME_NOPET_AVAILABLE, PLAYER_ALLOW_ONLY_ABILITY, POWER_MANA, SpellInfo::PreventionType, Unit::RemoveMovementImpairingAuras(), sAreaTableStore, Player::Satisfy(), sBattlefieldMgr, sConditionMgr, Unit::SendTameFailure(), sGlyphPropertiesStore, SKILL_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, sSpellShapeshiftStore, sSummonPropertiesStore, STATUS_IN_PROGRESS, STATUS_WAIT_LEAVE, SUMMON_CATEGORY_PET, SUMMON_CATEGORY_PUPPET, TARGET_FLAG_ITEM, TARGET_FLAG_TRADE_ITEM, TARGET_FLAG_UNIT_ENEMY, TARGET_GAMEOBJECT_ITEM_TARGET, TARGET_GAMEOBJECT_TARGET, TARGET_UNIT_PET, Object::ToCreature(), Unit::ToPet(), Object::ToPlayer(), Unit::ToTempSummon(), Object::ToUnit(), TRADE_SLOT_NONTRADED, TRIGGERED_IGNORE_CASTER_AURAS, TRIGGERED_IGNORE_CASTER_AURASTATE, TRIGGERED_IGNORE_CASTER_MOUNTED_OR_ON_VEHICLE, TRIGGERED_IGNORE_GCD, TRIGGERED_IGNORE_POWER_AND_REAGENT_COST, TRIGGERED_IGNORE_SHAPESHIFT, TRIGGERED_IGNORE_SPELL_AND_CATEGORY_CD, GameObjectTemplate::type, TYPEID_PLAYER, TYPEID_UNIT, UNIT_FLAG2_ALLOW_CHEAT_SPELLS, UNIT_FLAG_SKINNABLE, UNIT_STATE_CHARGING, UNIT_STATE_ROOT, unitTarget, PetStable::UnslottedPets, VEHICLE_SEAT_FLAG_CAN_ATTACK, VEHICLE_SEAT_FLAG_CAN_CAST_MOUNT_SPELL, VEHICLE_SEAT_FLAG_UNCONTROLLED, and WORLD_TRIGGER.

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

◆ CheckCasterAuras()

SpellCastResult Spell::CheckCasterAuras ( bool  preventionOnly) const
6819{
6820 // spells totally immuned to caster auras (wsg flag drop, give marks etc)
6822 return SPELL_CAST_OK;
6823
6824 uint8 school_immune = 0;
6825 uint32 mechanic_immune = 0;
6826 uint32 dispel_immune = 0;
6827
6828 // Check if the spell grants school or mechanic immunity.
6829 // We use bitmasks so the loop is done only once and not on every aura check below.
6831 {
6832 for (int i = 0; i < MAX_SPELL_EFFECTS; ++i)
6833 {
6834 if (m_spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_SCHOOL_IMMUNITY)
6835 school_immune |= uint32(m_spellInfo->Effects[i].MiscValue);
6836 else if (m_spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_MECHANIC_IMMUNITY)
6837 mechanic_immune |= 1 << uint32(m_spellInfo->Effects[i].MiscValue);
6838 else if (m_spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_DISPEL_IMMUNITY)
6839 dispel_immune |= SpellInfo::GetDispelMask(DispelType(m_spellInfo->Effects[i].MiscValue));
6840 }
6841 // immune movement impairment and loss of control
6842 // PVP trinket EMFH TOC PVP trinket Bullheaded Bestial Wrath // Beath Within // Medalion of Immunity
6843 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)
6845 }
6846
6848
6849 // Glyph of Pain Suppression
6850 // there is no other way to handle it
6851 if (m_spellInfo->Id == 33206 && !m_caster->HasAura(63248))
6852 usableInStun = false;
6853
6854 // Check whether the cast should be prevented by any state you might have.
6855 SpellCastResult prevented_reason = SPELL_CAST_OK;
6856 // Have to check if there is a stun aura. Otherwise will have problems with ghost aura apply while logging out
6857 uint32 unitflag = m_caster->GetUnitFlags(); // Get unit state
6858
6859 // Xinef: if spell is triggered check preventionType only
6860 if (!preventionOnly)
6861 {
6862 if (unitflag & UNIT_FLAG_STUNNED)
6863 {
6864 // spell is usable while stunned, check if caster has only mechanic stun auras, another stun types must prevent cast spell
6865 if (usableInStun)
6866 {
6867 bool foundNotStun = false;
6868 uint32 mask = (1 << MECHANIC_STUN) | (1 << MECHANIC_FREEZE) | (1 << MECHANIC_HORROR);
6869 // Barkskin should skip sleep effects, sap and fears
6870 if (m_spellInfo->Id == 22812)
6871 mask |= 1 << MECHANIC_SAPPED | 1 << MECHANIC_HORROR | 1 << MECHANIC_SLEEP;
6872 // Hand of Freedom, can be used while sapped
6873 if (m_spellInfo->Id == 1044)
6874 mask |= 1 << MECHANIC_SAPPED;
6876 for (Unit::AuraEffectList::const_iterator i = stunAuras.begin(); i != stunAuras.end(); ++i)
6877 {
6878 if ((*i)->GetSpellInfo()->GetAllEffectsMechanicMask() && !((*i)->GetSpellInfo()->GetAllEffectsMechanicMask() & mask))
6879 {
6880 foundNotStun = true;
6881 break;
6882 }
6883 }
6884 if (foundNotStun)
6885 prevented_reason = SPELL_FAILED_STUNNED;
6886 }
6887 else
6888 prevented_reason = SPELL_FAILED_STUNNED;
6889 }
6891 prevented_reason = SPELL_FAILED_CONFUSED;
6893 prevented_reason = SPELL_FAILED_FLEEING;
6894 }
6895
6896 // Xinef: if there is no prevented_reason, check prevention types
6897 if (prevented_reason == SPELL_CAST_OK)
6898 {
6900 prevented_reason = SPELL_FAILED_SILENCED;
6902 prevented_reason = SPELL_FAILED_PACIFIED;
6903 }
6904
6905 // Attr must make flag drop spell totally immune from all effects
6906 if (prevented_reason != SPELL_CAST_OK)
6907 {
6908 if (school_immune || mechanic_immune || dispel_immune)
6909 {
6910 //Checking auras is needed now, because you are prevented by some state but the spell grants immunity.
6912 for (Unit::AuraApplicationMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
6913 {
6914 Aura const* aura = itr->second->GetBase();
6915 SpellInfo const* auraInfo = aura->GetSpellInfo();
6916 if (auraInfo->GetAllEffectsMechanicMask() & mechanic_immune)
6917 continue;
6918 if (auraInfo->GetSchoolMask() & school_immune && !auraInfo->HasAttribute(SPELL_ATTR1_IMMUNITY_TO_HOSTILE_AND_FRIENDLY_EFFECTS))
6919 continue;
6920 if (auraInfo->GetDispelMask() & dispel_immune)
6921 continue;
6922
6923 //Make a second check for spell failed so the right SPELL_FAILED message is returned.
6924 //That is needed when your casting is prevented by multiple states and you are only immune to some of them.
6925 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
6926 {
6927 if (AuraEffect* part = aura->GetEffect(i))
6928 {
6929 switch (part->GetAuraType())
6930 {
6932 {
6933 uint32 mask = 1 << MECHANIC_STUN;
6934 // Barkskin should skip sleep effects, sap and fears
6935 if (m_spellInfo->Id == 22812)
6936 mask |= 1 << MECHANIC_SAPPED | 1 << MECHANIC_HORROR | 1 << MECHANIC_SLEEP;
6937 // Hand of Freedom, can be used while sapped
6938 if (m_spellInfo->Id == 1044)
6939 mask |= 1 << MECHANIC_SAPPED;
6940
6941 if (!usableInStun || !(auraInfo->GetAllEffectsMechanicMask() & mask))
6942 return SPELL_FAILED_STUNNED;
6943 break;
6944 }
6947 return SPELL_FAILED_CONFUSED;
6948 break;
6951 return SPELL_FAILED_FLEEING;
6952 break;
6957 return SPELL_FAILED_PACIFIED;
6959 return SPELL_FAILED_SILENCED;
6960 break;
6961 default:
6962 break;
6963 }
6964 }
6965 }
6966 }
6967 }
6968 // You are prevented from casting and the spell casted does not grant immunity. Return a failed error.
6969 else
6970 return prevented_reason;
6971 }
6972 return SPELL_CAST_OK;
6973}
@ UNIT_FLAG_STUNNED
Definition: Unit.h:466
@ UNIT_FLAG_PACIFIED
Definition: Unit.h:465
@ UNIT_FLAG_CONFUSED
Definition: Unit.h:470
@ UNIT_FLAG_FLEEING
Definition: Unit.h:471
@ UNIT_FLAG_SILENCED
Definition: Unit.h:461
@ SPELL_AURA_DISPEL_IMMUNITY
Definition: SpellAuraDefines.h:104
@ SPELL_AURA_MOD_FEAR
Definition: SpellAuraDefines.h:70
@ SPELL_AURA_MOD_PACIFY
Definition: SpellAuraDefines.h:88
@ SPELL_AURA_MOD_SILENCE
Definition: SpellAuraDefines.h:90
@ SPELL_AURA_SCHOOL_IMMUNITY
Definition: SpellAuraDefines.h:102
@ SPELL_AURA_MECHANIC_IMMUNITY
Definition: SpellAuraDefines.h:140
@ SPELL_AURA_MOD_PACIFY_SILENCE
Definition: SpellAuraDefines.h:123
@ SPELL_AURA_MOD_CONFUSE
Definition: SpellAuraDefines.h:68
@ SPELL_AURA_MOD_STUN
Definition: SpellAuraDefines.h:75
@ SPELL_PREVENTION_TYPE_SILENCE
Definition: SharedDefines.h: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:1311
AuraApplicationMap & GetAppliedAuras()
Definition: Unit.h:1938
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:1979

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

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

Referenced by SelectEffectImplicitTargets(), and SelectImplicitDestDestTargets().

◆ CheckEffectExecuteData()

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

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

Referenced by AddUnitTarget().

◆ CheckItems()

SpellCastResult Spell::CheckItems ( )
Todo:
Needs review
Todo:
: Not sure whether the fallthrough was a mistake (forgetting a break) or intended. This should be double-checked.
7147{
7148 Player* player = m_caster->ToPlayer();
7149 if (!player)
7150 {
7151 // Non-player case: Check if creature is disarmed
7153 {
7155 }
7156
7157 return SPELL_CAST_OK;
7158 }
7159
7160 if (!m_CastItem)
7161 {
7162 if (m_castItemGUID)
7164 }
7165 else
7166 {
7167 uint32 itemid = m_CastItem->GetEntry();
7168 if (!player->HasItemCount(itemid))
7170
7171 ItemTemplate const* proto = m_CastItem->GetTemplate();
7172 if (!proto)
7174
7175 for (int i = 0; i < MAX_ITEM_SPELLS; ++i)
7176 if (proto->Spells[i].SpellCharges)
7177 if (m_CastItem->GetSpellCharges(i) == 0)
7179
7180 // consumable cast item checks
7182 {
7183 // such items should only fail if there is no suitable effect at all - see Rejuvenation Potions for example
7184 SpellCastResult failReason = SPELL_CAST_OK;
7185 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; i++)
7186 {
7187 // skip check, pet not required like checks, and for TARGET_UNIT_PET m_targets.GetUnitTarget() is not the real target but the caster
7188 if (m_spellInfo->Effects[i].TargetA.GetTarget() == TARGET_UNIT_PET)
7189 continue;
7190
7191 if (m_spellInfo->Effects[i].Effect == SPELL_EFFECT_HEAL)
7192 {
7194 {
7196 continue;
7197 }
7198 else
7199 {
7200 failReason = SPELL_CAST_OK;
7201 break;
7202 }
7203 }
7204
7205 // Mana Potion, Rage Potion, Thistle Tea(Rogue), ...
7206 if (m_spellInfo->Effects[i].Effect == SPELL_EFFECT_ENERGIZE)
7207 {
7208 if (m_spellInfo->Effects[i].MiscValue < 0 || m_spellInfo->Effects[i].MiscValue >= int8(MAX_POWERS))
7209 {
7211 continue;
7212 }
7213
7214 Powers power = Powers(m_spellInfo->Effects[i].MiscValue);
7216 {
7218 continue;
7219 }
7220 else
7221 {
7222 failReason = SPELL_CAST_OK;
7223 break;
7224 }
7225 }
7226 }
7227 if (failReason != SPELL_CAST_OK)
7228 return failReason;
7229 }
7230 }
7231
7232 // check target item
7234 {
7237
7238 if (!m_targets.GetItemTarget())
7240
7243 }
7244 // if not item target then required item must be equipped
7245 else
7246 {
7247 // Xinef: this is not true in my opinion, in eg bladestorm will not be canceled after disarm
7248 //if (!(_triggeredCastFlags & TRIGGERED_IGNORE_EQUIPPED_ITEM_REQUIREMENT))
7251 }
7252
7253 // do not take reagents for these item casts
7255 {
7257 // Not own traded item (in trader trade slot) requires reagents even if triggered spell
7258 if (!checkReagents)
7259 if (Item* targetItem = m_targets.GetItemTarget())
7260 if (targetItem->GetOwnerGUID() != m_caster->GetGUID())
7261 checkReagents = true;
7262
7263 // check reagents (ignore triggered spells with reagents processed by original spell) and special reagent ignore case.
7264 if (checkReagents)
7265 {
7266 for (uint32 i = 0; i < MAX_SPELL_REAGENTS; i++)
7267 {
7268 if (m_spellInfo->Reagent[i] <= 0)
7269 continue;
7270
7271 uint32 itemid = m_spellInfo->Reagent[i];
7272 uint32 itemcount = m_spellInfo->ReagentCount[i];
7273
7274 // if CastItem is also spell reagent
7275 if (m_CastItem && m_CastItem->GetEntry() == itemid)
7276 {
7277 ItemTemplate const* proto = m_CastItem->GetTemplate();
7278 if (!proto)
7280 for (int s = 0; s < MAX_ITEM_PROTO_SPELLS; ++s)
7281 {
7282 // CastItem will be used up and does not count as reagent
7283 int32 charges = m_CastItem->GetSpellCharges(s);
7284 if (proto->Spells[s].SpellCharges < 0 && std::abs(charges) < 2)
7285 {
7286 ++itemcount;
7287 break;
7288 }
7289 }
7290 }
7291 if (!player->HasItemCount(itemid, itemcount))
7292 return SPELL_FAILED_REAGENTS;
7293 }
7294 }
7295
7296 // check totem-item requirements (items presence in inventory)
7297 uint32 totems = 2;
7298 for (int i = 0; i < 2; ++i)
7299 {
7300 if (m_spellInfo->Totem[i] != 0)
7301 {
7302 if (player->HasItemCount(m_spellInfo->Totem[i]))
7303 {
7304 totems -= 1;
7305 continue;
7306 }
7307 }
7308 else
7309 totems -= 1;
7310 }
7311 if (totems != 0)
7312 return SPELL_FAILED_TOTEMS; //0x7C
7313
7314 // Check items for TotemCategory (items presence in inventory)
7316 for (int i = 0; i < 2; ++i)
7317 {
7318 if (m_spellInfo->TotemCategory[i] != 0)
7319 {
7321 {
7322 TotemCategory -= 1;
7323 continue;
7324 }
7325 }
7326 else
7327 TotemCategory -= 1;
7328 }
7329 if (TotemCategory != 0)
7330 return SPELL_FAILED_TOTEM_CATEGORY; //0x7B
7331 }
7332
7333 // special checks for spell effects
7334 for (int i = 0; i < MAX_SPELL_EFFECTS; i++)
7335 {
7336 switch (m_spellInfo->Effects[i].Effect)
7337 {
7340 {
7341 // m_targets.GetUnitTarget() means explicit cast, otherwise we dont check for possible equip error
7342 Unit* target = m_targets.GetUnitTarget() ? m_targets.GetUnitTarget() : player;
7343 if (target->GetTypeId() == TYPEID_PLAYER && !IsTriggered())
7344 {
7345 // 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,
7346 // so we need to make sure there is at least one free space in the player's inventory
7348 if (target->ToPlayer()->GetFreeInventorySpace() == 0)
7349 {
7350 player->SendEquipError(EQUIP_ERR_INVENTORY_FULL, nullptr, nullptr, m_spellInfo->Effects[i].ItemType);
7352 }
7353
7354 if (m_spellInfo->Effects[i].ItemType)
7355 {
7356 ItemTemplate const* itemTemplate = sObjectMgr->GetItemTemplate(m_spellInfo->Effects[i].ItemType);
7357 if (!itemTemplate)
7359
7360 uint32 createCount = std::clamp<uint32>(m_spellInfo->Effects[i].CalcValue(), 1u, itemTemplate->GetMaxStackSize());
7361 ItemPosCountVec dest;
7362 InventoryResult msg = target->ToPlayer()->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, m_spellInfo->Effects[i].ItemType, createCount);
7363 if (msg != EQUIP_ERR_OK)
7364 {
7366 if (!itemTemplate->ItemLimitCategory)
7367 {
7368 player->SendEquipError(msg, nullptr, nullptr, m_spellInfo->Effects[i].ItemType);
7370 }
7371 else
7372 {
7373 // Conjure Food/Water/Refreshment spells
7376 else if (!(target->ToPlayer()->HasItemCount(m_spellInfo->Effects[i].ItemType)))
7377 {
7378 player->SendEquipError(msg, nullptr, nullptr, m_spellInfo->Effects[i].ItemType);
7380 }
7381 else
7382 player->CastSpell(player, m_spellInfo->Effects[EFFECT_1].CalcValue(), false); // move this to anywhere
7383
7385 }
7386 }
7387 }
7388 }
7389 break;
7390 }
7392 {
7393 if (player->GetFreeInventorySpace() == 0)
7394 {
7395 player->SendEquipError(EQUIP_ERR_INVENTORY_FULL, nullptr, nullptr, m_spellInfo->Effects[i].ItemType);
7397 }
7398 break;
7399 }
7401 if (m_spellInfo->Effects[i].ItemType && m_targets.GetItemTarget()
7403 {
7404 // cannot enchant vellum for other player
7407 // do not allow to enchant vellum from scroll made by vellum-prevent exploit
7410 ItemPosCountVec dest;
7411 InventoryResult msg = player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, m_spellInfo->Effects[i].ItemType, 1);
7412 if (msg != EQUIP_ERR_OK)
7413 {
7414 player->SendEquipError(msg, nullptr, nullptr, m_spellInfo->Effects[i].ItemType);
7416 }
7417 }
7418 [[fallthrough]];
7420 {
7421 Item* targetItem = m_targets.GetItemTarget();
7422 if (!targetItem)
7424
7425 // xinef: required level has to be checked also! Exploit fix
7426 if (targetItem->GetTemplate()->ItemLevel < m_spellInfo->BaseLevel || (targetItem->GetTemplate()->RequiredLevel && targetItem->GetTemplate()->RequiredLevel < m_spellInfo->BaseLevel))
7427 return SPELL_FAILED_LOWLEVEL;
7428
7429 bool isItemUsable = false;
7430 for (uint8 e = 0; e < MAX_ITEM_PROTO_SPELLS; ++e)
7431 {
7432 ItemTemplate const* proto = targetItem->GetTemplate();
7433 if (proto->Spells[e].SpellId && (
7436 {
7437 isItemUsable = true;
7438 break;
7439 }
7440 }
7441
7442 SpellItemEnchantmentEntry const* enchantEntry = sSpellItemEnchantmentStore.LookupEntry(m_spellInfo->Effects[i].MiscValue);
7443 // do not allow adding usable enchantments to items that have use effect already
7444 if (enchantEntry)
7445 {
7446 for (uint8 s = 0; s < MAX_SPELL_ITEM_ENCHANTMENT_EFFECTS; ++s)
7447 {
7448 switch (enchantEntry->type[s])
7449 {
7451 if (isItemUsable)
7453 break;
7455 {
7456 uint32 numSockets = 0;
7457 for (uint32 socket = 0; socket < MAX_ITEM_PROTO_SOCKETS; ++socket)
7458 if (targetItem->GetTemplate()->Socket[socket].Color)
7459 ++numSockets;
7460
7461 if (numSockets == MAX_ITEM_PROTO_SOCKETS || targetItem->GetEnchantmentId(PRISMATIC_ENCHANTMENT_SLOT))
7463 break;
7464 }
7465 }
7466 }
7467 }
7468
7469 // Not allow enchant in trade slot for some enchant type
7470 if (targetItem->GetOwner() != m_caster)
7471 {
7472 if (!enchantEntry)
7473 return SPELL_FAILED_ERROR;
7474 if (enchantEntry->slot & ENCHANTMENT_CAN_SOULBOUND)
7476 }
7477 break;
7478 }
7480 {
7481 Item* item = m_targets.GetItemTarget();
7482 if (!item)
7484 // Not allow enchant in trade slot for some enchant type
7485 if (item->GetOwner() != m_caster)
7486 {
7487 uint32 enchant_id = m_spellInfo->Effects[i].MiscValue;
7488 SpellItemEnchantmentEntry const* pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id);
7489 if (!pEnchant)
7490 return SPELL_FAILED_ERROR;
7491 if (pEnchant->slot & ENCHANTMENT_CAN_SOULBOUND)
7493 }
7494
7495 // Xinef: Apply item level restriction if the enchanting spell has max level restrition set
7496 if (m_CastItem && m_spellInfo->MaxLevel > 0)
7497 {
7499 return SPELL_FAILED_LOWLEVEL;
7500 if (item->GetTemplate()->ItemLevel > m_spellInfo->MaxLevel)
7502 }
7503
7504 break;
7505 }
7507 // check item existence in effect code (not output errors at offhand hold item effect to main hand for example
7508 break;
7510 {
7511 if (!m_targets.GetItemTarget())
7513
7514 // prevent disenchanting in trade slot
7517
7518 ItemTemplate const* itemProto = m_targets.GetItemTarget()->GetTemplate();
7519 if (!itemProto)
7521
7522 uint32 item_quality = itemProto->Quality;
7523 // 2.0.x addon: Check player enchanting level against the item disenchanting requirements
7524 uint32 item_disenchantskilllevel = itemProto->RequiredDisenchantSkill;
7525 if (item_disenchantskilllevel == uint32(-1))
7527 if (item_disenchantskilllevel > player->GetSkillValue(SKILL_ENCHANTING))
7529 if (item_quality > 4 || item_quality < 2)
7531 if (itemProto->Class != ITEM_CLASS_WEAPON && itemProto->Class != ITEM_CLASS_ARMOR)
7533 if (!itemProto->DisenchantID)
7535 break;
7536 }
7538 {
7539 if (!m_targets.GetItemTarget())
7541 //ensure item is a prospectable ore
7544 //prevent prospecting in trade slot
7547 //Check for enough skill in jewelcrafting
7548 uint32 item_prospectingskilllevel = m_targets.GetItemTarget()->GetTemplate()->RequiredSkillRank;
7549 if (item_prospectingskilllevel > player->GetSkillValue(SKILL_JEWELCRAFTING))
7551 //make sure the player has the required ores in inventory
7552 if (m_targets.GetItemTarget()->GetCount() < 5)
7554
7557
7558 break;
7559 }
7561 {
7562 if (!m_targets.GetItemTarget())
7564 //ensure item is a millable herb
7567 //prevent milling in trade slot
7570 //Check for enough skill in inscription
7571 uint32 item_millingskilllevel = m_targets.GetItemTarget()->GetTemplate()->RequiredSkillRank;
7572 if (item_millingskilllevel > player->GetSkillValue(SKILL_INSCRIPTION))
7574 //make sure the player has the required herbs in inventory
7575 if (m_targets.GetItemTarget()->GetCount() < 5)
7577
7580
7581 break;
7582 }
7585 {
7588
7590 break;
7591
7593 if (!pItem || pItem->IsBroken())
7595
7596 switch (pItem->GetTemplate()->SubClass)
7597 {
7599 {
7600 uint32 ammo = pItem->GetEntry();
7601 if (!m_caster->ToPlayer()->HasItemCount(ammo))
7602 return SPELL_FAILED_NO_AMMO;
7603 };
7604 break;
7608 {
7610 if (!ammo)
7611 {
7612 // Requires No Ammo
7613 if (m_caster->HasAura(46699))
7614 break; // skip other checks
7615
7616 return SPELL_FAILED_NO_AMMO;
7617 }
7618
7619 ItemTemplate const* ammoProto = sObjectMgr->GetItemTemplate(ammo);
7620 if (!ammoProto)
7621 return SPELL_FAILED_NO_AMMO;
7622
7623 if (ammoProto->Class != ITEM_CLASS_PROJECTILE)
7624 return SPELL_FAILED_NO_AMMO;
7625
7626 // check ammo ws. weapon compatibility
7627 switch (pItem->GetTemplate()->SubClass)
7628 {
7631 if (ammoProto->SubClass != ITEM_SUBCLASS_ARROW)
7632 return SPELL_FAILED_NO_AMMO;
7633 break;
7635 if (ammoProto->SubClass != ITEM_SUBCLASS_BULLET)
7636 return SPELL_FAILED_NO_AMMO;
7637 break;
7638 default:
7639 return SPELL_FAILED_NO_AMMO;
7640 }
7641
7642 if (!m_caster->ToPlayer()->HasItemCount(ammo))
7643 {
7645 return SPELL_FAILED_NO_AMMO;
7646 }
7647 };
7648 break;
7650 break;
7651 default:
7652 break;
7653 }
7654 break;
7655 }
7657 {
7658 uint32 item_id = m_spellInfo->Effects[i].ItemType;
7659 ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(item_id);
7660
7661 if (!pProto)
7663
7664 if (Item* pitem = player->GetItemByEntry(item_id))
7665 {
7666 for (int x = 0; x < MAX_ITEM_PROTO_SPELLS; ++x)
7667 if (pProto->Spells[x].SpellCharges != 0 && pitem->GetSpellCharges(x) == pProto->Spells[x].SpellCharges)
7669 }
7670 break;
7671 }
7672 default:
7673 break;
7674 }
7675 }
7676
7677 // check weapon presence in slots for main/offhand weapons
7678 if (/*never skip those checks !(_triggeredCastFlags & TRIGGERED_IGNORE_EQUIPPED_ITEM_REQUIREMENT) &&*/ m_spellInfo->EquippedItemClass >= 0)
7679 {
7680 // main hand weapon required
7682 {
7684
7685 // skip spell if no weapon in slot or broken
7686 if (!item || item->IsBroken())
7688
7689 // skip spell if weapon not fit to triggered spell
7692 }
7693
7694 // offhand hand weapon required
7696 {
7698
7699 // skip spell if no weapon in slot or broken
7700 if (!item || item->IsBroken())
7702
7703 // skip spell if weapon not fit to triggered spell
7706 }
7707
7709 }
7710
7711 return SPELL_CAST_OK;
7712}
std::int8_t int8
Definition: Define.h:106
DBCStorage< SpellItemEnchantmentEntry > sSpellItemEnchantmentStore(SpellItemEnchantmentfmt)
InventoryResult
Definition: Item.h:40
@ EQUIP_ERR_OK
Definition: Item.h:41
@ EQUIP_ERR_INVENTORY_FULL
Definition: Item.h:91
#define MAX_ITEM_SPELLS
Definition: Item.h:209
@ ENCHANTMENT_CAN_SOULBOUND
Definition: Item.h:195
@ PRISMATIC_ENCHANTMENT_SLOT
Definition: Item.h:169
@ ITEM_SUBCLASS_WEAPON_CROSSBOW
Definition: ItemTemplate.h:371
@ ITEM_SUBCLASS_WEAPON_GUN
Definition: ItemTemplate.h:356
@ ITEM_SUBCLASS_WEAPON_BOW
Definition: ItemTemplate.h:355
@ ITEM_SUBCLASS_WEAPON_WAND
Definition: ItemTemplate.h:372
@ ITEM_SUBCLASS_WEAPON_THROWN
Definition: ItemTemplate.h:369
@ ITEM_SPELLTRIGGER_ON_USE
Definition: ItemTemplate.h:78
@ ITEM_SPELLTRIGGER_ON_NO_DELAY_USE
Definition: ItemTemplate.h:88
@ ITEM_FLAG_IS_MILLABLE
Definition: ItemTemplate.h:177
@ ITEM_FLAG_NO_REAGENT_COST
Definition: ItemTemplate.h:176
@ ITEM_FLAG_IS_PROSPECTABLE
Definition: ItemTemplate.h:166
@ ITEM_SUBCLASS_ARROW
Definition: ItemTemplate.h:425
@ ITEM_SUBCLASS_BULLET
Definition: ItemTemplate.h:426
#define MAX_ITEM_PROTO_SOCKETS
Definition: ItemTemplate.h:623
#define MAX_ITEM_PROTO_SPELLS
Definition: ItemTemplate.h:624
@ ITEM_CLASS_PROJECTILE
Definition: ItemTemplate.h:306
@ ITEM_CLASS_ARMOR
Definition: ItemTemplate.h:304
@ ITEM_CLASS_WEAPON
Definition: ItemTemplate.h:302
@ ITEM_CLASS_CONSUMABLE
Definition: ItemTemplate.h:300
@ PLAYER_AMMO_ID
Definition: UpdateFields.h:369
std::vector< ItemPosCount > ItemPosCountVec
Definition: Player.h:772
@ NULL_BAG
Definition: Unit.h:210
@ NULL_SLOT
Definition: Unit.h:211
LootStore LootTemplates_Milling("milling_loot_template", "item entry (herb)", true)
LootStore LootTemplates_Prospecting("prospecting_loot_template", "item entry (ore)", true)
@ ITEM_ENCHANTMENT_TYPE_USE_SPELL
Definition: DBCEnums.h:381
@ ITEM_ENCHANTMENT_TYPE_PRISMATIC_SOCKET
Definition: DBCEnums.h:382
#define MAX_SPELL_REAGENTS
Definition: DBCStructure.h:1637
#define MAX_SPELL_ITEM_ENCHANTMENT_EFFECTS
Definition: DBCStructure.h:1839
@ 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
uint32 GetEnchantmentId(EnchantmentSlot slot) const
Definition: Item.h:295
int32 GetSpellCharges(uint8 index=0) const
Definition: Item.h:308
bool IsBroken() const
Definition: Item.h:251
bool IsWeaponVellum() const
Definition: Item.h:329
bool IsArmorVellum() const
Definition: Item.h:330
Player * GetOwner() const
Definition: Item.cpp:550
ObjectGuid GetOwnerGUID() const
Definition: Item.h:225
uint32 GetCount() const
Definition: Item.h:263
bool IsFitToSpellRequirements(SpellInfo const *spellInfo) const
Definition: Item.cpp:885
int32 SpellCharges
Definition: ItemTemplate.h:602
uint32 SpellTrigger
Definition: ItemTemplate.h:601
int32 SpellId
Definition: ItemTemplate.h:600
uint32 Color
Definition: ItemTemplate.h:611
Definition: ItemTemplate.h:628
uint32 DisenchantID
Definition: ItemTemplate.h:699
uint32 Quality
Definition: ItemTemplate.h:635
uint32 RequiredSkillRank
Definition: ItemTemplate.h:647
uint32 GetMaxStackSize() const
Definition: ItemTemplate.h:738
_Spell Spells[MAX_ITEM_PROTO_SPELLS]
Definition: ItemTemplate.h:671
uint32 RequiredDisenchantSkill
Definition: ItemTemplate.h:693
uint32 Flags
Definition: ItemTemplate.h:636
uint32 RequiredLevel
Definition: ItemTemplate.h:645
uint32 Class
Definition: ItemTemplate.h:630
uint32 ItemLimitCategory
Definition: ItemTemplate.h:696
uint32 SubClass
Definition: ItemTemplate.h:631
_Socket Socket[MAX_ITEM_PROTO_SOCKETS]
Definition: ItemTemplate.h:690
uint32 GetUInt32Value(uint16 index) const
Definition: Object.cpp:305
void SetUInt32Value(uint16 index, uint32 value)
Definition: Object.cpp:650
bool HasItemFitToSpellRequirements(SpellInfo const *spellInfo, Item const *ignoreItem=nullptr) const
Definition: Player.cpp:12431
uint32 GetFreeInventorySpace() const
Definition: PlayerStorage.cpp:494
Item * GetItemByEntry(uint32 entry) const
Definition: PlayerStorage.cpp:3391
bool HasItemCount(uint32 item, uint32 count=1, bool inBankAlso=false) const
Definition: PlayerStorage.cpp:683
bool HasItemTotemCategory(uint32 TotemCategory) const
Definition: PlayerStorage.cpp:879
bool CanNoReagentCast(SpellInfo const *spellInfo) const
Definition: Player.cpp:12476
void SendEquipError(InventoryResult msg, Item *pItem, Item *pItem2=nullptr, uint32 itemid=0)
Definition: PlayerStorage.cpp:4043
InventoryResult CanStoreNewItem(uint8 bag, uint8 slot, ItemPosCountVec &dest, uint32 item, uint32 count, uint32 *no_space_count=nullptr) const
Definition: Player.h:1260
bool CanUseAttackType(uint8 attacktype) const
Definition: Unit.h:1621
bool IsFullHealth() const
Definition: Unit.h:1457
uint32 GetMaxPower(Powers power) const
Definition: Unit.h:1476
uint32 GetPower(Powers power) const
Definition: Unit.h:1475
bool HaveLootFor(uint32 loot_id) const
Definition: LootMgr.h:224
uint32 GetItemTargetEntry() const
Definition: Spell.h:140
ObjectGuid m_castItemGUID
Definition: Spell.h:523
uint32 BaseLevel
Definition: SpellInfo.h:357
uint32 MaxLevel
Definition: SpellInfo.h:356
std::array< int32, MAX_SPELL_REAGENTS > Reagent
Definition: SpellInfo.h:371
flag96 SpellFamilyFlags
Definition: SpellInfo.h:386
std::array< uint32, 2 > TotemCategory
Definition: SpellInfo.h:376
int32 EquippedItemClass
Definition: SpellInfo.h:373
std::array< uint32, 2 > Totem
Definition: SpellInfo.h:370
std::array< uint32, MAX_SPELL_REAGENTS > ReagentCount
Definition: SpellInfo.h:372
Definition: DBCStructure.h:1842
uint32 type[MAX_SPELL_ITEM_ENCHANTMENT_EFFECTS]
Definition: DBCStructure.h:1845
uint32 slot
Definition: DBCStructure.h:1852

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

Referenced by CheckCast().

◆ CheckPetCast()

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

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

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

◆ CheckPower()

SpellCastResult Spell::CheckPower ( )
7102{
7103 // item cast not used power
7104 if (m_CastItem)
7105 return SPELL_CAST_OK;
7106
7107 //While .cheat power is enabled dont check if we need power to cast the spell
7109 {
7111 {
7112 return SPELL_CAST_OK;
7113 }
7114 }
7115
7116 // health as power used - need check health amount
7118 {
7121 return SPELL_CAST_OK;
7122 }
7123 // Check valid power type
7125 {
7126 LOG_ERROR("spells", "Spell::CheckPower: Unknown power type '{}'", m_spellInfo->PowerType);
7127 return SPELL_FAILED_UNKNOWN;
7128 }
7129
7130 //check rune cost only if a spell has PowerType == POWER_RUNE
7132 {
7134 if (failReason != SPELL_CAST_OK)
7135 return failReason;
7136 }
7137
7138 // Check power amount
7141 return SPELL_FAILED_NO_POWER;
7142 else
7143 return SPELL_CAST_OK;
7144}
@ CHEAT_POWER
Definition: Player.h:994
PowerType
Definition: VehicleDefines.h:30
@ 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:1454
SpellCastResult CheckRuneCost(uint32 RuneCostID)
Definition: Spell.cpp:5384
uint32 RuneCostID
Definition: SpellInfo.h:366
uint32 PowerType
Definition: SpellInfo.h:360

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

Referenced by CheckCast().

◆ CheckRange()

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

Referenced by CheckCast().

◆ CheckRuneCost()

SpellCastResult Spell::CheckRuneCost ( uint32  RuneCostID)
5385{
5386 if (m_spellInfo->PowerType != POWER_RUNE || !RuneCostID)
5387 return SPELL_CAST_OK;
5388
5390 return SPELL_CAST_OK;
5391
5392 Player* player = m_caster->ToPlayer();
5393 //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)
5394 if (player->GetCommandStatus(CHEAT_POWER))
5395 {
5396 return SPELL_CAST_OK;
5397 }
5398
5399 if (player->getClass() != CLASS_DEATH_KNIGHT)
5400 return SPELL_CAST_OK;
5401
5402 SpellRuneCostEntry const* src = sSpellRuneCostStore.LookupEntry(RuneCostID);
5403
5404 if (!src)
5405 return SPELL_CAST_OK;
5406
5407 if (src->NoRuneCost())
5408 return SPELL_CAST_OK;
5409
5410 int32 runeCost[NUM_RUNE_TYPES]; // blood, frost, unholy, death
5411
5412 for (uint32 i = 0; i < RUNE_DEATH; ++i)
5413 {
5414 runeCost[i] = src->RuneCost[i];
5415 if (Player* modOwner = m_caster->GetSpellModOwner())
5416 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_COST, runeCost[i], this);
5417 }
5418
5419 runeCost[RUNE_DEATH] = MAX_RUNES; // calculated later
5420
5421 for (uint32 i = 0; i < MAX_RUNES; ++i)
5422 {
5423 RuneType rune = player->GetCurrentRune(i);
5424 if ((player->GetRuneCooldown(i) == 0) && (runeCost[rune] > 0))
5425 runeCost[rune]--;
5426 }
5427
5428 for (uint32 i = 0; i < RUNE_DEATH; ++i)
5429 if (runeCost[i] > 0)
5430 runeCost[RUNE_DEATH] += runeCost[i];
5431
5432 if (runeCost[RUNE_DEATH] > MAX_RUNES)
5433 return SPELL_FAILED_NO_POWER; // not sure if result code is correct
5434
5435 return SPELL_CAST_OK;
5436}
DBCStorage< SpellRuneCostEntry > sSpellRuneCostStore(SpellRuneCostfmt)
RuneType
Definition: Player.h:409
@ RUNE_DEATH
Definition: Player.h:413
@ NUM_RUNE_TYPES
Definition: Player.h:414
#define MAX_RUNES
Definition: Player.h:399
@ SPELLMOD_COST
Definition: SpellDefines.h:91
@ CLASS_DEATH_KNIGHT
Definition: SharedDefines.h:146
uint32 GetRuneCooldown(uint8 index) const
Definition: Player.h:2471
RuneType GetCurrentRune(uint8 index) const
Definition: Player.h:2470
Definition: DBCStructure.h:1805
uint32 RuneCost[3]
Definition: DBCStructure.h:1807
bool NoRuneCost() const
Definition: DBCStructure.h:1810

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

Referenced by CheckPower().

◆ CheckScriptEffectImplicitTargets()

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

References m_loadedScripts, and m_spellInfo.

Referenced by SelectEffectImplicitTargets().

◆ CheckSpellFocus()

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

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

Referenced by CheckCast().

◆ CheckSrc()

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

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

◆ CleanupTargetList()

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

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

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

◆ Delayed()

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

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

◆ DelayedChannel()

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

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

◆ DoAllEffectOnLaunchTarget()

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

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

Referenced by HandleLaunchPhase().

◆ DoAllEffectOnTarget() [1/3]

void Spell::DoAllEffectOnTarget ( GOTargetInfo target)
protected
3330{
3331 if (target->processed) // Check target
3332 return;
3333 target->processed = true; // Target checked in apply effects procedure
3334
3335 uint32 effectMask = target->effectMask;
3336 if (!effectMask)
3337 return;
3338
3339 GameObject* go = m_caster->GetMap()->GetGameObject(target->targetGUID);
3340 if (!go)
3341 return;
3342
3345
3346 for (uint32 effectNumber = 0; effectNumber < MAX_SPELL_EFFECTS; ++effectNumber)
3347 if (effectMask & (1 << effectNumber))
3348 HandleEffects(nullptr, nullptr, go, effectNumber, SPELL_EFFECT_HANDLE_HIT_TARGET);
3349
3350 // xinef: inform ai about spellhit
3352
3354
3356}
virtual void SpellHit(Unit *, SpellInfo const *)
Definition: GameObjectAI.h:67
GameObjectAI * AI() const
Definition: GameObject.h:310
void CallScriptBeforeHitHandlers(SpellMissInfo missInfo)
Definition: Spell.cpp:8589
void CallScriptOnHitHandlers()
Definition: Spell.cpp:8602
void CallScriptAfterHitHandlers()
Definition: Spell.cpp:8615

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
3359{
3360 uint32 effectMask = target->effectMask;
3361 if (!target->item || !effectMask)
3362 return;
3363
3366
3367 for (uint32 effectNumber = 0; effectNumber < MAX_SPELL_EFFECTS; ++effectNumber)
3368 if (effectMask & (1 << effectNumber))
3369 HandleEffects(nullptr, target->item, nullptr, effectNumber, SPELL_EFFECT_HANDLE_HIT_TARGET);
3370
3372
3374}

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
2609{
2610 if (!target || target->processed)
2611 return;
2612
2613 target->processed = true; // Target checked in apply effects procedure
2614
2615 // Get mask of effects for target
2616 uint8 mask = target->effectMask;
2617
2618 Unit* effectUnit = m_caster->GetGUID() == target->targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, target->targetGUID);
2619 if (!effectUnit && !target->targetGUID.IsPlayer()) // only players may be targeted across maps
2620 return;
2621
2622 if (!effectUnit || m_spellInfo->Id == 45927)
2623 {
2624 uint8 farMask = 0;
2625 // create far target mask
2626 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
2627 if (m_spellInfo->Effects[i].IsFarUnitTargetEffect())
2628 if ((1 << i) & mask)
2629 farMask |= (1 << i);
2630
2631 if (!farMask)
2632 return;
2633 // find unit in world
2634 // Xinef: FindUnit Access without Map check!!! Intended
2635 effectUnit = ObjectAccessor::FindPlayer(target->targetGUID);
2636 if (!effectUnit)
2637 return;
2638
2639 // do far effects on the unit
2640 // can't use default call because of threading, do stuff as fast as possible
2641 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
2642 if (farMask & (1 << i))
2643 HandleEffects(effectUnit, nullptr, nullptr, i, SPELL_EFFECT_HANDLE_HIT_TARGET);
2644 return;
2645 }
2646
2647 if (effectUnit->IsAlive() != target->alive)
2648 return;
2649
2650 // Xinef: absorb delayed projectiles for 500ms
2652 (GameTime::GetGameTimeMS().count() - target->timeDelay) <= effectUnit->m_lastSanctuaryTime && GameTime::GetGameTimeMS().count() < (effectUnit->m_lastSanctuaryTime + 500) &&
2653 effectUnit->FindMap() && !effectUnit->FindMap()->IsDungeon()
2654 )
2655 return; // No missinfo in that case
2656
2657 // Get original caster (if exist) and calculate damage/healing from him data
2659
2660 // Skip if m_originalCaster not avaiable
2661 if (!caster)
2662 return;
2663
2664 SpellMissInfo missInfo = target->missCondition;
2665
2666 // Need init unitTarget by default unit (can changed in code on reflect)
2667 // Or on missInfo != SPELL_MISS_NONE unitTarget undefined (but need in trigger subsystem)
2668 unitTarget = effectUnit;
2669
2670 // Reset damage/healing counter
2671 m_damage = target->damage;
2672 m_healing = -target->damage;
2673
2674 m_spellAura = nullptr; // Set aura to null for every target-make sure that pointer is not used for unit without aura applied
2675
2678
2679 //Spells with this flag cannot trigger if effect is casted on self
2681 bool reflectedSpell = missInfo == SPELL_MISS_REFLECT;
2682 Unit* spellHitTarget = nullptr;
2683
2684 if (missInfo == SPELL_MISS_NONE) // In case spell hit target, do all effect on that target
2685 spellHitTarget = unitTarget;
2686 else if (missInfo == SPELL_MISS_REFLECT) // In case spell reflect from target, do all effect on caster (if hit)
2687 {
2688 missInfo = target->reflectResult;
2689 if (missInfo == SPELL_MISS_NONE) // If reflected spell hit caster -> do all effect on him
2690 {
2691 spellHitTarget = m_caster;
2693 if (m_caster->GetTypeId() == TYPEID_UNIT)
2695 }
2696 }
2697
2698 if (spellHitTarget)
2699 {
2700 SpellMissInfo missInfo2 = DoSpellHitOnUnit(spellHitTarget, mask, target->scaleAura);
2701 if (missInfo2 != SPELL_MISS_NONE)
2702 {
2703 if (missInfo2 != SPELL_MISS_MISS)
2704 m_caster->SendSpellMiss(spellHitTarget, m_spellInfo->Id, missInfo2);
2705 m_damage = 0;
2706 spellHitTarget = nullptr;
2707
2708 // Xinef: if missInfo2 is MISS_EVADE, override base missinfo data
2709 if (missInfo2 == SPELL_MISS_EVADE)
2710 missInfo = SPELL_MISS_EVADE;
2711 }
2712 }
2713
2714 // Do not take combo points on dodge and miss
2715 if (missInfo != SPELL_MISS_NONE && m_needComboPoints && m_targets.GetUnitTargetGUID() == target->targetGUID)
2716 {
2717 m_needComboPoints = false;
2718 // Restore spell mods for a miss/dodge/parry Cold Blood
2720 if (m_caster->GetTypeId() == TYPEID_PLAYER && (missInfo == SPELL_MISS_MISS || missInfo == SPELL_MISS_DODGE || missInfo == SPELL_MISS_PARRY))
2721 m_caster->ToPlayer()->RestoreSpellMods(this, 14177);
2722 }
2723
2724 // Fill base trigger info
2725 uint32 procAttacker = m_procAttacker;
2726 uint32 procVictim = m_procVictim;
2727 uint32 procEx = m_procEx;
2728
2729 // Trigger info was not filled in spell::preparedatafortriggersystem - we do it now
2730 if (canEffectTrigger && !procAttacker && !procVictim)
2731 {
2732 bool positive = true;
2733 if (m_damage > 0)
2734 positive = false;
2735 else if (!m_healing)
2736 {
2737 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
2738 // If at least one effect negative spell is negative hit
2739 // Xinef: if missInfo is immune state check all effects to properly determine positiveness of spell
2740 if ((missInfo == SPELL_MISS_IMMUNE2 || (mask & (1 << i))) && !m_spellInfo->IsPositiveEffect(i))
2741 {
2742 positive = false;
2743 break;
2744 }
2745 }
2746 switch (m_spellInfo->DmgClass)
2747 {
2749 if (positive)
2750 {
2753 }
2754 else
2755 {
2758 }
2759 break;
2761 if (positive)
2762 {
2765 }
2766 else
2767 {
2770 }
2771 break;
2772 }
2773 }
2775
2776 // All calculated do it!
2777 // Do healing and triggers
2778 if (m_healing > 0)
2779 {
2780 bool crit = target->crit;
2781 uint32 addhealth = m_healing;
2782
2783 if (crit)
2784 {
2785 procEx |= PROC_EX_CRITICAL_HIT;
2786 addhealth = Unit::SpellCriticalHealingBonus(caster, m_spellInfo, addhealth, nullptr);
2787 }
2788 else
2789 procEx |= PROC_EX_NORMAL_HIT;
2790
2791 HealInfo healInfo(caster, unitTarget, addhealth, m_spellInfo, m_spellInfo->GetSchoolMask());
2792
2793 // Xinef: override with forced crit, only visual result
2794 if (GetSpellValue()->ForcedCritResult)
2795 {
2796 crit = true;
2797 procEx |= PROC_EX_CRITICAL_HIT;
2798 }
2799
2800 int32 gain = caster->HealBySpell(healInfo, crit);
2801 unitTarget->getHostileRefMgr().threatAssist(caster, float(gain) * 0.5f, m_spellInfo);
2802 m_healing = gain;
2803
2804 // Xinef: if heal acutally healed something, add no overheal flag
2805 if (m_healing)
2806 procEx |= PROC_EX_NO_OVERHEAL;
2807
2808 // Do triggers for unit (reflect triggers passed on hit phase for correct drop charge)
2809 if (canEffectTrigger)
2810 Unit::ProcDamageAndSpell(caster, unitTarget, procAttacker, procVictim, procEx, addhealth, m_attackType, m_spellInfo, m_triggeredByAuraSpell.spellInfo,
2811 m_triggeredByAuraSpell.effectIndex, this, nullptr, &healInfo);
2812 }
2813 // Do damage and triggers
2814 else if (m_damage > 0)
2815 {
2817
2818 // Fill base damage struct (unitTarget - is real spell target)
2820
2821 // Add bonuses and fill damageInfo struct
2822 // Dancing Rune Weapon...
2823 if (m_caster->GetEntry() == 27893)
2824 {
2825 if (Unit* owner = m_caster->GetOwner())
2826 owner->CalculateSpellDamageTaken(&damageInfo, m_damage, m_spellInfo, m_attackType, target->crit);
2827 }
2828 else
2829 caster->CalculateSpellDamageTaken(&damageInfo, m_damage, m_spellInfo, m_attackType, target->crit);
2830
2831 // xinef: override miss info after absorb / block calculations
2832 if (missInfo == SPELL_MISS_NONE && damageInfo.damage == 0)
2833 {
2834 //if (damageInfo.absorb > 0)
2835 // missInfo = SPELL_MISS_ABSORB;
2836 if (damageInfo.blocked)
2837 missInfo = SPELL_MISS_BLOCK;
2838 }
2839
2840 // Xinef: override with forced crit, only visual result
2841 if (GetSpellValue()->ForcedCritResult)
2842 {
2843 damageInfo.HitInfo |= SPELL_HIT_TYPE_CRIT;
2844 }
2845
2846 Unit::DealDamageMods(damageInfo.target, damageInfo.damage, &damageInfo.absorb);
2847
2848 // xinef: health leech handling
2850 {
2851 uint8 effIndex = EFFECT_0;
2852 for (; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
2853 if (m_spellInfo->Effects[effIndex].Effect == SPELL_EFFECT_HEALTH_LEECH)
2854 break;
2855
2856 float healMultiplier = m_spellInfo->Effects[effIndex].CalcValueMultiplier(m_originalCaster, this);
2857
2858 // get max possible damage, don't count overkill for heal
2859 uint32 healthGain = uint32(-unitTarget->GetHealthGain(-int32(damageInfo.damage)) * healMultiplier);
2860
2861 if (m_caster->IsAlive())
2862 {
2863 healthGain = m_caster->SpellHealingBonusDone(m_caster, m_spellInfo, healthGain, HEAL, effIndex);
2864 healthGain = m_caster->SpellHealingBonusTaken(m_caster, m_spellInfo, healthGain, HEAL);
2865
2866 HealInfo healInfo(m_caster, m_caster, healthGain, m_spellInfo, m_spellInfo->GetSchoolMask());
2867 m_caster->HealBySpell(healInfo);
2868 }
2869 }
2870
2871 // Send log damage message to client
2872 caster->SendSpellNonMeleeDamageLog(&damageInfo);
2873 // Xinef: send info to target about reflect
2874 if (reflectedSpell)
2875 effectUnit->SendSpellNonMeleeReflectLog(&damageInfo, effectUnit);
2876
2877 procEx |= createProcExtendMask(&damageInfo, missInfo);
2878 procVictim |= PROC_FLAG_TAKEN_DAMAGE;
2879
2880 caster->DealSpellDamage(&damageInfo, true, this);
2881
2882 // do procs after damage, eg healing effects
2883 // no need to check if target is alive, done in procdamageandspell
2884
2885 // Do triggers for unit (reflect triggers passed on hit phase for correct drop charge)
2886 if (canEffectTrigger)
2887 {
2888 DamageInfo dmgInfo(damageInfo, SPELL_DIRECT_DAMAGE);
2889 Unit::ProcDamageAndSpell(caster, unitTarget, procAttacker, procVictim, procEx, damageInfo.damage, m_attackType, m_spellInfo, m_triggeredByAuraSpell.spellInfo,
2890 m_triggeredByAuraSpell.effectIndex, this, &dmgInfo);
2891
2894 caster->ToPlayer()->CastItemCombatSpell(unitTarget, m_attackType, procVictim, procEx);
2895 }
2896
2897 m_damage = damageInfo.damage;
2898 }
2899 // Passive spell hits/misses or active spells only misses (only triggers)
2900 else
2901 {
2902 // Fill base damage struct (unitTarget - is real spell target)
2904 procEx |= createProcExtendMask(&damageInfo, missInfo);
2905 // Do triggers for unit (reflect triggers passed on hit phase for correct drop charge)
2906 if (canEffectTrigger)
2907 {
2908 DamageInfo dmgInfo(damageInfo, NODAMAGE);
2909 Unit::ProcDamageAndSpell(caster, unitTarget, procAttacker, procVictim, procEx, 0, m_attackType, m_spellInfo, m_triggeredByAuraSpell.spellInfo,
2910 m_triggeredByAuraSpell.effectIndex, this, &dmgInfo);
2911
2912 // Xinef: eg. rogue poisons can proc off cheap shot, etc. so this block should be here also
2913 // Xinef: ofc count only spells that HIT the target, little hack used to fool the system
2917 }
2918
2919 // Failed Pickpocket, reveal rogue
2921 {
2925 }
2926 }
2927
2928 if (m_caster)
2929 {
2931 {
2933
2934 // 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.
2935 if (effectUnit->IsInCombatWith(m_caster))
2936 {
2937 if (Creature* creature = effectUnit->ToCreature())
2938 {
2939 if (!creature->hasLootRecipient() && m_caster->IsPlayer())
2940 {
2941 creature->SetLootRecipient(m_caster);
2942 }
2943 }
2944 }
2945
2946 // Unsure if there are more spells that are not supposed to stop enemy from
2947 // regenerating HP from food, so for now it stays as an ID.
2948 const uint32 SPELL_PREMEDITATION = 14183;
2949 if (m_spellInfo->Id != SPELL_PREMEDITATION)
2950 {
2951 if (!effectUnit->IsStandState())
2952 {
2954 }
2955 }
2956 }
2957 }
2958
2959 if (missInfo != SPELL_MISS_EVADE && effectUnit != m_caster && m_caster->IsFriendlyTo(effectUnit) && m_spellInfo->IsPositive() &&
2961 {
2962 m_caster->SetInCombatWith(effectUnit);
2963 }
2964
2965 // Check for SPELL_ATTR7_CAN_CAUSE_INTERRUPT
2967 caster->CastSpell(effectUnit, SPELL_INTERRUPT_NONPLAYER, true);
2968
2969 if (spellHitTarget)
2970 {
2971 //AI functions
2972 if (spellHitTarget->GetTypeId() == TYPEID_UNIT)
2973 {
2974 if (spellHitTarget->ToCreature()->IsAIEnabled)
2975 spellHitTarget->ToCreature()->AI()->SpellHit(m_caster, m_spellInfo);
2976 }
2977
2979 m_caster->ToCreature()->AI()->SpellHitTarget(spellHitTarget, m_spellInfo);
2980
2981 // Needs to be called after dealing damage/healing to not remove breaking on damage auras
2982 DoTriggersOnSpellHit(spellHitTarget, mask);
2983
2984 // if target is fallged for pvp also flag caster if a player
2985 // xinef: do not flag spells with aura bind sight (no special attribute)
2986 if (effectUnit->IsPvP() && effectUnit != m_caster && effectUnit->GetOwnerGUID() != m_caster->GetGUID() &&
2988 {
2989 m_caster->ToPlayer()->UpdatePvP(true);
2990 }
2991
2993 }
2994}
uint32 createProcExtendMask(SpellNonMeleeDamage *damageInfo, SpellMissInfo missCondition)
Definition: Unit.cpp:16262
@ UNIT_STAND_STATE_STAND
Definition: Unit.h:53
@ NODAMAGE
Definition: Unit.h:439
@ SPELL_DIRECT_DAMAGE
Definition: Unit.h:436
@ HEAL
Definition: Unit.h:438
static const uint32 SPELL_INTERRUPT_NONPLAYER
Definition: Spell.h:267
@ AURA_INTERRUPT_FLAG_TALK
Definition: SpellDefines.h:54
@ SPELL_ATTR0_CU_NO_PVP_FLAG
Definition: SpellInfo.h:183
@ SPELL_ATTR0_CU_PICKPOCKET
Definition: SpellInfo.h:186
@ PROC_EX_NO_OVERHEAL
Definition: SpellMgr.h:213
@ PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_NEG
Definition: SpellMgr.h:132
@ PROC_FLAG_TAKEN_SPELL_NONE_DMG_CLASS_NEG
Definition: SpellMgr.h:126
@ PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_POS
Definition: SpellMgr.h:129
@ PROC_FLAG_TAKEN_DAMAGE
Definition: SpellMgr.h:137
@ PROC_FLAG_TAKEN_SPELL_NONE_DMG_CLASS_POS
Definition: SpellMgr.h:123
@ SPELL_EFFECT_HEALTH_LEECH
Definition: SharedDefines.h: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:144
virtual void SpellHit(Unit *, SpellInfo const *)
Definition: CreatureAI.h:141
void threatAssist(Unit *victim, float baseThreat, SpellInfo const *threatSpell=nullptr)
Definition: HostileRefMgr.cpp:35
void LowerPlayerDamageReq(uint32 unDamage, bool damagedByPlayer=true)
Definition: Creature.cpp:3706
CreatureAI * AI() const
Definition: Creature.h:136
bool IsPlayer() const
Definition: Object.h:194
void RestoreSpellMods(Spell *spell, uint32 ownerAuraId=0, Aura *aura=nullptr)
Definition: Player.cpp:9854
void CastItemCombatSpell(Unit *target, WeaponAttackType attType, uint32 procVictim, uint32 procEx)
Definition: Player.cpp:7112
void UpdatePvP(bool state, bool _override=false)
Definition: PlayerUpdates.cpp:1484
Definition: Unit.h:761
Definition: Unit.h:804
Definition: Unit.h:920
uint32 m_lastSanctuaryTime
Definition: Unit.h:2151
void DealSpellDamage(SpellNonMeleeDamage *damageInfo, bool durabilityLoss, Spell const *spell=nullptr)
Definition: Unit.cpp:1440
void SendSpellMiss(Unit *target, uint32 spellID, SpellMissInfo missInfo)
Definition: Unit.cpp:6383
void SendSpellNonMeleeReflectLog(SpellNonMeleeDamage *log, Unit *attacker)
Definition: Unit.cpp:6216
bool CanProc()
Definition: Unit.h:2334
bool IsPvP() const
Definition: Unit.h:1531
uint32 SpellHealingBonusDone(Unit *victim, SpellInfo const *spellProto, uint32 healamount, DamageEffectType damagetype, uint8 effIndex, float TotalMod=0.0f, uint32 stack=1)
Definition: Unit.cpp:12446
void SetInCombatWith(Unit *enemy, uint32 duration=0)
Definition: Unit.cpp:13575
int32 HealBySpell(HealInfo &healInfo, bool critical=false)
Definition: Unit.cpp:11238
bool IsStandState() const
Definition: Unit.cpp:16988
bool IsInCombatWith(Unit const *who) const
Definition: Unit.cpp:21319
HostileRefMgr & getHostileRefMgr()
Definition: Unit.h:2163
int32 GetHealthGain(int32 dVal)
Definition: Unit.cpp:14111
static uint32 SpellCriticalHealingBonus(Unit const *caster, SpellInfo const *spellProto, uint32 damage, Unit const *victim)
Definition: Unit.cpp:12315
void SendSpellNonMeleeDamageLog(SpellNonMeleeDamage *log)
Definition: Unit.cpp:6248
bool IsAIEnabled
Definition: Unit.h:2364
void SetLastDamagedTargetGuid(ObjectGuid const &guid)
Definition: Unit.h:1586
uint32 SpellHealingBonusTaken(Unit *caster, SpellInfo const *spellProto, uint32 healamount, DamageEffectType damagetype, uint32 stack=1)
Definition: Unit.cpp:12564
void SetStandState(uint8 state)
Definition: Unit.cpp:16994
void RemoveAurasWithInterruptFlags(uint32 flag, uint32 except=0, bool isAutoshot=false)
Definition: Unit.cpp:5116
static void DealDamageMods(Unit const *victim, uint32 &damage, uint32 *absorb)
Definition: Unit.cpp:805
void CalculateSpellDamageTaken(SpellNonMeleeDamage *damageInfo, int32 damage, SpellInfo const *spellInfo, WeaponAttackType attackType=BASE_ATTACK, bool crit=false)
Definition: Unit.cpp:1297
ObjectGuid GetUnitTargetGUID() const
Definition: Spell.cpp:215
bool CanExecuteTriggersOnHit(uint8 effMask, SpellInfo const *triggeredByAura=nullptr) const
Definition: Spell.cpp:8693
SpellValue const * GetSpellValue()
Definition: Spell.h:582
SpellMissInfo DoSpellHitOnUnit(Unit *unit, uint32 effectMask, bool scaleAura)
Definition: Spell.cpp:2996
void DoTriggersOnSpellHit(Unit *unit, uint8 effMask)
Definition: Spell.cpp:3252
uint32 AttributesEx3
Definition: SpellInfo.h:325
bool IsTargetingArea() const
Definition: SpellInfo.cpp:1012
bool IsPositiveEffect(uint8 effIndex) const
Definition: SpellInfo.cpp:1229

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

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

◆ DoCreateItem()

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

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
2997{
2998 if (!unit || !effectMask)
2999 return SPELL_MISS_EVADE;
3000
3001 // For delayed spells immunity may be applied between missile launch and hit - check immunity for that case
3002 if (m_spellInfo->Speed && ((m_damage > 0 && unit->IsImmunedToDamage(this)) || unit->IsImmunedToSchool(this) || unit->IsImmunedToSpell(m_spellInfo, this)))
3003 {
3004 return SPELL_MISS_IMMUNE;
3005 }
3006
3007 // disable effects to which unit is immune
3008 SpellMissInfo returnVal = SPELL_MISS_IMMUNE;
3009 for (uint32 effectNumber = 0; effectNumber < MAX_SPELL_EFFECTS; ++effectNumber)
3010 {
3011 if (effectMask & (1 << effectNumber))
3012 {
3013 if (unit->IsImmunedToSpellEffect(m_spellInfo, effectNumber))
3014 effectMask &= ~(1 << effectNumber);
3015 // Xinef: Buggs out polymorph
3016 // Xinef: And this is checked in MagicSpellHitResult, why we check resistance twice?
3017 // Xinef: And why we check every spell effect basing on rand and generic dispel info? some effects will be appliend and some wont?
3018 /*else if (m_spellInfo->Effects[effectNumber].IsAura() && !m_spellInfo->IsPositiveEffect(effectNumber))
3019 {
3020 int32 debuff_resist_chance = unit->GetMaxPositiveAuraModifierByMiscValue(SPELL_AURA_MOD_DEBUFF_RESISTANCE, int32(m_spellInfo->Dispel));
3021 debuff_resist_chance += unit->GetMaxNegativeAuraModifierByMiscValue(SPELL_AURA_MOD_DEBUFF_RESISTANCE, int32(m_spellInfo->Dispel));
3022
3023 if (debuff_resist_chance > 0)
3024 if (irand(0,10000) <= (debuff_resist_chance * 100))
3025 {
3026 effectMask &= ~(1 << effectNumber);
3027 returnVal = SPELL_MISS_RESIST;
3028 }
3029 }*/
3030 }
3031 }
3032 if (!effectMask)
3033 return returnVal;
3034
3035 if (unit->GetTypeId() == TYPEID_PLAYER)
3036 {
3040 }
3041
3043 {
3046 }
3047
3048 if (m_caster != unit)
3049 {
3050 // Recheck UNIT_FLAG_NON_ATTACKABLE for delayed spells
3051 // Xinef: Also check evade state
3052 if (m_spellInfo->Speed > 0.0f)
3053 {
3054 if (unit->GetTypeId() == TYPEID_UNIT && unit->ToCreature()->IsInEvadeMode())
3055 return SPELL_MISS_EVADE;
3056
3058 return SPELL_MISS_EVADE;
3059 }
3060
3061 if (m_caster->_IsValidAttackTarget(unit, m_spellInfo) && /*Intervene Trigger*/ m_spellInfo->Id != 59667)
3062 {
3064 }
3065 else if (m_caster->IsFriendlyTo(unit))
3066 {
3067 // for delayed spells ignore negative spells (after duel end) for friendly targets
3069 if(!IsTriggered() && m_spellInfo->Speed > 0.0f && unit->GetTypeId() == TYPEID_PLAYER && !m_spellInfo->IsPositive())
3070 return SPELL_MISS_EVADE;
3071
3072 // assisting case, healing and resurrection
3074 {
3077 m_caster->ToPlayer()->UpdatePvP(true);
3078 }
3079
3080 // xinef: triggered spells should not prolong combat
3082 {
3083 m_caster->SetInCombatState(unit->GetCombatTimer() > 0, unit);
3084 unit->getHostileRefMgr().threatAssist(m_caster, 0.0f);
3085 }
3086 }
3087 }
3088
3089 uint8 aura_effmask = 0;
3090 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
3091 if (effectMask & (1 << i) && m_spellInfo->Effects[i].IsUnitOwnedAuraEffect())
3092 aura_effmask |= 1 << i;
3093
3094 Unit* originalCaster = GetOriginalCaster();
3095 if (!originalCaster)
3096 originalCaster = m_caster;
3097
3098 // Get Data Needed for Diminishing Returns, some effects may have multiple auras, so this must be done on spell hit, not aura add
3099 // Xinef: Do not increase diminishing level for self cast
3101 // xinef: do not increase diminish level for bosses (eg. Void Reaver silence is never diminished)
3103 {
3106
3107 uint32 flagsExtra = unit->GetTypeId() == TYPEID_UNIT ? unit->ToCreature()->GetCreatureTemplate()->flags_extra : 0;
3108
3109 // Increase Diminishing on unit, current informations for actually casts will use values above
3110 if ((type == DRTYPE_PLAYER && (unit->IsCharmedOwnedByPlayerOrPlayer() || flagsExtra & CREATURE_FLAG_EXTRA_ALL_DIMINISH ||
3112 {
3113 // Do not apply diminish return if caster is NPC
3115 {
3117 }
3118 }
3119 }
3120
3122 {
3124 }
3125
3126 if (aura_effmask)
3127 {
3128 // Select rank for aura with level requirements only in specific cases
3129 // 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
3130 SpellInfo const* aurSpellInfo = m_spellInfo;
3131 int32 basePoints[3];
3132 if (scaleAura)
3133 {
3135 ASSERT(aurSpellInfo);
3136 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
3137 {
3138 basePoints[i] = aurSpellInfo->Effects[i].BasePoints;
3139 if (m_spellInfo->Effects[i].Effect != aurSpellInfo->Effects[i].Effect)
3140 {
3141 aurSpellInfo = m_spellInfo;
3142 break;
3143 }
3144 }
3145 }
3146
3147 if (m_originalCaster)
3148 {
3149 bool refresh = false;
3150 bool refreshPeriodic = m_spellInfo->StackAmount < 2 && !(_triggeredCastFlags & TRIGGERED_NO_PERIODIC_RESET);
3151 m_spellAura = Aura::TryRefreshStackOrCreate(aurSpellInfo, effectMask, unit, m_originalCaster,
3152 (aurSpellInfo == m_spellInfo) ? &m_spellValue->EffectBasePoints[0] : &basePoints[0], m_CastItem, ObjectGuid::Empty, &refresh, refreshPeriodic);
3153
3154 // xinef: if aura was not refreshed, add proc ex
3155 if (!refresh)
3157
3158 if (m_spellAura)
3159 {
3160 // Set aura stack amount to desired value
3162 {
3163 if (!refresh)
3165 else
3167 }
3168
3169 // Now Reduce spell duration using data received at spell hit
3170 int32 duration = m_spellAura->GetMaxDuration();
3171 int32 limitduration = GetDiminishingReturnsLimitDuration(m_diminishGroup, aurSpellInfo);
3172
3173 // Xinef: if unit == caster - test versus original unit if available
3174 float diminishMod = 1.0f;
3175 if (unit == m_caster && m_targets.GetUnitTarget())
3177 else
3178 diminishMod = unit->ApplyDiminishingToDuration(m_diminishGroup, duration, m_originalCaster, m_diminishLevel, limitduration);
3179
3180 // unit is immune to aura if it was diminished to 0 duration
3181 if (diminishMod == 0.0f)
3182 {
3184 bool found = false;
3185 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
3186 if (effectMask & (1 << i) && m_spellInfo->Effects[i].Effect != SPELL_EFFECT_APPLY_AURA)
3187 found = true;
3188 if (!found)
3189 return SPELL_MISS_IMMUNE;
3190 }
3191 else
3192 {
3193 ((UnitAura*)m_spellAura)->SetDiminishGroup(m_diminishGroup);
3194
3195 bool positive = m_spellAura->GetSpellInfo()->IsPositive();
3197 positive = aurApp->IsPositive();
3198
3199 duration = m_originalCaster->ModSpellDuration(aurSpellInfo, unit, duration, positive, effectMask);
3200
3201 // xinef: haste affects duration of those spells twice
3204
3205 if (m_spellValue->AuraDuration != 0)
3206 {
3207 if (m_spellAura->GetMaxDuration() != -1)
3208 {
3210 }
3211
3213 }
3214 else if (duration != m_spellAura->GetMaxDuration())
3215 {
3216 m_spellAura->SetMaxDuration(duration);
3217 m_spellAura->SetDuration(duration);
3218 }
3219
3220 // xinef: apply relic cooldown, imo best place to add this
3223
3226 }
3227 }
3228 }
3229 }
3230
3231 int8 sanct_effect = -1;
3232
3233 for (uint32 effectNumber = 0; effectNumber < MAX_SPELL_EFFECTS; ++effectNumber)
3234 {
3235 // handle sanctuary effects after aura apply!
3236 if (m_spellInfo->Effects[effectNumber].Effect == SPELL_EFFECT_SANCTUARY)
3237 {
3238 sanct_effect = effectNumber;
3239 continue;
3240 }
3241
3242 if (effectMask & (1 << effectNumber))
3243 HandleEffects(unit, nullptr, nullptr, effectNumber, SPELL_EFFECT_HANDLE_HIT_TARGET);
3244 }
3245
3246 if( sanct_effect >= 0 && (effectMask & (1 << sanct_effect)) )
3247 HandleEffects(unit, nullptr, nullptr, sanct_effect, SPELL_EFFECT_HANDLE_HIT_TARGET);
3248
3249 return SPELL_MISS_NONE;
3250}
@ CREATURE_FLAG_EXTRA_OBEYS_TAUNT_DIMINISHING_RETURNS
Definition: CreatureData.h:68
@ CREATURE_FLAG_EXTRA_ALL_DIMINISH
Definition: CreatureData.h:69
@ UNIT_MOD_CAST_SPEED
Definition: UpdateFields.h:137
@ UNIT_STATE_ATTACK_PLAYER
Definition: Unit.h:339
@ UNIT_FLAG_NON_ATTACKABLE
Definition: Unit.h:449
@ SPELL_AURA_PERIODIC_HASTE
Definition: SpellAuraDefines.h:379
@ SPELL_AURA_REFLECT_SPELLS
Definition: SpellAuraDefines.h:91
@ SPELL_AURA_MOD_STEALTH
Definition: SpellAuraDefines.h:79
@ AURA_INTERRUPT_FLAG_HITBYSPELL
Definition: SpellDefines.h:44
@ TRIGGERED_NO_PERIODIC_RESET
Will ignore equipped item requirements.
Definition: SpellDefines.h:150
@ SPELL_ATTR0_CU_DONT_BREAK_STEALTH
Definition: SpellInfo.h:182
int32 GetDiminishingReturnsLimitDuration(DiminishingGroup group, SpellInfo const *spellproto)
Definition: SpellMgr.cpp:276
DiminishingGroup GetDiminishingReturnsGroupForSpell(SpellInfo const *spellproto, bool triggered)
Definition: SpellMgr.cpp:59
DiminishingReturnsType GetDiminishingReturnsGroupType(DiminishingGroup group)
Definition: SpellMgr.cpp:246
@ PROC_EX_NO_AURA_REFRESH
Definition: SpellMgr.h:214
@ ACHIEVEMENT_TIMED_TYPE_SPELL_CASTER
Definition: DBCEnums.h:120
@ ACHIEVEMENT_TIMED_TYPE_SPELL_TARGET
Definition: DBCEnums.h:121
@ ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET2
Definition: DBCEnums.h:189
@ ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET
Definition: DBCEnums.h:150
@ ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL2
Definition: DBCEnums.h:225
@ 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
bool isWorldBoss() const
Definition: Creature.h:116
bool IsInEvadeMode() const
Definition: Creature.h:130
uint32 flags_extra
Definition: CreatureData.h:239
float GetFloatValue(uint16 index) const
Definition: Object.cpp:317
static ObjectGuid const Empty
Definition: ObjectGuid.h:122
bool HasAuraTypeWithAffectMask(AuraType auratype, SpellInfo const *affectedSpell) const
Definition: Unit.cpp:5676
DiminishingLevels GetDiminishing(DiminishingGroup group)
Definition: Unit.cpp:14993
void IncrDiminishing(DiminishingGroup group)
Definition: Unit.cpp:15019
uint32 GetCombatTimer() const
Definition: Unit.h:1712
bool IsImmunedToSchool(SpellSchoolMask meleeSchoolMask) const
Definition: Unit.cpp:12826
void SetContestedPvP(Player *attackedPlayer=nullptr, bool lookForNearContestedGuards=true)
Definition: Unit.cpp:17513
bool HasUnitFlag(UnitFlags flags) const
Definition: Unit.h:1494
float ApplyDiminishingToDuration(DiminishingGroup group, int32 &duration, Unit *caster, DiminishingLevels Level, int32 limitduration)
Definition: Unit.cpp:15033
int32 ModSpellDuration(SpellInfo const *spellProto, Unit const *target, int32 duration, bool positive, uint32 effectMask)
Definition: Unit.cpp:14859
virtual void AddSpellCooldown(uint32, uint32, uint32, bool needSendToClient=false, bool forceSendToSpectator=false)
Definition: Unit.h:2434
void SetInCombatState(bool PvP, Unit *enemy=nullptr, uint32 duration=0)
Definition: Unit.cpp:13722
bool IsCharmedOwnedByPlayerOrPlayer() const
Definition: Unit.h:1852
bool HasAuraType(AuraType auraType) const
Definition: Unit.cpp:5643
bool IsImmunedToDamage(SpellSchoolMask meleeSchoolMask) const
Definition: Unit.cpp:12741
virtual bool IsImmunedToSpell(SpellInfo const *spellInfo, Spell const *spell=nullptr)
Definition: Unit.cpp:12910
bool IsHostileTo(Unit const *unit) const
Definition: Unit.cpp:10244
bool _IsValidAttackTarget(Unit const *target, SpellInfo const *bySpell, WorldObject const *obj=nullptr) const
Definition: Unit.cpp:13865
ObjectGuid GetCharmerOrOwnerGUID() const
Definition: Unit.h:1844
Definition: SpellAuras.h:37
int32 GetMaxDuration() const
Definition: SpellAuras.h:129
void SetStackAmount(uint8 num)
Definition: SpellAuras.cpp:1009
void SetTriggeredByAuraSpellInfo(SpellInfo const *triggeredByAuraSpellInfo)
Definition: SpellAuras.cpp:2761
void _RegisterForTargets()
Definition: SpellAuras.h:121
bool ModStackAmount(int32 num, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT, bool periodicReset=false)
Definition: SpellAuras.cpp:1035
static Aura * TryRefreshStackOrCreate(SpellInfo const *spellproto, uint8 tryEffMask, WorldObject *owner, Unit *caster, int32 *baseAmount=nullptr, Item *castItem=nullptr, ObjectGuid casterGUID=ObjectGuid::Empty, bool *refresh=nullptr, bool periodicReset=false)
Definition: SpellAuras.cpp:326
void SetDuration(int32 duration, bool withMods=false)
Definition: SpellAuras.cpp:882
const AuraApplication * GetApplicationOfTarget(ObjectGuid guid) const
Definition: SpellAuras.h:183
void SetMaxDuration(int32 duration)
Definition: SpellAuras.h:130
virtual void Remove(AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)=0
Definition: SpellAuras.h:279
int32 AuraDuration
Definition: Spell.h:217
uint8 AuraStackAmount
Definition: Spell.h:216
Unit * GetOriginalCaster() const
Definition: Spell.h:573
SpellInfo const * GetAuraRankForLevel(uint8 level) const
Definition: SpellInfo.cpp:2512

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

Referenced by DoAllEffectOnTarget().

◆ DoTriggersOnSpellHit()

void Spell::DoTriggersOnSpellHit ( Unit unit,
uint8  effMask 
)
protected
Todo:
: move this code to scripts
Todo:
: remove/cleanup this, as this table is not documented and people are doing stupid things with it
3253{
3254 // Apply additional spell effects to target
3256 if (m_preCastSpell)
3257 {
3258 // Paladin immunity shields
3259 if (m_preCastSpell == 61988)
3260 {
3261 // Cast Forbearance
3262 m_caster->CastSpell(unit, 25771, true);
3263 // Cast Avenging Wrath Marker
3264 unit->CastSpell(unit, 61987, true);
3265 }
3266
3267 // Avenging Wrath
3268 if (m_preCastSpell == 61987)
3269 // Cast the serverside immunity shield marker
3270 m_caster->CastSpell(unit, 61988, true);
3271
3272 // Fearie Fire (Feral) - damage
3273 if( m_preCastSpell == 60089 )
3274 m_caster->CastSpell(unit, m_preCastSpell, true);
3275 else if (sSpellMgr->GetSpellInfo(m_preCastSpell))
3276 // Blizz seems to just apply aura without bothering to cast
3278 }
3279
3280 // handle SPELL_AURA_ADD_TARGET_TRIGGER auras
3281 // this is executed after spell proc spells on target hit
3282 // spells are triggered for each hit spell target
3283 // info confirmed with retail sniffs of permafrost and shadow weaving
3284 if (!m_hitTriggerSpells.empty())
3285 {
3286 int _duration = 0;
3287 for (HitTriggerSpellList::const_iterator i = m_hitTriggerSpells.begin(); i != m_hitTriggerSpells.end(); ++i)
3288 {
3289 if (CanExecuteTriggersOnHit(effMask, i->triggeredByAura) && roll_chance_i(i->chance))
3290 {
3291 m_caster->CastSpell(unit, i->triggeredSpell->Id, true);
3292 LOG_DEBUG("spells.aura", "Spell {} triggered spell {} by SPELL_AURA_ADD_TARGET_TRIGGER aura", m_spellInfo->Id, i->triggeredSpell->Id);
3293
3294 // SPELL_AURA_ADD_TARGET_TRIGGER auras shouldn't trigger auras without duration
3295 // set duration of current aura to the triggered spell
3296 if (i->triggeredSpell->GetDuration() == -1)
3297 {
3298 if (Aura* triggeredAur = unit->GetAura(i->triggeredSpell->Id, m_caster->GetGUID()))
3299 {
3300 // get duration from aura-only once
3301 if (!_duration)
3302 {
3303 Aura* aur = unit->GetAura(m_spellInfo->Id, m_caster->GetGUID());
3304 _duration = aur ? aur->GetDuration() : -1;
3305 }
3306 triggeredAur->SetDuration(_duration);
3307 }
3308 }
3309 }
3310 }
3311 }
3312
3313 // trigger linked auras remove/apply
3315 if (std::vector<int32> const* spellTriggered = sSpellMgr->GetSpellLinked(m_spellInfo->Id + SPELL_LINK_HIT))
3316 {
3317 for (std::vector<int32>::const_iterator i = spellTriggered->begin(); i != spellTriggered->end(); ++i)
3318 if (*i < 0)
3319 {
3320 unit->RemoveAurasDueToSpell(-(*i));
3321 }
3322 else
3323 {
3324 unit->CastSpell(unit, *i, true, 0, 0, m_caster->GetGUID());
3325 }
3326 }
3327}
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:5519
Aura * AddAura(uint32 spellId, Unit *target)
Definition: Unit.cpp:19127
int32 GetDuration() const
Definition: SpellAuras.h:133
HitTriggerSpellList m_hitTriggerSpells
Definition: Spell.h:753

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

Referenced by DoAllEffectOnTarget().

◆ EffectActivateObject()

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

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

◆ EffectActivateRune()

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

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

◆ EffectActivateSpec()

void Spell::EffectActivateSpec ( SpellEffIndex  effIndex)
6177{
6179 return;
6180
6181 if (!unitTarget)
6182 return;
6183
6184 if (Player* player = unitTarget->ToPlayer())
6185 {
6186 player->ActivateSpec(damage - 1); // damage is 1 or 2, spec is 0 or 1
6187 }
6188}

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

◆ EffectAddComboPoints()

void Spell::EffectAddComboPoints ( SpellEffIndex  effIndex)
4101{
4103 {
4104 return;
4105 }
4106
4107 if (!unitTarget || damage <= 0)
4108 {
4109 return;
4110 }
4111
4113}
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)
4675{
4677 {
4678 return;
4679 }
4680
4681 if (!unitTarget || !unitTarget->IsAlive())
4682 {
4683 return;
4684 }
4685
4687
4689}
void AddExtraAttacks(uint32 count)
Definition: Unit.cpp:2737
void ExecuteLogEffectExtraAttacks(uint8 effIndex, Unit *victim, uint32 attCount)
Definition: Spell.cpp:5092

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

◆ EffectAddFarsight()

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

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

◆ EffectAddHonor()

void Spell::EffectAddHonor ( SpellEffIndex  effIndex)
2786{
2788 return;
2789
2791 return;
2792
2793 // not scale value for item based reward (/10 value expected)
2794 if (m_CastItem)
2795 {
2796 unitTarget->ToPlayer()->RewardHonor(nullptr, 1, damage / 10, false);
2797 LOG_DEBUG("spells.aura", "SpellEffect::AddHonor (spell_id {}) rewards {} honor points (item {}) for player: {}",
2799 return;
2800 }
2801
2802 // do not allow to add too many honor for player (50 * 21) = 1040 at level 70, or (50 * 31) = 1550 at level 80
2803 if (damage <= 50)
2804 {
2806 unitTarget->ToPlayer()->RewardHonor(nullptr, 1, honor_reward, false);
2807 LOG_DEBUG("spells.aura", "SpellEffect::AddHonor (spell_id {}) rewards {} honor points (scale) to player: {}",
2808 m_spellInfo->Id, honor_reward, unitTarget->ToPlayer()->GetGUID().ToString());
2809 }
2810 else
2811 {
2812 //maybe we have correct honor_gain in damage already
2813 unitTarget->ToPlayer()->RewardHonor(nullptr, 1, damage, false);
2814 LOG_DEBUG("spells.aura", "SpellEffect::AddHonor (spell_id {}) rewards {} honor points (non scale) for player: {}",
2816 }
2817}
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:5979

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

◆ EffectApplyAreaAura()

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

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

◆ EffectApplyAura()

void Spell::EffectApplyAura ( SpellEffIndex  effIndex)

◆ EffectApplyGlyph()

void Spell::EffectApplyGlyph ( SpellEffIndex  effIndex)
4342{
4344 return;
4345
4347 return;
4348
4349 Player* player = m_caster->ToPlayer();
4350
4351 // glyph sockets level requirement
4352 uint8 minLevel = 0;
4353 switch (m_glyphIndex)
4354 {
4355 case 0:
4356 case 1:
4357 minLevel = 15;
4358 break;
4359 case 2:
4360 minLevel = 50;
4361 break;
4362 case 3:
4363 minLevel = 30;
4364 break;
4365 case 4:
4366 minLevel = 70;
4367 break;
4368 case 5:
4369 minLevel = 80;
4370 break;
4371 }
4372 if (minLevel && m_caster->GetLevel() < minLevel)
4373 {
4375 return;
4376 }
4377
4378 // apply new one
4379 if (uint32 glyph = m_spellInfo->Effects[effIndex].MiscValue)
4380 {
4381 if (GlyphPropertiesEntry const* glyphEntry = sGlyphPropertiesStore.LookupEntry(glyph))
4382 {
4383 if (GlyphSlotEntry const* glyphSlotEntry = sGlyphSlotStore.LookupEntry(player->GetGlyphSlot(m_glyphIndex)))
4384 {
4385 if (glyphEntry->TypeFlags != glyphSlotEntry->TypeFlags)
4386 {
4388 return; // glyph slot mismatch
4389 }
4390 }
4391
4392 // remove old glyph aura
4393 if (uint32 oldGlyph = player->GetGlyph(m_glyphIndex))
4394 if (GlyphPropertiesEntry const* oldGlyphEntry = sGlyphPropertiesStore.LookupEntry(oldGlyph))
4395 {
4396 player->RemoveAurasDueToSpell(oldGlyphEntry->SpellId);
4397
4398 // Removed any triggered auras
4399 Unit::AuraMap& ownedAuras = player->GetOwnedAuras();
4400 for (Unit::AuraMap::iterator iter = ownedAuras.begin(); iter != ownedAuras.end();)
4401 {
4402 Aura* aura = iter->second;
4403 if (SpellInfo const* triggeredByAuraSpellInfo = aura->GetTriggeredByAuraSpellInfo())
4404 {
4405 if (triggeredByAuraSpellInfo->Id == oldGlyphEntry->SpellId)
4406 {
4407 player->RemoveOwnedAura(iter);
4408 continue;
4409 }
4410 }
4411 ++iter;
4412 }
4413
4414 player->SendLearnPacket(oldGlyphEntry->SpellId, false); // Send packet to properly handle client-side spell tooltips
4415 }
4416
4417 player->SendLearnPacket(glyphEntry->SpellId, true); // Send packet to properly handle client-side spell tooltips
4419 player->SetGlyph(m_glyphIndex, glyph, !player->GetSession()->PlayerLoading());
4420 player->SendTalentsInfoData(false);
4421 }
4422 }
4423}
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:14338
void SendLearnPacket(uint32 spellId, bool learn)
Definition: Player.cpp:2991
uint32 GetGlyph(uint8 slot) const
Definition: Player.h:1733
uint32 GetGlyphSlot(uint8 slot) const
Definition: Player.h:1724
void SetGlyph(uint8 slot, uint32 glyph, bool save)
Definition: Player.h:1725
void RemoveOwnedAura(AuraMap::iterator &i, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition: Unit.cpp:4651
std::multimap< uint32, Aura * > AuraMap
Definition: Unit.h:1307
AuraMap & GetOwnedAuras()
Definition: Unit.h:1928
bool PlayerLoading() const
Definition: WorldSession.h:337
SpellInfo const * GetTriggeredByAuraSpellInfo() const
Definition: SpellAuras.cpp:2775
Definition: DBCStructure.h:1020

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

◆ EffectBind()

void Spell::EffectBind ( SpellEffIndex  effIndex)
6310{
6312 return;
6313
6314 if (!unitTarget)
6315 return;
6316
6317 Player* player = unitTarget->ToPlayer();
6318 if (!player)
6319 {
6320 return;
6321 }
6322
6323 WorldLocation homeLoc;
6324 uint32 areaId = player->GetAreaId();
6325
6326 if (m_spellInfo->Effects[effIndex].MiscValue)
6327 areaId = m_spellInfo->Effects[effIndex].MiscValue;
6328
6329 if (m_targets.HasDst())
6330 homeLoc.WorldRelocate(*destTarget);
6331 else
6332 {
6333 homeLoc = player->GetWorldLocation();
6334 }
6335
6336 player->SetHomebind(homeLoc, areaId);
6337
6338 // binding
6339 WorldPacket data(SMSG_BINDPOINTUPDATE, 4 + 4 + 4 + 4 + 4);
6340 data << float(homeLoc.GetPositionX());
6341 data << float(homeLoc.GetPositionY());
6342 data << float(homeLoc.GetPositionZ());
6343 data << uint32(homeLoc.GetMapId());
6344 data << uint32(areaId);
6345 player->SendDirectMessage(&data);
6346
6347 LOG_DEBUG("spells.aura", "EffectBind: New homebind X: {}, Y: {}, Z: {}, MapId: {}, AreaId: {}",
6348 homeLoc.GetPositionX(), homeLoc.GetPositionY(), homeLoc.GetPositionZ(), homeLoc.GetMapId(), areaId);
6349 // zone update
6350 data.Initialize(SMSG_PLAYERBOUND, 8 + 4);
6351 data << m_caster->GetGUID();
6352 data << uint32(areaId);
6353 player->SendDirectMessage(&data);
6354}
@ 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:5607
void SetHomebind(WorldLocation const &loc, uint32 areaId)
Definition: PlayerStorage.cpp:4916

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)
4701{
4703 return;
4704
4706 m_caster->ToPlayer()->SetCanBlock(true);
4707}
void SetCanBlock(bool value)
Definition: Player.cpp:13050

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

◆ EffectCastButtons()

void Spell::EffectCastButtons ( SpellEffIndex  effIndex)

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

6237{
6239 return;
6240
6242 return;
6243
6244 Player* p_caster = m_caster->ToPlayer();
6245 uint32 button_id = m_spellInfo->Effects[effIndex].MiscValue + 132;
6246 uint32 n_buttons = m_spellInfo->Effects[effIndex].MiscValueB;
6247
6248 for (; n_buttons; --n_buttons, ++button_id)
6249 {
6250 ActionButton const* ab = p_caster->GetActionButton(button_id);
6251 if (!ab || ab->GetType() != ACTION_BUTTON_SPELL)
6252 continue;
6253
6256 uint32 spell_id = ab->GetAction();
6257 if (!spell_id)
6258 continue;
6259
6260 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spell_id);
6261 if (!spellInfo)
6262 continue;
6263
6264 if (!p_caster->HasSpell(spell_id) || p_caster->HasSpellCooldown(spell_id))
6265 continue;
6266
6268 continue;
6269
6270 uint32 cost = spellInfo->CalcPowerCost(m_caster, spellInfo->GetSchoolMask(), this);
6271 if (m_caster->GetPower(POWER_MANA) < cost)
6272 continue;
6273
6275 m_caster->CastSpell(m_caster, spell_id, triggerFlags);
6276 }
6277}
@ ACTION_BUTTON_SPELL
Definition: Player.h:230
@ SPELL_ATTR7_CAN_BE_MULTI_CAST
Definition: SharedDefines.h:646
Definition: Player.h:254
uint32 GetAction() const
Definition: Player.h:262
ActionButtonType GetType() const
Definition: Player.h:261
ActionButton const * GetActionButton(uint8 button)
Definition: Player.cpp:5568
bool HasSpell(uint32 spell) const override
Definition: Player.cpp:3831

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

◆ EffectCharge()

void Spell::EffectCharge ( SpellEffIndex  effIndex)
4920{
4922 {
4923 if (!unitTarget)
4924 return;
4925
4926 ObjectGuid targetGUID = ObjectGuid::Empty;
4927 Player* player = m_caster->ToPlayer();
4928 if (player)
4929 {
4930 sScriptMgr->AnticheatSetSkipOnePacketForASH(player, true);
4931 // charge changes fall time
4933
4935 {
4936 targetGUID = unitTarget->GetGUID();
4937 }
4938 }
4939
4940 float speed = G3D::fuzzyGt(m_spellInfo->Speed, 0.0f) ? m_spellInfo->Speed : SPEED_CHARGE;
4941 // Spell is not using explicit target - no generated path
4942 if (!m_preGeneratedPath)
4943 {
4945 m_caster->GetMotionMaster()->MoveCharge(pos.m_positionX, pos.m_positionY, pos.m_positionZ, speed, EVENT_CHARGE, nullptr, false, 0.0f, targetGUID);
4946 }
4947 else
4948 {
4949 m_caster->GetMotionMaster()->MoveCharge(*m_preGeneratedPath, speed, targetGUID);
4950 }
4951
4952 if (player)
4953 {
4954 sScriptMgr->AnticheatSetUnderACKmount(player);
4955 }
4956 }
4957
4959 {
4960 sScriptMgr->AnticheatSetSkipOnePacketForASH(m_caster->ToPlayer(), true);
4961 }
4962}
#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:2809
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:2298
MotionMaster * GetMotionMaster()
Definition: Unit.h:2276
void MoveCharge(float x, float y, float z, float speed=SPEED_CHARGE, uint32 id=EVENT_CHARGE, const Movement::PointsArray *path=nullptr, bool generatePath=false, float orientation=0.0f, ObjectGuid targetGUID=ObjectGuid::Empty)
Definition: MotionMaster.cpp:628

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

◆ EffectChargeDest()

◆ EffectCreateItem()

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

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

◆ EffectCreateItem2()

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

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

◆ EffectCreateRandomItem()

void Spell::EffectCreateRandomItem ( SpellEffIndex  effIndex)
Todo:
: ExecuteLogEffectCreateItem(i, m_spellInfo->Effects[i].ItemType);
1834{
1836 return;
1837
1838 if (!unitTarget)
1839 return;
1840
1841 Player* player = unitTarget->ToPlayer();
1842 if (!player)
1843 {
1844 return;
1845 }
1846
1847 // create some random items
1850}

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

◆ EffectCreateTamedPet()

void Spell::EffectCreateTamedPet ( SpellEffIndex  effIndex)
5858{
5860 return;
5861
5863 return;
5864
5865 uint32 creatureEntry = m_spellInfo->Effects[effIndex].MiscValue;
5866 Pet* pet = unitTarget->CreateTamedPetFrom(creatureEntry, m_spellInfo->Id);
5867 if (!pet)
5868 return;
5869
5870 // add to world
5871 pet->GetMap()->AddToMap(pet->ToCreature(), true);
5872
5873 // unitTarget has pet now
5874 unitTarget->SetMinion(pet, true);
5875
5876 pet->InitTalentForLevel();
5877
5879 {
5882 }
5883}
@ CLASS_HUNTER
Definition: SharedDefines.h:143
void InitTalentForLevel()
Definition: Pet.cpp:2216
void SavePetToDB(PetSaveMode mode)
Definition: Pet.cpp:493
void PetSpellInitialize()
Definition: Player.cpp:9387
void SetMinion(Minion *minion, bool apply)
Definition: Unit.cpp:10679
Pet * CreateTamedPetFrom(Creature *creatureTarget, uint32 spell_id=0)
Definition: Unit.cpp:17605
bool AddToMap(T *, bool checkTransport=false)
Definition: Map.cpp:555

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

◆ EffectDestroyAllTotems()

void Spell::EffectDestroyAllTotems ( SpellEffIndex  effIndex)
5266{
5268 return;
5269
5270 int32 mana = 0;
5271 for (uint8 slot = SUMMON_SLOT_TOTEM; slot < MAX_TOTEM_SLOT; ++slot)
5272 {
5273 if (!m_caster->m_SummonSlot[slot])
5274 continue;
5275
5277 if (totem && totem->IsTotem())
5278 {
5279 uint32 spell_id = totem->GetUInt32Value(UNIT_CREATED_BY_SPELL);
5280 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spell_id);
5281 if (spellInfo)
5282 {
5283 mana += spellInfo->ManaCost;
5285 }
5286 totem->ToTotem()->UnSummon();
5287 }
5288 }
5289 ApplyPct(mana, damage);
5290 if (mana)
5291 m_caster->CastCustomSpell(m_caster, 39104, &mana, nullptr, nullptr, true);
5292}
T ApplyPct(T &base, U pct)
Definition: Util.h:73
@ UNIT_CREATED_BY_SPELL
Definition: UpdateFields.h:138
#define SUMMON_SLOT_TOTEM
Definition: Unit.h:1223
#define MAX_TOTEM_SLOT
Definition: Unit.h:1224
void UnSummon(uint32 msTime=0) override
Definition: Totem.cpp:122
Totem * ToTotem()
Definition: Unit.h:2413
SpellCastResult CastCustomSpell(Unit *victim, uint32 spellId, int32 const *bp0, int32 const *bp1, int32 const *bp2, bool triggered, Item *castItem=nullptr, AuraEffect const *triggeredByAura=nullptr, ObjectGuid originalCaster=ObjectGuid::Empty)
Definition: Unit.cpp:1226
uint32 GetCreateMana() const
Definition: Unit.h:2055
ObjectGuid m_SummonSlot[MAX_SUMMON_SLOT]
Definition: Unit.h:2082
Creature * GetCreature(ObjectGuid const guid)
Definition: Map.cpp:3307
uint32 ManaCostPercentage
Definition: SpellInfo.h:365
uint32 ManaCost
Definition: SpellInfo.h:361

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

◆ EffectDiscoverTaxi()

void Spell::EffectDiscoverTaxi ( SpellEffIndex  effIndex)
5886{
5888 return;
5889
5890 if (!unitTarget)
5891 return;
5892
5893 Player* player = unitTarget->ToPlayer();
5894 if (!player)
5895 {
5896 return;
5897 }
5898
5899 uint32 nodeid = m_spellInfo->Effects[effIndex].MiscValue;
5900 if (sTaxiNodesStore.LookupEntry(nodeid))
5901 player->GetSession()->SendDiscoverNewTaxiNode(nodeid);
5902}
DBCStorage< TaxiNodesEntry > sTaxiNodesStore(TaxiNodesEntryfmt)
void SendDiscoverNewTaxiNode(uint32 nodeid)
Definition: TaxiHandler.cpp:156

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)
4479{
4481 return;
4482
4484 return;
4485
4486 if (Player* caster = m_caster->ToPlayer())
4487 {
4488 caster->UpdateCraftSkill(m_spellInfo->Id);
4489 caster->SendLoot(itemTarget->GetGUID(), LOOT_DISENCHANTING);
4490 }
4491
4492 // item will be removed at disenchanting end
4493}
@ 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)
4557{
4559 return;
4560
4561 if (!unitTarget || !unitTarget->IsPet())
4562 return;
4563
4564 Pet* pet = unitTarget->ToPet();
4565
4566 ExecuteLogEffectUnsummonObject(effIndex, pet);
4568}
@ PET_SAVE_NOT_IN_SLOT
Definition: PetDefines.h:45
void Remove(PetSaveMode mode, bool returnreagent=false)
Definition: Pet.cpp:875
void ExecuteLogEffectUnsummonObject(uint8 effIndex, WorldObject *obj)
Definition: Spell.cpp:5138

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

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)
5171{
5173 return;
5174
5175 if (!unitTarget)
5176 return;
5177
5178 uint32 mechanic = m_spellInfo->Effects[effIndex].MiscValue;
5179
5180 std::queue<std::pair<uint32, ObjectGuid>> dispel_list;
5181
5182 Unit::AuraMap const& auras = unitTarget->GetOwnedAuras();
5183 for (Unit::AuraMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
5184 {
5185 Aura* aura = itr->second;
5187 continue;
5189 {
5190 if ((aura->GetSpellInfo()->GetAllEffectsMechanicMask() & (1 << mechanic)))
5191 {
5192 dispel_list.push(std::make_pair(aura->GetId(), aura->GetCasterGUID()));
5193
5194 // spell only removes 1 bleed effect do not continue
5195 if (m_spellInfo->Effects[effIndex].BasePoints == 1)
5196 {
5197 break;
5198 }
5199 }
5200 }
5201 }
5202
5203 for (; dispel_list.size(); dispel_list.pop())
5204 {
5205 unitTarget->RemoveAura(dispel_list.front().first, dispel_list.front().second, 0, AURA_REMOVE_BY_ENEMY_SPELL);
5206 }
5207
5208 // put in combat
5211}
@ AURA_REMOVE_BY_ENEMY_SPELL
Definition: SpellAuraDefines.h:394
void RemoveAura(AuraApplicationMap::iterator &i, AuraRemoveMode mode=AURA_REMOVE_BY_DEFAULT)
Definition: Unit.cpp:4722
ObjectGuid GetCasterGUID() const
Definition: SpellAuras.h:105
uint32 GetId() const
Definition: SpellAuras.cpp:466
int32 CalcDispelChance(Unit *auraTarget, bool offensive) const
Definition: SpellAuras.cpp:1196

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

◆ EffectDistract()

void Spell::EffectDistract ( SpellEffIndex  effIndex)

@BUG Causes the player to stop moving + interrupts spellcast.

2688{
2690 return;
2691
2692 // Check for possible target
2693 if (!unitTarget || unitTarget->IsEngaged())
2694 return;
2695
2696 // target must be OK to do this
2698 return;
2699
2702}
@ UNIT_STATE_CONFUSED
Definition: Unit.h:336
@ UNIT_STATE_FLEEING
Definition: Unit.h:332
@ UNIT_STATE_STUNNED
Definition: Unit.h:328
float GetAngle(const Position *pos) const
Definition: Position.cpp:77
void SetFacingTo(float ori)
Definition: Unit.cpp:20884
bool IsEngaged() const
Definition: Unit.h:1699
void MoveDistract(uint32 time)
Definition: MotionMaster.cpp:748

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)
2674{
2676 return;
2677
2679}
virtual void SetCanDualWield(bool value)
Definition: Unit.h:1358

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

◆ EffectDuel()

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

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

◆ EffectDummy()

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

◆ EffectDurabilityDamage()

void Spell::EffectDurabilityDamage ( SpellEffIndex  effIndex)
5295{
5297 return;
5298
5299 if (!unitTarget)
5300 return;
5301
5302 Player* player = unitTarget->ToPlayer();
5303 if (!player)
5304 {
5305 return;
5306 }
5307
5308 int32 slot = m_spellInfo->Effects[effIndex].MiscValue;
5309
5310 // -1 means all player equipped items and -2 all items
5311 if (slot < 0)
5312 {
5313 player->DurabilityPointsLossAll(damage, (slot < -1));
5315 return;
5316 }
5317
5318 // invalid slot value
5319 if (slot >= INVENTORY_SLOT_BAG_END)
5320 return;
5321
5322 if (Item* item = player->GetItemByPos(INVENTORY_SLOT_BAG_0, slot))
5323 {
5324 player->DurabilityPointsLoss(item, damage);
5325 ExecuteLogEffectDurabilityDamage(effIndex, unitTarget, item->GetEntry(), slot);
5326 }
5327}
@ INVENTORY_SLOT_BAG_END
Definition: Player.h:701
#define INVENTORY_SLOT_BAG_0
Definition: Player.h:671
Item * GetItemByPos(uint16 pos) const
Definition: PlayerStorage.cpp:469
void DurabilityPointsLossAll(int32 points, bool inventory)
Definition: Player.cpp:4674
void DurabilityPointsLoss(Item *item, int32 points)
Definition: Player.cpp:4700
void ExecuteLogEffectDurabilityDamage(uint8 effIndex, Unit *victim, int32 itemId, int32 slot)
Definition: Spell.cpp:5106

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)
5330{
5332 return;
5333
5334 if (!unitTarget)
5335 return;
5336
5337 Player* player = unitTarget->ToPlayer();
5338 if (!player)
5339 {
5340 return;
5341 }
5342
5343 int32 slot = m_spellInfo->Effects[effIndex].MiscValue;
5344
5345 // FIXME: some spells effects have value -1/-2
5346 // Possibly its mean -1 all player equipped items and -2 all items
5347 if (slot < 0)
5348 {
5349 player->DurabilityLossAll(float(damage) / 100.0f, (slot < -1));
5350 return;
5351 }
5352
5353 // invalid slot value
5354 if (slot >= INVENTORY_SLOT_BAG_END)
5355 return;
5356
5357 if (damage <= 0)
5358 return;
5359
5360 if (Item* item = player->GetItemByPos(INVENTORY_SLOT_BAG_0, slot))
5361 player->DurabilityLoss(item, float(damage) / 100.0f);
5362}
void DurabilityLossAll(double percent, bool inventory)
Definition: Player.cpp:4630
void DurabilityLoss(Item *item, double percent)
Definition: Player.cpp:4656

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

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

◆ EffectEnchantItemPerm()

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

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

◆ EffectEnchantItemPrismatic()

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

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

◆ EffectEnchantItemTmp()

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

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

◆ EffectEnergize()

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

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

◆ EffectEnergizePct()

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

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

◆ EffectEnvironmentalDMG()

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

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

◆ EffectFeedPet()

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

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

◆ EffectForceCast()

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

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

◆ EffectForceDeselect()

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

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

◆ EffectGameObjectDamage()

void Spell::EffectGameObjectDamage ( SpellEffIndex  effIndex)
5930{
5932 return;
5933
5934 if (!gameObjTarget)
5935 return;
5936
5937 Unit* caster = m_originalCaster;
5938 if (!caster)
5939 return;
5940
5941 FactionTemplateEntry const* casterFaction = caster->GetFactionTemplateEntry();
5943 // Do not allow to damage GO's of friendly factions (ie: Wintergrasp Walls/Ulduar Storm Beacons)
5944 if ((casterFaction && targetFaction && !casterFaction->IsFriendlyTo(*targetFaction)) || !targetFaction)
5946}
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:10042
Definition: DBCStructure.h:930
bool IsFriendlyTo(FactionTemplateEntry const &entry) const
Definition: DBCStructure.h:942

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

◆ EffectGameObjectRepair()

void Spell::EffectGameObjectRepair ( SpellEffIndex  effIndex)

◆ EffectGameObjectSetDestructionState()

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

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

◆ EffectHealMaxHealth()

void Spell::EffectHealMaxHealth ( SpellEffIndex  effIndex)
3683{
3685 return;
3686
3687 if (!unitTarget || !unitTarget->IsAlive())
3688 return;
3689
3690 int32 addhealth = 0;
3691
3692 // damage == 0 - heal for caster max health
3693 if (damage == 0)
3694 addhealth = m_caster->GetMaxHealth();
3695 else
3696 addhealth = unitTarget->GetMaxHealth() - unitTarget->GetHealth();
3697
3698 m_healing += addhealth;
3699}
uint32 GetMaxHealth() const
Definition: Unit.h:1455

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

◆ EffectHealMechanical()

void Spell::EffectHealMechanical ( SpellEffIndex  effIndex)

◆ EffectHealPct()

void Spell::EffectHealPct ( SpellEffIndex  effIndex)

◆ EffectHealthLeech()

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

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)
4496{
4498 return;
4499
4500 if (!unitTarget)
4501 return;
4502
4503 Player* player = unitTarget->ToPlayer();
4504 if (!player)
4505 {
4506 return;
4507 }
4508
4509 uint8 currentDrunk = player->GetDrunkValue();
4510 uint8 drunkMod = damage;
4511 if (currentDrunk + drunkMod > 100)
4512 {
4513 currentDrunk = 100;
4514 if (rand_chance() < 25.0f)
4515 player->CastSpell(player, 67468, false); // Drunken Vomit
4516 }
4517 else
4518 currentDrunk += drunkMod;
4519
4520 player->SetDrunkValue(currentDrunk, m_CastItem ? m_CastItem->GetEntry() : 0);
4521}
double rand_chance()
Definition: Random.cpp:83
uint8 GetDrunkValue() const
Definition: Player.h:2135
void SetDrunkValue(uint8 newDrunkValue, uint32 itemId=0)
Definition: Player.cpp:972

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

◆ EffectInstaKill()

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

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

◆ EffectInterruptCast()

void Spell::EffectInterruptCast ( SpellEffIndex  effIndex)
Todo:
: not all spells that used this effect apply cooldown at school spells
3702{
3704 return;
3705
3706 if (!unitTarget || !unitTarget->IsAlive())
3707 return;
3708
3710 // also exist case: apply cooldown to interrupted cast only and to all spells
3711 // there is no CURRENT_AUTOREPEAT_SPELL spells that can be interrupted
3713 {
3715 {
3716 SpellInfo const* curSpellInfo = spell->m_spellInfo;
3717 // check if we can interrupt spell
3718 if ((spell->getState() == SPELL_STATE_CASTING
3719 || (spell->getState() == SPELL_STATE_PREPARING && spell->GetCastTime() > 0.0f))
3723 {
3724 if (m_originalCaster)
3725 {
3727 unitTarget->ProhibitSpellSchool(curSpellInfo->GetSchoolMask(), duration/*spellInfo->GetDuration()*/);
3728 }
3729 ExecuteLogEffectInterruptCast(effIndex, unitTarget, curSpellInfo->Id);
3731 }
3732 }
3733 }
3734}
#define CURRENT_FIRST_NON_MELEE_SPELL
Definition: Unit.h:996
CurrentSpellTypes
Definition: Unit.h:989
@ CURRENT_CHANNELED_SPELL
Definition: Unit.h:992
@ CURRENT_AUTOREPEAT_SPELL
Definition: Unit.h:993
@ 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:4014
int32 CalcSpellDuration(SpellInfo const *spellProto)
Definition: Unit.cpp:14842
virtual void ProhibitSpellSchool(SpellSchoolMask, uint32)
Definition: Unit.h:2062
void ExecuteLogEffectInterruptCast(uint8 effIndex, Unit *victim, uint32 spellId)
Definition: Spell.cpp:5099
uint32 ChannelInterruptFlags
Definition: SpellInfo.h:352
uint32 InterruptFlags
Definition: SpellInfo.h:350

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

◆ EffectJump()

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

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

◆ EffectJumpDest()

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

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

◆ EffectKillCredit()

void Spell::EffectKillCredit ( SpellEffIndex  effIndex)
5722{
5724 return;
5725
5726 if (!unitTarget)
5727 return;
5728
5730 if (!player)
5731 {
5732 return;
5733 }
5734
5735 int32 creatureEntry = m_spellInfo->Effects[effIndex].MiscValue;
5736 if (!creatureEntry)
5737 {
5738 if (m_spellInfo->Id == 42793) // Burn Body
5739 creatureEntry = 24008; // Fallen Combatant
5740 }
5741
5742 if (creatureEntry)
5743 player->RewardPlayerAndGroupAtEvent(creatureEntry, unitTarget);
5744}
void RewardPlayerAndGroupAtEvent(uint32 creature_id, WorldObject *pRewardSource)
Definition: Player.cpp:12650

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

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

◆ EffectKnockBack()

void Spell::EffectKnockBack ( SpellEffIndex  effIndex)
4995{
4997 return;
4998
4999 if (!unitTarget)
5000 return;
5001
5002 // Xinef: allow entry specific spells to skip those checks
5003 if (m_spellInfo->Effects[effIndex].TargetA.GetCheckType() != TARGET_CHECK_ENTRY && m_spellInfo->Effects[effIndex].TargetB.GetCheckType() != TARGET_CHECK_ENTRY)
5004 {
5006 return;
5007
5008 if (unitTarget->GetVehicle())
5009 return;
5010
5011 if (Creature* creatureTarget = unitTarget->ToCreature())
5012 if (creatureTarget->isWorldBoss() || creatureTarget->IsDungeonBoss() || creatureTarget->IsImmuneToKnockback() || unitTarget->ToCreature()->GetCreatureType() == CREATURE_TYPE_GIANT)
5013 return;
5014 }
5015
5016 // Spells with SPELL_EFFECT_KNOCK_BACK(like Thunderstorm) can't knoback target if target has ROOT
5018 return;
5019
5020 // Instantly interrupt non melee spells being casted
5023
5024 float ratio = 0.1f;
5025 float speedxy = float(m_spellInfo->Effects[effIndex].MiscValue) * ratio;
5026 float speedz = float(damage) * ratio;
5027 if (speedxy <= 0.1f && speedz <= 0.1f)
5028 return;
5029
5030 float x, y;
5031 if (m_spellInfo->Effects[effIndex].Effect == SPELL_EFFECT_KNOCK_BACK_DEST)
5032 {
5033 if (m_targets.HasDst())
5034 destTarget->GetPosition(x, y);
5035 else
5036 return;
5037 }
5038 else //if (m_spellInfo->Effects[i].Effect == SPELL_EFFECT_KNOCK_BACK)
5039 {
5040 m_caster->GetPosition(x, y);
5041 }
5042
5043 unitTarget->KnockbackFrom(x, y, speedxy, speedz);
5044
5046 {
5047 sScriptMgr->AnticheatSetUnderACKmount(unitTarget->ToPlayer());
5048 }
5049}
@ 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:4081
uint32 GetCreatureType() const
Definition: Unit.cpp:15168
void KnockbackFrom(float x, float y, float speedXY, float speedZ)
Definition: Unit.cpp:19407

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

◆ EffectLeap()

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

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)
5052{
5054 return;
5055
5056 if (!unitTarget)
5057 return;
5058
5059 float speedxy = m_spellInfo->Effects[effIndex].MiscValue / 10.0f;
5060 float speedz = damage / 10.0f;
5061 //1891: Disengage
5063
5065 {
5066 sScriptMgr->AnticheatSetUnderACKmount(m_caster->ToPlayer());
5067 }
5068
5069 // xinef: changes fall time
5072}
@ SPELLFAMILY_HUNTER
Definition: SharedDefines.h:3537
void JumpTo(float speedXY, float speedZ, bool forward=true)
Definition: Unit.cpp:19779

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

◆ EffectLearnPetSpell()

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

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)
2770{
2772 return;
2773
2775 return;
2776
2777 if (damage < 0)
2778 return;
2779
2780 uint32 skillid = m_spellInfo->Effects[effIndex].MiscValue;
2781 uint16 skillval = unitTarget->ToPlayer()->GetPureSkillValue(skillid);
2782 unitTarget->ToPlayer()->SetSkill(skillid, m_spellInfo->Effects[effIndex].CalcValue(), skillval ? skillval : 1, damage * 75);
2783}
uint16 GetPureSkillValue(uint32 skill) const
Definition: Player.cpp:5432
void SetSkill(uint16 id, uint16 step, uint16 currVal, uint16 maxVal)
Definition: Player.cpp:5244

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

◆ EffectLearnSpell()

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

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

Referenced by EffectLearnPetSpell().

◆ EffectMilling()

void Spell::EffectMilling ( SpellEffIndex  effIndex)
5535{
5537 return;
5538
5540 return;
5541
5542 Player* p_caster = m_caster->ToPlayer();
5544 return;
5545
5546 if (itemTarget->GetCount() < 5)
5547 return;
5548
5549 if (sWorld->getBoolConfig(CONFIG_SKILL_MILLING))
5550 {
5551 uint32 SkillValue = p_caster->GetPureSkillValue(SKILL_INSCRIPTION);
5552 uint32 reqSkillValue = itemTarget->GetTemplate()->RequiredSkillRank;
5553 p_caster->UpdateGatherSkill(SKILL_INSCRIPTION, SkillValue, reqSkillValue);
5554 }
5555
5557}
@ LOOT_MILLING
Definition: LootMgr.h:88
@ CONFIG_SKILL_MILLING
Definition: IWorld.h:97
void SendLoot(ObjectGuid guid, LootType loot_type)
Definition: Player.cpp:7686
bool UpdateGatherSkill(uint32 SkillId, uint32 SkillValue, uint32 RedLevel, uint32 Multiplicator=1)
Definition: PlayerUpdates.cpp:723

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

◆ EffectModifyThreatPercent()

void Spell::EffectModifyThreatPercent ( SpellEffIndex  effIndex)
5365{
5367 return;
5368
5369 if (!unitTarget)
5370 return;
5371
5373}
void ModifyThreatByPercent(Unit *victim, int32 percent)
Definition: ThreatMgr.cpp:508
ThreatMgr & GetThreatMgr()
Definition: Unit.h:2159

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

◆ EffectNULL()

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

References LOG_DEBUG.

Referenced by EffectPull().

◆ EffectOpenLock()

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

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

◆ EffectParry()

void Spell::EffectParry ( SpellEffIndex  effIndex)
4692{
4694 return;
4695
4697 m_caster->ToPlayer()->SetCanParry(true);
4698}
void SetCanParry(bool value)
Definition: Player.cpp:13041

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

◆ EffectPersistentAA()

void Spell::EffectPersistentAA ( SpellEffIndex  effIndex)
1853{
1855 return;
1856
1857 if (!m_spellAura)
1858 {
1860 float radius = m_spellInfo->Effects[effIndex].CalcRadius(caster);
1861
1862 // Caster not in world, might be spell triggered from aura removal
1863 if (!caster->IsInWorld() || !caster->FindMap() || !ObjectAccessor::GetUnit(*caster, caster->GetGUID())) // pussywizard: temporary crash fix (FindMap and GetUnit are mine)
1864 return;
1865 DynamicObject* dynObj = new DynamicObject(false);
1866 if (!dynObj->CreateDynamicObject(caster->GetMap()->GenerateLowGuid<HighGuid::DynamicObject>(), caster, m_spellInfo->Id, *destTarget, radius, DYNAMIC_OBJECT_AREA_SPELL))
1867 {
1868 delete dynObj;
1869 return;
1870 }
1871
1873 {
1874 m_spellAura = aura;
1877 }
1878 else
1879 return;
1880 }
1881
1884}
@ DYNAMIC_OBJECT_AREA_SPELL
Definition: DynamicObject.h:30
#define MAX_EFFECT_MASK
Definition: DBCStructure.h:1636
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)
6138{
6140 return;
6141
6142 if (!unitTarget)
6143 return;
6144
6145 Player* player = unitTarget->ToPlayer();
6146 if (!player)
6147 {
6148 return;
6149 }
6150
6151 uint32 soundid = m_spellInfo->Effects[effIndex].MiscValue;
6152
6153 if (!sSoundEntriesStore.LookupEntry(soundid))
6154 {
6155 LOG_ERROR("spells.effect", "EffectPlayMusic: Sound (Id: {}) not exist in spell {}.", soundid, m_spellInfo->Id);
6156 return;
6157 }
6158
6160}
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)
6191{
6193 return;
6194
6195 if (!unitTarget)
6196 return;
6197
6198 Player* player = unitTarget->ToPlayer();
6199 if (!player)
6200 {
6201 return;
6202 }
6203
6204 switch (m_spellInfo->Id)
6205 {
6206 case 58730: // Restricted Flight Area
6207 case 58600: // Restricted Flight Area
6209 break;
6210 default:
6211 break;
6212 }
6213
6214 uint32 soundId = m_spellInfo->Effects[effIndex].MiscValue;
6215
6216 if (!sSoundEntriesStore.LookupEntry(soundId))
6217 {
6218 LOG_ERROR("spells.effect", "EffectPlayerSound: Sound (Id: {}) not exist in spell {}.", soundId, m_spellInfo->Id);
6219 return;
6220 }
6221
6222 player->PlayDirectSound(soundId, player);
6223}
@ LANG_ZONE_NOFLYZONE
Definition: Language.h:736
void PlayDirectSound(uint32 sound_id, Player *target=nullptr)
Definition: Object.cpp:2878
void SendNotification(const char *format,...) ATTR_PRINTF(2
Definition: WorldSession.cpp:785

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

◆ EffectPowerBurn()

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

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

◆ EffectPowerDrain()

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

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

◆ EffectProficiency()

void Spell::EffectProficiency ( SpellEffIndex  effIndex)
2310{
2312 return;
2313
2315 return;
2316 Player* p_target = m_caster->ToPlayer();
2317
2319 if (m_spellInfo->EquippedItemClass == ITEM_CLASS_WEAPON && !(p_target->GetWeaponProficiency() & subClassMask))
2320 {
2321 p_target->AddWeaponProficiency(subClassMask);
2323 }
2324 if (m_spellInfo->EquippedItemClass == ITEM_CLASS_ARMOR && !(p_target->GetArmorProficiency() & subClassMask))
2325 {
2326 p_target->AddArmorProficiency(subClassMask);
2328 }
2329}
uint32 GetArmorProficiency() const
Definition: Player.h:1341
void SendProficiency(ItemClass itemClass, uint32 itemSubclassMask)
Definition: Player.cpp:10020
uint32 GetWeaponProficiency() const
Definition: Player.h:1340
void AddArmorProficiency(uint32 newflag)
Definition: Player.h:1339
void AddWeaponProficiency(uint32 newflag)
Definition: Player.h:1338
int32 EquippedItemSubClassMask
Definition: SpellInfo.h:374

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

◆ EffectProspecting()

void Spell::EffectProspecting ( SpellEffIndex  effIndex)

◆ EffectPull()

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

References EffectNULL().

◆ EffectPullTowards()

void Spell::EffectPullTowards ( SpellEffIndex  effIndex)
5137{
5139 return;
5140
5141 if (!unitTarget)
5142 return;
5143
5144 Position pos;
5145 if (m_spellInfo->Effects[effIndex].Effect == SPELL_EFFECT_PULL_TOWARDS_DEST)
5146 {
5147 if (m_targets.HasDst())
5148 pos.Relocate(*destTarget);
5149 else
5150 return;
5151 }
5152 else //if (m_spellInfo->Effects[i].Effect == SPELL_EFFECT_PULL_TOWARDS)
5153 {
5154 // Xinef: Increase Z position a little bit, should protect from falling through textures
5156 }
5157
5158 float speedXY = float(m_spellInfo->Effects[effIndex].MiscValue) ? float(m_spellInfo->Effects[effIndex].MiscValue) * 0.1f : 30.f;
5159 float speedZ = unitTarget->GetDistance(pos) / speedXY * 0.5f * Movement::gravity;
5160
5161 unitTarget->GetMotionMaster()->MoveJump(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), speedXY, speedZ);
5162
5164 {
5165 sScriptMgr->AnticheatSetSkipOnePacketForASH(unitTarget->ToPlayer(), true);
5166 sScriptMgr->AnticheatSetUnderACKmount(unitTarget->ToPlayer());
5167 }
5168}
@ 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(), Object::GetTypeId(), Movement::gravity, SpellCastTargets::HasDst(), m_caster, m_spellInfo, m_targets, MotionMaster::MoveJump(), Position::Relocate(), SPELL_EFFECT_HANDLE_HIT_TARGET, SPELL_EFFECT_PULL_TOWARDS_DEST, sScriptMgr, Object::ToPlayer(), TYPEID_PLAYER, and unitTarget.

◆ EffectQuestClear()

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

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

◆ EffectQuestComplete()

void Spell::EffectQuestComplete ( SpellEffIndex  effIndex)
4751{
4753 return;
4754
4755 if (!unitTarget)
4756 return;
4757
4758 Player* player = unitTarget->ToPlayer();
4759 if (!player)
4760 {
4761 return;
4762 }
4763
4764 uint32 questId = m_spellInfo->Effects[effIndex].MiscValue;
4765 if (questId)
4766 {
4767 Quest const* quest = sObjectMgr->GetQuestTemplate(questId);
4768 if (!quest)
4769 return;
4770
4771 uint16 logSlot = player->FindQuestSlot(questId);
4772 if (logSlot < MAX_QUEST_LOG_SIZE)
4773 player->AreaExploredOrEventHappens(questId);
4774 else if (player->CanTakeQuest(quest, false)) // never rewarded before
4775 player->CompleteQuest(questId); // quest not in log - for internal use
4776 }
4777}
uint16 FindQuestSlot(uint32 quest_id) const
Definition: PlayerQuest.cpp:1768
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:1777

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)
5747{
5749 return;
5750
5751 if (!unitTarget)
5752 return;
5753
5754 if (Player* player = unitTarget->ToPlayer())
5755 {
5756 player->FailQuest(m_spellInfo->Effects[effIndex].MiscValue);
5757 }
5758}

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

◆ EffectQuestStart()

void Spell::EffectQuestStart ( SpellEffIndex  effIndex)
5761{
5763 return;
5764
5765 if (!unitTarget)
5766 return;
5767
5768 Player* player = unitTarget->ToPlayer();
5769 if (!player)
5770 return;
5771
5772 if (Quest const* quest = sObjectMgr->GetQuestTemplate(m_spellInfo->Effects[effIndex].MiscValue))
5773 {
5774 if (!player->CanTakeQuest(quest, false))
5775 return;
5776
5777 if (quest->IsAutoAccept() && player->CanAddQuest(quest, false))
5778 player->AddQuestAndCheckCompletion(quest, player);
5779
5780 player->PlayerTalkClass->SendQuestGiverQuestDetails(quest, player->GetGUID(), true);
5781 }
5782}
void SendQuestGiverQuestDetails(Quest const *quest, ObjectGuid npcGUID, bool activateAccept) const
Definition: GossipDef.cpp:386
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:2201

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)
6280{
6282 return;
6283
6285 return;
6286
6287 Player* player = m_caster->ToPlayer();
6288
6289 if (!player)
6290 return;
6291
6292 uint32 item_id = m_spellInfo->Effects[EFFECT_0].ItemType;
6293
6294 ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(item_id);
6295 if (!pProto)
6296 {
6297 player->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, nullptr, nullptr);
6298 return;
6299 }
6300
6301 if (Item* pItem = player->GetItemByEntry(item_id))
6302 {
6303 for (int x = 0; x < MAX_ITEM_PROTO_SPELLS; ++x)
6304 pItem->SetSpellCharges(x, pProto->Spells[x].SpellCharges);
6305 pItem->SetState(ITEM_CHANGED, player);
6306 }
6307}

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

◆ EffectRedirectThreat()

void Spell::EffectRedirectThreat ( SpellEffIndex  effIndex)
5921{
5923 return;
5924
5925 if (unitTarget)
5927}
void SetRedirectThreat(ObjectGuid guid, uint32 pct)
Definition: Unit.h:2358

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

◆ EffectRemoveAura()

void Spell::EffectRemoveAura ( SpellEffIndex  effIndex)
6226{
6228 return;
6229
6230 if (!unitTarget)
6231 return;
6232 // there may be need of specifying casterguid of removed auras
6233 unitTarget->RemoveAurasDueToSpell(m_spellInfo->Effects[effIndex].TriggerSpell);
6234}

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

◆ EffectRenamePet()

void Spell::EffectRenamePet ( SpellEffIndex  effIndex)
6126{
6128 return;
6129
6132 return;
6133
6135}
@ UNIT_FIELD_BYTES_2
Definition: UpdateFields.h:161
@ UNIT_CAN_BE_RENAMED
Definition: Unit.h:149
void SetByteFlag(uint16 index, uint8 offset, uint8 newFlag)
Definition: Object.cpp:911
PetType getPetType() const
Definition: Pet.h:51

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

◆ EffectReputation()

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

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

◆ EffectResurrect()

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

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
5214{
5216 return;
5217
5218 if (damage < 0)
5219 return;
5220
5221 Player* player = m_caster->ToPlayer();
5222 if (!player)
5223 {
5224 return;
5225 }
5226
5227 Pet* pet = player->GetPet();
5228 if (!pet)
5229 {
5230 // Position passed to SummonPet is irrelevant with current implementation,
5231 // pet will be relocated without using these coords in Pet::LoadPetFromDB
5232 player->SummonPet(0, 0.0f, 0.0f, 0.0f, 0.0f, SUMMON_PET, 0s, damage);
5233 return;
5234 }
5235
5237 if (pet->IsAlive())
5238 {
5239 return;
5240 }
5241
5242 // Reposition the pet's corpse before reviving so as not to grab aggro
5243 // We can use a different, more accurate version of GetClosePoint() since we have a pet
5244 float x, y, z; // Will be used later to reposition the pet if we have one
5245 player->GetClosePoint(x, y, z, pet->GetCombatReach(), PET_FOLLOW_DIST, pet->GetFollowAngle());
5246 pet->NearTeleportTo(x, y, z, player->GetOrientation());
5247 pet->Relocate(x, y, z, player->GetOrientation()); // This is needed so SaveStayPosition() will get the proper coords.
5250 pet->setDeathState(DeathState::Alive);
5251 pet->ClearUnitState(uint32(UNIT_STATE_ALL_STATE & ~(UNIT_STATE_POSSESSED))); // xinef: just in case
5253 pet->SetDisplayId(pet->GetNativeDisplayId());
5254
5255 // xinef: restore movement
5256 if (auto ci = pet->GetCharmInfo())
5257 {
5258 ci->SetIsAtStay(false);
5259 ci->SetIsFollowing(false);
5260 }
5261
5263}
#define PET_FOLLOW_DIST
Definition: PetDefines.h:198
@ SUMMON_PET
Definition: PetDefines.h:31
@ UNIT_STATE_POSSESSED
Definition: Unit.h:341
@ UNIT_STATE_ALL_STATE
Definition: Unit.h:373
@ 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:2687
void setDeathState(DeathState s, bool despawn=false) override
Definition: Pet.cpp:617
void SetDisplayId(uint32 modelId) override
Definition: Pet.cpp:2415
Pet * SummonPet(uint32 entry, float x, float y, float z, float ang, PetType petType, Milliseconds duration=0s, uint32 healthPct=0)
Definition: Player.cpp:8842
void ReplaceAllDynamicFlags(uint32 flag) override
Definition: Unit.h:1338
void SetHealth(uint32 val)
Definition: Unit.cpp:15464
uint32 GetNativeDisplayId() const
Definition: Unit.h:2184
void RemoveUnitFlag(UnitFlags flags)
Definition: Unit.h:1496

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

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

◆ EffectSchoolDMG()

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

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

◆ EffectScriptEffect()

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

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

◆ EffectSelfResurrect()

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

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

◆ EffectSendEvent()

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

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

◆ EffectSendTaxi()

void Spell::EffectSendTaxi ( SpellEffIndex  effIndex)
5123{
5125 return;
5126
5127 if (!unitTarget)
5128 return;
5129
5130 if (Player* player = unitTarget->ToPlayer())
5131 {
5132 player->ActivateTaxiPathTo(m_spellInfo->Effects[effIndex].MiscValue, m_spellInfo->Id);
5133 }
5134}

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

◆ EffectSkill()

void Spell::EffectSkill ( SpellEffIndex  effIndex)
5560{
5562 return;
5563
5564 LOG_DEBUG("spells.aura", "WORLD: SkillEFFECT");
5565}

References effectHandleMode, LOG_DEBUG, and SPELL_EFFECT_HANDLE_HIT.

◆ EffectSkinning()

void Spell::EffectSkinning ( SpellEffIndex  effIndex)
4893{
4895 return;
4896
4898 return;
4900 return;
4901
4902 Creature* creature = unitTarget->ToCreature();
4903 int32 targetLevel = creature->GetLevel();
4904
4905 uint32 skill = creature->GetCreatureTemplate()->GetRequiredLootSkill();
4906
4910
4911 int32 reqValue = targetLevel < 10 ? 0 : targetLevel < 20 ? (targetLevel - 10) * 10 : targetLevel * 5;
4912
4913 int32 skillValue = m_caster->ToPlayer()->GetPureSkillValue(skill);
4914
4915 // Double chances for elites
4916 m_caster->ToPlayer()->UpdateGatherSkill(skill, skillValue, reqValue, creature->isElite() ? 2 : 1);
4917}
@ UNIT_DYNFLAG_LOOTABLE
Definition: SharedDefines.h:3121
bool isElite() const
Definition: Creature.h:107
virtual void SetDynamicFlag(uint32 flag)
Definition: Object.h:117

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

◆ EffectSkinPlayerCorpse()

void Spell::EffectSkinPlayerCorpse ( SpellEffIndex  effIndex)
5591{
5593 return;
5594
5595 LOG_DEBUG("spells.aura", "Effect: SkinPlayerCorpse");
5597 return;
5598
5600}
void RemovedInsignia(Player *looterPlr)
Definition: Player.cpp:7647

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

◆ EffectSpecCount()

void Spell::EffectSpecCount ( SpellEffIndex  effIndex)
6163{
6165 return;
6166
6167 if (!unitTarget)
6168 return;
6169
6170 if (Player* player = unitTarget->ToPlayer())
6171 {
6172 player->UpdateSpecCount(damage);
6173 }
6174}

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

◆ EffectSpiritHeal()

void Spell::EffectSpiritHeal ( SpellEffIndex  effIndex)
5572{
5574 return;
5575
5576 /*
5577 if (unitTarget->GetTypeId() != TYPEID_PLAYER)
5578 return;
5579 if (!unitTarget->IsInWorld())
5580 return;
5581
5582 //m_spellInfo->Effects[i].BasePoints; == 99 (percent?)
5583 //unitTarget->ToPlayer()->setResurrect(m_caster->GetGUID(), unitTarget->GetPositionX(), unitTarget->GetPositionY(), unitTarget->GetPositionZ(), unitTarget->GetMaxHealth(), unitTarget->GetMaxPower(POWER_MANA));
5584 unitTarget->ToPlayer()->ResurrectPlayer(1.0f);
5585 unitTarget->ToPlayer()->SpawnCorpseBones();
5586 */
5587}

References effectHandleMode, and SPELL_EFFECT_HANDLE_HIT_TARGET.

◆ EffectStealBeneficialBuff()

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

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

◆ EffectStuck()

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

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

◆ EffectSummonChangeItem()

void Spell::EffectSummonChangeItem ( SpellEffIndex  effIndex)
2201{
2203 return;
2204
2206 return;
2207
2208 Player* player = m_caster->ToPlayer();
2209
2210 // applied only to using item
2211 if (!m_CastItem)
2212 return;
2213
2214 // ... only to item in own inventory/bank/equip_slot
2215 if (m_CastItem->GetOwnerGUID() != player->GetGUID())
2216 return;
2217
2218 uint32 newitemid = m_spellInfo->Effects[effIndex].ItemType;
2219 if (!newitemid)
2220 return;
2221
2222 uint16 pos = m_CastItem->GetPos();
2223
2224 Item* pNewItem = Item::CreateItem(newitemid, 1, player);
2225 if (!pNewItem)
2226 return;
2227
2228 // Client-side enchantment durations update
2230
2234
2236 {
2238 player->DurabilityLoss(pNewItem, lossPercent);
2239 }
2240
2241 if (player->IsInventoryPos(pos))
2242 {
2243 ItemPosCountVec dest;
2244 InventoryResult msg = player->CanStoreItem(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->StoreItem(dest, pNewItem, true);
2257 player->ItemAddedQuestCheck(pNewItem->GetEntry(), 1);
2258 return;
2259 }
2260 }
2261 else if (player->IsBankPos(pos))
2262 {
2263 ItemPosCountVec dest;
2264 uint8 msg = player->CanBankItem(m_CastItem->GetBagSlot(), m_CastItem->GetSlot(), dest, pNewItem, true);
2265 if (msg == EQUIP_ERR_OK)
2266 {
2267 player->DestroyItem(m_CastItem->GetBagSlot(), m_CastItem->GetSlot(), true);
2268
2269 // prevent crash at access and unexpected charges counting with item update queue corrupt
2271 m_targets.SetItemTarget(nullptr);
2272
2273 m_CastItem = nullptr;
2275
2276 player->BankItem(dest, pNewItem, true);
2277 return;
2278 }
2279 }
2280 else if (player->IsEquipmentPos(pos))
2281 {
2282 uint16 dest;
2283
2284 player->DestroyItem(m_CastItem->GetBagSlot(), m_CastItem->GetSlot(), true);
2285
2286 uint8 msg = player->CanEquipItem(m_CastItem->GetSlot(), dest, pNewItem, true);
2287
2288 if (msg == EQUIP_ERR_OK || msg == EQUIP_ERR_CANT_DO_RIGHT_NOW)
2289 {
2291
2292 // prevent crash at access and unexpected charges counting with item update queue corrupt
2294 m_targets.SetItemTarget(nullptr);
2295
2296 m_CastItem = nullptr;
2298
2299 player->EquipItem(dest, pNewItem, true);
2300 player->AutoUnequipOffhandIfNeed();
2301 return;
2302 }
2303 }
2304
2305 // fail
2306 delete pNewItem;
2307}
@ EQUIP_ERR_CANT_DO_RIGHT_NOW
Definition: Item.h:80
@ ITEM_FIELD_DURABILITY
Definition: UpdateFields.h:69
@ ITEM_FIELD_MAXDURABILITY
Definition: UpdateFields.h:70
uint8 GetSlot() const
Definition: Item.h:272
static Item * CreateItem(uint32 item, uint32 count, Player const *player=nullptr, bool clone=false, uint32 randomPropertyId=0)
Definition: Item.cpp:1088
uint32 GetEnchantmentDuration(EnchantmentSlot slot) const
Definition: Item.h:296
uint16 GetPos() const
Definition: Item.h:276
uint32 GetEnchantmentCharges(EnchantmentSlot slot) const
Definition: Item.h:297
uint8 GetBagSlot() const
Definition: Item.cpp:785
void Clear()
Definition: ObjectGuid.h:140
static bool IsEquipmentPos(uint16 pos)
Definition: Player.h:1244
InventoryResult CanEquipItem(uint8 slot, uint16 &dest, Item *pItem, bool swap, bool not_loading=true) const
Definition: PlayerStorage.cpp:1833
Item * BankItem(ItemPosCountVec const &dest, Item *pItem, bool update)
Definition: Player.h:1313
InventoryResult CanStoreItem(uint8 bag, uint8 slot, ItemPosCountVec &dest, Item *pItem, bool swap=false) const
Definition: Player.h:1264
void UpdateEnchantmentDurations()
Definition: PlayerStorage.cpp:4754
Item * StoreItem(ItemPosCountVec const &pos, Item *pItem, bool update)
Definition: PlayerStorage.cpp:2596
void DestroyItem(uint8 bag, uint8 slot, bool update)
Definition: PlayerStorage.cpp:3045
static bool IsInventoryPos(uint16 pos)
Definition: Player.h:1242
void AutoUnequipOffhandIfNeed(bool force=false)
Definition: Player.cpp:12384
Item * EquipItem(uint16 pos, Item *pItem, bool update)
Definition: PlayerStorage.cpp:2749
InventoryResult CanBankItem(uint8 bag, uint8 slot, ItemPosCountVec &dest, Item *pItem, bool swap, bool not_loading=true) const
Definition: PlayerStorage.cpp:2052
void ItemAddedQuestCheck(uint32 entry, uint32 count)
Definition: PlayerQuest.cpp:1821
static bool IsBankPos(uint16 pos)
Definition: Player.h:1247

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

◆ EffectSummonCritter()

void Spell::EffectSummonCritter ( SpellEffIndex  effIndex)

◆ EffectSummonObject()

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

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

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

◆ EffectSummonPet()

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

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

◆ EffectSummonPlayer()

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

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)
6357{
6359 return;
6360
6362 return;
6363
6364 if (!unitTarget)
6365 return;
6366
6367 Player* player = unitTarget->ToPlayer();
6368 if (!player)
6369 {
6370 return;
6371 }
6372
6373 float x, y, z;
6374 m_caster->GetPosition(x, y, z);
6376 WorldPacket data(SMSG_SUMMON_REQUEST, 8 + 4 + 4);
6377 data << m_caster->GetGUID();
6378 data << uint32(m_caster->GetZoneId());
6379 data << uint32(MAX_PLAYER_SUMMON_DELAY * IN_MILLISECONDS); // auto decline after msecs
6380 player->GetSession()->SendPacket(&data);
6381}

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

◆ EffectSummonType()

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

References Unit::CastCustomSpell(), Unit::CastSpell(), SummonPropertiesEntry::Category, MotionMaster::Clear(), Unit::CountPctFromMaxHealth(), damage, destTarget, effectHandleMode, SpellInfo::Effects, ExecuteLogEffectSummonObject(), SummonPropertiesEntry::Flags, Creature::GetCreatureTemplate(), 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)
3083{
3085 return;
3086
3087 if (m_caster->GetPetGUID())
3088 return;
3089
3090 if (!unitTarget)
3091 return;
3092
3094 return;
3095
3096 Creature* creatureTarget = unitTarget->ToCreature();
3097
3098 if (creatureTarget->IsPet())
3099 return;
3100
3101 if (m_caster->getClass() != CLASS_HUNTER)
3102 return;
3103
3104 // cast finish successfully
3105 //SendChannelUpdate(0);
3106 finish();
3107
3108 Pet* pet = m_caster->CreateTamedPetFrom(creatureTarget, m_spellInfo->Id);
3109 if (!pet) // in very specific state like near world end/etc.
3110 return;
3111
3112 // "kill" original creature
3113 creatureTarget->DespawnOrUnsummon();
3114
3115 uint8 level = (creatureTarget->GetLevel() < (m_caster->GetLevel() - 5)) ? (m_caster->GetLevel() - 5) : creatureTarget->GetLevel();
3116
3117 // prepare visual effect for levelup
3118 pet->SetUInt32Value(UNIT_FIELD_LEVEL, level - 1);
3119
3120 // add to world
3121 pet->GetMap()->AddToMap(pet->ToCreature(), true);
3122
3123 // visual effect for levelup
3124 pet->SetUInt32Value(UNIT_FIELD_LEVEL, level);
3125
3126 // caster have pet now
3127 m_caster->SetMinion(pet, true);
3128
3129 pet->InitTalentForLevel();
3130
3132 {
3135 }
3136}
@ UNIT_FIELD_LEVEL
Definition: UpdateFields.h:114

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

◆ EffectTaunt()

void Spell::EffectTaunt ( SpellEffIndex  effIndex)
3279{
3281 return;
3282
3283 if (!unitTarget)
3284 return;
3285
3286 // xinef: Hand of Reckoning, cast before checing canhavethreatlist. fixes damage against pets
3287 if (m_spellInfo->Id == 62124 && unitTarget->GetVictim() != m_caster)
3288 {
3289 m_caster->CastSpell(unitTarget, 67485, true);
3291 }
3292
3293 // this effect use before aura Taunt apply for prevent taunt already attacking target
3294 // for spell as marked "non effective at already attacking target"
3296 {
3298 return;
3299 }
3300
3302 {
3303 // Also use this effect to set the taunter's threat to the taunted creature's highest value
3304 float myThreat = unitTarget->GetThreatMgr().GetThreat(m_caster);
3306 if (topThreat > myThreat)
3307 unitTarget->GetThreatMgr().DoAddThreat(m_caster, topThreat - myThreat);
3308
3309 //Set aggro victim to caster
3311 unitTarget->GetThreatMgr().setCurrentVictim(forcedVictim);
3312 }
3313}
@ 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:14600

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

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

◆ EffectTeleUnitsFaceCaster()

◆ EffectThreat()

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

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)
5905{
5907 return;
5908
5910 {
5911 if (Aura* aur = m_caster->GetAura(49152))
5912 aur->RecalculateAmountOfEffects();
5913 else
5914 m_caster->CastSpell(unitTarget, 49152, true); // damage reduction
5915
5917 }
5918}
void SetCanTitanGrip(bool value)
Definition: Player.cpp:13059

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

◆ EffectTradeSkill()

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

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

◆ EffectTransmitted()

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

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

◆ EffectTriggerMissileSpell()

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

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

◆ EffectTriggerRitualOfSummoning()

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

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

◆ EffectTriggerSpell()

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

◆ EffectUnlearnSpecialization()

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

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)
2744{
2746 return;
2747
2749 return;
2750
2751 if (ObjectGuid guid = m_caster->GetGUID()) // the trainer is the caster
2753}
void SendTalentWipeConfirm(ObjectGuid guid)
Definition: Player.cpp:8791

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

◆ EffectUnused()

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

◆ EffectWeaponDmg()

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

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

◆ ExecuteLogEffectCreateItem()

void Spell::ExecuteLogEffectCreateItem ( uint8  effIndex,
uint32  entry 
)
5121{
5122 InitEffectExecuteData(effIndex);
5123 *m_effectExecuteData[effIndex] << uint32(entry);
5124}
void InitEffectExecuteData(uint8 effIndex)
Definition: Spell.cpp:8432

References InitEffectExecuteData(), and m_effectExecuteData.

Referenced by EffectCreateItem().

◆ ExecuteLogEffectDestroyItem()

void Spell::ExecuteLogEffectDestroyItem ( uint8  effIndex,
uint32  entry 
)
5127{
5128 InitEffectExecuteData(effIndex);
5129 *m_effectExecuteData[effIndex] << uint32(entry);
5130}

References InitEffectExecuteData(), and m_effectExecuteData.

Referenced by EffectFeedPet().

◆ ExecuteLogEffectDurabilityDamage()

void Spell::ExecuteLogEffectDurabilityDamage ( uint8  effIndex,
Unit victim,
int32  itemId,
int32  slot 
)
5107{
5108 InitEffectExecuteData(effIndex);
5109 *m_effectExecuteData[effIndex] << victim->GetPackGUID();
5110 *m_effectExecuteData[effIndex] << int32(itemId);
5111 *m_effectExecuteData[effIndex] << int32(slot);
5112}

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

Referenced by EffectDurabilityDamage().

◆ ExecuteLogEffectExtraAttacks()

void Spell::ExecuteLogEffectExtraAttacks ( uint8  effIndex,
Unit victim,
uint32  attCount 
)
5093{
5094 InitEffectExecuteData(effIndex);
5095 *m_effectExecuteData[effIndex] << victim->GetPackGUID();
5096 *m_effectExecuteData[effIndex] << uint32(attCount);
5097}

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

Referenced by EffectAddExtraAttacks().

◆ ExecuteLogEffectInterruptCast()

void Spell::ExecuteLogEffectInterruptCast ( uint8  effIndex,
Unit victim,
uint32  spellId 
)
5100{
5101 InitEffectExecuteData(effIndex);
5102 *m_effectExecuteData[effIndex] << victim->GetPackGUID();
5103 *m_effectExecuteData[effIndex] << uint32(spellId);
5104}

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

Referenced by EffectInterruptCast().

◆ ExecuteLogEffectOpenLock()

void Spell::ExecuteLogEffectOpenLock ( uint8  effIndex,
Object obj 
)
5115{
5116 InitEffectExecuteData(effIndex);
5117 *m_effectExecuteData[effIndex] << obj->GetPackGUID();
5118}

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

Referenced by EffectOpenLock().

◆ ExecuteLogEffectResurrect()

void Spell::ExecuteLogEffectResurrect ( uint8  effIndex,
Unit target 
)
5145{
5146 InitEffectExecuteData(effIndex);
5147 *m_effectExecuteData[effIndex] << target->GetPackGUID();
5148}

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 
)
5084{
5085 InitEffectExecuteData(effIndex);
5086 *m_effectExecuteData[effIndex] << target->GetPackGUID();
5087 *m_effectExecuteData[effIndex] << uint32(powerTaken);
5088 *m_effectExecuteData[effIndex] << uint32(PowerType);
5089 *m_effectExecuteData[effIndex] << float(gainMultiplier);
5090}

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 
)
5139{
5140 InitEffectExecuteData(effIndex);
5141 *m_effectExecuteData[effIndex] << obj->GetPackGUID();
5142}

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

Referenced by EffectDismissPet().

◆ finish()

void Spell::finish ( bool  ok = true)
4464{
4465 if (!m_caster)
4466 return;
4467
4469 return;
4471
4472 if (m_spellInfo->IsChanneled())
4474
4477
4478 // Unsummon summon as possessed creatures on spell cancel
4480 {
4481 if (Unit* charm = m_caster->GetCharm())
4482 if (charm->GetTypeId() == TYPEID_UNIT
4483 && charm->ToCreature()->HasUnitTypeMask(UNIT_MASK_PUPPET)
4484 && charm->GetUInt32Value(UNIT_CREATED_BY_SPELL) == m_spellInfo->Id)
4485 ((Puppet*)charm)->UnSummon();
4486 }
4487
4488 if (Creature* creatureCaster = m_caster->ToCreature())
4489 creatureCaster->ReleaseFocus(this);
4490
4491 if (!ok)
4492 {
4494 {
4495 // Xinef: Restore spell mods in case of fail cast
4497
4498 // Xinef: Reset cooldown event in case of fail cast
4501 }
4502 return;
4503 }
4504
4505 // pussywizard:
4508
4510 {
4511 // Unsummon statue
4513 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spell);
4514 if (spellInfo && spellInfo->SpellIconID == 2056)
4515 {
4516 LOG_DEBUG("spells.aura", "Statue {} is unsummoned in spell {} finish", m_caster->GetGUID().ToString(), m_spellInfo->Id);
4517 m_caster->setDeathState(DeathState::JustDied);
4518 return;
4519 }
4520 }
4521
4522 // potions disabled by client, send event "not in combat" if need
4525
4526 // Take mods after trigger spell (needed for 14177 to affect 48664)
4527 // mods are taken only on succesfull cast and independantly from targets of the spell
4528 if (Player* player = m_caster->GetSpellModOwner())
4529 player->RemoveSpellMods(this);
4530
4531 // xinef: clear reactive auras states after spell cast
4534
4535 // Stop Attack for some spells
4538}
@ UNIT_MASK_PUPPET
Definition: Unit.h:681
@ ENCOUNTER_CREDIT_CAST_SPELL
Definition: Map.h:309
@ SPELL_ATTR0_CU_ENCOUNTER_REWARD
Definition: SpellInfo.h:206
@ 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:1501
virtual void setDeathState(DeathState s, bool despawn=false)
Definition: Unit.cpp:14538
void UpdateInterruptMask()
Definition: Unit.cpp:759
void ModifyAuraState(AuraStateType flag, bool apply)
Definition: Unit.cpp:10496
void UpdateEncounterState(EncounterCreditType type, uint32 creditEntry, Unit *source)
Definition: Map.cpp:3464

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

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

◆ FinishTargetProcessing()

void Spell::FinishTargetProcessing ( )
protected
8428{
8430}
void SendLogExecute()
Definition: Spell.cpp:5049

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
8891{
8892 std::stringstream sstr;
8893 sstr << std::boolalpha
8894 << "Id: " << GetSpellInfo()->Id << " OriginalCaster: " << m_originalCasterGUID.ToString()
8895 << " State: " << getState();
8896 return sstr.str();
8897}

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

◆ GetDelayMoment()

uint64 Spell::GetDelayMoment ( ) const
inline

◆ GetDelayStart()

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

References m_delayStart.

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

◆ GetDelayTrajectory()

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

References m_delayTrajectory.

◆ GetOriginalCaster()

Unit * Spell::GetOriginalCaster ( ) const
inline

◆ GetPowerCost()

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

References m_powerCost.

Referenced by Unit::HandleDummyAuraProc().

◆ GetSearcherTypeMask()

uint32 Spell::GetSearcherTypeMask ( SpellTargetObjectTypes  objType,
ConditionList condList 
)
2109{
2110 // this function selects which containers need to be searched for spell target
2112
2113 // filter searchers based on searched object type
2114 switch (objType)
2115 {
2122 break;
2126 break;
2127 default:
2128 break;
2129 }
2131 retMask &= ~GRID_MAP_TYPE_MASK_CORPSE;
2135 retMask &= GRID_MAP_TYPE_MASK_PLAYER;
2136
2137 if (condList)
2138 retMask &= sConditionMgr->GetSearcherTypeMaskForConditionList(*condList);
2139 return retMask;
2140}
@ 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
582{ return m_spellValue; }

References m_spellValue.

Referenced by DoAllEffectOnTarget().

◆ getState()

◆ GetTriggeredByAuraTickNumber()

uint32 Spell::GetTriggeredByAuraTickNumber ( ) const
inline

◆ GetTriggeredCastFlags()

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

References _triggeredCastFlags.

◆ GetUniqueTargetInfo()

◆ handle_delayed()

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

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

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

Referenced by _cast().

◆ HandleEffects()

void Spell::HandleEffects ( Unit pUnitTarget,
Item pItemTarget,
GameObject pGOTarget,
uint32  i,
SpellEffectHandleMode  mode 
)
5604{
5605 effectHandleMode = mode;
5606 unitTarget = pUnitTarget;
5607 itemTarget = pItemTarget;
5608 gameObjTarget = pGOTarget;
5610
5611 uint8 eff = m_spellInfo->Effects[i].Effect;
5612
5613 LOG_DEBUG("spells.aura", "Spell: {} Effect : {}", m_spellInfo->Id, eff);
5614
5615 // we do not need DamageMultiplier here.
5616 damage = CalculateSpellDamage(i, nullptr);
5617
5618 bool preventDefault = CallScriptEffectHandlers((SpellEffIndex)i, mode);
5619
5620 if (!preventDefault && eff < TOTAL_SPELL_EFFECTS)
5621 {
5622 (this->*SpellEffects[eff])((SpellEffIndex)i);
5623 }
5624}
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:8541

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

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

◆ HandleLaunchPhase()

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

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 ( )
5557{
5558 if (m_UniqueTargetInfo.empty())
5559 return;
5560
5562 return;
5563
5564 float threat = 0.0f;
5565 if (SpellThreatEntry const* threatEntry = sSpellMgr->GetSpellThreatEntry(m_spellInfo->Id))
5566 {
5567 if (threatEntry->apPctMod != 0.0f)
5568 threat += threatEntry->apPctMod * m_caster->GetTotalAttackPowerValue(BASE_ATTACK);
5569
5570 threat += threatEntry->flatMod;
5571 }
5573 threat += m_spellInfo->SpellLevel;
5574
5575 // past this point only multiplicative effects occur
5576 if (threat == 0.0f)
5577 return;
5578
5579 // 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
5580 threat /= m_UniqueTargetInfo.size();
5581
5582 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
5583 {
5584 float threatToAdd = threat;
5585 if (ihit->missCondition != SPELL_MISS_NONE)
5586 threatToAdd = 0.0f;
5587
5588 Unit* target = ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID);
5589 if (!target)
5590 continue;
5591
5592 bool IsFriendly = m_caster->IsFriendlyTo(target);
5593 // positive spells distribute threat among all units that are in combat with target, like healing
5595 target->getHostileRefMgr().threatAssist(m_caster, threatToAdd, m_spellInfo);
5596 // for negative spells threat gets distributed among affected targets
5597 else if (!m_spellInfo->_IsPositiveSpell() && !IsFriendly && target->CanHaveThreatList())
5598 target->AddThreat(m_caster, threatToAdd, m_spellInfo->GetSchoolMask(), m_spellInfo);
5599 }
5600 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()));
5601}
@ 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:2826
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

◆ HaveTargetsForEffect()

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

References m_UniqueGOTargetInfo, m_UniqueItemInfo, and m_UniqueTargetInfo.

◆ InitEffectExecuteData()

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

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

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

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

◆ IsAutoActionResetSpell()

bool Spell::IsAutoActionResetSpell ( ) const
Todo:
changed SPELL_INTERRUPT_FLAG_AUTOATTACK -> SPELL_INTERRUPT_FLAG_INTERRUPT to fix compile - is this check correct at all?
8038{
8041 {
8042 return false;
8043 }
8044
8046 {
8047 return false;
8048 }
8049
8050 return true;
8051}
@ 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
628 {
629 if (m_delayAtDamageCount >= 2)
630 return true;
631
633 return false;
634 }

References m_delayAtDamageCount.

Referenced by Delayed(), and DelayedChannel().

◆ IsDeletable()

◆ IsIgnoringCooldowns()

bool Spell::IsIgnoringCooldowns ( ) const

◆ IsInterruptable()

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

References m_executedCurrently.

Referenced by Unit::InterruptSpell().

◆ IsNeedSendToClient()

◆ IsNextMeleeSwingSpell()

bool Spell::IsNextMeleeSwingSpell ( ) const

◆ IsTriggered()

◆ IsValidDeadOrAliveTarget()

bool Spell::IsValidDeadOrAliveTarget ( Unit const *  target) const
protected
8183{
8184 if (target->IsAlive())
8186
8188}
bool IsRequiringDeadTarget() const
Definition: SpellInfo.cpp:1209
bool IsAllowingDeadTarget() const
Definition: SpellInfo.cpp:1214

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

Referenced by UpdateChanneledTargetList().

◆ LoadScripts()

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

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

3465{
3466 if (m_CastItem)
3467 {
3469 }
3470 else
3471 {
3473 }
3474
3475 InitExplicitTargets(*targets);
3476
3477 if (!sScriptMgr->CanPrepare(this, targets, triggeredByAura))
3478 {
3479 finish(false);
3480 return SPELL_FAILED_UNKNOWN;
3481 }
3482
3483 // Fill aura scaling information
3485 {
3486 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
3487 {
3488 if (m_spellInfo->Effects[i].Effect == SPELL_EFFECT_APPLY_AURA ||
3491 {
3492 // Change aura with ranks only if basepoints are taken from spellInfo and aura is positive
3494 {
3495 m_auraScaleMask |= (1 << i);
3496 if (m_spellValue->EffectBasePoints[i] != m_spellInfo->Effects[i].BasePoints)
3497 {
3498 m_auraScaleMask = 0;
3499 break;
3500 }
3501 }
3502 }
3503 }
3504 }
3505
3507
3508 if (triggeredByAura)
3509 {
3510 m_triggeredByAuraSpell.Init(triggeredByAura);
3511 }
3512
3513 // create and add update event for this spell
3514 _spellEvent = new SpellEvent(this);
3516
3518 {
3520 finish(false);
3522 }
3523
3524 //Prevent casting at cast another spell (ServerSide check)
3526 {
3528 finish(false);
3530 }
3531
3532 LoadScripts();
3533
3534 OnSpellLaunch();
3535
3537
3538 // Set combo point requirement
3540 m_needComboPoints = false;
3541
3542 SpellCastResult result = CheckCast(true);
3543 if (result != SPELL_CAST_OK && !IsAutoRepeat()) //always cast autorepeat dummy for triggering
3544 {
3545 // Periodic auras should be interrupted when aura triggers a spell which can't be cast
3546 // for example bladestorm aura should be removed on disarm as of patch 3.3.5
3547 // channeled periodic spells should be affected by this (arcane missiles, penance, etc)
3548 // a possible alternative sollution for those would be validating aura target on unit state change
3549 if (m_caster->GetTypeId() == TYPEID_PLAYER && triggeredByAura && triggeredByAura->IsPeriodic() && !triggeredByAura->GetBase()->IsPassive())
3550 {
3552 triggeredByAura->GetBase()->SetDuration(0);
3553 }
3554
3555 // Allows to cast melee attack spell if result is SPELL_FAILED_OUT_OF_RANGE
3557 {
3558 SendCastResult(result);
3559
3560 finish(false);
3561 return result;
3562 }
3563 }
3564
3565 // Prepare data for triggers
3566 prepareDataForTriggerSystem(triggeredByAura);
3567
3568 // calculate cast time (calculated after first CheckCast check to prevent charge counting for first CheckCast fail)
3570
3573 m_casttime = 0;
3574
3575 // don't allow channeled spells / spells with cast time to be casted while moving
3576 // (even if they are interrupted on moving, spells with almost immediate effect get to have their effect processed before movement interrupter kicks in)
3578 {
3579 // 1. Has casttime, 2. Or doesn't have flag to allow action during channel
3581 {
3583 finish(false);
3584 return SPELL_FAILED_MOVING;
3585 }
3586 }
3587
3588 // xinef: if spell have nearby target entry only, do not allow to cast if no targets are found
3589 if (m_CastItem)
3590 {
3591 bool selectTargets = false;
3592 bool nearbyDest = false;
3593
3594 for (uint8 i = EFFECT_0; i < MAX_SPELL_EFFECTS; ++i)
3595 {
3596 if (!m_spellInfo->Effects[i].IsEffect())
3597 continue;
3598
3599 if (m_spellInfo->Effects[i].TargetA.GetSelectionCategory() != TARGET_SELECT_CATEGORY_NEARBY || m_spellInfo->Effects[i].TargetA.GetCheckType() != TARGET_CHECK_ENTRY)
3600 {
3601 selectTargets = false;
3602 break;
3603 }
3604
3605 if (m_spellInfo->Effects[i].TargetA.GetObjectType() == TARGET_OBJECT_TYPE_DEST)
3606 {
3607 nearbyDest = true;
3608 }
3609
3610 // xinef: by default set it to false, and to true if any valid target is found
3611 selectTargets = true;
3612 }
3613
3614 if (selectTargets)
3615 {
3617 _spellTargetsSelected = true;
3618 bool spellFailed = false;
3619
3620 if (m_UniqueTargetInfo.empty() && m_UniqueGOTargetInfo.empty())
3621 {
3622 // no valid nearby target unit or game object found; check if nearby destination type
3623 if (nearbyDest)
3624 {
3625 if (!m_targets.HasDst())
3626 {
3627 // no valid target destination
3628 spellFailed = true;
3629 }
3630 }
3631 else
3632 {
3633 spellFailed = true;
3634 }
3635 }
3636
3637 if (spellFailed)
3638 {
3640 finish(false);
3642 }
3643 }
3644 }
3645
3646 // set timer base at cast time
3647 ReSetTimer();
3648
3649 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());
3650
3652 {
3654 }
3655
3656 //Containers for channeled spells have to be set
3657 //TODO:Apply this to all casted spells if needed
3658 // Why check duration? 29350: channelled triggers channelled
3660 cast(true);
3661 else
3662 {
3663 // stealth must be removed at cast starting (at show channel bar)
3664 // skip triggered spell (item equip spell casting and other not explicit character casts/item uses)
3666 {
3667 // Farsight spells exception
3668 uint32 exceptSpellId = 0;
3670 {
3671 exceptSpellId = m_spellInfo->Id;
3672 }
3673
3676 }
3677
3680
3681 // set target for proper facing
3683 {
3686 {
3687 // Xinef: Creature should focus to cast target if there is explicit target or self if casting positive spell
3688 // Xinef: Creature should not rotate when casting spell... based on halion behavior
3690 }
3691 }
3692
3693 //item: first cast may destroy item and second cast causes crash
3694 // xinef: removed !m_spellInfo->StartRecoveryTime
3695 // second los check failed in events
3696 // xinef: removed itemguid check, currently there is no such item in database
3698 cast(true);
3699
3702 }
3703
3704 return SPELL_CAST_OK;
3705}
@ CHEAT_CASTTIME
Definition: Player.h:992
@ AURA_INTERRUPT_FLAG_SPELL_ATTACK
Definition: SpellDefines.h:57
@ AURA_INTERRUPT_FLAG_CAST
Definition: SpellDefines.h:46
@ TRIGGERED_IGNORE_AURA_SCALING
Will not take away cast item or update related achievement criteria.
Definition: SpellDefines.h:136
@ TRIGGERED_IGNORE_AURA_INTERRUPT_FLAGS
In Spell::prepare, will be cast directly without setting containers for executed spell.
Definition: SpellDefines.h:140
@ TRIGGERED_IGNORE_COMBO_POINTS
Will not check if a current cast is in progress.
Definition: SpellDefines.h:138
@ SPELL_INTERRUPT_FLAG_MOVEMENT
Definition: SpellDefines.h:27
@ TARGET_SELECT_CATEGORY_NEARBY
Definition: SpellInfo.h:80
@ TARGET_OBJECT_TYPE_DEST
Definition: SpellInfo.h:100
@ SPELL_EFFECT_APPLY_AREA_AURA_PARTY
Definition: SharedDefines.h: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:3447
void SetCurrentCastedSpell(Spell *pSpell)
Definition: Unit.cpp:3921
bool IsSitState() const
Definition: Unit.cpp:16979
Definition: Spell.cpp:518
void Init(AuraEffect const *aurEff)
Definition: Spell.cpp:8883
void LoadScripts()
Definition: Spell.cpp:8455
void cast(bool skipCheck=false)
Definition: Spell.cpp:3779
void prepareDataForTriggerSystem(AuraEffect const *triggeredByAura)
Definition: Spell.cpp:2290
void SendSpellStart()
Definition: Spell.cpp:4693
void TriggerGlobalCooldown()
Definition: Spell.cpp:8799
void OnSpellLaunch()
Definition: Spell.cpp:8860
CurrentSpellTypes GetCurrentContainer() const
Definition: Spell.cpp:7873
void ReSetTimer()
Definition: Spell.h:550
void InitExplicitTargets(SpellCastTargets const &targets)
Definition: Spell.cpp:712
bool IsActionAllowedChannel() const
Definition: SpellInfo.cpp:1248
int32 GetMaxDuration() const
Definition: SpellInfo.cpp:2331
uint32 Attributes
Definition: SpellInfo.h:322
bool IsBreakingStealth() const
Definition: SpellInfo.cpp:1258

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

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

◆ prepareDataForTriggerSystem()

void Spell::prepareDataForTriggerSystem ( AuraEffect const *  triggeredByAura)
protected
2291{
2292 //==========================================================================================
2293 // Now fill data for trigger system, need know:
2294 // can spell trigger another or not (m_canTrigger)
2295 // Create base triggers flags for Attacker and Victim (m_procAttacker, m_procVictim and m_procEx)
2296 //==========================================================================================
2297
2299 // Get data for type of attack and fill base info for trigger
2300 switch (m_spellInfo->DmgClass)
2301 {
2304 if (m_attackType == OFF_ATTACK)
2306 else
2309 break;
2311 // Auto attack
2313 {
2316 }
2317 else // Ranged spell attack
2318 {
2321 }
2322 break;
2323 default:
2326 && m_spellInfo->HasAttribute(SPELL_ATTR2_AUTO_REPEAT)) // Wands auto attack
2327 {
2330 }
2331 // For other spells trigger procflags are set in Spell::DoAllEffectOnTarget
2332 // Because spell positivity is dependant on target
2333 }
2335
2336 // Hunter trap spells - activation proc for Lock and Load, Entrapment and Misdirection
2338 (m_spellInfo->SpellFamilyFlags[0] & 0x18 || // Freezing and Frost Trap, Freezing Arrow
2339 m_spellInfo->Id == 57879 || m_spellInfo->Id == 45145 || // Snake Trap - done this way to avoid double proc
2340 m_spellInfo->SpellFamilyFlags[2] & 0x00064000)) // Explosive and Immolation Trap
2341 {
2343 }
2344
2345 /* Effects which are result of aura proc from triggered spell cannot proc
2346 to prevent chain proc of these spells */
2347
2348 // Hellfire Effect - trigger as DOT
2350 {
2353 }
2354
2355 // Ranged autorepeat attack is set as triggered spell - ignore it
2357 {
2364 }
2365 // Totem casts require spellfamilymask defined in spell_proc_event to proc
2368}
@ 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 _triggeredCastFlags, SpellInfo::DmgClass, SpellInfo::EquippedItemClass, SpellInfo::EquippedItemSubClassMask, Object::GetTypeId(), SpellInfo::HasAttribute(), SpellInfo::Id, Unit::IsControlledByPlayer(), Unit::IsTotem(), ITEM_CLASS_WEAPON, ITEM_SUBCLASS_WEAPON_WAND, m_attackType, m_caster, m_originalCaster, m_procAttacker, m_procEx, m_procVictim, m_spellInfo, OFF_ATTACK, PROC_EX_INTERNAL_CANT_PROC, PROC_EX_INTERNAL_REQ_FAMILY, PROC_EX_INTERNAL_TRIGGERED, PROC_EX_NONE, PROC_FLAG_DONE_MAINHAND_ATTACK, PROC_FLAG_DONE_OFFHAND_ATTACK, PROC_FLAG_DONE_PERIODIC, PROC_FLAG_DONE_RANGED_AUTO_ATTACK, PROC_FLAG_DONE_SPELL_MELEE_DMG_CLASS, PROC_FLAG_DONE_SPELL_RANGED_DMG_CLASS, PROC_FLAG_DONE_TRAP_ACTIVATION, PROC_FLAG_TAKEN_PERIODIC, PROC_FLAG_TAKEN_RANGED_AUTO_ATTACK, PROC_FLAG_TAKEN_SPELL_MELEE_DMG_CLASS, PROC_FLAG_TAKEN_SPELL_RANGED_DMG_CLASS, SPELL_ATTR2_ACTIVE_THREAT, SPELL_ATTR2_AUTO_REPEAT, SPELL_ATTR3_NOT_A_PROC, SPELL_DAMAGE_CLASS_MELEE, SPELL_DAMAGE_CLASS_RANGED, SPELLFAMILY_HUNTER, SPELLFAMILY_WARLOCK, SpellInfo::SpellFamilyFlags, SpellInfo::SpellFamilyName, Object::ToCreature(), TRIGGERED_DISALLOW_PROC_EVENTS, and TYPEID_UNIT.

Referenced by prepare().

◆ PrepareScriptHitHandlers()

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

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

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

Referenced by _cast().

◆ RecalculateDelayMomentForDst()

void Spell::RecalculateDelayMomentForDst ( )
916{
919}
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:894
uint64 GetDelayStart() const
Definition: Spell.h:561

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

◆ ReSetTimer()

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

References m_casttime, and m_timer.

Referenced by prepare().

◆ SearchAreaTargets()

void Spell::SearchAreaTargets ( std::list< WorldObject * > &  targets,
float  range,
Position const *  position,
Unit referer,
SpellTargetObjectTypes  objectType,
SpellTargetCheckTypes  selectionType,
ConditionList condList 
)
2185{
2186 uint32 containerTypeMask = GetSearcherTypeMask(objectType, condList);
2187 if (!containerTypeMask)
2188 return;
2189 Acore::WorldObjectSpellAreaTargetCheck check(range, position, m_caster, referer, m_spellInfo, selectionType, condList);
2190 Acore::WorldObjectListSearcher<Acore::WorldObjectSpellAreaTargetCheck> searcher(m_caster, targets, check, containerTypeMask);
2191 SearchTargets<Acore::WorldObjectListSearcher<Acore::WorldObjectSpellAreaTargetCheck> > (searcher, containerTypeMask, m_caster, position, range);
2192}
Definition: GridNotifiers.h:236
uint32 GetSearcherTypeMask(SpellTargetObjectTypes objType, ConditionList *condList)
Definition: Spell.cpp:2108

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

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

References GetSearcherTypeMask(), m_caster, and m_spellInfo.

Referenced by SelectImplicitNearbyTargets().

◆ SearchTargets()

template<class SEARCHER >
void Spell::SearchTargets ( SEARCHER &  searcher,
uint32  containerMask,
Unit referer,
Position const *  pos,
float  radius 
)
2144{
2145 if (!containerMask)
2146 return;
2147
2148 // search world and grid for possible targets
2149 bool searchInGrid = containerMask & (GRID_MAP_TYPE_MASK_CREATURE | GRID_MAP_TYPE_MASK_GAMEOBJECT);
2150 bool searchInWorld = containerMask & (GRID_MAP_TYPE_MASK_CREATURE | GRID_MAP_TYPE_MASK_PLAYER | GRID_MAP_TYPE_MASK_CORPSE);
2151
2152 if (searchInGrid || searchInWorld)
2153 {
2154 float x, y;
2155 x = pos->GetPositionX();
2156 y = pos->GetPositionY();
2157
2159 Cell cell(p);
2160 cell.SetNoCreate();
2161
2162 Map* map = referer->GetMap();
2163
2164 if (searchInWorld)
2165 Cell::VisitWorldObjects(x, y, map, searcher, radius);
2166
2167 if (searchInGrid)
2168 Cell::VisitGridObjects(x, y, map, searcher, radius);
2169 }
2170}
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 
)
922{
923 if (!targetType.GetTarget())
924 return;
925
926 uint32 effectMask = 1 << effIndex;
927 // set the same target list for all effects
928 // some spells appear to need this, however this requires more research
929 switch (targetType.GetSelectionCategory())
930 {
934 {
935 // targets for effect already selected
936 if (effectMask & processedEffectMask)
937 {
938 return;
939 }
940
941 auto const& effects = GetSpellInfo()->Effects;
942
943 // choose which targets we can select at once
944 for (uint32 j = effIndex + 1; j < MAX_SPELL_EFFECTS; ++j)
945 {
946 if (effects[j].IsEffect() &&
947 effects[effIndex].TargetA.GetTarget() == effects[j].TargetA.GetTarget() &&
948 effects[effIndex].TargetB.GetTarget() == effects[j].TargetB.GetTarget() &&
949 effects[effIndex].ImplicitTargetConditions == effects[j].ImplicitTargetConditions &&
950 effects[effIndex].CalcRadius(m_caster) == effects[j].CalcRadius(m_caster) &&
952 {
953 effectMask |= 1 << j;
954 }
955 }
956 processedEffectMask |= effectMask;
957 break;
958 }
959 default:
960 break;
961 }
962
963 switch (targetType.GetSelectionCategory())
964 {
966 SelectImplicitChannelTargets(effIndex, targetType);
967 break;
969 SelectImplicitNearbyTargets(effIndex, targetType, effectMask);
970 break;
972 SelectImplicitConeTargets(effIndex, targetType, effectMask);
973 break;
975 SelectImplicitAreaTargets(effIndex, targetType, effectMask);
976 break;
978 // just in case there is no dest, explanation in SelectImplicitDestDestTargets
979 CheckDst();
980
981 SelectImplicitTrajTargets(effIndex, targetType);
982 break;
984 switch (targetType.GetObjectType())
985 {
987 switch (targetType.GetReferenceType())
988 {
991 break;
992 default:
993 ASSERT(false && "Spell::SelectEffectImplicitTargets: received not implemented select target reference type for TARGET_TYPE_OBJECT_SRC");
994 break;
995 }
996 break;
998 switch (targetType.GetReferenceType())
999 {
1001 SelectImplicitCasterDestTargets(effIndex, targetType);
1002 break;
1004 SelectImplicitTargetDestTargets(effIndex, targetType);
1005 break;
1007 SelectImplicitDestDestTargets(effIndex, targetType);
1008 break;
1009 default:
1010 ASSERT(false && "Spell::SelectEffectImplicitTargets: received not implemented select target reference type for TARGET_TYPE_OBJECT_DEST");
1011 break;
1012 }
1013 break;
1014 default:
1015 switch (targetType.GetReferenceType())
1016 {
1018 SelectImplicitCasterObjectTargets(effIndex, targetType);
1019 break;
1021 SelectImplicitTargetObjectTargets(effIndex, targetType);
1022 break;
1023 default:
1024 ASSERT(false && "Spell::SelectEffectImplicitTargets: received not implemented select target reference type for TARGET_TYPE_OBJECT");
1025 break;
1026 }
1027 break;
1028 }
1029 break;
1031 LOG_DEBUG("spells.aura", "SPELL: target type {}, found in spellID {}, effect {} is not implemented yet!", m_spellInfo->Id, effIndex, targetType.GetTarget());
1032 break;
1033 default:
1034 ASSERT(false && "Spell::SelectEffectImplicitTargets: received not implemented select target category");
1035 break;
1036 }
1037}
@ 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:1716
void CheckDst()
Definition: Spell.h:492
void SelectImplicitTrajTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition: Spell.cpp:1865
void SelectImplicitConeTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType, uint32 effMask)
Definition: Spell.cpp:1209
void SelectImplicitTargetDestTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition: Spell.cpp:1679
void SelectImplicitAreaTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType, uint32 effMask)
Definition: Spell.cpp:1259
void SelectImplicitChannelTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition: Spell.cpp:1039
void SelectImplicitTargetObjectTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition: Spell.cpp:1802
void SelectImplicitCasterObjectTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition: Spell.cpp:1755
void SelectImplicitNearbyTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType, uint32 effMask)
Definition: Spell.cpp:1095
bool CheckScriptEffectImplicitTargets(uint32 effIndex, uint32 effIndexToCheck)
Definition: Spell.cpp:8670
void SelectImplicitCasterDestTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition: Spell.cpp:1341

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

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

Referenced by SelectSpellTargets().

◆ SelectExplicitTargets()

void Spell::SelectExplicitTargets ( )
782{
783 // here go all explicit target changes made to explicit targets after spell prepare phase is finished
784 if (Unit* target = m_targets.GetUnitTarget())
785 {
786 // check for explicit target redirection, for Grounding Totem for example
790 {
791 Unit* redirect;
792 switch (m_spellInfo->DmgClass)
793 {
796 break;
800 break;
801 default:
802 redirect = nullptr;
803 break;
804 }
805 if (redirect && (redirect != target))
806 {
807 m_targets.SetUnitTarget(redirect);
809 }
810 }
811 }
812}
Unit * GetMeleeHitRedirectTarget(Unit *victim, SpellInfo const *spellInfo=nullptr)
Definition: Unit.cpp:11051
Unit * GetMagicHitRedirectTarget(Unit *victim, SpellInfo const *spellInfo)
Definition: Unit.cpp:11013

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

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

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

Referenced by SelectEffectImplicitTargets().

◆ SelectImplicitChainTargets()

void Spell::SelectImplicitChainTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType,
WorldObject target,
uint32  effMask 
)
1825{
1826 uint32 maxTargets = m_spellInfo->Effects[effIndex].ChainTarget;
1827 if (Player* modOwner = m_caster->GetSpellModOwner())
1828 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_JUMP_TARGETS, maxTargets, this);
1829
1830 if (maxTargets > 1)
1831 {
1832 // mark damage multipliers as used
1833 for (uint32 k = effIndex; k < MAX_SPELL_EFFECTS; ++k)
1834 if (effMask & (1 << k))
1835 m_damageMultipliers[k] = 1.0f;
1836 m_applyMultiplierMask |= effMask;
1837
1838 std::list<WorldObject*> targets;
1839 SearchChainTargets(targets, maxTargets - 1, target, targetType.GetObjectType(), targetType.GetCheckType(), targetType.GetSelectionCategory()
1840 , m_spellInfo->Effects[effIndex].ImplicitTargetConditions, targetType.GetTarget() == TARGET_UNIT_TARGET_CHAINHEAL_ALLY);
1841
1842 // Chain primary target is added earlier
1843 CallScriptObjectAreaTargetSelectHandlers(targets, effIndex, targetType);
1844
1845 for (std::list<WorldObject*>::iterator itr = targets.begin(); itr != targets.end(); ++itr)
1846 if (Unit* unitTarget = (*itr)->ToUnit())
1847 AddUnitTarget(unitTarget, effMask, false);
1848 }
1849}
@ 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:2194

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 
)
1040{
1041 if (targetType.GetReferenceType() != TARGET_REFERENCE_TYPE_CASTER)
1042 {
1043 ASSERT(false && "Spell::SelectImplicitChannelTargets: received not implemented target reference type");
1044 return;
1045 }
1046
1047 switch (targetType.GetTarget())
1048 {
1050 {
1051 // Xinef: All channel selectors have needed data passed in m_targets structure
1053 if (target)
1054 {
1055 CallScriptObjectTargetSelectHandlers(target, effIndex, targetType);
1056 // unit target may be no longer avalible - teleported out of map for example
1057 if (target && target->ToUnit())
1058 AddUnitTarget(target->ToUnit(), 1 << effIndex);
1059 }
1060 else
1061 {
1062 LOG_DEBUG("spells.aura", "SPELL: cannot find channel spell target for spell ID {}, effect {}", m_spellInfo->Id, effIndex);
1063 }
1064 break;
1065 }
1070 {
1071 CallScriptObjectTargetSelectHandlers(target, effIndex, targetType);
1072 if (target)
1073 m_targets.SetDst(*target);
1074 }
1076 {
1077 if (channeledSpell->m_targets.GetUnitTarget())
1078 m_targets.SetDst(*channeledSpell->m_targets.GetUnitTarget());
1079 }
1080 else //if (!m_targets.HasDst())
1081 {
1082 LOG_DEBUG("spells.aura", "SPELL: cannot find channel spell destination for spell ID {}, effect {}", m_spellInfo->Id, effIndex);
1083 }
1084 break;
1086 if (GetOriginalCaster())
1088 break;
1089 default:
1090 ASSERT(false && "Spell::SelectImplicitChannelTargets: received not implemented target type");
1091 break;
1092 }
1093}
@ 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:463
SpellDestination const * GetDstChannel() const
Definition: Spell.cpp:473
bool HasDstChannel() const
Definition: Spell.cpp:468

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

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

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 
)
1680{
1682
1683 SpellDestination dest(*target);
1684
1685 switch (targetType.GetTarget())
1686 {
1689 break;
1690 default:
1691 {
1692 float angle = targetType.CalcDirectionAngle();
1693 float dist = m_spellInfo->Effects[effIndex].CalcRadius(nullptr);
1694 if (targetType.GetTarget() == TARGET_DEST_TARGET_RANDOM)
1695 {
1696 dist *= float(rand_norm());
1697 }
1698
1699 if (targetType.GetTarget() == TARGET_DEST_TARGET_BACK)
1700 {
1702 }
1703
1704 Position pos = dest._position;
1705 target->MovePositionToFirstCollision(pos, dist, angle);
1706
1707 dest.Relocate(pos);
1708 break;
1709 }
1710 }
1711
1712 CallScriptDestinationTargetSelectHandlers(dest, effIndex, targetType);
1713 m_targets.SetDst(dest);
1714}
@ 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 
)
1803{
1804 ASSERT((m_targets.GetObjectTarget() || m_targets.GetItemTarget()) && "Spell::SelectImplicitTargetObjectTargets - no explicit object or item target available!");
1805
1807
1808 CallScriptObjectTargetSelectHandlers(target, effIndex, targetType);
1809
1810 if (target)
1811 {
1812 if (Unit* unit = target->ToUnit())
1813 AddUnitTarget(unit, 1 << effIndex, true, false);
1814 else if (GameObject* gobj = target->ToGameObject())
1815 AddGOTarget(gobj, 1 << effIndex);
1816
1817 SelectImplicitChainTargets(effIndex, targetType, target, 1 << effIndex);
1818 }
1819 // Script hook can remove object target and we would wrongly land here
1820 else if (Item* item = m_targets.GetItemTarget())
1821 AddItemTarget(item, 1 << effIndex);
1822}

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

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
4646{
4647 if (result == SPELL_CAST_OK)
4648 return;
4649
4650 WorldPacket data(SMSG_CAST_FAILED, 1 + 4 + 1);
4651 WriteCastResultInfo(data, caster, spellInfo, castCount, result, customError);
4652
4653 caster->GetSession()->SendPacket(&data);
4654}
@ 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:4540

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

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

◆ SendCastResult() [2/2]

void Spell::SendCastResult ( SpellCastResult  result)
4657{
4658 if (result == SPELL_CAST_OK)
4659 return;
4660
4662 return;
4663
4664 if (m_caster->ToPlayer()->GetSession()->PlayerLoading()) // don't send cast results at loading time
4665 return;
4666
4667 // 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
4669 result = SPELL_FAILED_DONT_REPORT;
4670
4672}
@ 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:1885

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

◆ SendChannelStart()

void Spell::SendChannelStart ( uint32  duration)
5183{
5184 ObjectGuid channelTarget = m_targets.GetObjectTargetGUID();
5185 if (!channelTarget && !m_spellInfo->NeedsExplicitUnitTarget())
5186 if (m_UniqueTargetInfo.size() + m_UniqueGOTargetInfo.size() == 1) // this is for TARGET_SELECT_CATEGORY_NEARBY
5187 channelTarget = !m_UniqueTargetInfo.empty() ? m_UniqueTargetInfo.front().targetGUID : m_UniqueGOTargetInfo.front().targetGUID;
5188
5189 WorldPacket data(MSG_CHANNEL_START, (8 + 4 + 4));
5190 data << m_caster->GetPackGUID();
5191 data << uint32(m_spellInfo->Id);
5192 data << uint32(duration);
5193
5194 m_caster->SendMessageToSet(&data, true);
5195
5198
5199 m_timer = duration;
5200 if (channelTarget)
5202
5204}
@ MSG_CHANNEL_START
Definition: Opcodes.h:343

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

Referenced by handle_immediate().

◆ SendChannelUpdate()

◆ SendInterrupted()

void Spell::SendInterrupted ( uint8  result)
5151{
5152 WorldPacket data(SMSG_SPELL_FAILURE, (8 + 1 + 4 + 1));
5153 data << m_caster->GetPackGUID();
5154 data << uint8(m_cast_count);
5155 data << uint32(m_spellInfo->Id);
5156 data << uint8(result);
5157 m_caster->SendMessageToSet(&data, true);
5158
5159 data.Initialize(SMSG_SPELL_FAILED_OTHER, (8 + 1 + 4 + 1));
5160 data << m_caster->GetPackGUID();
5161 data << uint8(m_cast_count);
5162 data << uint32(m_spellInfo->Id);
5163 data << uint8(result);
5164 m_caster->SendMessageToSet(&data, true);
5165}
@ 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 ( )
5050{
5051 WorldPacket data(SMSG_SPELLLOGEXECUTE, (8 + 4 + 4 + 4 + 4 + 8));
5052
5053 data << m_caster->GetPackGUID();
5054
5055 data << uint32(m_spellInfo->Id);
5056
5057 uint8 effCount = 0;
5058 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
5059 {
5060 if (m_effectExecuteData[i])
5061 ++effCount;
5062 }
5063
5064 if (!effCount)
5065 return;
5066
5067 data << uint32(effCount);
5068 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
5069 {
5070 if (!m_effectExecuteData[i])
5071 continue;
5072
5073 data << uint32(m_spellInfo->Effects[i].Effect); // spell effect
5074
5075 data.append(*m_effectExecuteData[i]);
5076
5077 delete m_effectExecuteData[i];
5078 m_effectExecuteData[i] = nullptr;
5079 }
5080 m_caster->SendMessageToSet(&data, true);
5081}
@ 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
2018{
2019 Player* player = m_caster->ToPlayer();
2020 if (!player)
2021 return;
2022
2023 if (gameObjTarget)
2024 {
2025 // Players shouldn't be able to loot gameobjects that are currently despawned
2026 if (!gameObjTarget->isSpawned() && !player->IsGameMaster())
2027 {
2028 LOG_ERROR("spells.effect", "Possible hacking attempt: Player {} [{}] tried to loot a gameobject [{}] which is on respawn time without being in GM mode!",
2029 player->GetName(), player->GetGUID().ToString(), gameObjTarget->GetGUID().ToString());
2030 return;
2031 }
2032 // special case, already has GossipHello inside so return and avoid calling twice
2034 {
2036 return;
2037 }
2038
2039 if (sScriptMgr->OnGossipHello(player, gameObjTarget))
2040 return;
2041
2042 if (gameObjTarget->AI()->GossipHello(player, false))
2043 return;
2044
2045 switch (gameObjTarget->GetGoType())
2046 {
2048 gameObjTarget->UseDoorOrButton(0, false, player);
2049 return;
2051 gameObjTarget->UseDoorOrButton(0, false, player);
2052
2053 // Xinef: properly link possible traps
2054 if (uint32 trapEntry = gameObjTarget->GetGOInfo()->button.linkedTrap)
2055 gameObjTarget->TriggeringLinkedGameObject(trapEntry, player);
2056 return;
2060 return;
2061
2063 // triggering linked GO
2066 return;
2067
2069 // triggering linked GO
2070 if (uint32 trapEntry = gameObjTarget->GetGOInfo()->chest.linkedTrapId)
2072
2073 // Don't return, let loots been taken
2074 default:
2075 break;
2076 }
2077 }
2078
2079 // Send loot
2080 player->SendLoot(guid, loottype);
2081}
@ 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:191
void TriggeringLinkedGameObject(uint32 trapEntry, Unit *target)
Definition: GameObject.cpp:1383
uint32 gossipID
Definition: GameObjectData.h:73
uint32 linkedTrap
Definition: GameObjectData.h:60
struct GameObjectTemplate::@223::@232 spellFocus
struct GameObjectTemplate::@223::@227 questgiver
struct GameObjectTemplate::@223::@228 chest
uint32 linkedTrapId
Definition: GameObjectData.h:91
void SendPreparedGossip(WorldObject *source)
Definition: PlayerGossip.cpp:208
void PrepareGossipMenu(WorldObject *source, uint32 menuId=0, bool showQuests=false)
Definition: PlayerGossip.cpp:31

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

Referenced by EffectOpenLock().

◆ SendPetCastResult()

void Spell::SendPetCastResult ( SpellCastResult  result)
4675{
4676 if (result == SPELL_CAST_OK)
4677 return;
4678
4679 Unit* owner = m_caster->GetCharmerOrOwner();
4680 if (!owner)
4681 return;
4682
4683 Player* player = owner->ToPlayer();
4684 if (!player)
4685 return;
4686
4687 WorldPacket data(SMSG_PET_CAST_FAILED, 1 + 4 + 1);
4689
4690 player->GetSession()->SendPacket(&data);
4691}
@ 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)
5207{
5208 // get resurrector name for creature resurrections, otherwise packet will be not accepted
5209 // for player resurrections the name is looked up by guid
5210 std::string const sentName(m_caster->GetTypeId() == TYPEID_PLAYER
5211 ? ""
5213
5214 WorldPacket data(SMSG_RESURRECT_REQUEST, (8 + 4 + sentName.size() + 1 + 1 + 1 + 4));
5215 data << m_caster->GetGUID();
5216 data << uint32(sentName.size() + 1);
5217
5218 data << sentName;
5219 data << uint8(0); // null terminator
5220
5221 data << uint8(m_caster->GetTypeId() == TYPEID_PLAYER ? 0 : 1); // "you'll be afflicted with resurrection sickness"
5222 // override delay sent with SMSG_CORPSE_RECLAIM_DELAY, set instant resurrection for spells with this attribute
5224 data << uint32(0);
5225 target->GetSession()->SendPacket(&data);
5226}
@ 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:449
LocaleConstant GetSessionDbLocaleIndex() const
Definition: WorldSession.h:500

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

Referenced by EffectResurrect(), and EffectResurrectNew().

◆ SendSpellCooldown()

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

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

Referenced by _cast().

◆ SendSpellGo()

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

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

Referenced by _cast().

◆ SendSpellStart()

void Spell::SendSpellStart ( )
4694{
4695 if (!IsNeedSendToClient(false))
4696 return;
4697
4698 //LOG_DEBUG("spells.aura", "Sending SMSG_SPELL_START id={}", m_spellInfo->Id);
4699
4700 uint32 castFlags = CAST_FLAG_HAS_TRAJECTORY;
4701
4703 castFlags |= CAST_FLAG_PENDING;
4704
4706 castFlags |= CAST_FLAG_PROJECTILE;
4707
4709 {
4710 switch (m_spellInfo->PowerType)
4711 {
4712 case POWER_HEALTH:
4713 break;
4714 case POWER_RUNE:
4715 castFlags |= CAST_FLAG_POWER_LEFT_SELF;
4716 break;
4717 default:
4718 if (m_powerCost != 0)
4719 {
4720 castFlags |= CAST_FLAG_POWER_LEFT_SELF;
4721 }
4722 break;
4723 }
4724 }
4725
4727 castFlags |= CAST_FLAG_NO_GCD; // not needed, but Blizzard sends it
4728
4729 PackedGuid realCasterGUID = m_caster->GetPackGUID();
4730 if (TempSummon const* tempSummon = m_caster->ToTempSummon())
4731 {
4732 if (tempSummon->GetEntry() == WORLD_TRIGGER)
4733 {
4734 if (GameObject* casterGameobject = tempSummon->GetSummonerGameObject())
4735 {
4736 realCasterGUID = casterGameobject->GetPackGUID();
4737 }
4738 }
4739 }
4740
4741 WorldPacket data(SMSG_SPELL_START, (8 + 8 + 4 + 4 + 2));
4742 if (m_CastItem)
4743 data << m_CastItem->GetPackGUID();
4744 else
4745 data << realCasterGUID;
4746
4747 data << realCasterGUID;
4748 data << uint8(m_cast_count); // pending spell cast?
4749 data << uint32(m_spellInfo->Id); // spellId
4750 data << uint32(castFlags); // cast flags
4751 data << int32(m_timer); // delay?
4752
4753 m_targets.Write(data);
4754
4755 if (castFlags & CAST_FLAG_POWER_LEFT_SELF)
4757
4758 if (castFlags & CAST_FLAG_PROJECTILE)
4759 WriteAmmoToPacket(&data);
4760
4761 if (castFlags & CAST_FLAG_UNKNOWN_23)
4762 {
4763 data << uint32(0);
4764 data << uint32(0);
4765 }
4766
4767 m_caster->SendMessageToSet(&data, true);
4768
4771}
@ CAST_FLAG_UNKNOWN_23
Definition: Spell.h:66
@ CAST_FLAG_HAS_TRAJECTORY
Definition: Spell.h:45
@ SMSG_SPELL_START
Definition: Opcodes.h:335

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

Referenced by prepare().

◆ SetAutoRepeat()

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

References m_autoRepeat.

◆ SetDelayStart()

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

References m_delayStart.

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

◆ SetExecutedCurrently()

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

References m_executedCurrently.

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

◆ SetReferencedFromCurrent()

void Spell::SetReferencedFromCurrent ( bool  yes)
inline

◆ SetSpellValue()

void Spell::SetSpellValue ( SpellValueMod  mod,
int32  value 
)
8392{
8393 switch (mod)
8394 {
8396 m_spellValue->EffectBasePoints[0] = m_spellInfo->Effects[EFFECT_0].CalcBaseValue(value);
8397 break;
8399 m_spellValue->EffectBasePoints[1] = m_spellInfo->Effects[EFFECT_1].CalcBaseValue(value);
8400 break;
8402 m_spellValue->EffectBasePoints[2] = m_spellInfo->Effects[EFFECT_2].CalcBaseValue(value);
8403 break;
8405 m_spellValue->RadiusMod = (float)value / 10000;
8406 break;
8409 break;
8412 break;
8414 m_spellValue->AuraDuration = value;
8415 break;
8417 m_spellValue->ForcedCritResult = (bool)value;
8418 break;
8419 }
8420}
@ 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
5972{
5973 Unit* caster = m_originalCaster;
5974 if (!caster)
5975 return;
5976
5977 if (caster->IsTotem())
5978 caster = caster->ToTotem()->GetOwner();
5979
5980 // in another case summon new
5981 uint8 summonLevel = caster->GetLevel();
5982
5983 // level of pet summoned using engineering item based at engineering skill level
5984 if (m_CastItem && caster->GetTypeId() == TYPEID_PLAYER)
5985 if (ItemTemplate const* proto = m_CastItem->GetTemplate())
5986 {
5987 // xinef: few special cases
5988 if (proto->RequiredSkill == SKILL_ENGINEERING)
5989 {
5990 if (uint16 skill202 = caster->ToPlayer()->GetSkillValue(SKILL_ENGINEERING))
5991 summonLevel = skill202 / 5;
5992 }
5993
5994 switch (m_spellInfo->Id)
5995 {
5996 // Dragon's Call
5997 case 13049:
5998 summonLevel = 55;
5999 break;
6000
6001 // Cleansed Timberling Heart: Summon Timberling
6002 case 5666:
6003 summonLevel = 7;
6004 break;
6005
6006 // Glowing Cat Figurine: Summon Ghost Saber
6007 case 6084:
6008 // minLevel 19, maxLevel 20
6009 summonLevel = 20;
6010 break;
6011
6012 // Spiked Collar: Summon Felhunter
6013 case 8176:
6014 summonLevel = 30;
6015 break;
6016
6017 // Dog Whistle: Summon Tracking Hound
6018 case 9515:
6019 summonLevel = 30;
6020 break;
6021
6022 // Barov Peasant Caller: Death by Peasant
6023 case 18307:
6024 case 18308:
6025 summonLevel = 60;
6026 break;
6027
6028 // Thornling Seed: Plant Thornling
6029 case 22792:
6030 summonLevel = 60;
6031 break;
6032
6033 // Cannonball Runner: Summon Crimson Cannon
6034 case 6251:
6035 summonLevel = 61;
6036 break;
6037 }
6038 }
6039
6040 summonLevel = std::min<uint8>(sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL) + sWorld->getIntConfig(CONFIG_WORLD_BOSS_LEVEL_DIFF), std::max<uint8>(1U, summonLevel));
6041
6042 float radius = 5.0f;
6043 int32 duration = m_spellInfo->GetDuration();
6044
6045 if (Player* modOwner = m_originalCaster->GetSpellModOwner())
6046 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_DURATION, duration);
6047
6048 //TempSummonType summonType = (duration == 0) ? TEMPSUMMON_DEAD_DESPAWN : TEMPSUMMON_TIMED_DESPAWN;
6049 Map* map = caster->GetMap();
6050 TempSummon* summon = nullptr;
6051
6052 uint32 currMinionsCount = m_caster->m_Controlled.size();
6053 uint32 totalNumGuardians = numGuardians + currMinionsCount;
6054
6055 for (uint32 count = 0; count < numGuardians; ++count)
6056 {
6057 Position pos;
6058
6059 // xinef: do not use precalculated position for effect summon pet in this function
6060 // it means it was cast by NPC and should have its position overridden unless the
6061 // target position is specified in the DB AND the effect has no or zero radius
6062 if ((totalNumGuardians == 1 && GetSpellInfo()->Effects[i].Effect != SPELL_EFFECT_SUMMON_PET) ||
6063 (GetSpellInfo()->Effects[i].TargetA.GetTarget() == TARGET_DEST_DB &&
6064 (!GetSpellInfo()->Effects[i].HasRadius() || GetSpellInfo()->Effects[i].RadiusEntry->RadiusMax == 0)))
6065 {
6066 pos = *destTarget;
6067 }
6068 else
6069 {
6070 // randomize position
6071 pos = m_caster->GetRandomPoint(*destTarget, radius);
6072 }
6073
6074 summon = map->SummonCreature(entry, pos, properties, duration, caster, m_spellInfo->Id, 0, personalSpawn);
6075 if (!summon)
6076 return;
6077
6078 // xinef: set calculated level
6079 summon->SetLevel(summonLevel);
6080
6081 // if summonLevel changed, set stats for calculated level
6082 if (summonLevel != caster->GetLevel())
6083 {
6084 ((Guardian*)summon)->InitStatsForLevel(summonLevel);
6085 }
6086
6087 // xinef: if we have more than one guardian, change follow angle
6088 if (summon->HasUnitTypeMask(UNIT_MASK_MINION) && totalNumGuardians > 1)
6089 ((Minion*)summon)->SetFollowAngle(m_caster->GetAbsoluteAngle(pos.GetPositionX(), pos.GetPositionY()));
6090 //else if (summon->HasUnitTypeMask(UNIT_MASK_MINION) && m_targets.HasDst())
6091 // ((Minion*)summon)->SetFollowAngle(m_caster->GetAngle(summon));
6092
6093 // xinef: move this here, some auras are added in initstatsforlevel!
6094 if (!summon->IsInCombat() && !summon->IsTrigger())
6095 {
6096 // summon->AI()->EnterEvadeMode();
6097 summon->GetMotionMaster()->Clear(false);
6099 }
6100
6101 if (properties && properties->Category == SUMMON_CATEGORY_ALLY)
6102 summon->SetFaction(caster->GetFaction());
6103
6105 }
6106
6107 // Summon infernal, cast enslave demon
6108 // xinef: have to do it here because in Pet init stats infernal is not in world, imo this should be changed...
6109 if (summon)
6110 {
6111 switch (m_spellInfo->Id)
6112 {
6113 // Inferno, Warlock summon spell
6114 case 1122:
6115 caster->AddAura(61191, summon);
6116 break;
6117 // Ritual of Doom, Warlock summon spell
6118 case 60478:
6119 caster->AddAura(SPELL_RITUAL_ENSLAVEMENT, summon);
6120 break;
6121 }
6122 }
6123}
@ SPELL_RITUAL_ENSLAVEMENT
Definition: PetDefines.h:155
@ CONFIG_MAX_PLAYER_LEVEL
Definition: IWorld.h:236
@ CONFIG_WORLD_BOSS_LEVEL_DIFF
Definition: IWorld.h:286
@ SKILL_ENGINEERING
Definition: SharedDefines.h:2923
bool IsTrigger() const
Definition: Creature.h:77
Definition: TemporarySummon.h:76
Unit * GetOwner() const
Definition: TemporarySummon.cpp:385
void SetLevel(uint8 lvl, bool showLevelChange=true)
Definition: Unit.cpp:15446

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

Referenced by EffectSummonPet(), and EffectSummonType().

◆ TakeAmmo()

void Spell::TakeAmmo ( )
5356{
5358 {
5360
5361 // wands don't have ammo
5362 if (!pItem || pItem->IsBroken() || pItem->GetTemplate()->SubClass == ITEM_SUBCLASS_WEAPON_WAND)
5363 return;
5364
5365 if (pItem->GetTemplate()->InventoryType == INVTYPE_THROWN)
5366 {
5367 if (pItem->GetMaxStackCount() == 1)
5368 {
5369 // decrease durability for non-stackable throw weapon
5371 }
5372 else
5373 {
5374 // decrease items amount for stackable throw weapon
5375 uint32 count = 1;
5376 m_caster->ToPlayer()->DestroyItemCount(pItem, count, true);
5377 }
5378 }
5380 m_caster->ToPlayer()->DestroyItemCount(ammo, 1, true);
5381 }
5382}
@ INVTYPE_THROWN
Definition: ItemTemplate.h:290
@ EQUIPMENT_SLOT_RANGED
Definition: Player.h:693
uint32 GetMaxStackCount() const
Definition: Item.h:265
void DurabilityPointLossForEquipSlot(EquipmentSlots slot)
Definition: Player.cpp:4732

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

Referenced by handle_immediate(), and HandleLaunchPhase().

◆ TakeCastItem()

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

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

Referenced by _cast(), and handle_immediate().

◆ TakePower()

void Spell::TakePower ( )
5292{
5294 return;
5295
5296 //Don't take power if the spell is cast while .cheat power is enabled.
5299 return;
5300
5302 bool hit = true;
5304 {
5306 if (ObjectGuid targetGUID = m_targets.GetUnitTargetGUID())
5307 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
5308 if (ihit->targetGUID == targetGUID)
5309 {
5310 if (ihit->missCondition != SPELL_MISS_NONE && ihit->missCondition != SPELL_MISS_BLOCK && ihit->missCondition != SPELL_MISS_ABSORB && ihit->missCondition != SPELL_MISS_REFLECT)
5311 {
5312 hit = false;
5313 //lower spell cost on fail (by talent aura)
5314 if (Player* modOwner = m_caster->ToPlayer()->GetSpellModOwner())
5315 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_SPELL_COST_REFUND_ON_FAIL, m_powerCost, this);
5316 }
5317 break;
5318 }
5319 }
5320
5321 if (PowerType == POWER_RUNE)
5322 {
5323 TakeRunePower(hit);
5324 return;
5325 }
5326
5327 if (!m_powerCost)
5328 return;
5329
5330 // health as power used
5331 if (PowerType == POWER_HEALTH)
5332 {
5334 return;
5335 }
5336
5337 if (PowerType >= MAX_POWERS)
5338 {
5339 LOG_ERROR("spells", "Spell::TakePower: Unknown power type '{}'", PowerType);
5340 return;
5341 }
5342
5343 if (hit)
5345 else
5347
5348 // Set the five second timer
5349 if (PowerType == POWER_MANA && m_powerCost > 0)
5350 {
5352 }
5353}
@ SPELLMOD_SPELL_COST_REFUND_ON_FAIL
Definition: SpellDefines.h:107
@ SPELL_MISS_ABSORB
Definition: SharedDefines.h:1529
int32 ModifyHealth(int32 val)
Definition: Unit.cpp:14079
void SetLastManaUse(uint32 spellCastTime)
Definition: Unit.h:2231
void TakeRunePower(bool didHit)
Definition: Spell.cpp:5438

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

Referenced by _cast().

◆ TakeReagents()

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

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

Referenced by _cast().

◆ TakeRunePower()

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

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

Referenced by TakePower().

◆ TriggerGlobalCooldown()

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

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

Referenced by prepare().

◆ update()

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

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

Referenced by SpellEvent::Execute().

◆ UpdateChanneledTargetList()

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

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 ( )
7824{
7827 else
7828 {
7831 m_originalCaster = nullptr;
7832 }
7833
7835 {
7837 // cast item not found, somehow the item is no longer where we expected
7838 if (!m_CastItem)
7839 return false;
7840 }
7841 else
7842 m_CastItem = nullptr;
7843
7845
7846 // further actions done only for dest targets
7847 if (!m_targets.HasDst())
7848 return true;
7849
7850 // cache last transport
7851 WorldObject* transport = nullptr;
7852
7853 // update effect destinations (in case of moved transport dest target)
7854 for (uint8 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
7855 {
7856 SpellDestination& dest = m_destTargets[effIndex];
7857 if (!dest._transportGUID)
7858 continue;
7859
7860 if (!transport || transport->GetGUID() != dest._transportGUID)
7862
7863 if (transport)
7864 {
7865 dest._position.Relocate(transport);
7867 }
7868 }
7869
7870 return true;
7871}
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:478

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

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

◆ WriteAmmoToPacket()

void Spell::WriteAmmoToPacket ( WorldPacket data)
4905{
4906 uint32 ammoInventoryType = 0;
4907 uint32 ammoDisplayID = 0;
4908
4910 {
4912 if (pItem)
4913 {
4914 ammoInventoryType = pItem->GetTemplate()->InventoryType;
4915 if (ammoInventoryType == INVTYPE_THROWN)
4916 ammoDisplayID = pItem->GetTemplate()->DisplayInfoID;
4917 else
4918 {
4920 if (ammoID)
4921 {
4922 ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(ammoID);
4923 if (pProto)
4924 {
4925 ammoDisplayID = pProto->DisplayInfoID;
4926 ammoInventoryType = pProto->InventoryType;
4927 }
4928 }
4929 else if (m_caster->HasAura(46699)) // Requires No Ammo
4930 {
4931 ammoDisplayID = 5996; // normal arrow
4932 ammoInventoryType = INVTYPE_AMMO;
4933 }
4934 }
4935 }
4936 }
4937 else
4938 {
4939 uint32 nonRangedAmmoDisplayID = 0;
4940 uint32 nonRangedAmmoInventoryType = 0;
4941 for (uint8 i = 0; i < 3; ++i)
4942 {
4944 {
4945 if (ItemEntry const* itemEntry = sItemStore.LookupEntry(item_id))
4946 {
4947 if (itemEntry->ClassID == ITEM_CLASS_WEAPON)
4948 {
4949 switch (itemEntry->SubclassID)
4950 {
4952 ammoDisplayID = itemEntry->DisplayInfoID;
4953 ammoInventoryType = itemEntry->InventoryType;
4954 break;
4957 ammoDisplayID = 5996; // is this need fixing?
4958 ammoInventoryType = INVTYPE_AMMO;
4959 break;
4961 ammoDisplayID = 5998; // is this need fixing?
4962 ammoInventoryType = INVTYPE_AMMO;
4963 break;
4964 default:
4965 nonRangedAmmoDisplayID = itemEntry->DisplayInfoID;
4966 nonRangedAmmoInventoryType = itemEntry->InventoryType;
4967 break;
4968 }
4969
4970 if (ammoDisplayID)
4971 break;
4972 }
4973 }
4974 }
4975 }
4976
4977 if (!ammoDisplayID && !ammoInventoryType)
4978 {
4979 ammoDisplayID = nonRangedAmmoDisplayID;
4980 ammoInventoryType = nonRangedAmmoInventoryType;
4981 }
4982 }
4983
4984 *data << uint32(ammoDisplayID);
4985 *data << uint32(ammoInventoryType);
4986}
DBCStorage< ItemEntry > sItemStore(Itemfmt)
@ INVTYPE_AMMO
Definition: ItemTemplate.h:289
@ UNIT_VIRTUAL_ITEM_SLOT_ID
Definition: UpdateFields.h:116
uint32 DisplayInfoID
Definition: ItemTemplate.h:634
Definition: DBCStructure.h:1131

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

Referenced by SendSpellGo(), and SendSpellStart().

◆ WriteCastResultInfo()

void Spell::WriteCastResultInfo ( WorldPacket data,
Player caster,
SpellInfo const *  spellInfo,
uint8  castCount,
SpellCastResult  result,
SpellCustomErrors  customError 
)
static
4541{
4542 data << uint8(castCount); // single cast or multi 2.3 (0/1)
4543 data << uint32(spellInfo->Id);
4544 data << uint8(result); // problem
4545 switch (result)
4546 {
4548 data << uint32(spellInfo->RequiresSpellFocus); // SpellFocusObject.dbc id
4549 break;
4550 case SPELL_FAILED_REQUIRES_AREA: // AreaTable.dbc id
4551 // hardcode areas limitation case
4552 switch (spellInfo->Id)
4553 {
4554 case 41617: // Cenarion Mana Salve
4555 case 41619: // Cenarion Healing Salve
4556 data << uint32(3905);
4557 break;
4558 case 41618: // Bottled Nethergon Energy
4559 case 41620: // Bottled Nethergon Vapor
4560 data << uint32(3842);
4561 break;
4562 case 45373: // Bloodberry Elixir
4563 data << uint32(4075);
4564 break;
4565 default: // default case (don't must be)
4566 data << uint32(0);
4567 break;
4568 }
4569 break;
4571 if (spellInfo->Totem[0])
4572 data << uint32(spellInfo->Totem[0]);
4573 if (spellInfo->Totem[1])
4574 data << uint32(spellInfo->Totem[1]);
4575 break;
4577 if (spellInfo->TotemCategory[0])
4578 data << uint32(spellInfo->TotemCategory[0]);
4579 if (spellInfo->TotemCategory[1])
4580 data << uint32(spellInfo->TotemCategory[1]);
4581 break;
4585 data << uint32(spellInfo->EquippedItemClass);
4586 data << uint32(spellInfo->EquippedItemSubClassMask);
4587 break;
4589 {
4590 uint32 item = 0;
4591 for (int8 eff = 0; eff < MAX_SPELL_EFFECTS; eff++)
4592 if (spellInfo->Effects[eff].ItemType)
4593 item = spellInfo->Effects[eff].ItemType;
4594 ItemTemplate const* proto = sObjectMgr->GetItemTemplate(item);
4595 if (proto && proto->ItemLimitCategory)
4596 data << uint32(proto->ItemLimitCategory);
4597 break;
4598 }
4600 data << uint32(customError);
4601 break;
4603 {
4604 uint32 missingItem = 0;
4605 for (uint32 i = 0; i < MAX_SPELL_REAGENTS; i++)
4606 {
4607 if (spellInfo->Reagent[i] <= 0)
4608 continue;
4609
4610 uint32 itemid = spellInfo->Reagent[i];
4611 uint32 itemcount = spellInfo->ReagentCount[i];
4612
4613 if (!caster->HasItemCount(itemid, itemcount))
4614 {
4615 missingItem = itemid;
4616 break;
4617 }
4618 }
4619
4620 data << uint32(missingItem); // first missing item
4621 break;
4622 }
4624 data << uint32(spellInfo->Mechanic);
4625 break;
4627 data << uint32(spellInfo->EquippedItemSubClassMask);
4628 break;
4630 data << uint32(0); // Item entry
4631 data << uint32(0); // Count
4632 break;
4634 data << uint32(0); // SkillLine.dbc Id
4635 data << uint32(0); // Amount
4636 break;
4638 data << uint32(0); // Skill level
4639 break;
4640 default:
4641 break;
4642 }
4643}
@ 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.

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

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

Referenced by SendSpellGo().

Friends And Related Function Documentation

◆ SpellScript

friend class SpellScript
friend

◆ Unit::SetCurrentCastedSpell

void Unit::SetCurrentCastedSpell ( Spell pSpell)
friend

Member Data Documentation

◆ _scriptsLoaded

bool Spell::_scriptsLoaded
protected

Referenced by LoadScripts(), and Spell().

◆ _spellEvent

SpellEvent* Spell::_spellEvent
protected

◆ _spellTargetsSelected

bool Spell::_spellTargetsSelected
protected

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

◆ _triggeredCastFlags

◆ damage

◆ destTarget

◆ effectHandleMode

SpellEffectHandleMode Spell::effectHandleMode
protected

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

◆ focusObject

◆ gameObjTarget

◆ itemTarget

◆ m_appliedMods

◆ m_applyMultiplierMask

uint8 Spell::m_applyMultiplierMask
protected

◆ m_attackType

◆ m_auraScaleMask

uint8 Spell::m_auraScaleMask
protected

◆ m_autoRepeat

bool Spell::m_autoRepeat
protected

◆ m_canReflect

bool Spell::m_canReflect
protected

Referenced by AddUnitTarget(), and Spell().

◆ m_cast_count

◆ m_caster

Unit* const Spell::m_caster
protected

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

◆ m_CastItem

◆ m_castItemGUID

◆ m_casttime

◆ m_channeledDuration

int32 Spell::m_channeledDuration
protected

◆ m_channelTargetEffectMask

uint8 Spell::m_channelTargetEffectMask
protected

◆ m_comboPointGain

int8 Spell::m_comboPointGain

◆ m_comboTarget

Unit* Spell::m_comboTarget

◆ m_customError

◆ m_damage

◆ m_damageMultipliers

float Spell::m_damageMultipliers[3]
protected

◆ m_delayAtDamageCount

uint8 Spell::m_delayAtDamageCount
protected

Referenced by isDelayableNoMore(), and Spell().

◆ m_delayMoment

◆ m_delayStart

uint64 Spell::m_delayStart
protected

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

◆ m_delayTrajectory

uint64 Spell::m_delayTrajectory
protected

◆ m_destTargets

SpellDestination Spell::m_destTargets[MAX_SPELL_EFFECTS]
protected

◆ m_diminishGroup

DiminishingGroup Spell::m_diminishGroup
protected

◆ m_diminishLevel

DiminishingLevels Spell::m_diminishLevel
protected

◆ m_effectExecuteData

◆ m_executedCurrently

bool Spell::m_executedCurrently
protected

◆ m_glyphIndex

uint32 Spell::m_glyphIndex

◆ m_healing

◆ m_hitTriggerSpells

HitTriggerSpellList Spell::m_hitTriggerSpells
protected

◆ m_immediateHandled

bool Spell::m_immediateHandled
protected

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

◆ m_loadedScripts

◆ m_needComboPoints

bool Spell::m_needComboPoints
protected

◆ m_originalCaster

◆ m_originalCasterGUID

◆ m_powerCost

◆ m_preCastSpell

uint32 Spell::m_preCastSpell

◆ m_preGeneratedPath

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

Referenced by CheckCast(), and EffectCharge().

◆ m_procAttacker

uint32 Spell::m_procAttacker
protected

◆ m_procEx

uint32 Spell::m_procEx
protected

◆ m_procVictim

uint32 Spell::m_procVictim
protected

◆ m_referencedFromCurrentSpell

bool Spell::m_referencedFromCurrentSpell
protected

◆ m_runesState

uint8 Spell::m_runesState
protected

◆ m_selfContainer

Spell** Spell::m_selfContainer
protected

◆ m_skipCheck

bool Spell::m_skipCheck
protected

Referenced by AddUnitTarget(), and Spell().

◆ m_spellAura

◆ m_spellFlags

◆ m_spellInfo

SpellInfo const* const Spell::m_spellInfo

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

◆ m_spellSchoolMask

◆ m_spellState

uint32 Spell::m_spellState
protected

◆ m_spellValue

◆ m_targets

SpellCastTargets Spell::m_targets

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

◆ m_timer

◆ m_triggeredByAuraSpell

◆ m_UniqueGOTargetInfo

◆ m_UniqueItemInfo

◆ m_UniqueTargetInfo

◆ m_weaponItem

Item* Spell::m_weaponItem

◆ unitTarget

Unit* Spell::unitTarget
protected

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