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, Acore::WorldObjectSpellAreaTargetSearchReason searchReason=Acore::WorldObjectSpellAreaTargetSearchReason::Area)
 
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, uint32 *param1=nullptr, uint32 *param2=nullptr)
 
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 (uint32 *param1=nullptr, uint32 *param2=nullptr)
 
SpellCastResult CheckSpellFocus ()
 
SpellCastResult CheckRange (bool strict)
 
SpellCastResult CheckPower ()
 
SpellCastResult CheckRuneCost (uint32 RuneCostID)
 
SpellCastResult CheckCasterAuras (bool preventionOnly) const
 
int32 CalculateSpellDamage (uint8 i, Unit const *target) const
 
bool HaveTargetsForEffect (uint8 effect) const
 
void Delayed ()
 
void DelayedChannel ()
 
uint32 getState () const
 
void setState (uint32 state)
 
void DoCreateItem (uint8 effIndex, uint32 itemId)
 
void WriteSpellGoTargets (WorldPacket *data)
 Writes miss and hit targets for a SMSG_SPELL_GO packet.
 
void WriteAmmoToPacket (WorldPacket *data)
 
bool CheckEffectTarget (Unit const *target, uint32 eff) const
 
bool CanAutoCast (Unit *target)
 
void CheckSrc ()
 
void CheckDst ()
 
void SendCastResult (SpellCastResult result)
 
void SendPetCastResult (SpellCastResult result)
 
void SendSpellStart ()
 
void SendSpellGo ()
 
void SendSpellCooldown ()
 
void SendLogExecute ()
 
void ExecuteLogEffectTakeTargetPower (uint8 effIndex, Unit *target, uint32 PowerType, uint32 powerTaken, float gainMultiplier)
 
void ExecuteLogEffectExtraAttacks (uint8 effIndex, Unit *victim, uint32 attCount)
 
void ExecuteLogEffectInterruptCast (uint8 effIndex, Unit *victim, uint32 spellId)
 
void ExecuteLogEffectDurabilityDamage (uint8 effIndex, Unit *victim, int32 itemId, int32 slot)
 
void ExecuteLogEffectOpenLock (uint8 effIndex, Object *obj)
 
void ExecuteLogEffectCreateItem (uint8 effIndex, uint32 entry)
 
void ExecuteLogEffectDestroyItem (uint8 effIndex, uint32 entry)
 
void ExecuteLogEffectSummonObject (uint8 effIndex, WorldObject *obj)
 
void ExecuteLogEffectUnsummonObject (uint8 effIndex, WorldObject *obj)
 
void ExecuteLogEffectResurrect (uint8 effIndex, Unit *target)
 
void SendInterrupted (uint8 result)
 
void SendChannelUpdate (uint32 time)
 
void SendChannelStart (uint32 duration)
 
void SendResurrectRequest (Player *target)
 
void HandleEffects (Unit *pUnitTarget, Item *pItemTarget, GameObject *pGOTarget, uint32 i, SpellEffectHandleMode mode)
 
void HandleThreatSpells ()
 
void AddComboPointGain (Unit *target, int8 amount)
 
int32 GetCastTime () const
 
bool IsAutoRepeat () const
 
void SetAutoRepeat (bool rep)
 
void ReSetTimer ()
 
int32 GetCastTimeRemaining ()
 
bool IsNextMeleeSwingSpell () const
 
bool IsTriggered () const
 
bool HasTriggeredCastFlag (TriggerCastFlags flag) const
 
bool IsProcDisabled () 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
 
UnitGetOriginalTarget () 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
 
SpellInfo const * GetTriggeredByAuraSpellInfo () 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
 
ObjectGuid m_originalTargetGUID
 
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
 
Unitm_reflectionTarget
 
ObjectGuid m_reflectionTargetGuid
 
Position m_reflectionTargetPosition
 
Auram_spellAura
 
DiminishingLevels m_diminishLevel
 
DiminishingGroup m_diminishGroup
 
GameObjectfocusObject
 
int32 m_damage
 
int32 m_healing
 
int32 m_damageBeforeTakenMods
 
uint32 m_procAttacker
 
uint32 m_procVictim
 
uint32 m_procEx
 
std::list< TargetInfom_UniqueTargetInfo
 
uint8 m_channelTargetEffectMask
 
std::list< GOTargetInfom_UniqueGOTargetInfo
 
std::list< ItemTargetInfom_UniqueItemInfo
 
SpellDestination m_destTargets [MAX_SPELL_EFFECTS]
 
bool _scriptsLoaded
 
std::list< SpellScript * > m_loadedScripts
 
HitTriggerSpellList m_hitTriggerSpells
 
uint32 m_spellState
 
int32 m_timer
 
SpellEvent_spellEvent
 
TriggerCastFlags _triggeredCastFlags
 
TriggeredByAuraSpellData m_triggeredByAuraSpell
 
bool m_skipCheck
 
uint8 m_auraScaleMask
 
std::unique_ptr< PathGeneratorm_preGeneratedPath
 
bool _spellTargetsSelected
 
ByteBufferm_effectExecuteData [MAX_SPELL_EFFECTS]
 

Friends

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

Detailed Description

Member Typedef Documentation

◆ HitTriggerSpellList

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

◆ UsedSpellMods

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

Constructor & Destructor Documentation

◆ Spell()

Spell::Spell ( Unit caster,
SpellInfo const *  info,
TriggerCastFlags  triggerFlags,
ObjectGuid  originalCasterGUID = ObjectGuid::Empty,
bool  skipCheck = false 
)
571 :
572 m_spellInfo(sSpellMgr->GetSpellForDifficultyFromSpell(info, caster)),
573 m_caster((info->HasAttribute(SPELL_ATTR6_ORIGINATE_FROM_CONTROLLER) && caster->GetCharmerOrOwner()) ? caster->GetCharmerOrOwner() : caster)
575{
577 m_skipCheck = skipCheck;
578 m_selfContainer = nullptr;
580 m_executedCurrently = false;
583 m_comboTarget = nullptr;
584 m_delayStart = 0;
586
588 m_auraScaleMask = 0;
589 memset(m_damageMultipliers, 0, sizeof(m_damageMultipliers));
590
591 // Get data for type of attack
592 switch (m_spellInfo->DmgClass)
593 {
597 else
599 break;
602 break;
603 default:
604 // Wands
607 else
609 break;
610 }
611
612 m_spellSchoolMask = info->GetSchoolMask(); // Can be override for some spell (wand shoot for example)
613
615 // wand case
618 m_spellSchoolMask = SpellSchoolMask(1 << pItem->GetTemplate()->Damage[0].DamageType);
619
620 if (originalCasterGUID)
621 m_originalCasterGUID = originalCasterGUID;
622 else
624
627 else
628 {
631 m_originalCaster = nullptr;
632 }
633
635 _triggeredCastFlags = triggerFlags;
636 if (info->HasAttribute(SPELL_ATTR4_ALLOW_CAST_WHILE_CASTING))
638
639 m_CastItem = nullptr;
640
641 unitTarget = nullptr;
642 itemTarget = nullptr;
643 gameObjTarget = nullptr;
644 destTarget = nullptr;
645 damage = 0;
646 m_reflectionTarget = nullptr;
651 m_damage = 0;
652 m_healing = 0;
654 m_procAttacker = 0;
655 m_procVictim = 0;
656 m_procEx = 0;
657 focusObject = nullptr;
658 m_cast_count = 0;
659 m_glyphIndex = 0;
660 m_preCastSpell = 0;
661 m_spellAura = nullptr;
662 _scriptsLoaded = false;
663
664 //Auto Shot & Shoot (wand)
666
667 m_runesState = 0;
668 m_powerCost = 0; // setup to correct value in Spell::prepare, must not be used before.
669 m_casttime = 0; // setup to correct value in Spell::prepare, must not be used before.
670 m_timer = 0; // will set to castime in prepare
671 m_channeledDuration = 0; // will be setup in Spell::handle_immediate
672 m_immediateHandled = false;
673
675
677
678 // Determine if spell can be reflected back to the caster
679 // Patch 1.2 notes: Spell Reflection no longer reflects abilities
683
685 memset(m_effectExecuteData, 0, MAX_SPELL_EFFECTS * sizeof(ByteBuffer*));
686
687 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
689
690 // xinef:
691 _spellTargetsSelected = false;
692
693 m_weaponItem = nullptr;
694}
#define MAX_SPELL_EFFECTS
Definition DBCStructure.h:1637
std::uint8_t uint8
Definition Define.h:109
std::uint32_t uint32
Definition Define.h:107
@ DIMINISHING_NONE
Definition SharedDefines.h:3491
@ SPELL_EFFECT_DISPEL
Definition SharedDefines.h:804
#define CLASSMASK_WAND_USERS
Definition SharedDefines.h:151
@ SPELL_ATTR2_AUTO_REPEAT
Definition SharedDefines.h:449
@ SPELL_ATTR1_NO_REFLECTION
Definition SharedDefines.h:414
@ SPELL_ATTR3_REQUIRES_OFF_HAND_WEAPON
Definition SharedDefines.h:505
@ SPELL_DAMAGE_CLASS_RANGED
Definition SharedDefines.h:1552
@ SPELL_DAMAGE_CLASS_MAGIC
Definition SharedDefines.h:1550
@ SPELL_DAMAGE_CLASS_MELEE
Definition SharedDefines.h:1551
@ SPELL_CUSTOM_ERROR_NONE
Definition SharedDefines.h:1131
@ SPELL_ATTR0_IS_ABILITY
Definition SharedDefines.h:374
@ SPELL_ATTR0_NO_IMMUNITIES
Definition SharedDefines.h:399
@ SPELL_ATTR4_ALLOW_CAST_WHILE_CASTING
Definition SharedDefines.h:525
@ SPELL_ATTR6_ORIGINATE_FROM_CONTROLLER
Definition SharedDefines.h:610
SpellSchoolMask
Definition SharedDefines.h:283
TriggerCastFlags
Definition SpellDefines.h:132
@ TRIGGERED_CAST_DIRECTLY
Will ignore combo point requirement.
Definition SpellDefines.h:141
@ TRIGGERED_IGNORE_CAST_IN_PROGRESS
Will ignore aura scaling.
Definition SpellDefines.h:139
#define sSpellMgr
Definition SpellMgr.h:847
@ SPELL_EFFECT_HANDLE_LAUNCH
Definition Spell.h:246
@ SPELL_FLAG_NORMAL
Definition Spell.h:93
@ SPELL_STATE_NULL
Definition Spell.h:236
@ OFF_ATTACK
Definition Unit.h:216
@ BASE_ATTACK
Definition Unit.h:215
@ RANGED_ATTACK
Definition Unit.h:217
@ DIMINISHING_LEVEL_1
Definition Unit.h:269
Definition ByteBuffer.h:70
Definition Item.h:220
void Clear()
Definition ObjectGuid.h:138
bool IsPlayer() const
Definition Object.h:201
Player * ToPlayer()
Definition Object.h:202
bool IsInWorld() const
Definition Object.h:109
static ObjectGuid GetGUID(Object const *o)
Definition Object.h:114
Item * GetWeaponForAttack(WeaponAttackType attackType, bool useable=false) const
Definition PlayerStorage.cpp:491
bool IsPassive() const
Definition SpellInfo.cpp:1130
bool NeedsComboPoints() const
Definition SpellInfo.cpp:1298
bool HasAttribute(SpellAttr0 attribute) const
Definition SpellInfo.h:441
bool HasEffect(SpellEffects effect) const
Definition SpellInfo.cpp:885
bool IsPositive() const
Definition SpellInfo.cpp:1269
bool IsAutoRepeatRangedSpell() const
Definition SpellInfo.cpp:1315
uint32 DmgClass
Definition SpellInfo.h:413
bool IsRangedWeaponSpell() const
Definition SpellInfo.cpp:1308
Unit * m_comboTarget
Definition Spell.h:557
int8 m_comboPointGain
Definition Spell.h:558
GameObject * gameObjTarget
Definition Spell.h:674
bool m_referencedFromCurrentSpell
Definition Spell.h:665
bool m_canReflect
Definition Spell.h:641
uint32 m_procVictim
Definition Spell.h:700
Unit * m_originalCaster
Definition Spell.h:627
bool m_needComboPoints
Definition Spell.h:667
uint64 m_delayStart
Definition Spell.h:659
bool _scriptsLoaded
Definition Spell.h:751
TriggerCastFlags _triggeredCastFlags
Definition Spell.h:792
int32 damage
Definition Spell.h:676
SpellEffectHandleMode effectHandleMode
Definition Spell.h:677
int32 m_channeledDuration
Definition Spell.h:640
Aura * m_spellAura
Definition Spell.h:682
SpellDestination m_destTargets[MAX_SPELL_EFFECTS]
Definition Spell.h:726
Unit *const m_caster
Definition Spell.h:621
uint8 m_delayAtDamageCount
Definition Spell.h:648
WeaponAttackType m_attackType
Definition Spell.h:637
bool m_immediateHandled
Definition Spell.h:662
uint32 m_spellState
Definition Spell.h:788
ObjectGuid m_originalCasterGUID
Definition Spell.h:625
void CleanupTargetList()
Definition Spell.cpp:2304
int32 m_timer
Definition Spell.h:789
int32 m_casttime
Definition Spell.h:639
Item * itemTarget
Definition Spell.h:673
uint8 m_cast_count
Definition Spell.h:539
int32 m_damage
Definition Spell.h:692
bool m_executedCurrently
Definition Spell.h:666
DiminishingLevels m_diminishLevel
Definition Spell.h:685
float m_damageMultipliers[3]
Definition Spell.h:669
ByteBuffer * m_effectExecuteData[MAX_SPELL_EFFECTS]
Definition Spell.h:806
uint8 m_auraScaleMask
Definition Spell.h:800
int32 m_damageBeforeTakenMods
Definition Spell.h:694
SpellCustomErrors m_customError
Definition Spell.h:543
uint8 m_spellFlags
Definition Spell.h:643
bool m_skipCheck
Definition Spell.h:799
int32 m_healing
Definition Spell.h:693
uint32 m_glyphIndex
Definition Spell.h:540
uint8 m_channelTargetEffectMask
Definition Spell.h:708
Item * m_weaponItem
Definition Spell.h:537
Unit * unitTarget
Definition Spell.h:672
SpellSchoolMask m_spellSchoolMask
Definition Spell.h:636
Unit * m_reflectionTarget
Definition Spell.h:678
SpellEvent * _spellEvent
Definition Spell.h:791
bool _spellTargetsSelected
Definition Spell.h:804
ObjectGuid m_reflectionTargetGuid
Definition Spell.h:679
uint32 m_preCastSpell
Definition Spell.h:541
WorldLocation * destTarget
Definition Spell.h:675
Spell ** m_selfContainer
Definition Spell.h:631
uint8 m_applyMultiplierMask
Definition Spell.h:668
DiminishingGroup m_diminishGroup
Definition Spell.h:686
uint32 m_procEx
Definition Spell.h:701
Item * m_CastItem
Definition Spell.h:536
SpellValue *const m_spellValue
Definition Spell.h:623
int32 m_powerCost
Definition Spell.h:638
uint32 m_procAttacker
Definition Spell.h:699
GameObject * focusObject
Definition Spell.h:689
SpellInfo const *const m_spellInfo
Definition Spell.h:535
uint8 m_runesState
Definition Spell.h:646
bool m_autoRepeat
Definition Spell.h:645
Unit * GetCharmerOrOwner() const
Definition Unit.h:1286
uint32 getClassMask() const
Definition Unit.h:845
Unit * GetUnit(WorldObject const &, ObjectGuid const &guid)
Definition ObjectAccessor.cpp:199
Definition Spell.h:106
Definition Spell.h:223

References _scriptsLoaded, _spellTargetsSelected, _triggeredCastFlags, BASE_ATTACK, CLASSMASK_WAND_USERS, CleanupTargetList(), ObjectGuid::Clear(), damage, destTarget, DIMINISHING_LEVEL_1, DIMINISHING_NONE, SpellInfo::DmgClass, effectHandleMode, focusObject, gameObjTarget, Unit::getClassMask(), Object::GetGUID(), SpellInfo::GetSchoolMask(), ObjectAccessor::GetUnit(), Player::GetWeaponForAttack(), SpellInfo::HasAttribute(), SpellInfo::HasEffect(), SpellInfo::IsAutoRepeatRangedSpell(), Object::IsInWorld(), SpellInfo::IsPassive(), Object::IsPlayer(), SpellInfo::IsPositive(), SpellInfo::IsRangedWeaponSpell(), itemTarget, m_applyMultiplierMask, m_attackType, m_auraScaleMask, m_autoRepeat, m_canReflect, m_cast_count, m_caster, m_CastItem, m_casttime, m_channeledDuration, m_channelTargetEffectMask, m_comboPointGain, m_comboTarget, m_customError, m_damage, m_damageBeforeTakenMods, 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_reflectionTarget, m_reflectionTargetGuid, m_runesState, m_selfContainer, m_skipCheck, m_spellAura, m_spellFlags, m_spellInfo, m_spellSchoolMask, m_spellState, m_timer, m_weaponItem, MAX_SPELL_EFFECTS, SpellInfo::NeedsComboPoints(), OFF_ATTACK, RANGED_ATTACK, SPELL_ATTR0_IS_ABILITY, SPELL_ATTR0_NO_IMMUNITIES, SPELL_ATTR1_NO_REFLECTION, SPELL_ATTR2_AUTO_REPEAT, SPELL_ATTR3_REQUIRES_OFF_HAND_WEAPON, SPELL_ATTR4_ALLOW_CAST_WHILE_CASTING, SPELL_CUSTOM_ERROR_NONE, SPELL_DAMAGE_CLASS_MAGIC, SPELL_DAMAGE_CLASS_MELEE, SPELL_DAMAGE_CLASS_RANGED, SPELL_EFFECT_DISPEL, SPELL_EFFECT_HANDLE_LAUNCH, SPELL_FLAG_NORMAL, SPELL_STATE_NULL, Object::ToPlayer(), TRIGGERED_CAST_DIRECTLY, TRIGGERED_IGNORE_CAST_IN_PROGRESS, and unitTarget.

Referenced by Creature::HasSpellFocus().

◆ ~Spell()

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

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

3765{
3766 // update pointers base at GUIDs to prevent access to non-existed already object
3767 if (!UpdatePointers())
3768 {
3769 // cancel the spell if UpdatePointers() returned false, something wrong happened there
3770 cancel();
3771 return;
3772 }
3773
3774 // cancel at lost explicit target during cast
3776 {
3777 cancel();
3778 return;
3779 }
3780
3781 // Xinef: implement attribute SPELL_ATTR1_DISMISS_PET_FIRST, on spell cast current pet is dismissed and charms are removed
3783 {
3785 if (Pet* pet = m_caster->ToPlayer()->GetPet())
3787
3788 if (Unit* charm = m_caster->GetCharm())
3789 charm->RemoveAurasByType(SPELL_AURA_MOD_CHARM, m_caster->GetGUID());
3790 }
3791
3792 if (Player* playerCaster = m_caster->ToPlayer())
3793 {
3794 // now that we've done the basic check, now run the scripts
3795 // should be done before the spell is actually executed
3796 sScriptMgr->OnPlayerSpellCast(playerCaster, this, skipCheck);
3797
3798 // As of 3.0.2 pets begin attacking their owner's target immediately
3799 // Let any pets know we've attacked something. Check DmgClass for harmful spells only
3800 // This prevents spells such as Hunter's Mark from triggering pet attack
3801 // xinef: take into account SPELL_ATTR3_SUPPRESS_TARGET_PROCS
3803 if (!playerCaster->m_Controlled.empty())
3804 for (Unit::ControlSet::iterator itr = playerCaster->m_Controlled.begin(); itr != playerCaster->m_Controlled.end(); ++itr)
3805 if (Unit* pet = *itr)
3806 if (pet->IsAlive() && pet->IsCreature())
3807 pet->ToCreature()->AI()->OwnerAttacked(m_targets.GetUnitTarget());
3808 }
3809
3811
3815
3817
3818 Player* modOwner = m_caster->GetSpellModOwner();
3819 // skip check if done already (for instant cast spells for example)
3820 if (!skipCheck)
3821 {
3822 SpellCastResult castResult = CheckCast(false);
3823 if (castResult != SPELL_CAST_OK)
3824 {
3825 SendCastResult(castResult);
3826 SendInterrupted(0);
3827
3828 finish(false);
3829 SetExecutedCurrently(false);
3830 return;
3831 }
3832
3833 // additional check after cast bar completes (must not be in CheckCast)
3834 // if trade not complete then remember it in trade data
3836 {
3837 if (m_caster->IsPlayer())
3838 {
3839 if (TradeData* my_trade = m_caster->ToPlayer()->GetTradeData())
3840 {
3841 if (!my_trade->IsInAcceptProcess())
3842 {
3843 // Spell will be casted at completing the trade. Silently ignore at this place
3844 my_trade->SetSpell(m_spellInfo->Id, m_CastItem);
3846 SendInterrupted(0);
3847
3848 finish(false);
3849 SetExecutedCurrently(false);
3850 return;
3851 }
3852 }
3853 }
3854 }
3855 }
3856
3857 if (modOwner)
3858 modOwner->SetSpellModTakingSpell(this, true);
3859
3862
3863 if (modOwner)
3864 modOwner->SetSpellModTakingSpell(this, false);
3865
3866 // Spell may be finished after target map check
3868 {
3869 SendInterrupted(0);
3870 finish(false);
3871 SetExecutedCurrently(false);
3872 return;
3873 }
3874
3875 if (modOwner)
3876 modOwner->SetSpellModTakingSpell(this, true);
3877
3879
3881
3882 if (modOwner)
3883 modOwner->SetSpellModTakingSpell(this, false);
3884
3885 // traded items have trade slot instead of guid in m_itemTargetGUID
3886 // set to real guid to be sent later to the client
3888
3889 if (m_caster->IsPlayer())
3890 {
3892 {
3895 }
3896
3898 }
3899
3901 {
3902 // Powers have to be taken before SendSpellGo
3903 TakePower();
3904 TakeReagents(); // we must remove reagents before HandleEffects to allow place crafted item in same slot
3905 }
3906 else if (Item* targetItem = m_targets.GetItemTarget())
3907 {
3909 if (targetItem->GetOwnerGUID() != m_caster->GetGUID())
3910 TakeReagents();
3911 }
3912
3914
3915 // CAST SPELL
3916 if (modOwner)
3917 modOwner->SetSpellModTakingSpell(this, true);
3918
3920
3922
3923 // we must send smsg_spell_go packet before m_castItem delete in TakeCastItem()...
3924 SendSpellGo();
3925
3927 if (resetAttackTimers)
3928 {
3930 for (Unit::AuraEffectList::const_iterator i = vIgnoreReset.begin(); i != vIgnoreReset.end(); ++i)
3931 {
3932 if ((*i)->IsAffectedOnSpell(m_spellInfo))
3933 {
3934 resetAttackTimers = false;
3935 break;
3936 }
3937 }
3938 }
3939
3940 // Okay, everything is prepared. Now we need to distinguish between immediate and evented delayed spells
3941 if ((m_spellInfo->Speed > 0.0f && !m_spellInfo->IsChanneled())/* xinef: we dont need this || m_spellInfo->Id == 14157*/)
3942 {
3943 // Remove used for cast item if need (it can be already nullptr after TakeReagents call
3944 // in case delayed spell remove item at cast delay start
3945 TakeCastItem();
3946
3947 // Okay, maps created, now prepare flags
3948 m_immediateHandled = false;
3950 SetDelayStart(0);
3951
3954
3955 // remove all applied mods at this point
3956 // dont allow user to use them twice in case spell did not reach current target
3957 if (modOwner)
3958 modOwner->RemoveSpellMods(this);
3959
3960 // Xinef: why do we keep focus after spell is sent to air?
3961 // Xinef: Because of this, in the middle of some animation after setting targetguid to 0 etc
3962 // Xinef: we get focused to it out of nowhere...
3963 if (Creature* creatureCaster = m_caster->ToCreature())
3964 creatureCaster->ReleaseFocus(this);
3965 }
3966 else
3967 {
3968 // Immediate spell, no big deal
3970 }
3971
3972 if (resetAttackTimers)
3973 {
3974 if (m_casttime == 0 && m_spellInfo->CalcCastTime())
3975 {
3976 resetAttackTimers = false;
3977 }
3978
3979 if (resetAttackTimers)
3980 {
3982
3984 {
3986 }
3987
3989 }
3990 }
3991
3993
3994 if (modOwner)
3995 modOwner->SetSpellModTakingSpell(this, false);
3996
3997 // Handle procs on cast - only for non-triggered spells
3998 // Triggered spells (from auras, items, etc.) should not fire CAST phase procs
3999 // as they are not player-initiated casts. This prevents issues like Arcane Potency
4000 // charges being consumed by periodic damage effects (e.g., Blizzard ticks).
4001 // Must be called AFTER handle_immediate() so spell mods (like Missile Barrage's
4002 // duration reduction) are applied before the aura is consumed by the proc.
4003 if (m_originalCaster && !IsTriggered())
4004 {
4005 uint32 procAttacker = m_procAttacker;
4006 if (!procAttacker)
4007 {
4008 bool IsPositive = m_spellInfo->IsPositive();
4010 {
4012 }
4013 else
4014 {
4016 }
4017 }
4018
4019 uint32 hitMask = PROC_HIT_NORMAL;
4020
4021 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
4022 {
4023 if (ihit->missCondition != SPELL_MISS_NONE)
4024 continue;
4025
4026 if (!ihit->crit)
4027 continue;
4028
4029 hitMask |= PROC_HIT_CRITICAL;
4030 break;
4031 }
4032
4035 }
4036
4037 if (std::vector<int32> const* spell_triggered = sSpellMgr->GetSpellLinked(m_spellInfo->Id))
4038 {
4039 for (int32 id : *spell_triggered)
4040 {
4041 if (id < 0)
4043 else
4045 }
4046 }
4047
4048 // Interrupt Spell casting
4049 // handle this here, in other places SpellHitTarget can be set to nullptr, if there is an error in this function
4051 if (Unit* target = m_targets.GetUnitTarget())
4052 if (target->IsCreature())
4053 m_caster->CastSpell(target, 32747, true);
4054
4055 if (m_caster->IsPlayer())
4058
4059 sScriptMgr->OnSpellCast(this, m_caster, m_spellInfo, skipCheck);
4060
4061 SetExecutedCurrently(false);
4062
4063 // Call CreatureAI hook on successful cast
4064 if (Creature* caster = m_caster->ToCreature())
4065 if (caster->IsAIEnabled)
4066 caster->AI()->OnSpellCast(GetSpellInfo());
4067}
@ ACHIEVEMENT_TIMED_TYPE_ITEM
Definition DBCEnums.h:115
@ ACHIEVEMENT_CRITERIA_TYPE_USE_ITEM
Definition DBCEnums.h:155
@ ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL
Definition DBCEnums.h:143
std::int32_t int32
Definition Define.h:103
@ PET_SAVE_AS_CURRENT
Definition PetDefines.h:43
@ CHEAT_COOLDOWN
Definition Player.h:997
#define sScriptMgr
Definition ScriptMgr.h:740
@ SPELL_ATTR7_CAN_CAUSE_INTERRUPT
Definition SharedDefines.h:640
@ SPELL_EFFECT_SUMMON_PET
Definition SharedDefines.h:822
@ SPELL_ATTR2_DO_NOT_RESET_COMBAT_TIMERS
Definition SharedDefines.h:461
@ SPELL_ATTR1_DISMISS_PET_FIRST
Definition SharedDefines.h:407
@ SPELL_ATTR3_SUPPRESS_TARGET_PROCS
Definition SharedDefines.h:498
@ SPELL_DAMAGE_CLASS_NONE
Definition SharedDefines.h:1549
@ SPELL_MISS_NONE
Definition SharedDefines.h:1523
SpellCastResult
Definition SharedDefines.h:936
@ SPELL_FAILED_DONT_REPORT
Definition SharedDefines.h:964
@ SPELL_CAST_OK
Definition SharedDefines.h:1126
@ SPELL_AURA_MOD_CHARM
Definition SpellAuraDefines.h:69
@ SPELL_AURA_IGNORE_MELEE_RESET
Definition SpellAuraDefines.h:335
@ TRIGGERED_IGNORE_POWER_AND_REAGENT_COST
Will ignore Spell and Category cooldowns.
Definition SpellDefines.h:136
@ TRIGGERED_IGNORE_CAST_ITEM
Will ignore power and reagent cost.
Definition SpellDefines.h:137
@ TRIGGERED_IGNORE_SET_FACING
Will ignore interruptible aura's at cast.
Definition SpellDefines.h:143
@ TARGET_FLAG_TRADE_ITEM
Definition SpellInfo.h:59
@ TARGET_FLAG_UNIT
Definition SpellInfo.h:48
@ PROC_HIT_CRITICAL
Definition SpellMgr.h:258
@ PROC_HIT_NORMAL
Definition SpellMgr.h:257
@ PROC_SPELL_PHASE_CAST
Definition SpellMgr.h:248
@ PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_POS
Definition SpellMgr.h:131
@ PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_POS
Definition SpellMgr.h:125
@ PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_NEG
Definition SpellMgr.h:128
@ PROC_FLAG_NONE
Definition SpellMgr.h:108
@ PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG
Definition SpellMgr.h:134
@ SPELL_STATE_DELAYED
Definition Spell.h:241
@ SPELL_STATE_FINISHED
Definition Spell.h:239
@ UNIT_STATE_CASTING
Definition UnitDefines.h:188
Definition Creature.h:47
uint32 GetEntry() const
Definition Object.h:117
bool IsCreature() const
Definition Object.h:205
Creature * ToCreature()
Definition Object.h:206
Definition Pet.h:41
Definition Player.h:1084
void UpdateAchievementCriteria(AchievementCriteriaTypes type, uint32 miscValue1=0, uint32 miscValue2=0, Unit *unit=nullptr)
Definition PlayerUpdates.cpp:2174
void SetSpellModTakingSpell(Spell *spell, bool apply)
Definition Player.cpp:10094
void StartTimedAchievement(AchievementCriteriaTimedTypes type, uint32 entry, uint32 timeLost=0)
Definition Player.cpp:14065
void RemoveSpellMods(Spell *spell)
Definition Player.cpp:10020
Pet * GetPet() const
Definition Player.cpp:8970
bool GetCommandStatus(uint32 command) const
Definition Player.h:1198
void RemovePet(Pet *pet, PetSaveMode mode, bool returnreagent=false)
Definition Player.cpp:9120
TradeData * GetTradeData() const
Definition Player.h:1396
void RemoveSpellCooldown(uint32 spell_id, bool update=false)
Definition Player.cpp:3532
WorldObject * GetObjectTarget() const
Definition Spell.cpp:311
void UpdateTradeSlotItem()
Definition Spell.cpp:348
ObjectGuid GetObjectTargetGUID() const
Definition Spell.cpp:316
Item * GetItemTarget() const
Definition Spell.h:151
uint32 GetTargetMask() const
Definition Spell.h:129
Unit * GetUnitTarget() const
Definition Spell.cpp:232
float Speed
Definition SpellInfo.h:394
bool IsChanneled() const
Definition SpellInfo.cpp:1288
uint32 CalcCastTime(Unit *caster=nullptr, Spell *spell=nullptr) const
Definition SpellInfo.cpp:2752
SpellInfo const * GetSpellInfo() const
Definition Spell.h:593
void CallScriptAfterCastHandlers()
Definition Spell.cpp:8602
void PrepareTriggersExecutedOnHit()
Definition Spell.cpp:8808
bool HasTriggeredCastFlag(TriggerCastFlags flag) const
Definition Spell.h:569
SpellCastTargets m_targets
Definition Spell.h:542
TriggeredByAuraSpellData m_triggeredByAuraSpell
Definition Spell.h:797
void handle_immediate()
Definition Spell.cpp:4069
void SendSpellGo()
Definition Spell.cpp:4767
void TakeReagents()
Definition Spell.cpp:5502
void SetExecutedCurrently(bool yes)
Definition Spell.h:578
void SendInterrupted(uint8 result)
Definition Spell.cpp:5144
void PrepareScriptHitHandlers()
Definition Spell.cpp:8634
void CallScriptOnCastHandlers()
Definition Spell.cpp:8589
void cancel(bool bySelf=false)
Definition Spell.cpp:3674
void SendSpellCooldown()
Definition Spell.cpp:4319
void CallScriptBeforeCastHandlers()
Definition Spell.cpp:8576
void HandleLaunchPhase()
Definition Spell.cpp:8270
bool UpdatePointers()
Definition Spell.cpp:7900
void SetDelayStart(uint64 m_time)
Definition Spell.h:580
std::list< TargetInfo > m_UniqueTargetInfo
Definition Spell.h:707
void SelectSpellTargets()
Definition Spell.cpp:823
void TakePower()
Definition Spell.cpp:5285
static void SendCastResult(Player *caster, SpellInfo const *spellInfo, uint8 castCount, SpellCastResult result, SpellCustomErrors customError=SPELL_CUSTOM_ERROR_NONE)
Definition Spell.cpp:4639
bool IsTriggered() const
Definition Spell.h:568
void TakeCastItem()
Definition Spell.cpp:5222
SpellCastResult CheckCast(bool strict, uint32 *param1=nullptr, uint32 *param2=nullptr)
Definition Spell.cpp:5630
bool IsAutoActionResetSpell() const
Definition Spell.cpp:8114
void finish(bool ok=true)
Definition Spell.cpp:4451
Definition TradeData.h:36
Definition Unit.h:664
bool HasOffhandWeaponForAttack() const
Definition Unit.h:990
void ClearUnitState(uint32 f)
Definition Unit.h:737
AuraEffectList const & GetAuraEffectsByType(AuraType type) const
Definition Unit.h:1428
Unit * GetCharm() const
Definition Unit.cpp:7788
std::vector< AuraEffect * > AuraEffectList
Definition Unit.h:680
Player * GetSpellModOwner() const
Definition Unit.cpp:12984
bool IsNonMeleeSpellCast(bool withDelayed, bool skipChanneled=false, bool skipAutorepeat=false, bool isAutoshoot=false, bool skipInstant=true) const
Definition Unit.cpp:4304
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:1389
void RemoveAurasDueToSpell(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, uint8 reqEffMask=0, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition Unit.cpp:5189
static void ProcSkillsAndAuras(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:6781
bool HasUnitState(const uint32 f) const
Definition Unit.h:736
void SetInFront(WorldObject const *target)
Definition Unit.cpp:16470
void resetAttackTimer(WeaponAttackType type=BASE_ATTACK)
Definition Unit.cpp:762
int8 effectIndex
Definition Spell.h:293
SpellInfo const * spellInfo
Definition Spell.h:292

References _spellTargetsSelected, ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL, ACHIEVEMENT_CRITERIA_TYPE_USE_ITEM, ACHIEVEMENT_TIMED_TYPE_ITEM, BASE_ATTACK, SpellInfo::CalcCastTime(), CallScriptAfterCastHandlers(), CallScriptBeforeCastHandlers(), CallScriptOnCastHandlers(), cancel(), Unit::CastSpell(), CHEAT_COOLDOWN, CheckCast(), Unit::ClearUnitState(), SpellInfo::DmgClass, TriggeredByAuraSpellData::effectIndex, finish(), Unit::GetAuraEffectsByType(), Unit::GetCharm(), Player::GetCommandStatus(), Object::GetEntry(), Object::GetGUID(), SpellCastTargets::GetItemTarget(), SpellCastTargets::GetObjectTarget(), SpellCastTargets::GetObjectTargetGUID(), Player::GetPet(), GetSpellInfo(), Unit::GetSpellModOwner(), SpellCastTargets::GetTargetMask(), Player::GetTradeData(), SpellCastTargets::GetUnitTarget(), handle_immediate(), HandleLaunchPhase(), SpellInfo::HasAttribute(), SpellInfo::HasEffect(), Unit::HasOffhandWeaponForAttack(), HasTriggeredCastFlag(), Unit::HasUnitState(), SpellInfo::Id, IsAutoActionResetSpell(), SpellInfo::IsChanneled(), Object::IsCreature(), Unit::IsNonMeleeSpellCast(), Object::IsPlayer(), SpellInfo::IsPositive(), IsTriggered(), 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_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_HIT_CRITICAL, PROC_HIT_NORMAL, PROC_SPELL_PHASE_CAST, Unit::ProcSkillsAndAuras(), RANGED_ATTACK, Unit::RemoveAurasDueToSpell(), Player::RemovePet(), Player::RemoveSpellCooldown(), Player::RemoveSpellMods(), Unit::resetAttackTimer(), SelectSpellTargets(), SendCastResult(), SendInterrupted(), SendSpellCooldown(), SendSpellGo(), SetDelayStart(), SetExecutedCurrently(), Unit::SetInFront(), Player::SetSpellModTakingSpell(), SpellInfo::Speed, SPELL_ATTR1_DISMISS_PET_FIRST, SPELL_ATTR2_DO_NOT_RESET_COMBAT_TIMERS, SPELL_ATTR3_SUPPRESS_TARGET_PROCS, SPELL_ATTR7_CAN_CAUSE_INTERRUPT, SPELL_AURA_IGNORE_MELEE_RESET, SPELL_AURA_MOD_CHARM, SPELL_CAST_OK, SPELL_DAMAGE_CLASS_MAGIC, SPELL_DAMAGE_CLASS_NONE, SPELL_EFFECT_SUMMON_PET, SPELL_FAILED_DONT_REPORT, SPELL_MISS_NONE, SPELL_STATE_DELAYED, SPELL_STATE_FINISHED, TriggeredByAuraSpellData::spellInfo, sScriptMgr, sSpellMgr, Player::StartTimedAchievement(), TakeCastItem(), TakePower(), TakeReagents(), TARGET_FLAG_TRADE_ITEM, TARGET_FLAG_UNIT, Object::ToCreature(), Object::ToPlayer(), TRIGGERED_IGNORE_CAST_ITEM, TRIGGERED_IGNORE_POWER_AND_REAGENT_COST, TRIGGERED_IGNORE_SET_FACING, UNIT_STATE_CASTING, Player::UpdateAchievementCriteria(), UpdatePointers(), and SpellCastTargets::UpdateTradeSlotItem().

Referenced by cast().

◆ _handle_finish_phase()

void Spell::_handle_finish_phase ( )
4243{
4244 // Take for real after all targets are processed
4246 {
4248 }
4249
4250 // Real add combo points from effects
4252 {
4253 // remove Premed-like effects unless they were caused by ourselves
4254 // (this Aura removes the already-added CP when it expires from duration - now that we've added CP, this shouldn't happen anymore!)
4256 {
4258 }
4259
4261 }
4262
4264 {
4266 }
4267
4270 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
4271 {
4272 // Xinef: Properly clear infinite cooldowns in some cases
4273 if (ihit->targetGUID == m_caster->GetGUID() && ihit->missCondition != SPELL_MISS_NONE)
4276 }
4277
4278 // Handle procs on finish
4279 if (m_originalCaster)
4280 {
4281 uint32 procAttacker = m_procAttacker;
4282 if (!procAttacker)
4283 {
4284 bool IsPositive = m_spellInfo->IsPositive();
4286 {
4288 }
4289 else
4290 {
4292 }
4293 }
4294
4295 uint32 hitMask = PROC_HIT_NORMAL;
4296 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
4297 {
4298 if (ihit->missCondition != SPELL_MISS_NONE)
4299 continue;
4300
4301 if (!ihit->crit)
4302 continue;
4303
4304 hitMask |= PROC_HIT_CRITICAL;
4305 break;
4306 }
4307
4308 // For trap activation, pass the original target (trap triggerer) so proc trigger spells
4309 // like Entrapment can find a valid target to cast on
4310 Unit* finishVictim = nullptr;
4311 if (procAttacker & PROC_FLAG_DONE_TRAP_ACTIVATION)
4312 finishVictim = GetOriginalTarget();
4313
4316 }
4317}
@ SPELL_EFFECT_ADD_EXTRA_ATTACKS
Definition SharedDefines.h:785
@ SPELL_AURA_RETAIN_COMBO_POINTS
Definition SpellAuraDefines.h:211
@ PROC_SPELL_PHASE_FINISH
Definition SpellMgr.h:250
@ PROC_FLAG_DONE_TRAP_ACTIVATION
Definition SpellMgr.h:141
void SendCooldownEvent(SpellInfo const *spellInfo, uint32 itemId=0, Spell *spell=nullptr, bool setCooldown=true)
Definition Player.cpp:11116
bool IsCooldownStartedOnEvent() const
Definition SpellInfo.cpp:1244
bool HasAura(AuraType aura) const
Definition SpellInfo.cpp:902
bool IsAutoRepeat() const
Definition Spell.h:563
Unit * GetOriginalTarget() const
Definition Spell.cpp:7895
bool IsNextMeleeSwingSpell() const
Definition Spell.cpp:8104
void SetLastExtraAttackSpell(uint32 spellId)
Definition Unit.h:1009
Player * GetCharmerOrOwnerPlayerOrPlayerItself() const
Definition Unit.cpp:7733
void ClearComboPoints()
Definition Unit.cpp:13286
void AddComboPoints(Unit *target, int8 count)
Definition Unit.cpp:13260
void RemoveAurasByType(AuraType auraType, ObjectGuid casterGUID=ObjectGuid::Empty, Aura *except=nullptr, bool negative=true, bool positive=true)
Definition Unit.cpp:5397

References Unit::AddComboPoints(), BASE_ATTACK, Unit::ClearComboPoints(), SpellInfo::DmgClass, TriggeredByAuraSpellData::effectIndex, Unit::GetCharmerOrOwnerPlayerOrPlayerItself(), Object::GetGUID(), GetOriginalTarget(), SpellInfo::HasAura(), SpellInfo::HasEffect(), SpellInfo::Id, IsAutoRepeat(), SpellInfo::IsCooldownStartedOnEvent(), IsNextMeleeSwingSpell(), Object::IsPlayer(), SpellInfo::IsPositive(), m_caster, m_comboPointGain, m_comboTarget, m_needComboPoints, m_originalCaster, m_procAttacker, m_spellInfo, m_triggeredByAuraSpell, m_UniqueTargetInfo, PROC_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_DONE_TRAP_ACTIVATION, PROC_FLAG_NONE, PROC_HIT_CRITICAL, PROC_HIT_NORMAL, PROC_SPELL_PHASE_FINISH, Unit::ProcSkillsAndAuras(), Unit::RemoveAurasByType(), Player::SendCooldownEvent(), Unit::SetLastExtraAttackSpell(), SPELL_AURA_RETAIN_COMBO_POINTS, SPELL_DAMAGE_CLASS_MAGIC, SPELL_EFFECT_ADD_EXTRA_ATTACKS, SPELL_MISS_NONE, TriggeredByAuraSpellData::spellInfo, and Object::ToPlayer().

Referenced by handle_delayed(), and handle_immediate().

◆ _handle_immediate_phase()

void Spell::_handle_immediate_phase ( )
4215{
4216 m_spellAura = nullptr;
4217 // initialize Diminishing Returns Data
4220
4221 // handle some immediate features of the spell here
4223
4225
4226 // handle effects with SPELL_EFFECT_HANDLE_HIT mode
4227 for (uint32 j = 0; j < MAX_SPELL_EFFECTS; ++j)
4228 {
4229 // don't do anything for empty effect
4230 if (!m_spellInfo->Effects[j].IsEffect())
4231 continue;
4232
4233 // call effect handlers to handle destination hit
4234 HandleEffects(nullptr, nullptr, nullptr, j, SPELL_EFFECT_HANDLE_HIT);
4235 }
4236
4237 // process items
4238 for (std::list<ItemTargetInfo>::iterator ihit = m_UniqueItemInfo.begin(); ihit != m_UniqueItemInfo.end(); ++ihit)
4239 DoAllEffectOnTarget(&(*ihit));
4240}
@ SPELL_EFFECT_HANDLE_HIT
Definition Spell.h:248
std::array< SpellEffectInfo, MAX_SPELL_EFFECTS > Effects
Definition SpellInfo.h:417
void HandleThreatSpells()
Definition Spell.cpp:5551
void HandleEffects(Unit *pUnitTarget, Item *pItemTarget, GameObject *pGOTarget, uint32 i, SpellEffectHandleMode mode)
Definition Spell.cpp:5604
std::list< ItemTargetInfo > m_UniqueItemInfo
Definition Spell.h:724
void DoAllEffectOnTarget(TargetInfo *target)
Definition Spell.cpp:2543

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
546 {
547 if (target != m_comboTarget)
548 {
549 m_comboTarget = target;
550 m_comboPointGain = amount;
551 }
552 else
553 {
554 m_comboPointGain += amount;
555 }
556 }

References m_comboPointGain, and m_comboTarget.

Referenced by EffectAddComboPoints(), and EffectWeaponDmg().

◆ AddDestTarget()

void Spell::AddDestTarget ( SpellDestination const &  dest,
uint32  effIndex 
)
protected
2539{
2540 m_destTargets[effIndex] = dest;
2541}

References m_destTargets.

Referenced by SelectSpellTargets().

◆ AddGOTarget()

void Spell::AddGOTarget ( GameObject target,
uint32  effectMask 
)
protected
2448{
2449 for (uint32 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
2450 {
2451 if (!m_spellInfo->Effects[effIndex].IsEffect())
2452 effectMask &= ~(1 << effIndex);
2453 else
2454 {
2455 switch (m_spellInfo->Effects[effIndex].Effect)
2456 {
2460 if (go->GetGoType() != GAMEOBJECT_TYPE_DESTRUCTIBLE_BUILDING)
2461 effectMask &= ~(1 << effIndex);
2462 break;
2463 default:
2464 break;
2465 }
2466 }
2467 }
2468
2469 if (!effectMask)
2470 return;
2471
2472 ObjectGuid targetGUID = go->GetGUID();
2473
2474 // Lookup target in already in list
2475 for (std::list<GOTargetInfo>::iterator ihit = m_UniqueGOTargetInfo.begin(); ihit != m_UniqueGOTargetInfo.end(); ++ihit)
2476 {
2477 if (targetGUID == ihit->targetGUID) // Found in list
2478 {
2479 ihit->effectMask |= effectMask; // Add only effect mask
2480 return;
2481 }
2482 }
2483
2484 // This is new target calculate data for him
2485
2486 GOTargetInfo target;
2487 target.targetGUID = targetGUID;
2488 target.effectMask = effectMask;
2489 target.processed = false; // Effects not apply on target
2490
2491 // Spell have speed - need calculate incoming time
2492 if (m_spellInfo->Speed > 0.0f)
2493 {
2494 // calculate spell incoming interval
2495 float dist = m_caster->GetDistance(go->GetPositionX(), go->GetPositionY(), go->GetPositionZ());
2496 if (dist < 5.0f)
2497 dist = 5.0f;
2498 target.timeDelay = uint64(std::floor(dist / m_spellInfo->Speed * 1000.0f));
2499 if (m_delayMoment == 0 || m_delayMoment > target.timeDelay)
2500 m_delayMoment = target.timeDelay;
2501 }
2502 else
2503 target.timeDelay = 0LL;
2504
2505 // Add target to list
2506 m_UniqueGOTargetInfo.push_back(target);
2507}
std::uint64_t uint64
Definition Define.h:106
@ GAMEOBJECT_TYPE_DESTRUCTIBLE_BUILDING
Definition SharedDefines.h:1597
@ SPELL_EFFECT_GAMEOBJECT_REPAIR
Definition SharedDefines.h:854
@ SPELL_EFFECT_GAMEOBJECT_SET_DESTRUCTION_STATE
Definition SharedDefines.h:855
@ SPELL_EFFECT_GAMEOBJECT_DAMAGE
Definition SharedDefines.h:853
Definition ObjectGuid.h:118
uint64 m_delayMoment
Definition Spell.h:660
std::list< GOTargetInfo > m_UniqueGOTargetInfo
Definition Spell.h:717
float GetDistance(WorldObject const *obj) const
Definition Object.cpp:1295

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
2510{
2511 for (uint32 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
2512 if (!m_spellInfo->Effects[effIndex].IsEffect())
2513 effectMask &= ~(1 << effIndex);
2514
2515 // no effects left
2516 if (!effectMask)
2517 return;
2518
2519 // Lookup target in already in list
2520 for (std::list<ItemTargetInfo>::iterator ihit = m_UniqueItemInfo.begin(); ihit != m_UniqueItemInfo.end(); ++ihit)
2521 {
2522 if (item == ihit->item) // Found in list
2523 {
2524 ihit->effectMask |= effectMask; // Add only effect mask
2525 return;
2526 }
2527 }
2528
2529 // This is new target add data
2530
2531 ItemTargetInfo target;
2532 target.item = item;
2533 target.effectMask = effectMask;
2534
2535 m_UniqueItemInfo.push_back(target);
2536}

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)
2314{
2315 for (uint32 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
2316 if (!m_spellInfo->Effects[effIndex].IsEffect() || !CheckEffectTarget(target, effIndex))
2317 effectMask &= ~(1 << effIndex);
2318
2319 // no effects left
2320 if (!effectMask)
2321 return;
2322
2323 if (checkIfValid)
2324 {
2325 SpellCastResult res = m_spellInfo->CheckTarget(m_caster, target, implicit);
2326 if (res != SPELL_CAST_OK)
2327 return;
2328 }
2329
2330 // Check for effect immune skip if immuned
2331 for (uint32 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
2332 if (target->IsImmunedToSpellEffect(m_spellInfo, effIndex, m_caster))
2333 effectMask &= ~(1 << effIndex);
2334
2335 ObjectGuid targetGUID = target->GetGUID();
2336
2337 // Lookup target in already in list
2338 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
2339 {
2340 if (targetGUID == ihit->targetGUID) // Found in list
2341 {
2342 ihit->effectMask |= effectMask; // Immune effects removed from mask
2343 ihit->scaleAura = false;
2344 if (m_auraScaleMask && ihit->effectMask == m_auraScaleMask && m_caster != target)
2345 {
2346 SpellInfo const* auraSpell = m_spellInfo->GetFirstRankSpell();
2347 if (uint32(target->GetLevel() + 10) >= auraSpell->SpellLevel)
2348 ihit->scaleAura = true;
2349 }
2350
2351 sScriptMgr->OnScaleAuraUnitAdd(this, target, effectMask, checkIfValid, implicit, m_auraScaleMask, *ihit);
2352 return;
2353 }
2354 }
2355
2356 // This is new target calculate data for him
2357
2358 // Get spell hit result on target
2359 TargetInfo targetInfo;
2360 targetInfo.targetGUID = targetGUID; // Store target GUID
2361 targetInfo.effectMask = effectMask; // Store all effects not immune
2362 targetInfo.processed = false; // Effects not apply on target
2363 targetInfo.alive = target->IsAlive();
2364 targetInfo.damage = 0;
2365 targetInfo.damageBeforeTakenMods = 0;
2366 targetInfo.crit = false;
2367 targetInfo.scaleAura = false;
2368 if (m_auraScaleMask && targetInfo.effectMask == m_auraScaleMask && m_caster != target)
2369 {
2370 SpellInfo const* auraSpell = m_spellInfo->GetFirstRankSpell();
2371 if (uint32(target->GetLevel() + 10) >= auraSpell->SpellLevel)
2372 targetInfo.scaleAura = true;
2373 }
2374
2375 sScriptMgr->OnScaleAuraUnitAdd(this, target, effectMask, checkIfValid, implicit, m_auraScaleMask, targetInfo);
2376
2377 // Calculate hit result
2378 if (m_originalCaster)
2379 {
2380 targetInfo.missCondition = m_originalCaster->SpellHitResult(target, this, m_canReflect);
2381 if (m_skipCheck && targetInfo.missCondition != SPELL_MISS_IMMUNE)
2382 {
2383 targetInfo.missCondition = SPELL_MISS_NONE;
2384 }
2385 }
2386 else
2387 targetInfo.missCondition = SPELL_MISS_EVADE; //SPELL_MISS_NONE;
2388
2389 // Spell have speed - need calculate incoming time
2390 // Incoming time is zero for self casts. At least I think so.
2391 if (m_spellInfo->Speed > 0.0f && m_caster != target)
2392 {
2393 // calculate spell incoming interval
2395 float dist = m_caster->GetDistance(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ());
2396
2397 if (dist < 5.0f)
2398 dist = 5.0f;
2399 targetInfo.timeDelay = (uint64) std::floor(dist / m_spellInfo->Speed * 1000.0f);
2400
2401 // Calculate minimum incoming time
2402 if (m_delayMoment == 0 || m_delayMoment > targetInfo.timeDelay)
2403 m_delayMoment = targetInfo.timeDelay;
2404 }
2405 else
2406 targetInfo.timeDelay = 0LL;
2407
2408 // If target reflect spell back to caster
2409 if (targetInfo.missCondition == SPELL_MISS_REFLECT)
2410 {
2411 // Calculate reflected spell result on caster
2413
2414 if (targetInfo.reflectResult == SPELL_MISS_REFLECT) // Impossible reflect again, so simply deflect spell
2415 targetInfo.reflectResult = SPELL_MISS_PARRY;
2416
2417 // Increase time interval for reflected spells by 1.5
2419 targetInfo.timeDelay += targetInfo.timeDelay >> 1;
2420
2422
2423 // HACK: workaround check for succubus seduction case
2425 if (m_caster->IsPet())
2426 {
2427 CreatureTemplate const* ci = sObjectMgr->GetCreatureTemplate(m_caster->GetEntry());
2428 switch (ci->family)
2429 {
2431 {
2432 if (m_spellInfo->SpellIconID != 694) // Soothing Kiss
2433 cancel();
2434 }
2435 break;
2436 return;
2437 }
2438 }
2439 }
2440 else
2441 targetInfo.reflectResult = SPELL_MISS_NONE;
2442
2443 // Add target to list
2444 m_UniqueTargetInfo.push_back(targetInfo);
2445}
std::chrono::milliseconds Milliseconds
Milliseconds shorthand typedef.
Definition Duration.h:27
#define sObjectMgr
Definition ObjectMgr.h:1732
@ CREATURE_FAMILY_SUCCUBUS
Definition SharedDefines.h:2658
@ SPELL_MISS_PARRY
Definition SharedDefines.h:1527
@ SPELL_MISS_IMMUNE
Definition SharedDefines.h:1530
@ SPELL_MISS_EVADE
Definition SharedDefines.h:1529
@ SPELL_MISS_REFLECT
Definition SharedDefines.h:1534
@ SPELL_FLAG_REFLECTED
Definition Spell.h:94
void AddEventAtOffset(BasicEvent *event, Milliseconds offset, uint8 eventGroup=0)
Definition EventProcessor.h:108
Definition Spell.h:864
Definition SpellInfo.h:340
uint32 SpellLevel
Definition SpellInfo.h:384
SpellInfo const * GetFirstRankSpell() const
Definition SpellInfo.cpp:2903
uint32 SpellIconID
Definition SpellInfo.h:404
SpellCastResult CheckTarget(Unit const *caster, WorldObject const *target, bool implicit=true) const
Definition SpellInfo.cpp:1653
bool CheckEffectTarget(Unit const *target, uint32 eff) const
Definition Spell.cpp:7962
bool IsPet() const
Definition Unit.h:797
bool IsAlive() const
Definition Unit.h:1797
SpellMissInfo SpellHitResult(Unit *victim, SpellInfo const *spell, bool canReflect=false)
Definition Unit.cpp:3660
virtual bool IsImmunedToSpellEffect(SpellInfo const *spellInfo, uint32 index, Unit const *caster=nullptr) const
Definition Unit.cpp:10136
uint8 GetLevel() const
Definition Unit.h:1103
EventProcessor m_Events
Definition Object.h:736
Definition CreatureData.h:187
uint32 family
Definition CreatureData.h:217
float GetPositionZ() const
Definition Position.h:123
float GetPositionX() const
Definition Position.h:121
float GetPositionY() const
Definition Position.h:122
Definition Spell.h:267
bool processed
Definition Spell.h:273
int32 damage
Definition Spell.h:277
SpellMissInfo missCondition
Definition Spell.h:270
int32 damageBeforeTakenMods
Definition Spell.h:278
bool scaleAura
Definition Spell.h:276
bool crit
Definition Spell.h:275
uint64 timeDelay
Definition Spell.h:269
ObjectGuid targetGUID
Definition Spell.h:268
SpellMissInfo reflectResult
Definition Spell.h:271
bool alive
Definition Spell.h:274
uint8 effectMask
Definition Spell.h:272

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

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

◆ CalculateDelayMomentForDst()

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

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

Referenced by RecalculateDelayMomentForDst(), and SelectSpellTargets().

◆ CalculateJumpSpeeds()

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

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

Referenced by EffectJump(), and EffectJumpDest().

◆ CalculateSpellDamage()

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

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

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

◆ CallScriptAfterCastHandlers()

void Spell::CallScriptAfterCastHandlers ( )
protected
8603{
8604 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8605 {
8606 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_AFTER_CAST);
8607 std::list<SpellScript::CastHandler>::iterator hookItrEnd = (*scritr)->AfterCast.end(), hookItr = (*scritr)->AfterCast.begin();
8608 for (; hookItr != hookItrEnd; ++hookItr)
8609 (*hookItr).Call(*scritr);
8610
8611 (*scritr)->_FinishScriptCall();
8612 }
8613}
@ 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
8715{
8716 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8717 {
8718 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_AFTER_HIT);
8719 std::list<SpellScript::HitHandler>::iterator hookItrEnd = (*scritr)->AfterHit.end(), hookItr = (*scritr)->AfterHit.begin();
8720 for (; hookItr != hookItrEnd; ++hookItr)
8721 (*hookItr).Call(*scritr);
8722
8723 (*scritr)->_FinishScriptCall();
8724 }
8725}
@ SPELL_SCRIPT_HOOK_AFTER_HIT
Definition SpellScript.h:165

References m_loadedScripts, and SPELL_SCRIPT_HOOK_AFTER_HIT.

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

◆ CallScriptBeforeCastHandlers()

void Spell::CallScriptBeforeCastHandlers ( )
protected
8577{
8578 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8579 {
8580 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_BEFORE_CAST);
8581 std::list<SpellScript::CastHandler>::iterator hookItrEnd = (*scritr)->BeforeCast.end(), hookItr = (*scritr)->BeforeCast.begin();
8582 for (; hookItr != hookItrEnd; ++hookItr)
8583 (*hookItr).Call(*scritr);
8584
8585 (*scritr)->_FinishScriptCall();
8586 }
8587}
@ 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
8689{
8690 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8691 {
8692 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_BEFORE_HIT);
8693 std::list<SpellScript::BeforeHitHandler>::iterator hookItrEnd = (*scritr)->BeforeHit.end(), hookItr = (*scritr)->BeforeHit.begin();
8694 for (; hookItr != hookItrEnd; ++hookItr)
8695 (*hookItr).Call(*scritr, missInfo);
8696
8697 (*scritr)->_FinishScriptCall();
8698 }
8699}
@ SPELL_SCRIPT_HOOK_BEFORE_HIT
Definition SpellScript.h:163

References m_loadedScripts, and SPELL_SCRIPT_HOOK_BEFORE_HIT.

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

◆ CallScriptCheckCastHandlers()

SpellCastResult Spell::CallScriptCheckCastHandlers ( )
protected
8616{
8618 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8619 {
8620 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_CHECK_CAST);
8621 std::list<SpellScript::CheckCastHandler>::iterator hookItrEnd = (*scritr)->OnCheckCast.end(), hookItr = (*scritr)->OnCheckCast.begin();
8622 for (; hookItr != hookItrEnd; ++hookItr)
8623 {
8624 SpellCastResult tempResult = (*hookItr).Call(*scritr);
8625 if (retVal == SPELL_CAST_OK)
8626 retVal = tempResult;
8627 }
8628
8629 (*scritr)->_FinishScriptCall();
8630 }
8631 return retVal;
8632}
@ 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
8756{
8757 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8758 {
8759 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_DESTINATION_TARGET_SELECT);
8760 std::list<SpellScript::DestinationTargetSelectHandler>::iterator hookItrEnd = (*scritr)->OnDestinationTargetSelect.end(), hookItr = (*scritr)->OnDestinationTargetSelect.begin();
8761 for (; hookItr != hookItrEnd; ++hookItr)
8762 if (hookItr->IsEffectAffected(m_spellInfo, effIndex) && targetType.GetTarget() == hookItr->GetTarget())
8763 hookItr->Call(*scritr, target);
8764
8765 (*scritr)->_FinishScriptCall();
8766 }
8767}
@ 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
8641{
8642 // execute script effect handler hooks and check if effects was prevented
8643 bool preventDefault = false;
8644 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8645 {
8646 std::list<SpellScript::EffectHandler>::iterator effItr, effEndItr;
8647 SpellScriptHookType hookType;
8648 switch (mode)
8649 {
8651 effItr = (*scritr)->OnEffectLaunch.begin();
8652 effEndItr = (*scritr)->OnEffectLaunch.end();
8654 break;
8656 effItr = (*scritr)->OnEffectLaunchTarget.begin();
8657 effEndItr = (*scritr)->OnEffectLaunchTarget.end();
8659 break;
8661 effItr = (*scritr)->OnEffectHit.begin();
8662 effEndItr = (*scritr)->OnEffectHit.end();
8664 break;
8666 effItr = (*scritr)->OnEffectHitTarget.begin();
8667 effEndItr = (*scritr)->OnEffectHitTarget.end();
8669 break;
8670 default:
8671 ABORT();
8672 return false;
8673 }
8674 (*scritr)->_PrepareScriptCall(hookType);
8675 for (; effItr != effEndItr; ++effItr)
8676 // effect execution can be prevented
8677 if (!(*scritr)->_IsEffectPrevented(effIndex) && (*effItr).IsEffectAffected(m_spellInfo, effIndex))
8678 (*effItr).Call(*scritr, effIndex);
8679
8680 if (!preventDefault)
8681 preventDefault = (*scritr)->_IsDefaultEffectPrevented(effIndex);
8682
8683 (*scritr)->_FinishScriptCall();
8684 }
8685 return preventDefault;
8686}
#define ABORT
Definition Errors.h:76
SpellScriptHookType
Definition SpellScript.h:158
@ SPELL_SCRIPT_HOOK_EFFECT_HIT
Definition SpellScript.h:161
@ SPELL_SCRIPT_HOOK_EFFECT_LAUNCH
Definition SpellScript.h:159
@ SPELL_SCRIPT_HOOK_EFFECT_LAUNCH_TARGET
Definition SpellScript.h:160
@ SPELL_SCRIPT_HOOK_EFFECT_HIT_TARGET
Definition SpellScript.h:162
@ SPELL_EFFECT_HANDLE_LAUNCH_TARGET
Definition Spell.h:247
@ SPELL_EFFECT_HANDLE_HIT_TARGET
Definition Spell.h:249

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
8728{
8729 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8730 {
8731 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_OBJECT_AREA_TARGET_SELECT);
8732 std::list<SpellScript::ObjectAreaTargetSelectHandler>::iterator hookItrEnd = (*scritr)->OnObjectAreaTargetSelect.end(), hookItr = (*scritr)->OnObjectAreaTargetSelect.begin();
8733 for (; hookItr != hookItrEnd; ++hookItr)
8734 if (hookItr->IsEffectAffected(m_spellInfo, effIndex) && targetType.GetTarget() == hookItr->GetTarget())
8735 hookItr->Call(*scritr, targets);
8736
8737 (*scritr)->_FinishScriptCall();
8738 }
8739}
@ 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
8742{
8743 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8744 {
8745 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_OBJECT_TARGET_SELECT);
8746 std::list<SpellScript::ObjectTargetSelectHandler>::iterator hookItrEnd = (*scritr)->OnObjectTargetSelect.end(), hookItr = (*scritr)->OnObjectTargetSelect.begin();
8747 for (; hookItr != hookItrEnd; ++hookItr)
8748 if (hookItr->IsEffectAffected(m_spellInfo, effIndex) && targetType.GetTarget() == hookItr->GetTarget())
8749 hookItr->Call(*scritr, target);
8750
8751 (*scritr)->_FinishScriptCall();
8752 }
8753}
@ 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
8590{
8591 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8592 {
8593 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_ON_CAST);
8594 std::list<SpellScript::CastHandler>::iterator hookItrEnd = (*scritr)->OnCast.end(), hookItr = (*scritr)->OnCast.begin();
8595 for (; hookItr != hookItrEnd; ++hookItr)
8596 (*hookItr).Call(*scritr);
8597
8598 (*scritr)->_FinishScriptCall();
8599 }
8600}
@ 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
8702{
8703 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8704 {
8705 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_HIT);
8706 std::list<SpellScript::HitHandler>::iterator hookItrEnd = (*scritr)->OnHit.end(), hookItr = (*scritr)->OnHit.begin();
8707 for (; hookItr != hookItrEnd; ++hookItr)
8708 (*hookItr).Call(*scritr);
8709
8710 (*scritr)->_FinishScriptCall();
8711 }
8712}
@ SPELL_SCRIPT_HOOK_HIT
Definition SpellScript.h:164

References m_loadedScripts, and SPELL_SCRIPT_HOOK_HIT.

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

◆ CanAutoCast()

bool Spell::CanAutoCast ( Unit target)
7002{
7003 ObjectGuid targetguid = target->GetGUID();
7004
7005 for (SpellEffectInfo const& spellEffectInfo : m_spellInfo->GetEffects())
7006 {
7007 if (!spellEffectInfo.IsAura())
7008 continue;
7009
7010 AuraType const& auraType = spellEffectInfo.ApplyAuraName;
7011 Unit::AuraEffectList const& auras = target->GetAuraEffectsByType(auraType);
7012 for (Unit::AuraEffectList::const_iterator auraIt = auras.begin(); auraIt != auras.end(); ++auraIt)
7013 {
7014 if (GetSpellInfo()->Id == (*auraIt)->GetSpellInfo()->Id)
7015 return false;
7016
7017 switch (sSpellMgr->CheckSpellGroupStackRules(GetSpellInfo(), (*auraIt)->GetSpellInfo()))
7018 {
7020 return false;
7022 if (GetCaster() == (*auraIt)->GetCaster())
7023 return false;
7024 break;
7025 case SPELL_GROUP_STACK_RULE_EXCLUSIVE_SAME_EFFECT: // this one has further checks, but i don't think they're necessary for autocast logic
7027 if (abs(spellEffectInfo.BasePoints) <= abs((*auraIt)->GetAmount()))
7028 return false;
7029 break;
7031 default:
7032 break;
7033 }
7034 }
7035 }
7036
7037 SpellCastResult result = CheckPetCast(target);
7038
7039 if (result == SPELL_CAST_OK || result == SPELL_FAILED_UNIT_NOT_INFRONT)
7040 {
7042 //check if among target units, our WANTED target is as well (->only self cast spells return false)
7043 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
7044 if (ihit->targetGUID == targetguid)
7045 return true;
7046 }
7047 return false; //target invalid
7048}
@ SPELL_FAILED_UNIT_NOT_INFRONT
Definition SharedDefines.h:1071
AuraType
Definition SpellAuraDefines.h:62
@ SPELL_GROUP_STACK_RULE_EXCLUSIVE_FROM_SAME_CASTER
Definition SpellMgr.h:364
@ SPELL_GROUP_STACK_RULE_EXCLUSIVE
Definition SpellMgr.h:363
@ SPELL_GROUP_STACK_RULE_DEFAULT
Definition SpellMgr.h:362
@ SPELL_GROUP_STACK_RULE_EXCLUSIVE_SAME_EFFECT
Definition SpellMgr.h:365
@ SPELL_GROUP_STACK_RULE_EXCLUSIVE_HIGHEST
Definition SpellMgr.h:366
Definition SpellInfo.h:270
Unit * GetCaster() const
Definition Spell.h:590
SpellCastResult CheckPetCast(Unit *target)
Definition Spell.cpp:6808

References CheckPetCast(), Unit::GetAuraEffectsByType(), GetCaster(), SpellInfo::GetEffects(), Object::GetGUID(), GetSpellInfo(), SpellInfo::Id, m_spellInfo, m_UniqueTargetInfo, SelectSpellTargets(), SPELL_CAST_OK, SPELL_FAILED_UNIT_NOT_INFRONT, SPELL_GROUP_STACK_RULE_DEFAULT, SPELL_GROUP_STACK_RULE_EXCLUSIVE, SPELL_GROUP_STACK_RULE_EXCLUSIVE_FROM_SAME_CASTER, SPELL_GROUP_STACK_RULE_EXCLUSIVE_HIGHEST, SPELL_GROUP_STACK_RULE_EXCLUSIVE_SAME_EFFECT, and sSpellMgr.

Referenced by PetAI::UpdateAI().

◆ cancel()

void Spell::cancel ( bool  bySelf = false)
3675{
3677 return;
3678
3679 uint32 oldState = m_spellState;
3681
3682 m_autoRepeat = false;
3683 switch (oldState)
3684 {
3688
3689 if (m_caster->IsPlayer())
3690 {
3692 ArenaSpectator::SendCommand_Spell(m_caster->FindMap(), m_caster->GetGUID(), "SPE", m_spellInfo->Id, bySelf ? 99998 : 99999);
3693 }
3694 [[fallthrough]];
3697 break;
3699 if (!bySelf)
3700 {
3701 for (std::list<TargetInfo>::const_iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
3702 if ((*ihit).missCondition == SPELL_MISS_NONE)
3703 if (Unit* unit = m_caster->GetGUID() == ihit->targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID))
3704 unit->RemoveOwnedAura(m_spellInfo->Id, m_originalCasterGUID, 0, AURA_REMOVE_BY_CANCEL);
3705
3708
3711 }
3712
3714 ArenaSpectator::SendCommand_Spell(m_caster->FindMap(), m_caster->GetGUID(), "SPE", m_spellInfo->Id, bySelf ? 99998 : 99999);
3715
3716 // spell is canceled-take mods and clear list
3717 if (Player* player = m_caster->GetSpellModOwner())
3718 player->RemoveSpellMods(this);
3719
3720 m_appliedMods.clear();
3721 break;
3722 default:
3723 break;
3724 }
3725
3727 if (m_selfContainer && *m_selfContainer == this)
3728 *m_selfContainer = nullptr;
3729
3730 // Do not remove current far sight object (already done in Spell::EffectAddFarsight) to prevent from reset viewpoint to player
3732 {
3734 }
3735
3736 if (m_spellInfo->IsChanneled()) // if not channeled then the object for the current cast wasn't summoned yet
3738
3739 //set state back so finish will be processed
3740 m_spellState = oldState;
3741
3742 sScriptMgr->OnSpellCastCancel(this, m_caster, m_spellInfo, bySelf);
3743
3744 finish(false);
3745}
@ SPELL_EFFECT_ADD_FARSIGHT
Definition SharedDefines.h:838
@ SPELL_FAILED_INTERRUPTED
Definition SharedDefines.h:977
@ AURA_REMOVE_BY_CANCEL
Definition SpellAuraDefines.h:393
@ SPELL_STATE_PREPARING
Definition Spell.h:237
@ SPELL_STATE_CASTING
Definition Spell.h:238
bool NeedSendSpectatorData() const
Definition Player.cpp:15644
void SendChannelUpdate(uint32 time)
Definition Spell.cpp:5161
void CancelGlobalCooldown()
Definition Spell.cpp:8943
void SetReferencedFromCurrent(bool yes)
Definition Spell.h:576
UsedSpellMods m_appliedMods
Definition Spell.h:560
void RemoveGameObject(GameObject *gameObj, bool del)
Definition Unit.cpp:6601
bool RemoveDynObject(uint32 spellId)
Definition Unit.cpp:6545
Map * FindMap() const
Definition Object.h:626
void SendCommand_Spell(T *o, ObjectGuid targetGUID, const char *prefix, uint32 id, int32 casttime)
Definition ArenaSpectator.h:80

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

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

◆ CancelGlobalCooldown()

void Spell::CancelGlobalCooldown ( )
protected
8944{
8946 return;
8947
8948 // Cancel global cooldown when interrupting current cast
8950 return;
8951
8952 // Only players or controlled units have global cooldown
8953 if (m_caster->GetCharmInfo())
8955 else if (m_caster->IsPlayer())
8957}
@ CURRENT_GENERIC_SPELL
Definition Unit.h:556
void CancelGlobalCooldown(SpellInfo const *spellInfo)
Definition CharmInfo.cpp:424
GlobalCooldownMgr & GetGlobalCooldownMgr()
Definition Player.h:1824
uint32 StartRecoveryTime
Definition SpellInfo.h:375
CharmInfo * GetCharmInfo()
Definition Unit.h:1281
Spell * GetCurrentSpell(CurrentSpellTypes spellType) const
Definition Unit.h:1576
GlobalCooldownMgr & GetGlobalCooldownMgr()
Definition CharmInfo.h:160

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

Referenced by cancel().

◆ CanExecuteTriggersOnHit()

bool Spell::CanExecuteTriggersOnHit ( uint8  effMask,
SpellInfo const *  triggeredByAura = nullptr 
) const
protected
8793{
8794 // Relentless strikes, proc only from first effect
8795 if (triggeredByAura && triggeredByAura->SpellIconID == 559)
8796 return effMask & (1 << EFFECT_0);
8797
8798 bool only_on_caster = (triggeredByAura && triggeredByAura->HasAttribute(SPELL_ATTR4_CLASS_TRIGGER_ONLY_ON_TARGET));
8799 // If triggeredByAura has SPELL_ATTR4_CLASS_TRIGGER_ONLY_ON_TARGET then it can only proc on a casted spell with TARGET_UNIT_CASTER
8800 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
8801 {
8802 if ((effMask & (1 << i)) && (!only_on_caster || (m_spellInfo->Effects[i].TargetA.GetTarget() == TARGET_UNIT_CASTER)))
8803 return true;
8804 }
8805 return effMask;
8806}
@ EFFECT_0
Definition SharedDefines.h:31
@ TARGET_UNIT_CASTER
Definition SharedDefines.h:1414
@ SPELL_ATTR4_CLASS_TRIGGER_ONLY_ON_TARGET
Definition SharedDefines.h:519

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
8408{
8409 if (!lockId) // possible case for GO and maybe for items.
8410 return SPELL_CAST_OK;
8411
8412 // Get LockInfo
8413 LockEntry const* lockInfo = sLockStore.LookupEntry(lockId);
8414
8415 if (!lockInfo)
8417
8418 bool reqKey = false; // some locks not have reqs
8419
8420 for (int j = 0; j < MAX_LOCK_CASE; ++j)
8421 {
8422 switch (lockInfo->Type[j])
8423 {
8424 // check key item (many fit cases can be)
8425 case LOCK_KEY_ITEM:
8426 if (lockInfo->Index[j] && m_CastItem && m_CastItem->GetEntry() == lockInfo->Index[j])
8427 return SPELL_CAST_OK;
8428 reqKey = true;
8429 break;
8430 // check key skill (only single first fit case can be)
8431 case LOCK_KEY_SKILL:
8432 {
8433 reqKey = true;
8434
8435 // wrong locktype, skip
8436 if (uint32(m_spellInfo->Effects[effIndex].MiscValue) != lockInfo->Index[j])
8437 continue;
8438
8439 skillId = SkillByLockType(LockType(lockInfo->Index[j]));
8440
8441 if (skillId != SKILL_NONE)
8442 {
8443 reqSkillValue = lockInfo->Skill[j];
8444
8445 // castitem check: rogue using skeleton keys. the skill values should not be added in this case.
8446 skillValue = m_CastItem || !m_caster->IsPlayer() ?
8447 0 : m_caster->ToPlayer()->GetSkillValue(skillId);
8448
8449 // skill bonus provided by casting spell (mostly item spells)
8450 // add the effect base points modifier from the spell casted (cheat lock / skeleton key etc.)
8451 if ((m_spellInfo->Effects[effIndex].TargetA.GetTarget() == TARGET_GAMEOBJECT_ITEM_TARGET || m_spellInfo->Effects[effIndex].TargetB.GetTarget() == TARGET_GAMEOBJECT_ITEM_TARGET)
8453 {
8454 skillValue += m_spellInfo->Effects[effIndex].CalcValue();
8455 }
8456
8457 if (skillValue < reqSkillValue)
8459 }
8460
8461 return SPELL_CAST_OK;
8462 }
8463 case LOCK_KEY_SPELL:
8464 {
8465 if (m_spellInfo->Id == lockInfo->Index[j])
8466 {
8467 return SPELL_CAST_OK;
8468 }
8469 reqKey = true;
8470 break;
8471 }
8472 }
8473 }
8474
8475 if (reqKey)
8477
8478 return SPELL_CAST_OK;
8479}
DBCStorage< LockEntry > sLockStore(LockEntryfmt)
#define MAX_LOCK_CASE
Definition DBCStructure.h:1305
@ TARGET_GAMEOBJECT_ITEM_TARGET
Definition SharedDefines.h:1434
LockType
Definition SharedDefines.h:2595
@ LOCK_KEY_ITEM
Definition SharedDefines.h:2589
@ LOCK_KEY_SKILL
Definition SharedDefines.h:2590
@ LOCK_KEY_SPELL
Definition SharedDefines.h:2591
@ SPELL_FAILED_BAD_TARGETS
Definition SharedDefines.h:949
@ SPELL_FAILED_LOW_CASTLEVEL
Definition SharedDefines.h:986
SkillType SkillByLockType(LockType locktype)
Definition SharedDefines.h:3253
@ SKILL_NONE
Definition SharedDefines.h:3097
@ SKILL_LOCKPICKING
Definition SharedDefines.h:3208
uint16 GetSkillValue(uint32 skill) const
Definition Player.cpp:5459
bool IsAbilityOfSkillType(uint32 skillType) const
Definition SpellInfo.cpp:1037
Definition DBCStructure.h:1308
uint32 Type[MAX_LOCK_CASE]
Definition DBCStructure.h:1310
uint32 Index[MAX_LOCK_CASE]
Definition DBCStructure.h:1311
uint32 Skill[MAX_LOCK_CASE]
Definition DBCStructure.h:1312

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

Referenced by CheckCast(), and EffectOpenLock().

◆ cast()

void Spell::cast ( bool  skipCheck = false)
3748{
3749 Player* modOwner = m_caster->GetSpellModOwner();
3750 Spell* lastMod = nullptr;
3751 if (modOwner)
3752 {
3753 lastMod = modOwner->m_spellModTakingSpell;
3754 if (lastMod)
3755 modOwner->SetSpellModTakingSpell(lastMod, false);
3756 }
3757
3758 _cast(skipCheck);
3759
3760 if (lastMod)
3761 modOwner->SetSpellModTakingSpell(lastMod, true);
3762}
Spell * m_spellModTakingSpell
Definition Player.h:2598
Definition Spell.h:298
void _cast(bool skipCheck)
Definition Spell.cpp:3764

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,
uint32 param1 = nullptr,
uint32 param2 = nullptr 
)
Todo:
: determine if there is some flag to enable/disable the check
5631{
5632 // check death state
5635
5636 // Spectator check
5637 if (m_caster->IsPlayer())
5638 if (((Player const*)m_caster)->IsSpectator() && m_spellInfo->Id != SPECTATOR_SPELL_BINDSIGHT)
5639 return SPELL_FAILED_NOT_HERE;
5640
5642
5643 sScriptMgr->OnSpellCheckCast(this, strict, res);
5644
5645 if (res != SPELL_CAST_OK)
5646 return res;
5647
5648 // check cooldowns to prevent cheating
5650 {
5651 if (m_caster->IsPlayer())
5652 {
5653 //can cast triggered (by aura only?) spells while have this flag
5656
5658 {
5661 else
5663 }
5664
5665 // check if we are using a potion in combat for the 2nd+ time. Cooldown is added only after caster gets out of combat
5668 }
5671 }
5672
5674 {
5677 }
5678
5679 // Check global cooldown
5682
5683 // only triggered spells can be processed an ended battleground
5684 if (!IsTriggered() && m_caster->IsPlayer())
5686 if (bg->GetStatus() == STATUS_WAIT_LEAVE)
5688
5689 if (m_caster->IsPlayer() /*&& VMAP::VMapFactory::createOrGetVMapMgr()->isLineOfSightCalcEnabled()*/) // pussywizard: optimization (commented)
5690 {
5692 !m_caster->IsOutdoors())
5694
5698 }
5699
5700 // only check at first call, Stealth auras are already removed at second call
5701 // for now, ignore triggered spells
5703 {
5704 bool checkForm = true;
5705 // Ignore form req aura
5707 for (Unit::AuraEffectList::const_iterator i = ignore.begin(); i != ignore.end(); ++i)
5708 {
5709 if (!(*i)->IsAffectedOnSpell(m_spellInfo))
5710 continue;
5711 checkForm = false;
5712 break;
5713 }
5714 if (checkForm)
5715 {
5716 // Cannot be used in this stance/form
5718 if (shapeError != SPELL_CAST_OK)
5719 return shapeError;
5720
5723 }
5724 }
5725
5727 for (Unit::AuraEffectList::const_iterator blockItr = blockSpells.begin(); blockItr != blockSpells.end(); ++blockItr)
5728 if (uint32((*blockItr)->GetMiscValue()) == m_spellInfo->SpellFamilyName)
5730
5731 bool reqCombat = true;
5733 for (Unit::AuraEffectList::const_iterator j = stateAuras.begin(); j != stateAuras.end(); ++j)
5734 {
5735 if ((*j)->IsAffectedOnSpell(m_spellInfo))
5736 {
5737 m_needComboPoints = false;
5738 if ((*j)->GetMiscValue() == 1)
5739 {
5740 reqCombat = false;
5741 break;
5742 }
5743 }
5744 }
5745
5746 // caster state requirements
5747 // not for triggered spells (needed by execute)
5749 {
5754
5755 // Note: spell 62473 requres CasterAuraSpell = triggering spell
5760
5761 if (reqCombat && m_caster->IsInCombat() && !m_spellInfo->CanBeUsedInCombat())
5763 }
5764
5765 // Xinef: exploit protection
5767 {
5768 if (m_caster->IsPlayer() && m_caster->GetMap()->IsDungeon())
5769 if (InstanceScript* instanceScript = m_caster->GetInstanceScript())
5770 if (instanceScript->IsEncounterInProgress())
5771 {
5772 if (Group* group = m_caster->ToPlayer()->GetGroup())
5773 for (GroupReference* itr = group->GetFirstMember(); itr != nullptr; itr = itr->next())
5774 if (Player* member = itr->GetSource())
5775 if (member->IsInMap(m_caster))
5776 if (Unit* victim = member->GetVictim())
5777 if (victim->IsInCombat() && m_caster->GetDistance(victim) < m_caster->GetVisibilityRange())
5778 {
5779 m_caster->EngageWithTarget(victim);
5780 break;
5781 }
5783 }
5784 }
5785
5786 // cancel autorepeat spells if cast start when moving
5787 // (not wand currently autorepeat cast delayed to moving stop anyway in spell update code)
5788 if (m_caster->IsPlayer() && m_caster->ToPlayer()->isMoving() && !IsTriggered())
5789 {
5790 // skip stuck spell to allow use it in falling case and apply spell limitations at movement
5793 return SPELL_FAILED_MOVING;
5794 }
5795
5796 Vehicle* vehicle = m_caster->GetVehicle();
5798 {
5799 uint16 checkMask = 0;
5800 for (uint8 effIndex = EFFECT_0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
5801 {
5802 SpellEffectInfo const* effInfo = &m_spellInfo->Effects[effIndex];
5804 {
5805 SpellShapeshiftFormEntry const* shapeShiftEntry = sSpellShapeshiftFormStore.LookupEntry(effInfo->MiscValue);
5806 if (shapeShiftEntry && (shapeShiftEntry->flags1 & SHAPESHIFT_FLAG_STANCE) == 0)
5807 checkMask |= VEHICLE_SEAT_FLAG_UNCONTROLLED;
5808 break;
5809 }
5810 }
5811
5814
5815 if (!checkMask)
5816 checkMask = VEHICLE_SEAT_FLAG_CAN_ATTACK;
5817
5818 // All creatures should be able to cast as passengers freely, restriction and attribute are only for players
5819 VehicleSeatEntry const* vehicleSeat = vehicle->GetSeatForPassenger(m_caster);
5821 && (vehicleSeat->m_flags & checkMask) != checkMask && m_caster->IsPlayer())
5823 }
5824
5825 // check spell cast conditions from database
5826 {
5829 ConditionList conditions = sConditionMgr->GetConditionsForNotGroupedEntry(CONDITION_SOURCE_TYPE_SPELL, m_spellInfo->Id);
5830 if (!conditions.empty() && !sConditionMgr->IsObjectMeetToConditions(condInfo, conditions))
5831 {
5832 // mLastFailedCondition can be nullptr if there was an error processing the condition in Condition::Meets (i.e. wrong data for ConditionTarget or others)
5833 if (condInfo.mLastFailedCondition && condInfo.mLastFailedCondition->ErrorType)
5834 {
5838 }
5839 if (!condInfo.mLastFailedCondition || !condInfo.mLastFailedCondition->ConditionTarget)
5842 }
5843 }
5844
5845 // Don't check explicit target for passive spells (workaround) (check should be skipped only for learn case)
5846 // those spells may have incorrect target entries or not filled at all (for example 15332)
5847 // such spells when learned are not targeting anyone using targeting system, they should apply directly to caster instead
5848 // also, such casts shouldn't be sent to client
5849 // Xinef: do not check explicit casts for self cast of triggered spells (eg. reflect case)
5851 {
5852 // Check explicit target for m_originalCaster - todo: get rid of such workarounds
5853 // Xinef: do not check explicit target for triggered spell casted on self with targetflag enemy
5855 {
5857 if (castResult != SPELL_CAST_OK)
5858 return castResult;
5859 }
5860 }
5861
5862 if (Unit* target = m_targets.GetUnitTarget())
5863 {
5864 SpellCastResult castResult = m_spellInfo->CheckTarget(m_caster, target, false);
5865 if (castResult != SPELL_CAST_OK)
5866 return castResult;
5867
5868 if (target != m_caster)
5869 {
5870 // Must be behind the target
5871 if (m_spellInfo->HasAttribute(SPELL_ATTR0_CU_REQ_CASTER_BEHIND_TARGET) && target->HasInArc(static_cast<float>(M_PI), m_caster))
5873
5874 // Target must be facing you
5875 if (m_spellInfo->HasAttribute(SPELL_ATTR0_CU_REQ_TARGET_FACING_CASTER) && !target->HasInArc(static_cast<float>(M_PI), m_caster))
5877
5880 {
5881 bool castedByGameobject = false;
5882 uint32 losChecks = LINEOFSIGHT_ALL_CHECKS;
5884 {
5885 castedByGameobject = m_caster->GetMap()->GetGameObject(m_originalCasterGUID) != nullptr;
5886 }
5887 else if (m_caster->GetEntry() == WORLD_TRIGGER)
5888 {
5889 if (TempSummon* tempSummon = m_caster->ToTempSummon())
5890 {
5891 castedByGameobject = tempSummon->GetSummonerGameObject() != nullptr;
5892 }
5893 }
5894
5895 if (castedByGameobject)
5896 {
5897 // If spell casted by gameobject then ignore M2 models
5898 losChecks &= ~LINEOFSIGHT_CHECK_GOBJECT_M2;
5899 }
5900
5902 {
5904 }
5905 }
5906 }
5907 }
5908
5909 // Check for line of sight for spells with dest
5910 if (m_targets.HasDst())
5911 {
5912 float x, y, z;
5913 m_targets.GetDstPos()->GetPosition(x, y, z);
5914
5917 {
5918 bool castedByGameobject = false;
5919 uint32 losChecks = LINEOFSIGHT_ALL_CHECKS;
5921 {
5922 castedByGameobject = m_caster->GetMap()->GetGameObject(m_originalCasterGUID) != nullptr;
5923 }
5924 else if (m_caster->GetEntry() == WORLD_TRIGGER)
5925 {
5926 if (TempSummon* tempSummon = m_caster->ToTempSummon())
5927 {
5928 castedByGameobject = tempSummon->GetSummonerGameObject() != nullptr;
5929 }
5930 }
5931
5932 if (castedByGameobject)
5933 {
5934 // If spell casted by gameobject then ignore M2 models
5935 losChecks &= ~LINEOFSIGHT_CHECK_GOBJECT_M2;
5936 }
5937
5939 {
5941 }
5942 }
5943 }
5944
5945 // check pet presence
5946 for (int j = 0; j < MAX_SPELL_EFFECTS; ++j)
5947 {
5948 if (m_spellInfo->Effects[j].TargetA.GetTarget() == TARGET_UNIT_PET)
5949 {
5951 {
5952 if (m_triggeredByAuraSpell.spellInfo) // not report pet not existence for triggered spells
5954 else
5955 return SPELL_FAILED_NO_PET;
5956 }
5957 break;
5958 }
5959 }
5960 // Spell casted only on battleground
5962 if (!m_caster->ToPlayer()->InBattleground())
5964
5965 // do not allow spells to be cast in arenas
5966 // - with greater than 10 min CD without SPELL_ATTR4_IGNORE_DEFAULT_ARENA_RESTRICTIONS flag
5967 // - with SPELL_ATTR4_NOT_IN_ARENA_OR_RATED_BATTLEGROUND flag
5970 if (MapEntry const* mapEntry = sMapStore.LookupEntry(m_caster->GetMapId()))
5971 if (mapEntry->IsBattleArena())
5973
5974 // zone check
5976 {
5977 uint32 zone, area;
5978 m_caster->GetZoneAndAreaId(zone, area);
5979
5981 m_caster->IsPlayer() ? m_caster->ToPlayer() : nullptr);
5982 if (locRes != SPELL_CAST_OK)
5983 return locRes;
5984 }
5985
5986 // not let players cast spells at mount (and let do it to creatures)
5989 {
5990 if (m_caster->IsInFlight())
5992 else
5994 }
5995
5996 SpellCastResult castResult = SPELL_CAST_OK;
5997
5998 // always (except passive spells) check items (focus object can be required for any type casts)
5999 if (!m_spellInfo->IsPassive())
6000 {
6001 // spell focus needs to be checked not only for players! there are vehicle spells that require spell focus
6002 castResult = CheckSpellFocus();
6003 if (castResult != SPELL_CAST_OK)
6004 return castResult;
6005
6006 castResult = CheckItems();
6007 if (castResult != SPELL_CAST_OK)
6008 return castResult;
6009 }
6010
6011 // Triggered spells also have range check
6013 castResult = CheckRange(strict);
6014 if (castResult != SPELL_CAST_OK)
6015 return castResult;
6016
6018 {
6019 castResult = CheckPower();
6020 if (castResult != SPELL_CAST_OK)
6021 return castResult;
6022 }
6023
6025 {
6026 return SPELL_CAST_OK;
6027 }
6028
6029 // xinef: do not skip triggered spells if they posses prevention type (eg. Bladestorm vs Hand of Protection)
6031 {
6033 if (castResult != SPELL_CAST_OK)
6034 return castResult;
6035
6036 // 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).
6038 {
6039 auto const& mechanicList = m_caster->m_spellImmune[IMMUNITY_MECHANIC];
6040 if (mechanicList.count(m_spellInfo->Mechanic) > 0)
6042 }
6043 }
6044
6045 // script hook
6046 castResult = CallScriptCheckCastHandlers();
6047 if (castResult != SPELL_CAST_OK)
6048 return castResult;
6049
6050 bool hasDispellableAura = false;
6051 bool hasNonDispelEffect = false;
6052 uint32 dispelMask = 0;
6053 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
6054 if (m_spellInfo->Effects[i].Effect == SPELL_EFFECT_DISPEL)
6055 {
6057 {
6058 hasDispellableAura = true;
6059 break;
6060 }
6061
6062 dispelMask |= SpellInfo::GetDispelMask(DispelType(m_spellInfo->Effects[i].MiscValue));
6063 }
6064 else if (m_spellInfo->Effects[i].IsEffect())
6065 {
6066 hasNonDispelEffect = true;
6067 break;
6068 }
6069
6070 if (!hasNonDispelEffect && !hasDispellableAura && dispelMask && !IsTriggered())
6071 {
6072 if (Unit* target = m_targets.GetUnitTarget())
6073 {
6074 // Xinef: do not allow to cast on hostile targets in sanctuary
6075 if (!m_caster->IsFriendlyTo(target))
6076 {
6077 if (m_caster->IsInSanctuary() || target->IsInSanctuary())
6078 {
6079 // Xinef: fix for duels
6080 Player* player = m_caster->ToPlayer();
6081 if (!player || !player->duel || target != player->duel->Opponent)
6083 }
6084 }
6085
6086 DispelChargesList dispelList;
6087 target->GetDispellableAuraList(m_caster, dispelMask, dispelList, m_spellInfo);
6088
6089 if (dispelList.empty())
6091 }
6092 }
6093
6094 uint8 approximateAuraEffectMask = 0;
6095 uint8 nonAuraEffectMask = 0;
6096 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
6097 {
6098 // for effects of spells that have only one target
6099 switch (m_spellInfo->Effects[i].Effect)
6100 {
6102 {
6103 if (!m_caster->IsPlayer())
6105
6106 if (m_spellInfo->Effects[i].TargetA.GetTarget() != TARGET_UNIT_PET)
6107 break;
6108
6109 Pet* pet = m_caster->ToPlayer()->GetPet();
6110
6111 if (!pet)
6112 return SPELL_FAILED_NO_PET;
6113
6114 SpellInfo const* learn_spellproto = sSpellMgr->GetSpellInfo(m_spellInfo->Effects[i].TriggerSpell);
6115
6116 if (!learn_spellproto)
6118
6119 if (m_spellInfo->SpellLevel > pet->GetLevel())
6120 return SPELL_FAILED_LOWLEVEL;
6121
6122 break;
6123 }
6125 {
6126 // check target only for unit target case
6128 {
6129 if (!m_caster->IsPlayer())
6131
6132 Pet* pet = unitTarget->ToPet();
6133 if (!pet || pet->GetOwner() != m_caster)
6135
6136 SpellInfo const* learn_spellproto = sSpellMgr->GetSpellInfo(m_spellInfo->Effects[i].TriggerSpell);
6137
6138 if (!learn_spellproto)
6140
6141 if (m_spellInfo->SpellLevel > pet->GetLevel())
6142 return SPELL_FAILED_LOWLEVEL;
6143 }
6144 break;
6145 }
6147 {
6148 uint32 glyphId = m_spellInfo->Effects[i].MiscValue;
6149 if (GlyphPropertiesEntry const* gp = sGlyphPropertiesStore.LookupEntry(glyphId))
6150 if (m_caster->HasAura(gp->SpellId))
6152 break;
6153 }
6155 {
6156 if (!m_caster->IsPlayer())
6158
6159 Item* foodItem = m_targets.GetItemTarget();
6160 if (!foodItem)
6162
6163 Pet* pet = m_caster->ToPlayer()->GetPet();
6164
6165 if (!pet)
6166 return SPELL_FAILED_NO_PET;
6167
6168 if (!pet->HaveInDiet(foodItem->GetTemplate()))
6170
6171 if (!pet->GetCurrentFoodBenefitLevel(foodItem->GetTemplate()->ItemLevel))
6173
6174 if (m_caster->IsInCombat() || pet->IsInCombat())
6176
6177 break;
6178 }
6181 {
6182 // Can be area effect, Check only for players and not check if target - caster (spell can have multiply drain/burn effects)
6183 if (m_caster->IsPlayer())
6184 if (Unit* target = m_targets.GetUnitTarget())
6185 if (target != m_caster && !target->HasActivePowerType(Powers(m_spellInfo->Effects[i].MiscValue)))
6187 break;
6188 }
6190 {
6192 {
6194 }
6195
6197 {
6198 // Warbringer - can't be handled in proc system - should be done before checkcast root check and charge effect process
6199 if (strict && m_caster->IsScriptOverriden(m_spellInfo, 6953))
6201 }
6203 {
6204 // Exception for Master's Call
6205 if (m_spellInfo->Id != 54216)
6206 {
6207 return SPELL_FAILED_ROOTED;
6208 }
6209 }
6210 if (m_caster->IsPlayer())
6211 if (Unit* target = m_targets.GetUnitTarget())
6212 if (!target->IsAlive())
6214 // Xinef: Pass only explicit unit target spells
6215 // pussywizard:
6216 if (sDisableMgr->IsPathfindingEnabled(m_caster->FindMap()) && m_spellInfo->NeedsExplicitUnitTarget())
6217 {
6218 Unit* target = m_targets.GetUnitTarget();
6219 if (!target)
6221
6222 // first we must check to see if the target is in LoS. A path can usually be built but LoS matters for charge spells
6223 if (!target->IsWithinLOSInMap(m_caster)) //Do full LoS/Path check. Don't exclude m2
6225
6226 float objSize = target->GetCombatReach();
6227 float range = m_spellInfo->GetMaxRange(true, m_caster, this) * 1.5f + objSize; // can't be overly strict
6228
6229 m_preGeneratedPath = std::make_unique<PathGenerator>(m_caster);
6230 m_preGeneratedPath->SetPathLengthLimit(range);
6231
6232 // first try with raycast, if it fails fall back to normal path
6233 bool result = m_preGeneratedPath->CalculatePath(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), false);
6234 if (m_preGeneratedPath->GetPathType() & PATHFIND_SHORT)
6235 return SPELL_FAILED_NOPATH;
6236 else if (!result || m_preGeneratedPath->GetPathType() & (PATHFIND_NOPATH | PATHFIND_INCOMPLETE))
6237 return SPELL_FAILED_NOPATH;
6238 else if (m_preGeneratedPath->IsInvalidDestinationZ(target)) // Check position z, if not in a straight line
6239 return SPELL_FAILED_NOPATH;
6240
6241 m_preGeneratedPath->ShortenPathUntilDist(G3D::Vector3(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ()), objSize); // move back
6242 }
6243 if (Player* player = m_caster->ToPlayer())
6244 player->SetCanTeleport(true);
6245 break;
6246 }
6248 {
6251
6254
6255 Creature* creature = m_targets.GetUnitTarget()->ToCreature();
6256 if (!creature->IsCritter() && !creature->loot.isLooted())
6258
6259 uint32 skill = creature->GetCreatureTemplate()->GetRequiredLootSkill();
6260
6261 int32 skillValue = m_caster->ToPlayer()->GetSkillValue(skill);
6262 int32 TargetLevel = m_targets.GetUnitTarget()->GetLevel();
6263 int32 ReqValue = (skillValue < 100 ? (TargetLevel - 10) * 10 : TargetLevel * 5);
6264 if (ReqValue > skillValue)
6266
6267 break;
6268 }
6270 {
6271 if (m_spellInfo->Effects[i].TargetA.GetTarget() != TARGET_GAMEOBJECT_TARGET &&
6272 m_spellInfo->Effects[i].TargetA.GetTarget() != TARGET_GAMEOBJECT_ITEM_TARGET)
6273 break;
6274
6275 if (!m_caster->IsPlayer() // only players can open locks, gather etc.
6276 // we need a go target in case of TARGET_GAMEOBJECT_TARGET
6277 || (m_spellInfo->Effects[i].TargetA.GetTarget() == TARGET_GAMEOBJECT_TARGET && !m_targets.GetGOTarget()))
6279
6280 Item* pTempItem = nullptr;
6282 {
6283 if (TradeData* pTrade = m_caster->ToPlayer()->GetTradeData())
6284 pTempItem = pTrade->GetTraderData()->GetItem(TradeSlots(m_targets.GetItemTargetGUID().GetRawValue()));
6285 }
6288
6289 // we need a go target, or an openable item target in case of TARGET_GAMEOBJECT_ITEM_TARGET
6290 if (m_spellInfo->Effects[i].TargetA.GetTarget() == TARGET_GAMEOBJECT_ITEM_TARGET &&
6292 (!pTempItem || !pTempItem->GetTemplate()->LockID || !pTempItem->IsLocked()))
6294
6295 // We must also ensure the gameobject we are opening is still closed by the time the spell finishes.
6296 if (GameObject* go = m_targets.GetGOTarget())
6297 {
6298 if (go->GetGoType() == GAMEOBJECT_TYPE_DOOR && go->GetGoState() != GO_STATE_READY)
6299 {
6301 }
6302 }
6303 if (m_spellInfo->Id != 1842 || (m_targets.GetGOTarget() &&
6305 {
6306 if (m_targets.GetGOTarget() && m_targets.GetGOTarget()->GetEntry() == 179697)
6307 {
6308 if (!m_caster->ToPlayer()->CanUseBattlegroundObject(nullptr))
6310 }
6311 else if (m_caster->ToPlayer()->InBattleground() && // In Battleground players can use only flags and banners, or Gurubashi chest
6314 }
6315
6316 // get the lock entry
6317 uint32 lockId = 0;
6318 if (GameObject* go = m_targets.GetGOTarget())
6319 {
6320 lockId = go->GetGOInfo()->GetLockId();
6321 if (!lockId)
6323 }
6324 else if (Item* itm = m_targets.GetItemTarget())
6325 lockId = itm->GetTemplate()->LockID;
6326
6327 SkillType skillId = SKILL_NONE;
6328 int32 reqSkillValue = 0;
6329 int32 skillValue = 0;
6330
6331 // check lock compatibility
6332 SpellCastResult res = CanOpenLock(i, lockId, skillId, reqSkillValue, skillValue);
6333 if (res != SPELL_CAST_OK)
6334 return res;
6335
6336 // chance for fail at lockpicking attempt
6337 // second check prevent fail at rechecks
6338 // herbalism and mining cannot fail as of patch 3.1.0
6339 if (skillId != SKILL_NONE && skillId != SKILL_HERBALISM && skillId != SKILL_MINING && (!m_selfContainer || ((*m_selfContainer) != this)))
6340 {
6341 // chance for failure in orange lockpick
6342 if (skillId == SKILL_LOCKPICKING && reqSkillValue > irand(skillValue - 25, skillValue + 37))
6343 {
6345 }
6346 }
6347 break;
6348 }
6350 {
6351 Unit* unitCaster = m_caster->ToUnit();
6352 if (!unitCaster)
6353 {
6355 }
6356
6357 Creature* pet = unitCaster->GetGuardianPet();
6358 if (pet)
6359 {
6360 if (pet->IsAlive())
6361 {
6363 }
6364 }
6365 else if (Player* playerCaster = m_caster->ToPlayer())
6366 {
6367 PetStable& petStable = playerCaster->GetOrInitPetStable();
6368 if (!petStable.CurrentPet && petStable.UnslottedPets.empty())
6369 {
6370 return SPELL_FAILED_NO_PET;
6371 }
6372 }
6373
6374 break;
6375 }
6376 // This is generic summon effect
6378 {
6379 SummonPropertiesEntry const* SummonProperties = sSummonPropertiesStore.LookupEntry(m_spellInfo->Effects[i].MiscValueB);
6380 if (!SummonProperties || m_spellInfo->HasAttribute(SPELL_ATTR1_DISMISS_PET_FIRST))
6381 break;
6382 switch (SummonProperties->Category)
6383 {
6385 if (m_caster->GetPetGUID())
6387 [[fallthrough]];
6389 if (m_caster->GetCharmGUID())
6391 break;
6392 }
6393 break;
6394 }
6396 {
6398 {
6403 }
6404 break;
6405 }
6407 {
6408 Unit* unitCaster = m_caster->ToUnit();
6409 if (!unitCaster)
6411
6413 {
6414 if (m_caster->GetPetGUID())
6416 if (m_caster->GetCharmGUID())
6418 }
6419
6421 if (Pet* pet = m_caster->ToPlayer()->GetPet())
6422 pet->CastSpell(pet, 32752, true, nullptr, nullptr, pet->GetGUID()); //starting cast, trigger pet stun (cast by pet so it doesn't attack player)
6423
6424 Player* playerCaster = unitCaster->ToPlayer();
6425 if (playerCaster && playerCaster->GetPetStable())
6426 {
6427 std::pair<PetStable::PetInfo const*, PetSaveMode> info = Pet::GetLoadPetInfo(*playerCaster->GetPetStable(), m_spellInfo->Effects[i].MiscValue, 0, false);
6428 if (info.first)
6429 {
6430 if (info.first->Type == HUNTER_PET)
6431 {
6432 if (!info.first->Health)
6433 {
6434 playerCaster->SendTameFailure(PET_TAME_DEAD);
6436 }
6437
6438 CreatureTemplate const* creatureInfo = sObjectMgr->GetCreatureTemplate(info.first->CreatureId);
6439 if (!creatureInfo || !creatureInfo->IsTameable(playerCaster->CanTameExoticPets()))
6440 {
6441 // if problem in exotic pet
6442 if (creatureInfo && creatureInfo->IsTameable(true))
6444 else
6446
6448 }
6449 }
6450 }
6451 else if (!m_spellInfo->Effects[i].MiscValue) // when miscvalue is present it is allowed to create new pets
6452 {
6455 }
6456 }
6457 break;
6458 }
6460 {
6461 if (!m_caster->IsPlayer())
6463 if (!m_caster->GetTarget())
6465
6467 if (!target || (!target->IsInSameRaidWith(m_caster->ToPlayer()) && m_spellInfo->Id != 48955)) // refer-a-friend spell
6469
6470 // Xinef: Implement summon pending error
6471 if (target->GetSummonExpireTimer() > GameTime::GetGameTime().count())
6473
6474 // check if our map is dungeon
6475 MapEntry const* map = sMapStore.LookupEntry(m_caster->GetMapId());
6476 if (map->IsDungeon())
6477 {
6478 uint32 mapId = m_caster->GetMap()->GetId();
6479 Difficulty difficulty = m_caster->GetMap()->GetDifficulty();
6480 /*if (map->IsRaid())
6481 if (InstancePlayerBind* targetBind = target->GetBoundInstance(mapId, difficulty))
6482 if (targetBind->perm && targetBind != m_caster->ToPlayer()->GetBoundInstance(mapId, difficulty))
6483 return SPELL_FAILED_TARGET_LOCKED_TO_RAID_INSTANCE;*/
6484
6485 InstanceTemplate const* instance = sObjectMgr->GetInstanceTemplate(mapId);
6486 if (!instance)
6488 if (!target->Satisfy(sObjectMgr->GetAccessRequirement(mapId, difficulty), mapId))
6490 }
6491 break;
6492 }
6493 // RETURN HERE
6495 {
6496 if (!m_caster->IsPlayer())
6498
6499 Player* playerCaster = m_caster->ToPlayer();
6500 //
6501 if (!(playerCaster->GetTarget()))
6503
6505
6506 if (!target ||
6507 !(target->GetSession()->GetRecruiterId() == playerCaster->GetSession()->GetAccountId() || target->GetSession()->GetAccountId() == playerCaster->GetSession()->GetRecruiterId()))
6509
6510 // Xinef: Implement summon pending error
6511 if (target->GetSummonExpireTimer() > GameTime::GetGameTime().count())
6513
6514 break;
6515 }
6516 case SPELL_EFFECT_LEAP:
6518 {
6519 //Do not allow to cast it before BG starts.
6520 if (m_caster->IsPlayer())
6521 if (Battleground const* bg = m_caster->ToPlayer()->GetBattleground())
6522 if (bg->GetStatus() != STATUS_IN_PROGRESS)
6524 break;
6525 }
6527 {
6530
6531 bool found = false;
6533 for(Unit::VisibleAuraMap::const_iterator itr = visibleAuras->begin(); itr != visibleAuras->end(); ++itr)
6534 {
6535 if (itr->second->GetBase()->IsPassive())
6536 continue;
6537
6538 if (!itr->second->IsPositive())
6539 continue;
6540
6541 found = true;
6542 break;
6543 }
6544
6545 if (!found)
6547
6548 break;
6549 }
6551 {
6553 {
6554 if (m_caster->IsPlayer())
6555 return SPELL_FAILED_ROOTED;
6556 else
6558 }
6559 break;
6560 }
6561 // xinef: do not allow to use leaps while rooted
6562 case SPELL_EFFECT_JUMP:
6564 {
6566 return SPELL_FAILED_ROOTED;
6567 break;
6568 }
6570 if (!sScriptMgr->CanSelectSpecTalent(this))
6572 // can't change during already started arena/battleground
6573 if (m_caster->IsPlayer())
6574 if (Battleground const* bg = m_caster->ToPlayer()->GetBattleground())
6575 if (bg->GetStatus() == STATUS_IN_PROGRESS)
6577 break;
6578 default:
6579 break;
6580 }
6581
6582 if (m_spellInfo->Effects[i].IsAura())
6583 approximateAuraEffectMask |= 1 << i;
6584 else if (m_spellInfo->Effects[i].IsEffect())
6585 nonAuraEffectMask |= 1 << i;
6586 }
6587
6588 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
6589 {
6590 switch (m_spellInfo->Effects[i].ApplyAuraName)
6591 {
6592 case SPELL_AURA_DUMMY:
6593 break;
6595 {
6596 if (!m_caster->IsPlayer())
6597 return SPELL_FAILED_NO_PET;
6598
6599 Pet* pet = m_caster->ToPlayer()->GetPet();
6600 if (!pet)
6601 return SPELL_FAILED_NO_PET;
6602
6603 if (pet->GetCharmerGUID())
6604 return SPELL_FAILED_CHARMED;
6605 break;
6606 }
6610 {
6611 if (m_caster->GetCharmerGUID())
6612 return SPELL_FAILED_CHARMED;
6613
6614 // Xinef: allow SPELL_AURA_MOD_POSSESS to posses target if caster has some pet
6616 {
6617 if (m_caster->GetPetGUID())
6619
6620 if (m_caster->GetCharmGUID())
6622 }
6623 else if (m_spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_MOD_POSSESS)
6624 {
6625 if (m_caster->GetCharmGUID())
6627 }
6628
6629 if (Unit* target = m_targets.GetUnitTarget())
6630 {
6631 if (target->IsCreature() && target->ToCreature()->IsVehicle())
6633
6634 // Allow SPELL_AURA_MOD_POSSESS to work on mounted players,
6635 // but keep the old restriction for everything else.
6636 if (target->IsMounted())
6637 {
6638 if (!(target->IsPlayer() && m_spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_MOD_POSSESS))
6640 }
6641
6642 if (target->GetCharmerGUID())
6643 return SPELL_FAILED_CHARMED;
6644
6645 if (target->GetOwnerGUID() && target->GetOwnerGUID().IsPlayer())
6647
6648 if (target->IsPet() && (!target->GetOwner() || target->GetOwner()->ToPlayer()))
6650
6651 int32 damage = CalculateSpellDamage(i, target);
6652 if (damage && int32(target->GetLevel()) > damage)
6654 }
6655
6656 break;
6657 }
6658 case SPELL_AURA_MOUNTED:
6659 {
6660 // Disallow casting flying mounts in water
6663
6664 // Ignore map check if spell have AreaId. AreaId already checked and this prevent special mount spells
6665 bool allowMount = !m_caster->GetMap()->IsDungeon() || m_caster->GetMap()->IsBattlegroundOrArena();
6666 InstanceTemplate const* it = sObjectMgr->GetInstanceTemplate(m_caster->GetMapId());
6667 if (it)
6668 allowMount = it->AllowMount;
6669 if (m_caster->IsPlayer() && !allowMount && !m_spellInfo->AreaGroupId)
6671
6674
6675 // xinef: dont allow to cast mounts in specific transforms
6676 if (m_caster->getTransForm())
6677 if (SpellInfo const* transformSpellInfo = sSpellMgr->GetSpellInfo(m_caster->getTransForm()))
6678 if (transformSpellInfo->HasAttribute(SPELL_ATTR0_NO_IMMUNITIES) &&
6679 !transformSpellInfo->HasAttribute(SpellAttr0(SPELL_ATTR0_ALLOW_WHILE_MOUNTED | SPELL_ATTR0_AURA_IS_DEBUFF)))
6681
6682 break;
6683 }
6685 {
6686 if (!m_targets.GetUnitTarget())
6688
6689 // can be casted at non-friendly unit or own pet/charm
6692
6693 break;
6694 }
6695 case SPELL_AURA_FLY:
6697 {
6698 // Xinef: added water check
6699 if (m_caster->IsInWater())
6701
6702 // not allow cast fly spells if not have req. skills (all spells is self target)
6703 // allow always ghost flight spells
6705 {
6706 Battlefield* Bf = sBattlefieldMgr->GetBattlefieldToZoneId(m_originalCaster->GetZoneId());
6707 if (AreaTableEntry const* pArea = sAreaTableStore.LookupEntry(m_originalCaster->GetAreaId()))
6708 if ((pArea->flags & AREA_FLAG_NO_FLY_ZONE) || (Bf && !Bf->CanFlyIn()))
6709 return SPELL_FAILED_NOT_HERE;
6710 }
6711 break;
6712 }
6714 {
6715 if (m_spellInfo->Effects[i].IsTargetingArea())
6716 break;
6717
6718 if (!m_caster->IsPlayer() || m_CastItem)
6719 break;
6720
6721 if (!m_targets.GetUnitTarget())
6723
6726
6727 break;
6728 }
6729 case SPELL_AURA_HOVER:
6730 {
6732 {
6734 }
6735 break;
6736 }
6738 {
6739 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.
6740 {
6742 }
6743 break;
6744 }
6745 default:
6746 break;
6747 }
6748
6749 // check if target already has the same type, but more powerful aura
6750 if (!nonAuraEffectMask && (approximateAuraEffectMask & (1 << i)) && !m_spellInfo->IsTargetingArea())
6751 if (Unit* target = m_targets.GetUnitTarget())
6752 if (!target->IsHighestExclusiveAuraEffect(m_spellInfo, AuraType(m_spellInfo->Effects[i].ApplyAuraName),
6753 m_spellInfo->Effects[i].CalcValue(m_caster, &m_spellValue->EffectBasePoints[i]), approximateAuraEffectMask, false))
6755 }
6756
6757 // check trade slot case (last, for allow catch any another cast problems)
6759 {
6760 if (m_CastItem)
6762
6763 if (!m_caster->IsPlayer())
6765
6766 TradeData* my_trade = m_caster->ToPlayer()->GetTradeData();
6767
6768 if (!my_trade)
6770
6772 if (slot != TRADE_SLOT_NONTRADED)
6774
6775 if (!IsTriggered())
6776 if (my_trade->GetSpell())
6778 }
6779
6780 // check if caster has at least 1 combo point on target for spells that require combo points
6782 {
6784 {
6786 {
6788 }
6789 }
6790 else
6791 {
6792 if (!m_caster->GetComboPoints())
6793 {
6795 }
6796 }
6797 }
6798
6799 // xinef: check relic cooldown
6803
6804 // all ok
6805 return SPELL_CAST_OK;
6806}
#define SPECTATOR_SPELL_BINDSIGHT
Definition ArenaSpectator.h:38
#define sBattlefieldMgr
Definition BattlefieldMgr.h:79
@ STATUS_WAIT_LEAVE
Definition Battleground.h:194
@ STATUS_IN_PROGRESS
Definition Battleground.h:193
constexpr auto IN_MILLISECONDS
Definition Common.h:53
constexpr auto MINUTE
Definition Common.h:47
#define sConditionMgr
Definition ConditionMgr.h:296
@ CONDITION_SOURCE_TYPE_SPELL
Definition ConditionMgr.h:143
std::list< Condition * > ConditionList
Definition ConditionMgr.h:240
@ VEHICLE_SEAT_FLAG_CAN_CAST_MOUNT_SPELL
Definition DBCEnums.h:456
@ VEHICLE_SEAT_FLAG_UNCONTROLLED
Definition DBCEnums.h:457
@ VEHICLE_SEAT_FLAG_CAN_ATTACK
Definition DBCEnums.h:458
Difficulty
Definition DBCEnums.h:266
@ AREA_FLAG_NO_FLY_ZONE
Definition DBCEnums.h:262
DBCStorage< SummonPropertiesEntry > sSummonPropertiesStore(SummonPropertiesfmt)
DBCStorage< SpellShapeshiftFormEntry > sSpellShapeshiftFormStore(SpellShapeshiftFormEntryfmt)
DBCStorage< MapEntry > sMapStore(MapEntryfmt)
DBCStorage< GlyphPropertiesEntry > sGlyphPropertiesStore(GlyphPropertiesfmt)
DBCStorage< AreaTableEntry > sAreaTableStore(AreaTableEntryfmt)
std::uint16_t uint16
Definition Define.h:108
#define sDisableMgr
Definition DisableMgr.h:88
@ GO_STATE_READY
Definition GameObjectData.h:709
@ INVTYPE_RELIC
Definition ItemTemplate.h:284
LineOfSightChecks
Definition Map.h:106
@ LINEOFSIGHT_ALL_CHECKS
Definition Map.h:113
@ PATHFIND_NOPATH
Definition PathGenerator.h:50
@ PATHFIND_SHORT
Definition PathGenerator.h:52
@ PATHFIND_INCOMPLETE
Definition PathGenerator.h:49
@ HUNTER_PET
Definition PetDefines.h:33
@ PLAYER_ALLOW_ONLY_ABILITY
Definition Player.h:482
int32 irand(int32 min, int32 max)
Definition Random.cpp:37
@ GAMEOBJECT_TYPE_TRAP
Definition SharedDefines.h:1570
@ GAMEOBJECT_TYPE_DOOR
Definition SharedDefines.h:1564
Powers
Definition SharedDefines.h:256
@ POWER_MANA
Definition SharedDefines.h:257
@ SPELL_ATTR7_DEBUG_SPELL
Definition SharedDefines.h:632
@ SPELL_EFFECT_LEAP
Definition SharedDefines.h:795
@ SPELL_EFFECT_POWER_BURN
Definition SharedDefines.h:828
@ SPELL_EFFECT_STUCK
Definition SharedDefines.h:850
@ SPELL_EFFECT_SUMMON_RAF_FRIEND
Definition SharedDefines.h:918
@ SPELL_EFFECT_APPLY_GLYPH
Definition SharedDefines.h:840
@ SPELL_EFFECT_FEED_PET
Definition SharedDefines.h:867
@ SPELL_EFFECT_SUMMON_PLAYER
Definition SharedDefines.h:851
@ SPELL_EFFECT_JUMP_DEST
Definition SharedDefines.h:808
@ SPELL_EFFECT_TELEPORT_UNITS_FACE_CASTER
Definition SharedDefines.h:809
@ SPELL_EFFECT_RESURRECT_PET
Definition SharedDefines.h:875
@ SPELL_EFFECT_LEAP_BACK
Definition SharedDefines.h:904
@ SPELL_EFFECT_SUMMON
Definition SharedDefines.h:794
@ SPELL_EFFECT_POWER_DRAIN
Definition SharedDefines.h:774
@ SPELL_EFFECT_RESURRECT
Definition SharedDefines.h:784
@ SPELL_EFFECT_CHARGE
Definition SharedDefines.h:862
@ SPELL_EFFECT_RESURRECT_NEW
Definition SharedDefines.h:879
@ SPELL_EFFECT_TALENT_SPEC_SELECT
Definition SharedDefines.h:928
@ SPELL_EFFECT_LEARN_SPELL
Definition SharedDefines.h:802
@ SPELL_EFFECT_JUMP
Definition SharedDefines.h:807
@ SPELL_EFFECT_SKINNING
Definition SharedDefines.h:861
@ SPELL_EFFECT_CREATE_TAMED_PET
Definition SharedDefines.h:919
@ SPELL_EFFECT_OPEN_LOCK
Definition SharedDefines.h:799
@ SPELL_EFFECT_STEAL_BENEFICIAL_BUFF
Definition SharedDefines.h:892
@ SPELL_EFFECT_LEARN_PET_SPELL
Definition SharedDefines.h:823
@ SPELL_PREVENTION_TYPE_NONE
Definition SharedDefines.h:1557
@ SPELL_ATTR5_ALWAYS_AOE_LINE_OF_SIGHT
Definition SharedDefines.h:581
@ TARGET_UNIT_PET
Definition SharedDefines.h:1418
@ TARGET_GAMEOBJECT_TARGET
Definition SharedDefines.h:1431
@ SPELL_ATTR2_IGNORE_LINE_OF_SIGHT
Definition SharedDefines.h:446
@ SPELL_ATTR1_INITIATE_COMBAT
Definition SharedDefines.h:416
@ SPELL_ATTR3_ONLY_BATTLEGROUNDS
Definition SharedDefines.h:492
@ PET_TAME_NOPET_AVAILABLE
Definition SharedDefines.h:3939
@ PET_TAME_DEAD
Definition SharedDefines.h:3942
@ PET_TAME_CANT_CONTROL_EXOTIC
Definition SharedDefines.h:3944
@ CLASS_WARLOCK
Definition SharedDefines.h:134
@ IMMUNITY_MECHANIC
Definition SharedDefines.h:1403
@ SPELLFAMILY_WARRIOR
Definition SharedDefines.h:3788
SpellCustomErrors
Definition SharedDefines.h:1130
@ SPELL_CUSTOM_ERROR_GM_ONLY
Definition SharedDefines.h:1196
SpellAttr0
Definition SharedDefines.h:369
@ SPELL_ATTR0_ONLY_INDOORS
Definition SharedDefines.h:384
@ SPELL_ATTR0_AURA_IS_DEBUFF
Definition SharedDefines.h:396
@ SPELL_ATTR0_ONLY_OUTDOORS
Definition SharedDefines.h:385
@ SPELL_ATTR0_ALLOW_WHILE_MOUNTED
Definition SharedDefines.h:394
@ SPELL_ATTR0_PASSIVE
Definition SharedDefines.h:376
@ SPELL_ATTR0_ALLOW_CAST_WHILE_DEAD
Definition SharedDefines.h:393
@ SPELL_ATTR0_ONLY_STEALTHED
Definition SharedDefines.h:387
AuraStateType
Definition SharedDefines.h:1276
DispelType
Definition SharedDefines.h:1374
@ SPELL_FAILED_TARGET_NOT_LOOTED
Definition SharedDefines.h:1058
@ SPELL_FAILED_NOT_INFRONT
Definition SharedDefines.h:998
@ SPELL_FAILED_MOVING
Definition SharedDefines.h:988
@ SPELL_FAILED_NOT_MOUNTED
Definition SharedDefines.h:1001
@ SPELL_FAILED_AFFECTING_COMBAT
Definition SharedDefines.h:938
@ SPELL_FAILED_CASTER_AURASTATE
Definition SharedDefines.h:959
@ SPELL_FAILED_NOTHING_TO_DISPEL
Definition SharedDefines.h:1023
@ SPELL_FAILED_NOT_KNOWN
Definition SharedDefines.h:1000
@ SPELL_FAILED_FOOD_LOWLEVEL
Definition SharedDefines.h:972
@ SPELL_FAILED_NOT_HERE
Definition SharedDefines.h:997
@ SPELL_FAILED_ROOTED
Definition SharedDefines.h:1040
@ SPELL_FAILED_WRONG_PET_FOOD
Definition SharedDefines.h:1072
@ SPELL_FAILED_CUSTOM_ERROR
Definition SharedDefines.h:1109
@ SPELL_FAILED_SUMMON_PENDING
Definition SharedDefines.h:1120
@ SPELL_FAILED_DAMAGE_IMMUNE
Definition SharedDefines.h:1083
@ SPELL_FAILED_BAD_IMPLICIT_TARGETS
Definition SharedDefines.h:948
@ SPELL_FAILED_TRY_AGAIN
Definition SharedDefines.h:1069
@ SPELL_FAILED_NO_COMBO_POINTS
Definition SharedDefines.h:1015
@ SPELL_FAILED_ALREADY_HAVE_SUMMON
Definition SharedDefines.h:944
@ SPELL_FAILED_ALREADY_OPEN
Definition SharedDefines.h:945
@ SPELL_FAILED_NOT_TRADING
Definition SharedDefines.h:1008
@ SPELL_FAILED_NOTHING_TO_STEAL
Definition SharedDefines.h:1024
@ SPELL_FAILED_NO_MOUNTS_ALLOWED
Definition SharedDefines.h:1020
@ SPELL_FAILED_NOT_IN_BATTLEGROUND
Definition SharedDefines.h:1103
@ SPELL_FAILED_NOT_BEHIND
Definition SharedDefines.h:994
@ SPELL_FAILED_ALREADY_HAVE_CHARM
Definition SharedDefines.h:943
@ SPELL_FAILED_TARGET_NOT_IN_INSTANCE
Definition SharedDefines.h:1074
@ SPELL_FAILED_HIGHLEVEL
Definition SharedDefines.h:973
@ SPELL_FAILED_LOWLEVEL
Definition SharedDefines.h:985
@ SPELL_FAILED_NOT_READY
Definition SharedDefines.h:1004
@ SPELL_FAILED_ONLY_BATTLEGROUNDS
Definition SharedDefines.h:1079
@ SPELL_FAILED_NOT_IN_ARENA
Definition SharedDefines.h:1088
@ SPELL_FAILED_ITEM_ALREADY_ENCHANTED
Definition SharedDefines.h:979
@ SPELL_FAILED_ONLY_STEALTHED
Definition SharedDefines.h:1032
@ SPELL_FAILED_TARGET_IS_PLAYER_CONTROLLED
Definition SharedDefines.h:1055
@ SPELL_FAILED_ONLY_ABOVEWATER
Definition SharedDefines.h:1025
@ SPELL_FAILED_AURA_BOUNCED
Definition SharedDefines.h:946
@ SPELL_FAILED_CANT_BE_CHARMED
Definition SharedDefines.h:950
@ SPELL_FAILED_CASTER_DEAD
Definition SharedDefines.h:960
@ SPELL_FAILED_NOT_ON_MOUNTED
Definition SharedDefines.h:1092
@ SPELL_FAILED_ITEM_ENCHANT_TRADE_WINDOW
Definition SharedDefines.h:1119
@ SPELL_FAILED_TARGET_CANNOT_BE_RESURRECTED
Definition SharedDefines.h:1123
@ SPELL_FAILED_TARGET_UNSKINNABLE
Definition SharedDefines.h:1063
@ SPELL_FAILED_NOT_SHAPESHIFT
Definition SharedDefines.h:1005
@ SPELL_FAILED_UNIQUE_GLYPH
Definition SharedDefines.h:1113
@ SPELL_FAILED_ONLY_OUTDOORS
Definition SharedDefines.h:1030
@ SPELL_FAILED_CHARMED
Definition SharedDefines.h:961
@ SPELL_FAILED_LINE_OF_SIGHT
Definition SharedDefines.h:984
@ SPELL_FAILED_SPELL_IN_PROGRESS
Definition SharedDefines.h:1042
@ SPELL_FAILED_NO_PET
Definition SharedDefines.h:1021
@ SPELL_FAILED_NOPATH
Definition SharedDefines.h:993
@ SPELL_FAILED_SPELL_UNAVAILABLE
Definition SharedDefines.h:1044
@ SPELL_FAILED_ONLY_INDOORS
Definition SharedDefines.h:1027
@ SPELL_FAILED_NOT_ON_TAXI
Definition SharedDefines.h:1002
@ SPELL_FAILED_TARGET_FRIENDLY
Definition SharedDefines.h:1052
@ SPELL_ATTR4_IGNORE_DEFAULT_ARENA_RESTRICTIONS
Definition SharedDefines.h:535
@ SPELL_ATTR4_NOT_IN_ARENA_OR_RATED_BATTLEGROUND
Definition SharedDefines.h:534
@ SUMMON_CATEGORY_PET
Definition SharedDefines.h:3518
@ SUMMON_CATEGORY_PUPPET
Definition SharedDefines.h:3519
SkillType
Definition SharedDefines.h:3096
@ SKILL_MINING
Definition SharedDefines.h:3152
@ SKILL_HERBALISM
Definition SharedDefines.h:3148
@ SPELL_ATTR6_ALLOW_WHILE_RIDING_VEHICLE
Definition SharedDefines.h:604
@ SPELL_AURA_ABILITY_IGNORE_AURASTATE
Definition SpellAuraDefines.h:325
@ SPELL_AURA_MOD_SHAPESHIFT
Definition SpellAuraDefines.h:99
@ SPELL_AURA_MOD_IGNORE_SHAPESHIFT
Definition SpellAuraDefines.h:338
@ SPELL_AURA_PERIODIC_MANA_LEECH
Definition SpellAuraDefines.h:127
@ SPELL_AURA_MOD_POSSESS_PET
Definition SpellAuraDefines.h:191
@ SPELL_AURA_RANGED_ATTACK_POWER_ATTACKER_BONUS
Definition SpellAuraDefines.h:190
@ SPELL_AURA_DUMMY
Definition SpellAuraDefines.h:67
@ SPELL_AURA_FLY
Definition SpellAuraDefines.h:264
@ SPELL_AURA_HOVER
Definition SpellAuraDefines.h:169
@ SPELL_AURA_MOUNTED
Definition SpellAuraDefines.h:141
@ SPELL_AURA_AOE_CHARM
Definition SpellAuraDefines.h:240
@ SPELL_AURA_MOD_POSSESS
Definition SpellAuraDefines.h:65
@ SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED
Definition SpellAuraDefines.h:270
@ SPELL_AURA_BLOCK_SPELL_FAMILY
Definition SpellAuraDefines.h:360
@ AURA_INTERRUPT_FLAG_NOT_SEATED
Definition SpellDefines.h:61
@ AURA_INTERRUPT_FLAG_MOUNT
Definition SpellDefines.h:60
@ TRIGGERED_IGNORE_SPELL_AND_CATEGORY_CD
Will ignore GCD.
Definition SpellDefines.h:135
@ TRIGGERED_IGNORE_CASTER_AURASTATE
Will ignore shapeshift checks.
Definition SpellDefines.h:145
@ TRIGGERED_IGNORE_CASTER_MOUNTED_OR_ON_VEHICLE
Will ignore caster aura states including combat requirements and death state.
Definition SpellDefines.h:146
@ TRIGGERED_IGNORE_SHAPESHIFT
Will not adjust facing to target (if any)
Definition SpellDefines.h:144
@ TRIGGERED_IGNORE_GCD
Not triggered.
Definition SpellDefines.h:134
@ TRIGGERED_IGNORE_EFFECTS
Periodic aura tick wont be reset on override.
Definition SpellDefines.h:153
@ TRIGGERED_IGNORE_CASTER_AURAS
Will ignore mounted/on vehicle restrictions.
Definition SpellDefines.h:147
@ TARGET_FLAG_UNIT_ENEMY
Definition SpellInfo.h:54
@ TARGET_FLAG_ITEM
Definition SpellInfo.h:51
@ SPELL_ATTR0_CU_REQ_TARGET_FACING_CASTER
Definition SpellInfo.h:193
@ SPELL_ATTR0_CU_REQ_CASTER_BEHIND_TARGET
Definition SpellInfo.h:194
#define SPELL_RELIC_COOLDOWN
Definition SpellMgr.h:37
@ SPELL_FLAG_REDIRECTED
Definition Spell.h:95
TradeSlots
Definition TradeData.h:28
@ TRADE_SLOT_NONTRADED
Definition TradeData.h:31
@ MOVEMENTFLAG_FALLING_FAR
Definition UnitDefines.h:385
@ CLASS_CONTEXT_PET
Definition UnitDefines.h:243
@ UNIT_FLAG2_ALLOW_CHEAT_SPELLS
Definition UnitDefines.h:313
@ SHAPESHIFT_FLAG_STANCE
Definition UnitDefines.h:107
@ UNIT_STATE_ROOT
Definition UnitDefines.h:183
@ UNIT_STATE_CHARGING
Definition UnitDefines.h:190
@ UNIT_FLAG_SKINNABLE
Definition UnitDefines.h:283
#define WORLD_TRIGGER
Definition Unit.h:37
std::list< std::pair< Aura *, uint8 > > DispelChargesList
Definition Unit.h:78
Definition Battlefield.h:196
bool CanFlyIn() const
Return if we can use mount in battlefield.
Definition Battlefield.h:336
Definition Battleground.h:304
Loot loot
Definition Creature.h:231
CreatureTemplate const * GetCreatureTemplate() const
Definition Creature.h:207
bool IsSpellProhibited(SpellSchoolMask idSchoolMask) const
Definition Creature.cpp:2946
Definition GameObject.h:120
GameObjectTemplate const * GetGOInfo() const
Definition GameObject.h:136
Definition GroupReference.h:27
GroupReference * next()
Definition GroupReference.h:36
Definition Group.h:176
Definition InstanceScript.h:143
bool IsLocked() const
Definition Item.h:253
ItemTemplate const * GetTemplate() const
Definition Item.cpp:544
bool IsPotion() const
Definition Item.h:337
bool IsDungeon() const
Definition Map.h:297
bool IsBattlegroundOrArena() const
Definition Map.h:305
GameObject * GetGameObject(ObjectGuid const &guid)
Definition Map.cpp:2367
uint32 GetId() const
Definition Map.h:232
Difficulty GetDifficulty() const
Definition Map.h:292
uint64 GetRawValue() const
Definition ObjectGuid.h:142
bool IsPlayer() const
Definition ObjectGuid.h:168
bool IsGameObject() const
Definition ObjectGuid.h:171
Unit * ToUnit()
Definition Object.h:210
Definition PetDefines.h:212
Optional< PetInfo > CurrentPet
Definition PetDefines.h:235
std::vector< PetInfo > UnslottedPets
Definition PetDefines.h:238
Player * GetOwner() const
Definition Pet.cpp:2479
bool HaveInDiet(ItemTemplate const *item) const
Definition Pet.cpp:1424
uint32 GetCurrentFoodBenefitLevel(uint32 itemlevel) const
Definition Pet.cpp:1442
static std::pair< PetStable::PetInfo const *, PetSaveMode > GetLoadPetInfo(PetStable const &stable, uint32 petEntry, uint32 petnumber, bool current)
Definition Pet.cpp:171
void SetCanTeleport(bool value)
Definition Player.h:2539
bool IsInSameRaidWith(Player const *p) const
Definition Player.h:1906
bool CanTameExoticPets() const
Definition Player.h:2212
bool CanUseBattlegroundObject(GameObject *gameobject) const
Definition Player.cpp:13355
bool InBattleground() const
Definition Player.h:2291
PetStable * GetPetStable()
Definition Player.h:1222
Battleground * GetBattleground(bool create=false) const
Definition Player.cpp:12258
WorldSession * GetSession() const
Definition Player.h:2023
bool HasSpellCooldown(uint32 spell_id) const override
Definition Player.cpp:16489
uint32 GetLastPotionId()
Definition Player.h:1831
Group * GetGroup()
Definition Player.h:2509
bool IsGameMaster() const
Definition Player.h:1174
time_t GetSummonExpireTimer() const
Definition Player.h:1116
bool Satisfy(DungeonProgressionRequirements const *ar, uint32 target_map, bool report=false)
Definition PlayerStorage.cpp:6813
bool HasPlayerFlag(PlayerFlags flags) const
Definition Player.h:1123
std::unique_ptr< DuelInfo > duel
Definition Player.h:1898
Item * GetItemByGuid(ObjectGuid guid) const
Definition PlayerStorage.cpp:410
GameObject * GetGOTarget() const
Definition Spell.cpp:264
ObjectGuid GetItemTargetGUID() const
Definition Spell.h:150
AuraType ApplyAuraName
Definition SpellInfo.h:275
int32 MiscValue
Definition SpellInfo.h:284
uint32 PreventionType
Definition SpellInfo.h:414
uint32 CasterAuraSpell
Definition SpellInfo.h:367
SpellCastResult CheckShapeshift(uint32 form) const
Definition SpellInfo.cpp:1444
uint32 Mechanic
Definition SpellInfo.h:347
uint32 GetDispelMask() const
Definition SpellInfo.cpp:1948
uint32 GetRecoveryTime() const
Definition SpellInfo.cpp:2798
bool IsSelfCast() const
Definition SpellInfo.cpp:1122
uint32 CasterAuraState
Definition SpellInfo.h:363
bool CanBeUsedInCombat() const
Definition SpellInfo.cpp:1264
uint32 CasterAuraStateNot
Definition SpellInfo.h:365
SpellCastResult CheckLocation(uint32 map_id, uint32 zone_id, uint32 area_id, Player *player=nullptr, bool strict=true) const
Definition SpellInfo.cpp:1499
SpellSchoolMask GetSchoolMask() const
Definition SpellInfo.cpp:1894
int32 AreaGroupId
Definition SpellInfo.h:415
float GetMaxRange(bool positive=false, Unit *caster=nullptr, Spell *spell=nullptr) const
Definition SpellInfo.cpp:2723
uint32 GetExplicitTargetMask() const
Definition SpellInfo.cpp:1962
bool NeedsExplicitUnitTarget() const
Definition SpellInfo.cpp:1065
uint32 ExcludeCasterAuraSpell
Definition SpellInfo.h:369
bool IsTargetingArea() const
Definition SpellInfo.cpp:1057
uint32 SpellFamilyName
Definition SpellInfo.h:411
uint32 AuraInterruptFlags
Definition SpellInfo.h:377
SpellCastResult CheckExplicitTarget(Unit const *caster, WorldObject const *target, Item const *itemTarget=nullptr) const
Definition SpellInfo.cpp:1844
std::unique_ptr< PathGenerator > m_preGeneratedPath
Definition Spell.h:801
SpellCastResult CheckSpellFocus()
Definition Spell.cpp:7780
SpellCastResult CanOpenLock(uint32 effIndex, uint32 lockid, SkillType &skillid, int32 &reqSkillValue, int32 &skillValue)
Definition Spell.cpp:8407
int32 CalculateSpellDamage(uint8 i, Unit const *target) const
Definition Spell.h:491
SpellCastResult CheckPower()
Definition Spell.cpp:7136
SpellCastResult CheckCasterAuras(bool preventionOnly) const
Definition Spell.cpp:6844
SpellCastResult CallScriptCheckCastHandlers()
Definition Spell.cpp:8615
SpellCastResult CheckItems(uint32 *param1=nullptr, uint32 *param2=nullptr)
Definition Spell.cpp:7181
SpellCastResult CheckRange(bool strict)
Definition Spell.cpp:7050
bool HasGlobalCooldown() const
Definition Spell.cpp:8887
Definition TemporarySummon.h:50
uint32 GetSpell() const
Definition TradeData.h:49
bool IsVehicle() const
Definition Unit.h:800
Vehicle * GetVehicle() const
Definition Unit.h:1930
SpellImmuneContainer m_spellImmune[MAX_SPELL_IMMUNITY]
Definition Unit.h:2093
Unit * GetOwner() const
Definition Unit.cpp:7717
Pet * ToPet()
Definition Unit.h:729
virtual bool HasSpellCooldown(uint32) const
Definition Unit.h:1335
ShapeshiftForm GetShapeshiftForm() const
Definition Unit.h:1961
virtual bool HasSpellItemCooldown(uint32, uint32) const
Definition Unit.h:1336
bool IsInDisallowedMountForm() const
Definition Unit.cpp:17333
bool HasUnitFlag2(UnitFlags2 flags) const
Definition Unit.h:753
bool IsInSanctuary() const
Definition Unit.h:1043
virtual bool IsClass(Classes unitClass, ClassContext context=CLASS_CONTEXT_NONE) const
Definition Unit.h:844
AuraEffect * IsScriptOverriden(SpellInfo const *spell, int32 script) const
Definition Unit.cpp:6128
float GetCombatReach() const override
Definition Unit.h:877
UnitFlags GetUnitFlags() const
Definition Unit.h:746
TempSummon * ToTempSummon()
Definition Unit.h:731
bool HasStealthAura() const
Definition Unit.h:1845
bool HasAura(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemCasterGUID=ObjectGuid::Empty, uint8 reqEffMask=0) const
Definition Unit.cpp:6017
std::map< uint8, AuraApplication * > VisibleAuraMap
Definition Unit.h:687
bool IsInFlight() const
Definition Unit.h:1708
void SendTameFailure(uint8 result)
Definition Unit.cpp:16000
void GetDispellableAuraList(Unit *caster, uint32 dispelMask, DispelChargesList &dispelList, SpellInfo const *dispelSpell)
Definition Unit.cpp:5901
bool HasUnitMovementFlag(uint32 f) const
Definition Unit.h:774
virtual bool IsInWater() const
Definition Unit.cpp:4553
bool HasAuraState(AuraStateType flag, SpellInfo const *spellProto=nullptr, Unit const *Caster=nullptr) const
Definition Unit.cpp:7664
bool isMoving() const
Definition Unit.h:1711
void EngageWithTarget(Unit *who)
Definition Unit.cpp:7537
ObjectGuid GetCharmGUID() const
Definition Unit.h:721
VisibleAuraMap const * GetVisibleAuras()
Definition Unit.h:1539
bool IsMounted() const
Definition Unit.h:1890
Unit * GetVictim() const
Definition Unit.h:903
bool IsCritter() const
Definition Unit.h:833
bool IsFriendlyTo(Unit const *unit) const
Definition Unit.cpp:7276
ObjectGuid GetOwnerGUID() const
Definition Unit.h:713
bool IsHighestExclusiveAuraEffect(SpellInfo const *spellInfo, AuraType auraType, int32 effectAmount, uint8 auraEffectMask, bool removeOtherAuraApplications=false)
Definition Unit.cpp:4602
uint8 GetComboPoints(Unit const *who=nullptr) const
Definition Unit.h:1014
ObjectGuid GetCharmerGUID() const
Definition Unit.h:719
uint32 getTransForm() const
Definition Unit.h:1972
virtual bool HasActivePowerType(Powers power)
Definition Unit.h:1132
void RemoveMovementImpairingAuras(bool withRoot)
Definition Unit.cpp:5521
bool IsTotem() const
Definition Unit.h:799
Guardian * GetGuardianPet() const
Definition Unit.cpp:7768
ObjectGuid GetTarget() const
Definition Unit.h:861
bool IsInCombat() const
Definition Unit.h:935
ObjectGuid GetPetGUID() const
Definition Unit.h:723
Definition Vehicle.h:28
VehicleSeatEntry const * GetSeatForPassenger(Unit const *passenger)
Definition Vehicle.cpp:621
uint32 GetMapId() const
Definition Position.h:281
Map * GetMap() const
Definition Object.h:625
InstanceScript * GetInstanceScript() const
Definition Object.cpp:1238
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:1403
bool IsOutdoors() const
Definition Object.cpp:3136
bool IsWithinLOS(float x, float y, float z, VMAP::ModelIgnoreFlags ignoreFlags=VMAP::ModelIgnoreFlags::Nothing, LineOfSightChecks checks=LINEOFSIGHT_ALL_CHECKS) const
Definition Object.cpp:1382
float GetVisibilityRange() const
Definition Object.cpp:1701
uint32 GetAreaId() const
Definition Object.cpp:3119
uint32 GetZoneId() const
Definition Object.cpp:3111
void GetZoneAndAreaId(uint32 &zoneid, uint32 &areaid) const
Definition Object.cpp:3127
uint32 GetRecruiterId() const
Definition WorldSession.h:627
uint32 GetAccountId() const
Definition WorldSession.h:463
Seconds GetGameTime()
Definition GameTime.cpp:38
Player * FindPlayer(ObjectGuid const guid)
Definition ObjectAccessor.cpp:245
Definition DBCStructure.h:519
Definition ConditionMgr.h:185
Condition * mLastFailedCondition
Definition ConditionMgr.h:187
WorldObject * mConditionTargets[MAX_CONDITION_TARGETS]
Definition ConditionMgr.h:186
uint32 ErrorType
Definition ConditionMgr.h:208
uint8 ConditionTarget
Definition ConditionMgr.h:212
uint32 ErrorTextId
Definition ConditionMgr.h:209
SkillType GetRequiredLootSkill() const
Definition CreatureData.h:252
bool IsTameable(bool exotic) const
Definition CreatureData.h:269
uint32 type
Definition GameObjectData.h:34
Definition DBCStructure.h:1024
Definition Map.h:124
bool AllowMount
Definition Map.h:127
uint32 ItemLevel
Definition ItemTemplate.h:635
uint32 LockID
Definition ItemTemplate.h:669
uint32 InventoryType
Definition ItemTemplate.h:632
bool isLooted() const
Definition LootMgr.h:368
Definition DBCStructure.h:1325
bool IsDungeon() const
Definition DBCStructure.h:1351
void GetPosition(float &x, float &y) const
Definition Position.h:126
Definition DBCStructure.h:1817
uint32 flags1
Definition DBCStructure.h:1822
Definition DBCStructure.h:1909
uint32 Category
Definition DBCStructure.h:1911
Definition DBCStructure.h:2064
uint32 m_flags
Definition DBCStructure.h:2066

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

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

◆ CheckCasterAuras()

SpellCastResult Spell::CheckCasterAuras ( bool  preventionOnly) const
6845{
6846 // spells totally immuned to caster auras (wsg flag drop, give marks etc)
6848 return SPELL_CAST_OK;
6849
6850 uint8 school_immune = 0;
6851 uint64 mechanic_immune = 0;
6852 uint32 dispel_immune = 0;
6853
6854 // Check if the spell grants school or mechanic immunity.
6855 // We use bitmasks so the loop is done only once and not on every aura check below.
6857 {
6858 for (int i = 0; i < MAX_SPELL_EFFECTS; ++i)
6859 {
6860 if (m_spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_SCHOOL_IMMUNITY)
6861 school_immune |= uint32(m_spellInfo->Effects[i].MiscValue);
6862 else if (m_spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_MECHANIC_IMMUNITY)
6863 mechanic_immune |= 1ULL << uint32(m_spellInfo->Effects[i].MiscValue);
6864 else if (m_spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_DISPEL_IMMUNITY)
6865 dispel_immune |= SpellInfo::GetDispelMask(DispelType(m_spellInfo->Effects[i].MiscValue));
6866 }
6867 // immune movement impairment and loss of control
6868 // PVP trinket EMFH TOC PVP trinket Bullheaded Bestial Wrath // Beath Within // Medalion of Immunity
6869 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)
6871 }
6872
6874
6875 // Glyph of Pain Suppression
6876 // there is no other way to handle it
6877 if (m_spellInfo->Id == 33206 && !m_caster->HasAura(63248))
6878 usableInStun = false;
6879
6880 // Check whether the cast should be prevented by any state you might have.
6881 SpellCastResult prevented_reason = SPELL_CAST_OK;
6882 // Have to check if there is a stun aura. Otherwise will have problems with ghost aura apply while logging out
6883 uint32 unitflag = m_caster->GetUnitFlags(); // Get unit state
6884
6885 // Xinef: if spell is triggered check preventionType only
6886 if (!preventionOnly)
6887 {
6888 if (unitflag & UNIT_FLAG_STUNNED)
6889 {
6890 // spell is usable while stunned, check if caster has only mechanic stun auras, another stun types must prevent cast spell
6891 if (usableInStun)
6892 {
6893 bool foundNotStun = false;
6894 uint64 mask = (1ULL << MECHANIC_STUN) | (1ULL << MECHANIC_FREEZE) | (1ULL << MECHANIC_HORROR);
6895 // Barkskin should skip sleep effects, sap and fears
6896 if (m_spellInfo->Id == 22812)
6897 mask |= 1ULL << MECHANIC_SAPPED | 1ULL << MECHANIC_HORROR | 1ULL << MECHANIC_SLEEP;
6898 // Hand of Freedom, can be used while sapped and while under fear-mechanic stuns (e.g. Intimidating Shout primary target)
6899 if (m_spellInfo->Id == 1044)
6900 mask |= (1ULL << MECHANIC_SAPPED) | (1ULL << MECHANIC_FEAR);
6902 for (Unit::AuraEffectList::const_iterator i = stunAuras.begin(); i != stunAuras.end(); ++i)
6903 {
6904 if ((*i)->GetSpellInfo()->GetAllEffectsMechanicMask() && !((*i)->GetSpellInfo()->GetAllEffectsMechanicMask() & mask))
6905 {
6906 foundNotStun = true;
6907 break;
6908 }
6909 }
6910 if (foundNotStun)
6911 prevented_reason = SPELL_FAILED_STUNNED;
6912 }
6913 else
6914 prevented_reason = SPELL_FAILED_STUNNED;
6915 }
6917 prevented_reason = SPELL_FAILED_CONFUSED;
6919 prevented_reason = SPELL_FAILED_FLEEING;
6920 }
6921
6922 // Xinef: if there is no prevented_reason, check prevention types
6923 if (prevented_reason == SPELL_CAST_OK)
6924 {
6926 prevented_reason = SPELL_FAILED_SILENCED;
6928 prevented_reason = SPELL_FAILED_PACIFIED;
6929 }
6930
6931 // Attr must make flag drop spell totally immune from all effects
6932 if (prevented_reason != SPELL_CAST_OK)
6933 {
6934 if (school_immune || mechanic_immune || dispel_immune)
6935 {
6936 //Checking auras is needed now, because you are prevented by some state but the spell grants immunity.
6938 for (Unit::AuraApplicationMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
6939 {
6940 Aura const* aura = itr->second->GetBase();
6941 SpellInfo const* auraInfo = aura->GetSpellInfo();
6942 if (auraInfo->GetAllEffectsMechanicMask() & mechanic_immune)
6943 continue;
6944 if (auraInfo->GetSchoolMask() & school_immune && !auraInfo->HasAttribute(SPELL_ATTR1_IMMUNITY_TO_HOSTILE_AND_FRIENDLY_EFFECTS))
6945 continue;
6946 if (auraInfo->GetDispelMask() & dispel_immune)
6947 continue;
6948
6949 //Make a second check for spell failed so the right SPELL_FAILED message is returned.
6950 //That is needed when your casting is prevented by multiple states and you are only immune to some of them.
6951 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
6952 {
6953 if (AuraEffect* part = aura->GetEffect(i))
6954 {
6955 switch (part->GetAuraType())
6956 {
6958 {
6959 uint64 mask = 1ULL << MECHANIC_STUN;
6960 // Barkskin should skip sleep effects, sap and fears
6961 if (m_spellInfo->Id == 22812)
6962 mask |= 1ULL << MECHANIC_SAPPED | 1ULL << MECHANIC_HORROR | 1ULL << MECHANIC_SLEEP;
6963 // Hand of Freedom, can be used while sapped and while under fear-mechanic stuns (e.g. Intimidating Shout primary target)
6964 if (m_spellInfo->Id == 1044)
6965 mask |= (1ULL << MECHANIC_SAPPED) | (1ULL << MECHANIC_FEAR);
6966
6967 if (!usableInStun || !(auraInfo->GetAllEffectsMechanicMask() & mask))
6968 return SPELL_FAILED_STUNNED;
6969 break;
6970 }
6973 return SPELL_FAILED_CONFUSED;
6974 break;
6977 return SPELL_FAILED_FLEEING;
6978 break;
6983 return SPELL_FAILED_PACIFIED;
6985 return SPELL_FAILED_SILENCED;
6986 break;
6987 default:
6988 break;
6989 }
6990 }
6991 }
6992 }
6993 }
6994 // You are prevented from casting and the spell casted does not grant immunity. Return a failed error.
6995 else
6996 return prevented_reason;
6997 }
6998 return SPELL_CAST_OK;
6999}
constexpr uint64 IMMUNE_TO_MOVEMENT_IMPAIRMENT_AND_LOSS_CONTROL_MASK
Definition SharedDefines.h:1354
@ SPELL_PREVENTION_TYPE_SILENCE
Definition SharedDefines.h:1558
@ SPELL_PREVENTION_TYPE_PACIFY
Definition SharedDefines.h:1559
@ SPELL_ATTR5_ALLOW_WHILE_STUNNED
Definition SharedDefines.h:558
@ SPELL_ATTR5_ALLOW_WHILE_FLEEING
Definition SharedDefines.h:572
@ SPELL_ATTR5_ALLOW_WHILE_CONFUSED
Definition SharedDefines.h:573
@ SPELL_ATTR1_IMMUNITY_PURGES_EFFECT
Definition SharedDefines.h:422
@ SPELL_ATTR1_IMMUNITY_TO_HOSTILE_AND_FRIENDLY_EFFECTS
Definition SharedDefines.h:423
@ MECHANIC_FEAR
Definition SharedDefines.h:1318
@ MECHANIC_STUN
Definition SharedDefines.h:1325
@ MECHANIC_FREEZE
Definition SharedDefines.h:1326
@ MECHANIC_SLEEP
Definition SharedDefines.h:1323
@ MECHANIC_SAPPED
Definition SharedDefines.h:1343
@ MECHANIC_HORROR
Definition SharedDefines.h:1337
@ SPELL_FAILED_STUNNED
Definition SharedDefines.h:1045
@ SPELL_FAILED_CONFUSED
Definition SharedDefines.h:963
@ SPELL_FAILED_SILENCED
Definition SharedDefines.h:1041
@ SPELL_FAILED_FLEEING
Definition SharedDefines.h:971
@ SPELL_FAILED_PACIFIED
Definition SharedDefines.h:1035
@ SPELL_ATTR6_NOT_AN_ATTACK
Definition SharedDefines.h:594
@ SPELL_AURA_DISPEL_IMMUNITY
Definition SpellAuraDefines.h:104
@ SPELL_AURA_MOD_FEAR
Definition SpellAuraDefines.h:70
@ SPELL_AURA_MOD_PACIFY
Definition SpellAuraDefines.h:88
@ SPELL_AURA_MOD_SILENCE
Definition SpellAuraDefines.h:90
@ SPELL_AURA_SCHOOL_IMMUNITY
Definition SpellAuraDefines.h:102
@ SPELL_AURA_MECHANIC_IMMUNITY
Definition SpellAuraDefines.h:140
@ SPELL_AURA_MOD_PACIFY_SILENCE
Definition SpellAuraDefines.h:123
@ SPELL_AURA_MOD_CONFUSE
Definition SpellAuraDefines.h:68
@ SPELL_AURA_MOD_STUN
Definition SpellAuraDefines.h:75
@ UNIT_FLAG_STUNNED
Definition UnitDefines.h:275
@ UNIT_FLAG_PACIFIED
Definition UnitDefines.h:274
@ UNIT_FLAG_CONFUSED
Definition UnitDefines.h:279
@ UNIT_FLAG_FLEEING
Definition UnitDefines.h:280
@ UNIT_FLAG_SILENCED
Definition UnitDefines.h:270
Definition SpellAuraEffects.h:39
Definition SpellAuras.h:87
AuraEffect * GetEffect(uint8 effIndex) const
Definition SpellAuras.h:176
SpellInfo const * GetSpellInfo() const
Definition SpellAuras.h:100
uint64 GetAllEffectsMechanicMask() const
Definition SpellInfo.cpp:1899
std::multimap< uint32, AuraApplication * > AuraApplicationMap
Definition Unit.h:673
AuraApplicationMap & GetAppliedAuras()
Definition Unit.h:1383

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_FEAR, MECHANIC_FREEZE, MECHANIC_HORROR, MECHANIC_SAPPED, MECHANIC_SLEEP, MECHANIC_STUN, SpellInfo::PreventionType, SPELL_ATTR1_IMMUNITY_PURGES_EFFECT, SPELL_ATTR1_IMMUNITY_TO_HOSTILE_AND_FRIENDLY_EFFECTS, SPELL_ATTR5_ALLOW_WHILE_CONFUSED, SPELL_ATTR5_ALLOW_WHILE_FLEEING, SPELL_ATTR5_ALLOW_WHILE_STUNNED, SPELL_ATTR6_NOT_AN_ATTACK, SPELL_AURA_DISPEL_IMMUNITY, SPELL_AURA_MECHANIC_IMMUNITY, SPELL_AURA_MOD_CONFUSE, SPELL_AURA_MOD_FEAR, SPELL_AURA_MOD_PACIFY, SPELL_AURA_MOD_PACIFY_SILENCE, SPELL_AURA_MOD_SILENCE, SPELL_AURA_MOD_STUN, SPELL_AURA_SCHOOL_IMMUNITY, SPELL_CAST_OK, SPELL_FAILED_CONFUSED, SPELL_FAILED_FLEEING, SPELL_FAILED_PACIFIED, SPELL_FAILED_SILENCED, SPELL_FAILED_STUNNED, SPELL_PREVENTION_TYPE_PACIFY, SPELL_PREVENTION_TYPE_SILENCE, UNIT_FLAG_CONFUSED, UNIT_FLAG_FLEEING, UNIT_FLAG_PACIFIED, UNIT_FLAG_SILENCED, and UNIT_FLAG_STUNNED.

Referenced by CheckCast().

◆ CheckDst()

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

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

Referenced by SelectEffectImplicitTargets(), and SelectImplicitDestDestTargets().

◆ CheckEffectExecuteData()

void Spell::CheckEffectExecuteData ( )
protected
8549{
8550 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
8552}
#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
7963{
7964 switch (m_spellInfo->Effects[eff].ApplyAuraName)
7965 {
7970 if (target->IsCreature() && target->IsVehicle())
7971 return false;
7972 if (target->IsMounted() && m_spellInfo->Effects[eff].ApplyAuraName != SPELL_AURA_MOD_POSSESS)
7973 return false;
7974 if (target->GetCharmerGUID())
7975 return false;
7976 if (int32 damage = CalculateSpellDamage(eff, target))
7977 if ((int32)target->GetLevel() > damage)
7978 return false;
7979 break;
7980 default:
7981 break;
7982 }
7983
7984 // xinef: skip los checking if spell has appropriate attribute, or target requires specific entry
7985 // 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
7986 if (m_spellInfo->HasAttribute(SPELL_ATTR2_IGNORE_LINE_OF_SIGHT) || (target->IsCreature() && target->HasUnitFlag(UNIT_FLAG_NOT_SELECTABLE) && (m_spellInfo->Effects[eff].TargetA.GetCheckType() == TARGET_CHECK_ENTRY || m_spellInfo->Effects[eff].TargetB.GetCheckType() == TARGET_CHECK_ENTRY)))
7987 return true;
7988
7989 // if spell is triggered, need to check for LOS disable on the aura triggering it and inherit that behaviour
7992 {
7993 return true;
7994 }
7995
7997 //Check targets for LOS visibility (except spells without range limitations)
7998 switch (m_spellInfo->Effects[eff].Effect)
7999 {
8001 // player far away, maybe his corpse near?
8002 if (target != m_caster && !target->IsWithinLOSInMap(m_caster))
8003 {
8005 return false;
8006
8008 if (!corpse)
8009 return false;
8010
8011 if (target->GetGUID() != corpse->GetOwnerGUID())
8012 return false;
8013
8015 return false;
8016 }
8017 break;
8019 {
8021 {
8022 if (target->IsWithinLOSInMap(m_caster, VMAP::ModelIgnoreFlags::M2) && target->HasUnitFlag(UNIT_FLAG_SKINNABLE))
8023 return true;
8024
8025 return false;
8026 }
8027
8029 if (!corpse)
8030 return false;
8031
8032 if (target->GetGUID() != corpse->GetOwnerGUID())
8033 return false;
8034
8036 return false;
8037
8039 return false;
8040 }
8041 break;
8043 if (!m_caster->IsPlayer() || !target->IsPlayer())
8044 return false;
8045 if (m_caster->ToPlayer()->GetSession()->IsARecruiter() && target->ToPlayer()->GetSession()->GetRecruiterId() != m_caster->ToPlayer()->GetSession()->GetAccountId())
8046 return false;
8047 if (m_caster->ToPlayer()->GetSession()->GetRecruiterId() != target->ToPlayer()->GetSession()->GetAccountId() && target->ToPlayer()->GetSession()->IsARecruiter())
8048 return false;
8049 if (target->ToPlayer()->GetLevel() >= sWorld->getIntConfig(CONFIG_MAX_RECRUIT_A_FRIEND_BONUS_PLAYER_LEVEL))
8050 return false;
8051 break;
8052 default: // normal case
8053 {
8054 uint32 losChecks = LINEOFSIGHT_ALL_CHECKS;
8055 GameObject* gobCaster = nullptr;
8057 {
8059 }
8060 else if (m_caster->GetEntry() == WORLD_TRIGGER)
8061 {
8062 if (TempSummon* tempSummon = m_caster->ToTempSummon())
8063 {
8064 gobCaster = tempSummon->GetSummonerGameObject();
8065 }
8066 }
8067
8068 if (gobCaster)
8069 {
8070 if (gobCaster->GetGOInfo()->IsIgnoringLOSChecks())
8071 {
8072 return true;
8073 }
8074
8075 // If spell casted by gameobject then ignore M2 models
8076 losChecks &= ~LINEOFSIGHT_CHECK_GOBJECT_M2;
8077 }
8078
8079 if (target != m_caster)
8080 {
8081 if (m_targets.HasDst())
8082 {
8083 float x = m_targets.GetDstPos()->GetPositionX();
8084 float y = m_targets.GetDstPos()->GetPositionY();
8085 float z = m_targets.GetDstPos()->GetPositionZ();
8086
8087 if (!target->IsWithinLOS(x, y, z, VMAP::ModelIgnoreFlags::M2, LineOfSightChecks(losChecks)))
8088 {
8089 return false;
8090 }
8091 }
8093 {
8094 return false;
8095 }
8096 }
8097 break;
8098 }
8099 }
8100
8101 return true;
8102}
@ CORPSE_FLAG_LOOTABLE
Definition Corpse.h:45
@ SPELL_DISABLE_LOS
Definition DisableMgr.h:50
@ DISABLE_TYPE_SPELL
Definition DisableMgr.h:28
@ SPELL_EFFECT_SKIN_PLAYER_CORPSE
Definition SharedDefines.h:882
@ TARGET_CHECK_ENTRY
Definition SpellInfo.h:116
@ UNIT_FLAG_NOT_SELECTABLE
Definition UnitDefines.h:282
@ CORPSE_FIELD_FLAGS
Definition UpdateFields.h:427
@ CONFIG_MAX_RECRUIT_A_FRIEND_BONUS_PLAYER_LEVEL
Definition WorldConfig.h:204
Definition Corpse.h:49
ObjectGuid GetOwnerGUID() const
Definition Corpse.h:68
bool HasFlag(uint16 index, uint32 flag) const
Definition Object.cpp:871
ObjectGuid GetCorpseTargetGUID() const
Definition Spell.cpp:281
bool IsARecruiter() const
Definition WorldSession.h:628
#define sWorld
Definition World.h:317
Corpse * GetCorpse(WorldObject const &u, ObjectGuid const &guid)
Definition ObjectAccessor.cpp:179
bool IsIgnoringLOSChecks() const
Definition GameObjectData.h:645

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

Referenced by AddUnitTarget().

◆ CheckItems()

SpellCastResult Spell::CheckItems ( uint32 param1 = nullptr,
uint32 param2 = nullptr 
)
Todo:
Needs review
Todo:
: Not sure whether the fallthrough was a mistake (forgetting a break) or intended. This should be double-checked.
7182{
7183 Player* player = m_caster->ToPlayer();
7184 if (!player)
7185 {
7186 // Non-player case: Check if creature is disarmed
7188 {
7190 }
7191
7192 return SPELL_CAST_OK;
7193 }
7194
7195 if (!m_CastItem)
7196 {
7197 if (m_castItemGUID)
7199 }
7200 else
7201 {
7202 uint32 itemid = m_CastItem->GetEntry();
7203 if (!player->HasItemCount(itemid))
7205
7206 ItemTemplate const* proto = m_CastItem->GetTemplate();
7207 if (!proto)
7209
7210 for (int i = 0; i < MAX_ITEM_SPELLS; ++i)
7211 if (proto->Spells[i].SpellCharges)
7212 if (m_CastItem->GetSpellCharges(i) == 0)
7214
7215 // consumable cast item checks
7217 {
7218 // such items should only fail if there is no suitable effect at all - see Rejuvenation Potions for example
7219 SpellCastResult failReason = SPELL_CAST_OK;
7220 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; i++)
7221 {
7222 // skip check, pet not required like checks, and for TARGET_UNIT_PET m_targets.GetUnitTarget() is not the real target but the caster
7223 if (m_spellInfo->Effects[i].TargetA.GetTarget() == TARGET_UNIT_PET)
7224 continue;
7225
7226 if (m_spellInfo->Effects[i].Effect == SPELL_EFFECT_HEAL)
7227 {
7229 {
7231 continue;
7232 }
7233 else
7234 {
7235 failReason = SPELL_CAST_OK;
7236 break;
7237 }
7238 }
7239
7240 // Mana Potion, Rage Potion, Thistle Tea(Rogue), ...
7241 if (m_spellInfo->Effects[i].Effect == SPELL_EFFECT_ENERGIZE)
7242 {
7243 if (m_spellInfo->Effects[i].MiscValue < 0 || m_spellInfo->Effects[i].MiscValue >= int8(MAX_POWERS))
7244 {
7246 continue;
7247 }
7248
7249 Powers power = Powers(m_spellInfo->Effects[i].MiscValue);
7251 {
7253 continue;
7254 }
7255 else
7256 {
7257 failReason = SPELL_CAST_OK;
7258 break;
7259 }
7260 }
7261 }
7262 if (failReason != SPELL_CAST_OK)
7263 return failReason;
7264 }
7265 }
7266
7267 // check target item
7269 {
7270 if (!m_caster->IsPlayer())
7272
7273 if (!m_targets.GetItemTarget())
7275
7278 }
7279 // if not item target then required item must be equipped
7280 else
7281 {
7282 // Xinef: this is not true in my opinion, in eg bladestorm will not be canceled after disarm
7283 //if (!HasTriggeredCastFlag(TRIGGERED_IGNORE_EQUIPPED_ITEM_REQUIREMENT))
7286 }
7287
7288 // do not take reagents for these item casts
7290 {
7292 // Not own traded item (in trader trade slot) requires reagents even if triggered spell
7293 if (!checkReagents)
7294 if (Item* targetItem = m_targets.GetItemTarget())
7295 if (targetItem->GetOwnerGUID() != m_caster->GetGUID())
7296 checkReagents = true;
7297
7298 // check reagents (ignore triggered spells with reagents processed by original spell) and special reagent ignore case.
7299 if (checkReagents)
7300 {
7301 for (uint32 i = 0; i < MAX_SPELL_REAGENTS; i++)
7302 {
7303 if (m_spellInfo->Reagent[i] <= 0)
7304 continue;
7305
7306 uint32 itemid = m_spellInfo->Reagent[i];
7307 uint32 itemcount = m_spellInfo->ReagentCount[i];
7308
7309 // if CastItem is also spell reagent
7310 if (m_CastItem && m_CastItem->GetEntry() == itemid)
7311 {
7312 ItemTemplate const* proto = m_CastItem->GetTemplate();
7313 if (!proto)
7315 for (int s = 0; s < MAX_ITEM_PROTO_SPELLS; ++s)
7316 {
7317 // CastItem will be used up and does not count as reagent
7318 int32 charges = m_CastItem->GetSpellCharges(s);
7319 if (proto->Spells[s].SpellCharges < 0 && std::abs(charges) < 2)
7320 {
7321 ++itemcount;
7322 break;
7323 }
7324 }
7325 }
7326 if (!player->HasItemCount(itemid, itemcount))
7327 return SPELL_FAILED_REAGENTS;
7328 }
7329 }
7330
7331 // check totem-item requirements (items presence in inventory)
7332 uint32 totems = 2;
7333 for (int i = 0; i < 2; ++i)
7334 {
7335 if (m_spellInfo->Totem[i] != 0)
7336 {
7337 if (player->HasItemCount(m_spellInfo->Totem[i]))
7338 {
7339 totems -= 1;
7340 continue;
7341 }
7342 }
7343 else
7344 totems -= 1;
7345 }
7346 if (totems != 0)
7347 return SPELL_FAILED_TOTEMS; //0x7C
7348
7349 // Check items for TotemCategory (items presence in inventory)
7351 for (int i = 0; i < 2; ++i)
7352 {
7353 if (m_spellInfo->TotemCategory[i] != 0)
7354 {
7356 {
7357 TotemCategory -= 1;
7358 continue;
7359 }
7360 }
7361 else
7362 TotemCategory -= 1;
7363 }
7364 if (TotemCategory != 0)
7365 return SPELL_FAILED_TOTEM_CATEGORY; //0x7B
7366 }
7367
7368 // special checks for spell effects
7369 for (int i = 0; i < MAX_SPELL_EFFECTS; i++)
7370 {
7371 switch (m_spellInfo->Effects[i].Effect)
7372 {
7375 {
7376 // m_targets.GetUnitTarget() means explicit cast, otherwise we dont check for possible equip error
7377 Unit* target = m_targets.GetUnitTarget() ? m_targets.GetUnitTarget() : player;
7378 if (target->IsPlayer() && !IsTriggered())
7379 {
7380 // 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,
7381 // so we need to make sure there is at least one free space in the player's inventory
7383 if (target->ToPlayer()->GetFreeInventorySpace() == 0)
7384 {
7385 player->SendEquipError(EQUIP_ERR_INVENTORY_FULL, nullptr, nullptr, m_spellInfo->Effects[i].ItemType);
7387 }
7388
7389 if (m_spellInfo->Effects[i].ItemType)
7390 {
7391 ItemTemplate const* itemTemplate = sObjectMgr->GetItemTemplate(m_spellInfo->Effects[i].ItemType);
7392 if (!itemTemplate)
7394
7395 uint32 createCount = std::clamp<uint32>(m_spellInfo->Effects[i].CalcValue(), 1u, itemTemplate->GetMaxStackSize());
7396 ItemPosCountVec dest;
7397 InventoryResult msg = target->ToPlayer()->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, m_spellInfo->Effects[i].ItemType, createCount);
7398 if (msg != EQUIP_ERR_OK)
7399 {
7401 if (!itemTemplate->ItemLimitCategory)
7402 {
7403 player->SendEquipError(msg, nullptr, nullptr, m_spellInfo->Effects[i].ItemType);
7405 }
7406 else
7407 {
7408 // Conjure Food/Water/Refreshment spells
7411 else if (!(target->ToPlayer()->HasItemCount(m_spellInfo->Effects[i].ItemType)))
7412 {
7413 player->SendEquipError(msg, nullptr, nullptr, m_spellInfo->Effects[i].ItemType);
7415 }
7416 else
7417 player->CastSpell(player, m_spellInfo->Effects[EFFECT_1].CalcValue(), false); // move this to anywhere
7418
7420 }
7421 }
7422 }
7423 }
7424 break;
7425 }
7427 {
7428 if (player->GetFreeInventorySpace() == 0)
7429 {
7430 player->SendEquipError(EQUIP_ERR_INVENTORY_FULL, nullptr, nullptr, m_spellInfo->Effects[i].ItemType);
7432 }
7433 break;
7434 }
7436 if (m_spellInfo->Effects[i].ItemType && m_targets.GetItemTarget()
7438 {
7439 // cannot enchant vellum for other player
7442 // do not allow to enchant vellum from scroll made by vellum-prevent exploit
7445 ItemPosCountVec dest;
7446 InventoryResult msg = player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, m_spellInfo->Effects[i].ItemType, 1);
7447 if (msg != EQUIP_ERR_OK)
7448 {
7449 player->SendEquipError(msg, nullptr, nullptr, m_spellInfo->Effects[i].ItemType);
7451 }
7452 }
7453 [[fallthrough]];
7455 {
7456 Item* targetItem = m_targets.GetItemTarget();
7457 if (!targetItem)
7459
7460 // Apply item level restriction
7462 {
7463 uint32 requiredLevel = targetItem->GetTemplate()->RequiredLevel;
7464 if (!requiredLevel)
7465 requiredLevel = targetItem->GetTemplate()->ItemLevel;
7466
7467 if (requiredLevel < m_spellInfo->BaseLevel)
7468 return SPELL_FAILED_LOWLEVEL;
7469 }
7470
7471 if (m_CastItem && m_spellInfo->MaxLevel > 0 && targetItem->GetTemplate()->ItemLevel > m_spellInfo->MaxLevel)
7473
7474 bool isItemUsable = false;
7475 for (uint8 e = 0; e < MAX_ITEM_PROTO_SPELLS; ++e)
7476 {
7477 ItemTemplate const* proto = targetItem->GetTemplate();
7478 if (proto->Spells[e].SpellId && (
7481 {
7482 isItemUsable = true;
7483 break;
7484 }
7485 }
7486
7487 SpellItemEnchantmentEntry const* enchantEntry = sSpellItemEnchantmentStore.LookupEntry(m_spellInfo->Effects[i].MiscValue);
7488 // do not allow adding usable enchantments to items that have use effect already
7489 if (enchantEntry)
7490 {
7491 for (uint8 s = 0; s < MAX_SPELL_ITEM_ENCHANTMENT_EFFECTS; ++s)
7492 {
7493 switch (enchantEntry->type[s])
7494 {
7496 if (isItemUsable)
7498 break;
7500 {
7501 uint32 numSockets = 0;
7502 for (uint32 socket = 0; socket < MAX_ITEM_PROTO_SOCKETS; ++socket)
7503 if (targetItem->GetTemplate()->Socket[socket].Color)
7504 ++numSockets;
7505
7506 if (numSockets == MAX_ITEM_PROTO_SOCKETS || targetItem->GetEnchantmentId(PRISMATIC_ENCHANTMENT_SLOT))
7508 break;
7509 }
7510 }
7511 }
7512 }
7513
7514 // Not allow enchant in trade slot for some enchant type
7515 if (targetItem->GetOwner() != m_caster)
7516 {
7517 if (!enchantEntry)
7518 return SPELL_FAILED_ERROR;
7519 if (enchantEntry->slot & ENCHANTMENT_CAN_SOULBOUND)
7521 }
7522 break;
7523 }
7525 {
7526 Item* item = m_targets.GetItemTarget();
7527 if (!item)
7529 // Not allow enchant in trade slot for some enchant type
7530 if (item->GetOwner() != m_caster)
7531 {
7532 uint32 enchant_id = m_spellInfo->Effects[i].MiscValue;
7533 SpellItemEnchantmentEntry const* pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id);
7534 if (!pEnchant)
7535 return SPELL_FAILED_ERROR;
7536 if (pEnchant->slot & ENCHANTMENT_CAN_SOULBOUND)
7538 }
7539
7540 // Apply item level restriction
7542 {
7543 uint32 requiredLevel = item->GetTemplate()->RequiredLevel;
7544 if (!requiredLevel)
7545 requiredLevel = item->GetTemplate()->ItemLevel;
7546
7547 if (requiredLevel < m_spellInfo->BaseLevel)
7548 return SPELL_FAILED_LOWLEVEL;
7549 }
7550
7553
7554 break;
7555 }
7557 // check item existence in effect code (not output errors at offhand hold item effect to main hand for example
7558 break;
7560 {
7561 if (!m_targets.GetItemTarget())
7563
7564 // prevent disenchanting in trade slot
7567
7568 ItemTemplate const* itemProto = m_targets.GetItemTarget()->GetTemplate();
7569 if (!itemProto)
7571
7572 uint32 item_quality = itemProto->Quality;
7573 // 2.0.x addon: Check player enchanting level against the item disenchanting requirements
7574 uint32 item_disenchantskilllevel = itemProto->RequiredDisenchantSkill;
7575 if (item_disenchantskilllevel == uint32(-1))
7577 if (item_disenchantskilllevel > player->GetSkillValue(SKILL_ENCHANTING))
7579 if (item_quality > 4 || item_quality < 2)
7581 if (itemProto->Class != ITEM_CLASS_WEAPON && itemProto->Class != ITEM_CLASS_ARMOR)
7583 if (!itemProto->DisenchantID)
7585 break;
7586 }
7588 {
7589 Item* item = m_targets.GetItemTarget();
7590 if (!item)
7592 //ensure item is a prospectable ore
7595 //prevent prospecting in trade slot
7596 if (item->GetOwnerGUID() != m_caster->GetGUID())
7598 //Check for enough skill in jewelcrafting
7599 uint32 item_prospectingskilllevel = item->GetTemplate()->RequiredSkillRank;
7600 if (item_prospectingskilllevel > player->GetSkillValue(SKILL_JEWELCRAFTING))
7602 //make sure the player has the required ores in inventory
7603 if (item->GetCount() < 5)
7604 {
7605 if (param1 && param2)
7606 {
7607 *param1 = item->GetEntry();
7608 *param2 = 5;
7609 }
7611 }
7612
7615
7616 break;
7617 }
7619 {
7620 Item* item = m_targets.GetItemTarget();
7621 if (!item)
7623 //ensure item is a millable herb
7624 if (!(item->GetTemplate()->HasFlag(ITEM_FLAG_IS_MILLABLE)))
7626 //prevent milling in trade slot
7627 if (item->GetOwnerGUID() != m_caster->GetGUID())
7629 //Check for enough skill in inscription
7630 uint32 item_millingskilllevel = item->GetTemplate()->RequiredSkillRank;
7631 if (item_millingskilllevel > player->GetSkillValue(SKILL_INSCRIPTION))
7633 //make sure the player has the required herbs in inventory
7634 if (item->GetCount() < 5)
7635 {
7636 if (param1 && param2)
7637 {
7638 *param1 = item->GetEntry();
7639 *param2 = 5;
7640 }
7642 }
7643
7646
7647 break;
7648 }
7651 {
7652 if (!m_caster->IsPlayer())
7654
7656 break;
7657
7659 if (!pItem || pItem->IsBroken())
7661
7662 switch (pItem->GetTemplate()->SubClass)
7663 {
7665 {
7666 uint32 ammo = pItem->GetEntry();
7667 if (!m_caster->ToPlayer()->HasItemCount(ammo))
7668 return SPELL_FAILED_NO_AMMO;
7669 };
7670 break;
7674 {
7676 if (!ammo)
7677 {
7678 // Requires No Ammo
7679 if (m_caster->HasAura(46699))
7680 break; // skip other checks
7681
7682 return SPELL_FAILED_NO_AMMO;
7683 }
7684
7685 ItemTemplate const* ammoProto = sObjectMgr->GetItemTemplate(ammo);
7686 if (!ammoProto)
7687 return SPELL_FAILED_NO_AMMO;
7688
7689 if (ammoProto->Class != ITEM_CLASS_PROJECTILE)
7690 return SPELL_FAILED_NO_AMMO;
7691
7692 // check ammo ws. weapon compatibility
7693 switch (pItem->GetTemplate()->SubClass)
7694 {
7697 if (ammoProto->SubClass != ITEM_SUBCLASS_ARROW)
7698 return SPELL_FAILED_NO_AMMO;
7699 break;
7701 if (ammoProto->SubClass != ITEM_SUBCLASS_BULLET)
7702 return SPELL_FAILED_NO_AMMO;
7703 break;
7704 default:
7705 return SPELL_FAILED_NO_AMMO;
7706 }
7707
7708 if (!m_caster->ToPlayer()->HasItemCount(ammo))
7709 {
7711 return SPELL_FAILED_NO_AMMO;
7712 }
7713 };
7714 break;
7716 break;
7717 default:
7718 break;
7719 }
7720 break;
7721 }
7723 {
7724 uint32 item_id = m_spellInfo->Effects[i].ItemType;
7725 ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(item_id);
7726
7727 if (!pProto)
7729
7730 if (Item* pitem = player->GetItemByEntry(item_id))
7731 {
7732 for (int x = 0; x < MAX_ITEM_PROTO_SPELLS; ++x)
7733 if (pProto->Spells[x].SpellCharges != 0 && pitem->GetSpellCharges(x) == pProto->Spells[x].SpellCharges)
7735 }
7736 break;
7737 }
7738 default:
7739 break;
7740 }
7741 }
7742
7743 // check weapon presence in slots for main/offhand weapons
7744 if (/*never skip those checks !HasTriggeredCastFlag(TRIGGERED_IGNORE_EQUIPPED_ITEM_REQUIREMENT) &&*/ m_spellInfo->EquippedItemClass >= 0)
7745 {
7746 // main hand weapon required
7748 {
7750
7751 // skip spell if no weapon in slot or broken
7752 if (!item || item->IsBroken())
7754
7755 // skip spell if weapon not fit to triggered spell
7758 }
7759
7760 // offhand hand weapon required
7762 {
7764
7765 // skip spell if no weapon in slot or broken
7766 if (!item || item->IsBroken())
7768
7769 // skip spell if weapon not fit to triggered spell
7772 }
7773
7775 }
7776
7777 return SPELL_CAST_OK;
7778}
@ ITEM_ENCHANTMENT_TYPE_USE_SPELL
Definition DBCEnums.h:373
@ ITEM_ENCHANTMENT_TYPE_PRISMATIC_SOCKET
Definition DBCEnums.h:374
DBCStorage< SpellItemEnchantmentEntry > sSpellItemEnchantmentStore(SpellItemEnchantmentfmt)
#define MAX_SPELL_REAGENTS
Definition DBCStructure.h:1639
#define MAX_SPELL_ITEM_ENCHANTMENT_EFFECTS
Definition DBCStructure.h:1838
std::int8_t int8
Definition Define.h:105
@ ITEM_SUBCLASS_WEAPON_CROSSBOW
Definition ItemTemplate.h:362
@ ITEM_SUBCLASS_WEAPON_GUN
Definition ItemTemplate.h:347
@ ITEM_SUBCLASS_WEAPON_BOW
Definition ItemTemplate.h:346
@ ITEM_SUBCLASS_WEAPON_WAND
Definition ItemTemplate.h:363
@ ITEM_SUBCLASS_WEAPON_THROWN
Definition ItemTemplate.h:360
@ ITEM_SPELLTRIGGER_ON_USE
Definition ItemTemplate.h:77
@ ITEM_SPELLTRIGGER_ON_NO_DELAY_USE
Definition ItemTemplate.h:87
@ ITEM_FLAG_IS_MILLABLE
Definition ItemTemplate.h:176
@ ITEM_FLAG_NO_REAGENT_COST
Definition ItemTemplate.h:175
@ ITEM_FLAG_IS_PROSPECTABLE
Definition ItemTemplate.h:165
@ ITEM_SUBCLASS_ARROW
Definition ItemTemplate.h:416
@ ITEM_SUBCLASS_BULLET
Definition ItemTemplate.h:417
#define MAX_ITEM_PROTO_SOCKETS
Definition ItemTemplate.h:614
#define MAX_ITEM_PROTO_SPELLS
Definition ItemTemplate.h:615
@ ITEM_CLASS_PROJECTILE
Definition ItemTemplate.h:297
@ ITEM_CLASS_ARMOR
Definition ItemTemplate.h:295
@ ITEM_CLASS_WEAPON
Definition ItemTemplate.h:293
@ ITEM_CLASS_CONSUMABLE
Definition ItemTemplate.h:291
InventoryResult
Definition Item.h:46
@ EQUIP_ERR_OK
Definition Item.h:47
@ EQUIP_ERR_INVENTORY_FULL
Definition Item.h:97
#define MAX_ITEM_SPELLS
Definition Item.h:215
@ ENCHANTMENT_CAN_SOULBOUND
Definition Item.h:201
@ NULL_BAG
Definition Item.h:40
@ NULL_SLOT
Definition Item.h:41
@ PRISMATIC_ENCHANTMENT_SLOT
Definition Item.h:175
LootStore LootTemplates_Milling("milling_loot_template", "item entry (herb)", true)
LootStore LootTemplates_Prospecting("prospecting_loot_template", "item entry (ore)", true)
std::vector< ItemPosCount > ItemPosCountVec
Definition Player.h:757
@ EFFECT_1
Definition SharedDefines.h:32
@ MAX_POWERS
Definition SharedDefines.h:264
@ SPELL_EFFECT_DISENCHANT
Definition SharedDefines.h:865
@ SPELL_EFFECT_PROSPECTING
Definition SharedDefines.h:893
@ SPELL_EFFECT_ENCHANT_HELD_ITEM
Definition SharedDefines.h:858
@ SPELL_EFFECT_ENCHANT_ITEM
Definition SharedDefines.h:819
@ SPELL_EFFECT_WEAPON_DAMAGE
Definition SharedDefines.h:824
@ SPELL_EFFECT_HEAL
Definition SharedDefines.h:776
@ SPELL_EFFECT_MILLING
Definition SharedDefines.h:924
@ SPELL_EFFECT_CREATE_MANA_GEM
Definition SharedDefines.h:832
@ SPELL_EFFECT_CREATE_ITEM_2
Definition SharedDefines.h:923
@ SPELL_EFFECT_WEAPON_DAMAGE_NOSCHOOL
Definition SharedDefines.h:783
@ SPELL_EFFECT_ENERGIZE
Definition SharedDefines.h:796
@ SPELL_EFFECT_CREATE_RANDOM_ITEM
Definition SharedDefines.h:825
@ SPELL_EFFECT_ENCHANT_ITEM_PRISMATIC
Definition SharedDefines.h:922
@ SPELL_EFFECT_ENCHANT_ITEM_TEMPORARY
Definition SharedDefines.h:820
@ SPELL_EFFECT_CREATE_ITEM
Definition SharedDefines.h:790
@ SPELL_ATTR2_ALLOW_LOW_LEVEL_BUFF
Definition SharedDefines.h:447
@ SPELL_ATTR3_REQUIRES_MAIN_HAND_WEAPON
Definition SharedDefines.h:491
@ SPELLFAMILY_MAGE
Definition SharedDefines.h:3787
TotemCategory
Definition SharedDefines.h:3316
@ SPELL_FAILED_CANT_BE_MILLED
Definition SharedDefines.h:953
@ SPELL_FAILED_EQUIPPED_ITEM_CLASS_OFFHAND
Definition SharedDefines.h:968
@ SPELL_FAILED_EQUIPPED_ITEM_CLASS
Definition SharedDefines.h:966
@ SPELL_FAILED_ITEM_AT_MAX_CHARGES
Definition SharedDefines.h:1116
@ SPELL_FAILED_TARGET_NOT_PLAYER
Definition SharedDefines.h:1059
@ SPELL_FAILED_ALREADY_AT_FULL_POWER
Definition SharedDefines.h:941
@ SPELL_FAILED_NOT_TRADEABLE
Definition SharedDefines.h:1007
@ SPELL_FAILED_ITEM_NOT_READY
Definition SharedDefines.h:982
@ SPELL_FAILED_NO_CHARGES_REMAIN
Definition SharedDefines.h:1013
@ SPELL_FAILED_ITEM_GONE
Definition SharedDefines.h:980
@ SPELL_FAILED_NO_AMMO
Definition SharedDefines.h:1012
@ SPELL_FAILED_ITEM_NOT_FOUND
Definition SharedDefines.h:981
@ SPELL_FAILED_EQUIPPED_ITEM
Definition SharedDefines.h:965
@ SPELL_FAILED_ALREADY_AT_FULL_HEALTH
Definition SharedDefines.h:939
@ SPELL_FAILED_ON_USE_ENCHANT
Definition SharedDefines.h:1107
@ SPELL_FAILED_TOTEMS
Definition SharedDefines.h:1068
@ SPELL_FAILED_ERROR
Definition SharedDefines.h:969
@ SPELL_FAILED_REAGENTS
Definition SharedDefines.h:1037
@ SPELL_FAILED_MAX_SOCKETS
Definition SharedDefines.h:1121
@ SPELL_FAILED_CANT_BE_DISENCHANTED
Definition SharedDefines.h:951
@ SPELL_FAILED_TOO_MANY_OF_ITEM
Definition SharedDefines.h:1066
@ SPELL_FAILED_NEED_MORE_ITEMS
Definition SharedDefines.h:992
@ SPELL_FAILED_CANT_BE_PROSPECTED
Definition SharedDefines.h:954
@ SPELL_FAILED_EQUIPPED_ITEM_CLASS_MAINHAND
Definition SharedDefines.h:967
@ SPELL_FAILED_TOTEM_CATEGORY
Definition SharedDefines.h:1067
@ SKILL_INSCRIPTION
Definition SharedDefines.h:3235
@ SKILL_ENCHANTING
Definition SharedDefines.h:3187
@ SKILL_JEWELCRAFTING
Definition SharedDefines.h:3218
@ PLAYER_AMMO_ID
Definition UpdateFields.h:369
uint32 GetEnchantmentId(EnchantmentSlot slot) const
Definition Item.h:304
int32 GetSpellCharges(uint8 index=0) const
Definition Item.h:317
bool IsBroken() const
Definition Item.h:257
bool IsWeaponVellum() const
Definition Item.h:338
bool IsArmorVellum() const
Definition Item.h:339
Player * GetOwner() const
Definition Item.cpp:549
ObjectGuid GetOwnerGUID() const
Definition Item.h:231
uint32 GetCount() const
Definition Item.h:272
bool IsFitToSpellRequirements(SpellInfo const *spellInfo) const
Definition Item.cpp:884
bool HaveLootFor(uint32 loot_id) const
Definition LootMgr.h:224
uint32 GetUInt32Value(uint16 index) const
Definition Object.cpp:294
bool HasItemFitToSpellRequirements(SpellInfo const *spellInfo, Item const *ignoreItem=nullptr) const
Definition Player.cpp:12600
uint32 GetFreeInventorySpace() const
Definition PlayerStorage.cpp:469
Item * GetItemByEntry(uint32 entry) const
Definition PlayerStorage.cpp:3435
bool HasItemCount(uint32 item, uint32 count=1, bool inBankAlso=false) const
Definition PlayerStorage.cpp:658
bool HasItemTotemCategory(uint32 TotemCategory) const
Definition PlayerStorage.cpp:859
bool CanNoReagentCast(SpellInfo const *spellInfo) const
Definition Player.cpp:12675
void SendEquipError(InventoryResult msg, Item *pItem, Item *pItem2=nullptr, uint32 itemid=0)
Definition PlayerStorage.cpp:4093
InventoryResult CanStoreNewItem(uint8 bag, uint8 slot, ItemPosCountVec &dest, uint32 item, uint32 count, uint32 *no_space_count=nullptr) const
Definition Player.h:1300
uint32 GetItemTargetEntry() const
Definition Spell.h:152
uint32 MaxLevel
Definition SpellInfo.h:382
std::array< int32, MAX_SPELL_REAGENTS > Reagent
Definition SpellInfo.h:397
flag96 SpellFamilyFlags
Definition SpellInfo.h:412
std::array< uint32, 2 > TotemCategory
Definition SpellInfo.h:402
int32 EquippedItemClass
Definition SpellInfo.h:399
std::array< uint32, 2 > Totem
Definition SpellInfo.h:396
std::array< uint32, MAX_SPELL_REAGENTS > ReagentCount
Definition SpellInfo.h:398
ObjectGuid m_castItemGUID
Definition Spell.h:538
bool IsFullHealth() const
Definition Unit.h:1114
bool CanUseAttackType(WeaponAttackType attacktype) const
Definition Unit.h:992
uint32 GetMaxPower(Powers power) const
Definition Unit.h:1136
void SetUInt32Value(uint16 index, uint32 value)
Definition Unit.cpp:17388
uint32 GetPower(Powers power) const
Definition Unit.h:1135
Definition ItemTemplate.h:619
uint32 DisenchantID
Definition ItemTemplate.h:690
uint32 Quality
Definition ItemTemplate.h:626
uint32 RequiredSkillRank
Definition ItemTemplate.h:638
uint32 GetMaxStackSize() const
Definition ItemTemplate.h:727
_Spell Spells[MAX_ITEM_PROTO_SPELLS]
Definition ItemTemplate.h:662
uint32 RequiredDisenchantSkill
Definition ItemTemplate.h:684
uint32 RequiredLevel
Definition ItemTemplate.h:636
bool HasFlag(ItemFlags flag) const
Definition ItemTemplate.h:825
uint32 Class
Definition ItemTemplate.h:621
uint32 ItemLimitCategory
Definition ItemTemplate.h:687
uint32 SubClass
Definition ItemTemplate.h:622
_Socket Socket[MAX_ITEM_PROTO_SOCKETS]
Definition ItemTemplate.h:681
Definition DBCStructure.h:1841
uint32 type[MAX_SPELL_ITEM_ENCHANTMENT_EFFECTS]
Definition DBCStructure.h:1844
uint32 slot
Definition DBCStructure.h:1851
uint32 Color
Definition ItemTemplate.h:602
int32 SpellCharges
Definition ItemTemplate.h:593
uint32 SpellTrigger
Definition ItemTemplate.h:592
int32 SpellId
Definition ItemTemplate.h:591

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

Referenced by CheckCast().

◆ CheckPetCast()

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

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

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

◆ CheckPower()

SpellCastResult Spell::CheckPower ( )
7137{
7138 // item cast not used power
7139 if (m_CastItem)
7140 return SPELL_CAST_OK;
7141
7142 //While .cheat power is enabled dont check if we need power to cast the spell
7143 if (m_caster->IsPlayer())
7144 {
7146 {
7147 return SPELL_CAST_OK;
7148 }
7149 }
7150
7151 // health as power used - need check health amount
7153 {
7156 return SPELL_CAST_OK;
7157 }
7158 // Check valid power type
7160 {
7161 LOG_ERROR("spells", "Spell::CheckPower: Unknown power type '{}'", m_spellInfo->PowerType);
7162 return SPELL_FAILED_UNKNOWN;
7163 }
7164
7165 //check rune cost only if a spell has PowerType == POWER_RUNE
7167 {
7169 if (failReason != SPELL_CAST_OK)
7170 return failReason;
7171 }
7172
7173 // Check power amount
7176 return SPELL_FAILED_NO_POWER;
7177 else
7178 return SPELL_CAST_OK;
7179}
@ CHEAT_POWER
Definition Player.h:998
@ POWER_HEALTH
Definition SharedDefines.h:266
@ POWER_RUNE
Definition SharedDefines.h:262
@ SPELL_FAILED_NO_POWER
Definition SharedDefines.h:1022
@ SPELL_FAILED_UNKNOWN
Definition SharedDefines.h:1124
PowerType
Definition VehicleDefines.h:29
uint32 RuneCostID
Definition SpellInfo.h:392
uint32 PowerType
Definition SpellInfo.h:386
SpellCastResult CheckRuneCost(uint32 RuneCostID)
Definition Spell.cpp:5379
uint32 GetHealth() const
Definition Unit.h:1108

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

Referenced by CheckCast().

◆ CheckRange()

SpellCastResult Spell::CheckRange ( bool  strict)
7051{
7052 // Don't check for instant cast spells
7053 if (!strict && m_casttime == 0)
7054 return SPELL_CAST_OK;
7055
7056 uint32 range_type = 0;
7057
7059 {
7060 // check needed by 68766 51693 - both spells are cast on enemies and have 0 max range
7061 // these are triggered by other spells - possibly we should omit range check in that case?
7062 if (m_spellInfo->RangeEntry->ID == 1)
7063 return SPELL_CAST_OK;
7064
7065 range_type = m_spellInfo->RangeEntry->Flags;
7066 }
7067
7068 Unit* target = m_targets.GetUnitTarget();
7069 float max_range = m_caster->GetSpellMaxRangeForTarget(target, m_spellInfo);
7070 float min_range = m_caster->GetSpellMinRangeForTarget(target, m_spellInfo);
7071
7072 // xinef: hack for npc shooters
7073 if (min_range && GetCaster()->IsCreature() && !GetCaster()->GetOwnerGUID().IsPlayer() && min_range <= 6.0f)
7074 range_type = SPELL_RANGE_RANGED;
7075
7076 if (Player* modOwner = m_caster->GetSpellModOwner())
7077 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_RANGE, max_range, this);
7078
7079 // xinef: dont check max_range to strictly after cast
7080 if (range_type != SPELL_RANGE_MELEE && !strict)
7081 max_range += std::min(3.0f, max_range * 0.1f); // 10% but no more than 3yd
7082
7083 if (target)
7084 {
7085 if (target != m_caster)
7086 {
7087 // Xinef: Spells with 5yd range can hit target 9yd away?
7088 if (range_type == SPELL_RANGE_MELEE)
7089 {
7090 float real_max_range = max_range;
7092 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)
7093 else
7094 real_max_range -= 2 * MIN_MELEE_REACH;
7095
7096 if (!m_caster->IsWithinMeleeRange(target, std::max(real_max_range, 0.0f)))
7098 }
7099 else if (!m_caster->IsWithinCombatRange(target, max_range))
7100 return SPELL_FAILED_OUT_OF_RANGE; //0x5A;
7101
7102 if (m_caster->IsPlayer() && (m_spellInfo->FacingCasterFlags & SPELL_FACING_FLAG_INFRONT) && !m_caster->HasInArc(static_cast<float>(M_PI), target) && !m_caster->IsWithinBoundaryRadius(target))
7104 }
7105
7106 // Check min range - for ranged spells, min range is the spell's min range + melee range (no leeway)
7107 if (range_type == SPELL_RANGE_RANGED)
7108 {
7109 float minRangeCombined = min_range + m_caster->GetMeleeRange(target);
7110 if (m_caster->IsWithinRange(target, minRangeCombined))
7112 }
7113 else if (min_range > 0 && m_caster->IsWithinCombatRange(target, min_range))
7115 }
7116
7117 if (GameObject* goTarget = m_targets.GetGOTarget())
7118 {
7119 if (!goTarget->IsAtInteractDistance(m_caster->ToPlayer(), m_spellInfo))
7120 {
7122 }
7123 }
7124
7125 if (m_targets.HasDst() && !m_targets.HasTraj())
7126 {
7127 if (!m_caster->IsWithinDist3d(m_targets.GetDstPos(), max_range))
7129 if (min_range && m_caster->IsWithinDist3d(m_targets.GetDstPos(), min_range))
7131 }
7132
7133 return SPELL_CAST_OK;
7134}
#define MIN_MELEE_REACH
Definition ObjectDefines.h:46
@ SPELL_FAILED_TOO_CLOSE
Definition SharedDefines.h:1065
@ SPELL_FAILED_OUT_OF_RANGE
Definition SharedDefines.h:1034
@ SPELLMOD_RANGE
Definition SpellDefines.h:81
@ SPELL_FACING_FLAG_INFRONT
Definition SpellDefines.h:128
@ SPELL_RANGE_MELEE
Definition Spell.h:101
@ SPELL_RANGE_RANGED
Definition Spell.h:102
SpellRangeEntry const * RangeEntry
Definition SpellInfo.h:393
uint32 FacingCasterFlags
Definition SpellInfo.h:362
bool IsWithinBoundaryRadius(const Unit *obj) const
Definition Unit.cpp:822
bool IsWithinCombatRange(Unit const *obj, float dist2compare) const
Definition Unit.cpp:767
float GetSpellMinRangeForTarget(Unit const *target, SpellInfo const *spellInfo) const
Definition Unit.cpp:11933
bool IsWithinMeleeRange(Unit const *obj, float dist=0.f) const
Definition Unit.cpp:783
float GetSpellMaxRangeForTarget(Unit const *target, SpellInfo const *spellInfo) const
Definition Unit.cpp:11913
bool IsWithinRange(Unit const *obj, float dist) const
Definition Unit.cpp:807
float GetMeleeRange(Unit const *target) const
Definition Unit.cpp:801
bool HasLeewayMovement() const
Definition Unit.h:1732
bool IsWithinDist3d(float x, float y, float z, float dist) const
Definition Object.cpp:1345
bool HasInArc(float arcangle, const Position *pos, float targetRadius=0.0f) const
Definition Position.cpp:148
uint32 Flags
Definition DBCStructure.h:1797
uint32 ID
Definition DBCStructure.h:1794

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

Referenced by CheckCast().

◆ CheckRuneCost()

SpellCastResult Spell::CheckRuneCost ( uint32  RuneCostID)
5380{
5381 if (m_spellInfo->PowerType != POWER_RUNE || !RuneCostID)
5382 return SPELL_CAST_OK;
5383
5384 if (!m_caster->IsPlayer())
5385 return SPELL_CAST_OK;
5386
5387 Player* player = m_caster->ToPlayer();
5388 //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)
5389 if (player->GetCommandStatus(CHEAT_POWER))
5390 {
5391 return SPELL_CAST_OK;
5392 }
5393
5395 return SPELL_CAST_OK;
5396
5397 SpellRuneCostEntry const* src = sSpellRuneCostStore.LookupEntry(RuneCostID);
5398
5399 if (!src)
5400 return SPELL_CAST_OK;
5401
5402 if (src->NoRuneCost())
5403 return SPELL_CAST_OK;
5404
5405 int32 runeCost[NUM_RUNE_TYPES]; // blood, frost, unholy, death
5406
5407 for (uint32 i = 0; i < RUNE_DEATH; ++i)
5408 {
5409 runeCost[i] = src->RuneCost[i];
5410 if (Player* modOwner = m_caster->GetSpellModOwner())
5411 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_COST, runeCost[i], this);
5412 }
5413
5414 runeCost[RUNE_DEATH] = MAX_RUNES; // calculated later
5415
5416 for (uint32 i = 0; i < MAX_RUNES; ++i)
5417 {
5418 RuneType rune = player->GetCurrentRune(i);
5419 if ((player->GetRuneCooldown(i) == 0) && (runeCost[rune] > 0))
5420 runeCost[rune]--;
5421 }
5422
5423 for (uint32 i = 0; i < RUNE_DEATH; ++i)
5424 if (runeCost[i] > 0)
5425 runeCost[RUNE_DEATH] += runeCost[i];
5426
5427 if (runeCost[RUNE_DEATH] > MAX_RUNES)
5428 return SPELL_FAILED_NO_POWER; // not sure if result code is correct
5429
5430 return SPELL_CAST_OK;
5431}
DBCStorage< SpellRuneCostEntry > sSpellRuneCostStore(SpellRuneCostfmt)
RuneType
Definition Player.h:395
@ RUNE_DEATH
Definition Player.h:399
@ NUM_RUNE_TYPES
Definition Player.h:400
#define MAX_RUNES
Definition Player.h:385
@ CLASS_DEATH_KNIGHT
Definition SharedDefines.h:131
@ SPELLMOD_COST
Definition SpellDefines.h:90
@ CLASS_CONTEXT_ABILITY
Definition UnitDefines.h:241
uint32 GetRuneCooldown(uint8 index) const
Definition Player.h:2549
bool IsClass(Classes playerClass, ClassContext context=CLASS_CONTEXT_NONE) const override
Definition Player.cpp:1302
RuneType GetCurrentRune(uint8 index) const
Definition Player.h:2548
Definition DBCStructure.h:1805
uint32 RuneCost[3]
Definition DBCStructure.h:1807
bool NoRuneCost() const
Definition DBCStructure.h:1810

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

Referenced by CheckPower().

◆ CheckScriptEffectImplicitTargets()

bool Spell::CheckScriptEffectImplicitTargets ( uint32  effIndex,
uint32  effIndexToCheck 
)
protected
8770{
8771 // Skip if there are not any script
8772 if (!m_loadedScripts.size())
8773 return true;
8774
8775 for (std::list<SpellScript*>::iterator itr = m_loadedScripts.begin(); itr != m_loadedScripts.end(); ++itr)
8776 {
8777 std::list<SpellScript::ObjectTargetSelectHandler>::iterator targetSelectHookEnd = (*itr)->OnObjectTargetSelect.end(), targetSelectHookItr = (*itr)->OnObjectTargetSelect.begin();
8778 for (; targetSelectHookItr != targetSelectHookEnd; ++targetSelectHookItr)
8779 if (((*targetSelectHookItr).IsEffectAffected(m_spellInfo, effIndex) && !(*targetSelectHookItr).IsEffectAffected(m_spellInfo, effIndexToCheck)) ||
8780 (!(*targetSelectHookItr).IsEffectAffected(m_spellInfo, effIndex) && (*targetSelectHookItr).IsEffectAffected(m_spellInfo, effIndexToCheck)))
8781 return false;
8782
8783 std::list<SpellScript::ObjectAreaTargetSelectHandler>::iterator areaTargetSelectHookEnd = (*itr)->OnObjectAreaTargetSelect.end(), areaTargetSelectHookItr = (*itr)->OnObjectAreaTargetSelect.begin();
8784 for (; areaTargetSelectHookItr != areaTargetSelectHookEnd; ++areaTargetSelectHookItr)
8785 if (((*areaTargetSelectHookItr).IsEffectAffected(m_spellInfo, effIndex) && !(*areaTargetSelectHookItr).IsEffectAffected(m_spellInfo, effIndexToCheck)) ||
8786 (!(*areaTargetSelectHookItr).IsEffectAffected(m_spellInfo, effIndex) && (*areaTargetSelectHookItr).IsEffectAffected(m_spellInfo, effIndexToCheck)))
8787 return false;
8788 }
8789 return true;
8790}

References m_loadedScripts, and m_spellInfo.

Referenced by SelectEffectImplicitTargets().

◆ CheckSpellFocus()

SpellCastResult Spell::CheckSpellFocus ( )
7781{
7782 // check spell focus object
7784 {
7786 Cell cell(p);
7787
7788 GameObject* ok = nullptr;
7791
7793 Map& map = *m_caster->GetMap();
7794 cell.Visit(p, object_checker, map, *m_caster, m_caster->GetVisibilityRange());
7795
7796 if (!ok)
7798
7799 focusObject = ok; // game object found in range
7800 }
7801 return SPELL_CAST_OK;
7802}
@ SPELL_FAILED_REQUIRES_SPELL_FOCUS
Definition SharedDefines.h:1039
Definition GridNotifiers.h:678
Definition Map.h:166
void Visit(const Cell &cell, TypeContainerVisitor< T, CONTAINER > &visitor)
Definition Map.h:762
uint32 RequiresSpellFocus
Definition SpellInfo.h:361
Definition TypeContainerVisitor.h:105
Definition TypeContainer.h:118
CellCoord ComputeCellCoord(float x, float y)
Definition GridDefines.h:197
Definition GridNotifiers.h:340
Definition Cell.h:45

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

Referenced by CheckCast().

◆ CheckSrc()

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

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

◆ CleanupTargetList()

void Spell::CleanupTargetList ( )
2305{
2306 m_UniqueTargetInfo.clear();
2307 m_UniqueGOTargetInfo.clear();
2308 m_UniqueItemInfo.clear();
2309 m_delayMoment = 0;
2311}
uint64 m_delayTrajectory
Definition Spell.h:661

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 ( )
7805{
7806 if (!m_caster)// || !m_caster->IsPlayer())
7807 return;
7808
7809 //if (m_spellState == SPELL_STATE_DELAYED)
7810 // return; // spell is active and can't be time-backed
7811
7812 if (isDelayableNoMore()) // Spells may only be delayed twice
7813 return;
7814
7816 return;
7817
7818 // spells not loosing casting time (slam, dynamites, bombs..)
7819 //if (!(m_spellInfo->InterruptFlags & SPELL_INTERRUPT_FLAG_DAMAGE))
7820 // return;
7821
7822 //check pushback reduce
7823 int32 delaytime = 500; // spellcasting delay is normally 500ms
7824 int32 delayReduce = 100; // must be initialized to 100 for percent modifiers
7827 if (delayReduce >= 100)
7828 return;
7829
7830 AddPct(delaytime, -delayReduce);
7831
7832 if (m_timer + delaytime > m_casttime)
7833 {
7834 delaytime = m_casttime - m_timer;
7836 }
7837 else
7838 m_timer += delaytime;
7839
7840 LOG_DEBUG("spells", "Spell {} partially interrupted for ({}) ms at damage", m_spellInfo->Id, delaytime);
7841
7842 WorldPacket data(SMSG_SPELL_DELAYED, 8 + 4);
7843 data << m_caster->GetPackGUID();
7844 data << uint32(delaytime);
7845
7846 m_caster->SendMessageToSet(&data, true);
7847}
#define LOG_DEBUG(filterType__,...)
Definition Log.h:157
@ SPELL_ATTR6_NO_PUSHBACK
Definition SharedDefines.h:607
@ SPELL_AURA_REDUCE_PUSHBACK
Definition SpellAuraDefines.h:212
@ SPELLMOD_NOT_LOSE_CASTING_TIME
Definition SpellDefines.h:85
T AddPct(T &base, U pct)
Definition Util.h:58
PackedGuid const & GetPackGUID() const
Definition Object.h:116
void ApplySpellMod(uint32 spellId, SpellModOp op, T &basevalue, Spell *spell=nullptr, bool temporaryPet=false)
Definition Player.cpp:9834
bool isDelayableNoMore()
Definition Spell.h:649
int32 GetTotalAuraModifier(AuraType auratype) const
Definition Unit.cpp:6303
virtual void SendMessageToSet(WorldPacket const *data, bool self) const
Definition Object.cpp:2112
Definition WorldPacket.h:26
@ SMSG_SPELL_DELAYED
Definition Opcodes.h:512

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

◆ DelayedChannel()

void Spell::DelayedChannel ( )
7850{
7852 return;
7853
7854 if (isDelayableNoMore()) // Spells may only be delayed twice
7855 return;
7856
7858 return;
7859
7860 //check pushback reduce
7861 // should be affected by modifiers, not take the dbc duration.
7862 int32 duration = ((m_channeledDuration > 0) ? m_channeledDuration : m_spellInfo->GetDuration());
7863
7864 int32 delaytime = CalculatePct(duration, 25); // channeling delay is normally 25% of its time per hit
7865 int32 delayReduce = 100; // must be initialized to 100 for percent modifiers
7868 if (delayReduce >= 100)
7869 return;
7870
7871 AddPct(delaytime, -delayReduce);
7872
7873 if (m_timer <= delaytime)
7874 {
7875 delaytime = m_timer;
7876 m_timer = 0;
7877 }
7878 else
7879 m_timer -= delaytime;
7880
7881 LOG_DEBUG("spells.aura", "Spell {} partially interrupted for {} ms, new duration: {} ms", m_spellInfo->Id, delaytime, m_timer);
7882
7883 for (std::list<TargetInfo>::const_iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
7884 if ((*ihit).missCondition == SPELL_MISS_NONE)
7885 if (Unit* unit = (m_caster->GetGUID() == ihit->targetGUID) ? m_caster : ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID))
7886 unit->DelayOwnedAuras(m_spellInfo->Id, m_originalCasterGUID, delaytime);
7887
7888 // partially interrupt persistent area auras
7890 dynObj->Delay(delaytime);
7891
7893}
T CalculatePct(T base, U pct)
Definition Util.h:52
Definition DynamicObject.h:35
uint32 getState() const
Definition Spell.h:496
DynamicObject * GetDynObject(uint32 spellId)
Definition Unit.cpp:6532

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

◆ DoAllEffectOnLaunchTarget()

void Spell::DoAllEffectOnLaunchTarget ( TargetInfo targetInfo,
float *  multiplier 
)
protected
8345{
8346 Unit* unit = nullptr;
8347 // In case spell hit target, do all effect on that target
8348 if (targetInfo.missCondition == SPELL_MISS_NONE)
8349 unit = m_caster->GetGUID() == targetInfo.targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, targetInfo.targetGUID);
8350 // In case spell reflect from target, do all effect on caster (if hit)
8351 else if (targetInfo.missCondition == SPELL_MISS_REFLECT && targetInfo.reflectResult == SPELL_MISS_NONE)
8352 unit = m_caster;
8353 if (!unit)
8354 return;
8355
8356 for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i)
8357 {
8358 if (targetInfo.effectMask & (1 << i))
8359 {
8360 m_damage = 0;
8361 m_healing = 0;
8363
8364 HandleEffects(unit, nullptr, nullptr, i, SPELL_EFFECT_HANDLE_LAUNCH_TARGET);
8365
8366 if (m_damage > 0)
8367 {
8368 // Xinef: Area Auras, AoE Targetting spells AND Chain Target spells (cleave etc.)
8369 if (m_spellInfo->Effects[i].IsAreaAuraEffect() || m_spellInfo->Effects[i].IsTargetingArea() || (m_spellInfo->Effects[i].ChainTarget > 1 && m_spellInfo->DmgClass != SPELL_DAMAGE_CLASS_MAGIC))
8370 {
8373 if (m_caster->IsPlayer())
8374 {
8375 uint32 targetAmount = m_UniqueTargetInfo.size();
8376 if (targetAmount > 10)
8377 m_damage = m_damage * 10 / targetAmount;
8378 }
8379 }
8380 }
8381
8382 if (m_applyMultiplierMask & (1 << i))
8383 {
8385 m_damageMultipliers[i] *= multiplier[i];
8386 }
8387 targetInfo.damage += m_damage;
8389 }
8390 }
8391
8392 // xinef: totem's inherit owner crit chance and dancing rune weapon
8393 Unit* caster = m_caster;
8394 if (m_caster->IsTotem() || m_caster->GetEntry() == 27893)
8395 {
8396 if (Unit* owner = m_caster->GetOwner())
8397 caster = owner;
8398 }
8399 else if (m_originalCaster)
8400 caster = m_originalCaster;
8401
8402 float critChance = caster->SpellDoneCritChance(unit, m_spellInfo, m_spellSchoolMask, m_attackType, false);
8403 critChance = unit->SpellTakenCritChance(caster, m_spellInfo, m_spellSchoolMask, critChance, m_attackType, false);
8404 targetInfo.crit = roll_chance_f(std::max(0.0f, critChance));
8405}
bool roll_chance_f(float chance)
Definition Random.h:57
@ SPELL_ATTR7_TREAT_AS_NPC_AOE
Definition SharedDefines.h:655
uint32 SchoolMask
Definition SpellInfo.h:416
float SpellTakenCritChance(Unit const *caster, SpellInfo const *spellProto, SpellSchoolMask schoolMask, float doneChance, WeaponAttackType attackType, bool skipEffectCheck) const
Definition Unit.cpp:9184
float SpellDoneCritChance(Unit const *, SpellInfo const *spellProto, SpellSchoolMask schoolMask, WeaponAttackType attackType, bool skipEffectCheck) const
Definition Unit.cpp:9094
int32 CalculateAOEDamageReduction(int32 damage, uint32 schoolMask, bool npcCaster) const
Definition Unit.cpp:16349

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

Referenced by HandleLaunchPhase().

◆ DoAllEffectOnTarget() [1/3]

void Spell::DoAllEffectOnTarget ( GOTargetInfo target)
protected
3290{
3291 if (target->processed) // Check target
3292 return;
3293 target->processed = true; // Target checked in apply effects procedure
3294
3295 uint32 effectMask = target->effectMask;
3296 if (!effectMask)
3297 return;
3298
3299 GameObject* go = m_caster->GetMap()->GetGameObject(target->targetGUID);
3300 if (!go)
3301 return;
3302
3305
3306 for (uint32 effectNumber = 0; effectNumber < MAX_SPELL_EFFECTS; ++effectNumber)
3307 if (effectMask & (1 << effectNumber))
3308 HandleEffects(nullptr, nullptr, go, effectNumber, SPELL_EFFECT_HANDLE_HIT_TARGET);
3309
3310 // xinef: inform ai about spellhit
3312
3314
3316}
virtual void SpellHit(Unit *, SpellInfo const *)
Definition GameObjectAI.h:66
GameObjectAI * AI() const
Definition GameObject.h:307
void CallScriptBeforeHitHandlers(SpellMissInfo missInfo)
Definition Spell.cpp:8688
void CallScriptOnHitHandlers()
Definition Spell.cpp:8701
void CallScriptAfterHitHandlers()
Definition Spell.cpp:8714

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
3319{
3320 uint32 effectMask = target->effectMask;
3321 if (!target->item || !effectMask)
3322 return;
3323
3326
3327 for (uint32 effectNumber = 0; effectNumber < MAX_SPELL_EFFECTS; ++effectNumber)
3328 if (effectMask & (1 << effectNumber))
3329 HandleEffects(nullptr, target->item, nullptr, effectNumber, SPELL_EFFECT_HANDLE_HIT_TARGET);
3330
3332
3334}

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
2544{
2545 if (!target || target->processed)
2546 return;
2547
2548 target->processed = true; // Target checked in apply effects procedure
2549
2550 // Get mask of effects for target
2551 uint8 mask = target->effectMask;
2552
2553 Unit* effectUnit = m_caster->GetGUID() == target->targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, target->targetGUID);
2554 if (!effectUnit && !target->targetGUID.IsPlayer()) // only players may be targeted across maps
2555 return;
2556
2557 if (!effectUnit || m_spellInfo->Id == 45927)
2558 {
2559 uint8 farMask = 0;
2560 // create far target mask
2561 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
2562 if (m_spellInfo->Effects[i].IsFarUnitTargetEffect())
2563 if ((1 << i) & mask)
2564 farMask |= (1 << i);
2565
2566 if (!farMask)
2567 return;
2568 // find unit in world
2569 // Xinef: FindUnit Access without Map check!!! Intended
2570 effectUnit = ObjectAccessor::FindPlayer(target->targetGUID);
2571 if (!effectUnit)
2572 return;
2573
2574 // do far effects on the unit
2575 // can't use default call because of threading, do stuff as fast as possible
2576 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
2577 if (farMask & (1 << i))
2578 HandleEffects(effectUnit, nullptr, nullptr, i, SPELL_EFFECT_HANDLE_HIT_TARGET);
2579 return;
2580 }
2581
2582 if (effectUnit->IsAlive() != target->alive)
2583 return;
2584
2585 // Absorb delayed projectiles launched before Sanctuary (e.g. Vanish dodging a Frostbolt in flight)
2587 (GameTime::GetGameTimeMS().count() - target->timeDelay) <= effectUnit->m_lastSanctuaryTime)
2588 return; // No missinfo in that case
2589
2590 // Absorb instant hostile spells on application within brief window after Sanctuary
2592 effectUnit->m_lastSanctuaryTime &&
2593 GameTime::GetGameTimeMS().count() <= (effectUnit->m_lastSanctuaryTime + 400))
2594 return; // No missinfo in that case
2595
2596 // Get original caster (if exist) and calculate damage/healing from him data
2598
2599 // Skip if m_originalCaster not avaiable
2600 if (!caster)
2601 return;
2602
2603 SpellMissInfo missInfo = target->missCondition;
2604
2605 // Need init unitTarget by default unit (can changed in code on reflect)
2606 // Or on missInfo != SPELL_MISS_NONE unitTarget undefined (but need in trigger subsystem)
2607 unitTarget = effectUnit;
2608
2609 // Reset damage/healing counter
2610 m_damage = target->damage;
2611 m_healing = -target->damage;
2612
2613 m_spellAura = nullptr; // Set aura to null for every target-make sure that pointer is not used for unit without aura applied
2614
2616 effectUnit->SetInCombatWith(m_originalCaster);
2617
2620
2621 //Spells with this flag cannot trigger if effect is casted on self
2623 bool reflectedSpell = missInfo == SPELL_MISS_REFLECT;
2624 Unit* reflectionSource = nullptr;
2625 Unit* spellHitTarget = nullptr;
2626
2627 if (missInfo == SPELL_MISS_NONE) // In case spell hit target, do all effect on that target
2628 spellHitTarget = unitTarget;
2629 else if (missInfo == SPELL_MISS_REFLECT) // In case spell reflect from target, do all effect on caster (if hit)
2630 {
2631 missInfo = target->reflectResult;
2632 if (missInfo == SPELL_MISS_NONE) // If reflected spell hit caster -> do all effect on him
2633 {
2634 spellHitTarget = m_caster;
2636 reflectionSource = effectUnit;
2637 if (m_caster->IsCreature())
2639 }
2640 }
2641
2642 if (spellHitTarget)
2643 {
2644 if (reflectionSource)
2645 {
2646 m_reflectionTarget = reflectionSource;
2647 m_reflectionTargetGuid = reflectionSource->GetGUID();
2648 m_reflectionTargetPosition.Relocate(reflectionSource);
2649 }
2650 else
2651 {
2652 m_reflectionTarget = nullptr;
2655 }
2656
2657 SpellMissInfo missInfo2 = DoSpellHitOnUnit(spellHitTarget, mask, target->scaleAura);
2658
2659 m_reflectionTarget = nullptr;
2662 if (missInfo2 != SPELL_MISS_NONE)
2663 {
2664 if (missInfo2 != SPELL_MISS_MISS)
2665 m_caster->SendSpellMiss(spellHitTarget, m_spellInfo->Id, missInfo2);
2666 m_damage = 0;
2667 spellHitTarget = nullptr;
2668
2669 // Xinef: if missInfo2 is MISS_EVADE, override base missinfo data
2670 if (missInfo2 == SPELL_MISS_EVADE)
2671 missInfo = SPELL_MISS_EVADE;
2672 }
2673 }
2674
2675 // Do not take combo points on dodge and miss
2676 if (missInfo != SPELL_MISS_NONE && m_needComboPoints && m_targets.GetUnitTargetGUID() == target->targetGUID)
2677 {
2678 m_needComboPoints = false;
2679 // Restore spell mods for a miss/dodge/parry Cold Blood
2681 if (m_caster->IsPlayer() && (missInfo == SPELL_MISS_MISS || missInfo == SPELL_MISS_DODGE || missInfo == SPELL_MISS_PARRY))
2682 m_caster->ToPlayer()->RestoreSpellMods(this, 14177);
2683 }
2684
2685 // Fill base trigger info
2686 uint32 procAttacker = m_procAttacker;
2687 uint32 procVictim = m_procVictim;
2688
2689 // Trigger info was not filled in spell::preparedatafortriggersystem - we do it now
2690 if (canEffectTrigger && !procAttacker && !procVictim)
2691 {
2692 bool positive = true;
2693 if (m_damage > 0)
2694 positive = false;
2695 else if (!m_healing)
2696 {
2697 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
2698 // If at least one effect negative spell is negative hit
2699 // Xinef: if missInfo is immune state check all effects to properly determine positiveness of spell
2700 if ((missInfo == SPELL_MISS_IMMUNE2 || (mask & (1 << i))) && !m_spellInfo->IsPositiveEffect(i))
2701 {
2702 positive = false;
2703 break;
2704 }
2705 }
2706 switch (m_spellInfo->DmgClass)
2707 {
2709 if (positive)
2710 {
2713 }
2714 else
2715 {
2718 }
2719 break;
2721 if (positive)
2722 {
2725 }
2726 else
2727 {
2730 }
2731 break;
2732 }
2733 }
2735
2736 // All calculated do it!
2737 // Do healing and triggers
2738 if (m_healing > 0)
2739 {
2740 bool crit = target->crit;
2741 uint32 addhealth = m_healing;
2742
2743 if (crit)
2744 addhealth = Unit::SpellCriticalHealingBonus(caster, m_spellInfo, addhealth, nullptr);
2745
2746 HealInfo healInfo(caster, unitTarget, addhealth, m_spellInfo, m_spellInfo->GetSchoolMask());
2747
2748 // Heal amount before SpellHealingBonusTaken, used by Beacon of Light
2749 if (target->damageBeforeTakenMods != 0)
2750 {
2751 uint32 healBeforeTakenMods = uint32(-target->damageBeforeTakenMods);
2752 if (crit)
2753 healBeforeTakenMods = Unit::SpellCriticalHealingBonus(caster, m_spellInfo, healBeforeTakenMods, nullptr);
2754 healInfo.SetHealBeforeTakenMods(healBeforeTakenMods);
2755 }
2756 else
2757 healInfo.SetHealBeforeTakenMods(addhealth);
2758
2759 // Set hitMask based on crit
2760 if (crit)
2761 healInfo.AddHitMask(PROC_HIT_CRITICAL);
2762 else
2763 healInfo.AddHitMask(PROC_HIT_NORMAL);
2764
2765 // Xinef: override with forced crit, only visual result
2766 if (GetSpellValue()->ForcedCritResult)
2767 {
2768 crit = true;
2769 healInfo.AddHitMask(PROC_HIT_CRITICAL);
2770 }
2771
2772 int32 gain = caster->HealBySpell(healInfo, crit);
2773 float threat = float(gain) * 0.5f;
2774 if (caster->IsClass(CLASS_PALADIN))
2775 threat *= 0.5f;
2777 m_healing = gain;
2778
2779 // Xinef: if heal actually healed something, add no overheal flag
2780 if (m_healing)
2781 healInfo.AddHitMask(PROC_EX_NO_OVERHEAL);
2782
2783 // Do triggers for unit (reflect triggers passed on hit phase for correct drop charge)
2784 if (canEffectTrigger)
2785 {
2786 uint32 hitMask = m_procEx | healInfo.GetHitMask();
2787 Unit::ProcSkillsAndAuras(caster, unitTarget, procAttacker, procVictim, hitMask, addhealth, m_attackType, m_spellInfo, m_triggeredByAuraSpell.spellInfo,
2788 m_triggeredByAuraSpell.effectIndex, this, nullptr, &healInfo);
2789 }
2790 }
2791 // Do damage and triggers
2792 else if (m_damage > 0)
2793 {
2795
2796 // Fill base damage struct (unitTarget - is real spell target)
2798
2799 // Check damage immunity
2801 {
2802 m_damage = 0;
2803
2804 // no packet found in sniffs
2805 }
2806 else
2807 {
2808 // Add bonuses and fill damageInfo struct
2809 // Dancing Rune Weapon...
2810 if (m_caster->GetEntry() == 27893)
2811 {
2812 if (Unit* owner = m_caster->GetOwner())
2813 owner->CalculateSpellDamageTaken(&damageInfo, m_damage, m_spellInfo, m_attackType, target->crit);
2814 }
2815 else
2816 caster->CalculateSpellDamageTaken(&damageInfo, m_damage, m_spellInfo, m_attackType, target->crit);
2817
2818 // xinef: override miss info after absorb / block calculations
2819 if (missInfo == SPELL_MISS_NONE && damageInfo.damage == 0)
2820 {
2821 //if (damageInfo.absorb > 0)
2822 // missInfo = SPELL_MISS_ABSORB;
2823 if (damageInfo.blocked)
2824 missInfo = SPELL_MISS_BLOCK;
2825 }
2826
2827 // Xinef: override with forced crit, only visual result
2828 if (GetSpellValue()->ForcedCritResult)
2829 {
2830 damageInfo.HitInfo |= SPELL_HIT_TYPE_CRIT;
2831 }
2832
2833 Unit::DealDamageMods(damageInfo.target, damageInfo.damage, &damageInfo.absorb);
2834
2835 // xinef: health leech handling
2837 {
2838 uint8 effIndex = EFFECT_0;
2839 for (; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
2840 if (m_spellInfo->Effects[effIndex].Effect == SPELL_EFFECT_HEALTH_LEECH)
2841 break;
2842
2843 float healMultiplier = m_spellInfo->Effects[effIndex].CalcValueMultiplier(m_originalCaster, this);
2844
2845 // get max possible damage, don't count overkill for heal
2846 uint32 healthGain = uint32(-unitTarget->GetHealthGain(-int32(damageInfo.damage)) * healMultiplier);
2847
2848 if (m_caster->IsAlive())
2849 {
2850 healthGain = m_caster->SpellHealingBonusDone(m_caster, m_spellInfo, healthGain, HEAL, effIndex);
2851 healthGain = m_caster->SpellHealingBonusTaken(m_caster, m_spellInfo, healthGain, HEAL);
2852
2853 HealInfo healInfo(m_caster, m_caster, healthGain, m_spellInfo, m_spellInfo->GetSchoolMask());
2854 m_caster->HealBySpell(healInfo);
2855 }
2856 }
2857
2858 // Send log damage message to client
2859 caster->SendSpellNonMeleeDamageLog(&damageInfo);
2860 // Xinef: send info to target about reflect
2861 if (reflectedSpell)
2862 effectUnit->SendSpellNonMeleeReflectLog(&damageInfo, effectUnit);
2863
2864 procVictim |= PROC_FLAG_TAKEN_DAMAGE;
2865
2866 caster->DealSpellDamage(&damageInfo, true, this);
2867
2868 // do procs after damage, eg healing effects
2869 // no need to check if target is alive, done in procdamageandspell
2870
2871 // Do triggers for unit (reflect triggers passed on hit phase for correct drop charge)
2872 if (canEffectTrigger)
2873 {
2874 DamageInfo dmgInfo(damageInfo, SPELL_DIRECT_DAMAGE, m_attackType, missInfo);
2875 uint32 hitMask = m_procEx | dmgInfo.GetHitMask();
2876 Unit::ProcSkillsAndAuras(caster, unitTarget, procAttacker, procVictim, hitMask, damageInfo.damage, m_attackType, m_spellInfo, m_triggeredByAuraSpell.spellInfo,
2877 m_triggeredByAuraSpell.effectIndex, this, &dmgInfo);
2878
2881 caster->ToPlayer()->CastItemCombatSpell(unitTarget, m_attackType, procVictim, dmgInfo.GetHitMask());
2882 }
2883
2884 m_damage = damageInfo.damage;
2885 }
2886 }
2887 // Passive spell hits/misses or active spells only misses (only triggers)
2888 else
2889 {
2890 // Fill base damage struct (unitTarget - is real spell target)
2892 // Do triggers for unit (reflect triggers passed on hit phase for correct drop charge)
2893 if (canEffectTrigger)
2894 {
2895 DamageInfo dmgInfo(damageInfo, NODAMAGE, m_attackType, missInfo);
2896 uint32 hitMask = m_procEx | dmgInfo.GetHitMask();
2897 Unit::ProcSkillsAndAuras(caster, unitTarget, procAttacker, procVictim, hitMask, 0, m_attackType, m_spellInfo, m_triggeredByAuraSpell.spellInfo,
2898 m_triggeredByAuraSpell.effectIndex, this, &dmgInfo);
2899
2900 // Xinef: eg. rogue poisons can proc off cheap shot, etc. so this block should be here also
2901 // Xinef: ofc count only spells that HIT the target, little hack used to fool the system
2902 if ((dmgInfo.GetHitMask() & (PROC_HIT_NORMAL | PROC_HIT_CRITICAL)) && caster->IsPlayer() && m_spellInfo->HasAttribute(SPELL_ATTR0_CANCELS_AUTO_ATTACK_COMBAT) == 0 &&
2904 caster->ToPlayer()->CastItemCombatSpell(unitTarget, m_attackType, procVictim | PROC_FLAG_TAKEN_DAMAGE, dmgInfo.GetHitMask());
2905 }
2906
2907 // Failed Pickpocket, reveal rogue
2909 {
2912 }
2913 }
2914
2915 if (m_caster)
2916 {
2918 {
2921
2922 // Spells that don't initiate combat shouldn't affect stand state (e.g. Premeditation, Storm Giant/Felreaver Passive)
2923 if (m_spellInfo->HasInitialAggro() && !effectUnit->IsStandState())
2925 }
2926 }
2927
2928 if (missInfo != SPELL_MISS_EVADE && effectUnit != m_caster && m_caster->IsFriendlyTo(effectUnit) && m_spellInfo->IsPositive() &&
2930 {
2931 m_caster->SetInCombatWith(effectUnit);
2932 }
2933
2934 // Check for SPELL_ATTR7_CAN_CAUSE_INTERRUPT
2936 caster->CastSpell(effectUnit, SPELL_INTERRUPT_NONPLAYER, true);
2937
2938 if (spellHitTarget)
2939 {
2940 //AI functions
2941 if (spellHitTarget->IsCreature())
2942 {
2943 if (spellHitTarget->ToCreature()->IsAIEnabled)
2944 spellHitTarget->ToCreature()->AI()->SpellHit(m_caster, m_spellInfo);
2945 }
2946
2948 m_caster->ToCreature()->AI()->SpellHitTarget(spellHitTarget, m_spellInfo);
2949
2950 // Needs to be called after dealing damage/healing to not remove breaking on damage auras
2951 DoTriggersOnSpellHit(spellHitTarget, mask);
2952
2953 // if target is fallged for pvp also flag caster if a player
2954 // xinef: do not flag spells with aura bind sight (no special attribute)
2955 if (effectUnit->IsPvP() && effectUnit != m_caster && effectUnit->GetOwnerGUID() != m_caster->GetGUID() &&
2957 {
2958 m_caster->ToPlayer()->UpdatePvP(true);
2959 }
2960
2962 }
2963}
@ SPELL_EFFECT_HEALTH_LEECH
Definition SharedDefines.h:775
@ SPELL_ATTR1_NO_THREAT
Definition SharedDefines.h:417
@ SPELL_ATTR3_SUPPRESS_CASTER_PROCS
Definition SharedDefines.h:497
@ CLASS_PALADIN
Definition SharedDefines.h:127
@ SPELL_ATTR0_CANCELS_AUTO_ATTACK_COMBAT
Definition SharedDefines.h:390
@ SPELL_HIT_TYPE_CRIT
Definition SharedDefines.h:1540
SpellMissInfo
Definition SharedDefines.h:1522
@ SPELL_MISS_DODGE
Definition SharedDefines.h:1526
@ SPELL_MISS_IMMUNE2
Definition SharedDefines.h:1531
@ SPELL_MISS_RESIST
Definition SharedDefines.h:1525
@ SPELL_MISS_MISS
Definition SharedDefines.h:1524
@ SPELL_MISS_BLOCK
Definition SharedDefines.h:1528
@ SPELL_ATTR4_SUPPRESS_WEAPON_PROCS
Definition SharedDefines.h:541
@ AURA_INTERRUPT_FLAG_TALK
Definition SpellDefines.h:53
@ SPELL_ATTR0_CU_NO_PVP_FLAG
Definition SpellInfo.h:184
@ SPELL_ATTR0_CU_PICKPOCKET
Definition SpellInfo.h:187
@ PROC_EX_NO_OVERHEAL
Definition SpellMgr.h:218
@ PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_NEG
Definition SpellMgr.h:135
@ PROC_FLAG_TAKEN_SPELL_NONE_DMG_CLASS_NEG
Definition SpellMgr.h:129
@ PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_POS
Definition SpellMgr.h:132
@ PROC_FLAG_TAKEN_DAMAGE
Definition SpellMgr.h:140
@ PROC_FLAG_TAKEN_SPELL_NONE_DMG_CLASS_POS
Definition SpellMgr.h:126
static const uint32 SPELL_INTERRUPT_NONPLAYER
Definition Spell.h:281
@ UNIT_STAND_STATE_STAND
Definition UnitDefines.h:35
@ NODAMAGE
Definition Unit.h:258
@ SPELL_DIRECT_DAMAGE
Definition Unit.h:255
@ HEAL
Definition Unit.h:257
virtual void SpellHitTarget(Unit *, SpellInfo const *)
Definition CreatureAI.h:165
virtual void SpellHit(Unit *, SpellInfo const *)
Definition CreatureAI.h:162
void LowerPlayerDamageReq(uint32 unDamage, bool damagedByPlayer=true, uint8 attackerLevel=0)
Definition Creature.cpp:3846
CreatureAI * AI() const
Definition Creature.h:144
Definition Unit.h:336
Definition Unit.h:383
void RestoreSpellMods(Spell *spell, uint32 ownerAuraId=0, Aura *aura=nullptr)
Definition Player.cpp:9960
void CastItemCombatSpell(Unit *target, WeaponAttackType attType, uint32 procVictim, uint32 procEx)
Definition Player.cpp:7245
void UpdatePvP(bool state, bool _override=false)
Definition PlayerUpdates.cpp:1530
ObjectGuid GetUnitTargetGUID() const
Definition Spell.cpp:216
bool HasInitialAggro() const
Definition SpellInfo.cpp:1320
bool IsAuraEffectEqual(SpellInfo const *otherSpellInfo) const
Definition SpellInfo.cpp:1592
bool IsPositiveEffect(uint8 effIndex) const
Definition SpellInfo.cpp:1274
bool CanExecuteTriggersOnHit(uint8 effMask, SpellInfo const *triggeredByAura=nullptr) const
Definition Spell.cpp:8792
SpellValue const * GetSpellValue()
Definition Spell.h:601
SpellMissInfo DoSpellHitOnUnit(Unit *unit, uint32 effectMask, bool scaleAura)
Definition Spell.cpp:2965
Position m_reflectionTargetPosition
Definition Spell.h:680
void DoTriggersOnSpellHit(Unit *unit, uint8 effMask)
Definition Spell.cpp:3222
void ForwardThreatForAssistingMe(Unit *assistant, float baseAmount, SpellInfo const *spell=nullptr, bool ignoreModifiers=false)
== AFFECT OTHERS' THREAT LISTS ==
Definition ThreatManager.cpp:755
uint32 m_lastSanctuaryTime
Definition Unit.h:2094
void DealSpellDamage(SpellNonMeleeDamage *damageInfo, bool durabilityLoss, Spell const *spell=nullptr)
Definition Unit.cpp:1669
void SetInCombatWith(Unit *enemy, bool addSecondUnitSuppressed=false)
Definition Unit.h:939
void SendSpellMiss(Unit *target, uint32 spellID, SpellMissInfo missInfo)
Definition Unit.cpp:6871
void SendSpellNonMeleeReflectLog(SpellNonMeleeDamage *log, Unit *attacker)
Definition Unit.cpp:6682
bool CanProc()
Definition Unit.h:1557
bool IsPvP() const
Definition Unit.h:1044
uint32 SpellHealingBonusDone(Unit *victim, SpellInfo const *spellProto, uint32 healamount, DamageEffectType damagetype, uint8 effIndex, float TotalMod=0.0f, uint32 stack=1)
Definition Unit.cpp:9556
void AtTargetAttacked(Unit *target, bool canInitialAggro)
Definition Unit.cpp:11483
int32 HealBySpell(HealInfo &healInfo, bool critical=false)
Definition Unit.cpp:8371
bool IsStandState() const
Definition Unit.cpp:13133
int32 GetHealthGain(int32 dVal)
Definition Unit.cpp:11028
bool IsImmunedToDamage(SpellSchoolMask schoolMask) const
Definition Unit.cpp:9858
static uint32 SpellCriticalHealingBonus(Unit const *caster, SpellInfo const *spellProto, uint32 damage, Unit const *victim)
Definition Unit.cpp:9431
void SendSpellNonMeleeDamageLog(SpellNonMeleeDamage *log)
Definition Unit.cpp:6714
ThreatManager & GetThreatMgr()
Definition Unit.h:951
bool IsAIEnabled
Definition Unit.h:2101
void SetLastDamagedTargetGuid(ObjectGuid const &guid)
Definition Unit.h:971
virtual bool IsEngaged() const
Definition Unit.h:931
uint32 SpellHealingBonusTaken(Unit *caster, SpellInfo const *spellProto, uint32 healamount, DamageEffectType damagetype, uint32 stack=1)
Definition Unit.cpp:9676
void SetStandState(uint8 state)
Definition Unit.cpp:13148
void RemoveAurasWithInterruptFlags(uint32 flag, uint32 except=0, bool isAutoshot=false)
Definition Unit.cpp:5468
static void DealDamageMods(Unit const *victim, uint32 &damage, uint32 *absorb)
Definition Unit.cpp:1000
void CalculateSpellDamageTaken(SpellNonMeleeDamage *damageInfo, int32 damage, SpellInfo const *spellInfo, WeaponAttackType attackType=BASE_ATTACK, bool crit=false)
Definition Unit.cpp:1522
Milliseconds GetGameTimeMS()
Definition GameTime.cpp:43
Definition Position.h:27
void Relocate(float x, float y)
Definition Position.h:77
Definition Unit.h:508

References SpellNonMeleeDamage::absorb, HealInfo::AddHitMask(), Creature::AI(), TargetInfo::alive, Unit::AtTargetAttacked(), AURA_INTERRUPT_FLAG_TALK, SpellNonMeleeDamage::blocked, Unit::CalculateSpellDamageTaken(), CallScriptAfterHitHandlers(), CallScriptBeforeHitHandlers(), CallScriptOnHitHandlers(), CanExecuteTriggersOnHit(), Unit::CanProc(), Player::CastItemCombatSpell(), Unit::CastSpell(), CLASS_PALADIN, ObjectGuid::Clear(), TargetInfo::crit, SpellNonMeleeDamage::damage, TargetInfo::damage, TargetInfo::damageBeforeTakenMods, Unit::DealDamageMods(), Unit::DealSpellDamage(), SpellInfo::DmgClass, DoSpellHitOnUnit(), DoTriggersOnSpellHit(), EFFECT_0, TriggeredByAuraSpellData::effectIndex, TargetInfo::effectMask, SpellInfo::Effects, Unit::EngageWithTarget(), ObjectAccessor::FindPlayer(), ThreatManager::ForwardThreatForAssistingMe(), Object::GetEntry(), GameTime::GetGameTimeMS(), Object::GetGUID(), Unit::GetHealthGain(), DamageInfo::GetHitMask(), HealInfo::GetHitMask(), Unit::GetOwner(), Unit::GetOwnerGUID(), SpellInfo::GetSchoolMask(), GetSpellValue(), getState(), Unit::GetThreatMgr(), ObjectAccessor::GetUnit(), SpellCastTargets::GetUnitTargetGUID(), HandleEffects(), SpellInfo::HasAttribute(), SpellInfo::HasEffect(), SpellInfo::HasInitialAggro(), HEAL, Unit::HealBySpell(), SpellNonMeleeDamage::HitInfo, SpellInfo::Id, Unit::IsAIEnabled, Unit::IsAlive(), SpellInfo::IsAuraEffectEqual(), Unit::IsClass(), Object::IsCreature(), Unit::IsEngaged(), Unit::IsFriendlyTo(), Unit::IsImmunedToDamage(), Unit::IsInCombat(), Object::IsPlayer(), ObjectGuid::IsPlayer(), SpellInfo::IsPositive(), SpellInfo::IsPositiveEffect(), Unit::IsPvP(), Unit::IsStandState(), Creature::LowerPlayerDamageReq(), m_attackType, m_caster, m_damage, m_healing, Unit::m_lastSanctuaryTime, m_needComboPoints, m_originalCaster, m_procAttacker, m_procEx, m_procVictim, m_reflectionTarget, m_reflectionTargetGuid, m_reflectionTargetPosition, m_spellAura, m_spellInfo, m_spellSchoolMask, m_targets, m_triggeredByAuraSpell, MAX_SPELL_EFFECTS, TargetInfo::missCondition, NODAMAGE, PrepareScriptHitHandlers(), PROC_EX_NO_OVERHEAL, 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, PROC_HIT_CRITICAL, PROC_HIT_NORMAL, TargetInfo::processed, Unit::ProcSkillsAndAuras(), TargetInfo::reflectResult, Position::Relocate(), Unit::RemoveAurasWithInterruptFlags(), Player::RestoreSpellMods(), TargetInfo::scaleAura, Unit::SendSpellMiss(), Unit::SendSpellNonMeleeDamageLog(), Unit::SendSpellNonMeleeReflectLog(), HealInfo::SetHealBeforeTakenMods(), Unit::SetInCombatWith(), Unit::SetLastDamagedTargetGuid(), Unit::SetStandState(), SPELL_ATTR0_CANCELS_AUTO_ATTACK_COMBAT, SPELL_ATTR0_CU_NO_PVP_FLAG, SPELL_ATTR0_CU_PICKPOCKET, SPELL_ATTR1_NO_THREAT, SPELL_ATTR3_SUPPRESS_CASTER_PROCS, SPELL_ATTR3_SUPPRESS_TARGET_PROCS, SPELL_ATTR4_SUPPRESS_WEAPON_PROCS, SPELL_ATTR7_CAN_CAUSE_INTERRUPT, SPELL_DAMAGE_CLASS_MAGIC, SPELL_DAMAGE_CLASS_MELEE, SPELL_DAMAGE_CLASS_NONE, SPELL_DAMAGE_CLASS_RANGED, SPELL_DIRECT_DAMAGE, SPELL_EFFECT_DISPEL, SPELL_EFFECT_HANDLE_HIT_TARGET, SPELL_EFFECT_HEALTH_LEECH, SPELL_HIT_TYPE_CRIT, SPELL_INTERRUPT_NONPLAYER, SPELL_MISS_BLOCK, SPELL_MISS_DODGE, SPELL_MISS_EVADE, SPELL_MISS_IMMUNE2, SPELL_MISS_MISS, SPELL_MISS_NONE, SPELL_MISS_PARRY, SPELL_MISS_REFLECT, SPELL_MISS_RESIST, SPELL_STATE_DELAYED, Unit::SpellCriticalHealingBonus(), Unit::SpellHealingBonusDone(), Unit::SpellHealingBonusTaken(), CreatureAI::SpellHit(), CreatureAI::SpellHitTarget(), TriggeredByAuraSpellData::spellInfo, SpellNonMeleeDamage::target, TargetInfo::targetGUID, TargetInfo::timeDelay, Object::ToCreature(), Object::ToPlayer(), UNIT_STAND_STATE_STAND, unitTarget, and Player::UpdatePvP().

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

◆ DoCreateItem()

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

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

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

◆ DoSpellHitOnUnit()

SpellMissInfo Spell::DoSpellHitOnUnit ( Unit unit,
uint32  effectMask,
bool  scaleAura 
)
protected
Todo:
: this cause soul transfer bugged
2966{
2967 if (!unit || !effectMask)
2968 return SPELL_MISS_EVADE;
2969
2970 // For delayed spells immunity may be applied between missile launch and hit - check immunity for that case
2971 if (m_spellInfo->Speed && ((m_damage > 0 && unit->IsImmunedToDamage(m_caster, m_spellInfo)) || unit->IsImmunedToSchool(this) || unit->IsImmunedToSpell(m_spellInfo, this)))
2972 {
2973 return SPELL_MISS_IMMUNE;
2974 }
2975
2976 // disable effects to which unit is immune
2977 SpellMissInfo returnVal = SPELL_MISS_IMMUNE;
2978 for (uint32 effectNumber = 0; effectNumber < MAX_SPELL_EFFECTS; ++effectNumber)
2979 {
2980 if (effectMask & (1 << effectNumber))
2981 {
2982 if (unit->IsImmunedToSpellEffect(m_spellInfo, effectNumber, m_caster))
2983 effectMask &= ~(1 << effectNumber);
2984 // Xinef: Buggs out polymorph
2985 // Xinef: And this is checked in MagicSpellHitResult, why we check resistance twice?
2986 // Xinef: And why we check every spell effect basing on rand and generic dispel info? some effects will be appliend and some wont?
2987 /*else if (m_spellInfo->Effects[effectNumber].IsAura() && !m_spellInfo->IsPositiveEffect(effectNumber))
2988 {
2989 int32 debuff_resist_chance = unit->GetMaxPositiveAuraModifierByMiscValue(SPELL_AURA_MOD_DEBUFF_RESISTANCE, int32(m_spellInfo->Dispel));
2990 debuff_resist_chance += unit->GetMaxNegativeAuraModifierByMiscValue(SPELL_AURA_MOD_DEBUFF_RESISTANCE, int32(m_spellInfo->Dispel));
2991
2992 if (debuff_resist_chance > 0)
2993 if (irand(0,10000) <= (debuff_resist_chance * 100))
2994 {
2995 effectMask &= ~(1 << effectNumber);
2996 returnVal = SPELL_MISS_RESIST;
2997 }
2998 }*/
2999 }
3000 }
3001 if (!effectMask)
3002 return returnVal;
3003
3004 if (unit->IsPlayer())
3005 {
3009 }
3010
3011 if (m_caster->IsPlayer())
3012 {
3015 }
3016
3017 if (m_caster != unit)
3018 {
3019 // Recheck UNIT_FLAG_NON_ATTACKABLE for delayed spells
3020 // Xinef: Also check evade state
3021 if (m_spellInfo->Speed > 0.0f)
3022 {
3023 if (unit->IsCreature() && unit->ToCreature()->IsInEvadeMode())
3024 return SPELL_MISS_EVADE;
3025
3027 return SPELL_MISS_EVADE;
3028 }
3029
3030 if (m_caster->_IsValidAttackTarget(unit, m_spellInfo) && /*Intervene Trigger*/ m_spellInfo->Id != 59667)
3031 {
3033 }
3034 else if (m_caster->IsFriendlyTo(unit))
3035 {
3036 // for delayed spells ignore negative spells (after duel end) for friendly targets
3038 if (!IsTriggered() && m_spellInfo->Speed > 0.0f && unit->IsPlayer() && !m_spellInfo->IsPositive())
3039 return SPELL_MISS_EVADE;
3040
3041 // assisting case, healing and resurrection
3043 {
3046 m_caster->ToPlayer()->UpdatePvP(true);
3047 }
3048
3049 // xinef: triggered spells should not prolong combat
3051 {
3054 unit->GetThreatMgr().ForwardThreatForAssistingMe(m_originalCaster, 0.0f, nullptr, true);
3055 }
3056 }
3057 }
3058
3059 uint8 aura_effmask = 0;
3060 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
3061 if (effectMask & (1 << i) && m_spellInfo->Effects[i].IsUnitOwnedAuraEffect())
3062 aura_effmask |= 1 << i;
3063
3064 Unit* originalCaster = GetOriginalCaster();
3065 if (!originalCaster)
3066 originalCaster = m_caster;
3067
3068 // Get Data Needed for Diminishing Returns, some effects may have multiple auras, so this must be done on spell hit, not aura add
3069 // Xinef: Do not increase diminishing level for self cast
3071 // xinef: do not increase diminish level for bosses (eg. Void Reaver silence is never diminished)
3072 if (((m_spellFlags & SPELL_FLAG_REFLECTED) && !(unit->HasReflectSpellsAura())) || (aura_effmask && m_diminishGroup && unit != m_caster && (!m_caster->IsCreature() || !m_caster->ToCreature()->isWorldBoss())))
3073 {
3076
3077 uint32 flagsExtra = unit->IsCreature() ? unit->ToCreature()->GetCreatureTemplate()->flags_extra : 0;
3078
3079 // Increase Diminishing on unit, current informations for actually casts will use values above
3080 if ((type == DRTYPE_PLAYER && (unit->IsCharmedOwnedByPlayerOrPlayer() || flagsExtra & CREATURE_FLAG_EXTRA_ALL_DIMINISH ||
3082 {
3083 // Do not apply diminish return if caster is NPC
3085 {
3087 }
3088 }
3089 }
3090
3093
3094 if (aura_effmask)
3095 {
3096 // Select rank for aura with level requirements only in specific cases
3097 // 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
3098 SpellInfo const* aurSpellInfo = m_spellInfo;
3099 int32 basePoints[3];
3100 if (scaleAura)
3101 {
3103 ASSERT(aurSpellInfo);
3104 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
3105 {
3106 basePoints[i] = aurSpellInfo->Effects[i].BasePoints;
3107 if (m_spellInfo->Effects[i].Effect != aurSpellInfo->Effects[i].Effect)
3108 {
3109 aurSpellInfo = m_spellInfo;
3110 break;
3111 }
3112 }
3113 }
3114
3115 if (m_originalCaster)
3116 {
3117 bool refresh = false;
3119 m_spellAura = Aura::TryRefreshStackOrCreate(aurSpellInfo, effectMask, unit, m_originalCaster,
3120 (aurSpellInfo == m_spellInfo) ? &m_spellValue->EffectBasePoints[0] : &basePoints[0], m_CastItem, ObjectGuid::Empty, &refresh, refreshPeriodic);
3121
3122 // xinef: if aura was not refreshed, add proc ex
3123 if (!refresh)
3125
3126 if (m_spellAura)
3127 {
3128 // Set aura stack amount to desired value
3130 {
3131 if (!refresh)
3133 else
3135 }
3136
3137 // Now Reduce spell duration using data received at spell hit
3138 int32 duration = m_spellAura->GetMaxDuration();
3139 int32 limitduration = GetDiminishingReturnsLimitDuration(m_diminishGroup, aurSpellInfo);
3140
3141 // Xinef: if unit == caster - test versus original unit if available
3142 float diminishMod = 1.0f;
3143 if (unit == m_caster && m_targets.GetUnitTarget())
3145 else
3146 diminishMod = unit->ApplyDiminishingToDuration(m_diminishGroup, duration, m_originalCaster, m_diminishLevel, limitduration);
3147
3148 // unit is immune to aura if it was diminished to 0 duration
3149 if (diminishMod == 0.0f)
3150 {
3153 return SPELL_MISS_IMMUNE;
3154 bool found = false;
3155 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
3156 if (effectMask & (1 << i) && m_spellInfo->Effects[i].Effect != SPELL_EFFECT_APPLY_AURA)
3157 found = true;
3158 if (!found)
3159 return SPELL_MISS_IMMUNE;
3160 }
3161 else
3162 {
3163 ((UnitAura*)m_spellAura)->SetDiminishGroup(m_diminishGroup);
3164
3165 bool positive = m_spellAura->GetSpellInfo()->IsPositive();
3167 positive = aurApp->IsPositive();
3168
3169 duration = m_originalCaster->ModSpellDuration(aurSpellInfo, unit, duration, positive, effectMask);
3170
3171 // xinef: haste affects duration of those spells twice
3174
3175 if (m_spellValue->AuraDuration != 0)
3176 {
3177 if (m_spellAura->GetMaxDuration() != -1)
3178 {
3180 }
3181
3183 }
3184 else if (duration != m_spellAura->GetMaxDuration())
3185 {
3186 m_spellAura->SetMaxDuration(duration);
3187 m_spellAura->SetDuration(duration);
3188 }
3189
3190 // xinef: apply relic cooldown, imo best place to add this
3193
3196 }
3197 }
3198 }
3199 }
3200
3201 int8 sanct_effect = -1;
3202
3203 for (uint32 effectNumber = 0; effectNumber < MAX_SPELL_EFFECTS; ++effectNumber)
3204 {
3205 // handle sanctuary effects after aura apply!
3206 if (m_spellInfo->Effects[effectNumber].Effect == SPELL_EFFECT_SANCTUARY)
3207 {
3208 sanct_effect = effectNumber;
3209 continue;
3210 }
3211
3212 if (effectMask & (1 << effectNumber))
3213 HandleEffects(unit, nullptr, nullptr, effectNumber, SPELL_EFFECT_HANDLE_HIT_TARGET);
3214 }
3215
3216 if (sanct_effect >= 0 && (effectMask & (1 << sanct_effect)))
3217 HandleEffects(unit, nullptr, nullptr, sanct_effect, SPELL_EFFECT_HANDLE_HIT_TARGET);
3218
3219 return SPELL_MISS_NONE;
3220}
@ CREATURE_FLAG_EXTRA_OBEYS_TAUNT_DIMINISHING_RETURNS
Definition CreatureData.h:65
@ CREATURE_FLAG_EXTRA_ALL_DIMINISH
Definition CreatureData.h:66
@ ACHIEVEMENT_TIMED_TYPE_SPELL_CASTER
Definition DBCEnums.h:112
@ ACHIEVEMENT_TIMED_TYPE_SPELL_TARGET
Definition DBCEnums.h:113
@ ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET2
Definition DBCEnums.h:181
@ ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET
Definition DBCEnums.h:142
@ ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL2
Definition DBCEnums.h:217
@ DIMINISHING_TAUNT
Definition SharedDefines.h:3509
@ SPELL_EFFECT_SANCTUARY
Definition SharedDefines.h:845
@ SPELL_EFFECT_APPLY_AURA
Definition SharedDefines.h:772
@ SPELL_ATTR5_SPELL_HASTE_AFFECTS_PERIODIC
Definition SharedDefines.h:568
DiminishingReturnsType
Definition SharedDefines.h:3482
@ DRTYPE_PLAYER
Definition SharedDefines.h:3484
@ DRTYPE_ALL
Definition SharedDefines.h:3485
@ SPELL_AURA_PERIODIC_HASTE
Definition SpellAuraDefines.h:379
@ SPELL_AURA_MOD_STEALTH
Definition SpellAuraDefines.h:79
@ AURA_INTERRUPT_FLAG_HITBYSPELL
Definition SpellDefines.h:43
@ TRIGGERED_NO_PERIODIC_RESET
Will ignore equipped item requirements.
Definition SpellDefines.h:152
@ SPELL_ATTR0_CU_DONT_BREAK_STEALTH
Definition SpellInfo.h:183
int32 GetDiminishingReturnsLimitDuration(DiminishingGroup group, SpellInfo const *spellproto)
Definition SpellMgr.cpp:324
DiminishingGroup GetDiminishingReturnsGroupForSpell(SpellInfo const *spellproto, bool triggered)
Definition SpellMgr.cpp:107
DiminishingReturnsType GetDiminishingReturnsGroupType(DiminishingGroup group)
Definition SpellMgr.cpp:294
@ PROC_EX_NO_AURA_REFRESH
Definition SpellMgr.h:219
@ UNIT_STATE_ATTACK_PLAYER
Definition UnitDefines.h:187
@ UNIT_FLAG_NON_ATTACKABLE
Definition UnitDefines.h:258
@ UNIT_FLAG_PLAYER_CONTROLLED
Definition UnitDefines.h:260
@ UNIT_MOD_CAST_SPEED
Definition UpdateFields.h:137
Definition SpellAuras.h:37
int32 GetMaxDuration() const
Definition SpellAuras.h:129
void SetStackAmount(uint8 num)
Definition SpellAuras.cpp:937
void SetTriggeredByAuraSpellInfo(SpellInfo const *triggeredByAuraSpellInfo)
Definition SpellAuras.cpp:2756
void _RegisterForTargets()
Definition SpellAuras.h:121
bool ModStackAmount(int32 num, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT, bool periodicReset=false)
Definition SpellAuras.cpp:963
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:265
void SetDuration(int32 duration, bool withMods=false)
Definition SpellAuras.cpp:810
const AuraApplication * GetApplicationOfTarget(ObjectGuid guid) const
Definition SpellAuras.h:184
void SetMaxDuration(int32 duration)
Definition SpellAuras.h:130
virtual void Remove(AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)=0
void InheritCombatStatesFrom(Unit const *who)
Definition CombatManager.cpp:270
bool isWorldBoss() const
Definition Creature.h:124
bool IsInEvadeMode() const
Definition Creature.h:138
float GetFloatValue(uint16 index) const
Definition Object.cpp:306
uint32 StackAmount
Definition SpellInfo.h:395
SpellInfo const * GetAuraRankForLevel(uint8 level) const
Definition SpellInfo.cpp:2928
Unit * GetOriginalCaster() const
Definition Spell.h:591
Definition SpellAuras.h:289
bool HasAuraTypeWithAffectMask(AuraType auratype, SpellInfo const *affectedSpell) const
Definition Unit.cpp:6057
DiminishingLevels GetDiminishing(DiminishingGroup group)
Definition Unit.cpp:11773
void IncrDiminishing(DiminishingGroup group)
Definition Unit.cpp:11799
void SetContestedPvP(Player *attackedPlayer=nullptr, bool lookForNearContestedGuards=true)
Definition Unit.cpp:13682
bool HasUnitFlag(UnitFlags flags) const
Definition Unit.h:747
float ApplyDiminishingToDuration(DiminishingGroup group, int32 &duration, Unit *caster, DiminishingLevels Level, int32 limitduration)
Definition Unit.cpp:11813
int32 ModSpellDuration(SpellInfo const *spellProto, Unit const *target, int32 duration, bool positive, uint32 effectMask)
Definition Unit.cpp:11639
virtual void AddSpellCooldown(uint32, uint32, uint32, bool needSendToClient=false, bool forceSendToSpectator=false)
Definition Unit.h:1337
bool HasReflectSpellsAura() const
Definition Unit.h:1820
bool IsCharmedOwnedByPlayerOrPlayer() const
Definition Unit.h:1309
bool IsImmunedToSchool(SpellSchoolMask schoolMask) const
Definition Unit.cpp:9919
virtual bool IsImmunedToSpell(SpellInfo const *spellInfo, Spell const *spell=nullptr)
Definition Unit.cpp:10126
CombatManager & GetCombatManager()
Definition Unit.h:953
bool IsHostileTo(Unit const *unit) const
Definition Unit.cpp:7271
bool _IsValidAttackTarget(Unit const *target, SpellInfo const *bySpell, WorldObject const *obj=nullptr) const
Definition Unit.cpp:10767
ObjectGuid GetCharmerOrOwnerGUID() const
Definition Unit.h:1295
uint32 flags_extra
Definition CreatureData.h:241
int32 AuraDuration
Definition Spell.h:229
uint8 AuraStackAmount
Definition Spell.h:228

References Unit::_IsValidAttackTarget(), Aura::_RegisterForTargets(), ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET, ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET2, ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL2, ACHIEVEMENT_TIMED_TYPE_SPELL_CASTER, ACHIEVEMENT_TIMED_TYPE_SPELL_TARGET, Unit::AddSpellCooldown(), Unit::ApplyDiminishingToDuration(), ASSERT, AURA_INTERRUPT_FLAG_HITBYSPELL, SpellValue::AuraDuration, SpellValue::AuraStackAmount, CREATURE_FLAG_EXTRA_ALL_DIMINISH, CREATURE_FLAG_EXTRA_OBEYS_TAUNT_DIMINISHING_RETURNS, DIMINISHING_TAUNT, DRTYPE_ALL, DRTYPE_PLAYER, SpellValue::EffectBasePoints, SpellInfo::Effects, ObjectGuid::Empty, CreatureTemplate::flags_extra, ThreatManager::ForwardThreatForAssistingMe(), Aura::GetApplicationOfTarget(), SpellInfo::GetAuraRankForLevel(), Unit::GetCharmerOrOwnerGUID(), Unit::GetCombatManager(), Creature::GetCreatureTemplate(), Unit::GetDiminishing(), GetDiminishingReturnsGroupForSpell(), GetDiminishingReturnsGroupType(), GetDiminishingReturnsLimitDuration(), Object::GetEntry(), Object::GetFloatValue(), Object::GetGUID(), Unit::GetLevel(), Aura::GetMaxDuration(), GetOriginalCaster(), Aura::GetSpellInfo(), Item::GetTemplate(), Unit::GetThreatMgr(), SpellCastTargets::GetUnitTarget(), HandleEffects(), SpellInfo::HasAttribute(), Unit::HasAuraTypeWithAffectMask(), Unit::HasReflectSpellsAura(), HasTriggeredCastFlag(), Unit::HasUnitFlag(), Unit::HasUnitState(), SpellInfo::Id, Unit::IncrDiminishing(), CombatManager::InheritCombatStatesFrom(), ItemTemplate::InventoryType, INVTYPE_RELIC, Unit::IsCharmedOwnedByPlayerOrPlayer(), Object::IsCreature(), Unit::IsFriendlyTo(), Unit::IsHostileTo(), Unit::IsImmunedToDamage(), Unit::IsImmunedToSchool(), Unit::IsImmunedToSpell(), Unit::IsImmunedToSpellEffect(), Unit::IsInCombat(), Creature::IsInEvadeMode(), Object::IsPlayer(), SpellInfo::IsPositive(), IsTriggered(), Creature::isWorldBoss(), m_caster, m_CastItem, m_damage, m_diminishGroup, m_diminishLevel, m_originalCaster, m_procEx, m_spellAura, m_spellFlags, m_spellInfo, m_spellValue, m_targets, m_triggeredByAuraSpell, MAX_SPELL_EFFECTS, Unit::ModSpellDuration(), Aura::ModStackAmount(), PROC_EX_NO_AURA_REFRESH, Aura::Remove(), Unit::RemoveAurasByType(), Unit::RemoveAurasWithInterruptFlags(), Unit::SetContestedPvP(), Aura::SetDuration(), Aura::SetMaxDuration(), Aura::SetStackAmount(), Aura::SetTriggeredByAuraSpellInfo(), SpellInfo::Speed, SPELL_ATTR0_CU_DONT_BREAK_STEALTH, SPELL_ATTR0_CU_NO_PVP_FLAG, SPELL_ATTR3_SUPPRESS_TARGET_PROCS, SPELL_ATTR5_SPELL_HASTE_AFFECTS_PERIODIC, SPELL_AURA_MOD_STEALTH, SPELL_AURA_PERIODIC_HASTE, SPELL_EFFECT_APPLY_AURA, SPELL_EFFECT_HANDLE_HIT_TARGET, SPELL_EFFECT_SANCTUARY, SPELL_FLAG_REFLECTED, SPELL_MISS_EVADE, SPELL_MISS_IMMUNE, SPELL_MISS_NONE, SPELL_RELIC_COOLDOWN, TriggeredByAuraSpellData::spellInfo, SpellInfo::StackAmount, Player::StartTimedAchievement(), Object::ToCreature(), Object::ToPlayer(), TRIGGERED_NO_PERIODIC_RESET, Aura::TryRefreshStackOrCreate(), UNIT_FLAG_NON_ATTACKABLE, UNIT_FLAG_PLAYER_CONTROLLED, 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
3223{
3224 // Apply additional spell effects to target
3226 if (m_preCastSpell)
3227 {
3228 // Avenging Wrath - also apply Immune Shield Marker
3229 if (m_preCastSpell == 61987)
3230 m_caster->CastSpell(unit, 61988, true);
3231
3232 // Fearie Fire (Feral) - damage
3233 if (m_preCastSpell == 60089)
3234 m_caster->CastSpell(unit, m_preCastSpell, true);
3235 else if (sSpellMgr->GetSpellInfo(m_preCastSpell))
3236 // Blizz seems to just apply aura without bothering to cast
3238 }
3239
3240 // handle SPELL_AURA_ADD_TARGET_TRIGGER auras
3241 // this is executed after spell proc spells on target hit
3242 // spells are triggered for each hit spell target
3243 // info confirmed with retail sniffs of permafrost and shadow weaving
3244 if (!m_hitTriggerSpells.empty())
3245 {
3246 int _duration = 0;
3247 for (HitTriggerSpellList::const_iterator i = m_hitTriggerSpells.begin(); i != m_hitTriggerSpells.end(); ++i)
3248 {
3249 if (CanExecuteTriggersOnHit(effMask, i->triggeredByAura) && roll_chance_i(i->chance))
3250 {
3251 m_caster->CastSpell(unit, i->triggeredSpell->Id, true);
3252 LOG_DEBUG("spells.aura", "Spell {} triggered spell {} by SPELL_AURA_ADD_TARGET_TRIGGER aura", m_spellInfo->Id, i->triggeredSpell->Id);
3253
3254 // SPELL_AURA_ADD_TARGET_TRIGGER auras shouldn't trigger auras without duration
3255 // set duration of current aura to the triggered spell
3256 if (i->triggeredSpell->GetDuration() == -1)
3257 {
3258 if (Aura* triggeredAur = unit->GetAura(i->triggeredSpell->Id, m_caster->GetGUID()))
3259 {
3260 // get duration from aura-only once
3261 if (!_duration)
3262 {
3263 Aura* aur = unit->GetAura(m_spellInfo->Id, m_caster->GetGUID());
3264 _duration = aur ? aur->GetDuration() : -1;
3265 }
3266 triggeredAur->SetDuration(std::max(triggeredAur->GetDuration(), _duration));
3267 }
3268 }
3269 }
3270 }
3271 }
3272
3273 // trigger linked auras remove/apply
3275 if (std::vector<int32> const* spellTriggered = sSpellMgr->GetSpellLinked(m_spellInfo->Id + SPELL_LINK_HIT))
3276 {
3277 for (std::vector<int32>::const_iterator i = spellTriggered->begin(); i != spellTriggered->end(); ++i)
3278 if (*i < 0)
3279 {
3280 unit->RemoveAurasDueToSpell(-(*i));
3281 }
3282 else
3283 {
3284 unit->CastSpell(unit, *i, true, 0, 0, m_caster->GetGUID());
3285 }
3286 }
3287}
bool roll_chance_i(int chance)
Definition Random.h:63
@ SPELL_LINK_HIT
Definition SpellMgr.h:100
int32 GetDuration() const
Definition SpellAuras.h:133
HitTriggerSpellList m_hitTriggerSpells
Definition Spell.h:779
Aura * GetAura(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemCasterGUID=ObjectGuid::Empty, uint8 reqEffMask=0) const
Definition Unit.cpp:5877
Aura * AddAura(uint32 spellId, Unit *target)
Definition Unit.cpp:15159

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)
4251{
4253 return;
4254
4255 if (!gameObjTarget)
4256 return;
4257
4258 GameObjectActions action = GameObjectActions(m_spellInfo->Effects[effIndex].MiscValue);
4259 switch (action)
4260 {
4266 break;
4267 case GameObjectActions::Disturb: // What's the difference with Open?
4269 if (Unit* unitCaster = m_caster->ToUnit())
4270 gameObjTarget->Use(unitCaster);
4271 break;
4273 if (Unit* unitCaster = m_caster->ToUnit())
4274 gameObjTarget->UseDoorOrButton(0, false, unitCaster);
4275 [[fallthrough]];
4279 break;
4283 break;
4286 break;
4290 break;
4294 break;
4296 if (Unit* unitCaster = m_caster->ToUnit())
4297 gameObjTarget->UseDoorOrButton(0, true, unitCaster);
4298 break;
4303 {
4304 GameObjectTemplateAddon const* templateAddon = gameObjTarget->GetTemplateAddon();
4305
4306 uint32 artKitIndex = uint32(action) - uint32(GameObjectActions::UseArtKit0);
4307
4308 uint32 artKitValue = 0;
4309 if (templateAddon)
4310 artKitValue = templateAddon->artKits[artKitIndex];
4311
4312 if (artKitValue == 0)
4313 LOG_ERROR("sql.sql", "GameObject {} hit by spell {} needs `artkit{}` in `gameobject_template_addon`", gameObjTarget->GetEntry(), m_spellInfo->Id, artKitIndex);
4314 else
4315 gameObjTarget->SetGoArtKit(artKitValue);
4316
4317 break;
4318 }
4320 LOG_FATAL("spell", "Spell {} has action type NONE in effect {}", m_spellInfo->Id, int32(effIndex));
4321 break;
4322 default:
4323 LOG_ERROR("spell", "Spell {} has unhandled action {} in effect {}", m_spellInfo->Id, int32(action), int32(effIndex));
4324 break;
4325 }
4326}
GameObjectActions
Definition GameObject.h:76
#define LOG_FATAL(filterType__,...)
Definition Log.h:141
@ GO_FLAG_NOT_SELECTABLE
Definition SharedDefines.h:1611
@ GO_FLAG_LOCKED
Definition SharedDefines.h:1608
@ GAMEOBJECT_FLAGS
Definition UpdateFields.h:399
void UseDoorOrButton(uint32 time_to_restore=0, bool alternative=false, Unit *user=nullptr)
Definition GameObject.cpp:1410
void SetGoArtKit(uint8 artkit)
Definition GameObject.cpp:1424
void SendCustomAnim(uint32 anim)
Definition GameObject.cpp:2142
void ResetDoorOrButton()
Definition GameObject.cpp:1400
void DespawnOrUnsummon(Milliseconds delay=0ms, Seconds forcedRespawnTime=0s)
Definition GameObject.cpp:927
GameObjectTemplateAddon const * GetTemplateAddon() const
Definition GameObject.cpp:906
void Use(Unit *user)
Definition GameObject.cpp:1460
void SetFlag(uint16 index, uint32 newFlag)
Definition Object.cpp:827
void ApplyModFlag(uint16 index, uint32 flag, bool apply)
Definition Object.cpp:881
Definition GameObjectData.h:667
std::array< uint32, 4 > artKits
Definition GameObjectData.h:673

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

◆ EffectActivateRune()

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

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

◆ EffectActivateSpec()

void Spell::EffectActivateSpec ( SpellEffIndex  effIndex)
6166{
6168 return;
6169
6170 if (!unitTarget)
6171 return;
6172
6173 if (Player* player = unitTarget->ToPlayer())
6174 {
6175 player->ActivateSpec(damage - 1); // damage is 1 or 2, spec is 0 or 1
6176 }
6177}

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

◆ EffectAddComboPoints()

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

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

◆ EffectAddExtraAttacks()

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

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

◆ EffectAddFarsight()

void Spell::EffectAddFarsight ( SpellEffIndex  effIndex)
2743{
2745 return;
2746
2747 if (!m_caster->IsPlayer())
2748 return;
2749
2750 float radius = m_spellInfo->Effects[effIndex].CalcRadius();
2751 int32 duration = m_spellInfo->GetDuration();
2752 // Caster not in world, might be spell triggered from aura removal
2753 if (!m_caster->IsInWorld())
2754 return;
2755
2756 // Remove old farsight if exist
2757 bool updateViewerVisibility = m_caster->RemoveDynObject(m_spellInfo->Id);
2758
2759 DynamicObject* dynObj = new DynamicObject();
2761 {
2762 delete dynObj;
2763 return;
2764 }
2765
2766 dynObj->SetDuration(duration);
2767 dynObj->SetCasterViewpoint(updateViewerVisibility);
2768}
@ DYNAMIC_OBJECT_FARSIGHT_FOCUS
Definition DynamicObject.h:31
void SetDuration(int32 newDuration)
Definition DynamicObject.cpp:198
void SetCasterViewpoint(bool updateViewerVisibility)
Definition DynamicObject.cpp:226
bool CreateDynamicObject(ObjectGuid::LowType guidlow, Unit *caster, uint32 spellId, Position const &pos, float radius, DynamicObjectType type)
Definition DynamicObject.cpp:97
ObjectGuid::LowType GenerateLowGuid()
Definition Map.h:519
int32 GetDuration() const
Definition SpellInfo.cpp:2738

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

◆ EffectAddHonor()

void Spell::EffectAddHonor ( SpellEffIndex  effIndex)
2813{
2815 return;
2816
2817 if (!unitTarget->IsPlayer())
2818 return;
2819
2820 // not scale value for item based reward (/10 value expected)
2821 if (m_CastItem)
2822 {
2823 unitTarget->ToPlayer()->RewardHonor(nullptr, 1, damage / 10, false);
2824 LOG_DEBUG("spells.aura", "SpellEffect::AddHonor (spell_id {}) rewards {} honor points (item {}) for player: {}",
2826 return;
2827 }
2828
2829 // do not allow to add too many honor for player (50 * 21) = 1040 at level 70, or (50 * 31) = 1550 at level 80
2830 if (damage <= 50)
2831 {
2833 unitTarget->ToPlayer()->RewardHonor(nullptr, 1, honor_reward, false);
2834 LOG_DEBUG("spells.aura", "SpellEffect::AddHonor (spell_id {}) rewards {} honor points (scale) to player: {}",
2835 m_spellInfo->Id, honor_reward, unitTarget->ToPlayer()->GetGUID().ToString());
2836 }
2837 else
2838 {
2839 //maybe we have correct honor_gain in damage already
2840 unitTarget->ToPlayer()->RewardHonor(nullptr, 1, damage, false);
2841 LOG_DEBUG("spells.aura", "SpellEffect::AddHonor (spell_id {}) rewards {} honor points (non scale) for player: {}",
2843 }
2844}
std::string ToString() const
Definition ObjectGuid.cpp:47
bool RewardHonor(Unit *victim, uint32 groupsize, int32 honor=-1, bool awardXP=true)
Definition Player.cpp:6106
uint32 hk_honor_at_level(uint8 level, float multiplier=1.0f)
Definition Formulas.h:38

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

◆ EffectApplyAreaAura()

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

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

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

◆ EffectBind()

void Spell::EffectBind ( SpellEffIndex  effIndex)
6299{
6301 return;
6302
6303 if (!unitTarget)
6304 return;
6305
6306 Player* player = unitTarget->ToPlayer();
6307 if (!player)
6308 {
6309 return;
6310 }
6311
6312 WorldLocation homeLoc;
6313 uint32 areaId = player->GetAreaId();
6314
6315 if (m_spellInfo->Effects[effIndex].MiscValue)
6316 areaId = m_spellInfo->Effects[effIndex].MiscValue;
6317
6318 if (m_targets.HasDst())
6319 homeLoc.WorldRelocate(*destTarget);
6320 else
6321 {
6322 homeLoc = player->GetWorldLocation();
6323 }
6324
6325 player->SetHomebind(homeLoc, areaId);
6326
6327 // binding
6328 WorldPacket data(SMSG_BINDPOINTUPDATE, 4 + 4 + 4 + 4 + 4);
6329 data << float(homeLoc.GetPositionX());
6330 data << float(homeLoc.GetPositionY());
6331 data << float(homeLoc.GetPositionZ());
6332 data << uint32(homeLoc.GetMapId());
6333 data << uint32(areaId);
6334 player->SendDirectMessage(&data);
6335
6336 LOG_DEBUG("spells.aura", "EffectBind: New homebind X: {}, Y: {}, Z: {}, MapId: {}, AreaId: {}",
6337 homeLoc.GetPositionX(), homeLoc.GetPositionY(), homeLoc.GetPositionZ(), homeLoc.GetMapId(), areaId);
6338 // zone update
6339 data.Initialize(SMSG_PLAYERBOUND, 8 + 4);
6340 data << m_caster->GetGUID();
6341 data << uint32(areaId);
6342 player->SendDirectMessage(&data);
6343}
void SendDirectMessage(WorldPacket const *data) const
Definition Player.cpp:5701
void SetHomebind(WorldLocation const &loc, uint32 areaId)
Definition PlayerStorage.cpp:4963
Definition Position.h:256
void WorldRelocate(const WorldLocation &loc)
Definition Position.h:264
void GetWorldLocation(uint32 &mapId, float &x, float &y) const
Definition Position.h:286
@ SMSG_BINDPOINTUPDATE
Definition Opcodes.h:371
@ SMSG_PLAYERBOUND
Definition Opcodes.h:374

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

◆ EffectBlock()

void Spell::EffectBlock ( SpellEffIndex  effIndex)
4697{
4699 return;
4700
4701 if (m_caster->IsPlayer())
4702 m_caster->ToPlayer()->SetCanBlock(true);
4703}
void SetCanBlock(bool value)
Definition Player.cpp:13262

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

◆ EffectCastButtons()

void Spell::EffectCastButtons ( SpellEffIndex  effIndex)

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

6226{
6228 return;
6229
6230 if (!m_caster->IsPlayer())
6231 return;
6232
6233 Player* p_caster = m_caster->ToPlayer();
6234 uint32 button_id = m_spellInfo->Effects[effIndex].MiscValue + 132;
6235 uint32 n_buttons = m_spellInfo->Effects[effIndex].MiscValueB;
6236
6237 for (; n_buttons; --n_buttons, ++button_id)
6238 {
6239 ActionButton const* ab = p_caster->GetActionButton(button_id);
6240 if (!ab || ab->GetType() != ACTION_BUTTON_SPELL)
6241 continue;
6242
6245 uint32 spell_id = ab->GetAction();
6246 if (!spell_id)
6247 continue;
6248
6249 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spell_id);
6250 if (!spellInfo)
6251 continue;
6252
6253 if (!p_caster->HasSpell(spell_id) || p_caster->HasSpellCooldown(spell_id))
6254 continue;
6255
6257 continue;
6258
6259 uint32 cost = spellInfo->CalcPowerCost(m_caster, spellInfo->GetSchoolMask(), this);
6260 if (m_caster->GetPower(POWER_MANA) < cost)
6261 continue;
6262
6264 m_caster->CastSpell(m_caster, spell_id, triggerFlags);
6265 }
6266}
@ ACTION_BUTTON_SPELL
Definition Player.h:222
@ SPELL_ATTR7_CAN_BE_MULTI_CAST
Definition SharedDefines.h:634
ActionButton const * GetActionButton(uint8 button)
Definition Player.cpp:5660
bool HasSpell(uint32 spell) const override
Definition Player.cpp:3888
Definition Player.h:240
uint32 GetAction() const
Definition Player.h:248
ActionButtonType GetType() const
Definition Player.h:247

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

◆ EffectCharge()

void Spell::EffectCharge ( SpellEffIndex  effIndex)
4916{
4918 {
4919 if (!unitTarget)
4920 return;
4921
4922 ObjectGuid targetGUID = ObjectGuid::Empty;
4923 Player* player = m_caster->ToPlayer();
4924 if (player)
4925 {
4926 // charge changes fall time
4928
4930 {
4931 targetGUID = unitTarget->GetGUID();
4932 }
4933 }
4934
4935 float speed = G3D::fuzzyGt(m_spellInfo->Speed, 0.0f) ? m_spellInfo->Speed : SPEED_CHARGE;
4936 // Spell is not using explicit target - no generated path
4937 if (!m_preGeneratedPath)
4938 {
4940 m_caster->GetMotionMaster()->MoveCharge(pos.m_positionX, pos.m_positionY, pos.m_positionZ, speed, EVENT_CHARGE, nullptr, false, 0.0f, targetGUID);
4941 }
4942 else
4943 {
4944 m_caster->GetMotionMaster()->MoveCharge(*m_preGeneratedPath, speed, targetGUID);
4945 }
4946
4947 if (player)
4948 {
4949 sScriptMgr->AnticheatSetUnderACKmount(player);
4950 }
4951 }
4952}
#define SPEED_CHARGE
Definition MotionMaster.h:135
@ EVENT_CHARGE
Definition SharedDefines.h:3560
void MoveCharge(float x, float y, float z, float speed=SPEED_CHARGE, uint32 id=EVENT_CHARGE, const Movement::PointsArray *path=nullptr, bool generatePath=false, float orientation=0.0f, ObjectGuid targetGUID=ObjectGuid::Empty)
The unit will charge the target. Doesn't work with UNIT_FLAG_DISABLE_MOVE.
Definition MotionMaster.cpp:731
static ObjectGuid const Empty
Definition ObjectGuid.h:120
void SetFallInformation(uint32 time, float z)
Definition Player.h:2376
MotionMaster * GetMotionMaster()
Definition Unit.h:1762
Position GetFirstCollisionPosition(float startX, float startY, float startZ, float destX, float destY)
Definition Object.cpp:2887
float m_positionZ
Definition Position.h:57
float GetRelativeAngle(const Position *pos) const
Definition Position.h:201
float m_positionX
Definition Position.h:55
float m_positionY
Definition Position.h:56

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

◆ EffectChargeDest()

◆ EffectCreateItem()

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

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

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

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)
5861{
5863 return;
5864
5866 return;
5867
5868 uint32 creatureEntry = m_spellInfo->Effects[effIndex].MiscValue;
5869 Pet* pet = unitTarget->CreateTamedPetFrom(creatureEntry, m_spellInfo->Id);
5870 if (!pet)
5871 return;
5872
5873 // add to world
5874 pet->GetMap()->AddToMap(pet->ToCreature(), true);
5875
5876 // unitTarget has pet now
5877 unitTarget->SetMinion(pet, true);
5878
5879 pet->InitTalentForLevel();
5880
5881 if (unitTarget->IsPlayer())
5882 {
5885 }
5886}
@ CLASS_HUNTER
Definition SharedDefines.h:128
bool AddToMap(T *, bool checkTransport=false)
Definition Map.cpp:304
void InitTalentForLevel()
Definition Pet.cpp:2210
void SavePetToDB(PetSaveMode mode)
Definition Pet.cpp:502
void PetSpellInitialize()
Definition Player.cpp:9573
void SetMinion(Minion *minion, bool apply)
Definition Unit.cpp:7802
Pet * CreateTamedPetFrom(Creature *creatureTarget, uint32 spell_id=0)
Definition Unit.cpp:13785

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

◆ EffectDestroyAllTotems()

void Spell::EffectDestroyAllTotems ( SpellEffIndex  effIndex)
5267{
5269 return;
5270
5271 int32 mana = 0;
5272 for (uint8 slot = SUMMON_SLOT_TOTEM_FIRE; slot < MAX_TOTEM_SLOT; ++slot)
5273 {
5274 if (!m_caster->m_SummonSlot[slot])
5275 continue;
5276
5278 if (totem && totem->IsTotem())
5279 {
5280 uint32 spell_id = totem->GetUInt32Value(UNIT_CREATED_BY_SPELL);
5281 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spell_id);
5282 if (spellInfo)
5283 {
5284 mana += spellInfo->ManaCost;
5286 }
5287 totem->ToTotem()->UnSummon();
5288 }
5289 }
5290 ApplyPct(mana, damage);
5291 if (mana)
5292 m_caster->CastCustomSpell(m_caster, 39104, &mana, nullptr, nullptr, true);
5293}
#define MAX_TOTEM_SLOT
Definition SharedDefines.h:3555
@ SUMMON_SLOT_TOTEM_FIRE
Definition SharedDefines.h:3545
@ UNIT_CREATED_BY_SPELL
Definition UpdateFields.h:138
T ApplyPct(T &base, U pct)
Definition Util.h:64
Creature * GetCreature(ObjectGuid const &guid)
Definition Map.cpp:2362
uint32 ManaCostPercentage
Definition SpellInfo.h:391
uint32 ManaCost
Definition SpellInfo.h:387
void UnSummon(Milliseconds msTime=0ms) override
Definition Totem.cpp:130
Totem * ToTotem()
Definition Unit.h:730
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:1446
uint32 GetCreateMana() const
Definition Unit.h:1148
ObjectGuid m_SummonSlot[MAX_SUMMON_SLOT]
Definition Unit.h:2082

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

◆ EffectDiscoverTaxi()

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

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)
4466{
4468 return;
4469
4471 return;
4472
4473 if (Player* caster = m_caster->ToPlayer())
4474 {
4475 caster->UpdateCraftSkill(m_spellInfo->Id);
4476 caster->SendLoot(itemTarget->GetGUID(), LOOT_DISENCHANTING);
4477 }
4478
4479 // item will be removed at disenchanting end
4480}
@ LOOT_DISENCHANTING
Definition LootMgr.h:83

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

◆ EffectDismissPet()

void Spell::EffectDismissPet ( SpellEffIndex  effIndex)
4552{
4554 return;
4555
4556 if (!unitTarget || !unitTarget->IsPet())
4557 return;
4558
4559 Pet* pet = unitTarget->ToPet();
4560
4561 ExecuteLogEffectUnsummonObject(effIndex, pet);
4563}
@ PET_SAVE_NOT_IN_SLOT
Definition PetDefines.h:46
void Remove(PetSaveMode mode, bool returnreagent=false)
Definition Pet.cpp:881
void ExecuteLogEffectUnsummonObject(uint8 effIndex, WorldObject *obj)
Definition Spell.cpp:5132

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

References Unit::CastCustomSpell(), damage, EFFECT_1, effectHandleMode, SpellInfo::Effects, ThreatManager::ForwardThreatForAssistingMe(), SpellInfo::GetCategory(), Unit::GetDispellableAuraList(), SpellInfo::GetDispelMask(), Object::GetGUID(), Unit::GetOwner(), Object::GetPackGUID(), Unit::GetThreatMgr(), 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, unitTarget, and urand().

◆ EffectDispelMechanic()

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

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

◆ EffectDistract()

void Spell::EffectDistract ( SpellEffIndex  effIndex)

@BUG Causes the player to stop moving.

2715{
2717 return;
2718
2719 // Check for possible target
2720 if (!unitTarget || unitTarget->IsEngaged())
2721 return;
2722
2723 // target must be OK to do this
2725 return;
2726
2729}
@ UNIT_STATE_CONFUSED
Definition UnitDefines.h:184
@ UNIT_STATE_FLEEING
Definition UnitDefines.h:180
@ UNIT_STATE_STUNNED
Definition UnitDefines.h:176
void MoveDistract(uint32 time)
Enable the target's distract movement. Doesn't work with UNIT_FLAG_DISABLE_MOVE and if the unit has M...
Definition MotionMaster.cpp:859
void SetFacingTo(float ori)
Definition Unit.cpp:16476
float GetAngle(const Position *pos) const
Definition Position.cpp:85

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

◆ EffectDualWield()

void Spell::EffectDualWield ( SpellEffIndex  effIndex)
2701{
2703 return;
2704
2706}
virtual void SetCanDualWield(bool value)
Definition Unit.h:979

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

◆ EffectDuel()

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

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

◆ EffectDummy()

void Spell::EffectDummy ( SpellEffIndex  effIndex)
664{
666 return;
667
669 return;
670
671 // selection by spell family
673 {
675 {
676 switch (m_spellInfo->Id)
677 {
678 // Trial of the Champion, Trample
679 case 67866:
680 {
682 unitTarget->CastSpell(unitTarget, 67867, false);
683 return;
684 }
685 // Trial of the Champion, Hammer of the Righteous
686 case 66867:
687 {
688 if (!unitTarget)
689 return;
690 if (unitTarget->HasAura(66940))
691 m_caster->CastSpell(unitTarget, 66903, true);
692 else
693 m_caster->CastSpell(unitTarget, 66904, true);
694 return;
695 }
696 case 17731:
697 case 69294:
698 {
700 return;
701
705 trigger->CastSpell(trigger, 17731, false);
706
707 return;
708 }
709 // HoL, Arc Weld
710 case 59086:
711 {
713 m_caster->CastSpell(m_caster, 59097, true);
714
715 return;
716 }
717 }
718 break;
719 }
721 switch (m_spellInfo->Id)
722 {
723 case 31789: // Righteous Defense (step 1)
724 {
725 if (!unitTarget)
726 return;
727 // not empty (checked), copy
729
730 // remove invalid attackers
731 for (Unit::AttackerSet::iterator aItr = attackers.begin(); aItr != attackers.end();)
732 if (!(*aItr)->IsValidAttackTarget(m_caster))
733 aItr = attackers.erase(aItr);
734 else
735 ++aItr;
736
737 // selected from list 3
738 uint32 maxTargets = std::min<uint32>(3, attackers.size());
739 for (uint32 i = 0; i < maxTargets; ++i)
740 {
741 Unit::AttackerSet::iterator aItr = attackers.begin();
742 std::advance(aItr, urand(0, attackers.size() - 1));
743 m_caster->CastSpell((*aItr), 31790, true);
744 attackers.erase(aItr);
745 }
746
747 return;
748 }
749 }
750 break;
752 // Hunger for Blood
753 if (m_spellInfo->Id == 51662)
754 {
755 m_caster->CastSpell(m_caster, 63848, true);
756 return;
757 }
758 break;
759 }
760
761 // pet auras
762 if (PetAura const* petSpell = sSpellMgr->GetPetAura(m_spellInfo->Id, effIndex))
763 {
764 m_caster->AddPetAura(petSpell);
765 return;
766 }
767
768 // normal DB scripted effect
769 LOG_DEBUG("spells.aura", "Spell ScriptStart spellid {} in EffectDummy({})", m_spellInfo->Id, effIndex);
771
772 if (gameObjTarget)
773 {
774 sScriptMgr->OnDummyEffect(m_caster, m_spellInfo->Id, effIndex, gameObjTarget);
775 }
776 else if (unitTarget && unitTarget->IsCreature())
777 {
778 sScriptMgr->OnDummyEffect(m_caster, m_spellInfo->Id, effIndex, unitTarget->ToCreature());
779 }
780 else if (itemTarget)
781 {
782 sScriptMgr->OnDummyEffect(m_caster, m_spellInfo->Id, effIndex, itemTarget);
783 }
784}
ScriptMapMap sSpellScripts
Definition ObjectMgr.cpp:60
@ TEMPSUMMON_TIMED_DESPAWN
Definition Object.h:51
@ SPELLFAMILY_GENERIC
Definition SharedDefines.h:3784
@ SPELLFAMILY_PALADIN
Definition SharedDefines.h:3794
@ SPELLFAMILY_ROGUE
Definition SharedDefines.h:3792
@ UNIT_FIELD_MOUNTDISPLAYID
Definition UpdateFields.h:126
uint8 GetGoAnimProgress() const
Definition GameObject.h:209
time_t GetRespawnTime() const
Definition GameObject.h:184
void ScriptsStart(std::map< uint32, std::multimap< uint32, ScriptInfo > > const &scripts, uint32 id, Object *source, Object *target)
Put scripts in the execution queue.
Definition MapScripts.cpp:31
Definition SpellMgr.h:467
void AddPetAura(PetAura const *petSpell)
Definition Unit.cpp:13731
std::unordered_set< Unit * > AttackerSet
Definition Unit.h:666
AttackerSet const & getAttackers() const
Definition Unit.h:900
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:2393

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

◆ EffectDurabilityDamage()

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

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

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

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

◆ EffectEnchantItemPerm()

void Spell::EffectEnchantItemPerm ( SpellEffIndex  effIndex)
2859{
2861 return;
2862
2863 if (!m_caster->IsPlayer())
2864 return;
2865 if (!itemTarget)
2866 return;
2867
2868 Player* p_caster = m_caster->ToPlayer();
2869
2870 // Handle vellums
2872 {
2873 // destroy one vellum from stack
2874 uint32 count = 1;
2875 p_caster->DestroyItemCount(itemTarget, count, true);
2876 unitTarget = p_caster;
2877 // and add a scroll
2878 DoCreateItem(effIndex, m_spellInfo->Effects[effIndex].ItemType);
2879 itemTarget = nullptr;
2880 m_targets.SetItemTarget(nullptr);
2881 }
2882 else
2883 {
2884 // do not increase skill if vellum used
2886 p_caster->UpdateCraftSkill(m_spellInfo->Id);
2887
2888 uint32 enchant_id = m_spellInfo->Effects[effIndex].MiscValue;
2889 if (!enchant_id)
2890 return;
2891
2892 SpellItemEnchantmentEntry const* pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id);
2893 if (!pEnchant)
2894 return;
2895
2896 // item can be in trade slot and have owner diff. from caster
2897 Player* item_owner = itemTarget->GetOwner();
2898 if (!item_owner)
2899 return;
2900
2901 // remove old enchanting before applying new if equipped
2903
2905
2906 // add new enchanting if equipped
2908
2909 if (item_owner != p_caster && p_caster->GetSession()->HasPermission(rbac::RBAC_PERM_LOG_GM_TRADE))
2910 {
2911 LOG_GM(p_caster->GetSession()->GetAccountId(), "GM {} (Account: {}) enchanting(perm): {} (SpellID: {} EncID: {}) on {}'s item: {} (Entry: {})",
2912 p_caster->GetName(), p_caster->GetSession()->GetAccountId(),
2913 m_spellInfo->SpellName[0], m_spellInfo->Id, enchant_id,
2914 item_owner->GetName(), itemTarget->GetTemplate()->Name1, itemTarget->GetEntry());
2915 }
2916
2917 item_owner->RemoveTradeableItem(itemTarget);
2919 }
2920}
@ PERM_ENCHANTMENT_SLOT
Definition Item.h:169
#define LOG_GM(accountId__,...)
Definition Log.h:164
void ClearSoulboundTradeable(Player *currentOwner)
Definition Item.cpp:1270
void RemoveTradeableItem(Item *item)
Definition PlayerStorage.cpp:4211
void SetItemTarget(Item *item)
Definition Spell.cpp:328
std::array< char const *, 16 > SpellName
Definition SpellInfo.h:407
std::string const & GetName() const
Definition Object.h:528
bool HasPermission(uint32 permissionId)
Definition WorldSession.cpp:1551
@ RBAC_PERM_LOG_GM_TRADE
Definition RBAC.h:62
std::string Name1
Definition ItemTemplate.h:624

References Player::ApplyEnchantment(), Item::ClearSoulboundTradeable(), Player::DestroyItemCount(), DoCreateItem(), effectHandleMode, SpellInfo::Effects, WorldSession::GetAccountId(), Object::GetEntry(), Object::GetGUID(), WorldObject::GetName(), Item::GetOwner(), Player::GetSession(), Item::GetTemplate(), ItemTemplate::HasFlag(), WorldSession::HasPermission(), SpellInfo::Id, Item::IsArmorVellum(), Object::IsPlayer(), Item::IsWeaponVellum(), ITEM_FLAG_NO_REAGENT_COST, itemTarget, LOG_GM, m_caster, m_CastItem, m_spellInfo, m_targets, ItemTemplate::Name1, PERM_ENCHANTMENT_SLOT, rbac::RBAC_PERM_LOG_GM_TRADE, Player::RemoveTradeableItem(), Item::SetEnchantment(), SpellCastTargets::SetItemTarget(), SPELL_EFFECT_HANDLE_HIT_TARGET, SpellInfo::SpellName, sSpellItemEnchantmentStore, Object::ToPlayer(), unitTarget, and Player::UpdateCraftSkill().

◆ EffectEnchantItemPrismatic()

void Spell::EffectEnchantItemPrismatic ( SpellEffIndex  effIndex)
2923{
2925 return;
2926
2927 if (!m_caster->IsPlayer())
2928 return;
2929 if (!itemTarget)
2930 return;
2931
2932 uint32 enchant_id = m_spellInfo->Effects[effIndex].MiscValue;
2933 if (!enchant_id)
2934 return;
2935
2936 SpellItemEnchantmentEntry const* pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id);
2937 if (!pEnchant)
2938 return;
2939
2940 // support only enchantings with add socket in this slot
2941 {
2942 bool add_socket = false;
2943 for (uint8 i = 0; i < MAX_SPELL_ITEM_ENCHANTMENT_EFFECTS; ++i)
2944 {
2945 if (pEnchant->type[i] == ITEM_ENCHANTMENT_TYPE_PRISMATIC_SOCKET)
2946 {
2947 add_socket = true;
2948 break;
2949 }
2950 }
2951 if (!add_socket)
2952 {
2953 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.",
2955 return;
2956 }
2957 }
2958
2959 // item can be in trade slot and have owner diff. from caster
2960 Player* item_owner = itemTarget->GetOwner();
2961 if (!item_owner)
2962 return;
2963
2964 Player* p_caster = m_caster->ToPlayer();
2965 if (item_owner != p_caster && p_caster->GetSession()->HasPermission(rbac::RBAC_PERM_LOG_GM_TRADE))
2966 {
2967 LOG_GM(p_caster->GetSession()->GetAccountId(), "GM {} (Account: {}) enchanting(prismatic): {} (SpellID: {} EncID: {}) on {}'s item: {} (Entry: {})",
2968 p_caster->GetName(), p_caster->GetSession()->GetAccountId(),
2969 m_spellInfo->SpellName[0], m_spellInfo->Id, enchant_id,
2970 item_owner->GetName(), itemTarget->GetTemplate()->Name1, itemTarget->GetEntry());
2971 }
2972
2973 // remove old enchanting before applying new if equipped
2975
2977
2978 // add new enchanting if equipped
2980
2981 item_owner->RemoveTradeableItem(itemTarget);
2983}

References Player::ApplyEnchantment(), Item::ClearSoulboundTradeable(), effectHandleMode, SpellInfo::Effects, WorldSession::GetAccountId(), Object::GetEntry(), Object::GetGUID(), WorldObject::GetName(), Item::GetOwner(), Player::GetSession(), Item::GetTemplate(), WorldSession::HasPermission(), SpellInfo::Id, Object::IsPlayer(), ITEM_ENCHANTMENT_TYPE_PRISMATIC_SOCKET, itemTarget, LOG_ERROR, LOG_GM, m_caster, m_spellInfo, MAX_SPELL_ITEM_ENCHANTMENT_EFFECTS, ItemTemplate::Name1, PRISMATIC_ENCHANTMENT_SLOT, rbac::RBAC_PERM_LOG_GM_TRADE, Player::RemoveTradeableItem(), Item::SetEnchantment(), SPELL_EFFECT_ENCHANT_ITEM_PRISMATIC, SPELL_EFFECT_HANDLE_HIT_TARGET, SpellInfo::SpellName, sSpellItemEnchantmentStore, Object::ToPlayer(), and SpellItemEnchantmentEntry::type.

◆ EffectEnchantItemTmp()

void Spell::EffectEnchantItemTmp ( SpellEffIndex  effIndex)
2986{
2988 return;
2989
2990 if (!m_caster->IsPlayer())
2991 return;
2992
2993 Player* p_caster = m_caster->ToPlayer();
2994
2995 // Rockbiter Weapon apply to both weapon
2996 if (!itemTarget)
2997 return;
2999 {
3000 uint32 spell_id = 0;
3001
3002 // enchanting spell selected by calculated damage-per-sec stored in Effect[1] base value
3003 // Note: damage calculated (correctly) with rounding int32(float(v)) but
3004 // RW enchantments applied damage int32(float(v)+0.5), this create 0..1 difference sometime
3005 switch (damage)
3006 {
3007 // Rank 1
3008 case 2:
3009 spell_id = 36744;
3010 break; // 0% [ 7% == 2, 14% == 2, 20% == 2]
3011 // Rank 2
3012 case 4:
3013 spell_id = 36753;
3014 break; // 0% [ 7% == 4, 14% == 4]
3015 case 5:
3016 spell_id = 36751;
3017 break; // 20%
3018 // Rank 3
3019 case 6:
3020 spell_id = 36754;
3021 break; // 0% [ 7% == 6, 14% == 6]
3022 case 7:
3023 spell_id = 36755;
3024 break; // 20%
3025 // Rank 4
3026 case 9:
3027 spell_id = 36761;
3028 break; // 0% [ 7% == 6]
3029 case 10:
3030 spell_id = 36758;
3031 break; // 14%
3032 case 11:
3033 spell_id = 36760;
3034 break; // 20%
3035 default:
3036 LOG_ERROR("spells.effect", "Spell::EffectEnchantItemTmp: Damage {} not handled in S'RW", damage);
3037 return;
3038 }
3039
3040 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spell_id);
3041 if (!spellInfo)
3042 {
3043 LOG_ERROR("spells.effect", "Spell::EffectEnchantItemTmp: unknown spell id {}", spell_id);
3044 return;
3045 }
3046
3047 for (int j = BASE_ATTACK; j <= OFF_ATTACK; ++j)
3048 {
3049 if (Item* item = p_caster->GetWeaponForAttack(WeaponAttackType(j)))
3050 {
3051 if (item->IsFitToSpellRequirements(m_spellInfo))
3052 {
3053 Spell* spell = new Spell(m_caster, spellInfo, TRIGGERED_FULL_MASK);
3054 SpellCastTargets targets;
3055 targets.SetItemTarget(item);
3056 spell->prepare(&targets);
3057 }
3058 }
3059 }
3060 return;
3061 }
3062 if (!itemTarget)
3063 return;
3064
3065 uint32 enchant_id = m_spellInfo->Effects[effIndex].MiscValue;
3066
3067 if (!enchant_id)
3068 {
3069 LOG_ERROR("spells.effect", "Spell {} Effect {} (SPELL_EFFECT_ENCHANT_ITEM_TEMPORARY) have 0 as enchanting id", m_spellInfo->Id, effIndex);
3070 return;
3071 }
3072
3073 SpellItemEnchantmentEntry const* pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id);
3074 if (!pEnchant)
3075 {
3076 LOG_ERROR("spells.effect", "Spell {} Effect {} (SPELL_EFFECT_ENCHANT_ITEM_TEMPORARY) have not existed enchanting id {} ", m_spellInfo->Id, effIndex, enchant_id);
3077 return;
3078 }
3079
3080 // select enchantment duration
3081 uint32 duration;
3082
3083 // rogue family enchantments exception by duration
3084 if (m_spellInfo->Id == 38615)
3085 duration = 1800; // 30 mins
3086 // other rogue family enchantments always 1 hour (some have spell damage=0, but some have wrong data in EffBasePoints)
3088 duration = 3600; // 1 hour
3089 // shaman family enchantments
3091 duration = 1800; // 30 mins
3092 // other cases with this SpellVisual already selected
3093 else if (m_spellInfo->SpellVisual[0] == 215)
3094 duration = 1800; // 30 mins
3095 // some fishing pole bonuses except Glow Worm which lasts full hour
3096 else if (m_spellInfo->SpellVisual[0] == 563 && m_spellInfo->Id != 64401)
3097 duration = 600; // 10 mins
3098 // shaman rockbiter enchantments
3099 else if (m_spellInfo->SpellVisual[0] == 0)
3100 duration = 1800; // 30 mins
3101 else if (m_spellInfo->Id == 29702)
3102 duration = 300; // 5 mins
3103 else if (m_spellInfo->Id == 37360)
3104 duration = 300; // 5 mins
3105 // default case
3106 else
3107 duration = 3600; // 1 hour
3108
3109 // item can be in trade slot and have owner diff. from caster
3110 Player* item_owner = itemTarget->GetOwner();
3111 if (!item_owner)
3112 return;
3113
3114 // remove old enchanting before applying new if equipped
3116
3117 itemTarget->SetEnchantment(TEMP_ENCHANTMENT_SLOT, enchant_id, duration * 1000, pEnchant->charges, m_caster->GetGUID());
3118
3119 // add new enchanting if equipped
3121
3122 if (item_owner != p_caster && p_caster->GetSession()->HasPermission(rbac::RBAC_PERM_LOG_GM_TRADE))
3123 {
3124 LOG_GM(p_caster->GetSession()->GetAccountId(), "GM {} (Account: {}) enchanting(temp): {} (SpellID: {} EncID: {}) on {}'s item: {} (Entry: {})",
3125 p_caster->GetName(), p_caster->GetSession()->GetAccountId(),
3126 m_spellInfo->SpellName[0], m_spellInfo->Id, enchant_id,
3127 item_owner->GetName(), itemTarget->GetTemplate()->Name1, itemTarget->GetEntry());
3128 }
3129
3130 item_owner->RemoveTradeableItem(itemTarget);
3132}
@ SPELLFAMILY_SHAMAN
Definition SharedDefines.h:3795
WeaponAttackType
Definition Unit.h:214
Definition Spell.h:121
std::array< uint32, 2 > SpellVisual
Definition SpellInfo.h:403
SpellCastResult prepare(SpellCastTargets const *targets, AuraEffect const *triggeredByAura=nullptr)
Definition Spell.cpp:3424

References Player::ApplyEnchantment(), BASE_ATTACK, SpellItemEnchantmentEntry::charges, Item::ClearSoulboundTradeable(), damage, effectHandleMode, SpellInfo::Effects, WorldSession::GetAccountId(), Object::GetEntry(), Object::GetGUID(), WorldObject::GetName(), Item::GetOwner(), Player::GetSession(), Item::GetTemplate(), Player::GetWeaponForAttack(), WorldSession::HasPermission(), SpellInfo::Id, Object::IsPlayer(), itemTarget, LOG_ERROR, LOG_GM, m_caster, m_spellInfo, ItemTemplate::Name1, OFF_ATTACK, prepare(), rbac::RBAC_PERM_LOG_GM_TRADE, Player::RemoveTradeableItem(), Item::SetEnchantment(), SpellCastTargets::SetItemTarget(), SPELL_EFFECT_HANDLE_HIT_TARGET, SPELLFAMILY_ROGUE, SPELLFAMILY_SHAMAN, SpellInfo::SpellFamilyFlags, SpellInfo::SpellFamilyName, SpellInfo::SpellName, SpellInfo::SpellVisual, sSpellItemEnchantmentStore, sSpellMgr, TEMP_ENCHANTMENT_SLOT, Object::ToPlayer(), and TRIGGERED_FULL_MASK.

◆ EffectEnergize()

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

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

◆ EffectEnergizePct()

void Spell::EffectEnergizePct ( SpellEffIndex  effIndex)
1996{
1998 return;
1999
2000 if (!unitTarget)
2001 return;
2002 if (!unitTarget->IsAlive())
2003 return;
2004
2006 {
2008 return;
2009 }
2010
2011 if (m_spellInfo->Effects[effIndex].MiscValue < 0 || m_spellInfo->Effects[effIndex].MiscValue >= int8(MAX_POWERS))
2012 return;
2013
2014 Powers power = Powers(m_spellInfo->Effects[effIndex].MiscValue);
2015
2017 return;
2018
2019 uint32 maxPower = unitTarget->GetMaxPower(power);
2020 if (maxPower == 0)
2021 return;
2022
2023 uint32 gain = CalculatePct(maxPower, damage);
2025}
@ UNIT_STATE_ISOLATED
Definition UnitDefines.h:186

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

◆ EffectEnvironmentalDMG()

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

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

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

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

◆ EffectForceDeselect()

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

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

◆ EffectGameObjectDamage()

void Spell::EffectGameObjectDamage ( SpellEffIndex  effIndex)
5933{
5935 return;
5936
5937 if (!gameObjTarget)
5938 return;
5939
5940 Unit* caster = m_originalCaster;
5941 if (!caster)
5942 return;
5943
5944 FactionTemplateEntry const* casterFaction = caster->GetFactionTemplateEntry();
5946 // Do not allow to damage GO's of friendly factions (ie: Wintergrasp Walls/Ulduar Storm Beacons)
5947 if ((casterFaction && targetFaction && !casterFaction->IsFriendlyTo(*targetFaction)) || !targetFaction)
5949}
DBCStorage< FactionTemplateEntry > sFactionTemplateStore(FactionTemplateEntryfmt)
void ModifyHealth(int32 change, Unit *attackerOrHealer=nullptr, uint32 spellId=0)
Definition GameObject.cpp:2297
FactionTemplateEntry const * GetFactionTemplateEntry() const
Definition Unit.cpp:7069
Definition DBCStructure.h:939
bool IsFriendlyTo(FactionTemplateEntry const &entry) const
Definition DBCStructure.h:951

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

◆ EffectGameObjectRepair()

void Spell::EffectGameObjectRepair ( SpellEffIndex  effIndex)

◆ EffectGameObjectSetDestructionState()

void Spell::EffectGameObjectSetDestructionState ( SpellEffIndex  effIndex)
5963{
5965 return;
5966
5968 return;
5969
5972}
GameObjectDestructibleState
Definition SharedDefines.h:1630
void SetDestructibleState(GameObjectDestructibleState state, Player *eventInvoker=nullptr, bool setHealth=false)
Definition GameObject.cpp:2360

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

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_damageBeforeTakenMods, m_originalCaster, m_originalCasterGUID, m_spellInfo, Unit::RemoveAura(), Unit::RemoveAurasDueToSpell(), SPELL_AURA_MOD_HEALING_DONE_PERCENT, 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)
3713{
3715 return;
3716
3717 if (!unitTarget || !unitTarget->IsAlive())
3718 return;
3719
3721 {
3723 return;
3724 }
3725
3726 int32 addhealth = 0;
3727
3728 // damage == 0 - heal for caster max health
3729 if (damage == 0)
3730 addhealth = m_caster->GetMaxHealth();
3731 else
3732 addhealth = unitTarget->GetMaxHealth() - unitTarget->GetHealth();
3733
3734 m_healing += addhealth;
3735}
uint32 GetMaxHealth() const
Definition Unit.h:1109

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

◆ EffectHealMechanical()

void Spell::EffectHealMechanical ( SpellEffIndex  effIndex)

◆ EffectHealPct()

◆ EffectHealthLeech()

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

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

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

◆ EffectInstaKill()

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

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

◆ EffectInterruptCast()

void Spell::EffectInterruptCast ( SpellEffIndex  effIndex)
Todo:
: not all spells that used this effect apply cooldown at school spells
3738{
3740 return;
3741
3742 if (!unitTarget || !unitTarget->IsAlive())
3743 return;
3744
3746 // also exist case: apply cooldown to interrupted cast only and to all spells
3747 // there is no CURRENT_AUTOREPEAT_SPELL spells that can be interrupted
3749 {
3751 {
3752 SpellInfo const* curSpellInfo = spell->m_spellInfo;
3753 // check if we can interrupt spell
3754 if ((spell->getState() == SPELL_STATE_CASTING
3755 || (spell->getState() == SPELL_STATE_PREPARING && spell->GetCastTime() > 0.0f))
3759 {
3760 if (m_originalCaster)
3761 {
3763 unitTarget->ProhibitSpellSchool(curSpellInfo->GetSchoolMask(), duration/*spellInfo->GetDuration()*/);
3764 }
3765 ExecuteLogEffectInterruptCast(effIndex, unitTarget, curSpellInfo->Id);
3767 }
3768 }
3769 }
3770}
@ CHANNEL_INTERRUPT_FLAG_INTERRUPT
Definition SpellDefines.h:37
@ SPELL_INTERRUPT_FLAG_INTERRUPT
Definition SpellDefines.h:29
#define CURRENT_FIRST_NON_MELEE_SPELL
Definition Unit.h:561
CurrentSpellTypes
Definition Unit.h:554
@ CURRENT_CHANNELED_SPELL
Definition Unit.h:557
@ CURRENT_AUTOREPEAT_SPELL
Definition Unit.h:558
uint32 ChannelInterruptFlags
Definition SpellInfo.h:378
uint32 InterruptFlags
Definition SpellInfo.h:376
void ExecuteLogEffectInterruptCast(uint8 effIndex, Unit *victim, uint32 spellId)
Definition Spell.cpp:5093
void InterruptSpell(CurrentSpellTypes spellType, bool withDelayed=true, bool withInstant=true, bool bySelf=false)
Definition Unit.cpp:4262
int32 CalcSpellDuration(SpellInfo const *spellProto)
Definition Unit.cpp:11622
virtual void ProhibitSpellSchool(SpellSchoolMask, uint32)
Definition Unit.h:1584

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)
1071{
1073 return;
1074
1075 if (m_caster->IsInFlight())
1076 return;
1077
1078 if (!unitTarget)
1079 return;
1080
1081 float speedXY, speedZ;
1082 CalculateJumpSpeeds(effIndex, m_caster->GetExactDist2d(unitTarget), speedXY, speedZ);
1083 m_caster->GetMotionMaster()->MoveJump(*unitTarget, speedXY, speedZ);
1084
1085 if (m_caster->IsPlayer())
1086 {
1087 sScriptMgr->AnticheatSetUnderACKmount(m_caster->ToPlayer());
1088 }
1089}
void MoveJump(Position const &pos, float speedXY, float speedZ, uint32 id=0)
Definition MotionMaster.h:256
void CalculateJumpSpeeds(uint8 i, float dist, float &speedxy, float &speedz)
Definition SpellEffects.cpp:1154
float GetExactDist2d(const float x, const float y) const
Definition Position.h:170

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

◆ EffectJumpDest()

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

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

◆ EffectKillCredit()

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

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

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

◆ EffectKnockBack()

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

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

◆ EffectLeap()

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

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

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

◆ EffectLearnPetSpell()

void Spell::EffectLearnPetSpell ( SpellEffIndex  effIndex)
3305{
3307 return;
3308
3309 if (!unitTarget)
3310 return;
3311
3312 if (unitTarget->ToPlayer())
3313 {
3314 EffectLearnSpell(effIndex);
3315 return;
3316 }
3317 Pet* pet = unitTarget->ToPet();
3318 if (!pet)
3319 return;
3320
3321 SpellInfo const* learn_spellproto = sSpellMgr->GetSpellInfo(m_spellInfo->Effects[effIndex].TriggerSpell);
3322 if (!learn_spellproto)
3323 return;
3324
3325 pet->learnSpell(learn_spellproto->Id);
3327 pet->GetOwner()->PetSpellInitialize();
3328}
bool learnSpell(uint32 spell_id)
Definition Pet.cpp:1897
void EffectLearnSpell(SpellEffIndex effIndex)
Definition SpellEffects.cpp:2565

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)
2797{
2799 return;
2800
2801 if (!unitTarget->IsPlayer())
2802 return;
2803
2804 if (damage < 0)
2805 return;
2806
2807 uint32 skillid = m_spellInfo->Effects[effIndex].MiscValue;
2808 uint16 skillval = unitTarget->ToPlayer()->GetPureSkillValue(skillid);
2809 unitTarget->ToPlayer()->SetSkill(skillid, m_spellInfo->Effects[effIndex].CalcValue(), skillval ? skillval : 1, damage * 75);
2810}
uint16 GetPureSkillValue(uint32 skill) const
Definition Player.cpp:5524
void SetSkill(uint16 id, uint16 step, uint16 currVal, uint16 maxVal)
Definition Player.cpp:5333

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

◆ EffectLearnSpell()

void Spell::EffectLearnSpell ( SpellEffIndex  effIndex)
2566{
2568 return;
2569
2570 if (!unitTarget)
2571 return;
2572
2573 if (!unitTarget->IsPlayer())
2574 {
2575 if (unitTarget->ToPet())
2576 EffectLearnPetSpell(effIndex);
2577 return;
2578 }
2579
2580 Player* player = unitTarget->ToPlayer();
2581
2582 uint32 spellToLearn = (m_spellInfo->Id == 483 || m_spellInfo->Id == 55884) ? damage : m_spellInfo->Effects[effIndex].TriggerSpell;
2583 player->learnSpell(spellToLearn);
2584
2585 LOG_DEBUG("spells.aura", "Spell: Player {} has learned spell {} from Npc {}",
2586 player->GetGUID().ToString(), spellToLearn, m_caster->GetGUID().ToString());
2587}
void learnSpell(uint32 spellId, bool temporary=false, bool learnFromSkill=false)
Definition Player.cpp:3300
void EffectLearnPetSpell(SpellEffIndex effIndex)
Definition SpellEffects.cpp:3304

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

Referenced by EffectLearnPetSpell().

◆ EffectMilling()

void Spell::EffectMilling ( SpellEffIndex  effIndex)
5534{
5536 return;
5537
5538 if (!m_caster->IsPlayer())
5539 return;
5540
5541 Player* p_caster = m_caster->ToPlayer();
5543 return;
5544
5545 if (itemTarget->GetCount() < 5)
5546 return;
5547
5548 if (sWorld->getBoolConfig(CONFIG_SKILL_MILLING))
5549 {
5550 uint32 SkillValue = p_caster->GetPureSkillValue(SKILL_INSCRIPTION);
5551 uint32 reqSkillValue = itemTarget->GetTemplate()->RequiredSkillRank;
5552 p_caster->UpdateGatherSkill(SKILL_INSCRIPTION, SkillValue, reqSkillValue);
5553 }
5554
5556}
@ LOOT_MILLING
Definition LootMgr.h:87
@ CONFIG_SKILL_MILLING
Definition WorldConfig.h:47
void SendLoot(ObjectGuid guid, LootType loot_type)
Definition Player.cpp:7822
bool UpdateGatherSkill(uint32 SkillId, uint32 SkillValue, uint32 RedLevel, uint32 Multiplicator=1)
Definition PlayerUpdates.cpp:760

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

◆ EffectModifyThreatPercent()

void Spell::EffectModifyThreatPercent ( SpellEffIndex  effIndex)
5366{
5368 return;
5369
5370 if (!unitTarget)
5371 return;
5372
5374}
void ModifyThreatByPercent(Unit *target, int32 percent)
Definition ThreatManager.h:150

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

◆ EffectNULL()

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

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

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

◆ EffectParry()

void Spell::EffectParry ( SpellEffIndex  effIndex)
4688{
4690 return;
4691
4692 if (m_caster->IsPlayer())
4693 m_caster->ToPlayer()->SetCanParry(true);
4694}
void SetCanParry(bool value)
Definition Player.cpp:13253

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

◆ EffectPersistentAA()

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

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

◆ EffectPickPocket()

void Spell::EffectPickPocket ( SpellEffIndex  effIndex)

◆ EffectPlayMusic()

void Spell::EffectPlayMusic ( SpellEffIndex  effIndex)
6127{
6129 return;
6130
6131 if (!unitTarget)
6132 return;
6133
6134 Player* player = unitTarget->ToPlayer();
6135 if (!player)
6136 {
6137 return;
6138 }
6139
6140 uint32 soundid = m_spellInfo->Effects[effIndex].MiscValue;
6141
6142 if (!sSoundEntriesStore.LookupEntry(soundid))
6143 {
6144 LOG_ERROR("spells.effect", "EffectPlayMusic: Sound (Id: {}) not exist in spell {}.", soundid, m_spellInfo->Id);
6145 return;
6146 }
6147
6149}
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)
6180{
6182 return;
6183
6184 if (!unitTarget)
6185 return;
6186
6187 Player* player = unitTarget->ToPlayer();
6188 if (!player)
6189 {
6190 return;
6191 }
6192
6193 switch (m_spellInfo->Id)
6194 {
6195 case 58730: // Restricted Flight Area
6196 case 58600: // Restricted Flight Area
6198 break;
6199 default:
6200 break;
6201 }
6202
6203 uint32 soundId = m_spellInfo->Effects[effIndex].MiscValue;
6204
6205 if (!sSoundEntriesStore.LookupEntry(soundId))
6206 {
6207 LOG_ERROR("spells.effect", "EffectPlayerSound: Sound (Id: {}) not exist in spell {}.", soundId, m_spellInfo->Id);
6208 return;
6209 }
6210
6211 player->PlayDirectSound(soundId, player);
6212}
@ LANG_ZONE_NOFLYZONE
Definition Language.h:764
Definition Chat.h:37
void SendNotification(std::string_view str)
Definition Chat.cpp:113
void PlayDirectSound(uint32 sound_id, Player *target=nullptr)
Definition Object.cpp:2956

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

◆ EffectPowerBurn()

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

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

◆ EffectPowerDrain()

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

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

◆ EffectProficiency()

void Spell::EffectProficiency ( SpellEffIndex  effIndex)
2320{
2322 return;
2323
2324 if (!m_caster->IsPlayer())
2325 return;
2326 Player* p_target = m_caster->ToPlayer();
2327
2329 if (m_spellInfo->EquippedItemClass == ITEM_CLASS_WEAPON && !(p_target->GetWeaponProficiency() & subClassMask))
2330 {
2331 p_target->AddWeaponProficiency(subClassMask);
2333 }
2334 if (m_spellInfo->EquippedItemClass == ITEM_CLASS_ARMOR && !(p_target->GetArmorProficiency() & subClassMask))
2335 {
2336 p_target->AddArmorProficiency(subClassMask);
2338 }
2339}
uint32 GetArmorProficiency() const
Definition Player.h:1381
void SendProficiency(ItemClass itemClass, uint32 itemSubclassMask)
Definition Player.cpp:10106
uint32 GetWeaponProficiency() const
Definition Player.h:1380
void AddArmorProficiency(uint32 newflag)
Definition Player.h:1379
void AddWeaponProficiency(uint32 newflag)
Definition Player.h:1378
int32 EquippedItemSubClassMask
Definition SpellInfo.h:400

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

◆ EffectProspecting()

void Spell::EffectProspecting ( SpellEffIndex  effIndex)

◆ EffectPull()

void Spell::EffectPull ( SpellEffIndex  effIndex)
Todo:
: create a proper pull towards distract spell center for distract
2709{
2711 EffectNULL(effIndex);
2712}
void EffectNULL(SpellEffIndex effIndex)
Definition SpellEffects.cpp:239

References EffectNULL().

◆ EffectPullTowards()

void Spell::EffectPullTowards ( SpellEffIndex  effIndex)
5139{
5141 return;
5142
5143 if (!unitTarget)
5144 return;
5145
5146 Position pos;
5147 if (m_spellInfo->Effects[effIndex].Effect == SPELL_EFFECT_PULL_TOWARDS_DEST)
5148 {
5149 if (m_targets.HasDst())
5150 pos.Relocate(*destTarget);
5151 else
5152 return;
5153 }
5154 else //if (m_spellInfo->Effects[i].Effect == SPELL_EFFECT_PULL_TOWARDS)
5155 {
5156 // Xinef: Increase Z position a little bit, should protect from falling through textures
5158 }
5159
5160 float speedXY = float(m_spellInfo->Effects[effIndex].MiscValue) ? float(m_spellInfo->Effects[effIndex].MiscValue) * 0.1f : 30.f;
5161 float speedZ = unitTarget->GetDistance(pos) / speedXY * 0.5f * Movement::gravity;
5162
5163 unitTarget->GetMotionMaster()->MoveJump(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), speedXY, speedZ);
5164
5165 if (unitTarget->IsPlayer())
5166 {
5167 sScriptMgr->AnticheatSetUnderACKmount(unitTarget->ToPlayer());
5168 }
5169}
@ SPELL_EFFECT_PULL_TOWARDS_DEST
Definition SharedDefines.h:911

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

◆ EffectQuestClear()

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

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

◆ EffectQuestComplete()

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

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

◆ EffectQuestFail()

void Spell::EffectQuestFail ( SpellEffIndex  effIndex)
5750{
5752 return;
5753
5754 if (!unitTarget)
5755 return;
5756
5757 if (Player* player = unitTarget->ToPlayer())
5758 {
5759 player->FailQuest(m_spellInfo->Effects[effIndex].MiscValue);
5760 }
5761}

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

◆ EffectQuestStart()

void Spell::EffectQuestStart ( SpellEffIndex  effIndex)
5764{
5766 return;
5767
5768 if (!unitTarget)
5769 return;
5770
5771 Player* player = unitTarget->ToPlayer();
5772 if (!player)
5773 return;
5774
5775 if (Quest const* quest = sObjectMgr->GetQuestTemplate(m_spellInfo->Effects[effIndex].MiscValue))
5776 {
5777 if (!player->CanTakeQuest(quest, false))
5778 return;
5779
5780 if (quest->IsAutoAccept() && player->CanAddQuest(quest, false))
5781 player->AddQuestAndCheckCompletion(quest, player);
5782
5783 player->PlayerTalkClass->SendQuestGiverQuestDetails(quest, player->GetGUID(), true);
5784 }
5785}
void SendQuestGiverQuestDetails(Quest const *quest, ObjectGuid npcGUID, bool activateAccept) const
Definition GossipDef.cpp:388
bool CanAddQuest(Quest const *quest, bool msg)
Definition PlayerQuest.cpp:266
void AddQuestAndCheckCompletion(Quest const *quest, Object *questGiver)
Definition PlayerQuest.cpp:423
PlayerMenu * PlayerTalkClass
Definition Player.h:2278

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)
6269{
6271 return;
6272
6273 if (!unitTarget || !unitTarget->IsPlayer())
6274 return;
6275
6276 Player* player = m_caster->ToPlayer();
6277
6278 if (!player)
6279 return;
6280
6281 uint32 item_id = m_spellInfo->Effects[EFFECT_0].ItemType;
6282
6283 ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(item_id);
6284 if (!pProto)
6285 {
6286 player->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, nullptr, nullptr);
6287 return;
6288 }
6289
6290 if (Item* pItem = player->GetItemByEntry(item_id))
6291 {
6292 for (int x = 0; x < MAX_ITEM_PROTO_SPELLS; ++x)
6293 pItem->SetSpellCharges(x, pProto->Spells[x].SpellCharges);
6294 pItem->SetState(ITEM_CHANGED, player);
6295 }
6296}

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

◆ EffectRedirectThreat()

void Spell::EffectRedirectThreat ( SpellEffIndex  effIndex)
5924{
5926 return;
5927
5928 if (unitTarget)
5930}
void RegisterRedirectThreat(uint32 spellId, ObjectGuid const &victim, uint32 pct)
== REDIRECT SYSTEM ==
Definition ThreatManager.cpp:826

References damage, effectHandleMode, Object::GetGUID(), Unit::GetThreatMgr(), SpellInfo::Id, m_caster, m_spellInfo, ThreatManager::RegisterRedirectThreat(), SPELL_EFFECT_HANDLE_HIT_TARGET, and unitTarget.

◆ EffectRemoveAura()

void Spell::EffectRemoveAura ( SpellEffIndex  effIndex)
6215{
6217 return;
6218
6219 if (!unitTarget)
6220 return;
6221 // there may be need of specifying casterguid of removed auras
6222 unitTarget->RemoveAurasDueToSpell(m_spellInfo->Effects[effIndex].TriggerSpell);
6223}

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

◆ EffectRenamePet()

void Spell::EffectRenamePet ( SpellEffIndex  effIndex)
6115{
6117 return;
6118
6119 if (!unitTarget || !unitTarget->IsCreature() ||
6121 return;
6122
6124}
@ UNIT_CAN_BE_RENAMED
Definition UnitDefines.h:152
@ UNIT_FIELD_BYTES_2
Definition UpdateFields.h:161
void SetByteFlag(uint16 index, uint8 offset, uint8 newFlag)
Definition Object.cpp:893
PetType getPetType() const
Definition Pet.h:52

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

◆ EffectReputation()

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

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

◆ EffectResurrect()

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

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
5215{
5217 return;
5218
5219 if (damage < 0)
5220 return;
5221
5222 Player* player = m_caster->ToPlayer();
5223 if (!player)
5224 {
5225 return;
5226 }
5227
5228 Pet* pet = player->GetPet();
5229 if (!pet)
5230 {
5231 // Position passed to SummonPet is irrelevant with current implementation,
5232 // pet will be relocated without using these coords in Pet::LoadPetFromDB
5233 player->SummonPet(0, 0.0f, 0.0f, 0.0f, 0.0f, SUMMON_PET, 0ms, damage);
5234 return;
5235 }
5236
5238 if (pet->IsAlive())
5239 {
5240 return;
5241 }
5242
5243 // Reposition the pet's corpse before reviving so as not to grab aggro
5244 // We can use a different, more accurate version of GetClosePoint() since we have a pet
5245 float x, y, z; // Will be used later to reposition the pet if we have one
5246 player->GetClosePoint(x, y, z, pet->GetCombatReach(), PET_FOLLOW_DIST, pet->GetFollowAngle());
5247 pet->NearTeleportTo(x, y, z, player->GetOrientation());
5248 pet->Relocate(x, y, z, player->GetOrientation()); // This is needed so SaveStayPosition() will get the proper coords.
5252 pet->ClearUnitState(uint32(UNIT_STATE_ALL_STATE & ~(UNIT_STATE_POSSESSED))); // xinef: just in case
5254 pet->SetDisplayId(pet->GetNativeDisplayId());
5255
5256 // xinef: restore movement
5257 if (auto ci = pet->GetCharmInfo())
5258 {
5259 ci->SetIsAtStay(false);
5260 ci->SetIsFollowing(false);
5261 }
5262
5264}
constexpr float PET_FOLLOW_DIST
Definition PetDefines.h:206
@ SUMMON_PET
Definition PetDefines.h:32
@ UNIT_DYNFLAG_NONE
Definition SharedDefines.h:3353
@ UNIT_STATE_POSSESSED
Definition UnitDefines.h:189
@ UNIT_STATE_ALL_STATE
Definition UnitDefines.h:227
float GetFollowAngle() const override
Definition TemporarySummon.h:93
void setDeathState(DeathState s, bool despawn=false) override
A creature can be in 4 different states: Alive, JustDied, Corpse, and JustRespawned....
Definition Pet.cpp:626
void SetDisplayId(uint32 modelId, float displayScale=1.f) override
Definition Pet.cpp:2407
Pet * SummonPet(uint32 entry, float x, float y, float z, float ang, PetType petType, Milliseconds duration=0ms, uint32 healthPct=0)
Definition Player.cpp:8993
void ReplaceAllDynamicFlags(uint32 flag) override
Definition Unit.h:769
void SetHealth(uint32 val)
Definition Unit.cpp:12374
uint32 GetNativeDisplayId() const
Definition Unit.h:1980
void RemoveUnitFlag(UnitFlags flags)
UnitFlags available in UnitDefines.h.
Definition Unit.h:749
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:2765

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

◆ EffectSanctuary()

void Spell::EffectSanctuary ( SpellEffIndex  effIndex)
4027{
4029 return;
4030
4031 if (!unitTarget)
4032 return;
4033
4035
4037 {
4038 // stop all pve combat for players outside dungeons, suppress pvp combat
4039 unitTarget->CombatStop(false, false);
4040 }
4041 else
4042 {
4043 // in dungeons (or for nonplayers), reset this unit on all enemies' threat lists
4044 for (auto const& pair : unitTarget->GetThreatMgr().GetThreatenedByMeList())
4045 pair.second->ScaleThreat(0.0f);
4046 }
4047
4048 UnitList targets;
4049 Acore::AnyUnfriendlyUnitInObjectRangeCheck u_check(unitTarget, unitTarget, unitTarget->GetVisibilityRange()); // no VISIBILITY_COMPENSATION, distance is enough
4052 for (UnitList::iterator iter = targets.begin(); iter != targets.end(); ++iter)
4053 {
4054 if (!(*iter)->HasUnitState(UNIT_STATE_CASTING))
4055 continue;
4056
4058 {
4059 if ((*iter)->GetCurrentSpell(i) && (*iter)->GetCurrentSpell(i)->m_targets.GetUnitTargetGUID() == unitTarget->GetGUID())
4060 {
4061 SpellInfo const* si = (*iter)->GetCurrentSpell(i)->GetSpellInfo();
4062 if (si->HasAttribute(SPELL_ATTR6_IGNORE_PHASE_SHIFT) && (*iter)->IsCreature())
4063 {
4064 Creature* c = (*iter)->ToCreature();
4065 if ((!c->IsPet() && c->GetCreatureTemplate()->rank == CREATURE_ELITE_WORLDBOSS) || c->isWorldBoss() || c->IsDungeonBoss())
4066 continue;
4067 }
4068 bool interrupt = false; // pussywizard: skip spells that don't target units, but casted on unit (eg. TARGET_DEST_TARGET_ENEMY)
4069 for (uint8 j = 0; j < MAX_SPELL_EFFECTS; ++j)
4070 if (si->Effects[j].Effect && (si->Effects[j].GetUsedTargetObjectType() == TARGET_OBJECT_TYPE_UNIT || si->Effects[j].GetUsedTargetObjectType() == TARGET_OBJECT_TYPE_UNIT_AND_DEST))
4071 {
4072 // at least one effect truly targets an unit, interrupt the spell
4073 interrupt = true;
4074 break;
4075 }
4076 if (interrupt)
4077 (*iter)->InterruptSpell(CurrentSpellTypes(i), false);
4078 }
4079 }
4080 }
4081
4082 // Xinef: Set last sanctuary time
4084}
#define CURRENT_MAX_SPELL
Definition Unit.h:562
void EvaluateSuppressed(bool canExpire=false)
Definition ThreatManager.cpp:374
void CombatStop(bool includingCast=false, bool mutualPvP=true)
Definition Unit.cpp:7504

References Unit::CombatStop(), CREATURE_ELITE_WORLDBOSS, CURRENT_FIRST_NON_MELEE_SPELL, CURRENT_MAX_SPELL, effectHandleMode, SpellInfo::Effects, ThreatManager::EvaluateSuppressed(), Creature::GetCreatureTemplate(), GameTime::GetGameTimeMS(), Object::GetGUID(), WorldObject::GetMap(), ThreatManager::GetThreatenedByMeList(), Unit::GetThreatMgr(), WorldObject::GetVisibilityRange(), SpellInfo::HasAttribute(), Unit::InterruptSpell(), Map::IsDungeon(), Creature::IsDungeonBoss(), Unit::IsPet(), Object::IsPlayer(), Creature::isWorldBoss(), Unit::m_lastSanctuaryTime, MAX_SPELL_EFFECTS, CreatureTemplate::rank, SPELL_ATTR6_IGNORE_PHASE_SHIFT, SPELL_EFFECT_HANDLE_HIT_TARGET, TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT_AND_DEST, Object::ToCreature(), UNIT_STATE_CASTING, unitTarget, and Cell::VisitObjects().

◆ EffectSchoolDMG()

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

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

◆ EffectScriptEffect()

void Spell::EffectScriptEffect ( SpellEffIndex  effIndex)
Todo:
: we must implement hunter pet summon at login there (spell 6962)
3824{
3826 return;
3827
3829
3831 {
3833 {
3834 switch (m_spellInfo->Id)
3835 {
3836 // Shadow Flame (All script effects, not just end ones to prevent player from dodging the last triggered spell)
3837 case 22539:
3838 case 22972:
3839 case 22975:
3840 case 22976:
3841 case 22977:
3842 case 22978:
3843 case 22979:
3844 case 22980:
3845 case 22981:
3846 case 22982:
3847 case 22983:
3848 case 22984:
3849 case 22985:
3850 {
3851 if (!unitTarget || !unitTarget->IsAlive())
3852 return;
3853
3854 // Onyxia Scale Cloak
3855 if (unitTarget->HasAura(22683))
3856 return;
3857
3858 // Shadow Flame
3859 m_caster->CastSpell(unitTarget, 22682, true);
3860 return;
3861 }
3862 // Plant Warmaul Ogre Banner
3863 case 32307:
3864 if (Player* caster = m_caster->ToPlayer())
3865 {
3866 caster->RewardPlayerAndGroupAtEvent(18388, unitTarget);
3867 if (Creature* target = unitTarget->ToCreature())
3868 {
3869 target->setDeathState(DeathState::Corpse);
3870 target->RemoveCorpse();
3871 }
3872 }
3873 break;
3874 // SOTA defender teleport
3875 case 54640:
3876 {
3877 if (Player* player = unitTarget->ToPlayer())
3878 if (player->GetBattleground() && player->GetBattleground()->GetBgTypeID(true) == BATTLEGROUND_SA)
3879 {
3880 if (GameObject* dportal = player->FindNearestGameObject(192819, 10.0f))
3881 {
3882 BattlegroundSA* bg = ((BattlegroundSA*)player->GetBattleground());
3883 bg->DefendersPortalTeleport(dportal, player);
3884 }
3885 }
3886 return;
3887 }
3888 /*// Mug Transformation
3889 case 41931:
3890 {
3891 if (!m_caster->IsPlayer())
3892 return;
3893
3894 uint8 bag = 19;
3895 uint8 slot = 0;
3896 Item* item = nullptr;
3897
3898 while (bag) // 256 = 0 due to var type
3899 {
3900 item = m_caster->ToPlayer()->GetItemByPos(bag, slot);
3901 if (item && item->GetEntry() == 38587)
3902 break;
3903
3904 ++slot;
3905 if (slot == 39)
3906 {
3907 slot = 0;
3908 ++bag;
3909 }
3910 }
3911 if (bag)
3912 {
3913 if (m_caster->ToPlayer()->GetItemByPos(bag, slot)->GetCount() == 1) m_caster->ToPlayer()->RemoveItem(bag, slot, true);
3914 else m_caster->ToPlayer()->GetItemByPos(bag, slot)->SetCount(m_caster->ToPlayer()->GetItemByPos(bag, slot)->GetCount()-1);
3915 // Spell 42518 (Braufest - Gratisprobe des Braufest herstellen)
3916 m_caster->CastSpell(m_caster, 42518, true);
3917 return;
3918 }
3919 break;
3920 }*/
3921 // Roll Dice - Decahedral Dwarven Dice
3922 case 47770:
3923 {
3924 char buf[128];
3925 const char* gender = "his";
3926 if (m_caster->getGender() > 0)
3927 gender = "her";
3928 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));
3929 m_caster->TextEmote(buf);
3930 break;
3931 }
3932 case 52173: // Coyote Spirit Despawn
3933 case 60243: // Blood Parrot Despawn
3936 return;
3937 case 57347: // Retrieving (Wintergrasp RP-GG pickup spell)
3938 {
3940 return;
3941
3943
3944 return;
3945 }
3946 case 57349: // Drop RP-GG (Wintergrasp RP-GG at death drop spell)
3947 {
3948 if (!m_caster->IsPlayer())
3949 return;
3950
3951 // Delete item from inventory at death
3953
3954 return;
3955 }
3956 case 58418: // Portal to Orgrimmar
3957 case 58420: // Portal to Stormwind
3958 {
3959 if (!unitTarget || !unitTarget->IsPlayer() || effIndex != 0)
3960 return;
3961
3962 uint32 spellID = m_spellInfo->Effects[EFFECT_0].CalcValue();
3963 uint32 questID = m_spellInfo->Effects[EFFECT_1].CalcValue();
3964
3966 unitTarget->CastSpell(unitTarget, spellID, true);
3967
3968 return;
3969 }
3970 case 61263: // for item Intravenous Healing Potion (44698)
3971 {
3972 if (!m_caster || !unitTarget)
3973 return;
3974
3975 m_caster->CastSpell(m_caster, 61267, true);
3976 m_caster->CastSpell(m_caster, 61268, true);
3977 return;
3978 }
3979 }
3980 break;
3981 }
3982 case SPELLFAMILY_ROGUE:
3983 {
3984 switch (m_spellInfo->Id)
3985 {
3986 // Master of Subtlety
3987 case 31666:
3988 {
3989 if (!unitTarget)
3990 return;
3991
3992 Aura* mos = unitTarget->GetAura(31665);
3993 if (mos)
3994 {
3995 mos->SetMaxDuration(6000);
3996 mos->SetDuration(6000, true);
3997 }
3998
3999 break;
4000 }
4001 // Overkill
4002 case 58428:
4003 {
4004 if (!unitTarget)
4005 return;
4006
4007 Aura* overkill = unitTarget->GetAura(58427);
4008 if (overkill)
4009 {
4010 overkill->SetMaxDuration(20000);
4011 overkill->SetDuration(20000, true);
4012 }
4013
4014 break;
4015 }
4016 }
4017 break;
4018 }
4019 }
4020
4021 // normal DB scripted effect
4022 LOG_DEBUG("spells.aura", "Spell ScriptStart spellid {} in EffectScriptEffect({})", m_spellInfo->Id, effIndex);
4024}
@ QUEST_STATUS_COMPLETE
Definition QuestDef.h:101
@ BATTLEGROUND_SA
Definition SharedDefines.h:3745
Class for manage Strand of Ancient battleground.
Definition BattlegroundSA.h:428
void DefendersPortalTeleport(GameObject *portal, Player *plr)
Definition BattlegroundSA.cpp:592
void DespawnOrUnsummon(Milliseconds msTimeToDespawn=0ms, Seconds forcedRespawnTimer=0s)
Definition Creature.cpp:2188
virtual void UnSummon(Milliseconds msTime=0ms)
Definition TemporarySummon.cpp:292
uint8 getGender() const
Definition Unit.h:848
bool IsSummon() const
Definition Unit.h:794
virtual void TextEmote(std::string_view text, WorldObject const *target=nullptr, bool isBossEmote=false)
Definition Unit.cpp:17215
GameObject * FindNearestGameObject(uint32 entry, float range, bool onlySpawned=false) const
Definition Object.cpp:2507

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

◆ EffectSelfResurrect()

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

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

◆ EffectSendEvent()

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

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

◆ EffectSendTaxi()

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

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

◆ EffectSkill()

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

References effectHandleMode, LOG_DEBUG, and SPELL_EFFECT_HANDLE_HIT.

◆ EffectSkinning()

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

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

◆ EffectSkinPlayerCorpse()

void Spell::EffectSkinPlayerCorpse ( SpellEffIndex  effIndex)
5590{
5592 return;
5593
5594 LOG_DEBUG("spells.aura", "Effect: SkinPlayerCorpse");
5595 if ((!m_caster->IsPlayer()) || (!unitTarget->IsPlayer()) || (unitTarget->IsAlive()))
5596 return;
5597
5599
5600 // We have a corpse object as the target.
5601 // This target was deleted in RemovedInsignia() -> ConvertCorpseToBones().
5603}
void RemovedInsignia(Player *looterPlr)
Definition Player.cpp:7783
void RemoveObjectTarget()
Definition Spell.cpp:321

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

◆ EffectSpecCount()

void Spell::EffectSpecCount ( SpellEffIndex  effIndex)
6152{
6154 return;
6155
6156 if (!unitTarget)
6157 return;
6158
6159 if (Player* player = unitTarget->ToPlayer())
6160 {
6161 player->UpdateSpecCount(damage);
6162 }
6163}

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

◆ EffectSpiritHeal()

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

References effectHandleMode, and SPELL_EFFECT_HANDLE_HIT_TARGET.

◆ EffectStealBeneficialBuff()

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

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

◆ EffectStuck()

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

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

◆ EffectSummonChangeItem()

void Spell::EffectSummonChangeItem ( SpellEffIndex  effIndex)
2211{
2213 return;
2214
2215 if (!m_caster->IsPlayer())
2216 return;
2217
2218 Player* player = m_caster->ToPlayer();
2219
2220 // applied only to using item
2221 if (!m_CastItem)
2222 return;
2223
2224 // ... only to item in own inventory/bank/equip_slot
2225 if (m_CastItem->GetOwnerGUID() != player->GetGUID())
2226 return;
2227
2228 uint32 newitemid = m_spellInfo->Effects[effIndex].ItemType;
2229 if (!newitemid)
2230 return;
2231
2232 uint16 pos = m_CastItem->GetPos();
2233
2234 Item* pNewItem = Item::CreateItem(newitemid, 1, player);
2235 if (!pNewItem)
2236 return;
2237
2238 // Client-side enchantment durations update
2240
2244
2246 {
2248 player->DurabilityLoss(pNewItem, lossPercent);
2249 }
2250
2251 if (player->IsInventoryPos(pos))
2252 {
2253 ItemPosCountVec dest;
2254 InventoryResult msg = player->CanStoreItem(m_CastItem->GetBagSlot(), m_CastItem->GetSlot(), dest, pNewItem, true);
2255 if (msg == EQUIP_ERR_OK)
2256 {
2257 player->DestroyItem(m_CastItem->GetBagSlot(), m_CastItem->GetSlot(), true);
2258
2259 // prevent crash at access and unexpected charges counting with item update queue corrupt
2261 m_targets.SetItemTarget(nullptr);
2262
2263 m_CastItem = nullptr;
2265
2266 player->StoreItem(dest, pNewItem, true);
2267 player->ItemAddedQuestCheck(pNewItem->GetEntry(), 1);
2268 return;
2269 }
2270 }
2271 else if (player->IsBankPos(pos))
2272 {
2273 ItemPosCountVec dest;
2274 uint8 msg = player->CanBankItem(m_CastItem->GetBagSlot(), m_CastItem->GetSlot(), dest, pNewItem, true);
2275 if (msg == EQUIP_ERR_OK)
2276 {
2277 player->DestroyItem(m_CastItem->GetBagSlot(), m_CastItem->GetSlot(), true);
2278
2279 // prevent crash at access and unexpected charges counting with item update queue corrupt
2281 m_targets.SetItemTarget(nullptr);
2282
2283 m_CastItem = nullptr;
2285
2286 player->BankItem(dest, pNewItem, true);
2287 return;
2288 }
2289 }
2290 else if (player->IsEquipmentPos(pos))
2291 {
2292 uint16 dest;
2293
2294 player->DestroyItem(m_CastItem->GetBagSlot(), m_CastItem->GetSlot(), true);
2295
2296 uint8 msg = player->CanEquipItem(m_CastItem->GetSlot(), dest, pNewItem, true);
2297
2298 if (msg == EQUIP_ERR_OK || msg == EQUIP_ERR_CANT_DO_RIGHT_NOW)
2299 {
2301
2302 // prevent crash at access and unexpected charges counting with item update queue corrupt
2304 m_targets.SetItemTarget(nullptr);
2305
2306 m_CastItem = nullptr;
2308
2309 player->EquipItem(dest, pNewItem, true);
2310 player->AutoUnequipOffhandIfNeed();
2311 return;
2312 }
2313 }
2314
2315 // fail
2316 delete pNewItem;
2317}
@ EQUIP_ERR_CANT_DO_RIGHT_NOW
Definition Item.h:86
@ ITEM_FIELD_DURABILITY
Definition UpdateFields.h:69
@ ITEM_FIELD_MAXDURABILITY
Definition UpdateFields.h:70
uint8 GetSlot() const
Definition Item.h:281
static Item * CreateItem(uint32 item, uint32 count, Player const *player=nullptr, bool clone=false, uint32 randomPropertyId=0)
Definition Item.cpp:1093
uint32 GetEnchantmentDuration(EnchantmentSlot slot) const
Definition Item.h:305
uint16 GetPos() const
Definition Item.h:285
uint32 GetEnchantmentCharges(EnchantmentSlot slot) const
Definition Item.h:306
uint8 GetBagSlot() const
Definition Item.cpp:784
static bool IsEquipmentPos(uint16 pos)
Definition Player.h:1280
InventoryResult CanEquipItem(uint8 slot, uint16 &dest, Item *pItem, bool swap, bool not_loading=true) const
Definition PlayerStorage.cpp:1873
Item * BankItem(ItemPosCountVec const &dest, Item *pItem, bool update)
Definition Player.h:1354
InventoryResult CanStoreItem(uint8 bag, uint8 slot, ItemPosCountVec &dest, Item *pItem, bool swap=false) const
Definition Player.h:1305
void UpdateEnchantmentDurations()
Definition PlayerStorage.cpp:4801
Item * StoreItem(ItemPosCountVec const &pos, Item *pItem, bool update)
Definition PlayerStorage.cpp:2656
void DestroyItem(uint8 bag, uint8 slot, bool update)
Definition PlayerStorage.cpp:3094
static bool IsInventoryPos(uint16 pos)
Definition Player.h:1278
void AutoUnequipOffhandIfNeed(bool force=false)
Definition Player.cpp:12545
Item * EquipItem(uint16 pos, Item *pItem, bool update)
Definition PlayerStorage.cpp:2803
InventoryResult CanBankItem(uint8 bag, uint8 slot, ItemPosCountVec &dest, Item *pItem, bool swap, bool not_loading=true) const
Definition PlayerStorage.cpp:2105
void ItemAddedQuestCheck(uint32 entry, uint32 count)
Definition PlayerQuest.cpp:1871
static bool IsBankPos(uint16 pos)
Definition Player.h:1283

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

◆ EffectSummonCritter()

void Spell::EffectSummonCritter ( SpellEffIndex  effIndex)

◆ EffectSummonObject()

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

◆ EffectSummonObjectWild()

void Spell::EffectSummonObjectWild ( SpellEffIndex  effIndex)
3773{
3775 return;
3776
3777 uint32 gameobject_id = m_spellInfo->Effects[effIndex].MiscValue;
3778
3779 GameObject* pGameObj = sObjectMgr->IsGameObjectStaticTransport(gameobject_id) ? new StaticTransport() : new GameObject();
3780
3781 WorldObject* target = focusObject;
3782 if (!target)
3783 target = m_caster;
3784
3785 float x, y, z;
3786 if (m_targets.HasDst())
3787 destTarget->GetPosition(x, y, z);
3788 else
3790
3791 Map* map = target->GetMap();
3792
3793 G3D::Quat rotation = G3D::Quat::fromAxisAngleRotation(G3D::Vector3::unitZ(), target->GetOrientation());
3794 if (!pGameObj->Create(map->GenerateLowGuid<HighGuid::GameObject>(), gameobject_id, map, m_caster->GetPhaseMask(), x, y, z, target->GetOrientation(), rotation, 100, GO_STATE_READY))
3795 {
3796 delete pGameObj;
3797 return;
3798 }
3799
3800 int32 duration = m_spellInfo->GetDuration();
3801
3802 pGameObj->SetRespawnTime(duration > 0 ? duration / IN_MILLISECONDS : 0);
3803 pGameObj->SetSpellId(m_spellInfo->Id);
3804
3805 ExecuteLogEffectSummonObject(effIndex, pGameObj);
3806
3807 // Wild object not have owner and check clickable by players
3808 map->AddToMap(pGameObj, true);
3809
3810 if (pGameObj->GetGoType() == GAMEOBJECT_TYPE_FLAGDROP)
3811 if (Player* player = m_caster->ToPlayer())
3812 if (Battleground* bg = player->GetBattleground())
3813 bg->SetDroppedFlagGUID(pGameObj->GetGUID(), player->GetTeamId() == TEAM_ALLIANCE ? TEAM_HORDE : TEAM_ALLIANCE);
3814
3815 if (GameObject* linkedTrap = pGameObj->GetLinkedTrap())
3816 {
3817 linkedTrap->SetRespawnTime(duration > 0 ? duration/IN_MILLISECONDS :0);
3818 linkedTrap->SetSpellId(m_spellInfo->Id);
3819 ExecuteLogEffectSummonObject(effIndex, linkedTrap);
3820 }
3821}
@ GAMEOBJECT_TYPE_FLAGDROP
Definition SharedDefines.h:1590
@ TEAM_ALLIANCE
Definition SharedDefines.h:748
@ TEAM_HORDE
Definition SharedDefines.h:749
GameObject * GetLinkedTrap()
Definition GameObject.cpp:2755
GameobjectTypes GetGoType() const
Definition GameObject.h:203

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

◆ EffectSummonPet()

void Spell::EffectSummonPet ( SpellEffIndex  effIndex)
3191{
3193 return;
3194
3195 if (!m_originalCaster)
3196 return;
3197
3198 uint32 petentry = m_spellInfo->Effects[effIndex].MiscValue;
3199 int32 duration = m_spellInfo->GetDuration();
3200
3201 if (Player* modOwner = m_originalCaster->GetSpellModOwner())
3202 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_DURATION, duration);
3203
3204 Player* owner = m_originalCaster->ToPlayer();
3205 if (!owner && m_originalCaster->ToCreature()->IsTotem())
3207
3208 if (!owner)
3209 {
3210 SummonPropertiesEntry const* properties = sSummonPropertiesStore.LookupEntry(67);
3211 if (properties)
3212 {
3213 // Xinef: unsummon old guardian
3214 if (Guardian* oldPet = m_originalCaster->GetGuardianPet())
3215 oldPet->UnSummon();
3216 SummonGuardian(effIndex, petentry, properties, 1, false);
3217 }
3218 return;
3219 }
3220
3221 Pet* OldSummon = owner->GetPet();
3222
3223 // if pet requested type already exist
3224 if (OldSummon)
3225 {
3226 if (petentry == 0 || OldSummon->GetEntry() == petentry)
3227 {
3228 // pet in corpse state can't be summoned
3229 if (OldSummon->isDead())
3230 return;
3231
3232 ASSERT(OldSummon->GetMap() == owner->GetMap());
3233
3234 //OldSummon->GetMap()->Remove(OldSummon->ToCreature(), false);
3235
3236 float px, py, pz;
3237 owner->GetClosePoint(px, py, pz, OldSummon->GetObjectSize());
3238
3239 OldSummon->NearTeleportTo(px, py, pz, OldSummon->GetOrientation());
3240 OldSummon->UpdateObjectVisibility();
3241
3242 OldSummon->SetHealth(OldSummon->GetMaxHealth());
3243 OldSummon->SetPower(OldSummon->getPowerType(), OldSummon->GetMaxPower(OldSummon->getPowerType()));
3244 // notify player
3245 for (CreatureSpellCooldowns::const_iterator itr = OldSummon->m_CreatureSpellCooldowns.begin(); itr != OldSummon->m_CreatureSpellCooldowns.end(); ++itr)
3246 owner->SendClearCooldown(itr->first, OldSummon);
3247
3248 // actually clear cooldowns
3249 OldSummon->m_CreatureSpellCooldowns.clear();
3250 Unit::AuraApplicationMap& myAuras = OldSummon->GetAppliedAuras();
3251 for (Unit::AuraApplicationMap::iterator i = myAuras.begin(); i != myAuras.end();)
3252 {
3253 Aura const* aura = i->second->GetBase();
3254 if (!aura->IsPassive() && !OldSummon->IsPetAura(aura) && aura->CanBeSentToClient())
3255 OldSummon->RemoveAura(i);
3256 else
3257 ++i;
3258 }
3259 return;
3260 }
3261
3262 if (owner->IsPlayer())
3263 owner->ToPlayer()->RemovePet(OldSummon, PET_SAVE_NOT_IN_SLOT, false);
3264 else
3265 return;
3266 }
3267
3268 float x, y, z;
3269 owner->GetClosePoint(x, y, z, owner->GetObjectSize());
3270 Pet* pet = owner->SummonPet(petentry, x, y, z, owner->GetOrientation(), SUMMON_PET);
3271 if (!pet)
3272 return;
3273
3274 if (m_caster->IsCreature())
3275 {
3276 if (m_caster->ToCreature()->IsTotem())
3278 else
3280 }
3281
3283
3284 // Reset cooldowns
3286 {
3287 pet->m_CreatureSpellCooldowns.clear();
3288 owner->PetSpellInitialize();
3289 }
3290
3291 // Set health to max if new pet is summoned
3292 // in this function old pet is saved with current health eg. 20% and new one is loaded from db with same amount
3293 // pet should have full health
3294 pet->SetHealth(pet->GetMaxHealth());
3295
3296 // generate new name for summon pet
3297 std::string new_name = sObjectMgr->GeneratePetName(petentry);
3298 if (!new_name.empty())
3299 pet->SetName(new_name);
3300
3301 // ExecuteLogEffectSummonObject(effectInfo->EffectIndex, pet);
3302}
@ SPELLMOD_DURATION
Definition SpellDefines.h:77
@ REACT_DEFENSIVE
Definition Unit.h:567
@ REACT_AGGRESSIVE
Definition Unit.h:568
bool CanBeSentToClient() const
Definition SpellAuras.cpp:1083
CreatureSpellCooldowns m_CreatureSpellCooldowns
Definition Creature.h:256
void SetReactState(ReactStates state)
A creature can have 3 ReactStates : Agressive, Passive, Neutral.
Definition Creature.h:100
Definition TemporarySummon.h:106
void SendClearCooldown(uint32 spell_id, Unit *target)
Definition Player.cpp:14887
void SummonGuardian(uint32 i, uint32 entry, SummonPropertiesEntry const *properties, uint32 numSummons, bool personalSpawn)
Definition SpellEffects.cpp:5974
bool IsPetAura(Aura const *aura)
Definition Unit.cpp:13770
void UpdateObjectVisibility(bool forced=true, bool fromUpdate=false) override
Definition Unit.cpp:15394
Powers getPowerType() const
Definition Unit.h:1131
bool isDead() const
Definition Unit.h:1799
void SetName(std::string const &newname)
Definition Object.h:529
float GetObjectSize() const
Definition Object.cpp:2837

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

◆ EffectSummonPlayer()

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

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

◆ EffectSummonRaFFriend()

void Spell::EffectSummonRaFFriend ( SpellEffIndex  effIndex)
6346{
6348 return;
6349
6350 if (!m_caster->IsPlayer())
6351 return;
6352
6353 if (!unitTarget)
6354 return;
6355
6356 Player* player = unitTarget->ToPlayer();
6357 if (!player)
6358 {
6359 return;
6360 }
6361
6362 float x, y, z;
6363 m_caster->GetPosition(x, y, z);
6365 WorldPacket data(SMSG_SUMMON_REQUEST, 8 + 4 + 4);
6366 data << m_caster->GetGUID();
6367 data << uint32(m_caster->GetZoneId());
6368 data << uint32(MAX_PLAYER_SUMMON_DELAY * IN_MILLISECONDS); // auto decline after msecs
6369 player->SendDirectMessage(&data);
6370}

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

◆ EffectSummonType()

void Spell::EffectSummonType ( SpellEffIndex  effIndex)
2342{
2344 return;
2345
2346 uint32 entry = m_spellInfo->Effects[effIndex].MiscValue;
2347
2348 if (m_spellValue->MiscVal[effIndex])
2349 entry = m_spellValue->MiscVal[effIndex];
2350
2351 if (!entry)
2352 return;
2353
2354 SummonPropertiesEntry const* properties = sSummonPropertiesStore.LookupEntry(m_spellInfo->Effects[effIndex].MiscValueB);
2355 if (!properties)
2356 {
2357 LOG_ERROR("spells.effect", "EffectSummonType: Unhandled summon type {}", m_spellInfo->Effects[effIndex].MiscValueB);
2358 return;
2359 }
2360
2361 if (!m_originalCaster)
2362 return;
2363
2364 bool personalSpawn = (properties->Flags & SUMMON_PROP_FLAG_ONLY_VISIBLE_TO_SUMMONER) != 0;
2365 int32 duration = m_spellInfo->GetDuration();
2366 if (Player* modOwner = m_originalCaster->GetSpellModOwner())
2367 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_DURATION, duration);
2368
2369 TempSummon* summon = nullptr;
2370
2371 // determine how many units should be summoned
2372 uint32 numSummons;
2373
2374 // some spells need to summon many units, for those spells number of summons is stored in effect value
2375 // however so far noone found a generic check to find all of those (there's no related data in summonproperties.dbc
2376 // and in spell attributes, possibly we need to add a table for those)
2377 // so here's a list of MiscValueB values, which is currently most generic check
2378 switch (properties->Id)
2379 {
2380 case 64:
2381 case 61:
2382 case 1101:
2383 case 66:
2384 case 648:
2385 case 2301:
2386 case 1061:
2387 case 1261:
2388 case 629:
2389 case 181:
2390 case 715:
2391 case 1562:
2392 case 833:
2393 case 1161:
2394 case 713: // xinef, bloodworms
2395 numSummons = (damage > 0) ? damage : 1;
2396 break;
2397 default:
2398 numSummons = 1;
2399 break;
2400 }
2401
2402 switch (properties->Category)
2403 {
2407 if (properties->Flags & 512)
2408 {
2409 SummonGuardian(effIndex, entry, properties, numSummons, personalSpawn);
2410 break;
2411 }
2412 switch (properties->Type)
2413 {
2414 case SUMMON_TYPE_PET:
2417 case SUMMON_TYPE_MINION:
2418 SummonGuardian(effIndex, entry, properties, numSummons, personalSpawn);
2419 break;
2420 // Summons a vehicle, but doesn't force anyone to enter it (see SUMMON_CATEGORY_VEHICLE)
2423 summon = m_caster->GetMap()->SummonCreature(entry, *destTarget, properties, duration, m_originalCaster, m_spellInfo->Id, 0, personalSpawn);
2424 break;
2426 case SUMMON_TYPE_TOTEM:
2427 {
2428 // protection code
2429 summon = m_caster->GetMap()->SummonCreature(entry, *destTarget, properties, duration, m_originalCaster, m_spellInfo->Id, 0, personalSpawn);
2430 if (!summon || !summon->IsTotem())
2431 return;
2432
2433 // Mana Tide Totem
2434 if (m_spellInfo->Id == 16190)
2436
2437 if (damage && properties->Type != SUMMON_TYPE_LIGHTWELL) // Health set in script for lightwell
2438 {
2439 summon->SetMaxHealth(damage);
2440 summon->SetHealth(damage);
2441 }
2442 break;
2443 }
2445 // For companions, recalculate the position to ensure they spawn at the intended π/4 angle.
2449 ));
2450 [[fallthrough]];
2451 case SUMMON_TYPE_JEEVES:
2452 {
2453 summon = m_caster->GetMap()->SummonCreature(entry, *destTarget, properties, duration, m_originalCaster, m_spellInfo->Id, 0, personalSpawn);
2454 if (!summon || !summon->HasUnitTypeMask(UNIT_MASK_MINION))
2455 return;
2456
2457 summon->SelectLevel(); // some summoned creaters have different from 1 DB data for level/hp
2459
2460 summon->SetImmuneToAll(true);
2462
2463 // Xinef: Pet can have some auras in creature_addon or in scripts, do not remove them instantly
2464 //summon->AI()->EnterEvadeMode();
2465 if (properties->Type != SUMMON_TYPE_JEEVES)
2466 {
2468 summon->GetMotionMaster()->Clear(false);
2470 }
2471 break;
2472 }
2473 default:
2474 {
2475 float radius = m_spellInfo->Effects[effIndex].CalcRadius();
2476
2477 TempSummonType summonType = (duration <= 0) ? TEMPSUMMON_DEAD_DESPAWN : TEMPSUMMON_TIMED_DESPAWN;
2478
2479 Unit* summoner = m_originalCaster;
2480 if (summoner->IsPet())
2481 if (Unit* owner = summoner->GetOwner())
2482 summoner = owner;
2483
2484 for (uint32 count = 0; count < numSummons; ++count)
2485 {
2486 Position pos;
2487 if (count == 0)
2488 pos = *destTarget;
2489 else
2490 // randomize position for multiple summons
2491 pos = m_caster->GetRandomPoint(*destTarget, radius);
2492
2493 summon = summoner->SummonCreature(entry, pos, summonType, duration, 0, nullptr, personalSpawn);
2494 if (!summon)
2495 continue;
2496
2497 summon->SetTempSummonType(summonType);
2498
2499 if (properties->Category == SUMMON_CATEGORY_ALLY)
2500 {
2501 summon->SetOwnerGUID(summoner->GetGUID());
2502 summon->SetFaction(summoner->GetFaction());
2503 }
2504
2505 ExecuteLogEffectSummonObject(effIndex, summon);
2506 }
2507 return;
2508 }
2509 }//switch
2510 break;
2512 // Xinef: SummonGuardian function can summon a few npcs of same type, remove old summons with same entry here
2513 if (m_originalCaster)
2515 SummonGuardian(effIndex, entry, properties, numSummons, personalSpawn);
2516 break;
2518 summon = m_caster->GetMap()->SummonCreature(entry, *destTarget, properties, duration, m_originalCaster, m_spellInfo->Id, 0, personalSpawn);
2519 break;
2521 // Summoning spells (usually triggered by npc_spellclick) that spawn a vehicle and that cause the clicker
2522 // to cast a ride vehicle spell on the summoned unit.
2523 //float x, y, z;
2524 //m_caster->GetClosePoint(x, y, z, DEFAULT_WORLD_OBJECT_SIZE);
2525 // xinef: vehicles summoned in air, eg. Cold Hearted quest
2526 if (std::fabs(m_caster->GetPositionZ() - destTarget->GetPositionZ()) > 6.0f)
2528
2529 summon = m_originalCaster->GetMap()->SummonCreature(entry, *destTarget, properties, duration, m_caster, m_spellInfo->Id, 0, personalSpawn);
2530 if (!summon || !summon->IsVehicle())
2531 return;
2532
2533 // The spell that this effect will trigger. It has SPELL_AURA_CONTROL_VEHICLE
2535 int32 basePoints = m_spellInfo->Effects[effIndex].CalcValue();
2536 if (basePoints > 1) // xinef: some summoning spells have value 1 - indicates vehicle seat
2537 {
2538 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(basePoints);
2539 if (spellInfo && spellInfo->HasAura(SPELL_AURA_CONTROL_VEHICLE))
2540 spellId = spellInfo->Id;
2541 }
2542
2543 // xinef: if we have small value, it indicates seat position
2544 if (basePoints > 0 && basePoints < MAX_VEHICLE_SEATS)
2545 m_originalCaster->CastCustomSpell(spellId, SPELLVALUE_BASE_POINT0, basePoints, summon, true);
2546 else
2547 m_originalCaster->CastSpell(summon, spellId, true);
2548
2549 // xinef: i think this is wrong, found only 2 vehicles with faction override and one of them should inherit caster faction...
2550 //uint32 faction = properties->Faction;
2551 //if (!faction)
2552 uint32 faction = m_originalCaster->GetFaction();
2553
2554 summon->SetFaction(faction);
2555 break;
2556 }
2557
2558 if (summon)
2559 {
2561 ExecuteLogEffectSummonObject(effIndex, summon);
2562 }
2563}
@ SUMMON_PROP_FLAG_ONLY_VISIBLE_TO_SUMMONER
Definition DBCEnums.h:428
#define MAX_VEHICLE_SEATS
Definition DBCStructure.h:2024
@ MOTION_SLOT_ACTIVE
Definition MotionMaster.h:65
TempSummonType
Definition Object.h:48
@ TEMPSUMMON_DEAD_DESPAWN
Definition Object.h:55
constexpr float MINI_PET_SUMMON_ANGLE
Definition PetDefines.h:208
constexpr float MINI_PET_FOLLOW_ANGLE
Definition PetDefines.h:209
@ SUMMON_TYPE_VEHICLE2
Definition SharedDefines.h:3537
@ SUMMON_TYPE_LIGHTWELL
Definition SharedDefines.h:3538
@ SUMMON_TYPE_MINION
Definition SharedDefines.h:3530
@ SUMMON_TYPE_GUARDIAN
Definition SharedDefines.h:3529
@ SUMMON_TYPE_JEEVES
Definition SharedDefines.h:3539
@ SUMMON_TYPE_PET
Definition SharedDefines.h:3528
@ SUMMON_TYPE_TOTEM
Definition SharedDefines.h:3531
@ SUMMON_TYPE_VEHICLE
Definition SharedDefines.h:3536
@ SUMMON_TYPE_MINIPET
Definition SharedDefines.h:3532
@ SUMMON_TYPE_GUARDIAN2
Definition SharedDefines.h:3533
@ SUMMON_CATEGORY_VEHICLE
Definition SharedDefines.h:3520
@ SUMMON_CATEGORY_ALLY
Definition SharedDefines.h:3517
@ SUMMON_CATEGORY_WILD
Definition SharedDefines.h:3516
@ SUMMON_CATEGORY_UNK
Definition SharedDefines.h:3521
@ SPELL_AURA_CONTROL_VEHICLE
Definition SpellAuraDefines.h:299
@ UNIT_MASK_MINION
Definition UnitDefines.h:160
NPCFlags
Non Player Character flags.
Definition UnitDefines.h:320
@ REACT_PASSIVE
Definition Unit.h:566
@ VEHICLE_SPELL_RIDE_HARDCODED
Definition VehicleDefines.h:52
void SelectLevel(bool changelevel=true)
Definition Creature.cpp:1495
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:2187
void MoveFollow(Unit *target, float dist, float angle, MovementSlot slot=MOTION_SLOT_ACTIVE, bool inheritWalkState=true, bool inheritSpeed=true)
The unit will follow this target. Doesn't work with UNIT_FLAG_DISABLE_MOVE.
Definition MotionMaster.cpp:447
void Clear(bool reset=true)
Definition MotionMaster.h:193
void SetTempSummonType(TempSummonType type)
Definition TemporarySummon.cpp:287
void SetFacingToObject(WorldObject *object, Milliseconds timed=0ms)
Definition Unit.cpp:16486
void SetFaction(uint32 faction)
Definition Unit.cpp:7091
void SetOwnerGUID(ObjectGuid owner)
Definition Unit.cpp:7690
uint32 HasUnitTypeMask(uint32 mask) const
Definition Unit.h:741
void SetMaxHealth(uint32 val)
Definition Unit.cpp:12424
void SetCreatorGUID(ObjectGuid creator)
Definition Unit.h:716
void ReplaceAllNpcFlags(NPCFlags flags)
Definition Unit.h:766
void RemoveAllMinionsByEntry(uint32 entry)
Definition Unit.cpp:7980
void SetImmuneToAll(bool apply, bool keepCombat=false)
Definition Unit.h:924
Position GetNearPosition(float dist, float angle)
Definition Object.cpp:2794
float GetDistance2d(WorldObject const *obj) const
Definition Object.cpp:1313
void GetRandomPoint(const Position &srcPos, float distance, float &rand_x, float &rand_y, float &rand_z) const
Definition Object.cpp:1558
uint32 npcflag
Definition CreatureData.h:200
uint32 MiscVal[MAX_SPELL_EFFECTS]
Definition Spell.h:231
uint32 Flags
Definition DBCStructure.h:1915
uint32 Type
Definition DBCStructure.h:1913
uint32 Id
Definition DBCStructure.h:1910

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

◆ EffectTameCreature()

void Spell::EffectTameCreature ( SpellEffIndex  effIndex)
3135{
3137 return;
3138
3139 if (m_caster->GetPetGUID())
3140 return;
3141
3142 if (!unitTarget)
3143 return;
3144
3145 if (!unitTarget->IsCreature())
3146 return;
3147
3148 Creature* creatureTarget = unitTarget->ToCreature();
3149
3150 if (creatureTarget->IsPet())
3151 return;
3152
3154 return;
3155
3156 // cast finish successfully
3157 //SendChannelUpdate(0);
3158 finish();
3159
3160 Pet* pet = m_caster->CreateTamedPetFrom(creatureTarget, m_spellInfo->Id);
3161 if (!pet) // in very specific state like near world end/etc.
3162 return;
3163
3164 // "kill" original creature
3165 creatureTarget->DespawnOrUnsummon();
3166
3167 uint8 level = (creatureTarget->GetLevel() < (m_caster->GetLevel() - 5)) ? (m_caster->GetLevel() - 5) : creatureTarget->GetLevel();
3168
3169 // prepare visual effect for levelup
3170 pet->SetUInt32Value(UNIT_FIELD_LEVEL, level - 1);
3171
3172 // add to world
3173 pet->GetMap()->AddToMap(pet->ToCreature(), true);
3174
3175 // visual effect for levelup
3176 pet->SetUInt32Value(UNIT_FIELD_LEVEL, level);
3177
3178 // caster have pet now
3179 m_caster->SetMinion(pet, true);
3180
3181 pet->InitTalentForLevel();
3182
3183 if (m_caster->IsPlayer())
3184 {
3187 }
3188}
@ UNIT_FIELD_LEVEL
Definition UpdateFields.h:114

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

◆ EffectTaunt()

void Spell::EffectTaunt ( SpellEffIndex  effIndex)
3331{
3333 return;
3334
3335 if (!unitTarget)
3336 return;
3337
3338 // xinef: Hand of Reckoning, cast before checking canhavethreatlist. fixes damage against pets
3339 if (m_spellInfo->Id == 62124 && unitTarget->GetVictim() != m_caster)
3340 m_caster->CastSpell(unitTarget, 67485, true);
3341
3343 {
3345 return;
3346 }
3347
3349 if (mgr.GetCurrentVictim() == m_caster)
3350 {
3352 return;
3353 }
3354
3355 if (!mgr.IsThreatListEmpty())
3357}
Definition ThreatManager.h:90
Unit * GetCurrentVictim()
Definition ThreatManager.cpp:248
bool IsThreatListEmpty(bool includeOffline=false) const
Definition ThreatManager.cpp:271
void MatchUnitThreatToHighestThreat(Unit *target)
Definition ThreatManager.cpp:497
bool CanHaveThreatList(bool skipAliveCheck=false) const
Definition Unit.cpp:11453

References Unit::CanHaveThreatList(), Unit::CastSpell(), effectHandleMode, ThreatManager::GetCurrentVictim(), Unit::GetThreatMgr(), Unit::GetVictim(), SpellInfo::Id, ThreatManager::IsThreatListEmpty(), m_caster, m_spellInfo, ThreatManager::MatchUnitThreatToHighestThreat(), SendCastResult(), SPELL_EFFECT_HANDLE_HIT_TARGET, SPELL_FAILED_DONT_REPORT, and unitTarget.

◆ EffectTeleportUnits()

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

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

◆ EffectTeleUnitsFaceCaster()

◆ EffectThreat()

void Spell::EffectThreat ( SpellEffIndex  effIndex)
3697{
3699 return;
3700
3701 if (!unitTarget || !unitTarget->IsAlive() || !m_caster->IsAlive())
3702 return;
3703
3704 // xinef: skip if target cannot have threat list or caster is friendly (ghoul leap)
3706 return;
3707
3708 // SPELL_EFFECT_THREAT adds flat threat that should not be modified by threat reduction
3710}
void AddThreat(Unit *target, float amount, SpellInfo const *spell=nullptr, bool ignoreModifiers=false, bool ignoreRedirects=false)
== AFFECT MY THREAT LIST ==
Definition ThreatManager.cpp:392

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

◆ EffectTitanGrip()

void Spell::EffectTitanGrip ( SpellEffIndex  effIndex)
5908{
5910 return;
5911
5912 if (m_caster->IsPlayer())
5913 {
5914 if (Aura* aur = m_caster->GetAura(49152))
5915 aur->RecalculateAmountOfEffects();
5916 else
5917 m_caster->CastSpell(unitTarget, 49152, true); // damage reduction
5918
5920 }
5921}
void SetCanTitanGrip(bool value)
Definition Player.cpp:13271

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

◆ EffectTradeSkill()

void Spell::EffectTradeSkill ( SpellEffIndex  effIndex)
2847{
2849 return;
2850
2851 if (!m_caster->IsPlayer())
2852 return;
2853 // uint32 skillid = m_spellInfo->Effects[i].MiscValue;
2854 // uint16 skillmax = unitTarget->ToPlayer()->(skillid);
2855 // m_caster->ToPlayer()->SetSkill(skillid, skillval?skillval:1, skillmax+75);
2856}

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

◆ EffectTransmitted()

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

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

◆ EffectTriggerMissileSpell()

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

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

◆ EffectTriggerRitualOfSummoning()

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

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

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

◆ EffectUnlearnSpecialization()

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

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)
2771{
2773 return;
2774
2775 if (!unitTarget || m_caster->IsPlayer())
2776 return;
2777
2778 if (ObjectGuid guid = m_caster->GetGUID()) // the trainer is the caster
2780}
void SendTalentWipeConfirm(ObjectGuid guid)
Definition Player.cpp:8942

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

◆ EffectUnused()

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

◆ EffectWeaponDmg()

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

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::GetOwner(), Unit::GetPctModifierValue(), Unit::GetPower(), SpellInfo::GetSchoolMask(), Unit::GetTotalAttackPowerValue(), Player::GetWeaponForAttack(), SpellInfo::HasAttribute(), Unit::HasAura(), Unit::HasAuraState(), Unit::HasDecreaseSpeedAura(), SpellInfo::Id, Unit::IsAlive(), Object::IsPlayer(), Unit::IsScriptOverriden(), ITEM_SUBCLASS_WEAPON_DAGGER, m_attackType, m_caster, m_damage, m_spellInfo, m_spellSchoolMask, m_UniqueTargetInfo, MAX_SPELL_EFFECTS, Unit::MeleeDamageBonusDone(), Unit::MeleeDamageBonusTaken(), OFF_ATTACK, POWER_RUNIC_POWER, RANGED_ATTACK, roll_chance_i(), SPELL_ATTR0_CU_SHARE_DAMAGE, SPELL_AURA_DUMMY, SPELL_EFFECT_HANDLE_LAUNCH_TARGET, SPELL_EFFECT_NORMALIZED_WEAPON_DMG, SPELL_EFFECT_WEAPON_DAMAGE, SPELL_EFFECT_WEAPON_DAMAGE_NOSCHOOL, SPELL_EFFECT_WEAPON_PERCENT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, Unit::SpellBaseDamageBonusDone(), SPELLFAMILY_DEATHKNIGHT, SPELLFAMILY_DRUID, SPELLFAMILY_GENERIC, SPELLFAMILY_HUNTER, SPELLFAMILY_PALADIN, SPELLFAMILY_ROGUE, SPELLFAMILY_SHAMAN, SPELLFAMILY_WARRIOR, SpellInfo::SpellFamilyFlags, SpellInfo::SpellFamilyName, SpellInfo::SpellIconID, Object::ToPlayer(), TOTAL_PCT, UNIT_MOD_DAMAGE_MAINHAND, UNIT_MOD_DAMAGE_OFFHAND, UNIT_MOD_DAMAGE_RANGED, and unitTarget.

◆ ExecuteLogEffectCreateItem()

void Spell::ExecuteLogEffectCreateItem ( uint8  effIndex,
uint32  entry 
)
5115{
5116 InitEffectExecuteData(effIndex);
5117 *m_effectExecuteData[effIndex] << uint32(entry);
5118}
void InitEffectExecuteData(uint8 effIndex)
Definition Spell.cpp:8531

References InitEffectExecuteData(), and m_effectExecuteData.

Referenced by EffectCreateItem().

◆ ExecuteLogEffectDestroyItem()

void Spell::ExecuteLogEffectDestroyItem ( uint8  effIndex,
uint32  entry 
)
5121{
5122 InitEffectExecuteData(effIndex);
5123 *m_effectExecuteData[effIndex] << uint32(entry);
5124}

References InitEffectExecuteData(), and m_effectExecuteData.

Referenced by EffectFeedPet().

◆ ExecuteLogEffectDurabilityDamage()

void Spell::ExecuteLogEffectDurabilityDamage ( uint8  effIndex,
Unit victim,
int32  itemId,
int32  slot 
)
5101{
5102 InitEffectExecuteData(effIndex);
5103 *m_effectExecuteData[effIndex] << victim->GetPackGUID();
5104 *m_effectExecuteData[effIndex] << int32(itemId);
5105 *m_effectExecuteData[effIndex] << int32(slot);
5106}

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

Referenced by EffectDurabilityDamage().

◆ ExecuteLogEffectExtraAttacks()

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

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

Referenced by EffectAddExtraAttacks().

◆ ExecuteLogEffectInterruptCast()

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

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

Referenced by EffectInterruptCast().

◆ ExecuteLogEffectOpenLock()

void Spell::ExecuteLogEffectOpenLock ( uint8  effIndex,
Object obj 
)
5109{
5110 InitEffectExecuteData(effIndex);
5111 *m_effectExecuteData[effIndex] << obj->GetPackGUID();
5112}

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

Referenced by EffectOpenLock().

◆ ExecuteLogEffectResurrect()

void Spell::ExecuteLogEffectResurrect ( uint8  effIndex,
Unit target 
)
5139{
5140 InitEffectExecuteData(effIndex);
5141 *m_effectExecuteData[effIndex] << target->GetPackGUID();
5142}

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 
)
5078{
5079 InitEffectExecuteData(effIndex);
5080 *m_effectExecuteData[effIndex] << target->GetPackGUID();
5081 *m_effectExecuteData[effIndex] << uint32(powerTaken);
5082 *m_effectExecuteData[effIndex] << uint32(PowerType);
5083 *m_effectExecuteData[effIndex] << float(gainMultiplier);
5084}

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 
)
5133{
5134 InitEffectExecuteData(effIndex);
5135 *m_effectExecuteData[effIndex] << obj->GetPackGUID();
5136}

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

Referenced by EffectDismissPet().

◆ finish()

void Spell::finish ( bool  ok = true)
4452{
4453 if (!m_caster)
4454 return;
4455
4457 return;
4459
4460 if (m_spellInfo->IsChanneled())
4462
4465
4466 // Unsummon summon as possessed creatures on spell cancel
4468 {
4469 if (Unit* charm = m_caster->GetCharm())
4470 if (charm->IsCreature()
4471 && charm->ToCreature()->HasUnitTypeMask(UNIT_MASK_PUPPET)
4472 && charm->GetUInt32Value(UNIT_CREATED_BY_SPELL) == m_spellInfo->Id)
4473 ((Puppet*)charm)->UnSummon();
4474 }
4475
4476 if (Creature* creatureCaster = m_caster->ToCreature())
4477 creatureCaster->ReleaseFocus(this);
4478
4479 if (ok)
4480 {
4483 }
4484 else
4485 {
4486 if (m_caster->IsPlayer())
4487 {
4488 // Xinef: Restore spell mods in case of fail cast
4490
4491 // Xinef: Reset cooldown event in case of fail cast
4494 }
4495
4496 return;
4497 }
4498
4499 // pussywizard:
4502
4504 {
4505 // Unsummon statue
4507 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spell);
4508 if (spellInfo && spellInfo->SpellIconID == 2056)
4509 {
4510 LOG_DEBUG("spells.aura", "Statue {} is unsummoned in spell {} finish", m_caster->GetGUID().ToString(), m_spellInfo->Id);
4512 return;
4513 }
4514 }
4515
4516 // potions disabled by client, send event "not in combat" if need
4519
4520 // Take mods after trigger spell (needed for 14177 to affect 48664)
4521 // mods are taken only on succesfull cast and independantly from targets of the spell
4522 if (Player* player = m_caster->GetSpellModOwner())
4523 player->RemoveSpellMods(this);
4524
4525 // xinef: clear reactive auras states after spell cast
4528
4529 // Stop Attack for some spells
4532}
@ ENCOUNTER_CREDIT_CAST_SPELL
Definition Map.h:162
@ AURA_STATE_DEFENSE
Definition SharedDefines.h:1280
@ AURA_STATE_HUNTER_PARRY
Definition SharedDefines.h:1286
@ SPELL_ATTR0_CU_ENCOUNTER_REWARD
Definition SpellInfo.h:208
@ UNIT_MASK_PUPPET
Definition UnitDefines.h:165
void UpdateEncounterState(EncounterCreditType type, uint32 creditEntry, Unit *source)
Definition Map.cpp:2857
void UpdatePotionCooldown(Spell *spell=nullptr)
Definition PlayerUpdates.cpp:1557
Definition TemporarySummon.h:125
virtual void setDeathState(DeathState s, bool despawn=false)
Definition Unit.cpp:11394
void UpdateInterruptMask()
Definition Unit.cpp:886
void ModifyAuraState(AuraStateType flag, bool apply)
Definition Unit.cpp:7614
bool AttackStop()
Force the unit to stop attacking. This will clear UNIT_STATE_MELEE_ATTACKING, Interrupt current spell...
Definition Unit.cpp:7471

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

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

◆ FinishTargetProcessing()

void Spell::FinishTargetProcessing ( )
protected
8527{
8529}
void SendLogExecute()
Definition Spell.cpp:5043

References SendLogExecute().

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

◆ GetCaster()

◆ GetCastTime()

◆ GetCastTimeRemaining()

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

References m_timer.

◆ GetCurrentContainer()

CurrentSpellTypes Spell::GetCurrentContainer ( ) const

◆ GetDebugInfo()

std::string Spell::GetDebugInfo ( ) const
protected
8990{
8991 std::stringstream sstr;
8992 sstr << std::boolalpha
8993 << "Id: " << GetSpellInfo()->Id << " OriginalCaster: " << m_originalCasterGUID.ToString()
8994 << " State: " << getState();
8995 return sstr.str();
8996}

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

◆ GetDelayMoment()

uint64 Spell::GetDelayMoment ( ) const
inline
581{ return m_delayMoment; }

References m_delayMoment.

Referenced by SpellEvent::Execute().

◆ GetDelayStart()

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

References m_delayStart.

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

◆ GetDelayTrajectory()

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

References m_delayTrajectory.

◆ GetOriginalCaster()

Unit * Spell::GetOriginalCaster ( ) const
inline

◆ GetOriginalTarget()

Unit * Spell::GetOriginalTarget ( ) const
7896{
7898}
ObjectGuid m_originalTargetGUID
Definition Spell.h:629

References ObjectAccessor::GetUnit(), m_caster, and m_originalTargetGUID.

Referenced by _handle_finish_phase().

◆ GetPowerCost()

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

References m_powerCost.

◆ GetSearcherTypeMask()

uint32 Spell::GetSearcherTypeMask ( SpellTargetObjectTypes  objType,
ConditionList condList 
)
2057{
2058 // this function selects which containers need to be searched for spell target
2060
2061 // filter searchers based on searched object type
2062 switch (objType)
2063 {
2070 break;
2074 break;
2075 default:
2076 break;
2077 }
2079 retMask &= ~GRID_MAP_TYPE_MASK_CORPSE;
2083 retMask &= GRID_MAP_TYPE_MASK_PLAYER;
2085 retMask &= ~GRID_MAP_TYPE_MASK_PLAYER;
2086
2087 if (condList)
2088 retMask &= sConditionMgr->GetSearcherTypeMaskForConditionList(*condList);
2089 return retMask;
2090}
@ GRID_MAP_TYPE_MASK_PLAYER
Definition GridDefines.h:75
@ GRID_MAP_TYPE_MASK_CREATURE
Definition GridDefines.h:72
@ GRID_MAP_TYPE_MASK_ALL
Definition GridDefines.h:76
@ GRID_MAP_TYPE_MASK_GAMEOBJECT
Definition GridDefines.h:74
@ GRID_MAP_TYPE_MASK_CORPSE
Definition GridDefines.h:71
@ SPELL_ATTR5_NOT_ON_PLAYER
Definition SharedDefines.h:562
@ SPELL_ATTR2_ALLOW_DEAD_TARGET
Definition SharedDefines.h:444
@ SPELL_ATTR3_ONLY_ON_GHOSTS
Definition SharedDefines.h:493
@ SPELL_ATTR3_ONLY_ON_PLAYER
Definition SharedDefines.h:489
@ TARGET_OBJECT_TYPE_CORPSE
Definition SpellInfo.h:107
@ TARGET_OBJECT_TYPE_GOBJ
Definition SpellInfo.h:104
@ TARGET_OBJECT_TYPE_CORPSE_ALLY
Definition SpellInfo.h:110
@ TARGET_OBJECT_TYPE_CORPSE_ENEMY
Definition SpellInfo.h:109
@ TARGET_OBJECT_TYPE_GOBJ_ITEM
Definition SpellInfo.h:105

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

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

◆ GetSpellInfo()

◆ GetSpellSchoolMask()

SpellSchoolMask Spell::GetSpellSchoolMask ( ) const
inline

◆ GetSpellValue()

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

References m_spellValue.

Referenced by DoAllEffectOnTarget().

◆ getState()

◆ GetTriggeredByAuraSpellInfo()

SpellInfo const * Spell::GetTriggeredByAuraSpellInfo ( ) const
inline

◆ GetTriggeredByAuraTickNumber()

uint32 Spell::GetTriggeredByAuraTickNumber ( ) const
inline

◆ GetTriggeredCastFlags()

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

References _triggeredCastFlags.

◆ GetUniqueTargetInfo()

◆ handle_delayed()

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

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 ( )
4070{
4071 // start channeling if applicable
4072 if (m_spellInfo->IsChanneled())
4073 {
4074 int32 duration = m_spellInfo->GetDuration();
4076 duration = -1;
4077
4078 if (duration > 0)
4079 {
4080 // First mod_duration then haste - see Missile Barrage
4081 // Apply duration mod
4082 if (Player* modOwner = m_caster->GetSpellModOwner())
4083 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_DURATION, duration);
4084
4085 // Apply haste mods
4087 duration = int32(duration * m_caster->GetFloatValue(UNIT_MOD_CAST_SPEED));
4088
4091 m_channeledDuration = duration;
4092 SendChannelStart(duration);
4093 }
4094 else if (duration == -1)
4095 {
4098 SendChannelStart(duration);
4099 }
4100 }
4101
4103
4104 // process immediate effects (items, ground, etc.) also initialize some variables
4106
4107 // Sync persistent area aura duration with hasted channel duration
4110 {
4113 }
4114
4115 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
4116 DoAllEffectOnTarget(&(*ihit));
4117
4118 for (std::list<GOTargetInfo>::iterator ihit = m_UniqueGOTargetInfo.begin(); ihit != m_UniqueGOTargetInfo.end(); ++ihit)
4119 DoAllEffectOnTarget(&(*ihit));
4120
4122
4123 // spell is finished, perform some last features of the spell here
4125
4126 // Remove used for cast item if need (it can be already nullptr after TakeReagents call
4127 TakeCastItem();
4128
4129 // handle ammo consumption for Hunter's volley spell
4131 TakeAmmo();
4132
4134 finish(true); // successfully finish spell cast (not last in case autorepeat or channel spell)
4135}
@ DYNOBJ_AURA_TYPE
Definition SpellAuraDefines.h:386
AuraObjectType GetType() const
Definition SpellAuras.cpp:420
void SendChannelStart(uint32 duration)
Definition Spell.cpp:5176
void TakeAmmo()
Definition Spell.cpp:5349
void AddInterruptMask(uint32 mask)
Definition Unit.h:1604

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

Referenced by _cast().

◆ HandleEffects()

void Spell::HandleEffects ( Unit pUnitTarget,
Item pItemTarget,
GameObject pGOTarget,
uint32  i,
SpellEffectHandleMode  mode 
)
5605{
5607 return;
5608
5609 effectHandleMode = mode;
5610 unitTarget = pUnitTarget;
5611 itemTarget = pItemTarget;
5612 gameObjTarget = pGOTarget;
5614
5615 uint8 eff = m_spellInfo->Effects[i].Effect;
5616
5617 LOG_DEBUG("spells.aura", "Spell: {} Effect : {}", m_spellInfo->Id, eff);
5618
5619 // we do not need DamageMultiplier here.
5620 damage = CalculateSpellDamage(i, nullptr);
5621
5622 bool preventDefault = CallScriptEffectHandlers((SpellEffIndex)i, mode);
5623
5624 if (!preventDefault && eff < TOTAL_SPELL_EFFECTS)
5625 {
5626 (this->*SpellEffects[eff])((SpellEffIndex)i);
5627 }
5628}
SpellEffIndex
Definition SharedDefines.h:30
SpellEffects
Definition SharedDefines.h:766
@ TOTAL_SPELL_EFFECTS
Definition SharedDefines.h:931
bool CallScriptEffectHandlers(SpellEffIndex effIndex, SpellEffectHandleMode mode)
Definition Spell.cpp:8640
WorldLocation _position
Definition Spell.h:115

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

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

◆ HandleLaunchPhase()

void Spell::HandleLaunchPhase ( )
protected
8271{
8272 // handle effects with SPELL_EFFECT_HANDLE_LAUNCH mode
8273 for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i)
8274 {
8275 // don't do anything for empty effect
8276 if (!m_spellInfo->Effects[i].IsEffect())
8277 continue;
8278
8279 HandleEffects(nullptr, nullptr, nullptr, i, SPELL_EFFECT_HANDLE_LAUNCH);
8280 }
8281
8282 float multiplier[MAX_SPELL_EFFECTS];
8283 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
8284 if (m_applyMultiplierMask & (1 << i))
8285 multiplier[i] = m_spellInfo->Effects[i].CalcDamageMultiplier(m_originalCaster, this);
8286
8289 for (Unit::AuraEffectList::const_iterator j = Auras.begin(); j != Auras.end(); ++j)
8290 {
8291 if ((*j)->IsAffectedOnSpell(m_spellInfo))
8292 usesAmmo = false;
8293 }
8294
8296
8297 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
8298 {
8299 TargetInfo& target = *ihit;
8300
8301 uint32 mask = target.effectMask;
8302 if (!mask)
8303 continue;
8304
8305 // do not consume ammo anymore for Hunter's volley spell
8307 usesAmmo = false;
8308
8309 if (usesAmmo)
8310 {
8311 bool ammoTaken = false;
8312 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; i++)
8313 {
8314 if (!(mask & 1 << i))
8315 continue;
8316 switch (m_spellInfo->Effects[i].Effect)
8317 {
8323 ammoTaken = true;
8324 TakeAmmo();
8325 }
8326 if (ammoTaken)
8327 break;
8328 }
8329 }
8330
8332 {
8333 Unit* targetUnit = m_caster->GetGUID() == target.targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, target.targetGUID);
8334 if (targetUnit && !m_originalCaster->IsFriendlyTo(targetUnit) && (!m_spellInfo->IsPositive() || m_spellInfo->HasEffect(SPELL_EFFECT_DISPEL)) && (m_spellInfo->HasInitialAggro() || targetUnit->IsEngaged()))
8335 m_originalCaster->SetInCombatWith(targetUnit, true);
8336 }
8337
8338 DoAllEffectOnLaunchTarget(target, multiplier);
8339 }
8340
8342}
@ SPELL_EFFECT_SCHOOL_DAMAGE
Definition SharedDefines.h:768
@ SPELL_AURA_ABILITY_CONSUME_NO_AMMO
Definition SpellAuraDefines.h:337
@ SPELL_ATTR0_CU_DIRECT_DAMAGE
Definition SpellInfo.h:185
void DoAllEffectOnLaunchTarget(TargetInfo &targetInfo, float *multiplier)
Definition Spell.cpp:8344

References DoAllEffectOnLaunchTarget(), TargetInfo::effectMask, SpellInfo::Effects, FinishTargetProcessing(), Unit::GetAuraEffectsByType(), Object::GetGUID(), ObjectAccessor::GetUnit(), HandleEffects(), SpellInfo::HasAttribute(), SpellInfo::HasEffect(), SpellInfo::HasInitialAggro(), Unit::IsEngaged(), Unit::IsFriendlyTo(), SpellInfo::IsPositive(), SpellInfo::IsTargetingArea(), IsTriggered(), m_applyMultiplierMask, m_caster, m_originalCaster, m_spellInfo, m_UniqueTargetInfo, MAX_SPELL_EFFECTS, TargetInfo::missCondition, PrepareTargetProcessing(), Unit::SetInCombatWith(), SPELL_ATTR0_CU_DIRECT_DAMAGE, SPELL_AURA_ABILITY_CONSUME_NO_AMMO, SPELL_EFFECT_DISPEL, 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, SPELL_MISS_EVADE, SPELLFAMILY_HUNTER, SpellInfo::SpellFamilyName, TakeAmmo(), and TargetInfo::targetGUID.

Referenced by _cast().

◆ HandleThreatSpells()

void Spell::HandleThreatSpells ( )
5552{
5553 if (m_UniqueTargetInfo.empty())
5554 return;
5555
5557 return;
5558
5560
5561 float threat = 0.0f;
5562 if (SpellThreatEntry const* threatEntry = sSpellMgr->GetSpellThreatEntry(m_spellInfo->Id))
5563 {
5564 if (threatEntry->apPctMod != 0.0f)
5565 threat += threatEntry->apPctMod * unitCaster->GetTotalAttackPowerValue(BASE_ATTACK);
5566
5567 threat += threatEntry->flatMod;
5568 }
5570 threat += m_spellInfo->SpellLevel;
5571
5572 // past this point only multiplicative effects occur
5573 if (threat == 0.0f)
5574 return;
5575
5576 // 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
5577 threat /= m_UniqueTargetInfo.size();
5578
5579 for (auto& ihit : m_UniqueTargetInfo)
5580 {
5581 float threatToAdd = threat;
5582 if (ihit.missCondition != SPELL_MISS_NONE)
5583 threatToAdd = 0.0f;
5584
5585 Unit* target = ObjectAccessor::GetUnit(*unitCaster, ihit.targetGUID);
5586 if (!target)
5587 continue;
5588
5589 // positive spells distribute threat among all units that are in combat with target, like healing
5591 target->GetThreatMgr().ForwardThreatForAssistingMe(unitCaster, threatToAdd, m_spellInfo);
5592 // for negative spells threat gets distributed among affected targets
5593 // ignoreModifiers=true because flat SpellThreatEntry threat should not have modifiers applied twice
5594 else
5595 {
5596 if (!target->CanHaveThreatList())
5597 continue;
5598 target->GetThreatMgr().AddThreat(unitCaster, threatToAdd, m_spellInfo, true);
5599 }
5600 }
5601 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()));
5602}
@ SPELL_ATTR0_CU_NO_INITIAL_THREAT
Definition SpellInfo.h:181
bool _IsPositiveSpell() const
Definition SpellInfo.cpp:3233
Definition SpellMgr.h:375

References SpellInfo::_IsPositiveSpell(), ThreatManager::AddThreat(), BASE_ATTACK, Unit::CanHaveThreatList(), ThreatManager::ForwardThreatForAssistingMe(), Unit::GetThreatMgr(), Unit::GetTotalAttackPowerValue(), ObjectAccessor::GetUnit(), SpellInfo::HasAttribute(), SpellInfo::Id, LOG_DEBUG, m_caster, m_originalCaster, m_spellInfo, m_UniqueTargetInfo, SPELL_ATTR0_CU_NO_INITIAL_THREAT, SPELL_ATTR1_NO_THREAT, SPELL_ATTR3_SUPPRESS_TARGET_PROCS, SPELL_MISS_NONE, SpellInfo::SpellLevel, and sSpellMgr.

Referenced by _handle_immediate_phase().

◆ HasGlobalCooldown()

bool Spell::HasGlobalCooldown ( ) const
protected

◆ HasTriggeredCastFlag()

◆ HaveTargetsForEffect()

bool Spell::HaveTargetsForEffect ( uint8  effect) const
8141{
8142 for (std::list<TargetInfo>::const_iterator itr = m_UniqueTargetInfo.begin(); itr != m_UniqueTargetInfo.end(); ++itr)
8143 if (itr->effectMask & (1 << effect))
8144 return true;
8145
8146 for (std::list<GOTargetInfo>::const_iterator itr = m_UniqueGOTargetInfo.begin(); itr != m_UniqueGOTargetInfo.end(); ++itr)
8147 if (itr->effectMask & (1 << effect))
8148 return true;
8149
8150 for (std::list<ItemTargetInfo>::const_iterator itr = m_UniqueItemInfo.begin(); itr != m_UniqueItemInfo.end(); ++itr)
8151 if (itr->effectMask & (1 << effect))
8152 return true;
8153
8154 return false;
8155}

References m_UniqueGOTargetInfo, m_UniqueItemInfo, and m_UniqueTargetInfo.

◆ InitEffectExecuteData()

void Spell::InitEffectExecuteData ( uint8  effIndex)
protected
8532{
8533 ASSERT(effIndex < MAX_SPELL_EFFECTS);
8534 if (!m_effectExecuteData[effIndex])
8535 {
8536 m_effectExecuteData[effIndex] = new ByteBuffer(0x20);
8537 // first dword - target counter
8538 *m_effectExecuteData[effIndex] << uint32(1);
8539 }
8540 else
8541 {
8542 // increase target counter by one
8543 uint32 count = (*m_effectExecuteData[effIndex]).read<uint32>(0);
8544 (*m_effectExecuteData[effIndex]).put<uint32>(0, ++count);
8545 }
8546}

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

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

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

◆ IsAutoActionResetSpell()

bool Spell::IsAutoActionResetSpell ( ) const
Todo:
changed SPELL_INTERRUPT_FLAG_AUTOATTACK -> SPELL_INTERRUPT_FLAG_INTERRUPT to fix compile - is this check correct at all?
8115{
8118 {
8119 return false;
8120 }
8121
8123 {
8124 return false;
8125 }
8126
8127 return true;
8128}
@ SPELL_ATTR6_DOESNT_RESET_SWING_TIMER_IF_INSTANT
Definition SharedDefines.h:617

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
650 {
651 if (m_delayAtDamageCount >= 2)
652 return true;
653
655 return false;
656 }

References m_delayAtDamageCount.

Referenced by Delayed(), and DelayedChannel().

◆ IsDeletable()

◆ IsIgnoringCooldowns()

bool Spell::IsIgnoringCooldowns ( ) const

◆ IsInterruptable()

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

References m_executedCurrently.

Referenced by Unit::InterruptSpell().

◆ IsNeedSendToClient()

◆ IsNextMeleeSwingSpell()

bool Spell::IsNextMeleeSwingSpell ( ) const

◆ IsProcDisabled()

bool Spell::IsProcDisabled ( ) const
inline
@ TRIGGERED_DISALLOW_PROC_EVENTS
Will ignore caster aura restrictions or requirements.
Definition SpellDefines.h:148

References HasTriggeredCastFlag(), and TRIGGERED_DISALLOW_PROC_EVENTS.

Referenced by Unit::TriggerAurasProcOnEvent().

◆ IsTriggered()

◆ IsValidDeadOrAliveTarget()

bool Spell::IsValidDeadOrAliveTarget ( Unit const *  target) const
protected
8263{
8264 if (target->IsAlive())
8266
8268}
bool IsRequiringDeadTarget() const
Definition SpellInfo.cpp:1254
bool IsAllowingDeadTarget() const
Definition SpellInfo.cpp:1259

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

Referenced by UpdateChanneledTargetList().

◆ LoadScripts()

void Spell::LoadScripts ( )
8555{
8556 if (_scriptsLoaded)
8557 return;
8558 _scriptsLoaded = true;
8559 sScriptMgr->CreateSpellScripts(m_spellInfo->Id, m_loadedScripts);
8560 for (std::list<SpellScript*>::iterator itr = m_loadedScripts.begin(); itr != m_loadedScripts.end();)
8561 {
8562 if (!(*itr)->_Load(this))
8563 {
8564 std::list<SpellScript*>::iterator bitr = itr;
8565 ++itr;
8566 delete (*bitr);
8567 m_loadedScripts.erase(bitr);
8568 continue;
8569 }
8570 LOG_DEBUG("spells.aura", "Spell::LoadScripts: Script `{}` for spell `{}` is loaded now", (*itr)->_GetScriptName()->c_str(), m_spellInfo->Id);
8571 (*itr)->Register();
8572 ++itr;
8573 }
8574}

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 ( )
8960{
8961 if (!m_caster || !m_caster->IsInWorld())
8962 return;
8963
8964 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(24390);
8965
8966 // Make sure the player is sending a valid GO target and lock ID. SPELL_EFFECT_OPEN_LOCK
8967 // can succeed with a lockId of 0
8968 if (m_spellInfo->Id == 21651)
8969 {
8970 if (GameObject* go = m_targets.GetGOTarget())
8971 {
8972 LockEntry const* lockInfo = sLockStore.LookupEntry(go->GetGOInfo()->GetLockId());
8973 if (lockInfo && lockInfo->Index[1] == LOCKTYPE_SLOW_OPEN)
8974 {
8975 Spell* visual = new Spell(m_caster, spellInfo, TRIGGERED_NONE);
8976 visual->prepare(&m_targets);
8977 }
8978 }
8979 }
8980}
@ LOCKTYPE_SLOW_OPEN
Definition SharedDefines.h:2612
@ TRIGGERED_NONE
Definition SpellDefines.h:133

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

Referenced by prepare().

◆ prepare()

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

m_castItemGUID &&

3425{
3426 if (m_CastItem)
3427 {
3429 }
3430 else
3431 {
3433 }
3434
3435 InitExplicitTargets(*targets);
3436
3437 if (!sScriptMgr->CanPrepare(this, targets, triggeredByAura))
3438 {
3439 finish(false);
3440 return SPELL_FAILED_UNKNOWN;
3441 }
3442
3443 // Fill aura scaling information
3445 {
3446 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
3447 {
3448 if (m_spellInfo->Effects[i].Effect == SPELL_EFFECT_APPLY_AURA ||
3451 {
3452 // Change aura with ranks only if basepoints are taken from spellInfo and aura is positive
3454 {
3455 m_auraScaleMask |= (1 << i);
3456 if (m_spellValue->EffectBasePoints[i] != m_spellInfo->Effects[i].BasePoints)
3457 {
3458 m_auraScaleMask = 0;
3459 break;
3460 }
3461 }
3462 }
3463 }
3464 }
3465
3467
3468 if (triggeredByAura)
3469 {
3470 m_triggeredByAuraSpell.Init(triggeredByAura);
3471 }
3472
3473 // create and add update event for this spell
3474 _spellEvent = new SpellEvent(this);
3476
3477 if (sDisableMgr->IsDisabledFor(DISABLE_TYPE_SPELL, m_spellInfo->Id, m_caster))
3478 {
3480 finish(false);
3482 }
3483
3484 //Prevent casting at cast another spell (ServerSide check)
3486 {
3488 finish(false);
3490 }
3491
3492 LoadScripts();
3493
3494 OnSpellLaunch();
3495
3497
3498 // Set combo point requirement
3500 m_needComboPoints = false;
3501
3502 SpellCastResult result = CheckCast(true);
3503 if (result != SPELL_CAST_OK && !IsAutoRepeat()) //always cast autorepeat dummy for triggering
3504 {
3505 // Periodic auras should be interrupted when aura triggers a spell which can't be cast
3506 // for example bladestorm aura should be removed on disarm as of patch 3.3.5
3507 // channeled periodic spells should be affected by this (arcane missiles, penance, etc)
3508 // a possible alternative sollution for those would be validating aura target on unit state change
3509 if (m_caster->IsPlayer() && triggeredByAura && triggeredByAura->IsPeriodic() && !triggeredByAura->GetBase()->IsPassive())
3510 {
3512 triggeredByAura->GetBase()->SetDuration(0);
3513 }
3514
3515 // Allows to cast melee attack spell if result is SPELL_FAILED_OUT_OF_RANGE
3517 {
3518 SendCastResult(result);
3519
3520 finish(false);
3521 return result;
3522 }
3523 }
3524
3525 // Prepare data for triggers
3526 prepareDataForTriggerSystem(triggeredByAura);
3527
3528 // calculate cast time (calculated after first CheckCast check to prevent charge counting for first CheckCast fail)
3530
3531 if (m_caster->IsPlayer())
3533 m_casttime = 0;
3534
3535 // don't allow channeled spells / spells with cast time to be casted while moving
3536 // (even if they are interrupted on moving, spells with almost immediate effect get to have their effect processed before movement interrupter kicks in)
3538 {
3539 // 1. Has casttime, 2. Or doesn't have flag to allow action during channel
3541 {
3543 finish(false);
3544 return SPELL_FAILED_MOVING;
3545 }
3546 }
3547
3548 // xinef: if spell have nearby target entry only, do not allow to cast if no targets are found
3549 if (m_CastItem)
3550 {
3551 bool selectTargets = false;
3552 bool nearbyDest = false;
3553
3554 for (uint8 i = EFFECT_0; i < MAX_SPELL_EFFECTS; ++i)
3555 {
3556 if (!m_spellInfo->Effects[i].IsEffect())
3557 continue;
3558
3559 if (m_spellInfo->Effects[i].TargetA.GetSelectionCategory() != TARGET_SELECT_CATEGORY_NEARBY || m_spellInfo->Effects[i].TargetA.GetCheckType() != TARGET_CHECK_ENTRY)
3560 {
3561 selectTargets = false;
3562 break;
3563 }
3564
3565 if (m_spellInfo->Effects[i].TargetA.GetObjectType() == TARGET_OBJECT_TYPE_DEST)
3566 {
3567 nearbyDest = true;
3568 }
3569
3570 // xinef: by default set it to false, and to true if any valid target is found
3571 selectTargets = true;
3572 }
3573
3574 if (selectTargets)
3575 {
3577 _spellTargetsSelected = true;
3578 bool spellFailed = false;
3579
3580 if (m_UniqueTargetInfo.empty() && m_UniqueGOTargetInfo.empty())
3581 {
3582 // no valid nearby target unit or game object found; check if nearby destination type
3583 if (nearbyDest)
3584 {
3585 if (!m_targets.HasDst())
3586 {
3587 // no valid target destination
3588 spellFailed = true;
3589 }
3590 }
3591 else
3592 {
3593 spellFailed = true;
3594 }
3595 }
3596
3597 if (spellFailed)
3598 {
3600 finish(false);
3602 }
3603 }
3604 }
3605
3606 // set timer base at cast time
3607 ReSetTimer();
3608
3609 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());
3610
3611 // prevent exploit that allows to cast spell while sitting
3614
3615 //Containers for channeled spells have to be set
3616 //TODO:Apply this to all casted spells if needed
3617 // Why check duration? 29350: channelled triggers channelled
3619 cast(true);
3620 else
3621 {
3622 // stealth must be removed at cast starting (at show channel bar)
3623 // skip triggered spell (item equip spell casting and other not explicit character casts/item uses)
3625 {
3626 // Farsight spells exception
3627 uint32 exceptSpellId = 0;
3629 {
3630 exceptSpellId = m_spellInfo->Id;
3631 }
3632
3635 }
3636
3639
3640 // Call CreatureAI hook OnSpellStart for spells with cast time or channeled spells
3641 if (m_casttime > 0 || m_spellInfo->IsChanneled())
3642 if (Creature* caster = m_caster->ToCreature())
3643 if (caster->IsAIEnabled)
3644 caster->AI()->OnSpellStart(GetSpellInfo());
3645
3646 // set target for proper facing
3648 {
3651 {
3652 // Xinef: Creature should focus to cast target if there is explicit target or self if casting positive spell
3653 // Xinef: Creature should not rotate when casting spell... based on halion behavior
3655 }
3656 }
3657
3658 //item: first cast may destroy item and second cast causes crash
3659 // xinef: removed !m_spellInfo->StartRecoveryTime
3660 // second los check failed in events
3661 // xinef: removed itemguid check, currently there is no such item in database
3663 cast(true);
3664
3667 }
3668
3669 sScriptMgr->OnSpellPrepare(this, m_caster, m_spellInfo);
3670
3671 return SPELL_CAST_OK;
3672}
@ CHEAT_CASTTIME
Definition Player.h:996
@ SPELL_EFFECT_APPLY_AREA_AURA_PARTY
Definition SharedDefines.h:801
@ SPELL_EFFECT_APPLY_AREA_AURA_RAID
Definition SharedDefines.h:831
@ SPELL_ATTR0_ALLOW_WHILE_SITTING
Definition SharedDefines.h:397
@ AURA_INTERRUPT_FLAG_SPELL_ATTACK
Definition SpellDefines.h:56
@ AURA_INTERRUPT_FLAG_CAST
Definition SpellDefines.h:45
@ TRIGGERED_IGNORE_AURA_SCALING
Will not take away cast item or update related achievement criteria.
Definition SpellDefines.h:138
@ TRIGGERED_IGNORE_AURA_INTERRUPT_FLAGS
In Spell::prepare, will be cast directly without setting containers for executed spell.
Definition SpellDefines.h:142
@ TRIGGERED_IGNORE_COMBO_POINTS
Will not check if a current cast is in progress.
Definition SpellDefines.h:140
@ SPELL_INTERRUPT_FLAG_MOVEMENT
Definition SpellDefines.h:26
@ TARGET_SELECT_CATEGORY_NEARBY
Definition SpellInfo.h:81
@ TARGET_OBJECT_TYPE_DEST
Definition SpellInfo.h:101
void FocusTarget(Spell const *focusSpell, WorldObject const *target)
Definition Creature.cpp:3557
Definition Spell.cpp:519
bool IsActionAllowedChannel() const
Definition SpellInfo.cpp:1293
int32 GetMaxDuration() const
Definition SpellInfo.cpp:2745
uint32 Attributes
Definition SpellInfo.h:348
bool IsBreakingStealth() const
Definition SpellInfo.cpp:1303
void LoadScripts()
Definition Spell.cpp:8554
void cast(bool skipCheck=false)
Definition Spell.cpp:3747
void prepareDataForTriggerSystem(AuraEffect const *triggeredByAura)
Definition Spell.cpp:2220
void SendSpellStart()
Definition Spell.cpp:4687
void TriggerGlobalCooldown()
Definition Spell.cpp:8898
void OnSpellLaunch()
Definition Spell.cpp:8959
CurrentSpellTypes GetCurrentContainer() const
Definition Spell.cpp:7950
void ReSetTimer()
Definition Spell.h:565
void InitExplicitTargets(SpellCastTargets const &targets)
Definition Spell.cpp:720
void SetCurrentCastedSpell(Spell *pSpell)
Definition Unit.cpp:4159
bool IsSitState() const
Definition Unit.cpp:13124
void Init(AuraEffect const *aurEff)
Definition Spell.cpp:8982

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

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

◆ prepareDataForTriggerSystem()

void Spell::prepareDataForTriggerSystem ( AuraEffect const *  triggeredByAura)
protected
2221{
2222 //==========================================================================================
2223 // Now fill data for trigger system, need know:
2224 // can spell trigger another or not (m_canTrigger)
2225 // Create base triggers flags for Attacker and Victim (m_procAttacker, m_procVictim and m_procEx)
2226 //==========================================================================================
2227
2229 // Get data for type of attack and fill base info for trigger
2230 switch (m_spellInfo->DmgClass)
2231 {
2234 if (m_attackType == OFF_ATTACK)
2236 else
2239 break;
2241 // Auto attack
2243 {
2246 }
2247 else // Ranged spell attack
2248 {
2251 }
2252 break;
2253 default:
2256 && m_spellInfo->HasAttribute(SPELL_ATTR2_AUTO_REPEAT)) // Wands auto attack
2257 {
2260 }
2261 // For other spells trigger procflags are set in Spell::DoAllEffectOnTarget
2262 // Because spell positivity is dependant on target
2263 }
2265
2266 // Hunter trap spells - activation proc for Lock and Load, Entrapment and Misdirection
2268 (m_spellInfo->SpellFamilyFlags[0] & 0x18 || // Freezing and Frost Trap, Freezing Arrow
2269 m_spellInfo->Id == 57879 || // Snake Trap - done this way to avoid double proc
2270 m_spellInfo->SpellFamilyFlags[2] & 0x00024000)) // Explosive and Immolation Trap
2271 {
2273
2274 // also fill up other flags (TargetInfo::DoDamageAndTriggers only fills up flag if both are not set)
2277 }
2278
2279 /* Effects which are result of aura proc from triggered spell cannot proc
2280 to prevent chain proc of these spells */
2281
2282 // Hellfire Effect - trigger as DOT
2284 {
2287 }
2288
2289 // Ranged autorepeat attack is set as triggered spell - ignore it
2291 {
2298 }
2299 // Totem casts require spellfamilymask defined in spell_proc to proc
2302}
@ SPELL_ATTR2_ACTIVE_THREAT
Definition SharedDefines.h:474
@ SPELL_ATTR3_NOT_A_PROC
Definition SharedDefines.h:490
@ PROC_EX_NONE
Definition SpellMgr.h:198
@ PROC_EX_INTERNAL_CANT_PROC
Definition SpellMgr.h:223
@ PROC_EX_INTERNAL_TRIGGERED
Definition SpellMgr.h:226
@ PROC_EX_INTERNAL_REQ_FAMILY
Definition SpellMgr.h:227
@ PROC_FLAG_DONE_SPELL_RANGED_DMG_CLASS
Definition SpellMgr.h:122
@ PROC_FLAG_TAKEN_RANGED_AUTO_ATTACK
Definition SpellMgr.h:120
@ PROC_FLAG_DONE_PERIODIC
Definition SpellMgr.h:137
@ PROC_FLAG_DONE_SPELL_MELEE_DMG_CLASS
Definition SpellMgr.h:116
@ PROC_FLAG_TAKEN_SPELL_RANGED_DMG_CLASS
Definition SpellMgr.h:123
@ PROC_FLAG_TAKEN_PERIODIC
Definition SpellMgr.h:138
@ PROC_FLAG_DONE_MAINHAND_ATTACK
Definition SpellMgr.h:143
@ PROC_FLAG_DONE_RANGED_AUTO_ATTACK
Definition SpellMgr.h:119
@ PROC_FLAG_TAKEN_SPELL_MELEE_DMG_CLASS
Definition SpellMgr.h:117
@ PROC_FLAG_DONE_OFFHAND_ATTACK
Definition SpellMgr.h:144

References SpellInfo::DmgClass, SpellInfo::EquippedItemClass, SpellInfo::EquippedItemSubClassMask, SpellInfo::HasAttribute(), HasTriggeredCastFlag(), SpellInfo::Id, Unit::IsControlledByPlayer(), Object::IsCreature(), Unit::IsTotem(), ITEM_CLASS_WEAPON, ITEM_SUBCLASS_WEAPON_WAND, m_attackType, m_caster, m_originalCaster, m_procAttacker, m_procEx, m_procVictim, m_spellInfo, OFF_ATTACK, PROC_EX_INTERNAL_CANT_PROC, PROC_EX_INTERNAL_REQ_FAMILY, PROC_EX_INTERNAL_TRIGGERED, PROC_EX_NONE, PROC_FLAG_DONE_MAINHAND_ATTACK, PROC_FLAG_DONE_OFFHAND_ATTACK, PROC_FLAG_DONE_PERIODIC, PROC_FLAG_DONE_RANGED_AUTO_ATTACK, PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG, 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_MAGIC_DMG_CLASS_NEG, PROC_FLAG_TAKEN_SPELL_MELEE_DMG_CLASS, PROC_FLAG_TAKEN_SPELL_RANGED_DMG_CLASS, SPELL_ATTR2_ACTIVE_THREAT, SPELL_ATTR2_AUTO_REPEAT, SPELL_ATTR3_NOT_A_PROC, SPELL_DAMAGE_CLASS_MELEE, SPELL_DAMAGE_CLASS_RANGED, SPELLFAMILY_HUNTER, SPELLFAMILY_WARLOCK, SpellInfo::SpellFamilyFlags, SpellInfo::SpellFamilyName, Object::ToCreature(), and TRIGGERED_DISALLOW_PROC_EVENTS.

Referenced by prepare().

◆ PrepareScriptHitHandlers()

void Spell::PrepareScriptHitHandlers ( )
protected
8635{
8636 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8637 (*scritr)->_InitHit();
8638}

References m_loadedScripts.

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

◆ PrepareTargetProcessing()

void Spell::PrepareTargetProcessing ( )
protected

◆ PrepareTriggersExecutedOnHit()

void Spell::PrepareTriggersExecutedOnHit ( )
protected
Todo:
: move this to scripts
Todo:
: move this to scripts
8809{
8812 {
8813 SpellInfo const* excludeCasterSpellInfo = sSpellMgr->GetSpellInfo(m_spellInfo->ExcludeCasterAuraSpell);
8814 if (excludeCasterSpellInfo && !excludeCasterSpellInfo->IsPositive())
8816 SpellInfo const* excludeTargetSpellInfo = sSpellMgr->GetSpellInfo(m_spellInfo->ExcludeTargetAuraSpell);
8817 if (excludeTargetSpellInfo && !excludeTargetSpellInfo->IsPositive())
8819 }
8820
8823 {
8825 {
8826 if (m_spellInfo->SpellFamilyFlags[1] & 0x40000000)
8827 {
8829 for(Unit::AuraEffectList::const_iterator itr = mVindication.begin(); itr != mVindication.end(); ++itr)
8830 {
8831 if ((*itr)->GetSpellInfo()->Effects[EFFECT_0].TriggerSpell == 26017 )
8832 {
8833 m_preCastSpell = 26017;
8834 break;
8835 }
8836 else if ((*itr)->GetSpellInfo()->Effects[EFFECT_0].TriggerSpell == 67 )
8837 m_preCastSpell = 67;
8838 }
8839 }
8840 break;
8841 }
8842 case SPELLFAMILY_DRUID:
8843 {
8844 // Faerie Fire (Feral)
8846 m_preCastSpell = 60089;
8847
8848 break;
8849 }
8850 }
8851
8852 // handle SPELL_AURA_ADD_TARGET_TRIGGER auras:
8853 // save auras which were present on spell caster on cast, to prevent triggered auras from affecting caster
8854 // and to correctly calculate proc chance when combopoints are present
8856 for (Unit::AuraEffectList::const_iterator i = targetTriggers.begin(); i != targetTriggers.end(); ++i)
8857 {
8858 if (!(*i)->IsAffectedOnSpell(m_spellInfo))
8859 continue;
8860 SpellInfo const* auraSpellInfo = (*i)->GetSpellInfo();
8861 uint32 auraSpellIdx = (*i)->GetEffIndex();
8862 if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(auraSpellInfo->Effects[auraSpellIdx].TriggerSpell))
8863 {
8864 // calculate the chance using spell base amount, because aura amount is not updated on combo-points change
8865 // this possibly needs fixing
8866 int32 auraBaseAmount = (*i)->GetBaseAmount();
8867 // proc chance is stored in effect amount
8868 int32 chance = m_caster->CalculateSpellDamage(nullptr, auraSpellInfo, auraSpellIdx, &auraBaseAmount);
8869 // build trigger and add to the list
8870 HitTriggerSpell spellTriggerInfo;
8871 spellTriggerInfo.triggeredSpell = spellInfo;
8872 spellTriggerInfo.triggeredByAura = auraSpellInfo;
8873 spellTriggerInfo.triggeredByEffIdx = (*i)->GetEffIndex();
8874 spellTriggerInfo.chance = chance * (*i)->GetBase()->GetStackAmount();
8875 m_hitTriggerSpells.push_back(spellTriggerInfo);
8876 }
8877 }
8878}
@ SPELL_AURA_PROC_TRIGGER_SPELL
Definition SpellAuraDefines.h:105
@ SPELL_AURA_ADD_TARGET_TRIGGER
Definition SpellAuraDefines.h:172
@ FORM_DIREBEAR
Definition UnitDefines.h:80
@ FORM_BEAR
Definition UnitDefines.h:77
uint32 ExcludeTargetAuraSpell
Definition SpellInfo.h:370

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 ( )
925{
928}
void ModifyEventTime(BasicEvent *event, Milliseconds newTime)
Definition EventProcessor.cpp:145
uint64 CalculateDelayMomentForDst() const
Definition Spell.cpp:903
uint64 GetDelayStart() const
Definition Spell.h:579

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

Referenced by WorldSession::HandleUpdateProjectilePosition().

◆ ReSetTimer()

void Spell::ReSetTimer ( )
inline
565{ 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,
Acore::WorldObjectSpellAreaTargetSearchReason  searchReason = Acore::WorldObjectSpellAreaTargetSearchReason::Area 
)
2114{
2115 uint32 containerTypeMask = GetSearcherTypeMask(objectType, condList);
2116 if (!containerTypeMask)
2117 return;
2118 Acore::WorldObjectSpellAreaTargetCheck check(range, position, m_caster, referer, m_spellInfo, selectionType, condList, searchReason);
2119 Acore::WorldObjectListSearcher<Acore::WorldObjectSpellAreaTargetCheck> searcher(m_caster, targets, check, containerTypeMask);
2120 SearchTargets<Acore::WorldObjectListSearcher<Acore::WorldObjectSpellAreaTargetCheck> > (searcher, containerTypeMask, m_caster, position, range);
2121}
uint32 GetSearcherTypeMask(SpellTargetObjectTypes objType, ConditionList *condList)
Definition Spell.cpp:2056
Definition GridNotifiers.h:260

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 
)
2124{
2125 // max dist for jump target selection
2126 float jumpRadius = 0.0f;
2127 switch (m_spellInfo->DmgClass)
2128 {
2130 // 7.5y for multi shot
2131 jumpRadius = 7.5f;
2132 break;
2134 // 10y for swipe, cleave and similar
2135 jumpRadius = 10.0f;
2136 break;
2139 // 12.5y for chain heal spell since 3.2 patch
2140 if (isChainHeal)
2141 jumpRadius = 12.5f;
2142 // 10y as default for magic chain spells
2143 else
2144 jumpRadius = 10.0f;
2145 break;
2146 }
2147
2148 // per-spell override from spell_jump_distance table
2149 if (m_spellInfo->JumpDistance > 0.0f)
2150 jumpRadius = m_spellInfo->JumpDistance;
2151
2152 // chain lightning/heal spells and similar - allow to jump at larger distance and go out of los
2156
2157 // max dist which spell can reach
2158 float searchRadius = jumpRadius;
2159 if (isBouncingFar)
2160 searchRadius *= chainTargets;
2161
2163 std::list<WorldObject*> tempTargets;
2164 SearchAreaTargets(tempTargets, searchRadius, chainSource, m_caster, objectType, selectType, condList, Acore::WorldObjectSpellAreaTargetSearchReason::Chain);
2165 tempTargets.remove(target);
2166
2167 // remove targets which are always invalid for chain spells
2168 // for some spells allow only chain targets in front of caster (swipe for example)
2169 if (!isBouncingFar)
2170 tempTargets.remove_if([this](WorldObject* target) { return !m_caster->HasInArc(static_cast<float>(M_PI), target); });
2171
2172 while (chainTargets)
2173 {
2174 // try to get unit for next chain jump
2175 std::list<WorldObject*>::iterator foundItr = tempTargets.end();
2176 // get unit with highest hp deficit in dist
2177 if (isChainHeal)
2178 {
2179 uint32 maxHPDeficit = 0;
2180 for (std::list<WorldObject*>::iterator itr = tempTargets.begin(); itr != tempTargets.end(); ++itr)
2181 {
2182 if (Unit* unit = (*itr)->ToUnit())
2183 {
2184 uint32 deficit = unit->GetMaxHealth() - unit->GetHealth();
2185 if (deficit > maxHPDeficit && chainSource->IsWithinDist(unit, jumpRadius) && chainSource->IsWithinLOSInMap(unit, VMAP::ModelIgnoreFlags::M2))
2186 {
2187 foundItr = itr;
2188 maxHPDeficit = deficit;
2189 }
2190 }
2191 }
2192 }
2193 // get closest object
2194 else
2195 {
2196 for (std::list<WorldObject*>::iterator itr = tempTargets.begin(); itr != tempTargets.end(); ++itr)
2197 {
2198 if (foundItr == tempTargets.end())
2199 {
2200 if ((!isBouncingFar || chainSource->IsWithinDist(*itr, jumpRadius)) && chainSource->IsWithinLOSInMap(*itr, VMAP::ModelIgnoreFlags::M2))
2201 foundItr = itr;
2202 }
2203 else if (chainSource->GetDistanceOrder(*itr, *foundItr) && chainSource->IsWithinLOSInMap(*itr, VMAP::ModelIgnoreFlags::M2))
2204 foundItr = itr;
2205 }
2206 }
2207 // not found any valid target - chain ends
2208 if (foundItr == tempTargets.end())
2209 break;
2210
2212 chainSource = *foundItr;
2213
2214 targets.push_back(*foundItr);
2215 tempTargets.erase(foundItr);
2216 --chainTargets;
2217 }
2218}
@ SPELL_ATTR2_CHAIN_FROM_CASTER
Definition SharedDefines.h:456
@ SPELL_ATTR4_BOUNCY_CHAIN_MISSILES
Definition SharedDefines.h:536
float JumpDistance
Definition SpellInfo.h:428
void SearchAreaTargets(std::list< WorldObject * > &targets, float range, Position const *position, Unit *referer, SpellTargetObjectTypes objectType, SpellTargetCheckTypes selectionType, ConditionList *condList, Acore::WorldObjectSpellAreaTargetSearchReason searchReason=Acore::WorldObjectSpellAreaTargetSearchReason::Area)
Definition Spell.cpp:2113
bool GetDistanceOrder(WorldObject const *obj1, WorldObject const *obj2, bool is3D=true) const
Definition Object.cpp:1437
bool IsWithinDist(WorldObject const *obj, float dist2compare, bool is3D=true, bool incOwnRadius=true, bool incTargetRadius=true) const
Definition Object.cpp:1372

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

Referenced by SelectImplicitChainTargets().

◆ SearchNearbyTarget()

WorldObject * Spell::SearchNearbyTarget ( float  range,
SpellTargetObjectTypes  objectType,
SpellTargetCheckTypes  selectionType,
ConditionList condList = nullptr 
)
2102{
2103 WorldObject* target = nullptr;
2104 uint32 containerTypeMask = GetSearcherTypeMask(objectType, condList);
2105 if (!containerTypeMask)
2106 return nullptr;
2107 Acore::WorldObjectSpellNearbyTargetCheck check(range, m_caster, m_spellInfo, selectionType, condList);
2109 SearchTargets<Acore::WorldObjectLastSearcher<Acore::WorldObjectSpellNearbyTargetCheck> > (searcher, containerTypeMask, m_caster, m_caster, range);
2110 return target;
2111}
Definition GridNotifiers.h:240

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 
)
2094{
2095 if (!containerMask)
2096 return;
2097
2098 Cell::VisitObjects(pos->GetPositionX(), pos->GetPositionY(), referer->GetMap(), searcher, radius);
2099}

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

◆ SelectEffectImplicitTargets()

void Spell::SelectEffectImplicitTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType,
uint32 processedEffectMask 
)
931{
932 if (!targetType.GetTarget())
933 return;
934
935 uint32 effectMask = 1 << effIndex;
936 // set the same target list for all effects
937 // some spells appear to need this, however this requires more research
938 switch (targetType.GetSelectionCategory())
939 {
943 {
944 // targets for effect already selected
945 if (effectMask & processedEffectMask)
946 {
947 return;
948 }
949
950 auto const& effects = GetSpellInfo()->Effects;
951
952 // choose which targets we can select at once
953 for (uint32 j = effIndex + 1; j < MAX_SPELL_EFFECTS; ++j)
954 {
955 if (effects[j].IsEffect() &&
956 effects[effIndex].TargetA.GetTarget() == effects[j].TargetA.GetTarget() &&
957 effects[effIndex].TargetB.GetTarget() == effects[j].TargetB.GetTarget() &&
958 effects[effIndex].ImplicitTargetConditions == effects[j].ImplicitTargetConditions &&
959 effects[effIndex].CalcRadius(m_caster) == effects[j].CalcRadius(m_caster) &&
961 {
962 effectMask |= 1 << j;
963 }
964 }
965 processedEffectMask |= effectMask;
966 break;
967 }
968 default:
969 break;
970 }
971
972 switch (targetType.GetSelectionCategory())
973 {
975 SelectImplicitChannelTargets(effIndex, targetType);
976 break;
978 SelectImplicitNearbyTargets(effIndex, targetType, effectMask);
979 break;
981 SelectImplicitConeTargets(effIndex, targetType, effectMask);
982 break;
984 SelectImplicitAreaTargets(effIndex, targetType, effectMask);
985 break;
987 // just in case there is no dest, explanation in SelectImplicitDestDestTargets
988 CheckDst();
989
990 SelectImplicitTrajTargets(effIndex, targetType);
991 break;
993 switch (targetType.GetObjectType())
994 {
996 switch (targetType.GetReferenceType())
997 {
1000 break;
1001 default:
1002 ASSERT(false && "Spell::SelectEffectImplicitTargets: received not implemented select target reference type for TARGET_TYPE_OBJECT_SRC");
1003 break;
1004 }
1005 break;
1007 switch (targetType.GetReferenceType())
1008 {
1010 SelectImplicitCasterDestTargets(effIndex, targetType);
1011 break;
1013 SelectImplicitTargetDestTargets(effIndex, targetType);
1014 break;
1016 SelectImplicitDestDestTargets(effIndex, targetType);
1017 break;
1018 default:
1019 ASSERT(false && "Spell::SelectEffectImplicitTargets: received not implemented select target reference type for TARGET_TYPE_OBJECT_DEST");
1020 break;
1021 }
1022 break;
1023 default:
1024 switch (targetType.GetReferenceType())
1025 {
1027 SelectImplicitCasterObjectTargets(effIndex, targetType);
1028 break;
1030 SelectImplicitTargetObjectTargets(effIndex, targetType);
1031 break;
1032 default:
1033 ASSERT(false && "Spell::SelectEffectImplicitTargets: received not implemented select target reference type for TARGET_TYPE_OBJECT");
1034 break;
1035 }
1036 break;
1037 }
1038 break;
1040 LOG_DEBUG("spells.aura", "SPELL: target type {}, found in spellID {}, effect {} is not implemented yet!", m_spellInfo->Id, effIndex, targetType.GetTarget());
1041 break;
1042 default:
1043 ASSERT(false && "Spell::SelectEffectImplicitTargets: received not implemented select target category");
1044 break;
1045 }
1046}
@ TARGET_SELECT_CATEGORY_CONE
Definition SpellInfo.h:82
@ TARGET_SELECT_CATEGORY_AREA
Definition SpellInfo.h:83
@ TARGET_SELECT_CATEGORY_DEFAULT
Definition SpellInfo.h:79
@ TARGET_SELECT_CATEGORY_NYI
Definition SpellInfo.h:78
@ TARGET_SELECT_CATEGORY_TRAJ
Definition SpellInfo.h:84
@ TARGET_SELECT_CATEGORY_CHANNEL
Definition SpellInfo.h:80
@ TARGET_OBJECT_TYPE_SRC
Definition SpellInfo.h:100
@ TARGET_REFERENCE_TYPE_TARGET
Definition SpellInfo.h:91
@ TARGET_REFERENCE_TYPE_CASTER
Definition SpellInfo.h:90
@ TARGET_REFERENCE_TYPE_DEST
Definition SpellInfo.h:94
void SelectImplicitDestDestTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition Spell.cpp:1744
void CheckDst()
Definition Spell.h:506
void SelectImplicitTrajTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition Spell.cpp:1890
void SelectImplicitConeTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType, uint32 effMask)
Definition Spell.cpp:1218
void SelectImplicitTargetDestTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition Spell.cpp:1707
void SelectImplicitAreaTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType, uint32 effMask)
Definition Spell.cpp:1283
void SelectImplicitChannelTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition Spell.cpp:1048
void SelectImplicitTargetObjectTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition Spell.cpp:1827
void SelectImplicitCasterObjectTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition Spell.cpp:1780
void SelectImplicitNearbyTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType, uint32 effMask)
Definition Spell.cpp:1104
bool CheckScriptEffectImplicitTargets(uint32 effIndex, uint32 effIndexToCheck)
Definition Spell.cpp:8769
void SelectImplicitCasterDestTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition Spell.cpp:1361

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
1974{
1975 // special case for SPELL_EFFECT_SUMMON_RAF_FRIEND and SPELL_EFFECT_SUMMON_PLAYER
1977 switch (m_spellInfo->Effects[effIndex].Effect)
1978 {
1982 {
1984
1986
1987 if (target && target->ToPlayer())
1988 AddUnitTarget(target->ToUnit(), 1 << effIndex, false);
1989 }
1990 return;
1991 default:
1992 break;
1993 }
1994
1995 // select spell implicit targets based on effect type
1996 if (!m_spellInfo->Effects[effIndex].GetImplicitTargetType())
1997 return;
1998
1999 uint32 targetMask = m_spellInfo->Effects[effIndex].GetMissingTargetMask();
2000
2001 if (!targetMask)
2002 return;
2003
2004 WorldObject* target = nullptr;
2005
2006 switch (m_spellInfo->Effects[effIndex].GetImplicitTargetType())
2007 {
2008 // add explicit object target or self to the target map
2010 // player which not released his spirit is Unit, but target flag for it is TARGET_FLAG_CORPSE_MASK
2012 {
2014 target = unitTarget;
2015 else if (targetMask & TARGET_FLAG_CORPSE_MASK)
2016 {
2017 if (Corpse* corpseTarget = m_targets.GetCorpseTarget())
2018 {
2020 if (Player* owner = ObjectAccessor::FindPlayer(corpseTarget->GetOwnerGUID()))
2021 target = owner;
2022 }
2023 }
2024 else //if (targetMask & TARGET_FLAG_UNIT_MASK)
2025 target = m_caster;
2026 }
2027 if (targetMask & TARGET_FLAG_ITEM_MASK)
2028 {
2030 AddItemTarget(itemTarget, 1 << effIndex);
2031 return;
2032 }
2033 if (targetMask & TARGET_FLAG_GAMEOBJECT_MASK)
2034 target = m_targets.GetGOTarget();
2035 break;
2036 // add self to the target map
2038 if (targetMask & TARGET_FLAG_UNIT_MASK)
2039 target = m_caster;
2040 break;
2041 default:
2042 break;
2043 }
2044
2046
2047 if (target)
2048 {
2049 if (target->ToUnit())
2050 AddUnitTarget(target->ToUnit(), 1 << effIndex, false);
2051 else if (target->ToGameObject())
2052 AddGOTarget(target->ToGameObject(), 1 << effIndex);
2053 }
2054}
@ EFFECT_IMPLICIT_TARGET_CASTER
Definition SpellInfo.h:145
@ EFFECT_IMPLICIT_TARGET_EXPLICIT
Definition SpellInfo.h:144
@ TARGET_FLAG_ITEM_MASK
Definition SpellInfo.h:73
GameObject * ToGameObject()
Definition Object.h:214
Corpse * GetCorpseTarget() const
Definition Spell.cpp:294
Definition SpellInfo.h:238
void AddGOTarget(GameObject *target, uint32 effectMask)
Definition Spell.cpp:2447
void AddUnitTarget(Unit *target, uint32 effectMask, bool checkIfValid=true, bool implicit=true)
Definition Spell.cpp:2313
void AddItemTarget(Item *item, uint32 effectMask)
Definition Spell.cpp:2509
void CallScriptObjectTargetSelectHandlers(WorldObject *&target, SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition Spell.cpp:8741

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

Referenced by SelectSpellTargets().

◆ SelectExplicitTargets()

void Spell::SelectExplicitTargets ( )
791{
792 // here go all explicit target changes made to explicit targets after spell prepare phase is finished
793 if (Unit* target = m_targets.GetUnitTarget())
794 {
795 // check for explicit target redirection, for Grounding Totem for example
799 {
800 Unit* redirect;
801 switch (m_spellInfo->DmgClass)
802 {
805 break;
809 break;
810 default:
811 redirect = nullptr;
812 break;
813 }
814 if (redirect && (redirect != target))
815 {
816 m_targets.SetUnitTarget(redirect);
818 }
819 }
820 }
821}
Unit * GetMeleeHitRedirectTarget(Unit *victim, SpellInfo const *spellInfo=nullptr)
Definition Unit.cpp:8180
Unit * GetMagicHitRedirectTarget(Unit *victim, SpellInfo const *spellInfo)
Definition Unit.cpp:8142

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 
)
1284{
1285 Unit* referer = nullptr;
1286 switch (targetType.GetReferenceType())
1287 {
1291 referer = m_caster;
1292 break;
1294 referer = m_targets.GetUnitTarget();
1295 break;
1297 {
1298 // find last added target for this effect
1299 for (std::list<TargetInfo>::reverse_iterator ihit = m_UniqueTargetInfo.rbegin(); ihit != m_UniqueTargetInfo.rend(); ++ihit)
1300 {
1301 if (ihit->effectMask & (1 << effIndex))
1302 {
1303 referer = ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID);
1304 break;
1305 }
1306 }
1307 break;
1308 }
1309 default:
1310 ASSERT(false && "Spell::SelectImplicitAreaTargets: received not implemented target reference type");
1311 return;
1312 }
1313 if (!referer)
1314 return;
1315
1316 Position const* center = nullptr;
1317 switch (targetType.GetReferenceType())
1318 {
1320 center = m_targets.GetSrcPos();
1321 break;
1323 center = m_targets.GetDstPos();
1324 break;
1328 center = referer;
1329 break;
1330 default:
1331 ASSERT(false && "Spell::SelectImplicitAreaTargets: received not implemented target reference type");
1332 return;
1333 }
1334
1335 // Xinef: the distance should be increased by caster size, it is neglected in latter calculations
1336 std::list<WorldObject*> targets;
1337 float radius = m_spellInfo->Effects[effIndex].CalcRadius(m_caster) * m_spellValue->RadiusMod;
1338 SearchAreaTargets(targets, radius, center, referer, targetType.GetObjectType(), targetType.GetCheckType(), m_spellInfo->Effects[effIndex].ImplicitTargetConditions, Acore::WorldObjectSpellAreaTargetSearchReason::Area);
1339
1340 CallScriptObjectAreaTargetSelectHandlers(targets, effIndex, targetType);
1341
1342 if (!targets.empty())
1343 {
1344 // Other special target selection goes here
1345 if (uint32 maxTargets = m_spellValue->MaxAffectedTargets)
1346 {
1348 Acore::Containers::RandomResize(targets, maxTargets);
1349 }
1350
1351 for (std::list<WorldObject*>::iterator itr = targets.begin(); itr != targets.end(); ++itr)
1352 {
1353 if (Unit* unitTarget = (*itr)->ToUnit())
1354 AddUnitTarget(unitTarget, effMask, false);
1355 else if (GameObject* gObjTarget = (*itr)->ToGameObject())
1356 AddGOTarget(gObjTarget, effMask);
1357 }
1358 }
1359}
@ SPELL_AURA_MOD_MAX_AFFECTED_TARGETS
Definition SpellAuraDefines.h:340
@ TARGET_REFERENCE_TYPE_SRC
Definition SpellInfo.h:93
@ TARGET_REFERENCE_TYPE_LAST
Definition SpellInfo.h:92
Position const * GetSrcPos() const
Definition Spell.cpp:362
void CallScriptObjectAreaTargetSelectHandlers(std::list< WorldObject * > &targets, SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition Spell.cpp:8727
int32 GetTotalAuraModifierByAffectMask(AuraType auratype, SpellInfo const *affectedSpell) const
Definition Unit.cpp:6403
void RandomResize(C &container, std::size_t requestedSize)
Definition Containers.h:79
float RadiusMod
Definition Spell.h:227
uint32 MaxAffectedTargets
Definition Spell.h:226

References AddGOTarget(), AddUnitTarget(), Acore::Area, ASSERT, CallScriptObjectAreaTargetSelectHandlers(), SpellInfo::Effects, SpellImplicitTargetInfo::GetCheckType(), SpellCastTargets::GetDstPos(), SpellImplicitTargetInfo::GetObjectType(), SpellImplicitTargetInfo::GetReferenceType(), SpellCastTargets::GetSrcPos(), Unit::GetTotalAuraModifierByAffectMask(), 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
1362{
1364
1365 switch (targetType.GetTarget())
1366 {
1367 case TARGET_DEST_CASTER:
1369 break;
1370 case TARGET_DEST_HOME:
1371 if (Player* playerCaster = m_caster->ToPlayer())
1372 dest = SpellDestination(playerCaster->m_homebindX, playerCaster->m_homebindY, playerCaster->m_homebindZ, playerCaster->GetOrientation(), playerCaster->m_homebindMapId);
1373 break;
1374 case TARGET_DEST_DB:
1375 if (SpellTargetPosition const* st = sSpellMgr->GetSpellTargetPosition(m_spellInfo->Id, effIndex))
1376 {
1379 dest = SpellDestination(st->target_X, st->target_Y, st->target_Z, st->target_Orientation, (int32)st->target_mapId);
1380 else if (st->target_mapId == m_caster->GetMapId())
1381 dest = SpellDestination(st->target_X, st->target_Y, st->target_Z, st->target_Orientation);
1382 }
1383 else
1384 {
1385 LOG_DEBUG("spells.aura", "SPELL: unknown target coordinates for spell ID {}", m_spellInfo->Id);
1386 if (WorldObject* target = m_targets.GetObjectTarget())
1387 dest = SpellDestination(*target);
1388 }
1389 break;
1391 {
1392 float min_dis = m_spellInfo->GetMinRange(true);
1393 float max_dis = m_spellInfo->GetMaxRange(true);
1394 float dis = (float)rand_norm() * (max_dis - min_dis) + min_dis;
1395 float x, y, z, angle;
1396 angle = (float)rand_norm() * static_cast<float>(M_PI * 35.0f / 180.0f) - static_cast<float>(M_PI * 17.5f / 180.0f);
1397 //m_caster->GetClosePoint(x, y, z, DEFAULT_WORLD_OBJECT_SIZE, dis, angle); this contains extra code that breaks fishing
1399
1400 float ground = m_caster->GetMapHeight(x, y, z, true);
1401 float liquidLevel = VMAP_INVALID_HEIGHT_VALUE;
1402 LiquidData const& liquidData = m_caster->GetMap()->GetLiquidData(m_caster->GetPhaseMask(), x, y, z, m_caster->GetCollisionHeight(), {});
1403 if (liquidData.Status)
1404 liquidLevel = liquidData.Level;
1405
1406 if (liquidLevel <= ground) // When there is no liquid Map::GetWaterOrGroundLevel returns ground level
1407 {
1410 finish(false);
1411 return;
1412 }
1413
1414 if (ground + 0.75 > liquidLevel)
1415 {
1418 finish(false);
1419 return;
1420 }
1421
1422 if (!m_caster->IsWithinLOS(x, y, z))
1423 {
1426 finish(false);
1427 return;
1428 }
1429
1430 dest = SpellDestination(x, y, liquidLevel, m_caster->GetOrientation());
1431 break;
1432 }
1434 {
1435 float distance = m_spellInfo->Effects[effIndex].CalcRadius(m_caster);
1436 Map* map = m_caster->GetMap();
1437 uint32 phasemask = m_caster->GetPhaseMask();
1438 float collisionHeight = m_caster->GetCollisionHeight();
1439 float destz = 0.0f, startx = 0.0f, starty = 0.0f, startz = 0.0f, starto = 0.0f;
1440
1441 Position pos;
1442 Position lastpos;
1443 m_caster->GetPosition(startx, starty, startz, starto);
1444 pos.Relocate(startx, starty, startz, starto);
1445 float destx = pos.GetPositionX() + distance * cos(pos.GetOrientation());
1446 float desty = pos.GetPositionY() + distance * sin(pos.GetOrientation());
1447
1448 // Added GROUND_HEIGHT_TOLERANCE to account for cases where, during a jump,
1449 // the Z position may be slightly below the vmap ground level.
1450 // Without this tolerance, a ray trace might incorrectly attempt to find ground
1451 // beneath the actual surface.
1452 //
1453 // Example:
1454 // actual vmap ground: -56.342392
1455 // Z position: -56.347195
1456 float searchGroundZPos = pos.GetPositionZ()+GROUND_HEIGHT_TOLERANCE;
1457 float ground = map->GetHeight(phasemask, pos.GetPositionX(), pos.GetPositionY(), searchGroundZPos);
1458
1459 bool isCasterInWater = m_caster->IsInWater();
1460 if (!m_caster->HasUnitMovementFlag(MOVEMENTFLAG_FALLING) || (pos.GetPositionZ() - ground < distance))
1461 {
1462 float tstX = 0.0f, tstY = 0.0f, tstZ = 0.0f, prevX = 0.0f, prevY = 0.0f, prevZ = 0.0f;
1463 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;
1464 float maxtravelDistZ = 2.65f;
1465 float overdistance = 0.0f;
1466 float totalpath = 0.0f;
1467 float beforewaterz = 0.0f;
1468 bool inwater = false;
1469 bool wcol = false;
1470 const float step = 2.0f;
1471 const uint8 numChecks = std::ceil(std::fabs(distance / step));
1472 const float DELTA_X = (destx - pos.GetPositionX()) / numChecks;
1473 const float DELTA_Y = (desty - pos.GetPositionY()) / numChecks;
1474 int j = 1;
1475 for (; j < (numChecks + 1); j++)
1476 {
1477 prevX = pos.GetPositionX() + (float(j - 1) * DELTA_X);
1478 prevY = pos.GetPositionY() + (float(j - 1) * DELTA_Y);
1479 tstX = pos.GetPositionX() + (float(j) * DELTA_X);
1480 tstY = pos.GetPositionY() + (float(j) * DELTA_Y);
1481
1482 if (j < 2)
1483 {
1484 prevZ = pos.GetPositionZ();
1485 }
1486 else
1487 {
1488 prevZ = tstZ;
1489 }
1490
1491 tstZ = map->GetHeight(phasemask, tstX, tstY, prevZ + maxtravelDistZ, true);
1492 ground = tstZ;
1493
1494 if (!isCasterInWater)
1495 {
1496 if (map->IsInWater(phasemask, tstX, tstY, tstZ, collisionHeight))
1497 {
1498 if (!(beforewaterz != 0.0f))
1499 {
1500 beforewaterz = prevZ;
1501 }
1502 tstZ = beforewaterz;
1503 srange = sqrt((tstY - prevY) * (tstY - prevY) + (tstX - prevX) * (tstX - prevX));
1504 //LOG_ERROR("spells", "(start was from land) step in water , number of cycle = {} , distance of step = {}, total path = {}, Z = {}", j, srange, totalpath, tstZ);
1505 }
1506 }
1507 else if (map->IsInWater(phasemask, tstX, tstY, tstZ, collisionHeight))
1508 {
1509 prevZ = pos.GetPositionZ();
1510 tstZ = pos.GetPositionZ();
1511 srange = sqrt((tstY - prevY) * (tstY - prevY) + (tstX - prevX) * (tstX - prevX));
1512
1513 inwater = true;
1514 if (inwater && (fabs(tstZ - ground) < 2.0f))
1515 {
1516 wcol = true;
1517 //LOG_ERROR("spells", "step in water with collide and use standart check (for continue way after possible collide), number of cycle = {} ", j);
1518 }
1519
1520 // if (j < 2)
1521 // LOG_ERROR("spells", "(start in water) step in water, number of cycle = {} , distance of step = {}, total path = {}", j, srange, totalpath);
1522 // else
1523 // LOG_ERROR("spells", "step in water, number of cycle = {} , distance of step = {}, total path = {}", j, srange, totalpath);
1524 }
1525
1526 bool IsInWater = map->IsInWater(phasemask, tstX, tstY, tstZ, collisionHeight);
1527 if ((!IsInWater && tstZ != beforewaterz) || wcol) // second safety check z for blink way if on the ground
1528 {
1529 if (inwater && !IsInWater)
1530 inwater = false;
1531
1532 // highest available point
1533 tstZ1 = map->GetHeight(phasemask, tstX, tstY, prevZ + maxtravelDistZ, true, 25.0f);
1534 // upper or floor
1535 tstZ2 = map->GetHeight(phasemask, tstX, tstY, prevZ, true, 25.0f);
1536 //lower than floor
1537 tstZ3 = map->GetHeight(phasemask, tstX, tstY, prevZ - maxtravelDistZ / 2, true, 25.0f);
1538
1539 //distance of rays, will select the shortest in 3D
1540 srange1 = sqrt((tstY - prevY) * (tstY - prevY) + (tstX - prevX) * (tstX - prevX) + (tstZ1 - prevZ) * (tstZ1 - prevZ));
1541 //LOG_ERROR("spells", "step = {}, distance of ray1 = {}", j, srange1);
1542 srange2 = sqrt((tstY - prevY) * (tstY - prevY) + (tstX - prevX) * (tstX - prevX) + (tstZ2 - prevZ) * (tstZ2 - prevZ));
1543 //LOG_ERROR("spells", "step = {}, distance of ray2 = {}", j, srange2);
1544 srange3 = sqrt((tstY - prevY) * (tstY - prevY) + (tstX - prevX) * (tstX - prevX) + (tstZ3 - prevZ) * (tstZ3 - prevZ));
1545 //LOG_ERROR("spells", "step = {}, distance of ray3 = {}", j, srange3);
1546
1547 if (srange1 < srange2)
1548 {
1549 tstZ = tstZ1;
1550 srange = srange1;
1551 }
1552 else if (srange3 < srange2)
1553 {
1554 tstZ = tstZ3;
1555 srange = srange3;
1556 }
1557 else
1558 {
1559 tstZ = tstZ2;
1560 srange = srange2;
1561 }
1562
1563 //LOG_ERROR("spells", "step on ground, number of cycle = {} , distance of step = {}, total path = {}", j, srange, totalpath);
1564 }
1565
1566 destx = tstX;
1567 desty = tstY;
1568 destz = tstZ;
1569
1570 totalpath += srange;
1571
1572 if (totalpath > distance)
1573 {
1574 overdistance = totalpath - distance;
1575 //LOG_ERROR("spells", "total path > than distance in 3D , need to move back a bit for save distance, total path = {}, overdistance = {}", totalpath, overdistance);
1576 }
1577
1578 bool col = m_caster->GetMap()->GetMapCollisionData().GetStaticTree().GetObjectHitPos(prevX, prevY, prevZ + 0.5f, tstX, tstY, tstZ + 0.5f, tstX, tstY, tstZ, -0.5f);
1579 // check dynamic collision
1580 bool dcol = m_caster->GetMap()->GetMapCollisionData().GetDynamicTree().GetObjectHitPos(phasemask, prevX, prevY, prevZ + 0.5f, tstX, tstY, tstZ + 0.5f, tstX, tstY, tstZ, -0.5f);
1581
1582 // collision occured
1583 if (col || dcol || (overdistance > 0.0f && !map->IsInWater(phasemask, tstX, tstY, ground, collisionHeight)) || (fabs(prevZ - tstZ) > maxtravelDistZ && (tstZ > prevZ)))
1584 {
1585 if ((overdistance > 0.0f) && (overdistance < 1.f))
1586 {
1587 destx = prevX + overdistance * cos(pos.GetOrientation());
1588 desty = prevY + overdistance * sin(pos.GetOrientation());
1589 //LOG_ERROR("spells", "(collision) collision occured 1");
1590 }
1591 else
1592 {
1593 // move back a bit
1594 destx = tstX - (0.6 * cos(pos.GetOrientation()));
1595 desty = tstY - (0.6 * sin(pos.GetOrientation()));
1596 //LOG_ERROR("spells", "(collision) collision occured 2");
1597 }
1598
1599 // highest available point
1600 destz1 = map->GetHeight(phasemask, destx, desty, prevZ + maxtravelDistZ, true, 25.0f);
1601 // upper or floor
1602 destz2 = map->GetHeight(phasemask, destx, desty, prevZ, true, 25.0f);
1603 //lower than floor
1604 destz3 = map->GetHeight(phasemask, destx, desty, prevZ - maxtravelDistZ / 2, true, 25.0f);
1605
1606 //distance of rays, will select the shortest in 3D
1607 srange1 = sqrt((desty - prevY) * (desty - prevY) + (destx - prevX) * (destx - prevX) + (destz1 - prevZ) * (destz1 - prevZ));
1608 srange2 = sqrt((desty - prevY) * (desty - prevY) + (destx - prevX) * (destx - prevX) + (destz2 - prevZ) * (destz2 - prevZ));
1609 srange3 = sqrt((desty - prevY) * (desty - prevY) + (destx - prevX) * (destx - prevX) + (destz3 - prevZ) * (destz3 - prevZ));
1610
1611 if (srange1 < srange2)
1612 destz = destz1;
1613 else if (srange3 < srange2)
1614 destz = destz3;
1615 else
1616 destz = destz2;
1617
1618 if (inwater && destz < prevZ && !wcol)
1619 destz = prevZ;
1620 //LOG_ERROR("spells", "(collision) destZ rewrited in prevZ");
1621
1622 // Don't make the player move backward from the xy adjustments by collisions.
1623 if ((DELTA_X > 0 && startx > destx) || (DELTA_X < 0 && startx < destx) ||
1624 (DELTA_Y > 0 && starty > desty) || (DELTA_Y < 0 && starty < desty))
1625 {
1626 destx = startx;
1627 desty = starty;
1628 destz = startz;
1629 }
1630
1631 break;
1632 }
1633 // we have correct destz now
1634 }
1635
1636 lastpos.Relocate(destx, desty, destz, pos.GetOrientation());
1637 dest = SpellDestination(lastpos);
1638 }
1639 else
1640 {
1641 float z = pos.GetPositionZ();
1642 bool col = m_caster->GetMap()->GetMapCollisionData().GetStaticTree().GetObjectHitPos(pos.GetPositionX(), pos.GetPositionY(), z, destx, desty, z, destx, desty, z, -0.5f);
1643 // check dynamic collision
1644 bool dcol = m_caster->GetMap()->GetMapCollisionData().GetDynamicTree().GetObjectHitPos(phasemask, pos.GetPositionX(), pos.GetPositionY(), z, destx, desty, z, destx, desty, z, -0.5f);
1645
1646 // collision occured
1647 if (col || dcol)
1648 {
1649 // move back a bit
1650 destx = destx - (0.6 * cos(pos.GetOrientation()));
1651 desty = desty - (0.6 * sin(pos.GetOrientation()));
1652 }
1653
1654 lastpos.Relocate(destx, desty, z, pos.GetOrientation());
1655 dest = SpellDestination(lastpos);
1656 //float range = sqrt((desty - pos.GetPositionY())*(desty - pos.GetPositionY()) + (destx - pos.GetPositionX())*(destx - pos.GetPositionX()));
1657 //LOG_ERROR("spells", "Blink number 2, in falling but at a hight, distance of blink = {}", range);
1658 }
1659 break;
1660 }
1661 default:
1662 {
1663 float dist = m_spellInfo->Effects[effIndex].CalcRadius(m_caster);
1664 float angle = targetType.CalcDirectionAngle();
1665 float objSize = m_caster->GetCombatReach();
1666
1667 switch (targetType.GetTarget())
1668 {
1670 dist = PET_FOLLOW_DIST;
1671 break;
1673 if (dist > objSize)
1674 dist = objSize + (dist - objSize) * float(rand_norm());
1675 break;
1680 {
1681 static float const DefaultTotemDistance = 3.0f;
1682 if (!m_spellInfo->Effects[effIndex].HasRadius())
1683 dist = DefaultTotemDistance;
1684 break;
1685 }
1686 default:
1687 break;
1688 }
1689
1690 if (dist < objSize)
1691 {
1692 dist = objSize;
1693 }
1694
1695 Position pos = dest._position;
1696 m_caster->MovePositionToFirstCollision(pos, dist, angle);
1697
1698 dest.Relocate(pos);
1699 break;
1700 }
1701 }
1702
1703 CallScriptDestinationTargetSelectHandlers(dest, effIndex, targetType);
1704 m_targets.SetDst(dest);
1705}
#define VMAP_INVALID_HEIGHT_VALUE
Definition IVMapMgr.h:51
@ SPELL_EFFECT_BIND
Definition SharedDefines.h:777
@ SPELL_EFFECT_TELEPORT_UNITS
Definition SharedDefines.h:771
@ TARGET_DEST_CASTER_RANDOM
Definition SharedDefines.h:1480
@ TARGET_DEST_DB
Definition SharedDefines.h:1426
@ TARGET_DEST_CASTER_FRONT_LEAP
Definition SharedDefines.h:1463
@ TARGET_DEST_CASTER_FRONT_LEFT
Definition SharedDefines.h:1452
@ TARGET_DEST_CASTER_BACK_RIGHT
Definition SharedDefines.h:1450
@ TARGET_DEST_CASTER_FISHING
Definition SharedDefines.h:1447
@ TARGET_DEST_CASTER_BACK_LEFT
Definition SharedDefines.h:1451
@ TARGET_DEST_CASTER_SUMMON
Definition SharedDefines.h:1440
@ TARGET_DEST_CASTER
Definition SharedDefines.h:1427
@ TARGET_DEST_CASTER_FRONT_RIGHT
Definition SharedDefines.h:1449
@ TARGET_DEST_CASTER_36
Definition SharedDefines.h:1444
@ TARGET_DEST_HOME
Definition SharedDefines.h:1422
float const GROUND_HEIGHT_TOLERANCE
Definition SharedDefines.h:26
@ SPELL_FAILED_TOO_SHALLOW
Definition SharedDefines.h:1093
@ MOVEMENTFLAG_FALLING
Definition UnitDefines.h:384
bool GetObjectHitPos(uint32 phasemask, float x1, float y1, float z1, float x2, float y2, float z2, float &rx, float &ry, float &rz, float modifyDist) const
Definition MapCollisionData.cpp:163
DynamicVMapCollisionData & GetDynamicTree()
Definition MapCollisionData.h:82
StaticVMapCollisionData & GetStaticTree()
Definition MapCollisionData.h:84
LiquidData const GetLiquidData(uint32 phaseMask, float x, float y, float z, float collisionHeight, Optional< uint8 > ReqLiquidType)
Definition Map.cpp:1304
float GetHeight(float x, float y, float z, bool checkVMap=true, float maxSearchDist=DEFAULT_HEIGHT_SEARCH) const
Definition Map.cpp:1156
MapCollisionData & GetMapCollisionData()
Definition Map.h:564
bool IsInWater(uint32 phaseMask, float x, float y, float z, float collisionHeight) const
Definition Map.cpp:1585
void CallScriptDestinationTargetSelectHandlers(SpellDestination &target, SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition Spell.cpp:8755
bool GetObjectHitPos(float x1, float y1, float z1, float x2, float y2, float z2, float &rx, float &ry, float &rz, float modifyDist) const
Definition MapCollisionData.cpp:89
float GetCollisionHeight() const override
Return collision height sent to client.
Definition Unit.cpp:17172
float GetMapHeight(float x, float y, float z, bool vmap=true, float distanceToSearch=50.0f) const
Definition Object.cpp:3085
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:2692
Definition GridTerrainData.h:199
float Level
Definition GridTerrainData.h:204
LiquidStatus Status
Definition GridTerrainData.h:206
Definition SpellMgr.h:386

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

Referenced by SelectEffectImplicitTargets().

◆ SelectImplicitCasterObjectTargets()

void Spell::SelectImplicitCasterObjectTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType 
)
1781{
1782 WorldObject* target = nullptr;
1783 bool checkIfValid = true;
1784
1785 switch (targetType.GetTarget())
1786 {
1787 case TARGET_UNIT_CASTER:
1788 target = m_caster;
1789 checkIfValid = false;
1790 break;
1791 case TARGET_UNIT_MASTER:
1792 target = m_caster->GetCharmerOrOwner();
1793 break;
1794 case TARGET_UNIT_PET:
1795 target = m_caster->GetGuardianPet();
1796 if (!target)
1797 target = m_caster->GetCharm();
1798 break;
1800 if (m_caster->IsSummon())
1801 target = m_caster->ToTempSummon()->GetSummonerUnit();
1802 break;
1804 target = m_caster->GetVehicleBase();
1805 break;
1815 target = m_caster->GetVehicleKit()->GetPassenger(targetType.GetTarget() - TARGET_UNIT_PASSENGER_0);
1816 break;
1817 default:
1818 break;
1819 }
1820
1821 CallScriptObjectTargetSelectHandlers(target, effIndex, targetType);
1822
1823 if (target && target->ToUnit())
1824 AddUnitTarget(target->ToUnit(), 1 << effIndex, checkIfValid);
1825}
@ TARGET_UNIT_PASSENGER_1
Definition SharedDefines.h:1505
@ TARGET_UNIT_PASSENGER_6
Definition SharedDefines.h:1510
@ TARGET_UNIT_VEHICLE
Definition SharedDefines.h:1502
@ TARGET_UNIT_PASSENGER_2
Definition SharedDefines.h:1506
@ TARGET_UNIT_PASSENGER_4
Definition SharedDefines.h:1508
@ TARGET_UNIT_PASSENGER_7
Definition SharedDefines.h:1511
@ TARGET_UNIT_MASTER
Definition SharedDefines.h:1435
@ TARGET_UNIT_PASSENGER_5
Definition SharedDefines.h:1509
@ TARGET_UNIT_PASSENGER_3
Definition SharedDefines.h:1507
@ TARGET_UNIT_SUMMONER
Definition SharedDefines.h:1500
@ TARGET_UNIT_PASSENGER_0
Definition SharedDefines.h:1504
Unit * GetSummonerUnit() const
Definition TemporarySummon.cpp:44
Unit * GetVehicleBase() const
Definition Unit.cpp:15038
Unit * GetPassenger(int8 seatId) const
Definition Vehicle.cpp:239

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

Referenced by SelectEffectImplicitTargets().

◆ SelectImplicitChainTargets()

void Spell::SelectImplicitChainTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType,
WorldObject target,
uint32  effMask 
)
1850{
1851 uint32 maxTargets = m_spellInfo->Effects[effIndex].ChainTarget;
1852 if (Player* modOwner = m_caster->GetSpellModOwner())
1853 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_JUMP_TARGETS, maxTargets, this);
1854
1855 if (maxTargets > 1)
1856 {
1857 // mark damage multipliers as used
1858 for (uint32 k = effIndex; k < MAX_SPELL_EFFECTS; ++k)
1859 if (effMask & (1 << k))
1860 m_damageMultipliers[k] = 1.0f;
1861 m_applyMultiplierMask |= effMask;
1862
1863 std::list<WorldObject*> targets;
1864 SearchChainTargets(targets, maxTargets - 1, target, targetType.GetObjectType(), targetType.GetCheckType(), targetType.GetSelectionCategory()
1865 , m_spellInfo->Effects[effIndex].ImplicitTargetConditions, targetType.GetTarget() == TARGET_UNIT_TARGET_CHAINHEAL_ALLY);
1866
1867 // Chain primary target is added earlier
1868 CallScriptObjectAreaTargetSelectHandlers(targets, effIndex, targetType);
1869
1870 for (std::list<WorldObject*>::iterator itr = targets.begin(); itr != targets.end(); ++itr)
1871 if (Unit* unitTarget = (*itr)->ToUnit())
1872 AddUnitTarget(unitTarget, effMask, false);
1873 }
1874}
@ TARGET_UNIT_TARGET_CHAINHEAL_ALLY
Definition SharedDefines.h:1453
@ SPELLMOD_JUMP_TARGETS
Definition SpellDefines.h:93
void SearchChainTargets(std::list< WorldObject * > &targets, uint32 chainTargets, WorldObject *target, SpellTargetObjectTypes objectType, SpellTargetCheckTypes selectType, SpellTargetSelectionCategories selectCategory, ConditionList *condList, bool isChainHeal)
Definition Spell.cpp:2123

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 
)
1049{
1050 if (targetType.GetReferenceType() != TARGET_REFERENCE_TYPE_CASTER)
1051 {
1052 ASSERT(false && "Spell::SelectImplicitChannelTargets: received not implemented target reference type");
1053 return;
1054 }
1055
1056 switch (targetType.GetTarget())
1057 {
1059 {
1060 // Xinef: All channel selectors have needed data passed in m_targets structure
1062 if (target)
1063 {
1064 CallScriptObjectTargetSelectHandlers(target, effIndex, targetType);
1065 // unit target may be no longer avalible - teleported out of map for example
1066 if (target && target->ToUnit())
1067 AddUnitTarget(target->ToUnit(), 1 << effIndex);
1068 }
1069 else
1070 {
1071 LOG_DEBUG("spells.aura", "SPELL: cannot find channel spell target for spell ID {}, effect {}", m_spellInfo->Id, effIndex);
1072 }
1073 break;
1074 }
1079 {
1080 CallScriptObjectTargetSelectHandlers(target, effIndex, targetType);
1081 if (target)
1082 m_targets.SetDst(*target);
1083 }
1085 {
1086 if (channeledSpell->m_targets.GetUnitTarget())
1087 m_targets.SetDst(*channeledSpell->m_targets.GetUnitTarget());
1088 }
1089 else //if (!m_targets.HasDst())
1090 {
1091 LOG_DEBUG("spells.aura", "SPELL: cannot find channel spell destination for spell ID {}, effect {}", m_spellInfo->Id, effIndex);
1092 }
1093 break;
1095 if (GetOriginalCaster())
1097 break;
1098 default:
1099 ASSERT(false && "Spell::SelectImplicitChannelTargets: received not implemented target type");
1100 break;
1101 }
1102}
@ TARGET_DEST_CHANNEL_TARGET
Definition SharedDefines.h:1484
@ TARGET_UNIT_CHANNEL_TARGET
Definition SharedDefines.h:1485
@ TARGET_DEST_CHANNEL_CASTER
Definition SharedDefines.h:1514
WorldObject * GetObjectTargetChannel(Unit *caster) const
Definition Spell.cpp:464
SpellDestination const * GetDstChannel() const
Definition Spell.cpp:474
bool HasDstChannel() const
Definition Spell.cpp:469

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

Referenced by SelectEffectImplicitTargets().

◆ SelectImplicitConeTargets()

void Spell::SelectImplicitConeTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType,
uint32  effMask 
)
1219{
1220 if (targetType.GetReferenceType() != TARGET_REFERENCE_TYPE_CASTER)
1221 {
1222 ASSERT(false && "Spell::SelectImplicitConeTargets: received not implemented target reference type");
1223 return;
1224 }
1225 std::list<WorldObject*> targets;
1226 SpellTargetObjectTypes objectType = targetType.GetObjectType();
1227 SpellTargetCheckTypes selectionType = targetType.GetCheckType();
1228 ConditionList* condList = m_spellInfo->Effects[effIndex].ImplicitTargetConditions;
1229 float coneAngle = G3D::toRadians(60.0f);
1230 if (SpellCone const* sc = sSpellMgr->GetSpellCone(m_spellInfo->Id))
1231 coneAngle = G3D::toRadians(static_cast<float>(sc->cone_degrees));
1232 else
1233 {
1234 switch (targetType.GetTarget())
1235 {
1237 coneAngle = G3D::toRadians(24.0f);
1238 break;
1240 coneAngle = G3D::toRadians(54.0f);
1241 break;
1243 coneAngle = G3D::toRadians(104.0f);
1244 break;
1245 default:
1246 break;
1247 }
1248 }
1249
1250 float radius = m_spellInfo->Effects[effIndex].CalcRadius(m_caster) * m_spellValue->RadiusMod;
1251 if (uint32 containerTypeMask = GetSearcherTypeMask(objectType, condList))
1252 {
1253 Acore::WorldObjectSpellConeTargetCheck check(coneAngle, radius, m_caster, m_spellInfo, selectionType, condList);
1254 Acore::WorldObjectListSearcher<Acore::WorldObjectSpellConeTargetCheck> searcher(m_caster, targets, check, containerTypeMask);
1255 SearchTargets<Acore::WorldObjectListSearcher<Acore::WorldObjectSpellConeTargetCheck> >(searcher, containerTypeMask, m_caster, m_caster, radius);
1256
1257 CallScriptObjectAreaTargetSelectHandlers(targets, effIndex, targetType);
1258
1259 if (!targets.empty())
1260 {
1261 // Other special target selection goes here
1262 if (uint32 maxTargets = m_spellValue->MaxAffectedTargets)
1263 {
1265 Acore::Containers::RandomResize(targets, maxTargets);
1266 }
1267
1268 for (std::list<WorldObject*>::iterator itr = targets.begin(); itr != targets.end(); ++itr)
1269 {
1270 if (Unit* unit = (*itr)->ToUnit())
1271 {
1272 AddUnitTarget(unit, effMask, false);
1273 }
1274 else if (GameObject* gObjTarget = (*itr)->ToGameObject())
1275 {
1276 AddGOTarget(gObjTarget, effMask);
1277 }
1278 }
1279 }
1280 }
1281}
@ TARGET_UNIT_CONE_ENEMY_104
Definition SharedDefines.h:1512
@ TARGET_UNIT_CONE_ENEMY_54
Definition SharedDefines.h:1462
@ TARGET_UNIT_CONE_ENEMY_24
Definition SharedDefines.h:1432
SpellTargetCheckTypes
Definition SpellInfo.h:114
SpellTargetObjectTypes
Definition SpellInfo.h:98
Definition SpellMgr.h:397

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

Referenced by SelectEffectImplicitTargets().

◆ SelectImplicitDestDestTargets()

void Spell::SelectImplicitDestDestTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType 
)
1745{
1746 // set destination to caster if no dest provided
1747 // can only happen if previous destination target could not be set for some reason
1748 // (not found nearby target, or channel target for example
1749 // maybe we should abort the spell in such case?
1750 CheckDst();
1751
1753
1754 switch (targetType.GetTarget())
1755 {
1759 case TARGET_DEST_DEST:
1760 return;
1761 default:
1762 {
1763 float angle = targetType.CalcDirectionAngle();
1764 float dist = m_spellInfo->Effects[effIndex].CalcRadius(m_caster);
1765 if (targetType.GetTarget() == TARGET_DEST_DEST_RANDOM)
1766 dist *= float(rand_norm());
1767
1768 Position pos = dest._position;
1769 m_caster->MovePosition(pos, dist, angle);
1770
1771 dest.Relocate(pos);
1772 break;
1773 }
1774 }
1775
1776 CallScriptDestinationTargetSelectHandlers(dest, effIndex, targetType);
1777 m_targets.ModDst(dest);
1778}
@ TARGET_DEST_DYNOBJ_ENEMY
Definition SharedDefines.h:1436
@ TARGET_DEST_DEST_RANDOM
Definition SharedDefines.h:1494
@ TARGET_DEST_DEST
Definition SharedDefines.h:1495
@ TARGET_DEST_DYNOBJ_NONE
Definition SharedDefines.h:1496
@ TARGET_DEST_DYNOBJ_ALLY
Definition SharedDefines.h:1437
void ModDst(Position const &pos)
Definition Spell.cpp:436
SpellDestination const * GetDst() const
Definition Spell.cpp:396
void MovePosition(Position &pos, float dist, float angle)
Definition Object.cpp:2842

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

Referenced by SelectEffectImplicitTargets().

◆ SelectImplicitNearbyTargets()

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

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 
)
1708{
1710
1711 SpellDestination dest(*target);
1712
1713 switch (targetType.GetTarget())
1714 {
1717 break;
1718 default:
1719 {
1720 float angle = targetType.CalcDirectionAngle();
1721 float dist = m_spellInfo->Effects[effIndex].CalcRadius(nullptr);
1722 if (targetType.GetTarget() == TARGET_DEST_TARGET_RANDOM)
1723 {
1724 dist *= float(rand_norm());
1725 }
1726
1727 if (targetType.GetTarget() == TARGET_DEST_TARGET_BACK)
1728 {
1730 }
1731
1732 Position pos = dest._position;
1733 target->MovePositionToFirstCollision(pos, dist, angle);
1734
1735 dest.Relocate(pos);
1736 break;
1737 }
1738 }
1739
1740 CallScriptDestinationTargetSelectHandlers(dest, effIndex, targetType);
1741 m_targets.SetDst(dest);
1742}
@ TARGET_DEST_TARGET_ANY
Definition SharedDefines.h:1471
@ TARGET_DEST_TARGET_BACK
Definition SharedDefines.h:1473
@ TARGET_DEST_TARGET_RANDOM
Definition SharedDefines.h:1482
@ TARGET_DEST_TARGET_ENEMY
Definition SharedDefines.h:1461
@ UNIT_FIELD_BOUNDINGRADIUS
Definition UpdateFields.h:122

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

Referenced by SelectEffectImplicitTargets().

◆ SelectImplicitTargetObjectTargets()

void Spell::SelectImplicitTargetObjectTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType 
)
1828{
1829 ASSERT((m_targets.GetObjectTarget() || m_targets.GetItemTarget()) && "Spell::SelectImplicitTargetObjectTargets - no explicit object or item target available!");
1830
1832
1833 CallScriptObjectTargetSelectHandlers(target, effIndex, targetType);
1834
1835 if (target)
1836 {
1837 if (Unit* unit = target->ToUnit())
1838 AddUnitTarget(unit, 1 << effIndex, true, false);
1839 else if (GameObject* gobj = target->ToGameObject())
1840 AddGOTarget(gobj, 1 << effIndex);
1841
1842 SelectImplicitChainTargets(effIndex, targetType, target, 1 << effIndex);
1843 }
1844 // Script hook can remove object target and we would wrongly land here
1845 else if (Item* item = m_targets.GetItemTarget())
1846 AddItemTarget(item, 1 << effIndex);
1847}

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

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

Referenced by SelectEffectImplicitTargets().

◆ SelectSpellTargets()

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

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
4640{
4641 if (result == SPELL_CAST_OK)
4642 return;
4643
4644 WorldPacket data(SMSG_CAST_FAILED, 1 + 4 + 1);
4645 WriteCastResultInfo(data, caster, spellInfo, castCount, result, customError);
4646
4647 caster->SendDirectMessage(&data);
4648}
static void WriteCastResultInfo(WorldPacket &data, Player *caster, SpellInfo const *spellInfo, uint8 castCount, SpellCastResult result, SpellCustomErrors customError)
Definition Spell.cpp:4534
@ SMSG_CAST_FAILED
Definition Opcodes.h:334

References Player::SendDirectMessage(), SMSG_CAST_FAILED, SPELL_CAST_OK, and WriteCastResultInfo().

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

◆ SendCastResult() [2/2]

void Spell::SendCastResult ( SpellCastResult  result)
4651{
4652 if (result == SPELL_CAST_OK)
4653 return;
4654
4655 if (!m_caster->IsPlayer() || m_caster->IsCharmed())
4656 return;
4657
4658 if (m_caster->ToPlayer()->GetSession()->PlayerLoading()) // don't send cast results at loading time
4659 return;
4660
4661 // 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
4663 result = SPELL_FAILED_DONT_REPORT;
4664
4666}
@ SPELL_FAILED_BM_OR_INVISGOD
Definition SharedDefines.h:1096
@ TRIGGERED_DONT_REPORT_CAST_ERROR
Disallows proc events from triggered spell (default)
Definition SpellDefines.h:149
bool IsCharmed() const
Definition Unit.h:1310

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

◆ SendChannelStart()

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

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

Referenced by handle_immediate().

◆ SendChannelUpdate()

◆ SendInterrupted()

void Spell::SendInterrupted ( uint8  result)
5145{
5146 WorldPacket data(SMSG_SPELL_FAILURE, (8 + 1 + 4 + 1));
5147 data << m_caster->GetPackGUID();
5148 data << uint8(m_cast_count);
5149 data << uint32(m_spellInfo->Id);
5150 data << uint8(result);
5151 m_caster->SendMessageToSet(&data, true);
5152
5153 data.Initialize(SMSG_SPELL_FAILED_OTHER, (8 + 1 + 4 + 1));
5154 data << m_caster->GetPackGUID();
5155 data << uint8(m_cast_count);
5156 data << uint32(m_spellInfo->Id);
5157 data << uint8(result);
5158 m_caster->SendMessageToSet(&data, true);
5159}
@ 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 ( )
5044{
5045 WorldPacket data(SMSG_SPELLLOGEXECUTE, (8 + 4 + 4 + 4 + 4 + 8));
5046
5047 data << m_caster->GetPackGUID();
5048
5049 data << uint32(m_spellInfo->Id);
5050
5051 uint8 effCount = 0;
5052 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
5053 {
5054 if (m_effectExecuteData[i])
5055 ++effCount;
5056 }
5057
5058 if (!effCount)
5059 return;
5060
5061 data << uint32(effCount);
5062 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
5063 {
5064 if (!m_effectExecuteData[i])
5065 continue;
5066
5067 data << uint32(m_spellInfo->Effects[i].Effect); // spell effect
5068
5069 data.append(*m_effectExecuteData[i]);
5070
5071 delete m_effectExecuteData[i];
5072 m_effectExecuteData[i] = nullptr;
5073 }
5074 m_caster->SendMessageToSet(&data, true);
5075}
@ 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
2028{
2029 Player* player = m_caster->ToPlayer();
2030 if (!player)
2031 return;
2032
2033 if (gameObjTarget)
2034 {
2035 // Players shouldn't be able to loot gameobjects that are currently despawned
2036 if (!gameObjTarget->isSpawned() && !player->IsGameMaster())
2037 {
2038 LOG_ERROR("spells.effect", "Possible hacking attempt: Player {} [{}] tried to loot a gameobject [{}] which is on respawn time without being in GM mode!",
2039 player->GetName(), player->GetGUID().ToString(), gameObjTarget->GetGUID().ToString());
2040 return;
2041 }
2042 // special case, already has GossipHello inside so return and avoid calling twice
2044 {
2046 return;
2047 }
2048
2049 if (sScriptMgr->OnGossipHello(player, gameObjTarget))
2050 return;
2051
2052 if (gameObjTarget->AI()->GossipHello(player, false))
2053 return;
2054
2055 switch (gameObjTarget->GetGoType())
2056 {
2058 gameObjTarget->UseDoorOrButton(0, false, player);
2059 return;
2061 gameObjTarget->UseDoorOrButton(0, false, player);
2062
2063 // Xinef: properly link possible traps
2064 if (uint32 trapEntry = gameObjTarget->GetGOInfo()->button.linkedTrap)
2065 gameObjTarget->TriggeringLinkedGameObject(trapEntry, player);
2066 return;
2070 return;
2071
2073 // triggering linked GO
2076 return;
2077
2079 // triggering linked GO
2080 if (uint32 trapEntry = gameObjTarget->GetGOInfo()->chest.linkedTrapId)
2082
2083 // Don't return, let loots been taken
2084 default:
2085 break;
2086 }
2087 }
2088
2089 // Send loot
2090 player->SendLoot(guid, loottype);
2091}
@ GAMEOBJECT_TYPE_SPELL_FOCUS
Definition SharedDefines.h:1572
@ GAMEOBJECT_TYPE_QUESTGIVER
Definition SharedDefines.h:1566
virtual bool GossipHello(Player *, bool)
Definition GameObjectAI.h:54
bool isSpawned() const
Definition GameObject.h:190
void TriggeringLinkedGameObject(uint32 trapEntry, Unit *target)
Definition GameObject.cpp:1366
void SendPreparedGossip(WorldObject *source)
Definition PlayerGossip.cpp:214
void PrepareGossipMenu(WorldObject *source, uint32 menuId=0, bool showQuests=false)
Definition PlayerGossip.cpp:32
uint32 gossipID
Definition GameObjectData.h:73
uint32 linkedTrap
Definition GameObjectData.h:60
struct GameObjectTemplate::@235::@240 chest
struct GameObjectTemplate::@235::@239 questgiver
uint32 linkedTrapId
Definition GameObjectData.h:91
struct GameObjectTemplate::@235::@244 spellFocus

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)
4669{
4670 if (result == SPELL_CAST_OK)
4671 return;
4672
4673 Unit* owner = m_caster->GetCharmerOrOwner();
4674 if (!owner)
4675 return;
4676
4677 Player* player = owner->ToPlayer();
4678 if (!player)
4679 return;
4680
4681 WorldPacket data(SMSG_PET_CAST_FAILED, 1 + 4 + 1);
4683
4684 player->SendDirectMessage(&data);
4685}
@ SMSG_PET_CAST_FAILED
Definition Opcodes.h:342

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

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

◆ SendResurrectRequest()

void Spell::SendResurrectRequest ( Player target)
5201{
5202 // get resurrector name for creature resurrections, otherwise packet will be not accepted
5203 // for player resurrections the name is looked up by guid
5204 std::string const sentName(m_caster->IsPlayer()
5205 ? ""
5206 : m_caster->GetNameForLocaleIdx(target->GetSession()->GetSessionDbLocaleIndex()));
5207
5208 WorldPacket data(SMSG_RESURRECT_REQUEST, (8 + 4 + sentName.size() + 1 + 1 + 1 + 4));
5209 data << m_caster->GetGUID();
5210 data << uint32(sentName.size() + 1);
5211
5212 data << sentName;
5213 data << uint8(0); // null terminator
5214
5215 data << uint8(m_caster->IsPlayer() ? 0 : 1); // "you'll be afflicted with resurrection sickness"
5216 // override delay sent with SMSG_CORPSE_RECLAIM_DELAY, set instant resurrection for spells with this attribute
5218 data << uint32(0);
5219 target->SendDirectMessage(&data);
5220}
@ SPELL_ATTR3_NO_RES_TIMER
Definition SharedDefines.h:485
@ SMSG_RESURRECT_REQUEST
Definition Opcodes.h:377

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

Referenced by EffectResurrect(), and EffectResurrectNew().

◆ SendSpellCooldown()

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

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

Referenced by _cast().

◆ SendSpellGo()

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

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

Referenced by _cast().

◆ SendSpellStart()

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

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

Referenced by prepare().

◆ SetAutoRepeat()

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

References m_autoRepeat.

◆ SetDelayStart()

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

References m_delayStart.

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

◆ SetExecutedCurrently()

void Spell::SetExecutedCurrently ( bool  yes)
inline
578{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 
)
8482{
8483 switch (mod)
8484 {
8486 m_spellValue->EffectBasePoints[0] = m_spellInfo->Effects[EFFECT_0].CalcBaseValue(value);
8487 break;
8489 m_spellValue->EffectBasePoints[1] = m_spellInfo->Effects[EFFECT_1].CalcBaseValue(value);
8490 break;
8492 m_spellValue->EffectBasePoints[2] = m_spellInfo->Effects[EFFECT_2].CalcBaseValue(value);
8493 break;
8495 m_spellValue->RadiusMod = (float)value / 10000;
8496 break;
8499 break;
8502 break;
8504 m_spellValue->AuraDuration = value;
8505 break;
8507 m_spellValue->ForcedCritResult = (bool)value;
8508 break;
8510 m_spellValue->MiscVal[0] = value;
8511 break;
8513 m_spellValue->MiscVal[1] = value;
8514 break;
8516 m_spellValue->MiscVal[2] = value;
8517 break;
8518 }
8519}
@ SPELLVALUE_AURA_STACK
Definition SpellDefines.h:118
@ SPELLVALUE_MISCVALUE1
Definition SpellDefines.h:122
@ SPELLVALUE_AURA_DURATION
Definition SpellDefines.h:119
@ SPELLVALUE_MISCVALUE2
Definition SpellDefines.h:123
@ SPELLVALUE_RADIUS_MOD
Definition SpellDefines.h:116
@ SPELLVALUE_MAX_TARGETS
Definition SpellDefines.h:117
@ SPELLVALUE_FORCED_CRIT_RESULT
Definition SpellDefines.h:120
@ SPELLVALUE_MISCVALUE0
Definition SpellDefines.h:121
bool ForcedCritResult
Definition Spell.h:230

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

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

◆ setState()

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

References m_spellState.

◆ SummonGuardian()

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

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

Referenced by EffectSummonPet(), and EffectSummonType().

◆ TakeAmmo()

void Spell::TakeAmmo ( )
5350{
5352 {
5354
5355 // wands don't have ammo
5356 if (!pItem || pItem->IsBroken() || pItem->GetTemplate()->SubClass == ITEM_SUBCLASS_WEAPON_WAND)
5357 return;
5358
5359 if (pItem->GetTemplate()->InventoryType == INVTYPE_THROWN)
5360 {
5361 if (pItem->GetMaxStackCount() == 1)
5362 {
5363 // decrease durability for non-stackable throw weapon
5365 }
5366 else if (!sWorld->getBoolConfig(CONFIG_ENABLE_INFINITEAMMO))
5367 {
5368 // decrease items amount for stackable throw weapon
5369 uint32 count = 1;
5370 m_caster->ToPlayer()->DestroyItemCount(pItem, count, true);
5371 }
5372 }
5373 else if (!sWorld->getBoolConfig(CONFIG_ENABLE_INFINITEAMMO))
5375 m_caster->ToPlayer()->DestroyItemCount(ammo, 1, true);
5376 }
5377}
@ INVTYPE_THROWN
Definition ItemTemplate.h:281
@ EQUIPMENT_SLOT_RANGED
Definition Player.h:678
@ SPELL_ATTR6_DO_NOT_CONSUME_RESOURCES
Definition SharedDefines.h:597
@ CONFIG_ENABLE_INFINITEAMMO
Definition WorldConfig.h:149
uint32 GetMaxStackCount() const
Definition Item.h:274
void DurabilityPointLossForEquipSlot(EquipmentSlots slot)
Definition Player.cpp:4741

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

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

◆ TakeCastItem()

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

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

Referenced by _cast(), and handle_immediate().

◆ TakePower()

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

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

Referenced by _cast().

◆ TakeReagents()

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

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

Referenced by _cast().

◆ TakeRunePower()

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

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

Referenced by TakePower().

◆ TriggerGlobalCooldown()

void Spell::TriggerGlobalCooldown ( )
protected
8899{
8901 if (!gcd)
8902 {
8903 // Xinef: fix for charmed pet spells with no cooldown info
8905 gcd = MIN_GCD;
8906 else
8907 return;
8908 }
8909
8910 if (m_caster->IsPlayer())
8912 return;
8913
8914 // Global cooldown can't leave range 1..1.5 secs
8915 // There are some spells (mostly not casted directly by player) that have < 1 sec and > 1.5 sec global cooldowns
8916 // but as tests show are not affected by any spell mods.
8918 {
8919 // gcd modifier auras are applied only to own spells and only players have such mods
8920 if (m_caster->IsPlayer())
8922
8923 // Apply haste rating
8926 {
8927 gcd = int32(float(gcd) * m_caster->GetFloatValue(UNIT_MOD_CAST_SPEED));
8928 }
8929
8930 if (gcd < MIN_GCD)
8931 gcd = MIN_GCD;
8932 else if (gcd > MAX_GCD)
8933 gcd = MAX_GCD;
8934 }
8935
8936 // Only players or controlled units have global cooldown
8937 if (m_caster->GetCharmInfo())
8939 else if (m_caster->IsPlayer())
8941}
@ SPELLMOD_GLOBAL_COOLDOWN
Definition SpellDefines.h:97
@ MIN_GCD
Definition Spell.cpp:8883
@ MAX_GCD
Definition Spell.cpp:8884
void AddGlobalCooldown(SpellInfo const *spellInfo, uint32 gcd)
Definition CharmInfo.cpp:419

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

Referenced by prepare().

◆ update()

void Spell::update ( uint32  difftime)
4366{
4367 // update pointers based at it's GUIDs
4368 if (!UpdatePointers())
4369 {
4370 // cancel the spell if UpdatePointers() returned false, something wrong happened there
4371 cancel();
4372 return;
4373 }
4374
4376 {
4377 LOG_DEBUG("spells.aura", "Spell {} is cancelled due to removal of target.", m_spellInfo->Id);
4378 cancel();
4379 return;
4380 }
4381
4382 // check if the player caster has moved before the spell finished
4383 // xinef: added preparing state (real cast, skip channels as they have other flags for this)
4384 if ((m_caster->IsPlayer() && m_timer != 0) &&
4387 {
4388 // don't cancel for melee, autorepeat, triggered and instant spells
4390 cancel(true);
4391 }
4392
4393 switch (m_spellState)
4394 {
4396 {
4397 if (m_timer > 0)
4398 {
4399 if (difftime >= (uint32)m_timer)
4400 m_timer = 0;
4401 else
4402 m_timer -= difftime;
4403 }
4404
4405 if (m_timer == 0 && !IsNextMeleeSwingSpell() && !IsAutoRepeat())
4406 // don't CheckCast for instant spells - done in spell::prepare, skip duplicate checks, needed for range checks for example
4407 cast(!m_casttime);
4408 break;
4409 }
4411 {
4412 if (m_timer)
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
4423 if (m_timer == 0)
4424 {
4426
4427 finish();
4428
4429 // We call the hook here instead of in Spell::finish because we only want to call it for completed channeling. Everything else is handled by interrupts
4430 if (Creature* creatureCaster = m_caster->ToCreature())
4431 if (creatureCaster->IsAIEnabled)
4432 creatureCaster->AI()->OnChannelFinished(m_spellInfo);
4433 }
4434 // Xinef: Dont update channeled target list on last tick, allow auras to update duration properly
4435 // Xinef: Added this strange check because of diffrent update routines for players / creatures
4436 // Xinef: If creature gets new aura in 800ms and in 840ms its updated with diff 270, not 40 is removed from duration but 270
4437 // Xinef: so the aura can be removed in different updates for all units
4438 else if ((m_timer < 0 || m_timer > 300) && !UpdateChanneledTargetList())
4439 {
4440 LOG_DEBUG("spells.aura", "Channeled spell {} is removed due to lack of targets", m_spellInfo->Id);
4442 finish();
4443 }
4444 break;
4445 }
4446 default:
4447 break;
4448 }
4449}
bool UpdateChanneledTargetList()
Definition Spell.cpp:3336

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

Referenced by SpellEvent::Execute().

◆ UpdateChanneledTargetList()

bool Spell::UpdateChanneledTargetList ( )
protected
3337{
3338 // Not need check return true
3340 return true;
3341
3342 uint8 channelTargetEffectMask = m_channelTargetEffectMask;
3343 uint8 channelAuraMask = 0;
3344 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
3346 channelAuraMask |= 1 << i;
3347
3348 channelAuraMask &= channelTargetEffectMask;
3349
3350 float range = 0;
3351 if (channelAuraMask)
3352 {
3354 if (range == 0)
3355 for(int i = EFFECT_0; i <= EFFECT_2; ++i)
3356 if (channelAuraMask & (1 << i) && m_spellInfo->Effects[i].RadiusEntry)
3357 {
3358 range = m_spellInfo->Effects[i].CalcRadius(nullptr, nullptr);
3359 break;
3360 }
3361
3362 if (Player* modOwner = m_caster->GetSpellModOwner())
3363 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_RANGE, range, this);
3364
3365 // xinef: add little tolerance level
3366 range += std::min(3.0f, range * 0.1f); // 10% but no more than 3yd
3367 }
3368
3369 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
3370 {
3371 if (ihit->missCondition == SPELL_MISS_NONE && (channelTargetEffectMask & ihit->effectMask))
3372 {
3373 Unit* unit = m_caster->GetGUID() == ihit->targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID);
3374
3375 if (!unit)
3376 continue;
3377
3378 if (IsValidDeadOrAliveTarget(unit))
3379 {
3380 if (channelAuraMask & ihit->effectMask)
3381 {
3383 {
3384 if (m_caster != unit)
3385 {
3386 if (!m_caster->IsWithinDistInMap(unit, range))
3387 {
3388 ihit->effectMask &= ~aurApp->GetEffectMask();
3389 unit->RemoveAura(aurApp);
3390 continue;
3391 }
3392 // Xinef: Update Orientation server side (non players wont sent appropriate packets)
3395 }
3396 }
3397 else // aura is dispelled
3398 continue;
3399 }
3400
3401 channelTargetEffectMask &= ~ihit->effectMask; // remove from need alive mask effect that have alive target
3402 }
3403 }
3404 }
3405
3406 // Xinef: not all effects are covered, remove applications from all targets
3407 if (channelTargetEffectMask != 0)
3408 {
3409 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
3410 if (ihit->missCondition == SPELL_MISS_NONE && (channelAuraMask & ihit->effectMask))
3411 if (Unit* unit = m_caster->GetGUID() == ihit->targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID))
3412 if (IsValidDeadOrAliveTarget(unit))
3414 {
3415 ihit->effectMask &= ~aurApp->GetEffectMask();
3416 unit->RemoveAura(aurApp);
3417 }
3418 }
3419
3420 // is all effects from m_needAliveTargetMask have alive targets
3421 return channelTargetEffectMask == 0;
3422}
@ SPELL_ATTR1_TRACK_TARGET_IN_CHANNEL
Definition SharedDefines.h:421
bool IsValidDeadOrAliveTarget(Unit const *target) const
Definition Spell.cpp:8262
AuraApplication * GetAuraApplication(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemCasterGUID=ObjectGuid::Empty, uint8 reqEffMask=0, AuraApplication *except=nullptr) const
Definition Unit.cpp:5858
void UpdateOrientation(float orientation)
Only server-side orientation update, does not broadcast to client.
Definition Unit.cpp:16064
bool IsWithinDistInMap(WorldObject const *obj, float dist2compare, bool is3D=true, bool incOwnRadius=true, bool incTargetRadius=true) const
Definition Object.cpp:1377

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

Referenced by update().

◆ UpdatePointers()

bool Spell::UpdatePointers ( )
7901{
7904 else
7905 {
7908 m_originalCaster = nullptr;
7909 }
7910
7912 {
7914 // cast item not found, somehow the item is no longer where we expected
7915 if (!m_CastItem)
7916 return false;
7917 }
7918 else
7919 m_CastItem = nullptr;
7920
7922
7923 // further actions done only for dest targets
7924 if (!m_targets.HasDst())
7925 return true;
7926
7927 // cache last transport
7928 WorldObject* transport = nullptr;
7929
7930 // update effect destinations (in case of moved transport dest target)
7931 for (uint8 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
7932 {
7933 SpellDestination& dest = m_destTargets[effIndex];
7934 if (!dest._transportGUID)
7935 continue;
7936
7937 if (!transport || transport->GetGUID() != dest._transportGUID)
7939
7940 if (transport)
7941 {
7942 dest._position.Relocate(transport);
7944 }
7945 }
7946
7947 return true;
7948}
void Update(Unit *caster)
Definition Spell.cpp:479
WorldObject * GetWorldObject(WorldObject const &, ObjectGuid const &guid)
Definition ObjectAccessor.cpp:115
void RelocateOffset(const Position &offset)
Definition Position.cpp:66
Position _transportOffset
Definition Spell.h:117
ObjectGuid _transportGUID
Definition Spell.h:116

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

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

◆ WriteAmmoToPacket()

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

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

Referenced by SendSpellGo(), and SendSpellStart().

◆ WriteCastResultInfo()

void Spell::WriteCastResultInfo ( WorldPacket data,
Player caster,
SpellInfo const *  spellInfo,
uint8  castCount,
SpellCastResult  result,
SpellCustomErrors  customError 
)
static
4535{
4536 data << uint8(castCount); // single cast or multi 2.3 (0/1)
4537 data << uint32(spellInfo->Id);
4538 data << uint8(result); // problem
4539 switch (result)
4540 {
4542 data << uint32(spellInfo->RequiresSpellFocus); // SpellFocusObject.dbc id
4543 break;
4544 case SPELL_FAILED_REQUIRES_AREA: // AreaTable.dbc id
4545 // hardcode areas limitation case
4546 switch (spellInfo->Id)
4547 {
4548 case 41617: // Cenarion Mana Salve
4549 case 41619: // Cenarion Healing Salve
4550 data << uint32(3905);
4551 break;
4552 case 41618: // Bottled Nethergon Energy
4553 case 41620: // Bottled Nethergon Vapor
4554 data << uint32(3842);
4555 break;
4556 case 45373: // Bloodberry Elixir
4557 data << uint32(4075);
4558 break;
4559 default: // default case (don't must be)
4560 data << uint32(0);
4561 break;
4562 }
4563 break;
4565 if (spellInfo->Totem[0])
4566 data << uint32(spellInfo->Totem[0]);
4567 if (spellInfo->Totem[1])
4568 data << uint32(spellInfo->Totem[1]);
4569 break;
4571 if (spellInfo->TotemCategory[0])
4572 data << uint32(spellInfo->TotemCategory[0]);
4573 if (spellInfo->TotemCategory[1])
4574 data << uint32(spellInfo->TotemCategory[1]);
4575 break;
4579 data << uint32(spellInfo->EquippedItemClass);
4580 data << uint32(spellInfo->EquippedItemSubClassMask);
4581 break;
4583 {
4584 uint32 item = 0;
4585 for (int8 eff = 0; eff < MAX_SPELL_EFFECTS; eff++)
4586 if (spellInfo->Effects[eff].ItemType)
4587 item = spellInfo->Effects[eff].ItemType;
4588 ItemTemplate const* proto = sObjectMgr->GetItemTemplate(item);
4589 if (proto && proto->ItemLimitCategory)
4590 data << uint32(proto->ItemLimitCategory);
4591 break;
4592 }
4594 data << uint32(customError);
4595 break;
4597 {
4598 uint32 missingItem = 0;
4599 for (uint32 i = 0; i < MAX_SPELL_REAGENTS; i++)
4600 {
4601 if (spellInfo->Reagent[i] <= 0)
4602 continue;
4603
4604 uint32 itemid = spellInfo->Reagent[i];
4605 uint32 itemcount = spellInfo->ReagentCount[i];
4606
4607 if (!caster->HasItemCount(itemid, itemcount))
4608 {
4609 missingItem = itemid;
4610 break;
4611 }
4612 }
4613
4614 data << uint32(missingItem); // first missing item
4615 break;
4616 }
4618 data << uint32(spellInfo->Mechanic);
4619 break;
4621 data << uint32(spellInfo->EquippedItemSubClassMask);
4622 break;
4624 data << uint32(0); // Item entry
4625 data << uint32(0); // Count
4626 break;
4628 data << uint32(0); // SkillLine.dbc Id
4629 data << uint32(0); // Amount
4630 break;
4632 data << uint32(0); // Skill level
4633 break;
4634 default:
4635 break;
4636 }
4637}
@ SPELL_FAILED_NEED_EXOTIC_AMMO
Definition SharedDefines.h:991
@ SPELL_FAILED_FISHING_TOO_LOW
Definition SharedDefines.h:1118
@ SPELL_FAILED_MIN_SKILL
Definition SharedDefines.h:1087
@ SPELL_FAILED_PREVENTED_BY_MECHANIC
Definition SharedDefines.h:1084
@ SPELL_FAILED_REQUIRES_AREA
Definition SharedDefines.h:1038

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.

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

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

Referenced by SendSpellGo().

Friends And Related Symbol Documentation

◆ SpellScript

friend class SpellScript
friend

◆ Unit::SetCurrentCastedSpell

void Unit::SetCurrentCastedSpell ( Spell pSpell)
friend

Member Data Documentation

◆ _scriptsLoaded

bool Spell::_scriptsLoaded
protected

Referenced by LoadScripts(), and Spell().

◆ _spellEvent

SpellEvent* Spell::_spellEvent
protected

◆ _spellTargetsSelected

bool Spell::_spellTargetsSelected
protected

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

◆ _triggeredCastFlags

TriggerCastFlags Spell::_triggeredCastFlags
protected

◆ damage

◆ destTarget

◆ effectHandleMode

SpellEffectHandleMode Spell::effectHandleMode
protected

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

◆ focusObject

◆ gameObjTarget

◆ itemTarget

◆ m_appliedMods

◆ m_applyMultiplierMask

uint8 Spell::m_applyMultiplierMask
protected

◆ m_attackType

◆ m_auraScaleMask

uint8 Spell::m_auraScaleMask
protected

◆ m_autoRepeat

bool Spell::m_autoRepeat
protected

◆ m_canReflect

bool Spell::m_canReflect
protected

Referenced by AddUnitTarget(), and Spell().

◆ m_cast_count

◆ m_caster

Unit* const Spell::m_caster
protected

Referenced by _cast(), _handle_finish_phase(), AddGOTarget(), AddUnitTarget(), CalculateDelayMomentForDst(), CalculateJumpSpeeds(), CalculateSpellDamage(), cancel(), CancelGlobalCooldown(), CanOpenLock(), cast(), CheckCast(), CheckCasterAuras(), CheckDst(), CheckEffectTarget(), CheckItems(), CheckPetCast(), CheckPower(), CheckRange(), CheckRuneCost(), CheckSpellFocus(), CheckSrc(), Delayed(), DelayedChannel(), DoAllEffectOnLaunchTarget(), DoAllEffectOnTarget(), DoAllEffectOnTarget(), DoCreateItem(), DoSpellHitOnUnit(), DoTriggersOnSpellHit(), EffectActivateObject(), EffectActivateRune(), EffectAddFarsight(), EffectApplyGlyph(), EffectBind(), EffectBlock(), EffectCastButtons(), EffectCharge(), EffectChargeDest(), EffectDestroyAllTotems(), EffectDisEnchant(), EffectDispel(), EffectDispelMechanic(), EffectDuel(), EffectDummy(), EffectEnchantHeldItem(), EffectEnchantItemPerm(), EffectEnchantItemPrismatic(), EffectEnchantItemTmp(), EffectEnergize(), EffectEnergizePct(), EffectEnvironmentalDMG(), EffectFeedPet(), EffectForceCast(), EffectForceDeselect(), EffectGameObjectRepair(), EffectHeal(), EffectHealMaxHealth(), EffectHealthLeech(), EffectInstaKill(), EffectJump(), EffectJumpDest(), EffectKnockBack(), EffectLeap(), EffectLeapBack(), EffectLearnSpell(), EffectMilling(), EffectModifyThreatPercent(), EffectOpenLock(), EffectParry(), EffectPersistentAA(), EffectPickPocket(), EffectPowerBurn(), EffectPowerDrain(), EffectProficiency(), EffectProspecting(), EffectPullTowards(), EffectRechargeManaGem(), EffectRedirectThreat(), EffectResurrect(), EffectResurrectNew(), EffectResurrectPet(), EffectSchoolDMG(), EffectScriptEffect(), EffectSelfResurrect(), EffectSendEvent(), EffectSkinning(), EffectSkinPlayerCorpse(), EffectStealBeneficialBuff(), EffectStuck(), EffectSummonChangeItem(), EffectSummonObject(), EffectSummonObjectWild(), EffectSummonPet(), EffectSummonPlayer(), EffectSummonRaFFriend(), EffectSummonType(), EffectTameCreature(), EffectTaunt(), EffectTeleportUnits(), EffectTeleUnitsFaceCaster(), EffectThreat(), EffectTitanGrip(), EffectTradeSkill(), EffectTransmitted(), EffectTriggerMissileSpell(), EffectTriggerRitualOfSummoning(), EffectTriggerSpell(), EffectUnlearnSpecialization(), EffectUntrainTalents(), EffectWeaponDmg(), finish(), GetCaster(), GetOriginalTarget(), 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_damageBeforeTakenMods

int32 Spell::m_damageBeforeTakenMods
protected

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

ObjectGuid Spell::m_originalTargetGUID
protected

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

Unit* Spell::m_reflectionTarget
protected

◆ m_reflectionTargetGuid

ObjectGuid Spell::m_reflectionTargetGuid
protected

◆ m_reflectionTargetPosition

Position Spell::m_reflectionTargetPosition
protected

◆ m_runesState

uint8 Spell::m_runesState
protected

◆ m_selfContainer

Spell** Spell::m_selfContainer
protected

◆ m_skipCheck

bool Spell::m_skipCheck
protected

Referenced by AddUnitTarget(), and Spell().

◆ m_spellAura

◆ m_spellFlags

◆ m_spellInfo

SpellInfo const* const Spell::m_spellInfo

Referenced by _cast(), _handle_finish_phase(), _handle_immediate_phase(), Unit::_UpdateAutoRepeatSpell(), AddGOTarget(), AddItemTarget(), AddUnitTarget(), CalculateDelayMomentForDst(), CalculateJumpSpeeds(), CalculateSpellDamage(), CallScriptDestinationTargetSelectHandlers(), CallScriptEffectHandlers(), CallScriptObjectAreaTargetSelectHandlers(), CallScriptObjectTargetSelectHandlers(), CanAutoCast(), cancel(), CancelGlobalCooldown(), CanExecuteTriggersOnHit(), CanOpenLock(), CheckCast(), CheckCasterAuras(), CheckEffectTarget(), CheckItems(), CheckPetCast(), CheckPower(), CheckRange(), CheckRuneCost(), CheckScriptEffectImplicitTargets(), CheckSpellFocus(), Delayed(), DelayedChannel(), DoAllEffectOnLaunchTarget(), DoAllEffectOnTarget(), DoAllEffectOnTarget(), DoCreateItem(), DoSpellHitOnUnit(), DoTriggersOnSpellHit(), EffectActivateObject(), EffectActivateRune(), EffectAddFarsight(), EffectAddHonor(), EffectApplyGlyph(), EffectBind(), EffectCastButtons(), EffectCharge(), EffectCreateItem(), EffectCreateItem2(), EffectCreateRandomItem(), EffectCreateTamedPet(), EffectDiscoverTaxi(), EffectDisEnchant(), EffectDispel(), EffectDispelMechanic(), EffectDuel(), EffectDummy(), EffectDurabilityDamage(), EffectDurabilityDamagePCT(), EffectEnchantHeldItem(), EffectEnchantItemPerm(), EffectEnchantItemPrismatic(), EffectEnchantItemTmp(), EffectEnergize(), EffectEnergizePct(), EffectEnvironmentalDMG(), EffectFeedPet(), EffectForceCast(), EffectForceDeselect(), EffectGameObjectSetDestructionState(), EffectHeal(), EffectHealMaxHealth(), 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(), EffectRedirectThreat(), EffectRemoveAura(), EffectReputation(), EffectResurrectNew(), EffectSchoolDMG(), EffectScriptEffect(), EffectSelfResurrect(), EffectSendEvent(), EffectSendTaxi(), EffectStealBeneficialBuff(), EffectSummonChangeItem(), EffectSummonObject(), EffectSummonObjectWild(), EffectSummonPet(), EffectSummonType(), EffectTameCreature(), EffectTaunt(), EffectTeleportUnits(), EffectThreat(), 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(), SetSpellValue(), Spell(), SummonGuardian(), TakeAmmo(), TakePower(), TakeReagents(), TakeRunePower(), TriggerGlobalCooldown(), update(), PetAI::UpdateAI(), UpdateChanneledTargetList(), Player::UpdatePotionCooldown(), ~Spell(), and SpellEvent::~SpellEvent().

◆ m_spellSchoolMask

◆ m_spellState

uint32 Spell::m_spellState
protected

◆ m_spellValue

◆ m_targets

SpellCastTargets Spell::m_targets

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

◆ m_timer

◆ m_triggeredByAuraSpell

◆ m_UniqueGOTargetInfo

◆ m_UniqueItemInfo

◆ m_UniqueTargetInfo

◆ m_weaponItem

Item* Spell::m_weaponItem

◆ unitTarget

Unit* Spell::unitTarget
protected

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


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