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 
)
570 :
571 m_spellInfo(sSpellMgr->GetSpellForDifficultyFromSpell(info, caster)),
572 m_caster((info->HasAttribute(SPELL_ATTR6_ORIGINATE_FROM_CONTROLLER) && caster->GetCharmerOrOwner()) ? caster->GetCharmerOrOwner() : caster)
574{
576 m_skipCheck = skipCheck;
577 m_selfContainer = nullptr;
579 m_executedCurrently = false;
582 m_comboTarget = nullptr;
583 m_delayStart = 0;
585
587 m_auraScaleMask = 0;
588 memset(m_damageMultipliers, 0, sizeof(m_damageMultipliers));
589
590 // Get data for type of attack
591 switch (m_spellInfo->DmgClass)
592 {
596 else
598 break;
601 break;
602 default:
603 // Wands
606 else
608 break;
609 }
610
611 m_spellSchoolMask = info->GetSchoolMask(); // Can be override for some spell (wand shoot for example)
612
614 // wand case
617 m_spellSchoolMask = SpellSchoolMask(1 << pItem->GetTemplate()->Damage[0].DamageType);
618
619 if (originalCasterGUID)
620 m_originalCasterGUID = originalCasterGUID;
621 else
623
626 else
627 {
630 m_originalCaster = nullptr;
631 }
632
634 _triggeredCastFlags = triggerFlags;
635 if (info->HasAttribute(SPELL_ATTR4_ALLOW_CAST_WHILE_CASTING))
637
638 m_CastItem = nullptr;
639
640 unitTarget = nullptr;
641 itemTarget = nullptr;
642 gameObjTarget = nullptr;
643 destTarget = nullptr;
644 damage = 0;
645 m_reflectionTarget = nullptr;
650 m_damage = 0;
651 m_healing = 0;
653 m_procAttacker = 0;
654 m_procVictim = 0;
655 m_procEx = 0;
656 focusObject = nullptr;
657 m_cast_count = 0;
658 m_glyphIndex = 0;
659 m_preCastSpell = 0;
660 m_spellAura = nullptr;
661 _scriptsLoaded = false;
662
663 //Auto Shot & Shoot (wand)
665
666 m_runesState = 0;
667 m_powerCost = 0; // setup to correct value in Spell::prepare, must not be used before.
668 m_casttime = 0; // setup to correct value in Spell::prepare, must not be used before.
669 m_timer = 0; // will set to castime in prepare
670 m_channeledDuration = 0; // will be setup in Spell::handle_immediate
671 m_immediateHandled = false;
672
674
676
677 // Determine if spell can be reflected back to the caster
678 // Patch 1.2 notes: Spell Reflection no longer reflects abilities
682
684 memset(m_effectExecuteData, 0, MAX_SPELL_EFFECTS * sizeof(ByteBuffer*));
685
686 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
688
689 // xinef:
690 _spellTargetsSelected = false;
691
692 m_weaponItem = nullptr;
693}
#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:836
@ 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:2284
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 ( )
696{
697 // unload scripts
698 while (!m_loadedScripts.empty())
699 {
700 std::list<SpellScript*>::iterator itr = m_loadedScripts.begin();
701 (*itr)->_Unload();
702 delete (*itr);
703 m_loadedScripts.erase(itr);
704 }
705
707 {
708 // Clean the reference to avoid later crash.
709 // If this error is repeating, we may have to add an ASSERT to better track down how we get into this case.
710 LOG_ERROR("spells", "Spell::~Spell: deleting spell for spell ID {}. However, spell still referenced.", m_spellInfo->Id);
711 *m_selfContainer = nullptr;
712 }
713
714 delete m_spellValue;
715
717}
#define LOG_ERROR(filterType__,...)
Definition Log.h:145
uint32 Id
Definition SpellInfo.h:344
void CheckEffectExecuteData()
Definition Spell.cpp:8528
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

3745{
3746 // update pointers base at GUIDs to prevent access to non-existed already object
3747 if (!UpdatePointers())
3748 {
3749 // cancel the spell if UpdatePointers() returned false, something wrong happened there
3750 cancel();
3751 return;
3752 }
3753
3754 // cancel at lost explicit target during cast
3756 {
3757 cancel();
3758 return;
3759 }
3760
3761 // Xinef: implement attribute SPELL_ATTR1_DISMISS_PET_FIRST, on spell cast current pet is dismissed and charms are removed
3763 {
3765 if (Pet* pet = m_caster->ToPlayer()->GetPet())
3767
3768 if (Unit* charm = m_caster->GetCharm())
3769 charm->RemoveAurasByType(SPELL_AURA_MOD_CHARM, m_caster->GetGUID());
3770 }
3771
3772 if (Player* playerCaster = m_caster->ToPlayer())
3773 {
3774 // now that we've done the basic check, now run the scripts
3775 // should be done before the spell is actually executed
3776 sScriptMgr->OnPlayerSpellCast(playerCaster, this, skipCheck);
3777
3778 // As of 3.0.2 pets begin attacking their owner's target immediately
3779 // Let any pets know we've attacked something. Check DmgClass for harmful spells only
3780 // This prevents spells such as Hunter's Mark from triggering pet attack
3781 // xinef: take into account SPELL_ATTR3_SUPPRESS_TARGET_PROCS
3783 if (!playerCaster->m_Controlled.empty())
3784 for (Unit::ControlSet::iterator itr = playerCaster->m_Controlled.begin(); itr != playerCaster->m_Controlled.end(); ++itr)
3785 if (Unit* pet = *itr)
3786 if (pet->IsAlive() && pet->IsCreature())
3787 pet->ToCreature()->AI()->OwnerAttacked(m_targets.GetUnitTarget());
3788 }
3789
3791
3795
3797
3798 Player* modOwner = m_caster->GetSpellModOwner();
3799 // skip check if done already (for instant cast spells for example)
3800 if (!skipCheck)
3801 {
3802 SpellCastResult castResult = CheckCast(false);
3803 if (castResult != SPELL_CAST_OK)
3804 {
3805 SendCastResult(castResult);
3806 SendInterrupted(0);
3807
3808 finish(false);
3809 SetExecutedCurrently(false);
3810 return;
3811 }
3812
3813 // additional check after cast bar completes (must not be in CheckCast)
3814 // if trade not complete then remember it in trade data
3816 {
3817 if (m_caster->IsPlayer())
3818 {
3819 if (TradeData* my_trade = m_caster->ToPlayer()->GetTradeData())
3820 {
3821 if (!my_trade->IsInAcceptProcess())
3822 {
3823 // Spell will be casted at completing the trade. Silently ignore at this place
3824 my_trade->SetSpell(m_spellInfo->Id, m_CastItem);
3826 SendInterrupted(0);
3827
3828 finish(false);
3829 SetExecutedCurrently(false);
3830 return;
3831 }
3832 }
3833 }
3834 }
3835 }
3836
3837 if (modOwner)
3838 modOwner->SetSpellModTakingSpell(this, true);
3839
3842
3843 if (modOwner)
3844 modOwner->SetSpellModTakingSpell(this, false);
3845
3846 // Spell may be finished after target map check
3848 {
3849 SendInterrupted(0);
3850 finish(false);
3851 SetExecutedCurrently(false);
3852 return;
3853 }
3854
3855 if (modOwner)
3856 modOwner->SetSpellModTakingSpell(this, true);
3857
3859
3861
3862 if (modOwner)
3863 modOwner->SetSpellModTakingSpell(this, false);
3864
3865 // traded items have trade slot instead of guid in m_itemTargetGUID
3866 // set to real guid to be sent later to the client
3868
3869 if (m_caster->IsPlayer())
3870 {
3872 {
3875 }
3876
3878 }
3879
3881 {
3882 // Powers have to be taken before SendSpellGo
3883 TakePower();
3884 TakeReagents(); // we must remove reagents before HandleEffects to allow place crafted item in same slot
3885 }
3886 else if (Item* targetItem = m_targets.GetItemTarget())
3887 {
3889 if (targetItem->GetOwnerGUID() != m_caster->GetGUID())
3890 TakeReagents();
3891 }
3892
3894
3895 // CAST SPELL
3896 if (modOwner)
3897 modOwner->SetSpellModTakingSpell(this, true);
3898
3900
3902
3903 // we must send smsg_spell_go packet before m_castItem delete in TakeCastItem()...
3904 SendSpellGo();
3905
3907 if (resetAttackTimers)
3908 {
3910 for (Unit::AuraEffectList::const_iterator i = vIgnoreReset.begin(); i != vIgnoreReset.end(); ++i)
3911 {
3912 if ((*i)->IsAffectedOnSpell(m_spellInfo))
3913 {
3914 resetAttackTimers = false;
3915 break;
3916 }
3917 }
3918 }
3919
3920 // Okay, everything is prepared. Now we need to distinguish between immediate and evented delayed spells
3921 if ((m_spellInfo->Speed > 0.0f && !m_spellInfo->IsChanneled())/* xinef: we dont need this || m_spellInfo->Id == 14157*/)
3922 {
3923 // Remove used for cast item if need (it can be already nullptr after TakeReagents call
3924 // in case delayed spell remove item at cast delay start
3925 TakeCastItem();
3926
3927 // Okay, maps created, now prepare flags
3928 m_immediateHandled = false;
3930 SetDelayStart(0);
3931
3934
3935 // remove all applied mods at this point
3936 // dont allow user to use them twice in case spell did not reach current target
3937 if (modOwner)
3938 modOwner->RemoveSpellMods(this);
3939
3940 // Xinef: why do we keep focus after spell is sent to air?
3941 // Xinef: Because of this, in the middle of some animation after setting targetguid to 0 etc
3942 // Xinef: we get focused to it out of nowhere...
3943 if (Creature* creatureCaster = m_caster->ToCreature())
3944 creatureCaster->ReleaseFocus(this);
3945 }
3946 else
3947 {
3948 // Immediate spell, no big deal
3950 }
3951
3952 if (resetAttackTimers)
3953 {
3954 if (m_casttime == 0 && m_spellInfo->CalcCastTime())
3955 {
3956 resetAttackTimers = false;
3957 }
3958
3959 if (resetAttackTimers)
3960 {
3962
3964 {
3966 }
3967
3969 }
3970 }
3971
3973
3974 if (modOwner)
3975 modOwner->SetSpellModTakingSpell(this, false);
3976
3977 // Handle procs on cast - only for non-triggered spells
3978 // Triggered spells (from auras, items, etc.) should not fire CAST phase procs
3979 // as they are not player-initiated casts. This prevents issues like Arcane Potency
3980 // charges being consumed by periodic damage effects (e.g., Blizzard ticks).
3981 // Must be called AFTER handle_immediate() so spell mods (like Missile Barrage's
3982 // duration reduction) are applied before the aura is consumed by the proc.
3983 if (m_originalCaster && !IsTriggered())
3984 {
3985 uint32 procAttacker = m_procAttacker;
3986 if (!procAttacker)
3987 {
3988 bool IsPositive = m_spellInfo->IsPositive();
3990 {
3992 }
3993 else
3994 {
3996 }
3997 }
3998
3999 uint32 hitMask = PROC_HIT_NORMAL;
4000
4001 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
4002 {
4003 if (ihit->missCondition != SPELL_MISS_NONE)
4004 continue;
4005
4006 if (!ihit->crit)
4007 continue;
4008
4009 hitMask |= PROC_HIT_CRITICAL;
4010 break;
4011 }
4012
4015 }
4016
4017 if (std::vector<int32> const* spell_triggered = sSpellMgr->GetSpellLinked(m_spellInfo->Id))
4018 {
4019 for (int32 id : *spell_triggered)
4020 {
4021 if (id < 0)
4023 else
4025 }
4026 }
4027
4028 // Interrupt Spell casting
4029 // handle this here, in other places SpellHitTarget can be set to nullptr, if there is an error in this function
4031 if (Unit* target = m_targets.GetUnitTarget())
4032 if (target->IsCreature())
4033 m_caster->CastSpell(target, 32747, true);
4034
4035 if (m_caster->IsPlayer())
4038
4039 sScriptMgr->OnSpellCast(this, m_caster, m_spellInfo, skipCheck);
4040
4041 SetExecutedCurrently(false);
4042
4043 // Call CreatureAI hook on successful cast
4044 if (Creature* caster = m_caster->ToCreature())
4045 if (caster->IsAIEnabled)
4046 caster->AI()->OnSpellCast(GetSpellInfo());
4047}
@ 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:737
@ 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:2169
void SetSpellModTakingSpell(Spell *spell, bool apply)
Definition Player.cpp:10034
void StartTimedAchievement(AchievementCriteriaTimedTypes type, uint32 entry, uint32 timeLost=0)
Definition Player.cpp:13980
void RemoveSpellMods(Spell *spell)
Definition Player.cpp:9960
Pet * GetPet() const
Definition Player.cpp:8961
bool GetCommandStatus(uint32 command) const
Definition Player.h:1198
void RemovePet(Pet *pet, PetSaveMode mode, bool returnreagent=false)
Definition Player.cpp:9111
TradeData * GetTradeData() const
Definition Player.h:1394
void RemoveSpellCooldown(uint32 spell_id, bool update=false)
Definition Player.cpp:3525
WorldObject * GetObjectTarget() const
Definition Spell.cpp:310
void UpdateTradeSlotItem()
Definition Spell.cpp:347
ObjectGuid GetObjectTargetGUID() const
Definition Spell.cpp:315
Item * GetItemTarget() const
Definition Spell.h:151
uint32 GetTargetMask() const
Definition Spell.h:129
Unit * GetUnitTarget() const
Definition Spell.cpp:231
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:8582
void PrepareTriggersExecutedOnHit()
Definition Spell.cpp:8788
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:4049
void SendSpellGo()
Definition Spell.cpp:4747
void TakeReagents()
Definition Spell.cpp:5482
void SetExecutedCurrently(bool yes)
Definition Spell.h:578
void SendInterrupted(uint8 result)
Definition Spell.cpp:5124
void PrepareScriptHitHandlers()
Definition Spell.cpp:8614
void CallScriptOnCastHandlers()
Definition Spell.cpp:8569
void cancel(bool bySelf=false)
Definition Spell.cpp:3654
void SendSpellCooldown()
Definition Spell.cpp:4299
void CallScriptBeforeCastHandlers()
Definition Spell.cpp:8556
void HandleLaunchPhase()
Definition Spell.cpp:8250
bool UpdatePointers()
Definition Spell.cpp:7880
void SetDelayStart(uint64 m_time)
Definition Spell.h:580
std::list< TargetInfo > m_UniqueTargetInfo
Definition Spell.h:707
void SelectSpellTargets()
Definition Spell.cpp:822
void TakePower()
Definition Spell.cpp:5265
static void SendCastResult(Player *caster, SpellInfo const *spellInfo, uint8 castCount, SpellCastResult result, SpellCustomErrors customError=SPELL_CUSTOM_ERROR_NONE)
Definition Spell.cpp:4619
bool IsTriggered() const
Definition Spell.h:568
void TakeCastItem()
Definition Spell.cpp:5202
SpellCastResult CheckCast(bool strict, uint32 *param1=nullptr, uint32 *param2=nullptr)
Definition Spell.cpp:5610
bool IsAutoActionResetSpell() const
Definition Spell.cpp:8094
void finish(bool ok=true)
Definition Spell.cpp:4431
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:7770
std::vector< AuraEffect * > AuraEffectList
Definition Unit.h:680
Player * GetSpellModOwner() const
Definition Unit.cpp:12951
bool IsNonMeleeSpellCast(bool withDelayed, bool skipChanneled=false, bool skipAutorepeat=false, bool isAutoshoot=false, bool skipInstant=true) const
Definition Unit.cpp:4286
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:1375
void RemoveAurasDueToSpell(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, uint8 reqEffMask=0, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition Unit.cpp:5171
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:6763
bool HasUnitState(const uint32 f) const
Definition Unit.h:736
void SetInFront(WorldObject const *target)
Definition Unit.cpp:16440
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 ( )
4223{
4224 // Take for real after all targets are processed
4226 {
4228 }
4229
4230 // Real add combo points from effects
4232 {
4233 // remove Premed-like effects unless they were caused by ourselves
4234 // (this Aura removes the already-added CP when it expires from duration - now that we've added CP, this shouldn't happen anymore!)
4236 {
4238 }
4239
4241 }
4242
4244 {
4246 }
4247
4250 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
4251 {
4252 // Xinef: Properly clear infinite cooldowns in some cases
4253 if (ihit->targetGUID == m_caster->GetGUID() && ihit->missCondition != SPELL_MISS_NONE)
4256 }
4257
4258 // Handle procs on finish
4259 if (m_originalCaster)
4260 {
4261 uint32 procAttacker = m_procAttacker;
4262 if (!procAttacker)
4263 {
4264 bool IsPositive = m_spellInfo->IsPositive();
4266 {
4268 }
4269 else
4270 {
4272 }
4273 }
4274
4275 uint32 hitMask = PROC_HIT_NORMAL;
4276 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
4277 {
4278 if (ihit->missCondition != SPELL_MISS_NONE)
4279 continue;
4280
4281 if (!ihit->crit)
4282 continue;
4283
4284 hitMask |= PROC_HIT_CRITICAL;
4285 break;
4286 }
4287
4288 // For trap activation, pass the original target (trap triggerer) so proc trigger spells
4289 // like Entrapment can find a valid target to cast on
4290 Unit* finishVictim = nullptr;
4291 if (procAttacker & PROC_FLAG_DONE_TRAP_ACTIVATION)
4292 finishVictim = GetOriginalTarget();
4293
4296 }
4297}
@ 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:11056
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:7875
bool IsNextMeleeSwingSpell() const
Definition Spell.cpp:8084
void SetLastExtraAttackSpell(uint32 spellId)
Definition Unit.h:1009
Player * GetCharmerOrOwnerPlayerOrPlayerItself() const
Definition Unit.cpp:7715
void ClearComboPoints()
Definition Unit.cpp:13253
void AddComboPoints(Unit *target, int8 count)
Definition Unit.cpp:13227
void RemoveAurasByType(AuraType auraType, ObjectGuid casterGUID=ObjectGuid::Empty, Aura *except=nullptr, bool negative=true, bool positive=true)
Definition Unit.cpp:5379

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 ( )
4195{
4196 m_spellAura = nullptr;
4197 // initialize Diminishing Returns Data
4200
4201 // handle some immediate features of the spell here
4203
4205
4206 // handle effects with SPELL_EFFECT_HANDLE_HIT mode
4207 for (uint32 j = 0; j < MAX_SPELL_EFFECTS; ++j)
4208 {
4209 // don't do anything for empty effect
4210 if (!m_spellInfo->Effects[j].IsEffect())
4211 continue;
4212
4213 // call effect handlers to handle destination hit
4214 HandleEffects(nullptr, nullptr, nullptr, j, SPELL_EFFECT_HANDLE_HIT);
4215 }
4216
4217 // process items
4218 for (std::list<ItemTargetInfo>::iterator ihit = m_UniqueItemInfo.begin(); ihit != m_UniqueItemInfo.end(); ++ihit)
4219 DoAllEffectOnTarget(&(*ihit));
4220}
@ SPELL_EFFECT_HANDLE_HIT
Definition Spell.h:248
std::array< SpellEffectInfo, MAX_SPELL_EFFECTS > Effects
Definition SpellInfo.h:417
void HandleThreatSpells()
Definition Spell.cpp:5531
void HandleEffects(Unit *pUnitTarget, Item *pItemTarget, GameObject *pGOTarget, uint32 i, SpellEffectHandleMode mode)
Definition Spell.cpp:5584
std::list< ItemTargetInfo > m_UniqueItemInfo
Definition Spell.h:724
void DoAllEffectOnTarget(TargetInfo *target)
Definition Spell.cpp:2523

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
2519{
2520 m_destTargets[effIndex] = dest;
2521}

References m_destTargets.

Referenced by SelectSpellTargets().

◆ AddGOTarget()

void Spell::AddGOTarget ( GameObject target,
uint32  effectMask 
)
protected
2428{
2429 for (uint32 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
2430 {
2431 if (!m_spellInfo->Effects[effIndex].IsEffect())
2432 effectMask &= ~(1 << effIndex);
2433 else
2434 {
2435 switch (m_spellInfo->Effects[effIndex].Effect)
2436 {
2440 if (go->GetGoType() != GAMEOBJECT_TYPE_DESTRUCTIBLE_BUILDING)
2441 effectMask &= ~(1 << effIndex);
2442 break;
2443 default:
2444 break;
2445 }
2446 }
2447 }
2448
2449 if (!effectMask)
2450 return;
2451
2452 ObjectGuid targetGUID = go->GetGUID();
2453
2454 // Lookup target in already in list
2455 for (std::list<GOTargetInfo>::iterator ihit = m_UniqueGOTargetInfo.begin(); ihit != m_UniqueGOTargetInfo.end(); ++ihit)
2456 {
2457 if (targetGUID == ihit->targetGUID) // Found in list
2458 {
2459 ihit->effectMask |= effectMask; // Add only effect mask
2460 return;
2461 }
2462 }
2463
2464 // This is new target calculate data for him
2465
2466 GOTargetInfo target;
2467 target.targetGUID = targetGUID;
2468 target.effectMask = effectMask;
2469 target.processed = false; // Effects not apply on target
2470
2471 // Spell have speed - need calculate incoming time
2472 if (m_spellInfo->Speed > 0.0f)
2473 {
2474 // calculate spell incoming interval
2475 float dist = m_caster->GetDistance(go->GetPositionX(), go->GetPositionY(), go->GetPositionZ());
2476 if (dist < 5.0f)
2477 dist = 5.0f;
2478 target.timeDelay = uint64(std::floor(dist / m_spellInfo->Speed * 1000.0f));
2479 if (m_delayMoment == 0 || m_delayMoment > target.timeDelay)
2480 m_delayMoment = target.timeDelay;
2481 }
2482 else
2483 target.timeDelay = 0LL;
2484
2485 // Add target to list
2486 m_UniqueGOTargetInfo.push_back(target);
2487}
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
2490{
2491 for (uint32 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
2492 if (!m_spellInfo->Effects[effIndex].IsEffect())
2493 effectMask &= ~(1 << effIndex);
2494
2495 // no effects left
2496 if (!effectMask)
2497 return;
2498
2499 // Lookup target in already in list
2500 for (std::list<ItemTargetInfo>::iterator ihit = m_UniqueItemInfo.begin(); ihit != m_UniqueItemInfo.end(); ++ihit)
2501 {
2502 if (item == ihit->item) // Found in list
2503 {
2504 ihit->effectMask |= effectMask; // Add only effect mask
2505 return;
2506 }
2507 }
2508
2509 // This is new target add data
2510
2511 ItemTargetInfo target;
2512 target.item = item;
2513 target.effectMask = effectMask;
2514
2515 m_UniqueItemInfo.push_back(target);
2516}

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)
2294{
2295 for (uint32 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
2296 if (!m_spellInfo->Effects[effIndex].IsEffect() || !CheckEffectTarget(target, effIndex))
2297 effectMask &= ~(1 << effIndex);
2298
2299 // no effects left
2300 if (!effectMask)
2301 return;
2302
2303 if (checkIfValid)
2304 {
2305 SpellCastResult res = m_spellInfo->CheckTarget(m_caster, target, implicit);
2306 if (res != SPELL_CAST_OK)
2307 return;
2308 }
2309
2310 // Check for effect immune skip if immuned
2311 for (uint32 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
2312 if (target->IsImmunedToSpellEffect(m_spellInfo, effIndex, m_caster))
2313 effectMask &= ~(1 << effIndex);
2314
2315 ObjectGuid targetGUID = target->GetGUID();
2316
2317 // Lookup target in already in list
2318 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
2319 {
2320 if (targetGUID == ihit->targetGUID) // Found in list
2321 {
2322 ihit->effectMask |= effectMask; // Immune effects removed from mask
2323 ihit->scaleAura = false;
2324 if (m_auraScaleMask && ihit->effectMask == m_auraScaleMask && m_caster != target)
2325 {
2326 SpellInfo const* auraSpell = m_spellInfo->GetFirstRankSpell();
2327 if (uint32(target->GetLevel() + 10) >= auraSpell->SpellLevel)
2328 ihit->scaleAura = true;
2329 }
2330
2331 sScriptMgr->OnScaleAuraUnitAdd(this, target, effectMask, checkIfValid, implicit, m_auraScaleMask, *ihit);
2332 return;
2333 }
2334 }
2335
2336 // This is new target calculate data for him
2337
2338 // Get spell hit result on target
2339 TargetInfo targetInfo;
2340 targetInfo.targetGUID = targetGUID; // Store target GUID
2341 targetInfo.effectMask = effectMask; // Store all effects not immune
2342 targetInfo.processed = false; // Effects not apply on target
2343 targetInfo.alive = target->IsAlive();
2344 targetInfo.damage = 0;
2345 targetInfo.damageBeforeTakenMods = 0;
2346 targetInfo.crit = false;
2347 targetInfo.scaleAura = false;
2348 if (m_auraScaleMask && targetInfo.effectMask == m_auraScaleMask && m_caster != target)
2349 {
2350 SpellInfo const* auraSpell = m_spellInfo->GetFirstRankSpell();
2351 if (uint32(target->GetLevel() + 10) >= auraSpell->SpellLevel)
2352 targetInfo.scaleAura = true;
2353 }
2354
2355 sScriptMgr->OnScaleAuraUnitAdd(this, target, effectMask, checkIfValid, implicit, m_auraScaleMask, targetInfo);
2356
2357 // Calculate hit result
2358 if (m_originalCaster)
2359 {
2360 targetInfo.missCondition = m_originalCaster->SpellHitResult(target, this, m_canReflect);
2361 if (m_skipCheck && targetInfo.missCondition != SPELL_MISS_IMMUNE)
2362 {
2363 targetInfo.missCondition = SPELL_MISS_NONE;
2364 }
2365 }
2366 else
2367 targetInfo.missCondition = SPELL_MISS_EVADE; //SPELL_MISS_NONE;
2368
2369 // Spell have speed - need calculate incoming time
2370 // Incoming time is zero for self casts. At least I think so.
2371 if (m_spellInfo->Speed > 0.0f && m_caster != target)
2372 {
2373 // calculate spell incoming interval
2375 float dist = m_caster->GetDistance(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ());
2376
2377 if (dist < 5.0f)
2378 dist = 5.0f;
2379 targetInfo.timeDelay = (uint64) std::floor(dist / m_spellInfo->Speed * 1000.0f);
2380
2381 // Calculate minimum incoming time
2382 if (m_delayMoment == 0 || m_delayMoment > targetInfo.timeDelay)
2383 m_delayMoment = targetInfo.timeDelay;
2384 }
2385 else
2386 targetInfo.timeDelay = 0LL;
2387
2388 // If target reflect spell back to caster
2389 if (targetInfo.missCondition == SPELL_MISS_REFLECT)
2390 {
2391 // Calculate reflected spell result on caster
2393
2394 if (targetInfo.reflectResult == SPELL_MISS_REFLECT) // Impossible reflect again, so simply deflect spell
2395 targetInfo.reflectResult = SPELL_MISS_PARRY;
2396
2397 // Increase time interval for reflected spells by 1.5
2399 targetInfo.timeDelay += targetInfo.timeDelay >> 1;
2400
2402
2403 // HACK: workaround check for succubus seduction case
2405 if (m_caster->IsPet())
2406 {
2407 CreatureTemplate const* ci = sObjectMgr->GetCreatureTemplate(m_caster->GetEntry());
2408 switch (ci->family)
2409 {
2411 {
2412 if (m_spellInfo->SpellIconID != 694) // Soothing Kiss
2413 cancel();
2414 }
2415 break;
2416 return;
2417 }
2418 }
2419 }
2420 else
2421 targetInfo.reflectResult = SPELL_MISS_NONE;
2422
2423 // Add target to list
2424 m_UniqueTargetInfo.push_back(targetInfo);
2425}
std::chrono::milliseconds Milliseconds
Milliseconds shorthand typedef.
Definition Duration.h:27
#define sObjectMgr
Definition ObjectMgr.h:1723
@ 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:7942
bool IsPet() const
Definition Unit.h:797
bool IsAlive() const
Definition Unit.h:1794
SpellMissInfo SpellHitResult(Unit *victim, SpellInfo const *spell, bool canReflect=false)
Definition Unit.cpp:3642
virtual bool IsImmunedToSpellEffect(SpellInfo const *spellInfo, uint32 index, Unit const *caster=nullptr) const
Definition Unit.cpp:10108
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
903{
904 if (m_targets.HasDst())
905 {
906 if (m_targets.HasTraj())
907 {
908 float speed = m_targets.GetSpeedXY();
909 if (speed > 0.0f)
910 return (uint64)std::floor(m_targets.GetDist2d() / speed * 1000.0f);
911 }
912 else if (m_spellInfo->Speed > 0.0f)
913 {
914 // We should not subtract caster size from dist calculation (fixes execution time desync with animation on client, eg. Malleable Goo cast by PP)
915 float dist = m_caster->GetExactDist(*m_targets.GetDstPos());
916 return (uint64)std::floor(dist / m_spellInfo->Speed * 1000.0f);
917 }
918 }
919
920 return 0;
921}
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:400
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:11291
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:11584
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
8583{
8584 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8585 {
8586 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_AFTER_CAST);
8587 std::list<SpellScript::CastHandler>::iterator hookItrEnd = (*scritr)->AfterCast.end(), hookItr = (*scritr)->AfterCast.begin();
8588 for (; hookItr != hookItrEnd; ++hookItr)
8589 (*hookItr).Call(*scritr);
8590
8591 (*scritr)->_FinishScriptCall();
8592 }
8593}
@ 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
8695{
8696 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8697 {
8698 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_AFTER_HIT);
8699 std::list<SpellScript::HitHandler>::iterator hookItrEnd = (*scritr)->AfterHit.end(), hookItr = (*scritr)->AfterHit.begin();
8700 for (; hookItr != hookItrEnd; ++hookItr)
8701 (*hookItr).Call(*scritr);
8702
8703 (*scritr)->_FinishScriptCall();
8704 }
8705}
@ 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
8557{
8558 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8559 {
8560 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_BEFORE_CAST);
8561 std::list<SpellScript::CastHandler>::iterator hookItrEnd = (*scritr)->BeforeCast.end(), hookItr = (*scritr)->BeforeCast.begin();
8562 for (; hookItr != hookItrEnd; ++hookItr)
8563 (*hookItr).Call(*scritr);
8564
8565 (*scritr)->_FinishScriptCall();
8566 }
8567}
@ 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
8669{
8670 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8671 {
8672 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_BEFORE_HIT);
8673 std::list<SpellScript::BeforeHitHandler>::iterator hookItrEnd = (*scritr)->BeforeHit.end(), hookItr = (*scritr)->BeforeHit.begin();
8674 for (; hookItr != hookItrEnd; ++hookItr)
8675 (*hookItr).Call(*scritr, missInfo);
8676
8677 (*scritr)->_FinishScriptCall();
8678 }
8679}
@ 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
8596{
8598 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8599 {
8600 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_CHECK_CAST);
8601 std::list<SpellScript::CheckCastHandler>::iterator hookItrEnd = (*scritr)->OnCheckCast.end(), hookItr = (*scritr)->OnCheckCast.begin();
8602 for (; hookItr != hookItrEnd; ++hookItr)
8603 {
8604 SpellCastResult tempResult = (*hookItr).Call(*scritr);
8605 if (retVal == SPELL_CAST_OK)
8606 retVal = tempResult;
8607 }
8608
8609 (*scritr)->_FinishScriptCall();
8610 }
8611 return retVal;
8612}
@ 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
8736{
8737 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8738 {
8739 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_DESTINATION_TARGET_SELECT);
8740 std::list<SpellScript::DestinationTargetSelectHandler>::iterator hookItrEnd = (*scritr)->OnDestinationTargetSelect.end(), hookItr = (*scritr)->OnDestinationTargetSelect.begin();
8741 for (; hookItr != hookItrEnd; ++hookItr)
8742 if (hookItr->IsEffectAffected(m_spellInfo, effIndex) && targetType.GetTarget() == hookItr->GetTarget())
8743 hookItr->Call(*scritr, target);
8744
8745 (*scritr)->_FinishScriptCall();
8746 }
8747}
@ 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
8621{
8622 // execute script effect handler hooks and check if effects was prevented
8623 bool preventDefault = false;
8624 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8625 {
8626 std::list<SpellScript::EffectHandler>::iterator effItr, effEndItr;
8627 SpellScriptHookType hookType;
8628 switch (mode)
8629 {
8631 effItr = (*scritr)->OnEffectLaunch.begin();
8632 effEndItr = (*scritr)->OnEffectLaunch.end();
8634 break;
8636 effItr = (*scritr)->OnEffectLaunchTarget.begin();
8637 effEndItr = (*scritr)->OnEffectLaunchTarget.end();
8639 break;
8641 effItr = (*scritr)->OnEffectHit.begin();
8642 effEndItr = (*scritr)->OnEffectHit.end();
8644 break;
8646 effItr = (*scritr)->OnEffectHitTarget.begin();
8647 effEndItr = (*scritr)->OnEffectHitTarget.end();
8649 break;
8650 default:
8651 ABORT();
8652 return false;
8653 }
8654 (*scritr)->_PrepareScriptCall(hookType);
8655 for (; effItr != effEndItr; ++effItr)
8656 // effect execution can be prevented
8657 if (!(*scritr)->_IsEffectPrevented(effIndex) && (*effItr).IsEffectAffected(m_spellInfo, effIndex))
8658 (*effItr).Call(*scritr, effIndex);
8659
8660 if (!preventDefault)
8661 preventDefault = (*scritr)->_IsDefaultEffectPrevented(effIndex);
8662
8663 (*scritr)->_FinishScriptCall();
8664 }
8665 return preventDefault;
8666}
#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
8708{
8709 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8710 {
8711 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_OBJECT_AREA_TARGET_SELECT);
8712 std::list<SpellScript::ObjectAreaTargetSelectHandler>::iterator hookItrEnd = (*scritr)->OnObjectAreaTargetSelect.end(), hookItr = (*scritr)->OnObjectAreaTargetSelect.begin();
8713 for (; hookItr != hookItrEnd; ++hookItr)
8714 if (hookItr->IsEffectAffected(m_spellInfo, effIndex) && targetType.GetTarget() == hookItr->GetTarget())
8715 hookItr->Call(*scritr, targets);
8716
8717 (*scritr)->_FinishScriptCall();
8718 }
8719}
@ 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
8722{
8723 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8724 {
8725 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_OBJECT_TARGET_SELECT);
8726 std::list<SpellScript::ObjectTargetSelectHandler>::iterator hookItrEnd = (*scritr)->OnObjectTargetSelect.end(), hookItr = (*scritr)->OnObjectTargetSelect.begin();
8727 for (; hookItr != hookItrEnd; ++hookItr)
8728 if (hookItr->IsEffectAffected(m_spellInfo, effIndex) && targetType.GetTarget() == hookItr->GetTarget())
8729 hookItr->Call(*scritr, target);
8730
8731 (*scritr)->_FinishScriptCall();
8732 }
8733}
@ 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
8570{
8571 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8572 {
8573 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_ON_CAST);
8574 std::list<SpellScript::CastHandler>::iterator hookItrEnd = (*scritr)->OnCast.end(), hookItr = (*scritr)->OnCast.begin();
8575 for (; hookItr != hookItrEnd; ++hookItr)
8576 (*hookItr).Call(*scritr);
8577
8578 (*scritr)->_FinishScriptCall();
8579 }
8580}
@ 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
8682{
8683 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8684 {
8685 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_HIT);
8686 std::list<SpellScript::HitHandler>::iterator hookItrEnd = (*scritr)->OnHit.end(), hookItr = (*scritr)->OnHit.begin();
8687 for (; hookItr != hookItrEnd; ++hookItr)
8688 (*hookItr).Call(*scritr);
8689
8690 (*scritr)->_FinishScriptCall();
8691 }
8692}
@ 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)
6982{
6983 ObjectGuid targetguid = target->GetGUID();
6984
6985 for (SpellEffectInfo const& spellEffectInfo : m_spellInfo->GetEffects())
6986 {
6987 if (!spellEffectInfo.IsAura())
6988 continue;
6989
6990 AuraType const& auraType = spellEffectInfo.ApplyAuraName;
6991 Unit::AuraEffectList const& auras = target->GetAuraEffectsByType(auraType);
6992 for (Unit::AuraEffectList::const_iterator auraIt = auras.begin(); auraIt != auras.end(); ++auraIt)
6993 {
6994 if (GetSpellInfo()->Id == (*auraIt)->GetSpellInfo()->Id)
6995 return false;
6996
6997 switch (sSpellMgr->CheckSpellGroupStackRules(GetSpellInfo(), (*auraIt)->GetSpellInfo()))
6998 {
7000 return false;
7002 if (GetCaster() == (*auraIt)->GetCaster())
7003 return false;
7004 break;
7005 case SPELL_GROUP_STACK_RULE_EXCLUSIVE_SAME_EFFECT: // this one has further checks, but i don't think they're necessary for autocast logic
7007 if (abs(spellEffectInfo.BasePoints) <= abs((*auraIt)->GetAmount()))
7008 return false;
7009 break;
7011 default:
7012 break;
7013 }
7014 }
7015 }
7016
7017 SpellCastResult result = CheckPetCast(target);
7018
7019 if (result == SPELL_CAST_OK || result == SPELL_FAILED_UNIT_NOT_INFRONT)
7020 {
7022 //check if among target units, our WANTED target is as well (->only self cast spells return false)
7023 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
7024 if (ihit->targetGUID == targetguid)
7025 return true;
7026 }
7027 return false; //target invalid
7028}
@ 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:6788

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)
3655{
3657 return;
3658
3659 uint32 oldState = m_spellState;
3661
3662 m_autoRepeat = false;
3663 switch (oldState)
3664 {
3668
3669 if (m_caster->IsPlayer())
3670 {
3672 ArenaSpectator::SendCommand_Spell(m_caster->FindMap(), m_caster->GetGUID(), "SPE", m_spellInfo->Id, bySelf ? 99998 : 99999);
3673 }
3674 [[fallthrough]];
3677 break;
3679 if (!bySelf)
3680 {
3681 for (std::list<TargetInfo>::const_iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
3682 if ((*ihit).missCondition == SPELL_MISS_NONE)
3683 if (Unit* unit = m_caster->GetGUID() == ihit->targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID))
3684 unit->RemoveOwnedAura(m_spellInfo->Id, m_originalCasterGUID, 0, AURA_REMOVE_BY_CANCEL);
3685
3688
3691 }
3692
3694 ArenaSpectator::SendCommand_Spell(m_caster->FindMap(), m_caster->GetGUID(), "SPE", m_spellInfo->Id, bySelf ? 99998 : 99999);
3695
3696 // spell is canceled-take mods and clear list
3697 if (Player* player = m_caster->GetSpellModOwner())
3698 player->RemoveSpellMods(this);
3699
3700 m_appliedMods.clear();
3701 break;
3702 default:
3703 break;
3704 }
3705
3707 if (m_selfContainer && *m_selfContainer == this)
3708 *m_selfContainer = nullptr;
3709
3710 // Do not remove current far sight object (already done in Spell::EffectAddFarsight) to prevent from reset viewpoint to player
3712 {
3714 }
3715
3716 if (m_spellInfo->IsChanneled()) // if not channeled then the object for the current cast wasn't summoned yet
3718
3719 //set state back so finish will be processed
3720 m_spellState = oldState;
3721
3722 sScriptMgr->OnSpellCastCancel(this, m_caster, m_spellInfo, bySelf);
3723
3724 finish(false);
3725}
@ 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:15559
void SendChannelUpdate(uint32 time)
Definition Spell.cpp:5141
void CancelGlobalCooldown()
Definition Spell.cpp:8923
void SetReferencedFromCurrent(bool yes)
Definition Spell.h:576
UsedSpellMods m_appliedMods
Definition Spell.h:560
void RemoveGameObject(GameObject *gameObj, bool del)
Definition Unit.cpp:6583
bool RemoveDynObject(uint32 spellId)
Definition Unit.cpp:6527
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
8924{
8926 return;
8927
8928 // Cancel global cooldown when interrupting current cast
8930 return;
8931
8932 // Only players or controlled units have global cooldown
8933 if (m_caster->GetCharmInfo())
8935 else if (m_caster->IsPlayer())
8937}
@ CURRENT_GENERIC_SPELL
Definition Unit.h:556
void CancelGlobalCooldown(SpellInfo const *spellInfo)
Definition CharmInfo.cpp:424
GlobalCooldownMgr & GetGlobalCooldownMgr()
Definition Player.h:1821
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
8773{
8774 // Relentless strikes, proc only from first effect
8775 if (triggeredByAura && triggeredByAura->SpellIconID == 559)
8776 return effMask & (1 << EFFECT_0);
8777
8778 bool only_on_caster = (triggeredByAura && triggeredByAura->HasAttribute(SPELL_ATTR4_CLASS_TRIGGER_ONLY_ON_TARGET));
8779 // If triggeredByAura has SPELL_ATTR4_CLASS_TRIGGER_ONLY_ON_TARGET then it can only proc on a casted spell with TARGET_UNIT_CASTER
8780 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
8781 {
8782 if ((effMask & (1 << i)) && (!only_on_caster || (m_spellInfo->Effects[i].TargetA.GetTarget() == TARGET_UNIT_CASTER)))
8783 return true;
8784 }
8785 return effMask;
8786}
@ 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
8388{
8389 if (!lockId) // possible case for GO and maybe for items.
8390 return SPELL_CAST_OK;
8391
8392 // Get LockInfo
8393 LockEntry const* lockInfo = sLockStore.LookupEntry(lockId);
8394
8395 if (!lockInfo)
8397
8398 bool reqKey = false; // some locks not have reqs
8399
8400 for (int j = 0; j < MAX_LOCK_CASE; ++j)
8401 {
8402 switch (lockInfo->Type[j])
8403 {
8404 // check key item (many fit cases can be)
8405 case LOCK_KEY_ITEM:
8406 if (lockInfo->Index[j] && m_CastItem && m_CastItem->GetEntry() == lockInfo->Index[j])
8407 return SPELL_CAST_OK;
8408 reqKey = true;
8409 break;
8410 // check key skill (only single first fit case can be)
8411 case LOCK_KEY_SKILL:
8412 {
8413 reqKey = true;
8414
8415 // wrong locktype, skip
8416 if (uint32(m_spellInfo->Effects[effIndex].MiscValue) != lockInfo->Index[j])
8417 continue;
8418
8419 skillId = SkillByLockType(LockType(lockInfo->Index[j]));
8420
8421 if (skillId != SKILL_NONE)
8422 {
8423 reqSkillValue = lockInfo->Skill[j];
8424
8425 // castitem check: rogue using skeleton keys. the skill values should not be added in this case.
8426 skillValue = m_CastItem || !m_caster->IsPlayer() ?
8427 0 : m_caster->ToPlayer()->GetSkillValue(skillId);
8428
8429 // skill bonus provided by casting spell (mostly item spells)
8430 // add the effect base points modifier from the spell casted (cheat lock / skeleton key etc.)
8431 if ((m_spellInfo->Effects[effIndex].TargetA.GetTarget() == TARGET_GAMEOBJECT_ITEM_TARGET || m_spellInfo->Effects[effIndex].TargetB.GetTarget() == TARGET_GAMEOBJECT_ITEM_TARGET)
8433 {
8434 skillValue += m_spellInfo->Effects[effIndex].CalcValue();
8435 }
8436
8437 if (skillValue < reqSkillValue)
8439 }
8440
8441 return SPELL_CAST_OK;
8442 }
8443 case LOCK_KEY_SPELL:
8444 {
8445 if (m_spellInfo->Id == lockInfo->Index[j])
8446 {
8447 return SPELL_CAST_OK;
8448 }
8449 reqKey = true;
8450 break;
8451 }
8452 }
8453 }
8454
8455 if (reqKey)
8457
8458 return SPELL_CAST_OK;
8459}
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:5450
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)
3728{
3729 Player* modOwner = m_caster->GetSpellModOwner();
3730 Spell* lastMod = nullptr;
3731 if (modOwner)
3732 {
3733 lastMod = modOwner->m_spellModTakingSpell;
3734 if (lastMod)
3735 modOwner->SetSpellModTakingSpell(lastMod, false);
3736 }
3737
3738 _cast(skipCheck);
3739
3740 if (lastMod)
3741 modOwner->SetSpellModTakingSpell(lastMod, true);
3742}
Spell * m_spellModTakingSpell
Definition Player.h:2594
Definition Spell.h:298
void _cast(bool skipCheck)
Definition Spell.cpp:3744

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
5611{
5612 // check death state
5615
5616 // Spectator check
5617 if (m_caster->IsPlayer())
5618 if (((Player const*)m_caster)->IsSpectator() && m_spellInfo->Id != SPECTATOR_SPELL_BINDSIGHT)
5619 return SPELL_FAILED_NOT_HERE;
5620
5622
5623 sScriptMgr->OnSpellCheckCast(this, strict, res);
5624
5625 if (res != SPELL_CAST_OK)
5626 return res;
5627
5628 // check cooldowns to prevent cheating
5630 {
5631 if (m_caster->IsPlayer())
5632 {
5633 //can cast triggered (by aura only?) spells while have this flag
5636
5638 {
5641 else
5643 }
5644
5645 // check if we are using a potion in combat for the 2nd+ time. Cooldown is added only after caster gets out of combat
5648 }
5651 }
5652
5654 {
5657 }
5658
5659 // Check global cooldown
5662
5663 // only triggered spells can be processed an ended battleground
5664 if (!IsTriggered() && m_caster->IsPlayer())
5666 if (bg->GetStatus() == STATUS_WAIT_LEAVE)
5668
5669 if (m_caster->IsPlayer() /*&& VMAP::VMapFactory::createOrGetVMapMgr()->isLineOfSightCalcEnabled()*/) // pussywizard: optimization (commented)
5670 {
5672 !m_caster->IsOutdoors())
5674
5678 }
5679
5680 // only check at first call, Stealth auras are already removed at second call
5681 // for now, ignore triggered spells
5683 {
5684 bool checkForm = true;
5685 // Ignore form req aura
5687 for (Unit::AuraEffectList::const_iterator i = ignore.begin(); i != ignore.end(); ++i)
5688 {
5689 if (!(*i)->IsAffectedOnSpell(m_spellInfo))
5690 continue;
5691 checkForm = false;
5692 break;
5693 }
5694 if (checkForm)
5695 {
5696 // Cannot be used in this stance/form
5698 if (shapeError != SPELL_CAST_OK)
5699 return shapeError;
5700
5703 }
5704 }
5705
5707 for (Unit::AuraEffectList::const_iterator blockItr = blockSpells.begin(); blockItr != blockSpells.end(); ++blockItr)
5708 if (uint32((*blockItr)->GetMiscValue()) == m_spellInfo->SpellFamilyName)
5710
5711 bool reqCombat = true;
5713 for (Unit::AuraEffectList::const_iterator j = stateAuras.begin(); j != stateAuras.end(); ++j)
5714 {
5715 if ((*j)->IsAffectedOnSpell(m_spellInfo))
5716 {
5717 m_needComboPoints = false;
5718 if ((*j)->GetMiscValue() == 1)
5719 {
5720 reqCombat = false;
5721 break;
5722 }
5723 }
5724 }
5725
5726 // caster state requirements
5727 // not for triggered spells (needed by execute)
5729 {
5734
5735 // Note: spell 62473 requres CasterAuraSpell = triggering spell
5740
5741 if (reqCombat && m_caster->IsInCombat() && !m_spellInfo->CanBeUsedInCombat())
5743 }
5744
5745 // Xinef: exploit protection
5747 {
5748 if (m_caster->IsPlayer() && m_caster->GetMap()->IsDungeon())
5749 if (InstanceScript* instanceScript = m_caster->GetInstanceScript())
5750 if (instanceScript->IsEncounterInProgress())
5751 {
5752 if (Group* group = m_caster->ToPlayer()->GetGroup())
5753 for (GroupReference* itr = group->GetFirstMember(); itr != nullptr; itr = itr->next())
5754 if (Player* member = itr->GetSource())
5755 if (member->IsInMap(m_caster))
5756 if (Unit* victim = member->GetVictim())
5757 if (victim->IsInCombat() && m_caster->GetDistance(victim) < m_caster->GetVisibilityRange())
5758 {
5759 m_caster->EngageWithTarget(victim);
5760 break;
5761 }
5763 }
5764 }
5765
5766 // cancel autorepeat spells if cast start when moving
5767 // (not wand currently autorepeat cast delayed to moving stop anyway in spell update code)
5768 if (m_caster->IsPlayer() && m_caster->ToPlayer()->isMoving() && !IsTriggered())
5769 {
5770 // skip stuck spell to allow use it in falling case and apply spell limitations at movement
5773 return SPELL_FAILED_MOVING;
5774 }
5775
5776 Vehicle* vehicle = m_caster->GetVehicle();
5778 {
5779 uint16 checkMask = 0;
5780 for (uint8 effIndex = EFFECT_0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
5781 {
5782 SpellEffectInfo const* effInfo = &m_spellInfo->Effects[effIndex];
5784 {
5785 SpellShapeshiftFormEntry const* shapeShiftEntry = sSpellShapeshiftFormStore.LookupEntry(effInfo->MiscValue);
5786 if (shapeShiftEntry && (shapeShiftEntry->flags1 & SHAPESHIFT_FLAG_STANCE) == 0)
5787 checkMask |= VEHICLE_SEAT_FLAG_UNCONTROLLED;
5788 break;
5789 }
5790 }
5791
5794
5795 if (!checkMask)
5796 checkMask = VEHICLE_SEAT_FLAG_CAN_ATTACK;
5797
5798 // All creatures should be able to cast as passengers freely, restriction and attribute are only for players
5799 VehicleSeatEntry const* vehicleSeat = vehicle->GetSeatForPassenger(m_caster);
5801 && (vehicleSeat->m_flags & checkMask) != checkMask && m_caster->IsPlayer())
5803 }
5804
5805 // check spell cast conditions from database
5806 {
5809 ConditionList conditions = sConditionMgr->GetConditionsForNotGroupedEntry(CONDITION_SOURCE_TYPE_SPELL, m_spellInfo->Id);
5810 if (!conditions.empty() && !sConditionMgr->IsObjectMeetToConditions(condInfo, conditions))
5811 {
5812 // mLastFailedCondition can be nullptr if there was an error processing the condition in Condition::Meets (i.e. wrong data for ConditionTarget or others)
5813 if (condInfo.mLastFailedCondition && condInfo.mLastFailedCondition->ErrorType)
5814 {
5818 }
5819 if (!condInfo.mLastFailedCondition || !condInfo.mLastFailedCondition->ConditionTarget)
5822 }
5823 }
5824
5825 // Don't check explicit target for passive spells (workaround) (check should be skipped only for learn case)
5826 // those spells may have incorrect target entries or not filled at all (for example 15332)
5827 // such spells when learned are not targeting anyone using targeting system, they should apply directly to caster instead
5828 // also, such casts shouldn't be sent to client
5829 // Xinef: do not check explicit casts for self cast of triggered spells (eg. reflect case)
5831 {
5832 // Check explicit target for m_originalCaster - todo: get rid of such workarounds
5833 // Xinef: do not check explicit target for triggered spell casted on self with targetflag enemy
5835 {
5837 if (castResult != SPELL_CAST_OK)
5838 return castResult;
5839 }
5840 }
5841
5842 if (Unit* target = m_targets.GetUnitTarget())
5843 {
5844 SpellCastResult castResult = m_spellInfo->CheckTarget(m_caster, target, false);
5845 if (castResult != SPELL_CAST_OK)
5846 return castResult;
5847
5848 if (target != m_caster)
5849 {
5850 // Must be behind the target
5851 if (m_spellInfo->HasAttribute(SPELL_ATTR0_CU_REQ_CASTER_BEHIND_TARGET) && target->HasInArc(static_cast<float>(M_PI), m_caster))
5853
5854 // Target must be facing you
5855 if (m_spellInfo->HasAttribute(SPELL_ATTR0_CU_REQ_TARGET_FACING_CASTER) && !target->HasInArc(static_cast<float>(M_PI), m_caster))
5857
5860 {
5861 bool castedByGameobject = false;
5862 uint32 losChecks = LINEOFSIGHT_ALL_CHECKS;
5864 {
5865 castedByGameobject = m_caster->GetMap()->GetGameObject(m_originalCasterGUID) != nullptr;
5866 }
5867 else if (m_caster->GetEntry() == WORLD_TRIGGER)
5868 {
5869 if (TempSummon* tempSummon = m_caster->ToTempSummon())
5870 {
5871 castedByGameobject = tempSummon->GetSummonerGameObject() != nullptr;
5872 }
5873 }
5874
5875 if (castedByGameobject)
5876 {
5877 // If spell casted by gameobject then ignore M2 models
5878 losChecks &= ~LINEOFSIGHT_CHECK_GOBJECT_M2;
5879 }
5880
5882 {
5884 }
5885 }
5886 }
5887 }
5888
5889 // Check for line of sight for spells with dest
5890 if (m_targets.HasDst())
5891 {
5892 float x, y, z;
5893 m_targets.GetDstPos()->GetPosition(x, y, z);
5894
5897 {
5898 bool castedByGameobject = false;
5899 uint32 losChecks = LINEOFSIGHT_ALL_CHECKS;
5901 {
5902 castedByGameobject = m_caster->GetMap()->GetGameObject(m_originalCasterGUID) != nullptr;
5903 }
5904 else if (m_caster->GetEntry() == WORLD_TRIGGER)
5905 {
5906 if (TempSummon* tempSummon = m_caster->ToTempSummon())
5907 {
5908 castedByGameobject = tempSummon->GetSummonerGameObject() != nullptr;
5909 }
5910 }
5911
5912 if (castedByGameobject)
5913 {
5914 // If spell casted by gameobject then ignore M2 models
5915 losChecks &= ~LINEOFSIGHT_CHECK_GOBJECT_M2;
5916 }
5917
5919 {
5921 }
5922 }
5923 }
5924
5925 // check pet presence
5926 for (int j = 0; j < MAX_SPELL_EFFECTS; ++j)
5927 {
5928 if (m_spellInfo->Effects[j].TargetA.GetTarget() == TARGET_UNIT_PET)
5929 {
5931 {
5932 if (m_triggeredByAuraSpell.spellInfo) // not report pet not existence for triggered spells
5934 else
5935 return SPELL_FAILED_NO_PET;
5936 }
5937 break;
5938 }
5939 }
5940 // Spell casted only on battleground
5942 if (!m_caster->ToPlayer()->InBattleground())
5944
5945 // do not allow spells to be cast in arenas
5946 // - with greater than 10 min CD without SPELL_ATTR4_IGNORE_DEFAULT_ARENA_RESTRICTIONS flag
5947 // - with SPELL_ATTR4_NOT_IN_ARENA_OR_RATED_BATTLEGROUND flag
5950 if (MapEntry const* mapEntry = sMapStore.LookupEntry(m_caster->GetMapId()))
5951 if (mapEntry->IsBattleArena())
5953
5954 // zone check
5956 {
5957 uint32 zone, area;
5958 m_caster->GetZoneAndAreaId(zone, area);
5959
5961 m_caster->IsPlayer() ? m_caster->ToPlayer() : nullptr);
5962 if (locRes != SPELL_CAST_OK)
5963 return locRes;
5964 }
5965
5966 // not let players cast spells at mount (and let do it to creatures)
5969 {
5970 if (m_caster->IsInFlight())
5972 else
5974 }
5975
5976 SpellCastResult castResult = SPELL_CAST_OK;
5977
5978 // always (except passive spells) check items (focus object can be required for any type casts)
5979 if (!m_spellInfo->IsPassive())
5980 {
5981 // spell focus needs to be checked not only for players! there are vehicle spells that require spell focus
5982 castResult = CheckSpellFocus();
5983 if (castResult != SPELL_CAST_OK)
5984 return castResult;
5985
5986 castResult = CheckItems();
5987 if (castResult != SPELL_CAST_OK)
5988 return castResult;
5989 }
5990
5991 // Triggered spells also have range check
5993 castResult = CheckRange(strict);
5994 if (castResult != SPELL_CAST_OK)
5995 return castResult;
5996
5998 {
5999 castResult = CheckPower();
6000 if (castResult != SPELL_CAST_OK)
6001 return castResult;
6002 }
6003
6005 {
6006 return SPELL_CAST_OK;
6007 }
6008
6009 // xinef: do not skip triggered spells if they posses prevention type (eg. Bladestorm vs Hand of Protection)
6011 {
6013 if (castResult != SPELL_CAST_OK)
6014 return castResult;
6015
6016 // 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).
6018 {
6019 auto const& mechanicList = m_caster->m_spellImmune[IMMUNITY_MECHANIC];
6020 if (mechanicList.count(m_spellInfo->Mechanic) > 0)
6022 }
6023 }
6024
6025 // script hook
6026 castResult = CallScriptCheckCastHandlers();
6027 if (castResult != SPELL_CAST_OK)
6028 return castResult;
6029
6030 bool hasDispellableAura = false;
6031 bool hasNonDispelEffect = false;
6032 uint32 dispelMask = 0;
6033 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
6034 if (m_spellInfo->Effects[i].Effect == SPELL_EFFECT_DISPEL)
6035 {
6037 {
6038 hasDispellableAura = true;
6039 break;
6040 }
6041
6042 dispelMask |= SpellInfo::GetDispelMask(DispelType(m_spellInfo->Effects[i].MiscValue));
6043 }
6044 else if (m_spellInfo->Effects[i].IsEffect())
6045 {
6046 hasNonDispelEffect = true;
6047 break;
6048 }
6049
6050 if (!hasNonDispelEffect && !hasDispellableAura && dispelMask && !IsTriggered())
6051 {
6052 if (Unit* target = m_targets.GetUnitTarget())
6053 {
6054 // Xinef: do not allow to cast on hostile targets in sanctuary
6055 if (!m_caster->IsFriendlyTo(target))
6056 {
6057 if (m_caster->IsInSanctuary() || target->IsInSanctuary())
6058 {
6059 // Xinef: fix for duels
6060 Player* player = m_caster->ToPlayer();
6061 if (!player || !player->duel || target != player->duel->Opponent)
6063 }
6064 }
6065
6066 DispelChargesList dispelList;
6067 target->GetDispellableAuraList(m_caster, dispelMask, dispelList, m_spellInfo);
6068
6069 if (dispelList.empty())
6071 }
6072 }
6073
6074 uint8 approximateAuraEffectMask = 0;
6075 uint8 nonAuraEffectMask = 0;
6076 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
6077 {
6078 // for effects of spells that have only one target
6079 switch (m_spellInfo->Effects[i].Effect)
6080 {
6082 {
6083 if (!m_caster->IsPlayer())
6085
6086 if (m_spellInfo->Effects[i].TargetA.GetTarget() != TARGET_UNIT_PET)
6087 break;
6088
6089 Pet* pet = m_caster->ToPlayer()->GetPet();
6090
6091 if (!pet)
6092 return SPELL_FAILED_NO_PET;
6093
6094 SpellInfo const* learn_spellproto = sSpellMgr->GetSpellInfo(m_spellInfo->Effects[i].TriggerSpell);
6095
6096 if (!learn_spellproto)
6098
6099 if (m_spellInfo->SpellLevel > pet->GetLevel())
6100 return SPELL_FAILED_LOWLEVEL;
6101
6102 break;
6103 }
6105 {
6106 // check target only for unit target case
6108 {
6109 if (!m_caster->IsPlayer())
6111
6112 Pet* pet = unitTarget->ToPet();
6113 if (!pet || pet->GetOwner() != m_caster)
6115
6116 SpellInfo const* learn_spellproto = sSpellMgr->GetSpellInfo(m_spellInfo->Effects[i].TriggerSpell);
6117
6118 if (!learn_spellproto)
6120
6121 if (m_spellInfo->SpellLevel > pet->GetLevel())
6122 return SPELL_FAILED_LOWLEVEL;
6123 }
6124 break;
6125 }
6127 {
6128 uint32 glyphId = m_spellInfo->Effects[i].MiscValue;
6129 if (GlyphPropertiesEntry const* gp = sGlyphPropertiesStore.LookupEntry(glyphId))
6130 if (m_caster->HasAura(gp->SpellId))
6132 break;
6133 }
6135 {
6136 if (!m_caster->IsPlayer())
6138
6139 Item* foodItem = m_targets.GetItemTarget();
6140 if (!foodItem)
6142
6143 Pet* pet = m_caster->ToPlayer()->GetPet();
6144
6145 if (!pet)
6146 return SPELL_FAILED_NO_PET;
6147
6148 if (!pet->HaveInDiet(foodItem->GetTemplate()))
6150
6151 if (!pet->GetCurrentFoodBenefitLevel(foodItem->GetTemplate()->ItemLevel))
6153
6154 if (m_caster->IsInCombat() || pet->IsInCombat())
6156
6157 break;
6158 }
6161 {
6162 // Can be area effect, Check only for players and not check if target - caster (spell can have multiply drain/burn effects)
6163 if (m_caster->IsPlayer())
6164 if (Unit* target = m_targets.GetUnitTarget())
6165 if (target != m_caster && !target->HasActivePowerType(Powers(m_spellInfo->Effects[i].MiscValue)))
6167 break;
6168 }
6170 {
6172 {
6174 }
6175
6177 {
6178 // Warbringer - can't be handled in proc system - should be done before checkcast root check and charge effect process
6179 if (strict && m_caster->IsScriptOverriden(m_spellInfo, 6953))
6181 }
6183 {
6184 // Exception for Master's Call
6185 if (m_spellInfo->Id != 54216)
6186 {
6187 return SPELL_FAILED_ROOTED;
6188 }
6189 }
6190 if (m_caster->IsPlayer())
6191 if (Unit* target = m_targets.GetUnitTarget())
6192 if (!target->IsAlive())
6194 // Xinef: Pass only explicit unit target spells
6195 // pussywizard:
6196 if (sDisableMgr->IsPathfindingEnabled(m_caster->FindMap()) && m_spellInfo->NeedsExplicitUnitTarget())
6197 {
6198 Unit* target = m_targets.GetUnitTarget();
6199 if (!target)
6201
6202 // first we must check to see if the target is in LoS. A path can usually be built but LoS matters for charge spells
6203 if (!target->IsWithinLOSInMap(m_caster)) //Do full LoS/Path check. Don't exclude m2
6205
6206 float objSize = target->GetCombatReach();
6207 float range = m_spellInfo->GetMaxRange(true, m_caster, this) * 1.5f + objSize; // can't be overly strict
6208
6209 m_preGeneratedPath = std::make_unique<PathGenerator>(m_caster);
6210 m_preGeneratedPath->SetPathLengthLimit(range);
6211
6212 // first try with raycast, if it fails fall back to normal path
6213 bool result = m_preGeneratedPath->CalculatePath(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), false);
6214 if (m_preGeneratedPath->GetPathType() & PATHFIND_SHORT)
6215 return SPELL_FAILED_NOPATH;
6216 else if (!result || m_preGeneratedPath->GetPathType() & (PATHFIND_NOPATH | PATHFIND_INCOMPLETE))
6217 return SPELL_FAILED_NOPATH;
6218 else if (m_preGeneratedPath->IsInvalidDestinationZ(target)) // Check position z, if not in a straight line
6219 return SPELL_FAILED_NOPATH;
6220
6221 m_preGeneratedPath->ShortenPathUntilDist(G3D::Vector3(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ()), objSize); // move back
6222 }
6223 if (Player* player = m_caster->ToPlayer())
6224 player->SetCanTeleport(true);
6225 break;
6226 }
6228 {
6231
6234
6235 Creature* creature = m_targets.GetUnitTarget()->ToCreature();
6236 if (!creature->IsCritter() && !creature->loot.isLooted())
6238
6239 uint32 skill = creature->GetCreatureTemplate()->GetRequiredLootSkill();
6240
6241 int32 skillValue = m_caster->ToPlayer()->GetSkillValue(skill);
6242 int32 TargetLevel = m_targets.GetUnitTarget()->GetLevel();
6243 int32 ReqValue = (skillValue < 100 ? (TargetLevel - 10) * 10 : TargetLevel * 5);
6244 if (ReqValue > skillValue)
6246
6247 break;
6248 }
6250 {
6251 if (m_spellInfo->Effects[i].TargetA.GetTarget() != TARGET_GAMEOBJECT_TARGET &&
6252 m_spellInfo->Effects[i].TargetA.GetTarget() != TARGET_GAMEOBJECT_ITEM_TARGET)
6253 break;
6254
6255 if (!m_caster->IsPlayer() // only players can open locks, gather etc.
6256 // we need a go target in case of TARGET_GAMEOBJECT_TARGET
6257 || (m_spellInfo->Effects[i].TargetA.GetTarget() == TARGET_GAMEOBJECT_TARGET && !m_targets.GetGOTarget()))
6259
6260 Item* pTempItem = nullptr;
6262 {
6263 if (TradeData* pTrade = m_caster->ToPlayer()->GetTradeData())
6264 pTempItem = pTrade->GetTraderData()->GetItem(TradeSlots(m_targets.GetItemTargetGUID().GetRawValue()));
6265 }
6268
6269 // we need a go target, or an openable item target in case of TARGET_GAMEOBJECT_ITEM_TARGET
6270 if (m_spellInfo->Effects[i].TargetA.GetTarget() == TARGET_GAMEOBJECT_ITEM_TARGET &&
6272 (!pTempItem || !pTempItem->GetTemplate()->LockID || !pTempItem->IsLocked()))
6274
6275 // We must also ensure the gameobject we are opening is still closed by the time the spell finishes.
6276 if (GameObject* go = m_targets.GetGOTarget())
6277 {
6278 if (go->GetGoType() == GAMEOBJECT_TYPE_DOOR && go->GetGoState() != GO_STATE_READY)
6279 {
6281 }
6282 }
6283 if (m_spellInfo->Id != 1842 || (m_targets.GetGOTarget() &&
6285 {
6286 if (m_targets.GetGOTarget() && m_targets.GetGOTarget()->GetEntry() == 179697)
6287 {
6288 if (!m_caster->ToPlayer()->CanUseBattlegroundObject(nullptr))
6290 }
6291 else if (m_caster->ToPlayer()->InBattleground() && // In Battleground players can use only flags and banners, or Gurubashi chest
6294 }
6295
6296 // get the lock entry
6297 uint32 lockId = 0;
6298 if (GameObject* go = m_targets.GetGOTarget())
6299 {
6300 lockId = go->GetGOInfo()->GetLockId();
6301 if (!lockId)
6303 }
6304 else if (Item* itm = m_targets.GetItemTarget())
6305 lockId = itm->GetTemplate()->LockID;
6306
6307 SkillType skillId = SKILL_NONE;
6308 int32 reqSkillValue = 0;
6309 int32 skillValue = 0;
6310
6311 // check lock compatibility
6312 SpellCastResult res = CanOpenLock(i, lockId, skillId, reqSkillValue, skillValue);
6313 if (res != SPELL_CAST_OK)
6314 return res;
6315
6316 // chance for fail at lockpicking attempt
6317 // second check prevent fail at rechecks
6318 // herbalism and mining cannot fail as of patch 3.1.0
6319 if (skillId != SKILL_NONE && skillId != SKILL_HERBALISM && skillId != SKILL_MINING && (!m_selfContainer || ((*m_selfContainer) != this)))
6320 {
6321 // chance for failure in orange lockpick
6322 if (skillId == SKILL_LOCKPICKING && reqSkillValue > irand(skillValue - 25, skillValue + 37))
6323 {
6325 }
6326 }
6327 break;
6328 }
6330 {
6331 Unit* unitCaster = m_caster->ToUnit();
6332 if (!unitCaster)
6333 {
6335 }
6336
6337 Creature* pet = unitCaster->GetGuardianPet();
6338 if (pet)
6339 {
6340 if (pet->IsAlive())
6341 {
6343 }
6344 }
6345 else if (Player* playerCaster = m_caster->ToPlayer())
6346 {
6347 PetStable& petStable = playerCaster->GetOrInitPetStable();
6348 if (!petStable.CurrentPet && petStable.UnslottedPets.empty())
6349 {
6350 return SPELL_FAILED_NO_PET;
6351 }
6352 }
6353
6354 break;
6355 }
6356 // This is generic summon effect
6358 {
6359 SummonPropertiesEntry const* SummonProperties = sSummonPropertiesStore.LookupEntry(m_spellInfo->Effects[i].MiscValueB);
6360 if (!SummonProperties || m_spellInfo->HasAttribute(SPELL_ATTR1_DISMISS_PET_FIRST))
6361 break;
6362 switch (SummonProperties->Category)
6363 {
6365 if (m_caster->GetPetGUID())
6367 [[fallthrough]];
6369 if (m_caster->GetCharmGUID())
6371 break;
6372 }
6373 break;
6374 }
6376 {
6378 {
6383 }
6384 break;
6385 }
6387 {
6388 Unit* unitCaster = m_caster->ToUnit();
6389 if (!unitCaster)
6391
6393 {
6394 if (m_caster->GetPetGUID())
6396 if (m_caster->GetCharmGUID())
6398 }
6399
6401 if (Pet* pet = m_caster->ToPlayer()->GetPet())
6402 pet->CastSpell(pet, 32752, true, nullptr, nullptr, pet->GetGUID()); //starting cast, trigger pet stun (cast by pet so it doesn't attack player)
6403
6404 Player* playerCaster = unitCaster->ToPlayer();
6405 if (playerCaster && playerCaster->GetPetStable())
6406 {
6407 std::pair<PetStable::PetInfo const*, PetSaveMode> info = Pet::GetLoadPetInfo(*playerCaster->GetPetStable(), m_spellInfo->Effects[i].MiscValue, 0, false);
6408 if (info.first)
6409 {
6410 if (info.first->Type == HUNTER_PET)
6411 {
6412 if (!info.first->Health)
6413 {
6414 playerCaster->SendTameFailure(PET_TAME_DEAD);
6416 }
6417
6418 CreatureTemplate const* creatureInfo = sObjectMgr->GetCreatureTemplate(info.first->CreatureId);
6419 if (!creatureInfo || !creatureInfo->IsTameable(playerCaster->CanTameExoticPets()))
6420 {
6421 // if problem in exotic pet
6422 if (creatureInfo && creatureInfo->IsTameable(true))
6424 else
6426
6428 }
6429 }
6430 }
6431 else if (!m_spellInfo->Effects[i].MiscValue) // when miscvalue is present it is allowed to create new pets
6432 {
6435 }
6436 }
6437 break;
6438 }
6440 {
6441 if (!m_caster->IsPlayer())
6443 if (!m_caster->GetTarget())
6445
6447 if (!target || (!target->IsInSameRaidWith(m_caster->ToPlayer()) && m_spellInfo->Id != 48955)) // refer-a-friend spell
6449
6450 // Xinef: Implement summon pending error
6451 if (target->GetSummonExpireTimer() > GameTime::GetGameTime().count())
6453
6454 // check if our map is dungeon
6455 MapEntry const* map = sMapStore.LookupEntry(m_caster->GetMapId());
6456 if (map->IsDungeon())
6457 {
6458 uint32 mapId = m_caster->GetMap()->GetId();
6459 Difficulty difficulty = m_caster->GetMap()->GetDifficulty();
6460 /*if (map->IsRaid())
6461 if (InstancePlayerBind* targetBind = target->GetBoundInstance(mapId, difficulty))
6462 if (targetBind->perm && targetBind != m_caster->ToPlayer()->GetBoundInstance(mapId, difficulty))
6463 return SPELL_FAILED_TARGET_LOCKED_TO_RAID_INSTANCE;*/
6464
6465 InstanceTemplate const* instance = sObjectMgr->GetInstanceTemplate(mapId);
6466 if (!instance)
6468 if (!target->Satisfy(sObjectMgr->GetAccessRequirement(mapId, difficulty), mapId))
6470 }
6471 break;
6472 }
6473 // RETURN HERE
6475 {
6476 if (!m_caster->IsPlayer())
6478
6479 Player* playerCaster = m_caster->ToPlayer();
6480 //
6481 if (!(playerCaster->GetTarget()))
6483
6485
6486 if (!target ||
6487 !(target->GetSession()->GetRecruiterId() == playerCaster->GetSession()->GetAccountId() || target->GetSession()->GetAccountId() == playerCaster->GetSession()->GetRecruiterId()))
6489
6490 // Xinef: Implement summon pending error
6491 if (target->GetSummonExpireTimer() > GameTime::GetGameTime().count())
6493
6494 break;
6495 }
6496 case SPELL_EFFECT_LEAP:
6498 {
6499 //Do not allow to cast it before BG starts.
6500 if (m_caster->IsPlayer())
6501 if (Battleground const* bg = m_caster->ToPlayer()->GetBattleground())
6502 if (bg->GetStatus() != STATUS_IN_PROGRESS)
6504 break;
6505 }
6507 {
6510
6511 bool found = false;
6513 for(Unit::VisibleAuraMap::const_iterator itr = visibleAuras->begin(); itr != visibleAuras->end(); ++itr)
6514 {
6515 if (itr->second->GetBase()->IsPassive())
6516 continue;
6517
6518 if (!itr->second->IsPositive())
6519 continue;
6520
6521 found = true;
6522 break;
6523 }
6524
6525 if (!found)
6527
6528 break;
6529 }
6531 {
6533 {
6534 if (m_caster->IsPlayer())
6535 return SPELL_FAILED_ROOTED;
6536 else
6538 }
6539 break;
6540 }
6541 // xinef: do not allow to use leaps while rooted
6542 case SPELL_EFFECT_JUMP:
6544 {
6546 return SPELL_FAILED_ROOTED;
6547 break;
6548 }
6550 if (!sScriptMgr->CanSelectSpecTalent(this))
6552 // can't change during already started arena/battleground
6553 if (m_caster->IsPlayer())
6554 if (Battleground const* bg = m_caster->ToPlayer()->GetBattleground())
6555 if (bg->GetStatus() == STATUS_IN_PROGRESS)
6557 break;
6558 default:
6559 break;
6560 }
6561
6562 if (m_spellInfo->Effects[i].IsAura())
6563 approximateAuraEffectMask |= 1 << i;
6564 else if (m_spellInfo->Effects[i].IsEffect())
6565 nonAuraEffectMask |= 1 << i;
6566 }
6567
6568 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
6569 {
6570 switch (m_spellInfo->Effects[i].ApplyAuraName)
6571 {
6572 case SPELL_AURA_DUMMY:
6573 break;
6575 {
6576 if (!m_caster->IsPlayer())
6577 return SPELL_FAILED_NO_PET;
6578
6579 Pet* pet = m_caster->ToPlayer()->GetPet();
6580 if (!pet)
6581 return SPELL_FAILED_NO_PET;
6582
6583 if (pet->GetCharmerGUID())
6584 return SPELL_FAILED_CHARMED;
6585 break;
6586 }
6590 {
6591 if (m_caster->GetCharmerGUID())
6592 return SPELL_FAILED_CHARMED;
6593
6594 // Xinef: allow SPELL_AURA_MOD_POSSESS to posses target if caster has some pet
6596 {
6597 if (m_caster->GetPetGUID())
6599
6600 if (m_caster->GetCharmGUID())
6602 }
6603 else if (m_spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_MOD_POSSESS)
6604 {
6605 if (m_caster->GetCharmGUID())
6607 }
6608
6609 if (Unit* target = m_targets.GetUnitTarget())
6610 {
6611 if (target->IsCreature() && target->ToCreature()->IsVehicle())
6613
6614 // Allow SPELL_AURA_MOD_POSSESS to work on mounted players,
6615 // but keep the old restriction for everything else.
6616 if (target->IsMounted())
6617 {
6618 if (!(target->IsPlayer() && m_spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_MOD_POSSESS))
6620 }
6621
6622 if (target->GetCharmerGUID())
6623 return SPELL_FAILED_CHARMED;
6624
6625 if (target->GetOwnerGUID() && target->GetOwnerGUID().IsPlayer())
6627
6628 if (target->IsPet() && (!target->GetOwner() || target->GetOwner()->ToPlayer()))
6630
6631 int32 damage = CalculateSpellDamage(i, target);
6632 if (damage && int32(target->GetLevel()) > damage)
6634 }
6635
6636 break;
6637 }
6638 case SPELL_AURA_MOUNTED:
6639 {
6640 // Disallow casting flying mounts in water
6643
6644 // Ignore map check if spell have AreaId. AreaId already checked and this prevent special mount spells
6645 bool allowMount = !m_caster->GetMap()->IsDungeon() || m_caster->GetMap()->IsBattlegroundOrArena();
6646 InstanceTemplate const* it = sObjectMgr->GetInstanceTemplate(m_caster->GetMapId());
6647 if (it)
6648 allowMount = it->AllowMount;
6649 if (m_caster->IsPlayer() && !allowMount && !m_spellInfo->AreaGroupId)
6651
6654
6655 // xinef: dont allow to cast mounts in specific transforms
6656 if (m_caster->getTransForm())
6657 if (SpellInfo const* transformSpellInfo = sSpellMgr->GetSpellInfo(m_caster->getTransForm()))
6658 if (transformSpellInfo->HasAttribute(SPELL_ATTR0_NO_IMMUNITIES) &&
6659 !transformSpellInfo->HasAttribute(SpellAttr0(SPELL_ATTR0_ALLOW_WHILE_MOUNTED | SPELL_ATTR0_AURA_IS_DEBUFF)))
6661
6662 break;
6663 }
6665 {
6666 if (!m_targets.GetUnitTarget())
6668
6669 // can be casted at non-friendly unit or own pet/charm
6672
6673 break;
6674 }
6675 case SPELL_AURA_FLY:
6677 {
6678 // Xinef: added water check
6679 if (m_caster->IsInWater())
6681
6682 // not allow cast fly spells if not have req. skills (all spells is self target)
6683 // allow always ghost flight spells
6685 {
6686 Battlefield* Bf = sBattlefieldMgr->GetBattlefieldToZoneId(m_originalCaster->GetZoneId());
6687 if (AreaTableEntry const* pArea = sAreaTableStore.LookupEntry(m_originalCaster->GetAreaId()))
6688 if ((pArea->flags & AREA_FLAG_NO_FLY_ZONE) || (Bf && !Bf->CanFlyIn()))
6689 return SPELL_FAILED_NOT_HERE;
6690 }
6691 break;
6692 }
6694 {
6695 if (m_spellInfo->Effects[i].IsTargetingArea())
6696 break;
6697
6698 if (!m_caster->IsPlayer() || m_CastItem)
6699 break;
6700
6701 if (!m_targets.GetUnitTarget())
6703
6706
6707 break;
6708 }
6709 case SPELL_AURA_HOVER:
6710 {
6712 {
6714 }
6715 break;
6716 }
6718 {
6719 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.
6720 {
6722 }
6723 break;
6724 }
6725 default:
6726 break;
6727 }
6728
6729 // check if target already has the same type, but more powerful aura
6730 if (!nonAuraEffectMask && (approximateAuraEffectMask & (1 << i)) && !m_spellInfo->IsTargetingArea())
6731 if (Unit* target = m_targets.GetUnitTarget())
6732 if (!target->IsHighestExclusiveAuraEffect(m_spellInfo, AuraType(m_spellInfo->Effects[i].ApplyAuraName),
6733 m_spellInfo->Effects[i].CalcValue(m_caster, &m_spellValue->EffectBasePoints[i]), approximateAuraEffectMask, false))
6735 }
6736
6737 // check trade slot case (last, for allow catch any another cast problems)
6739 {
6740 if (m_CastItem)
6742
6743 if (!m_caster->IsPlayer())
6745
6746 TradeData* my_trade = m_caster->ToPlayer()->GetTradeData();
6747
6748 if (!my_trade)
6750
6752 if (slot != TRADE_SLOT_NONTRADED)
6754
6755 if (!IsTriggered())
6756 if (my_trade->GetSpell())
6758 }
6759
6760 // check if caster has at least 1 combo point on target for spells that require combo points
6762 {
6764 {
6766 {
6768 }
6769 }
6770 else
6771 {
6772 if (!m_caster->GetComboPoints())
6773 {
6775 }
6776 }
6777 }
6778
6779 // xinef: check relic cooldown
6783
6784 // all ok
6785 return SPELL_CAST_OK;
6786}
#define SPECTATOR_SPELL_BINDSIGHT
Definition ArenaSpectator.h:38
#define sBattlefieldMgr
Definition BattlefieldMgr.h:76
@ 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:208
bool CanFlyIn() const
Return if we can use mount in battlefield.
Definition Battlefield.h:343
Definition Battleground.h:294
Loot loot
Definition Creature.h:231
CreatureTemplate const * GetCreatureTemplate() const
Definition Creature.h:207
bool IsSpellProhibited(SpellSchoolMask idSchoolMask) const
Definition Creature.cpp:2937
Definition GameObject.h:120
GameObjectTemplate const * GetGOInfo() const
Definition GameObject.h:136
Definition GroupReference.h:27
GroupReference * next()
Definition GroupReference.h:36
Definition Group.h:169
Definition InstanceScript.h:143
bool IsLocked() const
Definition Item.h:253
ItemTemplate const * GetTemplate() const
Definition Item.cpp:544
bool IsPotion() const
Definition Item.h:337
bool IsDungeon() const
Definition Map.h:297
bool IsBattlegroundOrArena() const
Definition Map.h:305
GameObject * GetGameObject(ObjectGuid const &guid)
Definition Map.cpp:2354
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:2535
bool IsInSameRaidWith(Player const *p) const
Definition Player.h:1903
bool CanTameExoticPets() const
Definition Player.h:2209
bool CanUseBattlegroundObject(GameObject *gameobject) const
Definition Player.cpp:13273
bool InBattleground() const
Definition Player.h:2288
PetStable * GetPetStable()
Definition Player.h:1222
Battleground * GetBattleground(bool create=false) const
Definition Player.cpp:12187
WorldSession * GetSession() const
Definition Player.h:2020
bool HasSpellCooldown(uint32 spell_id) const override
Definition Player.cpp:16404
uint32 GetLastPotionId()
Definition Player.h:1828
Group * GetGroup()
Definition Player.h:2505
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:6778
bool HasPlayerFlag(PlayerFlags flags) const
Definition Player.h:1123
std::unique_ptr< DuelInfo > duel
Definition Player.h:1895
Item * GetItemByGuid(ObjectGuid guid) const
Definition PlayerStorage.cpp:410
GameObject * GetGOTarget() const
Definition Spell.cpp:263
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:7760
SpellCastResult CanOpenLock(uint32 effIndex, uint32 lockid, SkillType &skillid, int32 &reqSkillValue, int32 &skillValue)
Definition Spell.cpp:8387
int32 CalculateSpellDamage(uint8 i, Unit const *target) const
Definition Spell.h:491
SpellCastResult CheckPower()
Definition Spell.cpp:7116
SpellCastResult CheckCasterAuras(bool preventionOnly) const
Definition Spell.cpp:6824
SpellCastResult CallScriptCheckCastHandlers()
Definition Spell.cpp:8595
SpellCastResult CheckItems(uint32 *param1=nullptr, uint32 *param2=nullptr)
Definition Spell.cpp:7161
SpellCastResult CheckRange(bool strict)
Definition Spell.cpp:7030
bool HasGlobalCooldown() const
Definition Spell.cpp:8867
Definition TemporarySummon.h:50
uint32 GetSpell() const
Definition TradeData.h:49
bool IsVehicle() const
Definition Unit.h:800
Vehicle * GetVehicle() const
Definition Unit.h:1927
SpellImmuneContainer m_spellImmune[MAX_SPELL_IMMUNITY]
Definition Unit.h:2090
Unit * GetOwner() const
Definition Unit.cpp:7699
Pet * ToPet()
Definition Unit.h:729
virtual bool HasSpellCooldown(uint32) const
Definition Unit.h:1335
ShapeshiftForm GetShapeshiftForm() const
Definition Unit.h:1958
virtual bool HasSpellItemCooldown(uint32, uint32) const
Definition Unit.h:1336
bool IsInDisallowedMountForm() const
Definition Unit.cpp:17303
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:6110
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:1842
bool HasAura(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemCasterGUID=ObjectGuid::Empty, uint8 reqEffMask=0) const
Definition Unit.cpp:5999
std::map< uint8, AuraApplication * > VisibleAuraMap
Definition Unit.h:687
bool IsInFlight() const
Definition Unit.h:1706
void SendTameFailure(uint8 result)
Definition Unit.cpp:15970
void GetDispellableAuraList(Unit *caster, uint32 dispelMask, DispelChargesList &dispelList, SpellInfo const *dispelSpell)
Definition Unit.cpp:5883
bool HasUnitMovementFlag(uint32 f) const
Definition Unit.h:774
virtual bool IsInWater() const
Definition Unit.cpp:4535
bool HasAuraState(AuraStateType flag, SpellInfo const *spellProto=nullptr, Unit const *Caster=nullptr) const
Definition Unit.cpp:7646
bool isMoving() const
Definition Unit.h:1709
void EngageWithTarget(Unit *who)
Definition Unit.cpp:7519
ObjectGuid GetCharmGUID() const
Definition Unit.h:721
VisibleAuraMap const * GetVisibleAuras()
Definition Unit.h:1539
bool IsMounted() const
Definition Unit.h:1887
Unit * GetVictim() const
Definition Unit.h:903
bool IsCritter() const
Definition Unit.h:833
bool IsFriendlyTo(Unit const *unit) const
Definition Unit.cpp:7258
ObjectGuid GetOwnerGUID() const
Definition Unit.h:713
bool IsHighestExclusiveAuraEffect(SpellInfo const *spellInfo, AuraType auraType, int32 effectAmount, uint8 auraEffectMask, bool removeOtherAuraApplications=false)
Definition Unit.cpp:4584
uint8 GetComboPoints(Unit const *who=nullptr) const
Definition Unit.h:1014
ObjectGuid GetCharmerGUID() const
Definition Unit.h:719
uint32 getTransForm() const
Definition Unit.h:1969
virtual bool HasActivePowerType(Powers power)
Definition Unit.h:1132
void RemoveMovementImpairingAuras(bool withRoot)
Definition Unit.cpp:5503
bool IsTotem() const
Definition Unit.h:799
Guardian * GetGuardianPet() const
Definition Unit.cpp:7750
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:623
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:617
uint32 GetAccountId() const
Definition WorldSession.h:453
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
6825{
6826 // spells totally immuned to caster auras (wsg flag drop, give marks etc)
6828 return SPELL_CAST_OK;
6829
6830 uint8 school_immune = 0;
6831 uint64 mechanic_immune = 0;
6832 uint32 dispel_immune = 0;
6833
6834 // Check if the spell grants school or mechanic immunity.
6835 // We use bitmasks so the loop is done only once and not on every aura check below.
6837 {
6838 for (int i = 0; i < MAX_SPELL_EFFECTS; ++i)
6839 {
6840 if (m_spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_SCHOOL_IMMUNITY)
6841 school_immune |= uint32(m_spellInfo->Effects[i].MiscValue);
6842 else if (m_spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_MECHANIC_IMMUNITY)
6843 mechanic_immune |= 1ULL << uint32(m_spellInfo->Effects[i].MiscValue);
6844 else if (m_spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_DISPEL_IMMUNITY)
6845 dispel_immune |= SpellInfo::GetDispelMask(DispelType(m_spellInfo->Effects[i].MiscValue));
6846 }
6847 // immune movement impairment and loss of control
6848 // PVP trinket EMFH TOC PVP trinket Bullheaded Bestial Wrath // Beath Within // Medalion of Immunity
6849 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)
6851 }
6852
6854
6855 // Glyph of Pain Suppression
6856 // there is no other way to handle it
6857 if (m_spellInfo->Id == 33206 && !m_caster->HasAura(63248))
6858 usableInStun = false;
6859
6860 // Check whether the cast should be prevented by any state you might have.
6861 SpellCastResult prevented_reason = SPELL_CAST_OK;
6862 // Have to check if there is a stun aura. Otherwise will have problems with ghost aura apply while logging out
6863 uint32 unitflag = m_caster->GetUnitFlags(); // Get unit state
6864
6865 // Xinef: if spell is triggered check preventionType only
6866 if (!preventionOnly)
6867 {
6868 if (unitflag & UNIT_FLAG_STUNNED)
6869 {
6870 // spell is usable while stunned, check if caster has only mechanic stun auras, another stun types must prevent cast spell
6871 if (usableInStun)
6872 {
6873 bool foundNotStun = false;
6874 uint64 mask = (1ULL << MECHANIC_STUN) | (1ULL << MECHANIC_FREEZE) | (1ULL << MECHANIC_HORROR);
6875 // Barkskin should skip sleep effects, sap and fears
6876 if (m_spellInfo->Id == 22812)
6877 mask |= 1ULL << MECHANIC_SAPPED | 1ULL << MECHANIC_HORROR | 1ULL << MECHANIC_SLEEP;
6878 // Hand of Freedom, can be used while sapped and while under fear-mechanic stuns (e.g. Intimidating Shout primary target)
6879 if (m_spellInfo->Id == 1044)
6880 mask |= (1ULL << MECHANIC_SAPPED) | (1ULL << MECHANIC_FEAR);
6882 for (Unit::AuraEffectList::const_iterator i = stunAuras.begin(); i != stunAuras.end(); ++i)
6883 {
6884 if ((*i)->GetSpellInfo()->GetAllEffectsMechanicMask() && !((*i)->GetSpellInfo()->GetAllEffectsMechanicMask() & mask))
6885 {
6886 foundNotStun = true;
6887 break;
6888 }
6889 }
6890 if (foundNotStun)
6891 prevented_reason = SPELL_FAILED_STUNNED;
6892 }
6893 else
6894 prevented_reason = SPELL_FAILED_STUNNED;
6895 }
6897 prevented_reason = SPELL_FAILED_CONFUSED;
6899 prevented_reason = SPELL_FAILED_FLEEING;
6900 }
6901
6902 // Xinef: if there is no prevented_reason, check prevention types
6903 if (prevented_reason == SPELL_CAST_OK)
6904 {
6906 prevented_reason = SPELL_FAILED_SILENCED;
6908 prevented_reason = SPELL_FAILED_PACIFIED;
6909 }
6910
6911 // Attr must make flag drop spell totally immune from all effects
6912 if (prevented_reason != SPELL_CAST_OK)
6913 {
6914 if (school_immune || mechanic_immune || dispel_immune)
6915 {
6916 //Checking auras is needed now, because you are prevented by some state but the spell grants immunity.
6918 for (Unit::AuraApplicationMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
6919 {
6920 Aura const* aura = itr->second->GetBase();
6921 SpellInfo const* auraInfo = aura->GetSpellInfo();
6922 if (auraInfo->GetAllEffectsMechanicMask() & mechanic_immune)
6923 continue;
6924 if (auraInfo->GetSchoolMask() & school_immune && !auraInfo->HasAttribute(SPELL_ATTR1_IMMUNITY_TO_HOSTILE_AND_FRIENDLY_EFFECTS))
6925 continue;
6926 if (auraInfo->GetDispelMask() & dispel_immune)
6927 continue;
6928
6929 //Make a second check for spell failed so the right SPELL_FAILED message is returned.
6930 //That is needed when your casting is prevented by multiple states and you are only immune to some of them.
6931 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
6932 {
6933 if (AuraEffect* part = aura->GetEffect(i))
6934 {
6935 switch (part->GetAuraType())
6936 {
6938 {
6939 uint64 mask = 1ULL << MECHANIC_STUN;
6940 // Barkskin should skip sleep effects, sap and fears
6941 if (m_spellInfo->Id == 22812)
6942 mask |= 1ULL << MECHANIC_SAPPED | 1ULL << MECHANIC_HORROR | 1ULL << MECHANIC_SLEEP;
6943 // Hand of Freedom, can be used while sapped and while under fear-mechanic stuns (e.g. Intimidating Shout primary target)
6944 if (m_spellInfo->Id == 1044)
6945 mask |= (1ULL << MECHANIC_SAPPED) | (1ULL << MECHANIC_FEAR);
6946
6947 if (!usableInStun || !(auraInfo->GetAllEffectsMechanicMask() & mask))
6948 return SPELL_FAILED_STUNNED;
6949 break;
6950 }
6953 return SPELL_FAILED_CONFUSED;
6954 break;
6957 return SPELL_FAILED_FLEEING;
6958 break;
6963 return SPELL_FAILED_PACIFIED;
6965 return SPELL_FAILED_SILENCED;
6966 break;
6967 default:
6968 break;
6969 }
6970 }
6971 }
6972 }
6973 }
6974 // You are prevented from casting and the spell casted does not grant immunity. Return a failed error.
6975 else
6976 return prevented_reason;
6977 }
6978 return SPELL_CAST_OK;
6979}
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:405

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

Referenced by SelectEffectImplicitTargets(), and SelectImplicitDestDestTargets().

◆ CheckEffectExecuteData()

void Spell::CheckEffectExecuteData ( )
protected
8529{
8530 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
8532}
#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
7943{
7944 switch (m_spellInfo->Effects[eff].ApplyAuraName)
7945 {
7950 if (target->IsCreature() && target->IsVehicle())
7951 return false;
7952 if (target->IsMounted() && m_spellInfo->Effects[eff].ApplyAuraName != SPELL_AURA_MOD_POSSESS)
7953 return false;
7954 if (target->GetCharmerGUID())
7955 return false;
7956 if (int32 damage = CalculateSpellDamage(eff, target))
7957 if ((int32)target->GetLevel() > damage)
7958 return false;
7959 break;
7960 default:
7961 break;
7962 }
7963
7964 // xinef: skip los checking if spell has appropriate attribute, or target requires specific entry
7965 // 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
7966 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)))
7967 return true;
7968
7969 // if spell is triggered, need to check for LOS disable on the aura triggering it and inherit that behaviour
7972 {
7973 return true;
7974 }
7975
7977 //Check targets for LOS visibility (except spells without range limitations)
7978 switch (m_spellInfo->Effects[eff].Effect)
7979 {
7981 // player far away, maybe his corpse near?
7982 if (target != m_caster && !target->IsWithinLOSInMap(m_caster))
7983 {
7985 return false;
7986
7988 if (!corpse)
7989 return false;
7990
7991 if (target->GetGUID() != corpse->GetOwnerGUID())
7992 return false;
7993
7995 return false;
7996 }
7997 break;
7999 {
8001 {
8002 if (target->IsWithinLOSInMap(m_caster, VMAP::ModelIgnoreFlags::M2) && target->HasUnitFlag(UNIT_FLAG_SKINNABLE))
8003 return true;
8004
8005 return false;
8006 }
8007
8009 if (!corpse)
8010 return false;
8011
8012 if (target->GetGUID() != corpse->GetOwnerGUID())
8013 return false;
8014
8016 return false;
8017
8019 return false;
8020 }
8021 break;
8023 if (!m_caster->IsPlayer() || !target->IsPlayer())
8024 return false;
8025 if (m_caster->ToPlayer()->GetSession()->IsARecruiter() && target->ToPlayer()->GetSession()->GetRecruiterId() != m_caster->ToPlayer()->GetSession()->GetAccountId())
8026 return false;
8027 if (m_caster->ToPlayer()->GetSession()->GetRecruiterId() != target->ToPlayer()->GetSession()->GetAccountId() && target->ToPlayer()->GetSession()->IsARecruiter())
8028 return false;
8029 if (target->ToPlayer()->GetLevel() >= sWorld->getIntConfig(CONFIG_MAX_RECRUIT_A_FRIEND_BONUS_PLAYER_LEVEL))
8030 return false;
8031 break;
8032 default: // normal case
8033 {
8034 uint32 losChecks = LINEOFSIGHT_ALL_CHECKS;
8035 GameObject* gobCaster = nullptr;
8037 {
8039 }
8040 else if (m_caster->GetEntry() == WORLD_TRIGGER)
8041 {
8042 if (TempSummon* tempSummon = m_caster->ToTempSummon())
8043 {
8044 gobCaster = tempSummon->GetSummonerGameObject();
8045 }
8046 }
8047
8048 if (gobCaster)
8049 {
8050 if (gobCaster->GetGOInfo()->IsIgnoringLOSChecks())
8051 {
8052 return true;
8053 }
8054
8055 // If spell casted by gameobject then ignore M2 models
8056 losChecks &= ~LINEOFSIGHT_CHECK_GOBJECT_M2;
8057 }
8058
8059 if (target != m_caster)
8060 {
8061 if (m_targets.HasDst())
8062 {
8063 float x = m_targets.GetDstPos()->GetPositionX();
8064 float y = m_targets.GetDstPos()->GetPositionY();
8065 float z = m_targets.GetDstPos()->GetPositionZ();
8066
8067 if (!target->IsWithinLOS(x, y, z, VMAP::ModelIgnoreFlags::M2, LineOfSightChecks(losChecks)))
8068 {
8069 return false;
8070 }
8071 }
8073 {
8074 return false;
8075 }
8076 }
8077 break;
8078 }
8079 }
8080
8081 return true;
8082}
@ 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:200
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:280
bool IsARecruiter() const
Definition WorldSession.h:618
#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.
7162{
7163 Player* player = m_caster->ToPlayer();
7164 if (!player)
7165 {
7166 // Non-player case: Check if creature is disarmed
7168 {
7170 }
7171
7172 return SPELL_CAST_OK;
7173 }
7174
7175 if (!m_CastItem)
7176 {
7177 if (m_castItemGUID)
7179 }
7180 else
7181 {
7182 uint32 itemid = m_CastItem->GetEntry();
7183 if (!player->HasItemCount(itemid))
7185
7186 ItemTemplate const* proto = m_CastItem->GetTemplate();
7187 if (!proto)
7189
7190 for (int i = 0; i < MAX_ITEM_SPELLS; ++i)
7191 if (proto->Spells[i].SpellCharges)
7192 if (m_CastItem->GetSpellCharges(i) == 0)
7194
7195 // consumable cast item checks
7197 {
7198 // such items should only fail if there is no suitable effect at all - see Rejuvenation Potions for example
7199 SpellCastResult failReason = SPELL_CAST_OK;
7200 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; i++)
7201 {
7202 // skip check, pet not required like checks, and for TARGET_UNIT_PET m_targets.GetUnitTarget() is not the real target but the caster
7203 if (m_spellInfo->Effects[i].TargetA.GetTarget() == TARGET_UNIT_PET)
7204 continue;
7205
7206 if (m_spellInfo->Effects[i].Effect == SPELL_EFFECT_HEAL)
7207 {
7209 {
7211 continue;
7212 }
7213 else
7214 {
7215 failReason = SPELL_CAST_OK;
7216 break;
7217 }
7218 }
7219
7220 // Mana Potion, Rage Potion, Thistle Tea(Rogue), ...
7221 if (m_spellInfo->Effects[i].Effect == SPELL_EFFECT_ENERGIZE)
7222 {
7223 if (m_spellInfo->Effects[i].MiscValue < 0 || m_spellInfo->Effects[i].MiscValue >= int8(MAX_POWERS))
7224 {
7226 continue;
7227 }
7228
7229 Powers power = Powers(m_spellInfo->Effects[i].MiscValue);
7231 {
7233 continue;
7234 }
7235 else
7236 {
7237 failReason = SPELL_CAST_OK;
7238 break;
7239 }
7240 }
7241 }
7242 if (failReason != SPELL_CAST_OK)
7243 return failReason;
7244 }
7245 }
7246
7247 // check target item
7249 {
7250 if (!m_caster->IsPlayer())
7252
7253 if (!m_targets.GetItemTarget())
7255
7258 }
7259 // if not item target then required item must be equipped
7260 else
7261 {
7262 // Xinef: this is not true in my opinion, in eg bladestorm will not be canceled after disarm
7263 //if (!HasTriggeredCastFlag(TRIGGERED_IGNORE_EQUIPPED_ITEM_REQUIREMENT))
7266 }
7267
7268 // do not take reagents for these item casts
7270 {
7272 // Not own traded item (in trader trade slot) requires reagents even if triggered spell
7273 if (!checkReagents)
7274 if (Item* targetItem = m_targets.GetItemTarget())
7275 if (targetItem->GetOwnerGUID() != m_caster->GetGUID())
7276 checkReagents = true;
7277
7278 // check reagents (ignore triggered spells with reagents processed by original spell) and special reagent ignore case.
7279 if (checkReagents)
7280 {
7281 for (uint32 i = 0; i < MAX_SPELL_REAGENTS; i++)
7282 {
7283 if (m_spellInfo->Reagent[i] <= 0)
7284 continue;
7285
7286 uint32 itemid = m_spellInfo->Reagent[i];
7287 uint32 itemcount = m_spellInfo->ReagentCount[i];
7288
7289 // if CastItem is also spell reagent
7290 if (m_CastItem && m_CastItem->GetEntry() == itemid)
7291 {
7292 ItemTemplate const* proto = m_CastItem->GetTemplate();
7293 if (!proto)
7295 for (int s = 0; s < MAX_ITEM_PROTO_SPELLS; ++s)
7296 {
7297 // CastItem will be used up and does not count as reagent
7298 int32 charges = m_CastItem->GetSpellCharges(s);
7299 if (proto->Spells[s].SpellCharges < 0 && std::abs(charges) < 2)
7300 {
7301 ++itemcount;
7302 break;
7303 }
7304 }
7305 }
7306 if (!player->HasItemCount(itemid, itemcount))
7307 return SPELL_FAILED_REAGENTS;
7308 }
7309 }
7310
7311 // check totem-item requirements (items presence in inventory)
7312 uint32 totems = 2;
7313 for (int i = 0; i < 2; ++i)
7314 {
7315 if (m_spellInfo->Totem[i] != 0)
7316 {
7317 if (player->HasItemCount(m_spellInfo->Totem[i]))
7318 {
7319 totems -= 1;
7320 continue;
7321 }
7322 }
7323 else
7324 totems -= 1;
7325 }
7326 if (totems != 0)
7327 return SPELL_FAILED_TOTEMS; //0x7C
7328
7329 // Check items for TotemCategory (items presence in inventory)
7331 for (int i = 0; i < 2; ++i)
7332 {
7333 if (m_spellInfo->TotemCategory[i] != 0)
7334 {
7336 {
7337 TotemCategory -= 1;
7338 continue;
7339 }
7340 }
7341 else
7342 TotemCategory -= 1;
7343 }
7344 if (TotemCategory != 0)
7345 return SPELL_FAILED_TOTEM_CATEGORY; //0x7B
7346 }
7347
7348 // special checks for spell effects
7349 for (int i = 0; i < MAX_SPELL_EFFECTS; i++)
7350 {
7351 switch (m_spellInfo->Effects[i].Effect)
7352 {
7355 {
7356 // m_targets.GetUnitTarget() means explicit cast, otherwise we dont check for possible equip error
7357 Unit* target = m_targets.GetUnitTarget() ? m_targets.GetUnitTarget() : player;
7358 if (target->IsPlayer() && !IsTriggered())
7359 {
7360 // 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,
7361 // so we need to make sure there is at least one free space in the player's inventory
7363 if (target->ToPlayer()->GetFreeInventorySpace() == 0)
7364 {
7365 player->SendEquipError(EQUIP_ERR_INVENTORY_FULL, nullptr, nullptr, m_spellInfo->Effects[i].ItemType);
7367 }
7368
7369 if (m_spellInfo->Effects[i].ItemType)
7370 {
7371 ItemTemplate const* itemTemplate = sObjectMgr->GetItemTemplate(m_spellInfo->Effects[i].ItemType);
7372 if (!itemTemplate)
7374
7375 uint32 createCount = std::clamp<uint32>(m_spellInfo->Effects[i].CalcValue(), 1u, itemTemplate->GetMaxStackSize());
7376 ItemPosCountVec dest;
7377 InventoryResult msg = target->ToPlayer()->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, m_spellInfo->Effects[i].ItemType, createCount);
7378 if (msg != EQUIP_ERR_OK)
7379 {
7381 if (!itemTemplate->ItemLimitCategory)
7382 {
7383 player->SendEquipError(msg, nullptr, nullptr, m_spellInfo->Effects[i].ItemType);
7385 }
7386 else
7387 {
7388 // Conjure Food/Water/Refreshment spells
7391 else if (!(target->ToPlayer()->HasItemCount(m_spellInfo->Effects[i].ItemType)))
7392 {
7393 player->SendEquipError(msg, nullptr, nullptr, m_spellInfo->Effects[i].ItemType);
7395 }
7396 else
7397 player->CastSpell(player, m_spellInfo->Effects[EFFECT_1].CalcValue(), false); // move this to anywhere
7398
7400 }
7401 }
7402 }
7403 }
7404 break;
7405 }
7407 {
7408 if (player->GetFreeInventorySpace() == 0)
7409 {
7410 player->SendEquipError(EQUIP_ERR_INVENTORY_FULL, nullptr, nullptr, m_spellInfo->Effects[i].ItemType);
7412 }
7413 break;
7414 }
7416 if (m_spellInfo->Effects[i].ItemType && m_targets.GetItemTarget()
7418 {
7419 // cannot enchant vellum for other player
7422 // do not allow to enchant vellum from scroll made by vellum-prevent exploit
7425 ItemPosCountVec dest;
7426 InventoryResult msg = player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, m_spellInfo->Effects[i].ItemType, 1);
7427 if (msg != EQUIP_ERR_OK)
7428 {
7429 player->SendEquipError(msg, nullptr, nullptr, m_spellInfo->Effects[i].ItemType);
7431 }
7432 }
7433 [[fallthrough]];
7435 {
7436 Item* targetItem = m_targets.GetItemTarget();
7437 if (!targetItem)
7439
7440 // Apply item level restriction
7442 {
7443 uint32 requiredLevel = targetItem->GetTemplate()->RequiredLevel;
7444 if (!requiredLevel)
7445 requiredLevel = targetItem->GetTemplate()->ItemLevel;
7446
7447 if (requiredLevel < m_spellInfo->BaseLevel)
7448 return SPELL_FAILED_LOWLEVEL;
7449 }
7450
7451 if (m_CastItem && m_spellInfo->MaxLevel > 0 && targetItem->GetTemplate()->ItemLevel > m_spellInfo->MaxLevel)
7453
7454 bool isItemUsable = false;
7455 for (uint8 e = 0; e < MAX_ITEM_PROTO_SPELLS; ++e)
7456 {
7457 ItemTemplate const* proto = targetItem->GetTemplate();
7458 if (proto->Spells[e].SpellId && (
7461 {
7462 isItemUsable = true;
7463 break;
7464 }
7465 }
7466
7467 SpellItemEnchantmentEntry const* enchantEntry = sSpellItemEnchantmentStore.LookupEntry(m_spellInfo->Effects[i].MiscValue);
7468 // do not allow adding usable enchantments to items that have use effect already
7469 if (enchantEntry)
7470 {
7471 for (uint8 s = 0; s < MAX_SPELL_ITEM_ENCHANTMENT_EFFECTS; ++s)
7472 {
7473 switch (enchantEntry->type[s])
7474 {
7476 if (isItemUsable)
7478 break;
7480 {
7481 uint32 numSockets = 0;
7482 for (uint32 socket = 0; socket < MAX_ITEM_PROTO_SOCKETS; ++socket)
7483 if (targetItem->GetTemplate()->Socket[socket].Color)
7484 ++numSockets;
7485
7486 if (numSockets == MAX_ITEM_PROTO_SOCKETS || targetItem->GetEnchantmentId(PRISMATIC_ENCHANTMENT_SLOT))
7488 break;
7489 }
7490 }
7491 }
7492 }
7493
7494 // Not allow enchant in trade slot for some enchant type
7495 if (targetItem->GetOwner() != m_caster)
7496 {
7497 if (!enchantEntry)
7498 return SPELL_FAILED_ERROR;
7499 if (enchantEntry->slot & ENCHANTMENT_CAN_SOULBOUND)
7501 }
7502 break;
7503 }
7505 {
7506 Item* item = m_targets.GetItemTarget();
7507 if (!item)
7509 // Not allow enchant in trade slot for some enchant type
7510 if (item->GetOwner() != m_caster)
7511 {
7512 uint32 enchant_id = m_spellInfo->Effects[i].MiscValue;
7513 SpellItemEnchantmentEntry const* pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id);
7514 if (!pEnchant)
7515 return SPELL_FAILED_ERROR;
7516 if (pEnchant->slot & ENCHANTMENT_CAN_SOULBOUND)
7518 }
7519
7520 // Apply item level restriction
7522 {
7523 uint32 requiredLevel = item->GetTemplate()->RequiredLevel;
7524 if (!requiredLevel)
7525 requiredLevel = item->GetTemplate()->ItemLevel;
7526
7527 if (requiredLevel < m_spellInfo->BaseLevel)
7528 return SPELL_FAILED_LOWLEVEL;
7529 }
7530
7533
7534 break;
7535 }
7537 // check item existence in effect code (not output errors at offhand hold item effect to main hand for example
7538 break;
7540 {
7541 if (!m_targets.GetItemTarget())
7543
7544 // prevent disenchanting in trade slot
7547
7548 ItemTemplate const* itemProto = m_targets.GetItemTarget()->GetTemplate();
7549 if (!itemProto)
7551
7552 uint32 item_quality = itemProto->Quality;
7553 // 2.0.x addon: Check player enchanting level against the item disenchanting requirements
7554 uint32 item_disenchantskilllevel = itemProto->RequiredDisenchantSkill;
7555 if (item_disenchantskilllevel == uint32(-1))
7557 if (item_disenchantskilllevel > player->GetSkillValue(SKILL_ENCHANTING))
7559 if (item_quality > 4 || item_quality < 2)
7561 if (itemProto->Class != ITEM_CLASS_WEAPON && itemProto->Class != ITEM_CLASS_ARMOR)
7563 if (!itemProto->DisenchantID)
7565 break;
7566 }
7568 {
7569 Item* item = m_targets.GetItemTarget();
7570 if (!item)
7572 //ensure item is a prospectable ore
7575 //prevent prospecting in trade slot
7576 if (item->GetOwnerGUID() != m_caster->GetGUID())
7578 //Check for enough skill in jewelcrafting
7579 uint32 item_prospectingskilllevel = item->GetTemplate()->RequiredSkillRank;
7580 if (item_prospectingskilllevel > player->GetSkillValue(SKILL_JEWELCRAFTING))
7582 //make sure the player has the required ores in inventory
7583 if (item->GetCount() < 5)
7584 {
7585 if (param1 && param2)
7586 {
7587 *param1 = item->GetEntry();
7588 *param2 = 5;
7589 }
7591 }
7592
7595
7596 break;
7597 }
7599 {
7600 Item* item = m_targets.GetItemTarget();
7601 if (!item)
7603 //ensure item is a millable herb
7604 if (!(item->GetTemplate()->HasFlag(ITEM_FLAG_IS_MILLABLE)))
7606 //prevent milling in trade slot
7607 if (item->GetOwnerGUID() != m_caster->GetGUID())
7609 //Check for enough skill in inscription
7610 uint32 item_millingskilllevel = item->GetTemplate()->RequiredSkillRank;
7611 if (item_millingskilllevel > player->GetSkillValue(SKILL_INSCRIPTION))
7613 //make sure the player has the required herbs in inventory
7614 if (item->GetCount() < 5)
7615 {
7616 if (param1 && param2)
7617 {
7618 *param1 = item->GetEntry();
7619 *param2 = 5;
7620 }
7622 }
7623
7626
7627 break;
7628 }
7631 {
7632 if (!m_caster->IsPlayer())
7634
7636 break;
7637
7639 if (!pItem || pItem->IsBroken())
7641
7642 switch (pItem->GetTemplate()->SubClass)
7643 {
7645 {
7646 uint32 ammo = pItem->GetEntry();
7647 if (!m_caster->ToPlayer()->HasItemCount(ammo))
7648 return SPELL_FAILED_NO_AMMO;
7649 };
7650 break;
7654 {
7656 if (!ammo)
7657 {
7658 // Requires No Ammo
7659 if (m_caster->HasAura(46699))
7660 break; // skip other checks
7661
7662 return SPELL_FAILED_NO_AMMO;
7663 }
7664
7665 ItemTemplate const* ammoProto = sObjectMgr->GetItemTemplate(ammo);
7666 if (!ammoProto)
7667 return SPELL_FAILED_NO_AMMO;
7668
7669 if (ammoProto->Class != ITEM_CLASS_PROJECTILE)
7670 return SPELL_FAILED_NO_AMMO;
7671
7672 // check ammo ws. weapon compatibility
7673 switch (pItem->GetTemplate()->SubClass)
7674 {
7677 if (ammoProto->SubClass != ITEM_SUBCLASS_ARROW)
7678 return SPELL_FAILED_NO_AMMO;
7679 break;
7681 if (ammoProto->SubClass != ITEM_SUBCLASS_BULLET)
7682 return SPELL_FAILED_NO_AMMO;
7683 break;
7684 default:
7685 return SPELL_FAILED_NO_AMMO;
7686 }
7687
7688 if (!m_caster->ToPlayer()->HasItemCount(ammo))
7689 {
7691 return SPELL_FAILED_NO_AMMO;
7692 }
7693 };
7694 break;
7696 break;
7697 default:
7698 break;
7699 }
7700 break;
7701 }
7703 {
7704 uint32 item_id = m_spellInfo->Effects[i].ItemType;
7705 ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(item_id);
7706
7707 if (!pProto)
7709
7710 if (Item* pitem = player->GetItemByEntry(item_id))
7711 {
7712 for (int x = 0; x < MAX_ITEM_PROTO_SPELLS; ++x)
7713 if (pProto->Spells[x].SpellCharges != 0 && pitem->GetSpellCharges(x) == pProto->Spells[x].SpellCharges)
7715 }
7716 break;
7717 }
7718 default:
7719 break;
7720 }
7721 }
7722
7723 // check weapon presence in slots for main/offhand weapons
7724 if (/*never skip those checks !HasTriggeredCastFlag(TRIGGERED_IGNORE_EQUIPPED_ITEM_REQUIREMENT) &&*/ m_spellInfo->EquippedItemClass >= 0)
7725 {
7726 // main hand weapon required
7728 {
7730
7731 // skip spell if no weapon in slot or broken
7732 if (!item || item->IsBroken())
7734
7735 // skip spell if weapon not fit to triggered spell
7738 }
7739
7740 // offhand hand weapon required
7742 {
7744
7745 // skip spell if no weapon in slot or broken
7746 if (!item || item->IsBroken())
7748
7749 // skip spell if weapon not fit to triggered spell
7752 }
7753
7755 }
7756
7757 return SPELL_CAST_OK;
7758}
@ 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:12523
uint32 GetFreeInventorySpace() const
Definition PlayerStorage.cpp:469
Item * GetItemByEntry(uint32 entry) const
Definition PlayerStorage.cpp:3431
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:12598
void SendEquipError(InventoryResult msg, Item *pItem, Item *pItem2=nullptr, uint32 itemid=0)
Definition PlayerStorage.cpp:4089
InventoryResult CanStoreNewItem(uint8 bag, uint8 slot, ItemPosCountVec &dest, uint32 item, uint32 count, uint32 *no_space_count=nullptr) const
Definition Player.h:1298
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:17358
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)
6789{
6790 if (m_caster->HasUnitState(UNIT_STATE_CASTING) && !HasTriggeredCastFlag(TRIGGERED_IGNORE_CAST_IN_PROGRESS)) //prevent spellcast interruption by another spellcast
6792
6793 // dead owner (pets still alive when owners ressed?)
6794 if (Unit* owner = m_caster->GetCharmerOrOwner())
6795 if (!owner->IsAlive() && m_caster->GetEntry() != 30230) // Rise Ally
6797
6798 if (!target && m_targets.GetUnitTarget())
6799 target = m_targets.GetUnitTarget();
6800
6802 {
6803 if (!target)
6805 m_targets.SetUnitTarget(target);
6806 }
6807
6808 // xinef: Calculate power cost here, so funciton checking power can work properly and dont return bad results
6810
6811 // cooldown
6812 if (Creature const* creatureCaster = m_caster->ToCreature())
6813 if (creatureCaster->HasSpellCooldown(m_spellInfo->Id))
6815
6816 // Check if spell is affected by GCD
6820
6821 return CheckCast(true);
6822}
bool HasGlobalCooldown(SpellInfo const *spellInfo) const
Definition CharmInfo.cpp:397
void SetUnitTarget(Unit *target)
Definition Spell.cpp:238
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 ( )
7117{
7118 // item cast not used power
7119 if (m_CastItem)
7120 return SPELL_CAST_OK;
7121
7122 //While .cheat power is enabled dont check if we need power to cast the spell
7123 if (m_caster->IsPlayer())
7124 {
7126 {
7127 return SPELL_CAST_OK;
7128 }
7129 }
7130
7131 // health as power used - need check health amount
7133 {
7136 return SPELL_CAST_OK;
7137 }
7138 // Check valid power type
7140 {
7141 LOG_ERROR("spells", "Spell::CheckPower: Unknown power type '{}'", m_spellInfo->PowerType);
7142 return SPELL_FAILED_UNKNOWN;
7143 }
7144
7145 //check rune cost only if a spell has PowerType == POWER_RUNE
7147 {
7149 if (failReason != SPELL_CAST_OK)
7150 return failReason;
7151 }
7152
7153 // Check power amount
7156 return SPELL_FAILED_NO_POWER;
7157 else
7158 return SPELL_CAST_OK;
7159}
@ 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:5359
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)
7031{
7032 // Don't check for instant cast spells
7033 if (!strict && m_casttime == 0)
7034 return SPELL_CAST_OK;
7035
7036 uint32 range_type = 0;
7037
7039 {
7040 // check needed by 68766 51693 - both spells are cast on enemies and have 0 max range
7041 // these are triggered by other spells - possibly we should omit range check in that case?
7042 if (m_spellInfo->RangeEntry->ID == 1)
7043 return SPELL_CAST_OK;
7044
7045 range_type = m_spellInfo->RangeEntry->Flags;
7046 }
7047
7048 Unit* target = m_targets.GetUnitTarget();
7049 float max_range = m_caster->GetSpellMaxRangeForTarget(target, m_spellInfo);
7050 float min_range = m_caster->GetSpellMinRangeForTarget(target, m_spellInfo);
7051
7052 // xinef: hack for npc shooters
7053 if (min_range && GetCaster()->IsCreature() && !GetCaster()->GetOwnerGUID().IsPlayer() && min_range <= 6.0f)
7054 range_type = SPELL_RANGE_RANGED;
7055
7056 if (Player* modOwner = m_caster->GetSpellModOwner())
7057 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_RANGE, max_range, this);
7058
7059 // xinef: dont check max_range to strictly after cast
7060 if (range_type != SPELL_RANGE_MELEE && !strict)
7061 max_range += std::min(3.0f, max_range * 0.1f); // 10% but no more than 3yd
7062
7063 if (target)
7064 {
7065 if (target != m_caster)
7066 {
7067 // Xinef: Spells with 5yd range can hit target 9yd away?
7068 if (range_type == SPELL_RANGE_MELEE)
7069 {
7070 float real_max_range = max_range;
7072 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)
7073 else
7074 real_max_range -= 2 * MIN_MELEE_REACH;
7075
7076 if (!m_caster->IsWithinMeleeRange(target, std::max(real_max_range, 0.0f)))
7078 }
7079 else if (!m_caster->IsWithinCombatRange(target, max_range))
7080 return SPELL_FAILED_OUT_OF_RANGE; //0x5A;
7081
7082 if (m_caster->IsPlayer() && (m_spellInfo->FacingCasterFlags & SPELL_FACING_FLAG_INFRONT) && !m_caster->HasInArc(static_cast<float>(M_PI), target) && !m_caster->IsWithinBoundaryRadius(target))
7084 }
7085
7086 // Check min range - for ranged spells, min range is the spell's min range + melee range (no leeway)
7087 if (range_type == SPELL_RANGE_RANGED)
7088 {
7089 float minRangeCombined = min_range + m_caster->GetMeleeRange(target);
7090 if (m_caster->IsWithinRange(target, minRangeCombined))
7092 }
7093 else if (min_range > 0 && m_caster->IsWithinCombatRange(target, min_range))
7095 }
7096
7097 if (GameObject* goTarget = m_targets.GetGOTarget())
7098 {
7099 if (!goTarget->IsAtInteractDistance(m_caster->ToPlayer(), m_spellInfo))
7100 {
7102 }
7103 }
7104
7105 if (m_targets.HasDst() && !m_targets.HasTraj())
7106 {
7107 if (!m_caster->IsWithinDist3d(m_targets.GetDstPos(), max_range))
7109 if (min_range && m_caster->IsWithinDist3d(m_targets.GetDstPos(), min_range))
7111 }
7112
7113 return SPELL_CAST_OK;
7114}
#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:11900
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:11880
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:1730
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)
5360{
5361 if (m_spellInfo->PowerType != POWER_RUNE || !RuneCostID)
5362 return SPELL_CAST_OK;
5363
5364 if (!m_caster->IsPlayer())
5365 return SPELL_CAST_OK;
5366
5367 Player* player = m_caster->ToPlayer();
5368 //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)
5369 if (player->GetCommandStatus(CHEAT_POWER))
5370 {
5371 return SPELL_CAST_OK;
5372 }
5373
5375 return SPELL_CAST_OK;
5376
5377 SpellRuneCostEntry const* src = sSpellRuneCostStore.LookupEntry(RuneCostID);
5378
5379 if (!src)
5380 return SPELL_CAST_OK;
5381
5382 if (src->NoRuneCost())
5383 return SPELL_CAST_OK;
5384
5385 int32 runeCost[NUM_RUNE_TYPES]; // blood, frost, unholy, death
5386
5387 for (uint32 i = 0; i < RUNE_DEATH; ++i)
5388 {
5389 runeCost[i] = src->RuneCost[i];
5390 if (Player* modOwner = m_caster->GetSpellModOwner())
5391 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_COST, runeCost[i], this);
5392 }
5393
5394 runeCost[RUNE_DEATH] = MAX_RUNES; // calculated later
5395
5396 for (uint32 i = 0; i < MAX_RUNES; ++i)
5397 {
5398 RuneType rune = player->GetCurrentRune(i);
5399 if ((player->GetRuneCooldown(i) == 0) && (runeCost[rune] > 0))
5400 runeCost[rune]--;
5401 }
5402
5403 for (uint32 i = 0; i < RUNE_DEATH; ++i)
5404 if (runeCost[i] > 0)
5405 runeCost[RUNE_DEATH] += runeCost[i];
5406
5407 if (runeCost[RUNE_DEATH] > MAX_RUNES)
5408 return SPELL_FAILED_NO_POWER; // not sure if result code is correct
5409
5410 return SPELL_CAST_OK;
5411}
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:2545
bool IsClass(Classes playerClass, ClassContext context=CLASS_CONTEXT_NONE) const override
Definition Player.cpp:1302
RuneType GetCurrentRune(uint8 index) const
Definition Player.h:2544
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
8750{
8751 // Skip if there are not any script
8752 if (!m_loadedScripts.size())
8753 return true;
8754
8755 for (std::list<SpellScript*>::iterator itr = m_loadedScripts.begin(); itr != m_loadedScripts.end(); ++itr)
8756 {
8757 std::list<SpellScript::ObjectTargetSelectHandler>::iterator targetSelectHookEnd = (*itr)->OnObjectTargetSelect.end(), targetSelectHookItr = (*itr)->OnObjectTargetSelect.begin();
8758 for (; targetSelectHookItr != targetSelectHookEnd; ++targetSelectHookItr)
8759 if (((*targetSelectHookItr).IsEffectAffected(m_spellInfo, effIndex) && !(*targetSelectHookItr).IsEffectAffected(m_spellInfo, effIndexToCheck)) ||
8760 (!(*targetSelectHookItr).IsEffectAffected(m_spellInfo, effIndex) && (*targetSelectHookItr).IsEffectAffected(m_spellInfo, effIndexToCheck)))
8761 return false;
8762
8763 std::list<SpellScript::ObjectAreaTargetSelectHandler>::iterator areaTargetSelectHookEnd = (*itr)->OnObjectAreaTargetSelect.end(), areaTargetSelectHookItr = (*itr)->OnObjectAreaTargetSelect.begin();
8764 for (; areaTargetSelectHookItr != areaTargetSelectHookEnd; ++areaTargetSelectHookItr)
8765 if (((*areaTargetSelectHookItr).IsEffectAffected(m_spellInfo, effIndex) && !(*areaTargetSelectHookItr).IsEffectAffected(m_spellInfo, effIndexToCheck)) ||
8766 (!(*areaTargetSelectHookItr).IsEffectAffected(m_spellInfo, effIndex) && (*areaTargetSelectHookItr).IsEffectAffected(m_spellInfo, effIndexToCheck)))
8767 return false;
8768 }
8769 return true;
8770}

References m_loadedScripts, and m_spellInfo.

Referenced by SelectEffectImplicitTargets().

◆ CheckSpellFocus()

SpellCastResult Spell::CheckSpellFocus ( )
7761{
7762 // check spell focus object
7764 {
7766 Cell cell(p);
7767
7768 GameObject* ok = nullptr;
7771
7773 Map& map = *m_caster->GetMap();
7774 cell.Visit(p, object_checker, map, *m_caster, m_caster->GetVisibilityRange());
7775
7776 if (!ok)
7778
7779 focusObject = ok; // game object found in range
7780 }
7781 return SPELL_CAST_OK;
7782}
@ SPELL_FAILED_REQUIRES_SPELL_FOCUS
Definition SharedDefines.h:1039
Definition GridNotifiers.h:648
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:310
Definition Cell.h:45

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

Referenced by CheckCast().

◆ CheckSrc()

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

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

◆ CleanupTargetList()

void Spell::CleanupTargetList ( )
2285{
2286 m_UniqueTargetInfo.clear();
2287 m_UniqueGOTargetInfo.clear();
2288 m_UniqueItemInfo.clear();
2289 m_delayMoment = 0;
2291}
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 ( )
7785{
7786 if (!m_caster)// || !m_caster->IsPlayer())
7787 return;
7788
7789 //if (m_spellState == SPELL_STATE_DELAYED)
7790 // return; // spell is active and can't be time-backed
7791
7792 if (isDelayableNoMore()) // Spells may only be delayed twice
7793 return;
7794
7796 return;
7797
7798 // spells not loosing casting time (slam, dynamites, bombs..)
7799 //if (!(m_spellInfo->InterruptFlags & SPELL_INTERRUPT_FLAG_DAMAGE))
7800 // return;
7801
7802 //check pushback reduce
7803 int32 delaytime = 500; // spellcasting delay is normally 500ms
7804 int32 delayReduce = 100; // must be initialized to 100 for percent modifiers
7807 if (delayReduce >= 100)
7808 return;
7809
7810 AddPct(delaytime, -delayReduce);
7811
7812 if (m_timer + delaytime > m_casttime)
7813 {
7814 delaytime = m_casttime - m_timer;
7816 }
7817 else
7818 m_timer += delaytime;
7819
7820 LOG_DEBUG("spells", "Spell {} partially interrupted for ({}) ms at damage", m_spellInfo->Id, delaytime);
7821
7822 WorldPacket data(SMSG_SPELL_DELAYED, 8 + 4);
7823 data << m_caster->GetPackGUID();
7824 data << uint32(delaytime);
7825
7826 m_caster->SendMessageToSet(&data, true);
7827}
#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:9774
bool isDelayableNoMore()
Definition Spell.h:649
int32 GetTotalAuraModifier(AuraType auratype) const
Definition Unit.cpp:6285
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 ( )
7830{
7832 return;
7833
7834 if (isDelayableNoMore()) // Spells may only be delayed twice
7835 return;
7836
7838 return;
7839
7840 //check pushback reduce
7841 // should be affected by modifiers, not take the dbc duration.
7842 int32 duration = ((m_channeledDuration > 0) ? m_channeledDuration : m_spellInfo->GetDuration());
7843
7844 int32 delaytime = CalculatePct(duration, 25); // channeling delay is normally 25% of its time per hit
7845 int32 delayReduce = 100; // must be initialized to 100 for percent modifiers
7848 if (delayReduce >= 100)
7849 return;
7850
7851 AddPct(delaytime, -delayReduce);
7852
7853 if (m_timer <= delaytime)
7854 {
7855 delaytime = m_timer;
7856 m_timer = 0;
7857 }
7858 else
7859 m_timer -= delaytime;
7860
7861 LOG_DEBUG("spells.aura", "Spell {} partially interrupted for {} ms, new duration: {} ms", m_spellInfo->Id, delaytime, m_timer);
7862
7863 for (std::list<TargetInfo>::const_iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
7864 if ((*ihit).missCondition == SPELL_MISS_NONE)
7865 if (Unit* unit = (m_caster->GetGUID() == ihit->targetGUID) ? m_caster : ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID))
7866 unit->DelayOwnedAuras(m_spellInfo->Id, m_originalCasterGUID, delaytime);
7867
7868 // partially interrupt persistent area auras
7870 dynObj->Delay(delaytime);
7871
7873}
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:6514

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
8325{
8326 Unit* unit = nullptr;
8327 // In case spell hit target, do all effect on that target
8328 if (targetInfo.missCondition == SPELL_MISS_NONE)
8329 unit = m_caster->GetGUID() == targetInfo.targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, targetInfo.targetGUID);
8330 // In case spell reflect from target, do all effect on caster (if hit)
8331 else if (targetInfo.missCondition == SPELL_MISS_REFLECT && targetInfo.reflectResult == SPELL_MISS_NONE)
8332 unit = m_caster;
8333 if (!unit)
8334 return;
8335
8336 for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i)
8337 {
8338 if (targetInfo.effectMask & (1 << i))
8339 {
8340 m_damage = 0;
8341 m_healing = 0;
8343
8344 HandleEffects(unit, nullptr, nullptr, i, SPELL_EFFECT_HANDLE_LAUNCH_TARGET);
8345
8346 if (m_damage > 0)
8347 {
8348 // Xinef: Area Auras, AoE Targetting spells AND Chain Target spells (cleave etc.)
8349 if (m_spellInfo->Effects[i].IsAreaAuraEffect() || m_spellInfo->Effects[i].IsTargetingArea() || (m_spellInfo->Effects[i].ChainTarget > 1 && m_spellInfo->DmgClass != SPELL_DAMAGE_CLASS_MAGIC))
8350 {
8353 if (m_caster->IsPlayer())
8354 {
8355 uint32 targetAmount = m_UniqueTargetInfo.size();
8356 if (targetAmount > 10)
8357 m_damage = m_damage * 10 / targetAmount;
8358 }
8359 }
8360 }
8361
8362 if (m_applyMultiplierMask & (1 << i))
8363 {
8365 m_damageMultipliers[i] *= multiplier[i];
8366 }
8367 targetInfo.damage += m_damage;
8369 }
8370 }
8371
8372 // xinef: totem's inherit owner crit chance and dancing rune weapon
8373 Unit* caster = m_caster;
8374 if (m_caster->IsTotem() || m_caster->GetEntry() == 27893)
8375 {
8376 if (Unit* owner = m_caster->GetOwner())
8377 caster = owner;
8378 }
8379 else if (m_originalCaster)
8380 caster = m_originalCaster;
8381
8382 float critChance = caster->SpellDoneCritChance(unit, m_spellInfo, m_spellSchoolMask, m_attackType, false);
8383 critChance = unit->SpellTakenCritChance(caster, m_spellInfo, m_spellSchoolMask, critChance, m_attackType, false);
8384 targetInfo.crit = roll_chance_f(std::max(0.0f, critChance));
8385}
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:9166
float SpellDoneCritChance(Unit const *, SpellInfo const *spellProto, SpellSchoolMask schoolMask, WeaponAttackType attackType, bool skipEffectCheck) const
Definition Unit.cpp:9076
int32 CalculateAOEDamageReduction(int32 damage, uint32 schoolMask, bool npcCaster) const
Definition Unit.cpp:16319

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
3270{
3271 if (target->processed) // Check target
3272 return;
3273 target->processed = true; // Target checked in apply effects procedure
3274
3275 uint32 effectMask = target->effectMask;
3276 if (!effectMask)
3277 return;
3278
3279 GameObject* go = m_caster->GetMap()->GetGameObject(target->targetGUID);
3280 if (!go)
3281 return;
3282
3285
3286 for (uint32 effectNumber = 0; effectNumber < MAX_SPELL_EFFECTS; ++effectNumber)
3287 if (effectMask & (1 << effectNumber))
3288 HandleEffects(nullptr, nullptr, go, effectNumber, SPELL_EFFECT_HANDLE_HIT_TARGET);
3289
3290 // xinef: inform ai about spellhit
3292
3294
3296}
virtual void SpellHit(Unit *, SpellInfo const *)
Definition GameObjectAI.h:66
GameObjectAI * AI() const
Definition GameObject.h:307
void CallScriptBeforeHitHandlers(SpellMissInfo missInfo)
Definition Spell.cpp:8668
void CallScriptOnHitHandlers()
Definition Spell.cpp:8681
void CallScriptAfterHitHandlers()
Definition Spell.cpp:8694

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
3299{
3300 uint32 effectMask = target->effectMask;
3301 if (!target->item || !effectMask)
3302 return;
3303
3306
3307 for (uint32 effectNumber = 0; effectNumber < MAX_SPELL_EFFECTS; ++effectNumber)
3308 if (effectMask & (1 << effectNumber))
3309 HandleEffects(nullptr, target->item, nullptr, effectNumber, SPELL_EFFECT_HANDLE_HIT_TARGET);
3310
3312
3314}

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
2524{
2525 if (!target || target->processed)
2526 return;
2527
2528 target->processed = true; // Target checked in apply effects procedure
2529
2530 // Get mask of effects for target
2531 uint8 mask = target->effectMask;
2532
2533 Unit* effectUnit = m_caster->GetGUID() == target->targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, target->targetGUID);
2534 if (!effectUnit && !target->targetGUID.IsPlayer()) // only players may be targeted across maps
2535 return;
2536
2537 if (!effectUnit || m_spellInfo->Id == 45927)
2538 {
2539 uint8 farMask = 0;
2540 // create far target mask
2541 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
2542 if (m_spellInfo->Effects[i].IsFarUnitTargetEffect())
2543 if ((1 << i) & mask)
2544 farMask |= (1 << i);
2545
2546 if (!farMask)
2547 return;
2548 // find unit in world
2549 // Xinef: FindUnit Access without Map check!!! Intended
2550 effectUnit = ObjectAccessor::FindPlayer(target->targetGUID);
2551 if (!effectUnit)
2552 return;
2553
2554 // do far effects on the unit
2555 // can't use default call because of threading, do stuff as fast as possible
2556 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
2557 if (farMask & (1 << i))
2558 HandleEffects(effectUnit, nullptr, nullptr, i, SPELL_EFFECT_HANDLE_HIT_TARGET);
2559 return;
2560 }
2561
2562 if (effectUnit->IsAlive() != target->alive)
2563 return;
2564
2565 // Absorb delayed projectiles launched before Sanctuary (e.g. Vanish dodging a Frostbolt in flight)
2567 (GameTime::GetGameTimeMS().count() - target->timeDelay) <= effectUnit->m_lastSanctuaryTime)
2568 return; // No missinfo in that case
2569
2570 // Absorb instant hostile spells on application within brief window after Sanctuary
2572 effectUnit->m_lastSanctuaryTime &&
2573 GameTime::GetGameTimeMS().count() <= (effectUnit->m_lastSanctuaryTime + 400))
2574 return; // No missinfo in that case
2575
2576 // Get original caster (if exist) and calculate damage/healing from him data
2578
2579 // Skip if m_originalCaster not avaiable
2580 if (!caster)
2581 return;
2582
2583 SpellMissInfo missInfo = target->missCondition;
2584
2585 // Need init unitTarget by default unit (can changed in code on reflect)
2586 // Or on missInfo != SPELL_MISS_NONE unitTarget undefined (but need in trigger subsystem)
2587 unitTarget = effectUnit;
2588
2589 // Reset damage/healing counter
2590 m_damage = target->damage;
2591 m_healing = -target->damage;
2592
2593 m_spellAura = nullptr; // Set aura to null for every target-make sure that pointer is not used for unit without aura applied
2594
2596 effectUnit->SetInCombatWith(m_originalCaster);
2597
2600
2601 //Spells with this flag cannot trigger if effect is casted on self
2603 bool reflectedSpell = missInfo == SPELL_MISS_REFLECT;
2604 Unit* reflectionSource = nullptr;
2605 Unit* spellHitTarget = nullptr;
2606
2607 if (missInfo == SPELL_MISS_NONE) // In case spell hit target, do all effect on that target
2608 spellHitTarget = unitTarget;
2609 else if (missInfo == SPELL_MISS_REFLECT) // In case spell reflect from target, do all effect on caster (if hit)
2610 {
2611 missInfo = target->reflectResult;
2612 if (missInfo == SPELL_MISS_NONE) // If reflected spell hit caster -> do all effect on him
2613 {
2614 spellHitTarget = m_caster;
2616 reflectionSource = effectUnit;
2617 if (m_caster->IsCreature())
2619 }
2620 }
2621
2622 if (spellHitTarget)
2623 {
2624 if (reflectionSource)
2625 {
2626 m_reflectionTarget = reflectionSource;
2627 m_reflectionTargetGuid = reflectionSource->GetGUID();
2628 m_reflectionTargetPosition.Relocate(reflectionSource);
2629 }
2630 else
2631 {
2632 m_reflectionTarget = nullptr;
2635 }
2636
2637 SpellMissInfo missInfo2 = DoSpellHitOnUnit(spellHitTarget, mask, target->scaleAura);
2638
2639 m_reflectionTarget = nullptr;
2642 if (missInfo2 != SPELL_MISS_NONE)
2643 {
2644 if (missInfo2 != SPELL_MISS_MISS)
2645 m_caster->SendSpellMiss(spellHitTarget, m_spellInfo->Id, missInfo2);
2646 m_damage = 0;
2647 spellHitTarget = nullptr;
2648
2649 // Xinef: if missInfo2 is MISS_EVADE, override base missinfo data
2650 if (missInfo2 == SPELL_MISS_EVADE)
2651 missInfo = SPELL_MISS_EVADE;
2652 }
2653 }
2654
2655 // Do not take combo points on dodge and miss
2656 if (missInfo != SPELL_MISS_NONE && m_needComboPoints && m_targets.GetUnitTargetGUID() == target->targetGUID)
2657 {
2658 m_needComboPoints = false;
2659 // Restore spell mods for a miss/dodge/parry Cold Blood
2661 if (m_caster->IsPlayer() && (missInfo == SPELL_MISS_MISS || missInfo == SPELL_MISS_DODGE || missInfo == SPELL_MISS_PARRY))
2662 m_caster->ToPlayer()->RestoreSpellMods(this, 14177);
2663 }
2664
2665 // Fill base trigger info
2666 uint32 procAttacker = m_procAttacker;
2667 uint32 procVictim = m_procVictim;
2668
2669 // Trigger info was not filled in spell::preparedatafortriggersystem - we do it now
2670 if (canEffectTrigger && !procAttacker && !procVictim)
2671 {
2672 bool positive = true;
2673 if (m_damage > 0)
2674 positive = false;
2675 else if (!m_healing)
2676 {
2677 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
2678 // If at least one effect negative spell is negative hit
2679 // Xinef: if missInfo is immune state check all effects to properly determine positiveness of spell
2680 if ((missInfo == SPELL_MISS_IMMUNE2 || (mask & (1 << i))) && !m_spellInfo->IsPositiveEffect(i))
2681 {
2682 positive = false;
2683 break;
2684 }
2685 }
2686 switch (m_spellInfo->DmgClass)
2687 {
2689 if (positive)
2690 {
2693 }
2694 else
2695 {
2698 }
2699 break;
2701 if (positive)
2702 {
2705 }
2706 else
2707 {
2710 }
2711 break;
2712 }
2713 }
2715
2716 // All calculated do it!
2717 // Do healing and triggers
2718 if (m_healing > 0)
2719 {
2720 bool crit = target->crit;
2721 uint32 addhealth = m_healing;
2722
2723 if (crit)
2724 addhealth = Unit::SpellCriticalHealingBonus(caster, m_spellInfo, addhealth, nullptr);
2725
2726 HealInfo healInfo(caster, unitTarget, addhealth, m_spellInfo, m_spellInfo->GetSchoolMask());
2727
2728 // Heal amount before SpellHealingBonusTaken, used by Beacon of Light
2729 if (target->damageBeforeTakenMods != 0)
2730 {
2731 uint32 healBeforeTakenMods = uint32(-target->damageBeforeTakenMods);
2732 if (crit)
2733 healBeforeTakenMods = Unit::SpellCriticalHealingBonus(caster, m_spellInfo, healBeforeTakenMods, nullptr);
2734 healInfo.SetHealBeforeTakenMods(healBeforeTakenMods);
2735 }
2736 else
2737 healInfo.SetHealBeforeTakenMods(addhealth);
2738
2739 // Set hitMask based on crit
2740 if (crit)
2741 healInfo.AddHitMask(PROC_HIT_CRITICAL);
2742 else
2743 healInfo.AddHitMask(PROC_HIT_NORMAL);
2744
2745 // Xinef: override with forced crit, only visual result
2746 if (GetSpellValue()->ForcedCritResult)
2747 {
2748 crit = true;
2749 healInfo.AddHitMask(PROC_HIT_CRITICAL);
2750 }
2751
2752 int32 gain = caster->HealBySpell(healInfo, crit);
2753 float threat = float(gain) * 0.5f;
2754 if (caster->IsClass(CLASS_PALADIN))
2755 threat *= 0.5f;
2757 m_healing = gain;
2758
2759 // Xinef: if heal actually healed something, add no overheal flag
2760 if (m_healing)
2761 healInfo.AddHitMask(PROC_EX_NO_OVERHEAL);
2762
2763 // Do triggers for unit (reflect triggers passed on hit phase for correct drop charge)
2764 if (canEffectTrigger)
2765 {
2766 uint32 hitMask = m_procEx | healInfo.GetHitMask();
2767 Unit::ProcSkillsAndAuras(caster, unitTarget, procAttacker, procVictim, hitMask, addhealth, m_attackType, m_spellInfo, m_triggeredByAuraSpell.spellInfo,
2768 m_triggeredByAuraSpell.effectIndex, this, nullptr, &healInfo);
2769 }
2770 }
2771 // Do damage and triggers
2772 else if (m_damage > 0)
2773 {
2775
2776 // Fill base damage struct (unitTarget - is real spell target)
2778
2779 // Check damage immunity
2781 {
2782 m_damage = 0;
2783
2784 // no packet found in sniffs
2785 }
2786 else
2787 {
2788 // Add bonuses and fill damageInfo struct
2789 // Dancing Rune Weapon...
2790 if (m_caster->GetEntry() == 27893)
2791 {
2792 if (Unit* owner = m_caster->GetOwner())
2793 owner->CalculateSpellDamageTaken(&damageInfo, m_damage, m_spellInfo, m_attackType, target->crit);
2794 }
2795 else
2796 caster->CalculateSpellDamageTaken(&damageInfo, m_damage, m_spellInfo, m_attackType, target->crit);
2797
2798 // xinef: override miss info after absorb / block calculations
2799 if (missInfo == SPELL_MISS_NONE && damageInfo.damage == 0)
2800 {
2801 //if (damageInfo.absorb > 0)
2802 // missInfo = SPELL_MISS_ABSORB;
2803 if (damageInfo.blocked)
2804 missInfo = SPELL_MISS_BLOCK;
2805 }
2806
2807 // Xinef: override with forced crit, only visual result
2808 if (GetSpellValue()->ForcedCritResult)
2809 {
2810 damageInfo.HitInfo |= SPELL_HIT_TYPE_CRIT;
2811 }
2812
2813 Unit::DealDamageMods(damageInfo.target, damageInfo.damage, &damageInfo.absorb);
2814
2815 // xinef: health leech handling
2817 {
2818 uint8 effIndex = EFFECT_0;
2819 for (; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
2820 if (m_spellInfo->Effects[effIndex].Effect == SPELL_EFFECT_HEALTH_LEECH)
2821 break;
2822
2823 float healMultiplier = m_spellInfo->Effects[effIndex].CalcValueMultiplier(m_originalCaster, this);
2824
2825 // get max possible damage, don't count overkill for heal
2826 uint32 healthGain = uint32(-unitTarget->GetHealthGain(-int32(damageInfo.damage)) * healMultiplier);
2827
2828 if (m_caster->IsAlive())
2829 {
2830 healthGain = m_caster->SpellHealingBonusDone(m_caster, m_spellInfo, healthGain, HEAL, effIndex);
2831 healthGain = m_caster->SpellHealingBonusTaken(m_caster, m_spellInfo, healthGain, HEAL);
2832
2833 HealInfo healInfo(m_caster, m_caster, healthGain, m_spellInfo, m_spellInfo->GetSchoolMask());
2834 m_caster->HealBySpell(healInfo);
2835 }
2836 }
2837
2838 // Send log damage message to client
2839 caster->SendSpellNonMeleeDamageLog(&damageInfo);
2840 // Xinef: send info to target about reflect
2841 if (reflectedSpell)
2842 effectUnit->SendSpellNonMeleeReflectLog(&damageInfo, effectUnit);
2843
2844 procVictim |= PROC_FLAG_TAKEN_DAMAGE;
2845
2846 caster->DealSpellDamage(&damageInfo, true, this);
2847
2848 // do procs after damage, eg healing effects
2849 // no need to check if target is alive, done in procdamageandspell
2850
2851 // Do triggers for unit (reflect triggers passed on hit phase for correct drop charge)
2852 if (canEffectTrigger)
2853 {
2854 DamageInfo dmgInfo(damageInfo, SPELL_DIRECT_DAMAGE, m_attackType, missInfo);
2855 uint32 hitMask = m_procEx | dmgInfo.GetHitMask();
2856 Unit::ProcSkillsAndAuras(caster, unitTarget, procAttacker, procVictim, hitMask, damageInfo.damage, m_attackType, m_spellInfo, m_triggeredByAuraSpell.spellInfo,
2857 m_triggeredByAuraSpell.effectIndex, this, &dmgInfo);
2858
2861 caster->ToPlayer()->CastItemCombatSpell(unitTarget, m_attackType, procVictim, dmgInfo.GetHitMask());
2862 }
2863
2864 m_damage = damageInfo.damage;
2865 }
2866 }
2867 // Passive spell hits/misses or active spells only misses (only triggers)
2868 else
2869 {
2870 // Fill base damage struct (unitTarget - is real spell target)
2872 // Do triggers for unit (reflect triggers passed on hit phase for correct drop charge)
2873 if (canEffectTrigger)
2874 {
2875 DamageInfo dmgInfo(damageInfo, NODAMAGE, m_attackType, missInfo);
2876 uint32 hitMask = m_procEx | dmgInfo.GetHitMask();
2877 Unit::ProcSkillsAndAuras(caster, unitTarget, procAttacker, procVictim, hitMask, 0, m_attackType, m_spellInfo, m_triggeredByAuraSpell.spellInfo,
2878 m_triggeredByAuraSpell.effectIndex, this, &dmgInfo);
2879
2880 // Xinef: eg. rogue poisons can proc off cheap shot, etc. so this block should be here also
2881 // Xinef: ofc count only spells that HIT the target, little hack used to fool the system
2882 if ((dmgInfo.GetHitMask() & (PROC_HIT_NORMAL | PROC_HIT_CRITICAL)) && caster->IsPlayer() && m_spellInfo->HasAttribute(SPELL_ATTR0_CANCELS_AUTO_ATTACK_COMBAT) == 0 &&
2884 caster->ToPlayer()->CastItemCombatSpell(unitTarget, m_attackType, procVictim | PROC_FLAG_TAKEN_DAMAGE, dmgInfo.GetHitMask());
2885 }
2886
2887 // Failed Pickpocket, reveal rogue
2889 {
2892 }
2893 }
2894
2895 if (m_caster)
2896 {
2898 {
2901
2902 // Spells that don't initiate combat shouldn't affect stand state (e.g. Premeditation, Storm Giant/Felreaver Passive)
2903 if (m_spellInfo->HasInitialAggro() && !effectUnit->IsStandState())
2905 }
2906 }
2907
2908 if (missInfo != SPELL_MISS_EVADE && effectUnit != m_caster && m_caster->IsFriendlyTo(effectUnit) && m_spellInfo->IsPositive() &&
2910 {
2911 m_caster->SetInCombatWith(effectUnit);
2912 }
2913
2914 // Check for SPELL_ATTR7_CAN_CAUSE_INTERRUPT
2916 caster->CastSpell(effectUnit, SPELL_INTERRUPT_NONPLAYER, true);
2917
2918 if (spellHitTarget)
2919 {
2920 //AI functions
2921 if (spellHitTarget->IsCreature())
2922 {
2923 if (spellHitTarget->ToCreature()->IsAIEnabled)
2924 spellHitTarget->ToCreature()->AI()->SpellHit(m_caster, m_spellInfo);
2925 }
2926
2928 m_caster->ToCreature()->AI()->SpellHitTarget(spellHitTarget, m_spellInfo);
2929
2930 // Needs to be called after dealing damage/healing to not remove breaking on damage auras
2931 DoTriggersOnSpellHit(spellHitTarget, mask);
2932
2933 // if target is fallged for pvp also flag caster if a player
2934 // xinef: do not flag spells with aura bind sight (no special attribute)
2935 if (effectUnit->IsPvP() && effectUnit != m_caster && effectUnit->GetOwnerGUID() != m_caster->GetGUID() &&
2937 {
2938 m_caster->ToPlayer()->UpdatePvP(true);
2939 }
2940
2942 }
2943}
@ 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)
Definition Creature.cpp:3837
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:9900
void CastItemCombatSpell(Unit *target, WeaponAttackType attType, uint32 procVictim, uint32 procEx)
Definition Player.cpp:7236
void UpdatePvP(bool state, bool _override=false)
Definition PlayerUpdates.cpp:1525
ObjectGuid GetUnitTargetGUID() const
Definition Spell.cpp:215
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:8772
SpellValue const * GetSpellValue()
Definition Spell.h:601
SpellMissInfo DoSpellHitOnUnit(Unit *unit, uint32 effectMask, bool scaleAura)
Definition Spell.cpp:2945
Position m_reflectionTargetPosition
Definition Spell.h:680
void DoTriggersOnSpellHit(Unit *unit, uint8 effMask)
Definition Spell.cpp:3202
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:2091
void DealSpellDamage(SpellNonMeleeDamage *damageInfo, bool durabilityLoss, Spell const *spell=nullptr)
Definition Unit.cpp:1651
void SetInCombatWith(Unit *enemy, bool addSecondUnitSuppressed=false)
Definition Unit.h:939
void SendSpellMiss(Unit *target, uint32 spellID, SpellMissInfo missInfo)
Definition Unit.cpp:6853
void SendSpellNonMeleeReflectLog(SpellNonMeleeDamage *log, Unit *attacker)
Definition Unit.cpp:6664
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:9539
void AtTargetAttacked(Unit *target, bool canInitialAggro)
Definition Unit.cpp:11450
int32 HealBySpell(HealInfo &healInfo, bool critical=false)
Definition Unit.cpp:8353
bool IsStandState() const
Definition Unit.cpp:13100
int32 GetHealthGain(int32 dVal)
Definition Unit.cpp:10998
bool IsImmunedToDamage(SpellSchoolMask schoolMask) const
Definition Unit.cpp:9841
static uint32 SpellCriticalHealingBonus(Unit const *caster, SpellInfo const *spellProto, uint32 damage, Unit const *victim)
Definition Unit.cpp:9414
void SendSpellNonMeleeDamageLog(SpellNonMeleeDamage *log)
Definition Unit.cpp:6696
ThreatManager & GetThreatMgr()
Definition Unit.h:951
bool IsAIEnabled
Definition Unit.h:2098
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:9659
void SetStandState(uint8 state)
Definition Unit.cpp:13115
void RemoveAurasWithInterruptFlags(uint32 flag, uint32 except=0, bool isAutoshot=false)
Definition Unit.cpp:5450
static void DealDamageMods(Unit const *victim, uint32 &damage, uint32 *absorb)
Definition Unit.cpp:997
void CalculateSpellDamageTaken(SpellNonMeleeDamage *damageInfo, int32 damage, SpellInfo const *spellInfo, WeaponAttackType attackType=BASE_ATTACK, bool crit=false)
Definition Unit.cpp:1508
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:4813
Item * StoreNewItem(ItemPosCountVec const &pos, uint32 item, bool update, int32 randomPropertyId=0, bool refund=false)
Definition PlayerStorage.cpp:2597
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
2946{
2947 if (!unit || !effectMask)
2948 return SPELL_MISS_EVADE;
2949
2950 // For delayed spells immunity may be applied between missile launch and hit - check immunity for that case
2951 if (m_spellInfo->Speed && ((m_damage > 0 && unit->IsImmunedToDamage(m_caster, m_spellInfo)) || unit->IsImmunedToSchool(this) || unit->IsImmunedToSpell(m_spellInfo, this)))
2952 {
2953 return SPELL_MISS_IMMUNE;
2954 }
2955
2956 // disable effects to which unit is immune
2957 SpellMissInfo returnVal = SPELL_MISS_IMMUNE;
2958 for (uint32 effectNumber = 0; effectNumber < MAX_SPELL_EFFECTS; ++effectNumber)
2959 {
2960 if (effectMask & (1 << effectNumber))
2961 {
2962 if (unit->IsImmunedToSpellEffect(m_spellInfo, effectNumber, m_caster))
2963 effectMask &= ~(1 << effectNumber);
2964 // Xinef: Buggs out polymorph
2965 // Xinef: And this is checked in MagicSpellHitResult, why we check resistance twice?
2966 // Xinef: And why we check every spell effect basing on rand and generic dispel info? some effects will be appliend and some wont?
2967 /*else if (m_spellInfo->Effects[effectNumber].IsAura() && !m_spellInfo->IsPositiveEffect(effectNumber))
2968 {
2969 int32 debuff_resist_chance = unit->GetMaxPositiveAuraModifierByMiscValue(SPELL_AURA_MOD_DEBUFF_RESISTANCE, int32(m_spellInfo->Dispel));
2970 debuff_resist_chance += unit->GetMaxNegativeAuraModifierByMiscValue(SPELL_AURA_MOD_DEBUFF_RESISTANCE, int32(m_spellInfo->Dispel));
2971
2972 if (debuff_resist_chance > 0)
2973 if (irand(0,10000) <= (debuff_resist_chance * 100))
2974 {
2975 effectMask &= ~(1 << effectNumber);
2976 returnVal = SPELL_MISS_RESIST;
2977 }
2978 }*/
2979 }
2980 }
2981 if (!effectMask)
2982 return returnVal;
2983
2984 if (unit->IsPlayer())
2985 {
2989 }
2990
2991 if (m_caster->IsPlayer())
2992 {
2995 }
2996
2997 if (m_caster != unit)
2998 {
2999 // Recheck UNIT_FLAG_NON_ATTACKABLE for delayed spells
3000 // Xinef: Also check evade state
3001 if (m_spellInfo->Speed > 0.0f)
3002 {
3003 if (unit->IsCreature() && unit->ToCreature()->IsInEvadeMode())
3004 return SPELL_MISS_EVADE;
3005
3007 return SPELL_MISS_EVADE;
3008 }
3009
3010 if (m_caster->_IsValidAttackTarget(unit, m_spellInfo) && /*Intervene Trigger*/ m_spellInfo->Id != 59667)
3011 {
3013 }
3014 else if (m_caster->IsFriendlyTo(unit))
3015 {
3016 // for delayed spells ignore negative spells (after duel end) for friendly targets
3018 if (!IsTriggered() && m_spellInfo->Speed > 0.0f && unit->IsPlayer() && !m_spellInfo->IsPositive())
3019 return SPELL_MISS_EVADE;
3020
3021 // assisting case, healing and resurrection
3023 {
3026 m_caster->ToPlayer()->UpdatePvP(true);
3027 }
3028
3029 // xinef: triggered spells should not prolong combat
3031 {
3034 unit->GetThreatMgr().ForwardThreatForAssistingMe(m_originalCaster, 0.0f, nullptr, true);
3035 }
3036 }
3037 }
3038
3039 uint8 aura_effmask = 0;
3040 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
3041 if (effectMask & (1 << i) && m_spellInfo->Effects[i].IsUnitOwnedAuraEffect())
3042 aura_effmask |= 1 << i;
3043
3044 Unit* originalCaster = GetOriginalCaster();
3045 if (!originalCaster)
3046 originalCaster = m_caster;
3047
3048 // Get Data Needed for Diminishing Returns, some effects may have multiple auras, so this must be done on spell hit, not aura add
3049 // Xinef: Do not increase diminishing level for self cast
3051 // xinef: do not increase diminish level for bosses (eg. Void Reaver silence is never diminished)
3052 if (((m_spellFlags & SPELL_FLAG_REFLECTED) && !(unit->HasReflectSpellsAura())) || (aura_effmask && m_diminishGroup && unit != m_caster && (!m_caster->IsCreature() || !m_caster->ToCreature()->isWorldBoss())))
3053 {
3056
3057 uint32 flagsExtra = unit->IsCreature() ? unit->ToCreature()->GetCreatureTemplate()->flags_extra : 0;
3058
3059 // Increase Diminishing on unit, current informations for actually casts will use values above
3060 if ((type == DRTYPE_PLAYER && (unit->IsCharmedOwnedByPlayerOrPlayer() || flagsExtra & CREATURE_FLAG_EXTRA_ALL_DIMINISH ||
3062 {
3063 // Do not apply diminish return if caster is NPC
3065 {
3067 }
3068 }
3069 }
3070
3073
3074 if (aura_effmask)
3075 {
3076 // Select rank for aura with level requirements only in specific cases
3077 // 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
3078 SpellInfo const* aurSpellInfo = m_spellInfo;
3079 int32 basePoints[3];
3080 if (scaleAura)
3081 {
3083 ASSERT(aurSpellInfo);
3084 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
3085 {
3086 basePoints[i] = aurSpellInfo->Effects[i].BasePoints;
3087 if (m_spellInfo->Effects[i].Effect != aurSpellInfo->Effects[i].Effect)
3088 {
3089 aurSpellInfo = m_spellInfo;
3090 break;
3091 }
3092 }
3093 }
3094
3095 if (m_originalCaster)
3096 {
3097 bool refresh = false;
3099 m_spellAura = Aura::TryRefreshStackOrCreate(aurSpellInfo, effectMask, unit, m_originalCaster,
3100 (aurSpellInfo == m_spellInfo) ? &m_spellValue->EffectBasePoints[0] : &basePoints[0], m_CastItem, ObjectGuid::Empty, &refresh, refreshPeriodic);
3101
3102 // xinef: if aura was not refreshed, add proc ex
3103 if (!refresh)
3105
3106 if (m_spellAura)
3107 {
3108 // Set aura stack amount to desired value
3110 {
3111 if (!refresh)
3113 else
3115 }
3116
3117 // Now Reduce spell duration using data received at spell hit
3118 int32 duration = m_spellAura->GetMaxDuration();
3119 int32 limitduration = GetDiminishingReturnsLimitDuration(m_diminishGroup, aurSpellInfo);
3120
3121 // Xinef: if unit == caster - test versus original unit if available
3122 float diminishMod = 1.0f;
3123 if (unit == m_caster && m_targets.GetUnitTarget())
3125 else
3126 diminishMod = unit->ApplyDiminishingToDuration(m_diminishGroup, duration, m_originalCaster, m_diminishLevel, limitduration);
3127
3128 // unit is immune to aura if it was diminished to 0 duration
3129 if (diminishMod == 0.0f)
3130 {
3133 return SPELL_MISS_IMMUNE;
3134 bool found = false;
3135 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
3136 if (effectMask & (1 << i) && m_spellInfo->Effects[i].Effect != SPELL_EFFECT_APPLY_AURA)
3137 found = true;
3138 if (!found)
3139 return SPELL_MISS_IMMUNE;
3140 }
3141 else
3142 {
3143 ((UnitAura*)m_spellAura)->SetDiminishGroup(m_diminishGroup);
3144
3145 bool positive = m_spellAura->GetSpellInfo()->IsPositive();
3147 positive = aurApp->IsPositive();
3148
3149 duration = m_originalCaster->ModSpellDuration(aurSpellInfo, unit, duration, positive, effectMask);
3150
3151 // xinef: haste affects duration of those spells twice
3154
3155 if (m_spellValue->AuraDuration != 0)
3156 {
3157 if (m_spellAura->GetMaxDuration() != -1)
3158 {
3160 }
3161
3163 }
3164 else if (duration != m_spellAura->GetMaxDuration())
3165 {
3166 m_spellAura->SetMaxDuration(duration);
3167 m_spellAura->SetDuration(duration);
3168 }
3169
3170 // xinef: apply relic cooldown, imo best place to add this
3173
3176 }
3177 }
3178 }
3179 }
3180
3181 int8 sanct_effect = -1;
3182
3183 for (uint32 effectNumber = 0; effectNumber < MAX_SPELL_EFFECTS; ++effectNumber)
3184 {
3185 // handle sanctuary effects after aura apply!
3186 if (m_spellInfo->Effects[effectNumber].Effect == SPELL_EFFECT_SANCTUARY)
3187 {
3188 sanct_effect = effectNumber;
3189 continue;
3190 }
3191
3192 if (effectMask & (1 << effectNumber))
3193 HandleEffects(unit, nullptr, nullptr, effectNumber, SPELL_EFFECT_HANDLE_HIT_TARGET);
3194 }
3195
3196 if (sanct_effect >= 0 && (effectMask & (1 << sanct_effect)))
3197 HandleEffects(unit, nullptr, nullptr, sanct_effect, SPELL_EFFECT_HANDLE_HIT_TARGET);
3198
3199 return SPELL_MISS_NONE;
3200}
@ 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:322
DiminishingGroup GetDiminishingReturnsGroupForSpell(SpellInfo const *spellproto, bool triggered)
Definition SpellMgr.cpp:105
DiminishingReturnsType GetDiminishingReturnsGroupType(DiminishingGroup group)
Definition SpellMgr.cpp:292
@ 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:269
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:6039
DiminishingLevels GetDiminishing(DiminishingGroup group)
Definition Unit.cpp:11740
void IncrDiminishing(DiminishingGroup group)
Definition Unit.cpp:11766
void SetContestedPvP(Player *attackedPlayer=nullptr, bool lookForNearContestedGuards=true)
Definition Unit.cpp:13649
bool HasUnitFlag(UnitFlags flags) const
Definition Unit.h:747
float ApplyDiminishingToDuration(DiminishingGroup group, int32 &duration, Unit *caster, DiminishingLevels Level, int32 limitduration)
Definition Unit.cpp:11780
int32 ModSpellDuration(SpellInfo const *spellProto, Unit const *target, int32 duration, bool positive, uint32 effectMask)
Definition Unit.cpp:11606
virtual void AddSpellCooldown(uint32, uint32, uint32, bool needSendToClient=false, bool forceSendToSpectator=false)
Definition Unit.h:1337
bool HasReflectSpellsAura() const
Definition Unit.h:1817
bool IsCharmedOwnedByPlayerOrPlayer() const
Definition Unit.h:1309
bool IsImmunedToSchool(SpellSchoolMask schoolMask) const
Definition Unit.cpp:9902
virtual bool IsImmunedToSpell(SpellInfo const *spellInfo, Spell const *spell=nullptr)
Definition Unit.cpp:10017
CombatManager & GetCombatManager()
Definition Unit.h:953
bool IsHostileTo(Unit const *unit) const
Definition Unit.cpp:7253
bool _IsValidAttackTarget(Unit const *target, SpellInfo const *bySpell, WorldObject const *obj=nullptr) const
Definition Unit.cpp:10737
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
3203{
3204 // Apply additional spell effects to target
3206 if (m_preCastSpell)
3207 {
3208 // Avenging Wrath - also apply Immune Shield Marker
3209 if (m_preCastSpell == 61987)
3210 m_caster->CastSpell(unit, 61988, true);
3211
3212 // Fearie Fire (Feral) - damage
3213 if (m_preCastSpell == 60089)
3214 m_caster->CastSpell(unit, m_preCastSpell, true);
3215 else if (sSpellMgr->GetSpellInfo(m_preCastSpell))
3216 // Blizz seems to just apply aura without bothering to cast
3218 }
3219
3220 // handle SPELL_AURA_ADD_TARGET_TRIGGER auras
3221 // this is executed after spell proc spells on target hit
3222 // spells are triggered for each hit spell target
3223 // info confirmed with retail sniffs of permafrost and shadow weaving
3224 if (!m_hitTriggerSpells.empty())
3225 {
3226 int _duration = 0;
3227 for (HitTriggerSpellList::const_iterator i = m_hitTriggerSpells.begin(); i != m_hitTriggerSpells.end(); ++i)
3228 {
3229 if (CanExecuteTriggersOnHit(effMask, i->triggeredByAura) && roll_chance_i(i->chance))
3230 {
3231 m_caster->CastSpell(unit, i->triggeredSpell->Id, true);
3232 LOG_DEBUG("spells.aura", "Spell {} triggered spell {} by SPELL_AURA_ADD_TARGET_TRIGGER aura", m_spellInfo->Id, i->triggeredSpell->Id);
3233
3234 // SPELL_AURA_ADD_TARGET_TRIGGER auras shouldn't trigger auras without duration
3235 // set duration of current aura to the triggered spell
3236 if (i->triggeredSpell->GetDuration() == -1)
3237 {
3238 if (Aura* triggeredAur = unit->GetAura(i->triggeredSpell->Id, m_caster->GetGUID()))
3239 {
3240 // get duration from aura-only once
3241 if (!_duration)
3242 {
3243 Aura* aur = unit->GetAura(m_spellInfo->Id, m_caster->GetGUID());
3244 _duration = aur ? aur->GetDuration() : -1;
3245 }
3246 triggeredAur->SetDuration(std::max(triggeredAur->GetDuration(), _duration));
3247 }
3248 }
3249 }
3250 }
3251 }
3252
3253 // trigger linked auras remove/apply
3255 if (std::vector<int32> const* spellTriggered = sSpellMgr->GetSpellLinked(m_spellInfo->Id + SPELL_LINK_HIT))
3256 {
3257 for (std::vector<int32>::const_iterator i = spellTriggered->begin(); i != spellTriggered->end(); ++i)
3258 if (*i < 0)
3259 {
3260 unit->RemoveAurasDueToSpell(-(*i));
3261 }
3262 else
3263 {
3264 unit->CastSpell(unit, *i, true, 0, 0, m_caster->GetGUID());
3265 }
3266 }
3267}
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:5859
Aura * AddAura(uint32 spellId, Unit *target)
Definition Unit.cpp:15117

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)
4250{
4252 return;
4253
4254 if (!gameObjTarget)
4255 return;
4256
4257 GameObjectActions action = GameObjectActions(m_spellInfo->Effects[effIndex].MiscValue);
4258 switch (action)
4259 {
4265 break;
4266 case GameObjectActions::Disturb: // What's the difference with Open?
4268 if (Unit* unitCaster = m_caster->ToUnit())
4269 gameObjTarget->Use(unitCaster);
4270 break;
4272 if (Unit* unitCaster = m_caster->ToUnit())
4273 gameObjTarget->UseDoorOrButton(0, false, unitCaster);
4274 [[fallthrough]];
4278 break;
4282 break;
4285 break;
4289 break;
4293 break;
4295 if (Unit* unitCaster = m_caster->ToUnit())
4296 gameObjTarget->UseDoorOrButton(0, true, unitCaster);
4297 break;
4302 {
4303 GameObjectTemplateAddon const* templateAddon = gameObjTarget->GetTemplateAddon();
4304
4305 uint32 artKitIndex = uint32(action) - uint32(GameObjectActions::UseArtKit0);
4306
4307 uint32 artKitValue = 0;
4308 if (templateAddon)
4309 artKitValue = templateAddon->artKits[artKitIndex];
4310
4311 if (artKitValue == 0)
4312 LOG_ERROR("sql.sql", "GameObject {} hit by spell {} needs `artkit{}` in `gameobject_template_addon`", gameObjTarget->GetEntry(), m_spellInfo->Id, artKitIndex);
4313 else
4314 gameObjTarget->SetGoArtKit(artKitValue);
4315
4316 break;
4317 }
4319 LOG_FATAL("spell", "Spell {} has action type NONE in effect {}", m_spellInfo->Id, int32(effIndex));
4320 break;
4321 default:
4322 LOG_ERROR("spell", "Spell {} has unhandled action {} in effect {}", m_spellInfo->Id, int32(action), int32(effIndex));
4323 break;
4324 }
4325}
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)
5787{
5789 return;
5790
5791 if (!m_caster->IsPlayer())
5792 return;
5793
5794 Player* player = m_caster->ToPlayer();
5795
5797 return;
5798
5799 // needed later
5801
5802 uint32 count = damage;
5803 if (count == 0) count = 1;
5804 for (uint32 j = 0; j < MAX_RUNES && count > 0; ++j)
5805 {
5806 if (player->GetRuneCooldown(j) && player->GetCurrentRune(j) == RuneType(m_spellInfo->Effects[effIndex].MiscValue))
5807 {
5808 if (m_spellInfo->Id == 45529)
5809 if (player->GetBaseRune(j) != RuneType(m_spellInfo->Effects[effIndex].MiscValueB))
5810 continue;
5811 player->SetRuneCooldown(j, 0);
5812 player->SetGracePeriod(j, player->IsInCombat()); // xinef: reset grace period
5813 --count;
5814 }
5815 }
5816
5817 // Blood Tap
5818 if (m_spellInfo->Id == 45529 && count > 0)
5819 {
5820 for (uint32 l = 0; l < MAX_RUNES && count > 0; ++l)
5821 {
5822 // Check if both runes are on cd as that is the only time when this needs to come into effect
5823 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)))
5824 {
5825 // Should always update the rune with the lowest cd
5826 if (player->GetRuneCooldown(l) >= player->GetRuneCooldown(l + 1))
5827 l++;
5828 player->SetRuneCooldown(l, 0);
5829 player->SetGracePeriod(l, player->IsInCombat()); // xinef: reset grace period
5830 --count;
5831 }
5832 else
5833 break;
5834 }
5835 }
5836
5837 // Empower rune weapon
5838 if (m_spellInfo->Id == 47568)
5839 {
5840 // Need to do this just once
5841 if (effIndex != 0)
5842 return;
5843
5844 for (uint32 i = 0; i < MAX_RUNES; ++i)
5845 {
5846 if (player->GetRuneCooldown(i) && (player->GetCurrentRune(i) == RUNE_FROST || player->GetCurrentRune(i) == RUNE_DEATH))
5847 {
5848 player->SetRuneCooldown(i, 0);
5849 player->SetGracePeriod(i, player->IsInCombat()); // xinef: reset grace period
5850 }
5851 }
5852 }
5853
5854 // is needed to push through to the client that the rune is active
5855 //player->ResyncRunes(MAX_RUNES);
5856 m_caster->CastSpell(m_caster, 47804, true);
5857}
@ RUNE_FROST
Definition Player.h:398
void SetRuneCooldown(uint8 index, uint32 cooldown)
Definition Player.h:2553
uint8 GetRunesState() const
Definition Player.h:2542
void SetGracePeriod(uint8 index, uint32 period)
Definition Player.h:2554
RuneType GetBaseRune(uint8 index) const
Definition Player.h:2543

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)
6165{
6167 return;
6168
6169 if (!unitTarget)
6170 return;
6171
6172 if (Player* player = unitTarget->ToPlayer())
6173 {
6174 player->ActivateSpec(damage - 1); // damage is 1 or 2, spec is 0 or 1
6175 }
6176}

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

◆ EffectAddComboPoints()

void Spell::EffectAddComboPoints ( SpellEffIndex  effIndex)
4086{
4088 {
4089 return;
4090 }
4091
4092 if (!unitTarget || damage <= 0)
4093 {
4094 return;
4095 }
4096
4098}
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)
4670{
4672 {
4673 return;
4674 }
4675
4676 if (!unitTarget || !unitTarget->IsAlive())
4677 {
4678 return;
4679 }
4680
4682
4684}
void ExecuteLogEffectExtraAttacks(uint8 effIndex, Unit *victim, uint32 attCount)
Definition Spell.cpp:5066
void AddExtraAttacks(uint32 count)
Definition Unit.cpp:2940

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

◆ EffectAddFarsight()

void Spell::EffectAddFarsight ( SpellEffIndex  effIndex)
2742{
2744 return;
2745
2746 if (!m_caster->IsPlayer())
2747 return;
2748
2749 float radius = m_spellInfo->Effects[effIndex].CalcRadius();
2750 int32 duration = m_spellInfo->GetDuration();
2751 // Caster not in world, might be spell triggered from aura removal
2752 if (!m_caster->IsInWorld())
2753 return;
2754
2755 // Remove old farsight if exist
2756 bool updateViewerVisibility = m_caster->RemoveDynObject(m_spellInfo->Id);
2757
2758 DynamicObject* dynObj = new DynamicObject();
2760 {
2761 delete dynObj;
2762 return;
2763 }
2764
2765 dynObj->SetDuration(duration);
2766 dynObj->SetCasterViewpoint(updateViewerVisibility);
2767}
@ 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)
2812{
2814 return;
2815
2816 if (!unitTarget->IsPlayer())
2817 return;
2818
2819 // not scale value for item based reward (/10 value expected)
2820 if (m_CastItem)
2821 {
2822 unitTarget->ToPlayer()->RewardHonor(nullptr, 1, damage / 10, false);
2823 LOG_DEBUG("spells.aura", "SpellEffect::AddHonor (spell_id {}) rewards {} honor points (item {}) for player: {}",
2825 return;
2826 }
2827
2828 // do not allow to add too many honor for player (50 * 21) = 1040 at level 70, or (50 * 31) = 1550 at level 80
2829 if (damage <= 50)
2830 {
2832 unitTarget->ToPlayer()->RewardHonor(nullptr, 1, honor_reward, false);
2833 LOG_DEBUG("spells.aura", "SpellEffect::AddHonor (spell_id {}) rewards {} honor points (scale) to player: {}",
2834 m_spellInfo->Id, honor_reward, unitTarget->ToPlayer()->GetGUID().ToString());
2835 }
2836 else
2837 {
2838 //maybe we have correct honor_gain in damage already
2839 unitTarget->ToPlayer()->RewardHonor(nullptr, 1, damage, false);
2840 LOG_DEBUG("spells.aura", "SpellEffect::AddHonor (spell_id {}) rewards {} honor points (non scale) for player: {}",
2842 }
2843}
std::string ToString() const
Definition ObjectGuid.cpp:47
bool RewardHonor(Unit *victim, uint32 groupsize, int32 honor=-1, bool awardXP=true)
Definition Player.cpp:6097
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)
4328{
4330 return;
4331
4333 return;
4334
4335 Player* player = m_caster->ToPlayer();
4336
4337 // glyph sockets level requirement
4338 uint8 minLevel = 0;
4339 switch (m_glyphIndex)
4340 {
4341 case 0:
4342 case 1:
4343 minLevel = 15;
4344 break;
4345 case 2:
4346 minLevel = 50;
4347 break;
4348 case 3:
4349 minLevel = 30;
4350 break;
4351 case 4:
4352 minLevel = 70;
4353 break;
4354 case 5:
4355 minLevel = 80;
4356 break;
4357 }
4358 if (minLevel && m_caster->GetLevel() < minLevel)
4359 {
4361 return;
4362 }
4363
4364 // apply new one
4365 if (uint32 glyph = m_spellInfo->Effects[effIndex].MiscValue)
4366 {
4367 if (GlyphPropertiesEntry const* glyphEntry = sGlyphPropertiesStore.LookupEntry(glyph))
4368 {
4369 if (GlyphSlotEntry const* glyphSlotEntry = sGlyphSlotStore.LookupEntry(player->GetGlyphSlot(m_glyphIndex)))
4370 {
4371 if (glyphEntry->TypeFlags != glyphSlotEntry->TypeFlags)
4372 {
4374 return; // glyph slot mismatch
4375 }
4376 }
4377
4378 // remove old glyph aura
4379 if (uint32 oldGlyph = player->GetGlyph(m_glyphIndex))
4380 if (GlyphPropertiesEntry const* oldGlyphEntry = sGlyphPropertiesStore.LookupEntry(oldGlyph))
4381 {
4382 player->RemoveAurasDueToSpell(oldGlyphEntry->SpellId);
4383
4384 // Removed any triggered auras
4385 Unit::AuraMap& ownedAuras = player->GetOwnedAuras();
4386 for (Unit::AuraMap::iterator iter = ownedAuras.begin(); iter != ownedAuras.end();)
4387 {
4388 Aura* aura = iter->second;
4389 if (SpellInfo const* triggeredByAuraSpellInfo = aura->GetTriggeredByAuraSpellInfo())
4390 {
4391 if (triggeredByAuraSpellInfo->Id == oldGlyphEntry->SpellId)
4392 {
4393 player->RemoveOwnedAura(iter);
4394 continue;
4395 }
4396 }
4397 ++iter;
4398 }
4399
4400 player->SendLearnPacket(oldGlyphEntry->SpellId, false); // Send packet to properly handle client-side spell tooltips
4401 }
4402
4403 player->SendLearnPacket(glyphEntry->SpellId, true); // Send packet to properly handle client-side spell tooltips
4405 player->SetGlyph(m_glyphIndex, glyph, !player->GetSession()->PlayerLoading());
4406 player->SendTalentsInfoData(false);
4407 }
4408 }
4409}
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:14572
void SendLearnPacket(uint32 spellId, bool learn)
Definition Player.cpp:3022
uint32 GetGlyph(uint8 slot) const
Definition Player.h:1782
uint32 GetGlyphSlot(uint8 slot) const
Definition Player.h:1773
void SetGlyph(uint8 slot, uint32 glyph, bool save)
Definition Player.h:1774
void RemoveOwnedAura(AuraMap::iterator &i, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition Unit.cpp:4967
std::multimap< uint32, Aura * > AuraMap
Definition Unit.h:669
AuraMap & GetOwnedAuras()
Definition Unit.h:1373
bool PlayerLoading() const
Definition WorldSession.h:401
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)
6298{
6300 return;
6301
6302 if (!unitTarget)
6303 return;
6304
6305 Player* player = unitTarget->ToPlayer();
6306 if (!player)
6307 {
6308 return;
6309 }
6310
6311 WorldLocation homeLoc;
6312 uint32 areaId = player->GetAreaId();
6313
6314 if (m_spellInfo->Effects[effIndex].MiscValue)
6315 areaId = m_spellInfo->Effects[effIndex].MiscValue;
6316
6317 if (m_targets.HasDst())
6318 homeLoc.WorldRelocate(*destTarget);
6319 else
6320 {
6321 homeLoc = player->GetWorldLocation();
6322 }
6323
6324 player->SetHomebind(homeLoc, areaId);
6325
6326 // binding
6327 WorldPacket data(SMSG_BINDPOINTUPDATE, 4 + 4 + 4 + 4 + 4);
6328 data << float(homeLoc.GetPositionX());
6329 data << float(homeLoc.GetPositionY());
6330 data << float(homeLoc.GetPositionZ());
6331 data << uint32(homeLoc.GetMapId());
6332 data << uint32(areaId);
6333 player->SendDirectMessage(&data);
6334
6335 LOG_DEBUG("spells.aura", "EffectBind: New homebind X: {}, Y: {}, Z: {}, MapId: {}, AreaId: {}",
6336 homeLoc.GetPositionX(), homeLoc.GetPositionY(), homeLoc.GetPositionZ(), homeLoc.GetMapId(), areaId);
6337 // zone update
6338 data.Initialize(SMSG_PLAYERBOUND, 8 + 4);
6339 data << m_caster->GetGUID();
6340 data << uint32(areaId);
6341 player->SendDirectMessage(&data);
6342}
void SendDirectMessage(WorldPacket const *data) const
Definition Player.cpp:5692
void SetHomebind(WorldLocation const &loc, uint32 areaId)
Definition PlayerStorage.cpp:4959
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)
4696{
4698 return;
4699
4700 if (m_caster->IsPlayer())
4701 m_caster->ToPlayer()->SetCanBlock(true);
4702}
void SetCanBlock(bool value)
Definition Player.cpp:13180

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.

6225{
6227 return;
6228
6229 if (!m_caster->IsPlayer())
6230 return;
6231
6232 Player* p_caster = m_caster->ToPlayer();
6233 uint32 button_id = m_spellInfo->Effects[effIndex].MiscValue + 132;
6234 uint32 n_buttons = m_spellInfo->Effects[effIndex].MiscValueB;
6235
6236 for (; n_buttons; --n_buttons, ++button_id)
6237 {
6238 ActionButton const* ab = p_caster->GetActionButton(button_id);
6239 if (!ab || ab->GetType() != ACTION_BUTTON_SPELL)
6240 continue;
6241
6244 uint32 spell_id = ab->GetAction();
6245 if (!spell_id)
6246 continue;
6247
6248 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spell_id);
6249 if (!spellInfo)
6250 continue;
6251
6252 if (!p_caster->HasSpell(spell_id) || p_caster->HasSpellCooldown(spell_id))
6253 continue;
6254
6256 continue;
6257
6258 uint32 cost = spellInfo->CalcPowerCost(m_caster, spellInfo->GetSchoolMask(), this);
6259 if (m_caster->GetPower(POWER_MANA) < cost)
6260 continue;
6261
6263 m_caster->CastSpell(m_caster, spell_id, triggerFlags);
6264 }
6265}
@ 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:5651
bool HasSpell(uint32 spell) const override
Definition Player.cpp:3881
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)
4915{
4917 {
4918 if (!unitTarget)
4919 return;
4920
4921 ObjectGuid targetGUID = ObjectGuid::Empty;
4922 Player* player = m_caster->ToPlayer();
4923 if (player)
4924 {
4925 // charge changes fall time
4927
4929 {
4930 targetGUID = unitTarget->GetGUID();
4931 }
4932 }
4933
4934 float speed = G3D::fuzzyGt(m_spellInfo->Speed, 0.0f) ? m_spellInfo->Speed : SPEED_CHARGE;
4935 // Spell is not using explicit target - no generated path
4936 if (!m_preGeneratedPath)
4937 {
4939 m_caster->GetMotionMaster()->MoveCharge(pos.m_positionX, pos.m_positionY, pos.m_positionZ, speed, EVENT_CHARGE, nullptr, false, 0.0f, targetGUID);
4940 }
4941 else
4942 {
4943 m_caster->GetMotionMaster()->MoveCharge(*m_preGeneratedPath, speed, targetGUID);
4944 }
4945
4946 if (player)
4947 {
4948 sScriptMgr->AnticheatSetUnderACKmount(player);
4949 }
4950 }
4951}
#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:2372
MotionMaster * GetMotionMaster()
Definition Unit.h:1759
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:5094
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:13543
void DestroyItemCount(uint32 item, uint32 count, bool update, bool unequip_check=false)
Definition PlayerStorage.cpp:3183
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)
5860{
5862 return;
5863
5865 return;
5866
5867 uint32 creatureEntry = m_spellInfo->Effects[effIndex].MiscValue;
5868 Pet* pet = unitTarget->CreateTamedPetFrom(creatureEntry, m_spellInfo->Id);
5869 if (!pet)
5870 return;
5871
5872 // add to world
5873 pet->GetMap()->AddToMap(pet->ToCreature(), true);
5874
5875 // unitTarget has pet now
5876 unitTarget->SetMinion(pet, true);
5877
5878 pet->InitTalentForLevel();
5879
5880 if (unitTarget->IsPlayer())
5881 {
5884 }
5885}
@ 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:9513
void SetMinion(Minion *minion, bool apply)
Definition Unit.cpp:7784
Pet * CreateTamedPetFrom(Creature *creatureTarget, uint32 spell_id=0)
Definition Unit.cpp:13752

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)
5266{
5268 return;
5269
5270 int32 mana = 0;
5271 for (uint8 slot = SUMMON_SLOT_TOTEM_FIRE; slot < MAX_TOTEM_SLOT; ++slot)
5272 {
5273 if (!m_caster->m_SummonSlot[slot])
5274 continue;
5275
5277 if (totem && totem->IsTotem())
5278 {
5279 uint32 spell_id = totem->GetUInt32Value(UNIT_CREATED_BY_SPELL);
5280 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spell_id);
5281 if (spellInfo)
5282 {
5283 mana += spellInfo->ManaCost;
5285 }
5286 totem->ToTotem()->UnSummon();
5287 }
5288 }
5289 ApplyPct(mana, damage);
5290 if (mana)
5291 m_caster->CastCustomSpell(m_caster, 39104, &mana, nullptr, nullptr, true);
5292}
#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:2349
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:1432
uint32 GetCreateMana() const
Definition Unit.h:1148
ObjectGuid m_SummonSlot[MAX_SUMMON_SLOT]
Definition Unit.h:2079

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)
5888{
5890 return;
5891
5892 if (!unitTarget)
5893 return;
5894
5895 Player* player = unitTarget->ToPlayer();
5896 if (!player)
5897 {
5898 return;
5899 }
5900
5901 uint32 nodeid = m_spellInfo->Effects[effIndex].MiscValue;
5902 if (sTaxiNodesStore.LookupEntry(nodeid))
5903 player->GetSession()->SendDiscoverNewTaxiNode(nodeid);
5904}
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)
4465{
4467 return;
4468
4470 return;
4471
4472 if (Player* caster = m_caster->ToPlayer())
4473 {
4474 caster->UpdateCraftSkill(m_spellInfo->Id);
4475 caster->SendLoot(itemTarget->GetGUID(), LOOT_DISENCHANTING);
4476 }
4477
4478 // item will be removed at disenchanting end
4479}
@ 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)
4551{
4553 return;
4554
4555 if (!unitTarget || !unitTarget->IsPet())
4556 return;
4557
4558 Pet* pet = unitTarget->ToPet();
4559
4560 ExecuteLogEffectUnsummonObject(effIndex, pet);
4562}
@ 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:5112

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->GetId() == itr->first->GetId())
2633 {
2634 ++successItr->second;
2635 alreadyListed = true;
2636 }
2637 }
2638 if (!alreadyListed)
2639 success_list.push_back(std::make_pair(itr->first, 1));
2640 --itr->second;
2641 if (itr->second <= 0)
2642 dispel_list.erase(itr);
2643 }
2644 else
2645 {
2646 if (!failCount)
2647 {
2648 // Failed to dispell
2649 dataFail << m_caster->GetGUID(); // Caster GUID
2650 dataFail << unitTarget->GetGUID(); // Victim GUID
2651 dataFail << uint32(m_spellInfo->Id); // dispel spell id
2652 }
2653 ++failCount;
2654 dataFail << uint32(itr->first->GetId()); // Spell Id
2655 }
2656 ++count;
2657 }
2658 }
2659
2660 if (failCount)
2661 m_caster->SendMessageToSet(&dataFail, true);
2662
2663 // put in combat
2666
2667 if (success_list.empty())
2668 return;
2669
2670 WorldPacket dataSuccess(SMSG_SPELLDISPELLOG, 8 + 8 + 4 + 1 + 4 + success_list.size() * 5);
2671 // Send packet header
2672 dataSuccess << unitTarget->GetPackGUID(); // Victim GUID
2673 dataSuccess << m_caster->GetPackGUID(); // Caster GUID
2674 dataSuccess << uint32(m_spellInfo->Id); // dispel spell id
2675 dataSuccess << uint8(0); // not used
2676 dataSuccess << uint32(success_list.size()); // count
2677 for (DispelChargesList::iterator itr = success_list.begin(); itr != success_list.end(); ++itr)
2678 {
2679 // Send dispelled spell info
2680 dataSuccess << uint32(itr->first->GetId()); // Spell Id
2681 dataSuccess << uint8(0); // 0 - dispelled !=0 cleansed
2682 unitTarget->RemoveAurasDueToSpellByDispel(itr->first->GetId(), m_spellInfo->Id, itr->first->GetCasterGUID(), m_caster, itr->second);
2683 }
2684 m_caster->SendMessageToSet(&dataSuccess, true);
2685
2686 // On success dispel
2687 // Devour Magic
2689 {
2690 int32 heal_amount = m_spellInfo->Effects[EFFECT_1].CalcValue();
2691 m_caster->CastCustomSpell(m_caster, 19658, &heal_amount, nullptr, nullptr, true);
2692 // Glyph of Felhunter
2693 if (Unit* owner = m_caster->GetOwner())
2694 if (owner->GetAura(56249))
2695 owner->CastCustomSpell(owner, 19658, &heal_amount, nullptr, nullptr, true);
2696 }
2697}
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:5204
@ 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)
5171{
5173 return;
5174
5175 if (!unitTarget)
5176 return;
5177
5178 uint32 mechanic = m_spellInfo->Effects[effIndex].MiscValue;
5179
5180 std::queue<std::pair<uint32, ObjectGuid>> dispel_list;
5181
5182 Unit::AuraMap const& auras = unitTarget->GetOwnedAuras();
5183 for (Unit::AuraMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
5184 {
5185 Aura* aura = itr->second;
5187 continue;
5189 {
5190 if (aura->GetSpellInfo()->GetAllEffectsMechanicMask() & (1ULL << mechanic))
5191 {
5192 dispel_list.push(std::make_pair(aura->GetId(), aura->GetCasterGUID()));
5193
5194 // spell only removes 1 bleed effect do not continue
5195 if (m_spellInfo->Effects[effIndex].BasePoints == 1)
5196 {
5197 break;
5198 }
5199 }
5200 }
5201 }
5202
5203 for (; dispel_list.size(); dispel_list.pop())
5204 {
5205 unitTarget->RemoveAura(dispel_list.front().first, dispel_list.front().second, 0, AURA_REMOVE_BY_ENEMY_SPELL);
5206 }
5207
5208 // put in combat
5211}
@ AURA_REMOVE_BY_ENEMY_SPELL
Definition SpellAuraDefines.h:394
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:5038

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.

2714{
2716 return;
2717
2718 // Check for possible target
2719 if (!unitTarget || unitTarget->IsEngaged())
2720 return;
2721
2722 // target must be OK to do this
2724 return;
2725
2728}
@ 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:16446
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)
2700{
2702 return;
2703
2705}
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)
4101{
4103 return;
4104
4105 if (!unitTarget || !m_caster->IsPlayer() || !unitTarget->IsPlayer())
4106 return;
4107
4108 Player* caster = m_caster->ToPlayer();
4109 Player* target = unitTarget->ToPlayer();
4110
4111 // caster or target already have requested duel
4112 if (caster->duel || target->duel || !target->GetSocial() || target->GetSocial()->HasIgnore(caster->GetGUID()))
4113 return;
4114
4115 // Players can only fight a duel in zones with this flag
4116 AreaTableEntry const* casterAreaEntry = sAreaTableStore.LookupEntry(caster->GetAreaId());
4117 if (casterAreaEntry && !(casterAreaEntry->flags & AREA_FLAG_ALLOW_DUELS))
4118 {
4119 SendCastResult(SPELL_FAILED_NO_DUELING); // Dueling isn't allowed here
4120 return;
4121 }
4122
4123 AreaTableEntry const* targetAreaEntry = sAreaTableStore.LookupEntry(target->GetAreaId());
4124 if (targetAreaEntry && !(targetAreaEntry->flags & AREA_FLAG_ALLOW_DUELS))
4125 {
4126 SendCastResult(SPELL_FAILED_NO_DUELING); // Dueling isn't allowed here
4127 return;
4128 }
4129
4130 //CREATE DUEL FLAG OBJECT
4131 uint32 gameobject_id = m_spellInfo->Effects[effIndex].MiscValue;
4132 GameObject* pGameObj = sObjectMgr->IsGameObjectStaticTransport(gameobject_id) ? new StaticTransport() : new GameObject();
4133
4134 Map* map = m_caster->GetMap();
4135 G3D::Quat rotation = G3D::Quat::fromAxisAngleRotation(G3D::Vector3::unitZ(), m_caster->GetOrientation());
4136 if (!pGameObj->Create(map->GenerateLowGuid<HighGuid::GameObject>(), gameobject_id,
4137 map, m_caster->GetPhaseMask(),
4141 m_caster->GetOrientation(), rotation, 0, GO_STATE_READY))
4142 {
4143 delete pGameObj;
4144 return;
4145 }
4146
4149 int32 duration = m_spellInfo->GetDuration();
4150 pGameObj->SetRespawnTime(duration > 0 ? duration / IN_MILLISECONDS : 0);
4151 pGameObj->SetSpellId(m_spellInfo->Id);
4152
4153 ExecuteLogEffectSummonObject(effIndex, pGameObj);
4154
4155 m_caster->AddGameObject(pGameObj);
4156 map->AddToMap(pGameObj, true);
4157 //END
4158
4159 // Send request
4160 WorldPacket data(SMSG_DUEL_REQUESTED, 8 + 8);
4161 data << pGameObj->GetGUID();
4162 data << caster->GetGUID();
4163 caster->SendDirectMessage(&data);
4164 target->SendDirectMessage(&data);
4165
4166 // create duel-info
4167 bool isMounted = (GetSpellInfo()->Id == 62875);
4168 caster->duel = std::make_unique<DuelInfo>(target, caster, isMounted);
4169 target->duel = std::make_unique<DuelInfo>(caster, caster, isMounted);
4170
4171 caster->SetGuidValue(PLAYER_DUEL_ARBITER, pGameObj->GetGUID());
4172 target->SetGuidValue(PLAYER_DUEL_ARBITER, pGameObj->GetGUID());
4173
4174 sScriptMgr->OnPlayerDuelRequest(target, caster);
4175}
@ 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:5106
Definition Transport.h:115
uint32 GetFaction() const
Definition Unit.h:851
void AddGameObject(GameObject *gameObj)
Definition Unit.cpp:6565
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:460
void AddPetAura(PetAura const *petSpell)
Definition Unit.cpp:13698
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)
5295{
5297 return;
5298
5299 if (!unitTarget)
5300 return;
5301
5302 Player* player = unitTarget->ToPlayer();
5303 if (!player)
5304 {
5305 return;
5306 }
5307
5308 int32 slot = m_spellInfo->Effects[effIndex].MiscValue;
5309
5310 // -1 means all player equipped items and -2 all items
5311 if (slot < 0)
5312 {
5313 player->DurabilityPointsLossAll(damage, (slot < -1));
5315 return;
5316 }
5317
5318 // invalid slot value
5319 if (slot >= INVENTORY_SLOT_BAG_END)
5320 return;
5321
5322 if (Item* item = player->GetItemByPos(INVENTORY_SLOT_BAG_0, slot))
5323 {
5324 player->DurabilityPointsLoss(item, damage);
5325 ExecuteLogEffectDurabilityDamage(effIndex, unitTarget, item->GetEntry(), slot);
5326 }
5327}
@ INVENTORY_SLOT_BAG_END
Definition Player.h: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:4678
void DurabilityPointsLoss(Item *item, int32 points)
Definition Player.cpp:4704
void ExecuteLogEffectDurabilityDamage(uint8 effIndex, Unit *victim, int32 itemId, int32 slot)
Definition Spell.cpp:5080

References damage, Player::DurabilityPointsLoss(), Player::DurabilityPointsLossAll(), effectHandleMode, SpellInfo::Effects, ExecuteLogEffectDurabilityDamage(), Object::GetEntry(), Player::GetItemByPos(), INVENTORY_SLOT_BAG_0, INVENTORY_SLOT_BAG_END, m_spellInfo, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectDurabilityDamagePCT()

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

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)
4412{
4414 return;
4415
4416 // this is only item spell effect applied to main-hand weapon of target player (players in area)
4417 if (!unitTarget)
4418 return;
4419
4420 Player* item_owner = unitTarget->ToPlayer();
4421 if (!item_owner)
4422 {
4423 return;
4424 }
4425
4427 if (!item)
4428 return;
4429
4430 // must be equipped
4431 if (!item->IsEquipped())
4432 return;
4433
4434 if (m_spellInfo->Effects[effIndex].MiscValue)
4435 {
4436 uint32 enchant_id = m_spellInfo->Effects[effIndex].MiscValue;
4437 int32 duration = m_spellInfo->GetDuration(); //Try duration index first ..
4438 if (!duration)
4439 duration = damage * IN_MILLISECONDS; //+1; //Base points after ..
4440 if (!duration)
4441 duration = 10 * IN_MILLISECONDS; //10 seconds for enchants which don't have listed duration
4442
4443 // Xinef: Venomhide poison, no other spell uses this effect...
4444 if (m_spellInfo->Id == 14792)
4445 duration = 5 * MINUTE * IN_MILLISECONDS;
4446
4447 SpellItemEnchantmentEntry const* pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id);
4448 if (!pEnchant)
4449 return;
4450
4451 // Always go to temp enchantment slot
4453
4454 // Enchantment will not be applied if a different one already exists
4455 if (item->GetEnchantmentId(slot) && item->GetEnchantmentId(slot) != enchant_id)
4456 return;
4457
4458 // Apply the temporary enchantment
4459 item->SetEnchantment(slot, enchant_id, duration, pEnchant->charges, m_caster->GetGUID());
4460 item_owner->ApplyEnchantment(item, slot, true);
4461 }
4462}
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:4372
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)
2858{
2860 return;
2861
2862 if (!m_caster->IsPlayer())
2863 return;
2864 if (!itemTarget)
2865 return;
2866
2867 Player* p_caster = m_caster->ToPlayer();
2868
2869 // Handle vellums
2871 {
2872 // destroy one vellum from stack
2873 uint32 count = 1;
2874 p_caster->DestroyItemCount(itemTarget, count, true);
2875 unitTarget = p_caster;
2876 // and add a scroll
2877 DoCreateItem(effIndex, m_spellInfo->Effects[effIndex].ItemType);
2878 itemTarget = nullptr;
2879 m_targets.SetItemTarget(nullptr);
2880 }
2881 else
2882 {
2883 // do not increase skill if vellum used
2885 p_caster->UpdateCraftSkill(m_spellInfo->Id);
2886
2887 uint32 enchant_id = m_spellInfo->Effects[effIndex].MiscValue;
2888 if (!enchant_id)
2889 return;
2890
2891 SpellItemEnchantmentEntry const* pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id);
2892 if (!pEnchant)
2893 return;
2894
2895 // item can be in trade slot and have owner diff. from caster
2896 Player* item_owner = itemTarget->GetOwner();
2897 if (!item_owner)
2898 return;
2899
2900 // remove old enchanting before applying new if equipped
2902
2904
2905 // add new enchanting if equipped
2907
2908 if (item_owner != p_caster && p_caster->GetSession()->HasPermission(rbac::RBAC_PERM_LOG_GM_TRADE))
2909 {
2910 LOG_GM(p_caster->GetSession()->GetAccountId(), "GM {} (Account: {}) enchanting(perm): {} (SpellID: {} EncID: {}) on {}'s item: {} (Entry: {})",
2911 p_caster->GetName(), p_caster->GetSession()->GetAccountId(),
2912 m_spellInfo->SpellName[0], m_spellInfo->Id, enchant_id,
2913 item_owner->GetName(), itemTarget->GetTemplate()->Name1, itemTarget->GetEntry());
2914 }
2915
2916 item_owner->RemoveTradeableItem(itemTarget);
2918 }
2919}
@ PERM_ENCHANTMENT_SLOT
Definition Item.h:169
#define LOG_GM(accountId__,...)
Definition Log.h:164
void ClearSoulboundTradeable(Player *currentOwner)
Definition Item.cpp:1264
void RemoveTradeableItem(Item *item)
Definition PlayerStorage.cpp:4207
void SetItemTarget(Item *item)
Definition Spell.cpp:327
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)
2922{
2924 return;
2925
2926 if (!m_caster->IsPlayer())
2927 return;
2928 if (!itemTarget)
2929 return;
2930
2931 uint32 enchant_id = m_spellInfo->Effects[effIndex].MiscValue;
2932 if (!enchant_id)
2933 return;
2934
2935 SpellItemEnchantmentEntry const* pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id);
2936 if (!pEnchant)
2937 return;
2938
2939 // support only enchantings with add socket in this slot
2940 {
2941 bool add_socket = false;
2942 for (uint8 i = 0; i < MAX_SPELL_ITEM_ENCHANTMENT_EFFECTS; ++i)
2943 {
2944 if (pEnchant->type[i] == ITEM_ENCHANTMENT_TYPE_PRISMATIC_SOCKET)
2945 {
2946 add_socket = true;
2947 break;
2948 }
2949 }
2950 if (!add_socket)
2951 {
2952 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.",
2954 return;
2955 }
2956 }
2957
2958 // item can be in trade slot and have owner diff. from caster
2959 Player* item_owner = itemTarget->GetOwner();
2960 if (!item_owner)
2961 return;
2962
2963 Player* p_caster = m_caster->ToPlayer();
2964 if (item_owner != p_caster && p_caster->GetSession()->HasPermission(rbac::RBAC_PERM_LOG_GM_TRADE))
2965 {
2966 LOG_GM(p_caster->GetSession()->GetAccountId(), "GM {} (Account: {}) enchanting(prismatic): {} (SpellID: {} EncID: {}) on {}'s item: {} (Entry: {})",
2967 p_caster->GetName(), p_caster->GetSession()->GetAccountId(),
2968 m_spellInfo->SpellName[0], m_spellInfo->Id, enchant_id,
2969 item_owner->GetName(), itemTarget->GetTemplate()->Name1, itemTarget->GetEntry());
2970 }
2971
2972 // remove old enchanting before applying new if equipped
2974
2976
2977 // add new enchanting if equipped
2979
2980 item_owner->RemoveTradeableItem(itemTarget);
2982}

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

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

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

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

◆ EffectGameObjectDamage()

void Spell::EffectGameObjectDamage ( SpellEffIndex  effIndex)
5932{
5934 return;
5935
5936 if (!gameObjTarget)
5937 return;
5938
5939 Unit* caster = m_originalCaster;
5940 if (!caster)
5941 return;
5942
5943 FactionTemplateEntry const* casterFaction = caster->GetFactionTemplateEntry();
5945 // Do not allow to damage GO's of friendly factions (ie: Wintergrasp Walls/Ulduar Storm Beacons)
5946 if ((casterFaction && targetFaction && !casterFaction->IsFriendlyTo(*targetFaction)) || !targetFaction)
5948}
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:7051
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)
5962{
5964 return;
5965
5967 return;
5968
5971}
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:5772
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)
3712{
3714 return;
3715
3716 if (!unitTarget || !unitTarget->IsAlive())
3717 return;
3718
3720 {
3722 return;
3723 }
3724
3725 int32 addhealth = 0;
3726
3727 // damage == 0 - heal for caster max health
3728 if (damage == 0)
3729 addhealth = m_caster->GetMaxHealth();
3730 else
3731 addhealth = unitTarget->GetMaxHealth() - unitTarget->GetHealth();
3732
3733 m_healing += addhealth;
3734}
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:8894
uint32 SpellDamageBonusDone(Unit *victim, SpellInfo const *spellProto, uint32 pdamage, DamageEffectType damagetype, uint8 effIndex, float TotalMod=0.0f, uint32 stack=1)
Definition Unit.cpp:8720

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)
4482{
4484 return;
4485
4486 if (!unitTarget)
4487 return;
4488
4489 Player* player = unitTarget->ToPlayer();
4490 if (!player)
4491 {
4492 return;
4493 }
4494
4495 uint8 currentDrunk = player->GetDrunkValue();
4496 int32 drunkMod = damage;
4497
4498 if (drunkMod == 0)
4499 return;
4500
4501 // drunkMod may contain values ​​that are guaranteed to cause uint8 overflow/underflow (examples: 29690, 46874)
4502 // In addition, we would not want currentDrunk to become more than 100.
4503 // So before adding the values, let's check that everything is fine.
4504 if (drunkMod > 0 && drunkMod > static_cast<int32>(100 - currentDrunk))
4505 currentDrunk = 100;
4506 else if (drunkMod < 0 && drunkMod < static_cast<int32>(0 - currentDrunk))
4507 currentDrunk = 0;
4508 else
4509 currentDrunk += drunkMod; // Due to previous checks we can be sure that currentDrunk will not go beyond [0-100] range.
4510
4511 player->SetDrunkValue(currentDrunk, m_CastItem ? m_CastItem->GetEntry() : 0);
4512
4513 if (currentDrunk == 100 && roll_chance_i(25))
4514 player->CastSpell(player, 67468, false); // Drunken Vomit
4515}
uint8 GetDrunkValue() const
Definition Player.h:2191
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:1007
@ 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
3737{
3739 return;
3740
3741 if (!unitTarget || !unitTarget->IsAlive())
3742 return;
3743
3745 // also exist case: apply cooldown to interrupted cast only and to all spells
3746 // there is no CURRENT_AUTOREPEAT_SPELL spells that can be interrupted
3748 {
3750 {
3751 SpellInfo const* curSpellInfo = spell->m_spellInfo;
3752 // check if we can interrupt spell
3753 if ((spell->getState() == SPELL_STATE_CASTING
3754 || (spell->getState() == SPELL_STATE_PREPARING && spell->GetCastTime() > 0.0f))
3758 {
3759 if (m_originalCaster)
3760 {
3762 unitTarget->ProhibitSpellSchool(curSpellInfo->GetSchoolMask(), duration/*spellInfo->GetDuration()*/);
3763 }
3764 ExecuteLogEffectInterruptCast(effIndex, unitTarget, curSpellInfo->Id);
3766 }
3767 }
3768 }
3769}
@ 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:5073
void InterruptSpell(CurrentSpellTypes spellType, bool withDelayed=true, bool withInstant=true, bool bySelf=false)
Definition Unit.cpp:4244
int32 CalcSpellDuration(SpellInfo const *spellProto)
Definition Unit.cpp:11589
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)
5724{
5726 return;
5727
5728 if (!unitTarget)
5729 return;
5730
5732 if (!player)
5733 {
5734 return;
5735 }
5736
5737 int32 creatureEntry = m_spellInfo->Effects[effIndex].MiscValue;
5738 if (!creatureEntry)
5739 {
5740 if (m_spellInfo->Id == 42793) // Burn Body
5741 creatureEntry = 24008; // Fallen Combatant
5742 }
5743
5744 if (creatureEntry)
5745 player->RewardPlayerAndGroupAtEvent(creatureEntry, unitTarget);
5746}
void RewardPlayerAndGroupAtEvent(uint32 creature_id, WorldObject *pRewardSource)
Definition Player.cpp:12766

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

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

◆ EffectKnockBack()

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

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

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

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)
3304{
3306 return;
3307
3308 if (!unitTarget)
3309 return;
3310
3311 if (unitTarget->ToPlayer())
3312 {
3313 EffectLearnSpell(effIndex);
3314 return;
3315 }
3316 Pet* pet = unitTarget->ToPet();
3317 if (!pet)
3318 return;
3319
3320 SpellInfo const* learn_spellproto = sSpellMgr->GetSpellInfo(m_spellInfo->Effects[effIndex].TriggerSpell);
3321 if (!learn_spellproto)
3322 return;
3323
3324 pet->learnSpell(learn_spellproto->Id);
3326 pet->GetOwner()->PetSpellInitialize();
3327}
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)
2796{
2798 return;
2799
2800 if (!unitTarget->IsPlayer())
2801 return;
2802
2803 if (damage < 0)
2804 return;
2805
2806 uint32 skillid = m_spellInfo->Effects[effIndex].MiscValue;
2807 uint16 skillval = unitTarget->ToPlayer()->GetPureSkillValue(skillid);
2808 unitTarget->ToPlayer()->SetSkill(skillid, m_spellInfo->Effects[effIndex].CalcValue(), skillval ? skillval : 1, damage * 75);
2809}
uint16 GetPureSkillValue(uint32 skill) const
Definition Player.cpp:5515
void SetSkill(uint16 id, uint16 step, uint16 currVal, uint16 maxVal)
Definition Player.cpp:5326

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:3293
void EffectLearnPetSpell(SpellEffIndex effIndex)
Definition SpellEffects.cpp:3303

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)
5533{
5535 return;
5536
5537 if (!m_caster->IsPlayer())
5538 return;
5539
5540 Player* p_caster = m_caster->ToPlayer();
5542 return;
5543
5544 if (itemTarget->GetCount() < 5)
5545 return;
5546
5547 if (sWorld->getBoolConfig(CONFIG_SKILL_MILLING))
5548 {
5549 uint32 SkillValue = p_caster->GetPureSkillValue(SKILL_INSCRIPTION);
5550 uint32 reqSkillValue = itemTarget->GetTemplate()->RequiredSkillRank;
5551 p_caster->UpdateGatherSkill(SKILL_INSCRIPTION, SkillValue, reqSkillValue);
5552 }
5553
5555}
@ LOOT_MILLING
Definition LootMgr.h:87
@ CONFIG_SKILL_MILLING
Definition WorldConfig.h:47
void SendLoot(ObjectGuid guid, LootType loot_type)
Definition Player.cpp:7813
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)
5365{
5367 return;
5368
5369 if (!unitTarget)
5370 return;
5371
5373}
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:5088
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)
4687{
4689 return;
4690
4691 if (m_caster->IsPlayer())
4692 m_caster->ToPlayer()->SetCanParry(true);
4693}
void SetCanParry(bool value)
Definition Player.cpp:13171

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)
6126{
6128 return;
6129
6130 if (!unitTarget)
6131 return;
6132
6133 Player* player = unitTarget->ToPlayer();
6134 if (!player)
6135 {
6136 return;
6137 }
6138
6139 uint32 soundid = m_spellInfo->Effects[effIndex].MiscValue;
6140
6141 if (!sSoundEntriesStore.LookupEntry(soundid))
6142 {
6143 LOG_ERROR("spells.effect", "EffectPlayMusic: Sound (Id: {}) not exist in spell {}.", soundid, m_spellInfo->Id);
6144 return;
6145 }
6146
6148}
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)
6179{
6181 return;
6182
6183 if (!unitTarget)
6184 return;
6185
6186 Player* player = unitTarget->ToPlayer();
6187 if (!player)
6188 {
6189 return;
6190 }
6191
6192 switch (m_spellInfo->Id)
6193 {
6194 case 58730: // Restricted Flight Area
6195 case 58600: // Restricted Flight Area
6197 break;
6198 default:
6199 break;
6200 }
6201
6202 uint32 soundId = m_spellInfo->Effects[effIndex].MiscValue;
6203
6204 if (!sSoundEntriesStore.LookupEntry(soundId))
6205 {
6206 LOG_ERROR("spells.effect", "EffectPlayerSound: Sound (Id: {}) not exist in spell {}.", soundId, m_spellInfo->Id);
6207 return;
6208 }
6209
6210 player->PlayDirectSound(soundId, player);
6211}
@ 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:5057
int32 ModifyPower(Powers power, int32 val, bool withPowerUpdate=true)
Definition Unit.cpp:11024
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:1379
void SendProficiency(ItemClass itemClass, uint32 itemSubclassMask)
Definition Player.cpp:10046
uint32 GetWeaponProficiency() const
Definition Player.h:1378
void AddArmorProficiency(uint32 newflag)
Definition Player.h:1377
void AddWeaponProficiency(uint32 newflag)
Definition Player.h:1376
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
2708{
2710 EffectNULL(effIndex);
2711}
void EffectNULL(SpellEffIndex effIndex)
Definition SpellEffects.cpp:239

References EffectNULL().

◆ EffectPullTowards()

void Spell::EffectPullTowards ( SpellEffIndex  effIndex)
5138{
5140 return;
5141
5142 if (!unitTarget)
5143 return;
5144
5145 Position pos;
5146 if (m_spellInfo->Effects[effIndex].Effect == SPELL_EFFECT_PULL_TOWARDS_DEST)
5147 {
5148 if (m_targets.HasDst())
5149 pos.Relocate(*destTarget);
5150 else
5151 return;
5152 }
5153 else //if (m_spellInfo->Effects[i].Effect == SPELL_EFFECT_PULL_TOWARDS)
5154 {
5155 // Xinef: Increase Z position a little bit, should protect from falling through textures
5157 }
5158
5159 float speedXY = float(m_spellInfo->Effects[effIndex].MiscValue) ? float(m_spellInfo->Effects[effIndex].MiscValue) * 0.1f : 30.f;
5160 float speedZ = unitTarget->GetDistance(pos) / speedXY * 0.5f * Movement::gravity;
5161
5162 unitTarget->GetMotionMaster()->MoveJump(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), speedXY, speedZ);
5163
5164 if (unitTarget->IsPlayer())
5165 {
5166 sScriptMgr->AnticheatSetUnderACKmount(unitTarget->ToPlayer());
5167 }
5168}
@ 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)
5076{
5078 return;
5079
5080 if (!unitTarget)
5081 return;
5082
5083 Player* player = unitTarget->ToPlayer();
5084 if (!player)
5085 {
5086 return;
5087 }
5088
5089 uint32 quest_id = m_spellInfo->Effects[effIndex].MiscValue;
5090
5091 Quest const* quest = sObjectMgr->GetQuestTemplate(quest_id);
5092
5093 if (!quest)
5094 return;
5095
5096 // Player has never done this quest
5097 if (player->GetQuestStatus(quest_id) == QUEST_STATUS_NONE)
5098 return;
5099
5100 // remove all quest entries for 'entry' from quest log
5101 for (uint8 slot = 0; slot < MAX_QUEST_LOG_SIZE; ++slot)
5102 {
5103 uint32 logQuest = player->GetQuestSlotQuestId(slot);
5104 if (logQuest == quest_id)
5105 {
5106 player->SetQuestSlot(slot, 0);
5107
5108 // we ignore unequippable quest items in this case, it's still be equipped
5109 player->TakeQuestSourceItem(logQuest, false);
5110
5111 if (quest->HasFlag(QUEST_FLAGS_FLAGS_PVP))
5112 {
5113 player->pvpInfo.IsHostile = player->pvpInfo.IsInHostileArea || player->HasPvPForcingQuest();
5114 player->UpdatePvPState();
5115 }
5116 }
5117 }
5118
5119 player->RemoveRewardedQuest(quest_id);
5120 player->RemoveActiveQuest(quest_id, false);
5121}
@ 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:2530
void UpdatePvPState()
Definition PlayerUpdates.cpp:1432
uint32 GetQuestSlotQuestId(uint16 slot) const
Definition Player.h:1503
void SetQuestSlot(uint16 slot, uint32 quest_id, uint32 timer=0)
Definition Player.h:1507
PvPInfo pvpInfo
Definition Player.h:1864
bool TakeQuestSourceItem(uint32 questId, bool msg)
Definition PlayerQuest.cpp:1397
void RemoveActiveQuest(uint32 questId, bool update=true)
Definition PlayerQuest.cpp:1530
QuestStatus GetQuestStatus(uint32 quest_id) const
Definition PlayerQuest.cpp:1465
void RemoveRewardedQuest(uint32 questId, bool update=true)
Definition PlayerQuest.cpp:1548
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)
4746{
4748 return;
4749
4750 if (!unitTarget)
4751 return;
4752
4753 Player* player = unitTarget->ToPlayer();
4754 if (!player)
4755 {
4756 return;
4757 }
4758
4759 uint32 questId = m_spellInfo->Effects[effIndex].MiscValue;
4760 if (questId)
4761 {
4762 Quest const* quest = sObjectMgr->GetQuestTemplate(questId);
4763 if (!quest)
4764 return;
4765
4766 uint16 logSlot = player->FindQuestSlot(questId);
4767 if (logSlot < MAX_QUEST_LOG_SIZE)
4768 player->AreaExploredOrEventHappens(questId);
4769 else if (player->CanTakeQuest(quest, false)) // Check if the quest has already been turned in.
4770 player->SetRewardedQuest(questId); // If not, set status to rewarded without broadcasting it to client.
4771 }
4772}
uint16 FindQuestSlot(uint32 quest_id) const
Definition PlayerQuest.cpp:1817
bool CanTakeQuest(Quest const *quest, bool msg)
Definition PlayerQuest.cpp:251
void SetRewardedQuest(uint32 quest_id)
Definition PlayerQuest.cpp:881
void AreaExploredOrEventHappens(uint32 questId)
Definition PlayerQuest.cpp:1826

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

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

◆ EffectQuestStart()

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

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

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)
5923{
5925 return;
5926
5927 if (unitTarget)
5929}
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)
6214{
6216 return;
6217
6218 if (!unitTarget)
6219 return;
6220 // there may be need of specifying casterguid of removed auras
6221 unitTarget->RemoveAurasDueToSpell(m_spellInfo->Effects[effIndex].TriggerSpell);
6222}

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

◆ EffectRenamePet()

void Spell::EffectRenamePet ( SpellEffIndex  effIndex)
6114{
6116 return;
6117
6118 if (!unitTarget || !unitTarget->IsCreature() ||
6120 return;
6121
6123}
@ 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)
4720{
4722 return;
4723
4724 if (!unitTarget)
4725 return;
4726
4727 Player* player = unitTarget->ToPlayer();
4728 if (!player)
4729 {
4730 return;
4731 }
4732
4733 float repChange = static_cast<float>(damage);
4734
4735 uint32 factionId = m_spellInfo->Effects[effIndex].MiscValue;
4736
4737 FactionEntry const* factionEntry = sFactionStore.LookupEntry(factionId);
4738 if (!factionEntry)
4739 return;
4740
4741 repChange = player->CalculateReputationGain(REPUTATION_SOURCE_SPELL, 0, repChange, factionId);
4742 player->GetReputationMgr().ModifyReputation(factionEntry, repChange);
4743}
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:5868
ReputationMgr & GetReputationMgr()
Definition Player.h:2145
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)
4638{
4640 return;
4641
4642 if (!unitTarget)
4643 return;
4644
4645 if (!unitTarget)
4646 return;
4647
4648 Player* target = unitTarget->ToPlayer();
4649 if (!target)
4650 {
4651 return;
4652 }
4653
4654 if (unitTarget->IsAlive() || !unitTarget->IsInWorld())
4655 return;
4656
4657 if (target->isResurrectRequested()) // already have one active request
4658 return;
4659
4660 uint32 health = target->CountPctFromMaxHealth(damage);
4662
4663 ExecuteLogEffectResurrect(effIndex, target);
4664
4666 SendResurrectRequest(target);
4667}
void setResurrectRequestData(ObjectGuid guid, uint32 mapId, float X, float Y, float Z, uint32 health, uint32 mana)
Definition Player.h:1833
bool isResurrectRequested() const
Definition Player.h:1845
void ExecuteLogEffectResurrect(uint8 effIndex, Unit *target)
Definition Spell.cpp:5118
void SendResurrectRequest(Player *target)
Definition Spell.cpp:5180

References CalculatePct(), Unit::CountPctFromMaxHealth(), damage, effectHandleMode, ExecuteLogEffectResurrect(), Object::GetGUID(), WorldLocation::GetMapId(), Unit::GetMaxPower(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), Unit::IsAlive(), Object::IsInWorld(), Player::isResurrectRequested(), m_caster, POWER_MANA, SendResurrectRequest(), Player::setResurrectRequestData(), SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectResurrectNew()

◆ EffectResurrectPet()

void Spell::EffectResurrectPet ( SpellEffIndex  effIndex)
Todo:
: Better to fail Hunter's "Revive Pet" at cast instead of here when casting ends
5214{
5216 return;
5217
5218 if (damage < 0)
5219 return;
5220
5221 Player* player = m_caster->ToPlayer();
5222 if (!player)
5223 {
5224 return;
5225 }
5226
5227 Pet* pet = player->GetPet();
5228 if (!pet)
5229 {
5230 // Position passed to SummonPet is irrelevant with current implementation,
5231 // pet will be relocated without using these coords in Pet::LoadPetFromDB
5232 player->SummonPet(0, 0.0f, 0.0f, 0.0f, 0.0f, SUMMON_PET, 0ms, damage);
5233 return;
5234 }
5235
5237 if (pet->IsAlive())
5238 {
5239 return;
5240 }
5241
5242 // Reposition the pet's corpse before reviving so as not to grab aggro
5243 // We can use a different, more accurate version of GetClosePoint() since we have a pet
5244 float x, y, z; // Will be used later to reposition the pet if we have one
5245 player->GetClosePoint(x, y, z, pet->GetCombatReach(), PET_FOLLOW_DIST, pet->GetFollowAngle());
5246 pet->NearTeleportTo(x, y, z, player->GetOrientation());
5247 pet->Relocate(x, y, z, player->GetOrientation()); // This is needed so SaveStayPosition() will get the proper coords.
5251 pet->ClearUnitState(uint32(UNIT_STATE_ALL_STATE & ~(UNIT_STATE_POSSESSED))); // xinef: just in case
5253 pet->SetDisplayId(pet->GetNativeDisplayId());
5254
5255 // xinef: restore movement
5256 if (auto ci = pet->GetCharmInfo())
5257 {
5258 ci->SetIsAtStay(false);
5259 ci->SetIsFollowing(false);
5260 }
5261
5263}
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:8984
void ReplaceAllDynamicFlags(uint32 flag) override
Definition Unit.h:769
void SetHealth(uint32 val)
Definition Unit.cpp:12341
uint32 GetNativeDisplayId() const
Definition Unit.h:1977
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)
4026{
4028 return;
4029
4030 if (!unitTarget)
4031 return;
4032
4034
4036 {
4037 // stop all pve combat for players outside dungeons, suppress pvp combat
4038 unitTarget->CombatStop(false, false);
4039 }
4040 else
4041 {
4042 // in dungeons (or for nonplayers), reset this unit on all enemies' threat lists
4043 for (auto const& pair : unitTarget->GetThreatMgr().GetThreatenedByMeList())
4044 pair.second->ScaleThreat(0.0f);
4045 }
4046
4047 UnitList targets;
4048 Acore::AnyUnfriendlyUnitInObjectRangeCheck u_check(unitTarget, unitTarget, unitTarget->GetVisibilityRange()); // no VISIBILITY_COMPENSATION, distance is enough
4051 for (UnitList::iterator iter = targets.begin(); iter != targets.end(); ++iter)
4052 {
4053 if (!(*iter)->HasUnitState(UNIT_STATE_CASTING))
4054 continue;
4055
4057 {
4058 if ((*iter)->GetCurrentSpell(i) && (*iter)->GetCurrentSpell(i)->m_targets.GetUnitTargetGUID() == unitTarget->GetGUID())
4059 {
4060 SpellInfo const* si = (*iter)->GetCurrentSpell(i)->GetSpellInfo();
4061 if (si->HasAttribute(SPELL_ATTR6_IGNORE_PHASE_SHIFT) && (*iter)->IsCreature())
4062 {
4063 Creature* c = (*iter)->ToCreature();
4064 if ((!c->IsPet() && c->GetCreatureTemplate()->rank == CREATURE_ELITE_WORLDBOSS) || c->isWorldBoss() || c->IsDungeonBoss())
4065 continue;
4066 }
4067 bool interrupt = false; // pussywizard: skip spells that don't target units, but casted on unit (eg. TARGET_DEST_TARGET_ENEMY)
4068 for (uint8 j = 0; j < MAX_SPELL_EFFECTS; ++j)
4069 if (si->Effects[j].Effect && (si->Effects[j].GetUsedTargetObjectType() == TARGET_OBJECT_TYPE_UNIT || si->Effects[j].GetUsedTargetObjectType() == TARGET_OBJECT_TYPE_UNIT_AND_DEST))
4070 {
4071 // at least one effect truly targets an unit, interrupt the spell
4072 interrupt = true;
4073 break;
4074 }
4075 if (interrupt)
4076 (*iter)->InterruptSpell(CurrentSpellTypes(i), false);
4077 }
4078 }
4079 }
4080
4081 // Xinef: Set last sanctuary time
4083}
#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:7486

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:12291
float ApplyEffectModifiers(SpellInfo const *spellProto, uint8 effect_index, float value) const
Definition Unit.cpp:11562
virtual uint32 GetShieldBlockValue() const =0
void RemoveAuraFromStack(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition Unit.cpp:5187
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)
3823{
3825 return;
3826
3828
3830 {
3832 {
3833 switch (m_spellInfo->Id)
3834 {
3835 // Shadow Flame (All script effects, not just end ones to prevent player from dodging the last triggered spell)
3836 case 22539:
3837 case 22972:
3838 case 22975:
3839 case 22976:
3840 case 22977:
3841 case 22978:
3842 case 22979:
3843 case 22980:
3844 case 22981:
3845 case 22982:
3846 case 22983:
3847 case 22984:
3848 case 22985:
3849 {
3850 if (!unitTarget || !unitTarget->IsAlive())
3851 return;
3852
3853 // Onyxia Scale Cloak
3854 if (unitTarget->HasAura(22683))
3855 return;
3856
3857 // Shadow Flame
3858 m_caster->CastSpell(unitTarget, 22682, true);
3859 return;
3860 }
3861 // Plant Warmaul Ogre Banner
3862 case 32307:
3863 if (Player* caster = m_caster->ToPlayer())
3864 {
3865 caster->RewardPlayerAndGroupAtEvent(18388, unitTarget);
3866 if (Creature* target = unitTarget->ToCreature())
3867 {
3868 target->setDeathState(DeathState::Corpse);
3869 target->RemoveCorpse();
3870 }
3871 }
3872 break;
3873 // SOTA defender teleport
3874 case 54640:
3875 {
3876 if (Player* player = unitTarget->ToPlayer())
3877 if (player->GetBattleground() && player->GetBattleground()->GetBgTypeID(true) == BATTLEGROUND_SA)
3878 {
3879 if (GameObject* dportal = player->FindNearestGameObject(192819, 10.0f))
3880 {
3881 BattlegroundSA* bg = ((BattlegroundSA*)player->GetBattleground());
3882 bg->DefendersPortalTeleport(dportal, player);
3883 }
3884 }
3885 return;
3886 }
3887 /*// Mug Transformation
3888 case 41931:
3889 {
3890 if (!m_caster->IsPlayer())
3891 return;
3892
3893 uint8 bag = 19;
3894 uint8 slot = 0;
3895 Item* item = nullptr;
3896
3897 while (bag) // 256 = 0 due to var type
3898 {
3899 item = m_caster->ToPlayer()->GetItemByPos(bag, slot);
3900 if (item && item->GetEntry() == 38587)
3901 break;
3902
3903 ++slot;
3904 if (slot == 39)
3905 {
3906 slot = 0;
3907 ++bag;
3908 }
3909 }
3910 if (bag)
3911 {
3912 if (m_caster->ToPlayer()->GetItemByPos(bag, slot)->GetCount() == 1) m_caster->ToPlayer()->RemoveItem(bag, slot, true);
3913 else m_caster->ToPlayer()->GetItemByPos(bag, slot)->SetCount(m_caster->ToPlayer()->GetItemByPos(bag, slot)->GetCount()-1);
3914 // Spell 42518 (Braufest - Gratisprobe des Braufest herstellen)
3915 m_caster->CastSpell(m_caster, 42518, true);
3916 return;
3917 }
3918 break;
3919 }*/
3920 // Roll Dice - Decahedral Dwarven Dice
3921 case 47770:
3922 {
3923 char buf[128];
3924 const char* gender = "his";
3925 if (m_caster->getGender() > 0)
3926 gender = "her";
3927 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));
3928 m_caster->TextEmote(buf);
3929 break;
3930 }
3931 case 52173: // Coyote Spirit Despawn
3932 case 60243: // Blood Parrot Despawn
3935 return;
3936 case 57347: // Retrieving (Wintergrasp RP-GG pickup spell)
3937 {
3939 return;
3940
3942
3943 return;
3944 }
3945 case 57349: // Drop RP-GG (Wintergrasp RP-GG at death drop spell)
3946 {
3947 if (!m_caster->IsPlayer())
3948 return;
3949
3950 // Delete item from inventory at death
3952
3953 return;
3954 }
3955 case 58418: // Portal to Orgrimmar
3956 case 58420: // Portal to Stormwind
3957 {
3958 if (!unitTarget || !unitTarget->IsPlayer() || effIndex != 0)
3959 return;
3960
3961 uint32 spellID = m_spellInfo->Effects[EFFECT_0].CalcValue();
3962 uint32 questID = m_spellInfo->Effects[EFFECT_1].CalcValue();
3963
3965 unitTarget->CastSpell(unitTarget, spellID, true);
3966
3967 return;
3968 }
3969 case 61263: // for item Intravenous Healing Potion (44698)
3970 {
3971 if (!m_caster || !unitTarget)
3972 return;
3973
3974 m_caster->CastSpell(m_caster, 61267, true);
3975 m_caster->CastSpell(m_caster, 61268, true);
3976 return;
3977 }
3978 }
3979 break;
3980 }
3981 case SPELLFAMILY_ROGUE:
3982 {
3983 switch (m_spellInfo->Id)
3984 {
3985 // Master of Subtlety
3986 case 31666:
3987 {
3988 if (!unitTarget)
3989 return;
3990
3991 Aura* mos = unitTarget->GetAura(31665);
3992 if (mos)
3993 {
3994 mos->SetMaxDuration(6000);
3995 mos->SetDuration(6000, true);
3996 }
3997
3998 break;
3999 }
4000 // Overkill
4001 case 58428:
4002 {
4003 if (!unitTarget)
4004 return;
4005
4006 Aura* overkill = unitTarget->GetAura(58427);
4007 if (overkill)
4008 {
4009 overkill->SetMaxDuration(20000);
4010 overkill->SetDuration(20000, true);
4011 }
4012
4013 break;
4014 }
4015 }
4016 break;
4017 }
4018 }
4019
4020 // normal DB scripted effect
4021 LOG_DEBUG("spells.aura", "Spell ScriptStart spellid {} in EffectScriptEffect({})", m_spellInfo->Id, effIndex);
4023}
@ 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:2186
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:17185
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)
4848{
4850 return;
4851
4852 if (!m_caster || m_caster->IsAlive())
4853 return;
4854 if (!m_caster->IsPlayer())
4855 return;
4856 if (!m_caster->IsInWorld())
4857 return;
4858
4859 uint32 health = 0;
4860 uint32 mana = 0;
4861
4862 // flat case
4863 if (damage < 0)
4864 {
4865 health = uint32(-damage);
4866 mana = m_spellInfo->Effects[effIndex].MiscValue;
4867 }
4868 // percent case
4869 else
4870 {
4874 }
4875
4876 Player* player = m_caster->ToPlayer();
4877 player->ResurrectPlayer(0.0f);
4878
4879 player->SetHealth(health);
4880 player->SetPower(POWER_MANA, mana);
4881 player->SetPower(POWER_RAGE, 0);
4882 player->SetPower(POWER_ENERGY, player->GetMaxPower(POWER_ENERGY));
4883
4884 player->SpawnCorpseBones();
4885}
@ POWER_RAGE
Definition SharedDefines.h:258
void SpawnCorpseBones(bool triggerSave=true)
Definition Player.cpp:4604
void ResurrectPlayer(float restore_percent, bool applySickness=false)
Definition Player.cpp:4386
void SetPower(Powers power, uint32 val, bool withPowerUpdate=true, bool fromRegenerate=false)
Definition Unit.cpp:12429

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)
5124{
5126 return;
5127
5128 if (!unitTarget)
5129 return;
5130
5131 if (Player* player = unitTarget->ToPlayer())
5132 {
5133 player->ActivateTaxiPathTo(m_spellInfo->Effects[effIndex].MiscValue, m_spellInfo->Id);
5134 }
5135}

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

◆ EffectSkill()

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

References effectHandleMode, LOG_DEBUG, and SPELL_EFFECT_HANDLE_HIT.

◆ EffectSkinning()

void Spell::EffectSkinning ( SpellEffIndex  effIndex)
4888{
4890 return;
4891
4892 if (!unitTarget->IsCreature())
4893 return;
4894 if (!m_caster->IsPlayer())
4895 return;
4896
4897 Creature* creature = unitTarget->ToCreature();
4898 int32 targetLevel = creature->GetLevel();
4899
4900 uint32 skill = creature->GetCreatureTemplate()->GetRequiredLootSkill();
4901
4905
4906 int32 reqValue = targetLevel < 10 ? 0 : targetLevel < 20 ? (targetLevel - 10) * 10 : targetLevel * 5;
4907
4908 int32 skillValue = m_caster->ToPlayer()->GetPureSkillValue(skill);
4909
4910 // Double chances for elites
4911 m_caster->ToPlayer()->UpdateGatherSkill(skill, skillValue, reqValue, creature->isElite() ? 2 : 1);
4912}
@ 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)
5589{
5591 return;
5592
5593 LOG_DEBUG("spells.aura", "Effect: SkinPlayerCorpse");
5594 if ((!m_caster->IsPlayer()) || (!unitTarget->IsPlayer()) || (unitTarget->IsAlive()))
5595 return;
5596
5598
5599 // We have a corpse object as the target.
5600 // This target was deleted in RemovedInsignia() -> ConvertCorpseToBones().
5602}
void RemovedInsignia(Player *looterPlr)
Definition Player.cpp:7774
void RemoveObjectTarget()
Definition Spell.cpp:320

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)
6151{
6153 return;
6154
6155 if (!unitTarget)
6156 return;
6157
6158 if (Player* player = unitTarget->ToPlayer())
6159 {
6160 player->UpdateSpecCount(damage);
6161 }
6162}

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

◆ EffectSpiritHeal()

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

References effectHandleMode, and SPELL_EFFECT_HANDLE_HIT_TARGET.

◆ EffectStealBeneficialBuff()

void Spell::EffectStealBeneficialBuff ( SpellEffIndex  effIndex)
5605{
5607 return;
5608
5609 LOG_DEBUG("spells.aura", "Effect: StealBeneficialBuff");
5610
5611 if (!unitTarget || unitTarget == m_caster) // can't steal from self
5612 return;
5613
5614 DispelChargesList steal_list;
5615
5616 // Create dispel mask by dispel type
5617 uint32 dispelMask = SpellInfo::GetDispelMask(DispelType(m_spellInfo->Effects[effIndex].MiscValue));
5618 Unit::AuraMap const& auras = unitTarget->GetOwnedAuras();
5619 for (Unit::AuraMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
5620 {
5621 Aura* aura = itr->second;
5623 if (!aurApp)
5624 continue;
5625
5626 if ((aura->GetSpellInfo()->GetDispelMask()) & dispelMask)
5627 {
5628 // Need check for passive? this
5629 if (!aurApp->IsPositive() || aura->IsPassive() || aura->GetSpellInfo()->HasAttribute(SPELL_ATTR4_CANNOT_BE_STOLEN))
5630 continue;
5631
5632 // The charges / stack amounts don't count towards the total number of auras that can be dispelled.
5633 // Ie: A dispel on a target with 5 stacks of Winters Chill and a Polymorph has 1 / (1 + 1) -> 50% chance to dispell
5634 // Polymorph instead of 1 / (5 + 1) -> 16%.
5635 bool dispel_charges = aura->GetSpellInfo()->HasAttribute(SPELL_ATTR7_DISPEL_REMOVES_CHARGES);
5636 uint8 charges = dispel_charges ? aura->GetCharges() : aura->GetStackAmount();
5637 if (charges > 0)
5638 steal_list.push_back(std::make_pair(aura, charges));
5639 }
5640 }
5641
5642 if (steal_list.empty())
5643 return;
5644
5645 // Ok if exist some buffs for dispel try dispel it
5646 uint32 failCount = 0;
5647 DispelList success_list;
5648 WorldPacket dataFail(SMSG_DISPEL_FAILED, 8 + 8 + 4 + 4 + damage * 4);
5649 // dispel N = damage buffs (or while exist buffs for dispel)
5650 for (int32 count = 0; count < damage && !steal_list.empty();)
5651 {
5652 // Random select buff for dispel
5653 DispelChargesList::iterator itr = steal_list.begin();
5654 std::advance(itr, urand(0, steal_list.size() - 1));
5655
5656 int32 chance = itr->first->CalcDispelChance(unitTarget, !unitTarget->IsFriendlyTo(m_caster));
5657 // 2.4.3 Patch Notes: "Dispel effects will no longer attempt to remove effects that have 100% dispel resistance."
5658 if (!chance)
5659 {
5660 steal_list.erase(itr);
5661 continue;
5662 }
5663 else
5664 {
5665 if (roll_chance_i(chance))
5666 {
5667 success_list.push_back(std::make_pair(itr->first->GetId(), itr->first->GetCasterGUID()));
5668 --itr->second;
5669 if (itr->second <= 0)
5670 steal_list.erase(itr);
5671 }
5672 else
5673 {
5674 if (!failCount)
5675 {
5676 // Failed to dispell
5677 dataFail << m_caster->GetGUID(); // Caster GUID
5678 dataFail << unitTarget->GetGUID(); // Victim GUID
5679 dataFail << uint32(m_spellInfo->Id); // dispel spell id
5680 }
5681 ++failCount;
5682 dataFail << uint32(itr->first->GetId()); // Spell Id
5683 }
5684 ++count;
5685 }
5686 }
5687
5688 if (failCount)
5689 m_caster->SendMessageToSet(&dataFail, true);
5690
5691 if (success_list.empty())
5692 return;
5693
5694 WorldPacket dataSuccess(SMSG_SPELLSTEALLOG, 8 + 8 + 4 + 1 + 4 + damage * 5);
5695 dataSuccess << unitTarget->GetPackGUID(); // Victim GUID
5696 dataSuccess << m_caster->GetPackGUID(); // Caster GUID
5697 dataSuccess << uint32(m_spellInfo->Id); // dispel spell id
5698 dataSuccess << uint8(0); // not used
5699 dataSuccess << uint32(success_list.size()); // count
5700 for (DispelList::iterator itr = success_list.begin(); itr != success_list.end(); ++itr)
5701 {
5702 dataSuccess << uint32(itr->first); // Spell Id
5703 dataSuccess << uint8(0); // 0 - steals !=0 transfers
5704 unitTarget->RemoveAurasDueToSpellBySteal(itr->first, itr->second, m_caster);
5705 }
5706 m_caster->SendMessageToSet(&dataSuccess, true);
5707}
@ 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:5268
@ 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)
4178{
4180 return;
4181
4182 if (!m_caster->IsPlayer())
4183 return;
4184
4185 Player* target = m_caster->ToPlayer();
4186 if (target->IsInFlight())
4187 return;
4188
4189 // xinef: if player is dead - teleport to graveyard
4190 if (!target->IsAlive())
4191 {
4192 if (target->HasPreventResurectionAura())
4193 return;
4194
4195 // xinef: player is in corpse
4196 if (!target->HasPlayerFlag(PLAYER_FLAGS_GHOST))
4197 target->BuildPlayerRepop();
4198 target->RepopAtGraveyard();
4199 return;
4200 }
4201
4202 // xinef: no hearthstone in bag or on cooldown
4203 Item* hearthStone = target->GetItemByEntry(6948);
4204 if (!hearthStone || target->HasSpellCooldown(8690))
4205 {
4206 float o = rand_norm() * 2 * M_PI;
4207 Position pos = *target;
4208 target->MovePositionToFirstCollision(pos, 5.0f, o);
4209 target->NearTeleportTo(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), target->GetOrientation());
4210 return;
4211 }
4212
4213 // xinef: we have hearthstone not on cooldown, just use it
4215}
@ PLAYER_FLAGS_GHOST
Definition Player.h:463
double rand_norm()
Definition Random.cpp:85
void RepopAtGraveyard()
Definition Player.cpp:4836
void BuildPlayerRepop()
Definition Player.cpp:4338
bool HasPreventResurectionAura() const
Definition Unit.h:1808
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:1087
uint32 GetEnchantmentDuration(EnchantmentSlot slot) const
Definition Item.h:305
uint16 GetPos() const
Definition Item.h:285
uint32 GetEnchantmentCharges(EnchantmentSlot slot) const
Definition Item.h:306
uint8 GetBagSlot() const
Definition Item.cpp:784
static bool IsEquipmentPos(uint16 pos)
Definition Player.h:1278
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:1352
InventoryResult CanStoreItem(uint8 bag, uint8 slot, ItemPosCountVec &dest, Item *pItem, bool swap=false) const
Definition Player.h:1303
void UpdateEnchantmentDurations()
Definition PlayerStorage.cpp:4797
Item * StoreItem(ItemPosCountVec const &pos, Item *pItem, bool update)
Definition PlayerStorage.cpp:2652
void DestroyItem(uint8 bag, uint8 slot, bool update)
Definition PlayerStorage.cpp:3090
static bool IsInventoryPos(uint16 pos)
Definition Player.h:1276
void AutoUnequipOffhandIfNeed(bool force=false)
Definition Player.cpp:12468
Item * EquipItem(uint16 pos, Item *pItem, bool update)
Definition PlayerStorage.cpp:2799
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:1870
static bool IsBankPos(uint16 pos)
Definition Player.h:1281

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

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)
3772{
3774 return;
3775
3776 uint32 gameobject_id = m_spellInfo->Effects[effIndex].MiscValue;
3777
3778 GameObject* pGameObj = sObjectMgr->IsGameObjectStaticTransport(gameobject_id) ? new StaticTransport() : new GameObject();
3779
3780 WorldObject* target = focusObject;
3781 if (!target)
3782 target = m_caster;
3783
3784 float x, y, z;
3785 if (m_targets.HasDst())
3786 destTarget->GetPosition(x, y, z);
3787 else
3789
3790 Map* map = target->GetMap();
3791
3792 G3D::Quat rotation = G3D::Quat::fromAxisAngleRotation(G3D::Vector3::unitZ(), target->GetOrientation());
3793 if (!pGameObj->Create(map->GenerateLowGuid<HighGuid::GameObject>(), gameobject_id, map, m_caster->GetPhaseMask(), x, y, z, target->GetOrientation(), rotation, 100, GO_STATE_READY))
3794 {
3795 delete pGameObj;
3796 return;
3797 }
3798
3799 int32 duration = m_spellInfo->GetDuration();
3800
3801 pGameObj->SetRespawnTime(duration > 0 ? duration / IN_MILLISECONDS : 0);
3802 pGameObj->SetSpellId(m_spellInfo->Id);
3803
3804 ExecuteLogEffectSummonObject(effIndex, pGameObj);
3805
3806 // Wild object not have owner and check clickable by players
3807 map->AddToMap(pGameObj, true);
3808
3809 if (pGameObj->GetGoType() == GAMEOBJECT_TYPE_FLAGDROP)
3810 if (Player* player = m_caster->ToPlayer())
3811 if (Battleground* bg = player->GetBattleground())
3812 bg->SetDroppedFlagGUID(pGameObj->GetGUID(), player->GetTeamId() == TEAM_ALLIANCE ? TEAM_HORDE : TEAM_ALLIANCE);
3813
3814 if (GameObject* linkedTrap = pGameObj->GetLinkedTrap())
3815 {
3816 linkedTrap->SetRespawnTime(duration > 0 ? duration/IN_MILLISECONDS :0);
3817 linkedTrap->SetSpellId(m_spellInfo->Id);
3818 ExecuteLogEffectSummonObject(effIndex, linkedTrap);
3819 }
3820}
@ 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)
3190{
3192 return;
3193
3194 if (!m_originalCaster)
3195 return;
3196
3197 uint32 petentry = m_spellInfo->Effects[effIndex].MiscValue;
3198 int32 duration = m_spellInfo->GetDuration();
3199
3200 if (Player* modOwner = m_originalCaster->GetSpellModOwner())
3201 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_DURATION, duration);
3202
3203 Player* owner = m_originalCaster->ToPlayer();
3204 if (!owner && m_originalCaster->ToCreature()->IsTotem())
3206
3207 if (!owner)
3208 {
3209 SummonPropertiesEntry const* properties = sSummonPropertiesStore.LookupEntry(67);
3210 if (properties)
3211 {
3212 // Xinef: unsummon old guardian
3213 if (Guardian* oldPet = m_originalCaster->GetGuardianPet())
3214 oldPet->UnSummon();
3215 SummonGuardian(effIndex, petentry, properties, 1, false);
3216 }
3217 return;
3218 }
3219
3220 Pet* OldSummon = owner->GetPet();
3221
3222 // if pet requested type already exist
3223 if (OldSummon)
3224 {
3225 if (petentry == 0 || OldSummon->GetEntry() == petentry)
3226 {
3227 // pet in corpse state can't be summoned
3228 if (OldSummon->isDead())
3229 return;
3230
3231 ASSERT(OldSummon->GetMap() == owner->GetMap());
3232
3233 //OldSummon->GetMap()->Remove(OldSummon->ToCreature(), false);
3234
3235 float px, py, pz;
3236 owner->GetClosePoint(px, py, pz, OldSummon->GetObjectSize());
3237
3238 OldSummon->NearTeleportTo(px, py, pz, OldSummon->GetOrientation());
3239 OldSummon->UpdateObjectVisibility();
3240
3241 OldSummon->SetHealth(OldSummon->GetMaxHealth());
3242 OldSummon->SetPower(OldSummon->getPowerType(), OldSummon->GetMaxPower(OldSummon->getPowerType()));
3243 // notify player
3244 for (CreatureSpellCooldowns::const_iterator itr = OldSummon->m_CreatureSpellCooldowns.begin(); itr != OldSummon->m_CreatureSpellCooldowns.end(); ++itr)
3245 owner->SendClearCooldown(itr->first, OldSummon);
3246
3247 // actually clear cooldowns
3248 OldSummon->m_CreatureSpellCooldowns.clear();
3249 Unit::AuraApplicationMap& myAuras = OldSummon->GetAppliedAuras();
3250 for (Unit::AuraApplicationMap::iterator i = myAuras.begin(); i != myAuras.end();)
3251 {
3252 Aura const* aura = i->second->GetBase();
3253 if (!aura->IsPassive() && !OldSummon->IsPetAura(aura) && aura->CanBeSentToClient())
3254 OldSummon->RemoveAura(i);
3255 else
3256 ++i;
3257 }
3258 return;
3259 }
3260
3261 if (owner->IsPlayer())
3262 owner->ToPlayer()->RemovePet(OldSummon, PET_SAVE_NOT_IN_SLOT, false);
3263 else
3264 return;
3265 }
3266
3267 float x, y, z;
3268 owner->GetClosePoint(x, y, z, owner->GetObjectSize());
3269 Pet* pet = owner->SummonPet(petentry, x, y, z, owner->GetOrientation(), SUMMON_PET);
3270 if (!pet)
3271 return;
3272
3273 if (m_caster->IsCreature())
3274 {
3275 if (m_caster->ToCreature()->IsTotem())
3277 else
3279 }
3280
3282
3283 // Reset cooldowns
3285 {
3286 pet->m_CreatureSpellCooldowns.clear();
3287 owner->PetSpellInitialize();
3288 }
3289
3290 // Set health to max if new pet is summoned
3291 // in this function old pet is saved with current health eg. 20% and new one is loaded from db with same amount
3292 // pet should have full health
3293 pet->SetHealth(pet->GetMaxHealth());
3294
3295 // generate new name for summon pet
3296 std::string new_name = sObjectMgr->GeneratePetName(petentry);
3297 if (!new_name.empty())
3298 pet->SetName(new_name);
3299
3300 // ExecuteLogEffectSummonObject(effectInfo->EffectIndex, pet);
3301}
@ 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:14802
void SummonGuardian(uint32 i, uint32 entry, SummonPropertiesEntry const *properties, uint32 numSummons, bool personalSpawn)
Definition SpellEffects.cpp:5973
bool IsPetAura(Aura const *aura)
Definition Unit.cpp:13737
void UpdateObjectVisibility(bool forced=true, bool fromUpdate=false) override
Definition Unit.cpp:15372
Powers getPowerType() const
Definition Unit.h:1131
bool isDead() const
Definition Unit.h:1796
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)
4218{
4219 // workaround - this effect should not use target map
4221 return;
4222
4223 if (!unitTarget)
4224 return;
4225
4226 Player* player = unitTarget->ToPlayer();
4227 if (!player)
4228 {
4229 return;
4230 }
4231
4232 // Evil Twin (ignore player summon, but hide this for summoner)
4233 // Xinef: Unit Target may be on other map!!!, Need workaround
4234 if (unitTarget->HasAura(23445))
4235 return;
4236
4237 float x, y, z;
4238 m_caster->GetPosition(x, y, z);
4239
4240 player->SetSummonPoint(m_caster->GetMapId(), x, y, z);
4241
4242 WorldPacket data(SMSG_SUMMON_REQUEST, 8 + 4 + 4);
4243 data << m_caster->GetGUID(); // summoner guid
4244 data << uint32(m_caster->GetZoneId()); // summoner zone
4245 data << uint32(MAX_PLAYER_SUMMON_DELAY * IN_MILLISECONDS); // auto decline after msecs
4246 player->SendDirectMessage(&data);
4247}
#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:16389
@ 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)
6345{
6347 return;
6348
6349 if (!m_caster->IsPlayer())
6350 return;
6351
6352 if (!unitTarget)
6353 return;
6354
6355 Player* player = unitTarget->ToPlayer();
6356 if (!player)
6357 {
6358 return;
6359 }
6360
6361 float x, y, z;
6362 m_caster->GetPosition(x, y, z);
6364 WorldPacket data(SMSG_SUMMON_REQUEST, 8 + 4 + 4);
6365 data << m_caster->GetGUID();
6366 data << uint32(m_caster->GetZoneId());
6367 data << uint32(MAX_PLAYER_SUMMON_DELAY * IN_MILLISECONDS); // auto decline after msecs
6368 player->SendDirectMessage(&data);
6369}

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:1497
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:16456
void SetFaction(uint32 faction)
Definition Unit.cpp:7073
void SetOwnerGUID(ObjectGuid owner)
Definition Unit.cpp:7672
uint32 HasUnitTypeMask(uint32 mask) const
Definition Unit.h:741
void SetMaxHealth(uint32 val)
Definition Unit.cpp:12391
void SetCreatorGUID(ObjectGuid creator)
Definition Unit.h:716
void ReplaceAllNpcFlags(NPCFlags flags)
Definition Unit.h:766
void RemoveAllMinionsByEntry(uint32 entry)
Definition Unit.cpp:7962
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)
3134{
3136 return;
3137
3138 if (m_caster->GetPetGUID())
3139 return;
3140
3141 if (!unitTarget)
3142 return;
3143
3144 if (!unitTarget->IsCreature())
3145 return;
3146
3147 Creature* creatureTarget = unitTarget->ToCreature();
3148
3149 if (creatureTarget->IsPet())
3150 return;
3151
3153 return;
3154
3155 // cast finish successfully
3156 //SendChannelUpdate(0);
3157 finish();
3158
3159 Pet* pet = m_caster->CreateTamedPetFrom(creatureTarget, m_spellInfo->Id);
3160 if (!pet) // in very specific state like near world end/etc.
3161 return;
3162
3163 // "kill" original creature
3164 creatureTarget->DespawnOrUnsummon();
3165
3166 uint8 level = (creatureTarget->GetLevel() < (m_caster->GetLevel() - 5)) ? (m_caster->GetLevel() - 5) : creatureTarget->GetLevel();
3167
3168 // prepare visual effect for levelup
3169 pet->SetUInt32Value(UNIT_FIELD_LEVEL, level - 1);
3170
3171 // add to world
3172 pet->GetMap()->AddToMap(pet->ToCreature(), true);
3173
3174 // visual effect for levelup
3175 pet->SetUInt32Value(UNIT_FIELD_LEVEL, level);
3176
3177 // caster have pet now
3178 m_caster->SetMinion(pet, true);
3179
3180 pet->InitTalentForLevel();
3181
3182 if (m_caster->IsPlayer())
3183 {
3186 }
3187}
@ 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)
3330{
3332 return;
3333
3334 if (!unitTarget)
3335 return;
3336
3337 // xinef: Hand of Reckoning, cast before checking canhavethreatlist. fixes damage against pets
3338 if (m_spellInfo->Id == 62124 && unitTarget->GetVictim() != m_caster)
3339 m_caster->CastSpell(unitTarget, 67485, true);
3340
3342 {
3344 return;
3345 }
3346
3348 if (mgr.GetCurrentVictim() == m_caster)
3349 {
3351 return;
3352 }
3353
3354 if (!mgr.IsThreatListEmpty())
3356}
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:11420

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:2128
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:1926
void TeleportVehicle(float x, float y, float z, float ang)
Definition Vehicle.cpp:588

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)
3696{
3698 return;
3699
3700 if (!unitTarget || !unitTarget->IsAlive() || !m_caster->IsAlive())
3701 return;
3702
3703 // xinef: skip if target cannot have threat list or caster is friendly (ghoul leap)
3705 return;
3706
3707 // SPELL_EFFECT_THREAT adds flat threat that should not be modified by threat reduction
3709}
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)
5907{
5909 return;
5910
5911 if (m_caster->IsPlayer())
5912 {
5913 if (Aura* aur = m_caster->GetAura(49152))
5914 aur->RecalculateAmountOfEffects();
5915 else
5916 m_caster->CastSpell(unitTarget, 49152, true); // damage reduction
5917
5919 }
5920}
void SetCanTitanGrip(bool value)
Definition Player.cpp:13189

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)
2846{
2848 return;
2849
2850 if (!m_caster->IsPlayer())
2851 return;
2852 // uint32 skillid = m_spellInfo->Effects[i].MiscValue;
2853 // uint16 skillmax = unitTarget->ToPlayer()->(skillid);
2854 // m_caster->ToPlayer()->SetSkill(skillid, skillval?skillval:1, skillmax+75);
2855}

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

◆ EffectTransmitted()

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

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

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

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 
)
5095{
5096 InitEffectExecuteData(effIndex);
5097 *m_effectExecuteData[effIndex] << uint32(entry);
5098}
void InitEffectExecuteData(uint8 effIndex)
Definition Spell.cpp:8511

References InitEffectExecuteData(), and m_effectExecuteData.

Referenced by EffectCreateItem().

◆ ExecuteLogEffectDestroyItem()

void Spell::ExecuteLogEffectDestroyItem ( uint8  effIndex,
uint32  entry 
)
5101{
5102 InitEffectExecuteData(effIndex);
5103 *m_effectExecuteData[effIndex] << uint32(entry);
5104}

References InitEffectExecuteData(), and m_effectExecuteData.

Referenced by EffectFeedPet().

◆ ExecuteLogEffectDurabilityDamage()

void Spell::ExecuteLogEffectDurabilityDamage ( uint8  effIndex,
Unit victim,
int32  itemId,
int32  slot 
)
5081{
5082 InitEffectExecuteData(effIndex);
5083 *m_effectExecuteData[effIndex] << victim->GetPackGUID();
5084 *m_effectExecuteData[effIndex] << int32(itemId);
5085 *m_effectExecuteData[effIndex] << int32(slot);
5086}

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

Referenced by EffectDurabilityDamage().

◆ ExecuteLogEffectExtraAttacks()

void Spell::ExecuteLogEffectExtraAttacks ( uint8  effIndex,
Unit victim,
uint32  attCount 
)
5067{
5068 InitEffectExecuteData(effIndex);
5069 *m_effectExecuteData[effIndex] << victim->GetPackGUID();
5070 *m_effectExecuteData[effIndex] << uint32(attCount);
5071}

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

Referenced by EffectAddExtraAttacks().

◆ ExecuteLogEffectInterruptCast()

void Spell::ExecuteLogEffectInterruptCast ( uint8  effIndex,
Unit victim,
uint32  spellId 
)
5074{
5075 InitEffectExecuteData(effIndex);
5076 *m_effectExecuteData[effIndex] << victim->GetPackGUID();
5077 *m_effectExecuteData[effIndex] << uint32(spellId);
5078}

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

Referenced by EffectInterruptCast().

◆ ExecuteLogEffectOpenLock()

void Spell::ExecuteLogEffectOpenLock ( uint8  effIndex,
Object obj 
)
5089{
5090 InitEffectExecuteData(effIndex);
5091 *m_effectExecuteData[effIndex] << obj->GetPackGUID();
5092}

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

Referenced by EffectOpenLock().

◆ ExecuteLogEffectResurrect()

void Spell::ExecuteLogEffectResurrect ( uint8  effIndex,
Unit target 
)
5119{
5120 InitEffectExecuteData(effIndex);
5121 *m_effectExecuteData[effIndex] << target->GetPackGUID();
5122}

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 
)
5058{
5059 InitEffectExecuteData(effIndex);
5060 *m_effectExecuteData[effIndex] << target->GetPackGUID();
5061 *m_effectExecuteData[effIndex] << uint32(powerTaken);
5062 *m_effectExecuteData[effIndex] << uint32(PowerType);
5063 *m_effectExecuteData[effIndex] << float(gainMultiplier);
5064}

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 
)
5113{
5114 InitEffectExecuteData(effIndex);
5115 *m_effectExecuteData[effIndex] << obj->GetPackGUID();
5116}

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

Referenced by EffectDismissPet().

◆ finish()

void Spell::finish ( bool  ok = true)
4432{
4433 if (!m_caster)
4434 return;
4435
4437 return;
4439
4440 if (m_spellInfo->IsChanneled())
4442
4445
4446 // Unsummon summon as possessed creatures on spell cancel
4448 {
4449 if (Unit* charm = m_caster->GetCharm())
4450 if (charm->IsCreature()
4451 && charm->ToCreature()->HasUnitTypeMask(UNIT_MASK_PUPPET)
4452 && charm->GetUInt32Value(UNIT_CREATED_BY_SPELL) == m_spellInfo->Id)
4453 ((Puppet*)charm)->UnSummon();
4454 }
4455
4456 if (Creature* creatureCaster = m_caster->ToCreature())
4457 creatureCaster->ReleaseFocus(this);
4458
4459 if (ok)
4460 {
4463 }
4464 else
4465 {
4466 if (m_caster->IsPlayer())
4467 {
4468 // Xinef: Restore spell mods in case of fail cast
4470
4471 // Xinef: Reset cooldown event in case of fail cast
4474 }
4475
4476 return;
4477 }
4478
4479 // pussywizard:
4482
4484 {
4485 // Unsummon statue
4487 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spell);
4488 if (spellInfo && spellInfo->SpellIconID == 2056)
4489 {
4490 LOG_DEBUG("spells.aura", "Statue {} is unsummoned in spell {} finish", m_caster->GetGUID().ToString(), m_spellInfo->Id);
4492 return;
4493 }
4494 }
4495
4496 // potions disabled by client, send event "not in combat" if need
4499
4500 // Take mods after trigger spell (needed for 14177 to affect 48664)
4501 // mods are taken only on succesfull cast and independantly from targets of the spell
4502 if (Player* player = m_caster->GetSpellModOwner())
4503 player->RemoveSpellMods(this);
4504
4505 // xinef: clear reactive auras states after spell cast
4508
4509 // Stop Attack for some spells
4512}
@ 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:2834
void UpdatePotionCooldown(Spell *spell=nullptr)
Definition PlayerUpdates.cpp:1552
Definition TemporarySummon.h:125
virtual void setDeathState(DeathState s, bool despawn=false)
Definition Unit.cpp:11361
void UpdateInterruptMask()
Definition Unit.cpp:886
void ModifyAuraState(AuraStateType flag, bool apply)
Definition Unit.cpp:7596
bool AttackStop()
Force the unit to stop attacking. This will clear UNIT_STATE_MELEE_ATTACKING, Interrupt current spell...
Definition Unit.cpp:7453

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
8507{
8509}
void SendLogExecute()
Definition Spell.cpp:5023

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
8970{
8971 std::stringstream sstr;
8972 sstr << std::boolalpha
8973 << "Id: " << GetSpellInfo()->Id << " OriginalCaster: " << m_originalCasterGUID.ToString()
8974 << " State: " << getState();
8975 return sstr.str();
8976}

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
7876{
7878}
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 
)
2037{
2038 // this function selects which containers need to be searched for spell target
2040
2041 // filter searchers based on searched object type
2042 switch (objType)
2043 {
2050 break;
2054 break;
2055 default:
2056 break;
2057 }
2059 retMask &= ~GRID_MAP_TYPE_MASK_CORPSE;
2063 retMask &= GRID_MAP_TYPE_MASK_PLAYER;
2065 retMask &= ~GRID_MAP_TYPE_MASK_PLAYER;
2066
2067 if (condList)
2068 retMask &= sConditionMgr->GetSearcherTypeMaskForConditionList(*condList);
2069 return retMask;
2070}
@ 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)
4118{
4119 if (!UpdatePointers())
4120 {
4121 // finish the spell if UpdatePointers() returned false, something wrong happened there
4122 finish(false);
4123 return 0;
4124 }
4125
4126 Player* modOwner = m_caster->GetSpellModOwner();
4127 if (modOwner)
4128 modOwner->SetSpellModTakingSpell(this, true);
4129
4130 uint64 next_time = m_delayTrajectory;
4131
4133
4134 if (!m_immediateHandled && m_delayTrajectory <= t_offset)
4135 {
4137 m_immediateHandled = true;
4139 next_time = 0;
4140 }
4141
4142 bool single_missile = (m_targets.HasDst());
4143
4144 // 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)
4145 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
4146 {
4147 if (ihit->processed == false)
4148 {
4149 if (single_missile || ihit->timeDelay <= t_offset)
4150 {
4151 ihit->timeDelay = t_offset;
4152 DoAllEffectOnTarget(&(*ihit));
4153 }
4154 else if (next_time == 0 || ihit->timeDelay < next_time)
4155 next_time = ihit->timeDelay;
4156 }
4157 }
4158
4159 // now recheck gameobject targeting correctness
4160 for (std::list<GOTargetInfo>::iterator ighit = m_UniqueGOTargetInfo.begin(); ighit != m_UniqueGOTargetInfo.end(); ++ighit)
4161 {
4162 if (ighit->processed == false)
4163 {
4164 if (single_missile || ighit->timeDelay <= t_offset)
4165 DoAllEffectOnTarget(&(*ighit));
4166 else if (next_time == 0 || ighit->timeDelay < next_time)
4167 next_time = ighit->timeDelay;
4168 }
4169 }
4170
4172
4173 if (modOwner)
4174 modOwner->SetSpellModTakingSpell(this, false);
4175
4176 // All targets passed - need finish phase
4177 if (next_time == 0)
4178 {
4179 // spell is finished, perform some last features of the spell here
4181
4182 finish(true); // successfully finish spell cast
4183
4184 // return zero, spell is finished now
4185 return 0;
4186 }
4187 else
4188 {
4189 // spell is unfinished, return next execution time
4190 return next_time;
4191 }
4192}
void _handle_finish_phase()
Definition Spell.cpp:4222
void PrepareTargetProcessing()
Definition Spell.cpp:8501
void _handle_immediate_phase()
Definition Spell.cpp:4194
void FinishTargetProcessing()
Definition Spell.cpp:8506

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 ( )
4050{
4051 // start channeling if applicable
4052 if (m_spellInfo->IsChanneled())
4053 {
4054 int32 duration = m_spellInfo->GetDuration();
4056 duration = -1;
4057
4058 if (duration > 0)
4059 {
4060 // First mod_duration then haste - see Missile Barrage
4061 // Apply duration mod
4062 if (Player* modOwner = m_caster->GetSpellModOwner())
4063 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_DURATION, duration);
4064
4065 // Apply haste mods
4067 duration = int32(duration * m_caster->GetFloatValue(UNIT_MOD_CAST_SPEED));
4068
4071 m_channeledDuration = duration;
4072 SendChannelStart(duration);
4073 }
4074 else if (duration == -1)
4075 {
4078 SendChannelStart(duration);
4079 }
4080 }
4081
4083
4084 // process immediate effects (items, ground, etc.) also initialize some variables
4086
4087 // Sync persistent area aura duration with hasted channel duration
4090 {
4093 }
4094
4095 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
4096 DoAllEffectOnTarget(&(*ihit));
4097
4098 for (std::list<GOTargetInfo>::iterator ihit = m_UniqueGOTargetInfo.begin(); ihit != m_UniqueGOTargetInfo.end(); ++ihit)
4099 DoAllEffectOnTarget(&(*ihit));
4100
4102
4103 // spell is finished, perform some last features of the spell here
4105
4106 // Remove used for cast item if need (it can be already nullptr after TakeReagents call
4107 TakeCastItem();
4108
4109 // handle ammo consumption for Hunter's volley spell
4111 TakeAmmo();
4112
4114 finish(true); // successfully finish spell cast (not last in case autorepeat or channel spell)
4115}
@ DYNOBJ_AURA_TYPE
Definition SpellAuraDefines.h:386
AuraObjectType GetType() const
Definition SpellAuras.cpp:420
void SendChannelStart(uint32 duration)
Definition Spell.cpp:5156
void TakeAmmo()
Definition Spell.cpp:5329
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 
)
5585{
5587 return;
5588
5589 effectHandleMode = mode;
5590 unitTarget = pUnitTarget;
5591 itemTarget = pItemTarget;
5592 gameObjTarget = pGOTarget;
5594
5595 uint8 eff = m_spellInfo->Effects[i].Effect;
5596
5597 LOG_DEBUG("spells.aura", "Spell: {} Effect : {}", m_spellInfo->Id, eff);
5598
5599 // we do not need DamageMultiplier here.
5600 damage = CalculateSpellDamage(i, nullptr);
5601
5602 bool preventDefault = CallScriptEffectHandlers((SpellEffIndex)i, mode);
5603
5604 if (!preventDefault && eff < TOTAL_SPELL_EFFECTS)
5605 {
5606 (this->*SpellEffects[eff])((SpellEffIndex)i);
5607 }
5608}
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:8620
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
8251{
8252 // handle effects with SPELL_EFFECT_HANDLE_LAUNCH mode
8253 for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i)
8254 {
8255 // don't do anything for empty effect
8256 if (!m_spellInfo->Effects[i].IsEffect())
8257 continue;
8258
8259 HandleEffects(nullptr, nullptr, nullptr, i, SPELL_EFFECT_HANDLE_LAUNCH);
8260 }
8261
8262 float multiplier[MAX_SPELL_EFFECTS];
8263 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
8264 if (m_applyMultiplierMask & (1 << i))
8265 multiplier[i] = m_spellInfo->Effects[i].CalcDamageMultiplier(m_originalCaster, this);
8266
8269 for (Unit::AuraEffectList::const_iterator j = Auras.begin(); j != Auras.end(); ++j)
8270 {
8271 if ((*j)->IsAffectedOnSpell(m_spellInfo))
8272 usesAmmo = false;
8273 }
8274
8276
8277 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
8278 {
8279 TargetInfo& target = *ihit;
8280
8281 uint32 mask = target.effectMask;
8282 if (!mask)
8283 continue;
8284
8285 // do not consume ammo anymore for Hunter's volley spell
8287 usesAmmo = false;
8288
8289 if (usesAmmo)
8290 {
8291 bool ammoTaken = false;
8292 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; i++)
8293 {
8294 if (!(mask & 1 << i))
8295 continue;
8296 switch (m_spellInfo->Effects[i].Effect)
8297 {
8303 ammoTaken = true;
8304 TakeAmmo();
8305 }
8306 if (ammoTaken)
8307 break;
8308 }
8309 }
8310
8312 {
8313 Unit* targetUnit = m_caster->GetGUID() == target.targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, target.targetGUID);
8314 if (targetUnit && !m_originalCaster->IsFriendlyTo(targetUnit) && (!m_spellInfo->IsPositive() || m_spellInfo->HasEffect(SPELL_EFFECT_DISPEL)) && (m_spellInfo->HasInitialAggro() || targetUnit->IsEngaged()))
8315 m_originalCaster->SetInCombatWith(targetUnit, true);
8316 }
8317
8318 DoAllEffectOnLaunchTarget(target, multiplier);
8319 }
8320
8322}
@ 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:8324

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 ( )
5532{
5533 if (m_UniqueTargetInfo.empty())
5534 return;
5535
5537 return;
5538
5540
5541 float threat = 0.0f;
5542 if (SpellThreatEntry const* threatEntry = sSpellMgr->GetSpellThreatEntry(m_spellInfo->Id))
5543 {
5544 if (threatEntry->apPctMod != 0.0f)
5545 threat += threatEntry->apPctMod * unitCaster->GetTotalAttackPowerValue(BASE_ATTACK);
5546
5547 threat += threatEntry->flatMod;
5548 }
5550 threat += m_spellInfo->SpellLevel;
5551
5552 // past this point only multiplicative effects occur
5553 if (threat == 0.0f)
5554 return;
5555
5556 // 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
5557 threat /= m_UniqueTargetInfo.size();
5558
5559 for (auto& ihit : m_UniqueTargetInfo)
5560 {
5561 float threatToAdd = threat;
5562 if (ihit.missCondition != SPELL_MISS_NONE)
5563 threatToAdd = 0.0f;
5564
5565 Unit* target = ObjectAccessor::GetUnit(*unitCaster, ihit.targetGUID);
5566 if (!target)
5567 continue;
5568
5569 // positive spells distribute threat among all units that are in combat with target, like healing
5571 target->GetThreatMgr().ForwardThreatForAssistingMe(unitCaster, threatToAdd, m_spellInfo);
5572 // for negative spells threat gets distributed among affected targets
5573 // ignoreModifiers=true because flat SpellThreatEntry threat should not have modifiers applied twice
5574 else
5575 {
5576 if (!target->CanHaveThreatList())
5577 continue;
5578 target->GetThreatMgr().AddThreat(unitCaster, threatToAdd, m_spellInfo, true);
5579 }
5580 }
5581 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()));
5582}
@ 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
8121{
8122 for (std::list<TargetInfo>::const_iterator itr = m_UniqueTargetInfo.begin(); itr != m_UniqueTargetInfo.end(); ++itr)
8123 if (itr->effectMask & (1 << effect))
8124 return true;
8125
8126 for (std::list<GOTargetInfo>::const_iterator itr = m_UniqueGOTargetInfo.begin(); itr != m_UniqueGOTargetInfo.end(); ++itr)
8127 if (itr->effectMask & (1 << effect))
8128 return true;
8129
8130 for (std::list<ItemTargetInfo>::const_iterator itr = m_UniqueItemInfo.begin(); itr != m_UniqueItemInfo.end(); ++itr)
8131 if (itr->effectMask & (1 << effect))
8132 return true;
8133
8134 return false;
8135}

References m_UniqueGOTargetInfo, m_UniqueItemInfo, and m_UniqueTargetInfo.

◆ InitEffectExecuteData()

void Spell::InitEffectExecuteData ( uint8  effIndex)
protected
8512{
8513 ASSERT(effIndex < MAX_SPELL_EFFECTS);
8514 if (!m_effectExecuteData[effIndex])
8515 {
8516 m_effectExecuteData[effIndex] = new ByteBuffer(0x20);
8517 // first dword - target counter
8518 *m_effectExecuteData[effIndex] << uint32(1);
8519 }
8520 else
8521 {
8522 // increase target counter by one
8523 uint32 count = (*m_effectExecuteData[effIndex]).read<uint32>(0);
8524 (*m_effectExecuteData[effIndex]).put<uint32>(0, ++count);
8525 }
8526}

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

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?
8095{
8098 {
8099 return false;
8100 }
8101
8103 {
8104 return false;
8105 }
8106
8107 return true;
8108}
@ 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
8243{
8244 if (target->IsAlive())
8246
8248}
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 ( )
8535{
8536 if (_scriptsLoaded)
8537 return;
8538 _scriptsLoaded = true;
8539 sScriptMgr->CreateSpellScripts(m_spellInfo->Id, m_loadedScripts);
8540 for (std::list<SpellScript*>::iterator itr = m_loadedScripts.begin(); itr != m_loadedScripts.end();)
8541 {
8542 if (!(*itr)->_Load(this))
8543 {
8544 std::list<SpellScript*>::iterator bitr = itr;
8545 ++itr;
8546 delete (*bitr);
8547 m_loadedScripts.erase(bitr);
8548 continue;
8549 }
8550 LOG_DEBUG("spells.aura", "Spell::LoadScripts: Script `{}` for spell `{}` is loaded now", (*itr)->_GetScriptName()->c_str(), m_spellInfo->Id);
8551 (*itr)->Register();
8552 ++itr;
8553 }
8554}

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 ( )
8940{
8941 if (!m_caster || !m_caster->IsInWorld())
8942 return;
8943
8944 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(24390);
8945
8946 // Make sure the player is sending a valid GO target and lock ID. SPELL_EFFECT_OPEN_LOCK
8947 // can succeed with a lockId of 0
8948 if (m_spellInfo->Id == 21651)
8949 {
8950 if (GameObject* go = m_targets.GetGOTarget())
8951 {
8952 LockEntry const* lockInfo = sLockStore.LookupEntry(go->GetGOInfo()->GetLockId());
8953 if (lockInfo && lockInfo->Index[1] == LOCKTYPE_SLOW_OPEN)
8954 {
8955 Spell* visual = new Spell(m_caster, spellInfo, TRIGGERED_NONE);
8956 visual->prepare(&m_targets);
8957 }
8958 }
8959 }
8960}
@ 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 &&

3405{
3406 if (m_CastItem)
3407 {
3409 }
3410 else
3411 {
3413 }
3414
3415 InitExplicitTargets(*targets);
3416
3417 if (!sScriptMgr->CanPrepare(this, targets, triggeredByAura))
3418 {
3419 finish(false);
3420 return SPELL_FAILED_UNKNOWN;
3421 }
3422
3423 // Fill aura scaling information
3425 {
3426 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
3427 {
3428 if (m_spellInfo->Effects[i].Effect == SPELL_EFFECT_APPLY_AURA ||
3431 {
3432 // Change aura with ranks only if basepoints are taken from spellInfo and aura is positive
3434 {
3435 m_auraScaleMask |= (1 << i);
3436 if (m_spellValue->EffectBasePoints[i] != m_spellInfo->Effects[i].BasePoints)
3437 {
3438 m_auraScaleMask = 0;
3439 break;
3440 }
3441 }
3442 }
3443 }
3444 }
3445
3447
3448 if (triggeredByAura)
3449 {
3450 m_triggeredByAuraSpell.Init(triggeredByAura);
3451 }
3452
3453 // create and add update event for this spell
3454 _spellEvent = new SpellEvent(this);
3456
3457 if (sDisableMgr->IsDisabledFor(DISABLE_TYPE_SPELL, m_spellInfo->Id, m_caster))
3458 {
3460 finish(false);
3462 }
3463
3464 //Prevent casting at cast another spell (ServerSide check)
3466 {
3468 finish(false);
3470 }
3471
3472 LoadScripts();
3473
3474 OnSpellLaunch();
3475
3477
3478 // Set combo point requirement
3480 m_needComboPoints = false;
3481
3482 SpellCastResult result = CheckCast(true);
3483 if (result != SPELL_CAST_OK && !IsAutoRepeat()) //always cast autorepeat dummy for triggering
3484 {
3485 // Periodic auras should be interrupted when aura triggers a spell which can't be cast
3486 // for example bladestorm aura should be removed on disarm as of patch 3.3.5
3487 // channeled periodic spells should be affected by this (arcane missiles, penance, etc)
3488 // a possible alternative sollution for those would be validating aura target on unit state change
3489 if (m_caster->IsPlayer() && triggeredByAura && triggeredByAura->IsPeriodic() && !triggeredByAura->GetBase()->IsPassive())
3490 {
3492 triggeredByAura->GetBase()->SetDuration(0);
3493 }
3494
3495 // Allows to cast melee attack spell if result is SPELL_FAILED_OUT_OF_RANGE
3497 {
3498 SendCastResult(result);
3499
3500 finish(false);
3501 return result;
3502 }
3503 }
3504
3505 // Prepare data for triggers
3506 prepareDataForTriggerSystem(triggeredByAura);
3507
3508 // calculate cast time (calculated after first CheckCast check to prevent charge counting for first CheckCast fail)
3510
3511 if (m_caster->IsPlayer())
3513 m_casttime = 0;
3514
3515 // don't allow channeled spells / spells with cast time to be casted while moving
3516 // (even if they are interrupted on moving, spells with almost immediate effect get to have their effect processed before movement interrupter kicks in)
3518 {
3519 // 1. Has casttime, 2. Or doesn't have flag to allow action during channel
3521 {
3523 finish(false);
3524 return SPELL_FAILED_MOVING;
3525 }
3526 }
3527
3528 // xinef: if spell have nearby target entry only, do not allow to cast if no targets are found
3529 if (m_CastItem)
3530 {
3531 bool selectTargets = false;
3532 bool nearbyDest = false;
3533
3534 for (uint8 i = EFFECT_0; i < MAX_SPELL_EFFECTS; ++i)
3535 {
3536 if (!m_spellInfo->Effects[i].IsEffect())
3537 continue;
3538
3539 if (m_spellInfo->Effects[i].TargetA.GetSelectionCategory() != TARGET_SELECT_CATEGORY_NEARBY || m_spellInfo->Effects[i].TargetA.GetCheckType() != TARGET_CHECK_ENTRY)
3540 {
3541 selectTargets = false;
3542 break;
3543 }
3544
3545 if (m_spellInfo->Effects[i].TargetA.GetObjectType() == TARGET_OBJECT_TYPE_DEST)
3546 {
3547 nearbyDest = true;
3548 }
3549
3550 // xinef: by default set it to false, and to true if any valid target is found
3551 selectTargets = true;
3552 }
3553
3554 if (selectTargets)
3555 {
3557 _spellTargetsSelected = true;
3558 bool spellFailed = false;
3559
3560 if (m_UniqueTargetInfo.empty() && m_UniqueGOTargetInfo.empty())
3561 {
3562 // no valid nearby target unit or game object found; check if nearby destination type
3563 if (nearbyDest)
3564 {
3565 if (!m_targets.HasDst())
3566 {
3567 // no valid target destination
3568 spellFailed = true;
3569 }
3570 }
3571 else
3572 {
3573 spellFailed = true;
3574 }
3575 }
3576
3577 if (spellFailed)
3578 {
3580 finish(false);
3582 }
3583 }
3584 }
3585
3586 // set timer base at cast time
3587 ReSetTimer();
3588
3589 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());
3590
3591 // prevent exploit that allows to cast spell while sitting
3594
3595 //Containers for channeled spells have to be set
3596 //TODO:Apply this to all casted spells if needed
3597 // Why check duration? 29350: channelled triggers channelled
3599 cast(true);
3600 else
3601 {
3602 // stealth must be removed at cast starting (at show channel bar)
3603 // skip triggered spell (item equip spell casting and other not explicit character casts/item uses)
3605 {
3606 // Farsight spells exception
3607 uint32 exceptSpellId = 0;
3609 {
3610 exceptSpellId = m_spellInfo->Id;
3611 }
3612
3615 }
3616
3619
3620 // Call CreatureAI hook OnSpellStart for spells with cast time or channeled spells
3621 if (m_casttime > 0 || m_spellInfo->IsChanneled())
3622 if (Creature* caster = m_caster->ToCreature())
3623 if (caster->IsAIEnabled)
3624 caster->AI()->OnSpellStart(GetSpellInfo());
3625
3626 // set target for proper facing
3628 {
3631 {
3632 // Xinef: Creature should focus to cast target if there is explicit target or self if casting positive spell
3633 // Xinef: Creature should not rotate when casting spell... based on halion behavior
3635 }
3636 }
3637
3638 //item: first cast may destroy item and second cast causes crash
3639 // xinef: removed !m_spellInfo->StartRecoveryTime
3640 // second los check failed in events
3641 // xinef: removed itemguid check, currently there is no such item in database
3643 cast(true);
3644
3647 }
3648
3649 sScriptMgr->OnSpellPrepare(this, m_caster, m_spellInfo);
3650
3651 return SPELL_CAST_OK;
3652}
@ 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:3548
Definition Spell.cpp:518
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:8534
void cast(bool skipCheck=false)
Definition Spell.cpp:3727
void prepareDataForTriggerSystem(AuraEffect const *triggeredByAura)
Definition Spell.cpp:2200
void SendSpellStart()
Definition Spell.cpp:4667
void TriggerGlobalCooldown()
Definition Spell.cpp:8878
void OnSpellLaunch()
Definition Spell.cpp:8939
CurrentSpellTypes GetCurrentContainer() const
Definition Spell.cpp:7930
void ReSetTimer()
Definition Spell.h:565
void InitExplicitTargets(SpellCastTargets const &targets)
Definition Spell.cpp:719
void SetCurrentCastedSpell(Spell *pSpell)
Definition Unit.cpp:4141
bool IsSitState() const
Definition Unit.cpp:13091
void Init(AuraEffect const *aurEff)
Definition Spell.cpp:8962

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
2201{
2202 //==========================================================================================
2203 // Now fill data for trigger system, need know:
2204 // can spell trigger another or not (m_canTrigger)
2205 // Create base triggers flags for Attacker and Victim (m_procAttacker, m_procVictim and m_procEx)
2206 //==========================================================================================
2207
2209 // Get data for type of attack and fill base info for trigger
2210 switch (m_spellInfo->DmgClass)
2211 {
2214 if (m_attackType == OFF_ATTACK)
2216 else
2219 break;
2221 // Auto attack
2223 {
2226 }
2227 else // Ranged spell attack
2228 {
2231 }
2232 break;
2233 default:
2236 && m_spellInfo->HasAttribute(SPELL_ATTR2_AUTO_REPEAT)) // Wands auto attack
2237 {
2240 }
2241 // For other spells trigger procflags are set in Spell::DoAllEffectOnTarget
2242 // Because spell positivity is dependant on target
2243 }
2245
2246 // Hunter trap spells - activation proc for Lock and Load, Entrapment and Misdirection
2248 (m_spellInfo->SpellFamilyFlags[0] & 0x18 || // Freezing and Frost Trap, Freezing Arrow
2249 m_spellInfo->Id == 57879 || // Snake Trap - done this way to avoid double proc
2250 m_spellInfo->SpellFamilyFlags[2] & 0x00024000)) // Explosive and Immolation Trap
2251 {
2253
2254 // also fill up other flags (TargetInfo::DoDamageAndTriggers only fills up flag if both are not set)
2257 }
2258
2259 /* Effects which are result of aura proc from triggered spell cannot proc
2260 to prevent chain proc of these spells */
2261
2262 // Hellfire Effect - trigger as DOT
2264 {
2267 }
2268
2269 // Ranged autorepeat attack is set as triggered spell - ignore it
2271 {
2278 }
2279 // Totem casts require spellfamilymask defined in spell_proc to proc
2282}
@ 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
8615{
8616 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8617 (*scritr)->_InitHit();
8618}

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
8789{
8792 {
8793 SpellInfo const* excludeCasterSpellInfo = sSpellMgr->GetSpellInfo(m_spellInfo->ExcludeCasterAuraSpell);
8794 if (excludeCasterSpellInfo && !excludeCasterSpellInfo->IsPositive())
8796 SpellInfo const* excludeTargetSpellInfo = sSpellMgr->GetSpellInfo(m_spellInfo->ExcludeTargetAuraSpell);
8797 if (excludeTargetSpellInfo && !excludeTargetSpellInfo->IsPositive())
8799 }
8800
8803 {
8805 {
8806 if (m_spellInfo->SpellFamilyFlags[1] & 0x40000000)
8807 {
8809 for(Unit::AuraEffectList::const_iterator itr = mVindication.begin(); itr != mVindication.end(); ++itr)
8810 {
8811 if ((*itr)->GetSpellInfo()->Effects[EFFECT_0].TriggerSpell == 26017 )
8812 {
8813 m_preCastSpell = 26017;
8814 break;
8815 }
8816 else if ((*itr)->GetSpellInfo()->Effects[EFFECT_0].TriggerSpell == 67 )
8817 m_preCastSpell = 67;
8818 }
8819 }
8820 break;
8821 }
8822 case SPELLFAMILY_DRUID:
8823 {
8824 // Faerie Fire (Feral)
8826 m_preCastSpell = 60089;
8827
8828 break;
8829 }
8830 }
8831
8832 // handle SPELL_AURA_ADD_TARGET_TRIGGER auras:
8833 // save auras which were present on spell caster on cast, to prevent triggered auras from affecting caster
8834 // and to correctly calculate proc chance when combopoints are present
8836 for (Unit::AuraEffectList::const_iterator i = targetTriggers.begin(); i != targetTriggers.end(); ++i)
8837 {
8838 if (!(*i)->IsAffectedOnSpell(m_spellInfo))
8839 continue;
8840 SpellInfo const* auraSpellInfo = (*i)->GetSpellInfo();
8841 uint32 auraSpellIdx = (*i)->GetEffIndex();
8842 if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(auraSpellInfo->Effects[auraSpellIdx].TriggerSpell))
8843 {
8844 // calculate the chance using spell base amount, because aura amount is not updated on combo-points change
8845 // this possibly needs fixing
8846 int32 auraBaseAmount = (*i)->GetBaseAmount();
8847 // proc chance is stored in effect amount
8848 int32 chance = m_caster->CalculateSpellDamage(nullptr, auraSpellInfo, auraSpellIdx, &auraBaseAmount);
8849 // build trigger and add to the list
8850 HitTriggerSpell spellTriggerInfo;
8851 spellTriggerInfo.triggeredSpell = spellInfo;
8852 spellTriggerInfo.triggeredByAura = auraSpellInfo;
8853 spellTriggerInfo.triggeredByEffIdx = (*i)->GetEffIndex();
8854 spellTriggerInfo.chance = chance * (*i)->GetBase()->GetStackAmount();
8855 m_hitTriggerSpells.push_back(spellTriggerInfo);
8856 }
8857 }
8858}
@ 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 ( )
924{
927}
void ModifyEventTime(BasicEvent *event, Milliseconds newTime)
Definition EventProcessor.cpp:145
uint64 CalculateDelayMomentForDst() const
Definition Spell.cpp:902
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 
)
2094{
2095 uint32 containerTypeMask = GetSearcherTypeMask(objectType, condList);
2096 if (!containerTypeMask)
2097 return;
2098 Acore::WorldObjectSpellAreaTargetCheck check(range, position, m_caster, referer, m_spellInfo, selectionType, condList, searchReason);
2099 Acore::WorldObjectListSearcher<Acore::WorldObjectSpellAreaTargetCheck> searcher(m_caster, targets, check, containerTypeMask);
2100 SearchTargets<Acore::WorldObjectListSearcher<Acore::WorldObjectSpellAreaTargetCheck> > (searcher, containerTypeMask, m_caster, position, range);
2101}
uint32 GetSearcherTypeMask(SpellTargetObjectTypes objType, ConditionList *condList)
Definition Spell.cpp:2036
Definition GridNotifiers.h:230

References GetSearcherTypeMask(), m_caster, and m_spellInfo.

Referenced by SearchChainTargets(), and SelectImplicitAreaTargets().

◆ SearchChainTargets()

void Spell::SearchChainTargets ( std::list< WorldObject * > &  targets,
uint32  chainTargets,
WorldObject target,
SpellTargetObjectTypes  objectType,
SpellTargetCheckTypes  selectType,
SpellTargetSelectionCategories  selectCategory,
ConditionList condList,
bool  isChainHeal 
)
2104{
2105 // max dist for jump target selection
2106 float jumpRadius = 0.0f;
2107 switch (m_spellInfo->DmgClass)
2108 {
2110 // 7.5y for multi shot
2111 jumpRadius = 7.5f;
2112 break;
2114 // 5y for swipe, cleave and similar
2115 jumpRadius = 5.0f;
2116 break;
2119 // 12.5y for chain heal spell since 3.2 patch
2120 if (isChainHeal)
2121 jumpRadius = 12.5f;
2122 // 10y as default for magic chain spells
2123 else
2124 jumpRadius = 10.0f;
2125 break;
2126 }
2127
2128 // per-spell override from spell_jump_distance table
2129 if (m_spellInfo->JumpDistance > 0.0f)
2130 jumpRadius = m_spellInfo->JumpDistance;
2131
2132 // chain lightning/heal spells and similar - allow to jump at larger distance and go out of los
2136
2137 // max dist which spell can reach
2138 float searchRadius = jumpRadius;
2139 if (isBouncingFar)
2140 searchRadius *= chainTargets;
2141
2143 std::list<WorldObject*> tempTargets;
2144 SearchAreaTargets(tempTargets, searchRadius, chainSource, m_caster, objectType, selectType, condList, Acore::WorldObjectSpellAreaTargetSearchReason::Chain);
2145 tempTargets.remove(target);
2146
2147 // remove targets which are always invalid for chain spells
2148 // for some spells allow only chain targets in front of caster (swipe for example)
2149 if (!isBouncingFar)
2150 tempTargets.remove_if([this](WorldObject* target) { return !m_caster->HasInArc(static_cast<float>(M_PI), target); });
2151
2152 while (chainTargets)
2153 {
2154 // try to get unit for next chain jump
2155 std::list<WorldObject*>::iterator foundItr = tempTargets.end();
2156 // get unit with highest hp deficit in dist
2157 if (isChainHeal)
2158 {
2159 uint32 maxHPDeficit = 0;
2160 for (std::list<WorldObject*>::iterator itr = tempTargets.begin(); itr != tempTargets.end(); ++itr)
2161 {
2162 if (Unit* unit = (*itr)->ToUnit())
2163 {
2164 uint32 deficit = unit->GetMaxHealth() - unit->GetHealth();
2165 if (deficit > maxHPDeficit && chainSource->IsWithinDist(unit, jumpRadius) && chainSource->IsWithinLOSInMap(unit, VMAP::ModelIgnoreFlags::M2))
2166 {
2167 foundItr = itr;
2168 maxHPDeficit = deficit;
2169 }
2170 }
2171 }
2172 }
2173 // get closest object
2174 else
2175 {
2176 for (std::list<WorldObject*>::iterator itr = tempTargets.begin(); itr != tempTargets.end(); ++itr)
2177 {
2178 if (foundItr == tempTargets.end())
2179 {
2180 if ((!isBouncingFar || chainSource->IsWithinDist(*itr, jumpRadius)) && chainSource->IsWithinLOSInMap(*itr, VMAP::ModelIgnoreFlags::M2))
2181 foundItr = itr;
2182 }
2183 else if (chainSource->GetDistanceOrder(*itr, *foundItr) && chainSource->IsWithinLOSInMap(*itr, VMAP::ModelIgnoreFlags::M2))
2184 foundItr = itr;
2185 }
2186 }
2187 // not found any valid target - chain ends
2188 if (foundItr == tempTargets.end())
2189 break;
2190
2192 chainSource = *foundItr;
2193
2194 targets.push_back(*foundItr);
2195 tempTargets.erase(foundItr);
2196 --chainTargets;
2197 }
2198}
@ 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:2093
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 
)
2082{
2083 WorldObject* target = nullptr;
2084 uint32 containerTypeMask = GetSearcherTypeMask(objectType, condList);
2085 if (!containerTypeMask)
2086 return nullptr;
2087 Acore::WorldObjectSpellNearbyTargetCheck check(range, m_caster, m_spellInfo, selectionType, condList);
2089 SearchTargets<Acore::WorldObjectLastSearcher<Acore::WorldObjectSpellNearbyTargetCheck> > (searcher, containerTypeMask, m_caster, m_caster, range);
2090 return target;
2091}
Definition GridNotifiers.h:210

References GetSearcherTypeMask(), m_caster, and m_spellInfo.

Referenced by SelectImplicitNearbyTargets().

◆ SearchTargets()

template<class SEARCHER >
void Spell::SearchTargets ( SEARCHER &  searcher,
uint32  containerMask,
Unit referer,
Position const *  pos,
float  radius 
)
2074{
2075 if (!containerMask)
2076 return;
2077
2078 Cell::VisitObjects(pos->GetPositionX(), pos->GetPositionY(), referer->GetMap(), searcher, radius);
2079}

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

◆ SelectEffectImplicitTargets()

void Spell::SelectEffectImplicitTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType,
uint32 processedEffectMask 
)
930{
931 if (!targetType.GetTarget())
932 return;
933
934 uint32 effectMask = 1 << effIndex;
935 // set the same target list for all effects
936 // some spells appear to need this, however this requires more research
937 switch (targetType.GetSelectionCategory())
938 {
942 {
943 // targets for effect already selected
944 if (effectMask & processedEffectMask)
945 {
946 return;
947 }
948
949 auto const& effects = GetSpellInfo()->Effects;
950
951 // choose which targets we can select at once
952 for (uint32 j = effIndex + 1; j < MAX_SPELL_EFFECTS; ++j)
953 {
954 if (effects[j].IsEffect() &&
955 effects[effIndex].TargetA.GetTarget() == effects[j].TargetA.GetTarget() &&
956 effects[effIndex].TargetB.GetTarget() == effects[j].TargetB.GetTarget() &&
957 effects[effIndex].ImplicitTargetConditions == effects[j].ImplicitTargetConditions &&
958 effects[effIndex].CalcRadius(m_caster) == effects[j].CalcRadius(m_caster) &&
960 {
961 effectMask |= 1 << j;
962 }
963 }
964 processedEffectMask |= effectMask;
965 break;
966 }
967 default:
968 break;
969 }
970
971 switch (targetType.GetSelectionCategory())
972 {
974 SelectImplicitChannelTargets(effIndex, targetType);
975 break;
977 SelectImplicitNearbyTargets(effIndex, targetType, effectMask);
978 break;
980 SelectImplicitConeTargets(effIndex, targetType, effectMask);
981 break;
983 SelectImplicitAreaTargets(effIndex, targetType, effectMask);
984 break;
986 // just in case there is no dest, explanation in SelectImplicitDestDestTargets
987 CheckDst();
988
989 SelectImplicitTrajTargets(effIndex, targetType);
990 break;
992 switch (targetType.GetObjectType())
993 {
995 switch (targetType.GetReferenceType())
996 {
999 break;
1000 default:
1001 ASSERT(false && "Spell::SelectEffectImplicitTargets: received not implemented select target reference type for TARGET_TYPE_OBJECT_SRC");
1002 break;
1003 }
1004 break;
1006 switch (targetType.GetReferenceType())
1007 {
1009 SelectImplicitCasterDestTargets(effIndex, targetType);
1010 break;
1012 SelectImplicitTargetDestTargets(effIndex, targetType);
1013 break;
1015 SelectImplicitDestDestTargets(effIndex, targetType);
1016 break;
1017 default:
1018 ASSERT(false && "Spell::SelectEffectImplicitTargets: received not implemented select target reference type for TARGET_TYPE_OBJECT_DEST");
1019 break;
1020 }
1021 break;
1022 default:
1023 switch (targetType.GetReferenceType())
1024 {
1026 SelectImplicitCasterObjectTargets(effIndex, targetType);
1027 break;
1029 SelectImplicitTargetObjectTargets(effIndex, targetType);
1030 break;
1031 default:
1032 ASSERT(false && "Spell::SelectEffectImplicitTargets: received not implemented select target reference type for TARGET_TYPE_OBJECT");
1033 break;
1034 }
1035 break;
1036 }
1037 break;
1039 LOG_DEBUG("spells.aura", "SPELL: target type {}, found in spellID {}, effect {} is not implemented yet!", m_spellInfo->Id, effIndex, targetType.GetTarget());
1040 break;
1041 default:
1042 ASSERT(false && "Spell::SelectEffectImplicitTargets: received not implemented select target category");
1043 break;
1044 }
1045}
@ 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:1724
void CheckDst()
Definition Spell.h:506
void SelectImplicitTrajTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition Spell.cpp:1870
void SelectImplicitConeTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType, uint32 effMask)
Definition Spell.cpp:1217
void SelectImplicitTargetDestTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition Spell.cpp:1687
void SelectImplicitAreaTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType, uint32 effMask)
Definition Spell.cpp:1263
void SelectImplicitChannelTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition Spell.cpp:1047
void SelectImplicitTargetObjectTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition Spell.cpp:1807
void SelectImplicitCasterObjectTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition Spell.cpp:1760
void SelectImplicitNearbyTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType, uint32 effMask)
Definition Spell.cpp:1103
bool CheckScriptEffectImplicitTargets(uint32 effIndex, uint32 effIndexToCheck)
Definition Spell.cpp:8749
void SelectImplicitCasterDestTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition Spell.cpp:1341

References ASSERT, CheckDst(), CheckScriptEffectImplicitTargets(), SpellInfo::Effects, SpellImplicitTargetInfo::GetObjectType(), SpellImplicitTargetInfo::GetReferenceType(), SpellImplicitTargetInfo::GetSelectionCategory(), GetSpellInfo(), SpellImplicitTargetInfo::GetTarget(), SpellInfo::Id, LOG_DEBUG, m_caster, m_spellInfo, m_targets, MAX_SPELL_EFFECTS, SelectImplicitAreaTargets(), SelectImplicitCasterDestTargets(), SelectImplicitCasterObjectTargets(), SelectImplicitChannelTargets(), SelectImplicitConeTargets(), SelectImplicitDestDestTargets(), SelectImplicitNearbyTargets(), SelectImplicitTargetDestTargets(), SelectImplicitTargetObjectTargets(), SelectImplicitTrajTargets(), SpellCastTargets::SetSrc(), TARGET_OBJECT_TYPE_DEST, TARGET_OBJECT_TYPE_SRC, TARGET_REFERENCE_TYPE_CASTER, TARGET_REFERENCE_TYPE_DEST, TARGET_REFERENCE_TYPE_TARGET, TARGET_SELECT_CATEGORY_AREA, TARGET_SELECT_CATEGORY_CHANNEL, TARGET_SELECT_CATEGORY_CONE, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_SELECT_CATEGORY_NEARBY, TARGET_SELECT_CATEGORY_NYI, and TARGET_SELECT_CATEGORY_TRAJ.

Referenced by SelectSpellTargets().

◆ SelectEffectTypeImplicitTargets()

void Spell::SelectEffectTypeImplicitTargets ( uint8  effIndex)
Todo:
: this is a workaround - target shouldn't be stored in target map for those spells
Todo:
: this is a workaround - corpses should be added to spell target map too, but we can't do that so we add owner instead
1954{
1955 // special case for SPELL_EFFECT_SUMMON_RAF_FRIEND and SPELL_EFFECT_SUMMON_PLAYER
1957 switch (m_spellInfo->Effects[effIndex].Effect)
1958 {
1962 {
1964
1966
1967 if (target && target->ToPlayer())
1968 AddUnitTarget(target->ToUnit(), 1 << effIndex, false);
1969 }
1970 return;
1971 default:
1972 break;
1973 }
1974
1975 // select spell implicit targets based on effect type
1976 if (!m_spellInfo->Effects[effIndex].GetImplicitTargetType())
1977 return;
1978
1979 uint32 targetMask = m_spellInfo->Effects[effIndex].GetMissingTargetMask();
1980
1981 if (!targetMask)
1982 return;
1983
1984 WorldObject* target = nullptr;
1985
1986 switch (m_spellInfo->Effects[effIndex].GetImplicitTargetType())
1987 {
1988 // add explicit object target or self to the target map
1990 // player which not released his spirit is Unit, but target flag for it is TARGET_FLAG_CORPSE_MASK
1992 {
1994 target = unitTarget;
1995 else if (targetMask & TARGET_FLAG_CORPSE_MASK)
1996 {
1997 if (Corpse* corpseTarget = m_targets.GetCorpseTarget())
1998 {
2000 if (Player* owner = ObjectAccessor::FindPlayer(corpseTarget->GetOwnerGUID()))
2001 target = owner;
2002 }
2003 }
2004 else //if (targetMask & TARGET_FLAG_UNIT_MASK)
2005 target = m_caster;
2006 }
2007 if (targetMask & TARGET_FLAG_ITEM_MASK)
2008 {
2010 AddItemTarget(itemTarget, 1 << effIndex);
2011 return;
2012 }
2013 if (targetMask & TARGET_FLAG_GAMEOBJECT_MASK)
2014 target = m_targets.GetGOTarget();
2015 break;
2016 // add self to the target map
2018 if (targetMask & TARGET_FLAG_UNIT_MASK)
2019 target = m_caster;
2020 break;
2021 default:
2022 break;
2023 }
2024
2026
2027 if (target)
2028 {
2029 if (target->ToUnit())
2030 AddUnitTarget(target->ToUnit(), 1 << effIndex, false);
2031 else if (target->ToGameObject())
2032 AddGOTarget(target->ToGameObject(), 1 << effIndex);
2033 }
2034}
@ 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:293
Definition SpellInfo.h:238
void AddGOTarget(GameObject *target, uint32 effectMask)
Definition Spell.cpp:2427
void AddUnitTarget(Unit *target, uint32 effectMask, bool checkIfValid=true, bool implicit=true)
Definition Spell.cpp:2293
void AddItemTarget(Item *item, uint32 effectMask)
Definition Spell.cpp:2489
void CallScriptObjectTargetSelectHandlers(WorldObject *&target, SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition Spell.cpp:8721

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 ( )
790{
791 // here go all explicit target changes made to explicit targets after spell prepare phase is finished
792 if (Unit* target = m_targets.GetUnitTarget())
793 {
794 // check for explicit target redirection, for Grounding Totem for example
798 {
799 Unit* redirect;
800 switch (m_spellInfo->DmgClass)
801 {
804 break;
808 break;
809 default:
810 redirect = nullptr;
811 break;
812 }
813 if (redirect && (redirect != target))
814 {
815 m_targets.SetUnitTarget(redirect);
817 }
818 }
819 }
820}
Unit * GetMeleeHitRedirectTarget(Unit *victim, SpellInfo const *spellInfo=nullptr)
Definition Unit.cpp:8162
Unit * GetMagicHitRedirectTarget(Unit *victim, SpellInfo const *spellInfo)
Definition Unit.cpp:8124

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 
)
1264{
1265 Unit* referer = nullptr;
1266 switch (targetType.GetReferenceType())
1267 {
1271 referer = m_caster;
1272 break;
1274 referer = m_targets.GetUnitTarget();
1275 break;
1277 {
1278 // find last added target for this effect
1279 for (std::list<TargetInfo>::reverse_iterator ihit = m_UniqueTargetInfo.rbegin(); ihit != m_UniqueTargetInfo.rend(); ++ihit)
1280 {
1281 if (ihit->effectMask & (1 << effIndex))
1282 {
1283 referer = ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID);
1284 break;
1285 }
1286 }
1287 break;
1288 }
1289 default:
1290 ASSERT(false && "Spell::SelectImplicitAreaTargets: received not implemented target reference type");
1291 return;
1292 }
1293 if (!referer)
1294 return;
1295
1296 Position const* center = nullptr;
1297 switch (targetType.GetReferenceType())
1298 {
1300 center = m_targets.GetSrcPos();
1301 break;
1303 center = m_targets.GetDstPos();
1304 break;
1308 center = referer;
1309 break;
1310 default:
1311 ASSERT(false && "Spell::SelectImplicitAreaTargets: received not implemented target reference type");
1312 return;
1313 }
1314
1315 // Xinef: the distance should be increased by caster size, it is neglected in latter calculations
1316 std::list<WorldObject*> targets;
1317 float radius = m_spellInfo->Effects[effIndex].CalcRadius(m_caster) * m_spellValue->RadiusMod;
1318 SearchAreaTargets(targets, radius, center, referer, targetType.GetObjectType(), targetType.GetCheckType(), m_spellInfo->Effects[effIndex].ImplicitTargetConditions, Acore::WorldObjectSpellAreaTargetSearchReason::Area);
1319
1320 CallScriptObjectAreaTargetSelectHandlers(targets, effIndex, targetType);
1321
1322 if (!targets.empty())
1323 {
1324 // Other special target selection goes here
1325 if (uint32 maxTargets = m_spellValue->MaxAffectedTargets)
1326 {
1328 Acore::Containers::RandomResize(targets, maxTargets);
1329 }
1330
1331 for (std::list<WorldObject*>::iterator itr = targets.begin(); itr != targets.end(); ++itr)
1332 {
1333 if (Unit* unitTarget = (*itr)->ToUnit())
1334 AddUnitTarget(unitTarget, effMask, false);
1335 else if (GameObject* gObjTarget = (*itr)->ToGameObject())
1336 AddGOTarget(gObjTarget, effMask);
1337 }
1338 }
1339}
@ SPELL_AURA_MOD_MAX_AFFECTED_TARGETS
Definition SpellAuraDefines.h:340
@ TARGET_REFERENCE_TYPE_SRC
Definition SpellInfo.h:93
@ TARGET_REFERENCE_TYPE_LAST
Definition SpellInfo.h:92
Position const * GetSrcPos() const
Definition Spell.cpp:361
void CallScriptObjectAreaTargetSelectHandlers(std::list< WorldObject * > &targets, SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition Spell.cpp:8707
int32 GetTotalAuraModifierByAffectMask(AuraType auratype, SpellInfo const *affectedSpell) const
Definition Unit.cpp:6385
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
1342{
1344
1345 switch (targetType.GetTarget())
1346 {
1347 case TARGET_DEST_CASTER:
1349 break;
1350 case TARGET_DEST_HOME:
1351 if (Player* playerCaster = m_caster->ToPlayer())
1352 dest = SpellDestination(playerCaster->m_homebindX, playerCaster->m_homebindY, playerCaster->m_homebindZ, playerCaster->GetOrientation(), playerCaster->m_homebindMapId);
1353 break;
1354 case TARGET_DEST_DB:
1355 if (SpellTargetPosition const* st = sSpellMgr->GetSpellTargetPosition(m_spellInfo->Id, effIndex))
1356 {
1359 dest = SpellDestination(st->target_X, st->target_Y, st->target_Z, st->target_Orientation, (int32)st->target_mapId);
1360 else if (st->target_mapId == m_caster->GetMapId())
1361 dest = SpellDestination(st->target_X, st->target_Y, st->target_Z, st->target_Orientation);
1362 }
1363 else
1364 {
1365 LOG_DEBUG("spells.aura", "SPELL: unknown target coordinates for spell ID {}", m_spellInfo->Id);
1366 if (WorldObject* target = m_targets.GetObjectTarget())
1367 dest = SpellDestination(*target);
1368 }
1369 break;
1371 {
1372 float min_dis = m_spellInfo->GetMinRange(true);
1373 float max_dis = m_spellInfo->GetMaxRange(true);
1374 float dis = (float)rand_norm() * (max_dis - min_dis) + min_dis;
1375 float x, y, z, angle;
1376 angle = (float)rand_norm() * static_cast<float>(M_PI * 35.0f / 180.0f) - static_cast<float>(M_PI * 17.5f / 180.0f);
1377 //m_caster->GetClosePoint(x, y, z, DEFAULT_WORLD_OBJECT_SIZE, dis, angle); this contains extra code that breaks fishing
1379
1380 float ground = m_caster->GetMapHeight(x, y, z, true);
1381 float liquidLevel = VMAP_INVALID_HEIGHT_VALUE;
1382 LiquidData const& liquidData = m_caster->GetMap()->GetLiquidData(m_caster->GetPhaseMask(), x, y, z, m_caster->GetCollisionHeight(), {});
1383 if (liquidData.Status)
1384 liquidLevel = liquidData.Level;
1385
1386 if (liquidLevel <= ground) // When there is no liquid Map::GetWaterOrGroundLevel returns ground level
1387 {
1390 finish(false);
1391 return;
1392 }
1393
1394 if (ground + 0.75 > liquidLevel)
1395 {
1398 finish(false);
1399 return;
1400 }
1401
1402 if (!m_caster->IsWithinLOS(x, y, z))
1403 {
1406 finish(false);
1407 return;
1408 }
1409
1410 dest = SpellDestination(x, y, liquidLevel, m_caster->GetOrientation());
1411 break;
1412 }
1414 {
1415 float distance = m_spellInfo->Effects[effIndex].CalcRadius(m_caster);
1416 Map* map = m_caster->GetMap();
1417 uint32 phasemask = m_caster->GetPhaseMask();
1418 float collisionHeight = m_caster->GetCollisionHeight();
1419 float destz = 0.0f, startx = 0.0f, starty = 0.0f, startz = 0.0f, starto = 0.0f;
1420
1421 Position pos;
1422 Position lastpos;
1423 m_caster->GetPosition(startx, starty, startz, starto);
1424 pos.Relocate(startx, starty, startz, starto);
1425 float destx = pos.GetPositionX() + distance * cos(pos.GetOrientation());
1426 float desty = pos.GetPositionY() + distance * sin(pos.GetOrientation());
1427
1428 // Added GROUND_HEIGHT_TOLERANCE to account for cases where, during a jump,
1429 // the Z position may be slightly below the vmap ground level.
1430 // Without this tolerance, a ray trace might incorrectly attempt to find ground
1431 // beneath the actual surface.
1432 //
1433 // Example:
1434 // actual vmap ground: -56.342392
1435 // Z position: -56.347195
1436 float searchGroundZPos = pos.GetPositionZ()+GROUND_HEIGHT_TOLERANCE;
1437 float ground = map->GetHeight(phasemask, pos.GetPositionX(), pos.GetPositionY(), searchGroundZPos);
1438
1439 bool isCasterInWater = m_caster->IsInWater();
1440 if (!m_caster->HasUnitMovementFlag(MOVEMENTFLAG_FALLING) || (pos.GetPositionZ() - ground < distance))
1441 {
1442 float tstX = 0.0f, tstY = 0.0f, tstZ = 0.0f, prevX = 0.0f, prevY = 0.0f, prevZ = 0.0f;
1443 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;
1444 float maxtravelDistZ = 2.65f;
1445 float overdistance = 0.0f;
1446 float totalpath = 0.0f;
1447 float beforewaterz = 0.0f;
1448 bool inwater = false;
1449 bool wcol = false;
1450 const float step = 2.0f;
1451 const uint8 numChecks = std::ceil(std::fabs(distance / step));
1452 const float DELTA_X = (destx - pos.GetPositionX()) / numChecks;
1453 const float DELTA_Y = (desty - pos.GetPositionY()) / numChecks;
1454 int j = 1;
1455 for (; j < (numChecks + 1); j++)
1456 {
1457 prevX = pos.GetPositionX() + (float(j - 1) * DELTA_X);
1458 prevY = pos.GetPositionY() + (float(j - 1) * DELTA_Y);
1459 tstX = pos.GetPositionX() + (float(j) * DELTA_X);
1460 tstY = pos.GetPositionY() + (float(j) * DELTA_Y);
1461
1462 if (j < 2)
1463 {
1464 prevZ = pos.GetPositionZ();
1465 }
1466 else
1467 {
1468 prevZ = tstZ;
1469 }
1470
1471 tstZ = map->GetHeight(phasemask, tstX, tstY, prevZ + maxtravelDistZ, true);
1472 ground = tstZ;
1473
1474 if (!isCasterInWater)
1475 {
1476 if (map->IsInWater(phasemask, tstX, tstY, tstZ, collisionHeight))
1477 {
1478 if (!(beforewaterz != 0.0f))
1479 {
1480 beforewaterz = prevZ;
1481 }
1482 tstZ = beforewaterz;
1483 srange = sqrt((tstY - prevY) * (tstY - prevY) + (tstX - prevX) * (tstX - prevX));
1484 //LOG_ERROR("spells", "(start was from land) step in water , number of cycle = {} , distance of step = {}, total path = {}, Z = {}", j, srange, totalpath, tstZ);
1485 }
1486 }
1487 else if (map->IsInWater(phasemask, tstX, tstY, tstZ, collisionHeight))
1488 {
1489 prevZ = pos.GetPositionZ();
1490 tstZ = pos.GetPositionZ();
1491 srange = sqrt((tstY - prevY) * (tstY - prevY) + (tstX - prevX) * (tstX - prevX));
1492
1493 inwater = true;
1494 if (inwater && (fabs(tstZ - ground) < 2.0f))
1495 {
1496 wcol = true;
1497 //LOG_ERROR("spells", "step in water with collide and use standart check (for continue way after possible collide), number of cycle = {} ", j);
1498 }
1499
1500 // if (j < 2)
1501 // LOG_ERROR("spells", "(start in water) step in water, number of cycle = {} , distance of step = {}, total path = {}", j, srange, totalpath);
1502 // else
1503 // LOG_ERROR("spells", "step in water, number of cycle = {} , distance of step = {}, total path = {}", j, srange, totalpath);
1504 }
1505
1506 bool IsInWater = map->IsInWater(phasemask, tstX, tstY, tstZ, collisionHeight);
1507 if ((!IsInWater && tstZ != beforewaterz) || wcol) // second safety check z for blink way if on the ground
1508 {
1509 if (inwater && !IsInWater)
1510 inwater = false;
1511
1512 // highest available point
1513 tstZ1 = map->GetHeight(phasemask, tstX, tstY, prevZ + maxtravelDistZ, true, 25.0f);
1514 // upper or floor
1515 tstZ2 = map->GetHeight(phasemask, tstX, tstY, prevZ, true, 25.0f);
1516 //lower than floor
1517 tstZ3 = map->GetHeight(phasemask, tstX, tstY, prevZ - maxtravelDistZ / 2, true, 25.0f);
1518
1519 //distance of rays, will select the shortest in 3D
1520 srange1 = sqrt((tstY - prevY) * (tstY - prevY) + (tstX - prevX) * (tstX - prevX) + (tstZ1 - prevZ) * (tstZ1 - prevZ));
1521 //LOG_ERROR("spells", "step = {}, distance of ray1 = {}", j, srange1);
1522 srange2 = sqrt((tstY - prevY) * (tstY - prevY) + (tstX - prevX) * (tstX - prevX) + (tstZ2 - prevZ) * (tstZ2 - prevZ));
1523 //LOG_ERROR("spells", "step = {}, distance of ray2 = {}", j, srange2);
1524 srange3 = sqrt((tstY - prevY) * (tstY - prevY) + (tstX - prevX) * (tstX - prevX) + (tstZ3 - prevZ) * (tstZ3 - prevZ));
1525 //LOG_ERROR("spells", "step = {}, distance of ray3 = {}", j, srange3);
1526
1527 if (srange1 < srange2)
1528 {
1529 tstZ = tstZ1;
1530 srange = srange1;
1531 }
1532 else if (srange3 < srange2)
1533 {
1534 tstZ = tstZ3;
1535 srange = srange3;
1536 }
1537 else
1538 {
1539 tstZ = tstZ2;
1540 srange = srange2;
1541 }
1542
1543 //LOG_ERROR("spells", "step on ground, number of cycle = {} , distance of step = {}, total path = {}", j, srange, totalpath);
1544 }
1545
1546 destx = tstX;
1547 desty = tstY;
1548 destz = tstZ;
1549
1550 totalpath += srange;
1551
1552 if (totalpath > distance)
1553 {
1554 overdistance = totalpath - distance;
1555 //LOG_ERROR("spells", "total path > than distance in 3D , need to move back a bit for save distance, total path = {}, overdistance = {}", totalpath, overdistance);
1556 }
1557
1558 bool col = m_caster->GetMap()->GetMapCollisionData().GetStaticTree().GetObjectHitPos(prevX, prevY, prevZ + 0.5f, tstX, tstY, tstZ + 0.5f, tstX, tstY, tstZ, -0.5f);
1559 // check dynamic collision
1560 bool dcol = m_caster->GetMap()->GetMapCollisionData().GetDynamicTree().GetObjectHitPos(phasemask, prevX, prevY, prevZ + 0.5f, tstX, tstY, tstZ + 0.5f, tstX, tstY, tstZ, -0.5f);
1561
1562 // collision occured
1563 if (col || dcol || (overdistance > 0.0f && !map->IsInWater(phasemask, tstX, tstY, ground, collisionHeight)) || (fabs(prevZ - tstZ) > maxtravelDistZ && (tstZ > prevZ)))
1564 {
1565 if ((overdistance > 0.0f) && (overdistance < 1.f))
1566 {
1567 destx = prevX + overdistance * cos(pos.GetOrientation());
1568 desty = prevY + overdistance * sin(pos.GetOrientation());
1569 //LOG_ERROR("spells", "(collision) collision occured 1");
1570 }
1571 else
1572 {
1573 // move back a bit
1574 destx = tstX - (0.6 * cos(pos.GetOrientation()));
1575 desty = tstY - (0.6 * sin(pos.GetOrientation()));
1576 //LOG_ERROR("spells", "(collision) collision occured 2");
1577 }
1578
1579 // highest available point
1580 destz1 = map->GetHeight(phasemask, destx, desty, prevZ + maxtravelDistZ, true, 25.0f);
1581 // upper or floor
1582 destz2 = map->GetHeight(phasemask, destx, desty, prevZ, true, 25.0f);
1583 //lower than floor
1584 destz3 = map->GetHeight(phasemask, destx, desty, prevZ - maxtravelDistZ / 2, true, 25.0f);
1585
1586 //distance of rays, will select the shortest in 3D
1587 srange1 = sqrt((desty - prevY) * (desty - prevY) + (destx - prevX) * (destx - prevX) + (destz1 - prevZ) * (destz1 - prevZ));
1588 srange2 = sqrt((desty - prevY) * (desty - prevY) + (destx - prevX) * (destx - prevX) + (destz2 - prevZ) * (destz2 - prevZ));
1589 srange3 = sqrt((desty - prevY) * (desty - prevY) + (destx - prevX) * (destx - prevX) + (destz3 - prevZ) * (destz3 - prevZ));
1590
1591 if (srange1 < srange2)
1592 destz = destz1;
1593 else if (srange3 < srange2)
1594 destz = destz3;
1595 else
1596 destz = destz2;
1597
1598 if (inwater && destz < prevZ && !wcol)
1599 destz = prevZ;
1600 //LOG_ERROR("spells", "(collision) destZ rewrited in prevZ");
1601
1602 // Don't make the player move backward from the xy adjustments by collisions.
1603 if ((DELTA_X > 0 && startx > destx) || (DELTA_X < 0 && startx < destx) ||
1604 (DELTA_Y > 0 && starty > desty) || (DELTA_Y < 0 && starty < desty))
1605 {
1606 destx = startx;
1607 desty = starty;
1608 destz = startz;
1609 }
1610
1611 break;
1612 }
1613 // we have correct destz now
1614 }
1615
1616 lastpos.Relocate(destx, desty, destz, pos.GetOrientation());
1617 dest = SpellDestination(lastpos);
1618 }
1619 else
1620 {
1621 float z = pos.GetPositionZ();
1622 bool col = m_caster->GetMap()->GetMapCollisionData().GetStaticTree().GetObjectHitPos(pos.GetPositionX(), pos.GetPositionY(), z, destx, desty, z, destx, desty, z, -0.5f);
1623 // check dynamic collision
1624 bool dcol = m_caster->GetMap()->GetMapCollisionData().GetDynamicTree().GetObjectHitPos(phasemask, pos.GetPositionX(), pos.GetPositionY(), z, destx, desty, z, destx, desty, z, -0.5f);
1625
1626 // collision occured
1627 if (col || dcol)
1628 {
1629 // move back a bit
1630 destx = destx - (0.6 * cos(pos.GetOrientation()));
1631 desty = desty - (0.6 * sin(pos.GetOrientation()));
1632 }
1633
1634 lastpos.Relocate(destx, desty, z, pos.GetOrientation());
1635 dest = SpellDestination(lastpos);
1636 //float range = sqrt((desty - pos.GetPositionY())*(desty - pos.GetPositionY()) + (destx - pos.GetPositionX())*(destx - pos.GetPositionX()));
1637 //LOG_ERROR("spells", "Blink number 2, in falling but at a hight, distance of blink = {}", range);
1638 }
1639 break;
1640 }
1641 default:
1642 {
1643 float dist = m_spellInfo->Effects[effIndex].CalcRadius(m_caster);
1644 float angle = targetType.CalcDirectionAngle();
1645 float objSize = m_caster->GetCombatReach();
1646
1647 switch (targetType.GetTarget())
1648 {
1650 dist = PET_FOLLOW_DIST;
1651 break;
1653 if (dist > objSize)
1654 dist = objSize + (dist - objSize) * float(rand_norm());
1655 break;
1660 {
1661 static float const DefaultTotemDistance = 3.0f;
1662 if (!m_spellInfo->Effects[effIndex].HasRadius())
1663 dist = DefaultTotemDistance;
1664 break;
1665 }
1666 default:
1667 break;
1668 }
1669
1670 if (dist < objSize)
1671 {
1672 dist = objSize;
1673 }
1674
1675 Position pos = dest._position;
1676 m_caster->MovePositionToFirstCollision(pos, dist, angle);
1677
1678 dest.Relocate(pos);
1679 break;
1680 }
1681 }
1682
1683 CallScriptDestinationTargetSelectHandlers(dest, effIndex, targetType);
1684 m_targets.SetDst(dest);
1685}
#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:8735
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:17142
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 
)
1761{
1762 WorldObject* target = nullptr;
1763 bool checkIfValid = true;
1764
1765 switch (targetType.GetTarget())
1766 {
1767 case TARGET_UNIT_CASTER:
1768 target = m_caster;
1769 checkIfValid = false;
1770 break;
1771 case TARGET_UNIT_MASTER:
1772 target = m_caster->GetCharmerOrOwner();
1773 break;
1774 case TARGET_UNIT_PET:
1775 target = m_caster->GetGuardianPet();
1776 if (!target)
1777 target = m_caster->GetCharm();
1778 break;
1780 if (m_caster->IsSummon())
1781 target = m_caster->ToTempSummon()->GetSummonerUnit();
1782 break;
1784 target = m_caster->GetVehicleBase();
1785 break;
1795 target = m_caster->GetVehicleKit()->GetPassenger(targetType.GetTarget() - TARGET_UNIT_PASSENGER_0);
1796 break;
1797 default:
1798 break;
1799 }
1800
1801 CallScriptObjectTargetSelectHandlers(target, effIndex, targetType);
1802
1803 if (target && target->ToUnit())
1804 AddUnitTarget(target->ToUnit(), 1 << effIndex, checkIfValid);
1805}
@ 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:14996
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 
)
1830{
1831 uint32 maxTargets = m_spellInfo->Effects[effIndex].ChainTarget;
1832 if (Player* modOwner = m_caster->GetSpellModOwner())
1833 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_JUMP_TARGETS, maxTargets, this);
1834
1835 if (maxTargets > 1)
1836 {
1837 // mark damage multipliers as used
1838 for (uint32 k = effIndex; k < MAX_SPELL_EFFECTS; ++k)
1839 if (effMask & (1 << k))
1840 m_damageMultipliers[k] = 1.0f;
1841 m_applyMultiplierMask |= effMask;
1842
1843 std::list<WorldObject*> targets;
1844 SearchChainTargets(targets, maxTargets - 1, target, targetType.GetObjectType(), targetType.GetCheckType(), targetType.GetSelectionCategory()
1845 , m_spellInfo->Effects[effIndex].ImplicitTargetConditions, targetType.GetTarget() == TARGET_UNIT_TARGET_CHAINHEAL_ALLY);
1846
1847 // Chain primary target is added earlier
1848 CallScriptObjectAreaTargetSelectHandlers(targets, effIndex, targetType);
1849
1850 for (std::list<WorldObject*>::iterator itr = targets.begin(); itr != targets.end(); ++itr)
1851 if (Unit* unitTarget = (*itr)->ToUnit())
1852 AddUnitTarget(unitTarget, effMask, false);
1853 }
1854}
@ 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:2103

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

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

Referenced by SelectEffectImplicitTargets().

◆ SelectImplicitConeTargets()

void Spell::SelectImplicitConeTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType,
uint32  effMask 
)
1218{
1219 if (targetType.GetReferenceType() != TARGET_REFERENCE_TYPE_CASTER)
1220 {
1221 ASSERT(false && "Spell::SelectImplicitConeTargets: received not implemented target reference type");
1222 return;
1223 }
1224 std::list<WorldObject*> targets;
1225 SpellTargetObjectTypes objectType = targetType.GetObjectType();
1226 SpellTargetCheckTypes selectionType = targetType.GetCheckType();
1227 ConditionList* condList = m_spellInfo->Effects[effIndex].ImplicitTargetConditions;
1228 float coneAngle = M_PI / 2;
1229 float radius = m_spellInfo->Effects[effIndex].CalcRadius(m_caster) * m_spellValue->RadiusMod;
1230
1231 if (uint32 containerTypeMask = GetSearcherTypeMask(objectType, condList))
1232 {
1233 Acore::WorldObjectSpellConeTargetCheck check(coneAngle, radius, m_caster, m_spellInfo, selectionType, condList);
1234 Acore::WorldObjectListSearcher<Acore::WorldObjectSpellConeTargetCheck> searcher(m_caster, targets, check, containerTypeMask);
1235 SearchTargets<Acore::WorldObjectListSearcher<Acore::WorldObjectSpellConeTargetCheck> >(searcher, containerTypeMask, m_caster, m_caster, radius);
1236
1237 CallScriptObjectAreaTargetSelectHandlers(targets, effIndex, targetType);
1238
1239 if (!targets.empty())
1240 {
1241 // Other special target selection goes here
1242 if (uint32 maxTargets = m_spellValue->MaxAffectedTargets)
1243 {
1245 Acore::Containers::RandomResize(targets, maxTargets);
1246 }
1247
1248 for (std::list<WorldObject*>::iterator itr = targets.begin(); itr != targets.end(); ++itr)
1249 {
1250 if (Unit* unit = (*itr)->ToUnit())
1251 {
1252 AddUnitTarget(unit, effMask, false);
1253 }
1254 else if (GameObject* gObjTarget = (*itr)->ToGameObject())
1255 {
1256 AddGOTarget(gObjTarget, effMask);
1257 }
1258 }
1259 }
1260 }
1261}
SpellTargetCheckTypes
Definition SpellInfo.h:114
SpellTargetObjectTypes
Definition SpellInfo.h:98

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

Referenced by SelectEffectImplicitTargets().

◆ SelectImplicitDestDestTargets()

void Spell::SelectImplicitDestDestTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType 
)
1725{
1726 // set destination to caster if no dest provided
1727 // can only happen if previous destination target could not be set for some reason
1728 // (not found nearby target, or channel target for example
1729 // maybe we should abort the spell in such case?
1730 CheckDst();
1731
1733
1734 switch (targetType.GetTarget())
1735 {
1739 case TARGET_DEST_DEST:
1740 return;
1741 default:
1742 {
1743 float angle = targetType.CalcDirectionAngle();
1744 float dist = m_spellInfo->Effects[effIndex].CalcRadius(m_caster);
1745 if (targetType.GetTarget() == TARGET_DEST_DEST_RANDOM)
1746 dist *= float(rand_norm());
1747
1748 Position pos = dest._position;
1749 m_caster->MovePosition(pos, dist, angle);
1750
1751 dest.Relocate(pos);
1752 break;
1753 }
1754 }
1755
1756 CallScriptDestinationTargetSelectHandlers(dest, effIndex, targetType);
1757 m_targets.ModDst(dest);
1758}
@ 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:435
SpellDestination const * GetDst() const
Definition Spell.cpp:395
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 
)
1104{
1105 if (targetType.GetReferenceType() != TARGET_REFERENCE_TYPE_CASTER)
1106 {
1107 ASSERT(false && "Spell::SelectImplicitNearbyTargets: received not implemented target reference type");
1108 return;
1109 }
1110
1111 float range = 0.0f;
1112 switch (targetType.GetCheckType())
1113 {
1114 case TARGET_CHECK_ENEMY:
1115 range = m_spellInfo->GetMaxRange(false, m_caster, this);
1116 break;
1117 case TARGET_CHECK_ALLY:
1118 case TARGET_CHECK_PARTY:
1119 case TARGET_CHECK_RAID:
1121 range = m_spellInfo->GetMaxRange(true, m_caster, this);
1122 break;
1123 case TARGET_CHECK_ENTRY:
1126 break;
1127 default:
1128 ASSERT(false && "Spell::SelectImplicitNearbyTargets: received not implemented selection check type");
1129 break;
1130 }
1131
1132 ConditionList* condList = m_spellInfo->Effects[effIndex].ImplicitTargetConditions;
1133
1134 // handle emergency case - try to use other provided targets if no conditions provided
1135 if (targetType.GetCheckType() == TARGET_CHECK_ENTRY && (!condList || condList->empty()))
1136 {
1137 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);
1138 switch (targetType.GetObjectType())
1139 {
1142 {
1143 if (focusObject)
1144 AddGOTarget(focusObject, effMask);
1145 return;
1146 }
1147 break;
1150 {
1151 if (focusObject)
1153 return;
1154 }
1155 break;
1156 default:
1157 break;
1158 }
1159 }
1160
1161 WorldObject* target = SearchNearbyTarget(range, targetType.GetObjectType(), targetType.GetCheckType(), condList);
1162 if (!target)
1163 {
1164 LOG_DEBUG("spells.aura", "Spell::SelectImplicitNearbyTargets: cannot find nearby target for spell ID {}, effect {}", m_spellInfo->Id, effIndex);
1165 return;
1166 }
1167
1168 CallScriptObjectTargetSelectHandlers(target, effIndex, targetType);
1169 if (!target)
1170 {
1171 //LOG_DEBUG("spells", "Spell::SelectImplicitNearbyTargets: OnObjectTargetSelect script hook for spell Id {} set nullptr target, effect {}", m_spellInfo->Id, effIndex);
1172 return;
1173 }
1174
1175 switch (targetType.GetObjectType())
1176 {
1178 {
1179 if (Unit* unit = target->ToUnit())
1180 {
1181 AddUnitTarget(unit, effMask, true, false);
1182 // xinef: important! if channeling spell have nearby entry, it has no unitTarget by default
1183 // and if channeled spell has target 77, it requires unitTarget, set it here!
1184 // xinef: if we have NO unit target
1185 if (!m_targets.GetUnitTarget())
1186 {
1188 }
1189 }
1190 else
1191 {
1192 //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);
1193 return;
1194 }
1195 break;
1196 }
1198 if (GameObject* gobjTarget = target->ToGameObject())
1199 AddGOTarget(gobjTarget, effMask);
1200 else
1201 {
1202 //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);
1203 return;
1204 }
1205 break;
1207 m_targets.SetDst(*target);
1208 break;
1209 default:
1210 ASSERT(false && "Spell::SelectImplicitNearbyTargets: received not implemented target object type");
1211 break;
1212 }
1213
1214 SelectImplicitChainTargets(effIndex, targetType, target, effMask);
1215}
@ 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:2081
void SelectImplicitChainTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType, WorldObject *target, uint32 effMask)
Definition Spell.cpp:1829

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

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 
)
1871{
1872 if (!m_targets.HasTraj())
1873 return;
1874
1875 float dist2d = m_targets.GetDist2d();
1876 if (!dist2d)
1877 return;
1878
1879 Position srcPos = *m_targets.GetSrcPos();
1881 float srcToDestDelta = m_targets.GetDstPos()->m_positionZ - srcPos.m_positionZ;
1882
1883 std::list<WorldObject*> targets;
1884 Acore::WorldObjectSpellTrajTargetCheck check(dist2d, &srcPos, m_caster, m_spellInfo, targetType.GetCheckType(), m_spellInfo->Effects[effIndex].ImplicitTargetConditions);
1886 SearchTargets<Acore::WorldObjectListSearcher<Acore::WorldObjectSpellTrajTargetCheck> > (searcher, GRID_MAP_TYPE_MASK_ALL, m_caster, &srcPos, dist2d);
1887 if (targets.empty())
1888 return;
1889
1891
1892 float b = tangent(m_targets.GetElevation());
1893 float a = (srcToDestDelta - dist2d * b) / (dist2d * dist2d);
1894 if (a > -0.0001f)
1895 a = 0.f;
1896
1897 // We should check if triggered spell has greater range (which is true in many cases, and initial spell has too short max range)
1898 // limit max range to 300 yards, sometimes triggered spells can have 50000yds
1899 float bestDist = m_spellInfo->GetMaxRange(false);
1900 if (SpellInfo const* triggerSpellInfo = sSpellMgr->GetSpellInfo(m_spellInfo->Effects[effIndex].TriggerSpell))
1901 bestDist = std::min(std::max(bestDist, triggerSpellInfo->GetMaxRange(false)), std::min(dist2d, 300.0f));
1902
1903 // GameObjects don't cast traj
1904 Unit* unitCaster = ASSERT_NOTNULL(m_caster->ToUnit());
1905 for (auto itr = targets.begin(); itr != targets.end(); ++itr)
1906 {
1907 if (m_spellInfo->CheckTarget(unitCaster, *itr, true) != SPELL_CAST_OK)
1908 continue;
1909
1910 if (Unit* unit = (*itr)->ToUnit())
1911 {
1912 if (unitCaster == *itr || unitCaster->IsOnVehicle(unit) || unit->GetVehicle())
1913 continue;
1914
1915 if (Creature* creatureTarget = unit->ToCreature())
1916 {
1917 if (!(creatureTarget->GetCreatureTemplate()->type_flags & CREATURE_TYPE_FLAG_COLLIDE_WITH_MISSILES))
1918 continue;
1919 }
1920 }
1921
1922 float const size = std::max((*itr)->GetCombatReach(), 1.0f);
1923 float const objDist2d = srcPos.GetExactDist2d(*itr);
1924 float const dz = (*itr)->GetPositionZ() - srcPos.m_positionZ;
1925
1926 float const horizontalDistToTraj = std::fabs(objDist2d * std::sin(srcPos.GetRelativeAngle(*itr)));
1927 float const sizeFactor = std::cos((horizontalDistToTraj / size) * (M_PI / 2.0f));
1928 float const distToHitPoint = std::max(objDist2d * std::cos(srcPos.GetRelativeAngle(*itr)) - size * sizeFactor, 0.0f);
1929 float const height = distToHitPoint * (a * distToHitPoint + b);
1930
1931 if (fabs(dz - height) > size + b / 2.0f + TRAJECTORY_MISSILE_SIZE)
1932 continue;
1933
1934 if (distToHitPoint < bestDist)
1935 {
1936 bestDist = distToHitPoint;
1937 break;
1938 }
1939 }
1940
1941 if (dist2d > bestDist)
1942 {
1943 float x = m_targets.GetSrcPos()->m_positionX + std::cos(unitCaster->GetOrientation()) * bestDist;
1944 float y = m_targets.GetSrcPos()->m_positionY + std::sin(unitCaster->GetOrientation()) * bestDist;
1945 float z = m_targets.GetSrcPos()->m_positionZ + bestDist * (a * bestDist + b);
1946
1947 SpellDestination dest(x, y, z, unitCaster->GetOrientation());
1948 CallScriptDestinationTargetSelectHandlers(dest, effIndex, targetType);
1949 m_targets.ModDst(dest);
1950 }
1951}
#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:1856
#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:1928
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 ( )
823{
824 // select targets for cast phase
826
827 uint32 processedAreaEffectsMask = 0;
828 for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i)
829 {
830 // not call for empty effect.
831 // Also some spells use not used effect targets for store targets for dummy effect in triggered spells
832 if (!m_spellInfo->Effects[i].IsEffect())
833 continue;
834
835 // set expected type of implicit targets to be sent to client
836 uint32 implicitTargetMask = GetTargetFlagMask(m_spellInfo->Effects[i].TargetA.GetObjectType()) | GetTargetFlagMask(m_spellInfo->Effects[i].TargetB.GetObjectType());
837 if (implicitTargetMask & TARGET_FLAG_UNIT)
839 if (implicitTargetMask & (TARGET_FLAG_GAMEOBJECT | TARGET_FLAG_GAMEOBJECT_ITEM))
841
842 SelectEffectImplicitTargets(SpellEffIndex(i), m_spellInfo->Effects[i].TargetA, processedAreaEffectsMask);
843 SelectEffectImplicitTargets(SpellEffIndex(i), m_spellInfo->Effects[i].TargetB, processedAreaEffectsMask);
844
845 // Select targets of effect based on effect type
846 // those are used when no valid target could be added for spell effect based on spell target type
847 // some spell effects use explicit target as a default target added to target map (like SPELL_EFFECT_LEARN_SPELL)
848 // some spell effects add target to target map only when target type specified (like SPELL_EFFECT_WEAPON)
849 // some spell effects don't add anything to target map (confirmed with sniffs) (like SPELL_EFFECT_DESTROY_ALL_TOTEMS)
851
852 if (m_targets.HasDst())
854
856 {
857 // maybe do this for all spells?
858 if (!focusObject && m_UniqueTargetInfo.empty() && m_UniqueGOTargetInfo.empty() && m_UniqueItemInfo.empty() && !m_targets.HasDst())
859 {
861 finish(false);
862 return;
863 }
864
865 uint8 mask = (1 << i);
866 for (auto ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
867 {
868 if (ihit->effectMask & mask)
869 {
871 break;
872 }
873 }
874 }
875 else if (m_auraScaleMask)
876 {
877 bool checkLvl = !m_UniqueTargetInfo.empty();
878 m_UniqueTargetInfo.erase(std::remove_if(std::begin(m_UniqueTargetInfo), std::end(m_UniqueTargetInfo), [&](TargetInfo const& targetInfo) -> bool
879 {
880 // remove targets which did not pass min level check
881 if (m_auraScaleMask && targetInfo.effectMask == m_auraScaleMask)
882 {
883 if (!targetInfo.scaleAura && targetInfo.targetGUID != m_caster->GetGUID())
884 return true;
885 }
886
887 return false;
888 }), std::end(m_UniqueTargetInfo));
889
890 if (checkLvl && m_UniqueTargetInfo.empty())
891 {
893 finish(false);
894 }
895 }
896 }
897
898 if (uint64 dstDelay = CalculateDelayMomentForDst())
899 m_delayMoment = dstDelay;
900}
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:929
void SelectExplicitTargets()
Definition Spell.cpp:789
void AddDestTarget(SpellDestination const &dest, uint32 effIndex)
Definition Spell.cpp:2518
void SelectEffectTypeImplicitTargets(uint8 effIndex)
Definition Spell.cpp:1953

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
4620{
4621 if (result == SPELL_CAST_OK)
4622 return;
4623
4624 WorldPacket data(SMSG_CAST_FAILED, 1 + 4 + 1);
4625 WriteCastResultInfo(data, caster, spellInfo, castCount, result, customError);
4626
4627 caster->SendDirectMessage(&data);
4628}
static void WriteCastResultInfo(WorldPacket &data, Player *caster, SpellInfo const *spellInfo, uint8 castCount, SpellCastResult result, SpellCustomErrors customError)
Definition Spell.cpp:4514
@ 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)
4631{
4632 if (result == SPELL_CAST_OK)
4633 return;
4634
4635 if (!m_caster->IsPlayer() || m_caster->IsCharmed())
4636 return;
4637
4638 if (m_caster->ToPlayer()->GetSession()->PlayerLoading()) // don't send cast results at loading time
4639 return;
4640
4641 // 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
4643 result = SPELL_FAILED_DONT_REPORT;
4644
4646}
@ 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)
5157{
5158 ObjectGuid channelTarget = m_targets.GetObjectTargetGUID();
5159 if (!channelTarget && !m_spellInfo->NeedsExplicitUnitTarget())
5160 if (m_UniqueTargetInfo.size() + m_UniqueGOTargetInfo.size() == 1) // this is for TARGET_SELECT_CATEGORY_NEARBY
5161 channelTarget = !m_UniqueTargetInfo.empty() ? m_UniqueTargetInfo.front().targetGUID : m_UniqueGOTargetInfo.front().targetGUID;
5162
5163 WorldPacket data(MSG_CHANNEL_START, (8 + 4 + 4));
5164 data << m_caster->GetPackGUID();
5165 data << uint32(m_spellInfo->Id);
5166 data << uint32(duration);
5167
5168 m_caster->SendMessageToSet(&data, true);
5169
5172
5173 m_timer = duration;
5174 if (channelTarget)
5176
5178}
@ 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)
5125{
5126 WorldPacket data(SMSG_SPELL_FAILURE, (8 + 1 + 4 + 1));
5127 data << m_caster->GetPackGUID();
5128 data << uint8(m_cast_count);
5129 data << uint32(m_spellInfo->Id);
5130 data << uint8(result);
5131 m_caster->SendMessageToSet(&data, true);
5132
5133 data.Initialize(SMSG_SPELL_FAILED_OTHER, (8 + 1 + 4 + 1));
5134 data << m_caster->GetPackGUID();
5135 data << uint8(m_cast_count);
5136 data << uint32(m_spellInfo->Id);
5137 data << uint8(result);
5138 m_caster->SendMessageToSet(&data, true);
5139}
@ 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 ( )
5024{
5025 WorldPacket data(SMSG_SPELLLOGEXECUTE, (8 + 4 + 4 + 4 + 4 + 8));
5026
5027 data << m_caster->GetPackGUID();
5028
5029 data << uint32(m_spellInfo->Id);
5030
5031 uint8 effCount = 0;
5032 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
5033 {
5034 if (m_effectExecuteData[i])
5035 ++effCount;
5036 }
5037
5038 if (!effCount)
5039 return;
5040
5041 data << uint32(effCount);
5042 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
5043 {
5044 if (!m_effectExecuteData[i])
5045 continue;
5046
5047 data << uint32(m_spellInfo->Effects[i].Effect); // spell effect
5048
5049 data.append(*m_effectExecuteData[i]);
5050
5051 delete m_effectExecuteData[i];
5052 m_effectExecuteData[i] = nullptr;
5053 }
5054 m_caster->SendMessageToSet(&data, true);
5055}
@ 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)
4649{
4650 if (result == SPELL_CAST_OK)
4651 return;
4652
4653 Unit* owner = m_caster->GetCharmerOrOwner();
4654 if (!owner)
4655 return;
4656
4657 Player* player = owner->ToPlayer();
4658 if (!player)
4659 return;
4660
4661 WorldPacket data(SMSG_PET_CAST_FAILED, 1 + 4 + 1);
4663
4664 player->SendDirectMessage(&data);
4665}
@ 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)
5181{
5182 // get resurrector name for creature resurrections, otherwise packet will be not accepted
5183 // for player resurrections the name is looked up by guid
5184 std::string const sentName(m_caster->IsPlayer()
5185 ? ""
5186 : m_caster->GetNameForLocaleIdx(target->GetSession()->GetSessionDbLocaleIndex()));
5187
5188 WorldPacket data(SMSG_RESURRECT_REQUEST, (8 + 4 + sentName.size() + 1 + 1 + 1 + 4));
5189 data << m_caster->GetGUID();
5190 data << uint32(sentName.size() + 1);
5191
5192 data << sentName;
5193 data << uint8(0); // null terminator
5194
5195 data << uint8(m_caster->IsPlayer() ? 0 : 1); // "you'll be afflicted with resurrection sickness"
5196 // override delay sent with SMSG_CORPSE_RECLAIM_DELAY, set instant resurrection for spells with this attribute
5198 data << uint32(0);
5199 target->SendDirectMessage(&data);
5200}
@ 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 ( )
4300{
4301 // xinef: properly add creature cooldowns
4302 if (!m_caster->IsPlayer())
4303 {
4305 {
4306 // xinef: this should be added here
4307 //m_caster->AddSpellCooldown(m_spellInfo->Id, 0, 0);
4308
4309 // xinef: this adds cooldowns to vehicle spells which misses them client-side (when we overwrote dbc info in eg.)
4312 {
4313 WorldPacket data(SMSG_SPELL_COOLDOWN, 8 + 1 + 4 + 4);
4314 data << m_caster->GetGUID();
4316 data << uint32(m_spellInfo->Id);
4318 player->SendDirectMessage(&data);
4319 }
4320 }
4321 return;
4322 }
4323
4324 Player* _player = m_caster->ToPlayer();
4325
4326 // mana/health/etc potions, disabled by client (until combat out as declarate)
4328 {
4329 // need in some way provided data for Spell::finish SendCooldownEvent
4330 _player->SetLastPotionId(m_CastItem->GetEntry());
4331 return;
4332 }
4333
4334 // have infinity cooldown but set at aura apply
4335 // do not set cooldown for triggered spells (needed by reincarnation)
4340 return;
4341
4343}
@ 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:1829
void AddSpellAndCategoryCooldowns(SpellInfo const *spellInfo, uint32 itemId, Spell *spell=nullptr, bool infinityCooldown=false)
Definition Player.cpp:10858
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 ( )
4748{
4749 // not send invisible spell casting
4750 if (!IsNeedSendToClient(true))
4751 return;
4752
4753 //LOG_DEBUG("spells.aura", "Sending SMSG_SPELL_GO id={}", m_spellInfo->Id);
4754
4755 uint32 castFlags = CAST_FLAG_UNKNOWN_9;
4756
4757 // triggered spells with spell visual != 0
4759 castFlags |= CAST_FLAG_PENDING;
4760
4762 castFlags |= CAST_FLAG_PROJECTILE; // arrows/bullets visual
4763
4764 // should only be sent to self, but the current messaging doesn't make that possible
4765 if (m_caster->IsPlayer() || m_caster->IsPet())
4766 {
4767 switch (m_spellInfo->PowerType)
4768 {
4769 case POWER_HEALTH:
4770 break;
4771 case POWER_RUNE:
4772 castFlags |= CAST_FLAG_POWER_LEFT_SELF;
4773 break;
4774 default:
4775 if (m_powerCost != 0)
4776 {
4777 castFlags |= CAST_FLAG_POWER_LEFT_SELF;
4778 }
4779 break;
4780 }
4781 }
4782
4783 if ((m_caster->IsPlayer())
4787 {
4788 castFlags |= CAST_FLAG_NO_GCD; // not needed, but Blizzard sends it
4789 castFlags |= CAST_FLAG_RUNE_LIST; // rune cooldowns list
4790 }
4791
4793 castFlags |= CAST_FLAG_RUNE_LIST; // rune cooldowns list
4794
4795 if (m_targets.HasTraj())
4796 castFlags |= CAST_FLAG_ADJUST_MISSILE;
4797
4799 castFlags |= CAST_FLAG_NO_GCD;
4800
4801 PackedGuid realCasterGUID = m_caster->GetPackGUID();
4802 if (TempSummon const* tempSummon = m_caster->ToTempSummon())
4803 {
4804 if (tempSummon->GetEntry() == WORLD_TRIGGER)
4805 {
4806 if (GameObject* casterGameobject = tempSummon->GetSummonerGameObject())
4807 {
4808 realCasterGUID = casterGameobject->GetPackGUID();
4809 }
4810 }
4811 }
4812
4813 WorldPacket data(SMSG_SPELL_GO, 150); // guess size
4814
4815 if (m_CastItem)
4816 data << m_CastItem->GetPackGUID();
4817 else
4818 data << realCasterGUID;
4819
4820 data << realCasterGUID;
4821 data << uint8(m_cast_count); // pending spell cast?
4822 data << uint32(m_spellInfo->Id); // spellId
4823 data << uint32(castFlags); // cast flags
4824 data << uint32(GameTime::GetGameTimeMS().count()); // timestamp
4825
4826 WriteSpellGoTargets(&data);
4827
4828 m_targets.Write(data);
4829
4830 if (castFlags & CAST_FLAG_POWER_LEFT_SELF)
4832
4833 if (castFlags & CAST_FLAG_RUNE_LIST) // rune cooldowns list
4834 {
4835 //TODO: There is a crash caused by a spell with CAST_FLAG_RUNE_LIST casted by a creature
4836 //The creature is the mover of a player, so HandleCastSpellOpcode uses it as the caster
4837 if (Player* player = m_caster->ToPlayer())
4838 {
4839 uint8 runeMaskInitial = m_runesState;
4840 uint8 runeMaskAfterCast = player->GetRunesState();
4841 data << uint8(runeMaskInitial); // runes state before
4842 data << uint8(runeMaskAfterCast); // runes state after
4843 for (uint8 i = 0; i < MAX_RUNES; ++i)
4844 {
4845 uint8 mask = (1 << i);
4846 if (mask & runeMaskInitial && !(mask & runeMaskAfterCast)) // usable before andon cooldown now...
4847 {
4848 // float casts ensure the division is performed on floats as we need float result
4849 float baseCd = float(player->GetRuneBaseCooldown(i, true));
4850 data << uint8((baseCd - float(player->GetRuneCooldown(i))) / baseCd * 255); // rune cooldown passed
4851 }
4852 }
4853 }
4854 }
4855 if (castFlags & CAST_FLAG_ADJUST_MISSILE)
4856 {
4857 data << m_targets.GetElevation();
4859 }
4860
4861 if (castFlags & CAST_FLAG_PROJECTILE)
4862 WriteAmmoToPacket(&data);
4863
4864 if (castFlags & CAST_FLAG_VISUAL_CHAIN)
4865 {
4866 data << uint32(0);
4867 data << uint32(0);
4868 }
4869
4871 {
4872 data << uint8(0);
4873 }
4874
4875 m_caster->SendMessageToSet(&data, true);
4876}
@ 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:178
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:4963
void WriteAmmoToPacket(WorldPacket *data)
Definition Spell.cpp:4878
bool IsNeedSendToClient(bool go) const
Definition Spell.cpp:8110
@ 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 ( )
4668{
4669 if (!IsNeedSendToClient(false))
4670 return;
4671
4672 //LOG_DEBUG("spells.aura", "Sending SMSG_SPELL_START id={}", m_spellInfo->Id);
4673
4674 uint32 castFlags = CAST_FLAG_HAS_TRAJECTORY;
4675
4677 castFlags |= CAST_FLAG_PENDING;
4678
4680 castFlags |= CAST_FLAG_PROJECTILE;
4681
4682 if (m_caster->IsPlayer() || m_caster->IsPet())
4683 {
4684 switch (m_spellInfo->PowerType)
4685 {
4686 case POWER_HEALTH:
4687 break;
4688 case POWER_RUNE:
4689 castFlags |= CAST_FLAG_POWER_LEFT_SELF;
4690 break;
4691 default:
4692 if (m_powerCost != 0)
4693 {
4694 castFlags |= CAST_FLAG_POWER_LEFT_SELF;
4695 }
4696 break;
4697 }
4698 }
4699
4701 castFlags |= CAST_FLAG_NO_GCD; // not needed, but Blizzard sends it
4702
4703 PackedGuid realCasterGUID = m_caster->GetPackGUID();
4704 if (TempSummon const* tempSummon = m_caster->ToTempSummon())
4705 {
4706 if (tempSummon->GetEntry() == WORLD_TRIGGER)
4707 {
4708 if (GameObject* casterGameobject = tempSummon->GetSummonerGameObject())
4709 {
4710 realCasterGUID = casterGameobject->GetPackGUID();
4711 }
4712 }
4713 }
4714
4715 WorldPacket data(SMSG_SPELL_START, (8 + 8 + 4 + 4 + 2));
4716 if (m_CastItem)
4717 data << m_CastItem->GetPackGUID();
4718 else
4719 data << realCasterGUID;
4720
4721 data << realCasterGUID;
4722 data << uint8(m_cast_count); // pending spell cast?
4723 data << uint32(m_spellInfo->Id); // spellId
4724 data << uint32(castFlags); // cast flags
4725 data << int32(m_timer); // delay?
4726
4727 m_targets.Write(data);
4728
4729 if (castFlags & CAST_FLAG_POWER_LEFT_SELF)
4731
4732 if (castFlags & CAST_FLAG_PROJECTILE)
4733 WriteAmmoToPacket(&data);
4734
4735 if (castFlags & CAST_FLAG_UNKNOWN_23)
4736 {
4737 data << uint32(0);
4738 data << uint32(0);
4739 }
4740
4741 m_caster->SendMessageToSet(&data, true);
4742
4745}
@ 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 
)
8462{
8463 switch (mod)
8464 {
8466 m_spellValue->EffectBasePoints[0] = m_spellInfo->Effects[EFFECT_0].CalcBaseValue(value);
8467 break;
8469 m_spellValue->EffectBasePoints[1] = m_spellInfo->Effects[EFFECT_1].CalcBaseValue(value);
8470 break;
8472 m_spellValue->EffectBasePoints[2] = m_spellInfo->Effects[EFFECT_2].CalcBaseValue(value);
8473 break;
8475 m_spellValue->RadiusMod = (float)value / 10000;
8476 break;
8479 break;
8482 break;
8484 m_spellValue->AuraDuration = value;
8485 break;
8487 m_spellValue->ForcedCritResult = (bool)value;
8488 break;
8490 m_spellValue->MiscVal[0] = value;
8491 break;
8493 m_spellValue->MiscVal[1] = value;
8494 break;
8496 m_spellValue->MiscVal[2] = value;
8497 break;
8498 }
8499}
@ 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
5974{
5975 Unit* caster = m_originalCaster;
5976 if (!caster)
5977 return;
5978
5979 if (caster->IsTotem())
5980 caster = caster->ToTotem()->GetOwner();
5981 else if (caster->IsPet())
5982 if (Unit* owner = caster->GetOwner())
5983 caster = owner;
5984
5985 // in another case summon new
5986 uint8 summonLevel = caster->GetLevel();
5987
5988 // level of pet summoned using engineering item based at engineering skill level
5989 if (m_CastItem && caster->IsPlayer())
5990 if (ItemTemplate const* proto = m_CastItem->GetTemplate())
5991 {
5992 // xinef: few special cases
5993 if (proto->RequiredSkill == SKILL_ENGINEERING)
5994 {
5995 if (uint16 skill202 = caster->ToPlayer()->GetSkillValue(SKILL_ENGINEERING))
5996 summonLevel = skill202 / 5;
5997 }
5998
5999 switch (m_spellInfo->Id)
6000 {
6001 // Dragon's Call
6002 case 13049:
6003 summonLevel = 55;
6004 break;
6005
6006 // Cleansed Timberling Heart: Summon Timberling
6007 case 5666:
6008 summonLevel = 7;
6009 break;
6010
6011 // Glowing Cat Figurine: Summon Ghost Saber
6012 case 6084:
6013 // minLevel 19, maxLevel 20
6014 summonLevel = 20;
6015 break;
6016
6017 // Spiked Collar: Summon Felhunter
6018 case 8176:
6019 summonLevel = 30;
6020 break;
6021
6022 // Dog Whistle: Summon Tracking Hound
6023 case 9515:
6024 summonLevel = 30;
6025 break;
6026
6027 // Barov Peasant Caller: Death by Peasant
6028 case 18307:
6029 case 18308:
6030 summonLevel = 60;
6031 break;
6032
6033 // Thornling Seed: Plant Thornling
6034 case 22792:
6035 summonLevel = 60;
6036 break;
6037
6038 // Cannonball Runner: Summon Crimson Cannon
6039 case 6251:
6040 summonLevel = 61;
6041 break;
6042 }
6043 }
6044
6045 summonLevel = std::min<uint8>(sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL) + sWorld->getIntConfig(CONFIG_WORLD_BOSS_LEVEL_DIFF), std::max<uint8>(1U, summonLevel));
6046
6047 float radius = 5.0f;
6048 int32 duration = m_spellInfo->GetDuration();
6049
6050 if (Player* modOwner = m_originalCaster->GetSpellModOwner())
6051 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_DURATION, duration);
6052
6053 //TempSummonType summonType = (duration == 0) ? TEMPSUMMON_DEAD_DESPAWN : TEMPSUMMON_TIMED_DESPAWN;
6054 Map* map = caster->GetMap();
6055 TempSummon* summon = nullptr;
6056
6057 uint32 currMinionsCount = m_caster->m_Controlled.size();
6058 uint32 totalNumGuardians = numGuardians + currMinionsCount;
6059
6060 for (uint32 count = 0; count < numGuardians; ++count)
6061 {
6062 Position pos;
6063
6064 // xinef: do not use precalculated position for effect summon pet in this function
6065 // it means it was cast by NPC and should have its position overridden unless the
6066 // target position is specified in the DB AND the effect has no or zero radius
6067 if ((totalNumGuardians == 1 && GetSpellInfo()->Effects[i].Effect != SPELL_EFFECT_SUMMON_PET) ||
6068 (GetSpellInfo()->Effects[i].TargetA.GetTarget() == TARGET_DEST_DB &&
6069 (!GetSpellInfo()->Effects[i].HasRadius() || GetSpellInfo()->Effects[i].RadiusEntry->RadiusMax == 0)))
6070 {
6071 pos = *destTarget;
6072 }
6073 else
6074 {
6075 // randomize position
6076 pos = m_caster->GetRandomPoint(*destTarget, radius);
6077 }
6078
6079 summon = map->SummonCreature(entry, pos, properties, duration, caster, m_spellInfo->Id, 0, personalSpawn);
6080 if (!summon)
6081 return;
6082
6083 // xinef: set calculated level
6084 summon->SetLevel(summonLevel);
6085
6086 // if summonLevel changed, set stats for calculated level
6087 if (summonLevel != caster->GetLevel())
6088 {
6089 ((Guardian*)summon)->InitStatsForLevel(summonLevel);
6090 }
6091
6092 // xinef: if we have more than one guardian, change follow angle
6093 if (summon->HasUnitTypeMask(UNIT_MASK_MINION) && totalNumGuardians > 1)
6094 ((Minion*)summon)->SetFollowAngle(m_caster->GetAbsoluteAngle(pos.GetPositionX(), pos.GetPositionY()));
6095 //else if (summon->HasUnitTypeMask(UNIT_MASK_MINION) && m_targets.HasDst())
6096 // ((Minion*)summon)->SetFollowAngle(m_caster->GetAngle(summon));
6097
6098 // xinef: move this here, some auras are added in initstatsforlevel!
6099 if (!summon->IsInCombat() && !summon->IsTrigger())
6100 {
6101 // summon->AI()->EnterEvadeMode();
6102 summon->GetMotionMaster()->Clear(false);
6104 }
6105
6106 if (properties && properties->Category == SUMMON_CATEGORY_ALLY)
6107 summon->SetFaction(caster->GetFaction());
6108
6110 }
6111}
@ SKILL_ENGINEERING
Definition SharedDefines.h:3156
@ CONFIG_MAX_PLAYER_LEVEL
Definition WorldConfig.h:189
@ CONFIG_WORLD_BOSS_LEVEL_DIFF
Definition WorldConfig.h:238
bool IsTrigger() const
Definition Creature.h:80
Definition TemporarySummon.h:87
Unit * GetOwner() const
Definition TemporarySummon.cpp:390
void SetLevel(uint8 lvl, bool showLevelChange=true)
Definition Unit.cpp:12323
virtual float GetFollowAngle() const
Definition Unit.h:1896

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 ( )
5330{
5332 {
5334
5335 // wands don't have ammo
5336 if (!pItem || pItem->IsBroken() || pItem->GetTemplate()->SubClass == ITEM_SUBCLASS_WEAPON_WAND)
5337 return;
5338
5339 if (pItem->GetTemplate()->InventoryType == INVTYPE_THROWN)
5340 {
5341 if (pItem->GetMaxStackCount() == 1)
5342 {
5343 // decrease durability for non-stackable throw weapon
5345 }
5346 else if (!sWorld->getBoolConfig(CONFIG_ENABLE_INFINITEAMMO))
5347 {
5348 // decrease items amount for stackable throw weapon
5349 uint32 count = 1;
5350 m_caster->ToPlayer()->DestroyItemCount(pItem, count, true);
5351 }
5352 }
5353 else if (!sWorld->getBoolConfig(CONFIG_ENABLE_INFINITEAMMO))
5355 m_caster->ToPlayer()->DestroyItemCount(ammo, 1, true);
5356 }
5357}
@ 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:145
uint32 GetMaxStackCount() const
Definition Item.h:274
void DurabilityPointLossForEquipSlot(EquipmentSlots slot)
Definition Player.cpp:4734

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 ( )
5203{
5204 if (!m_CastItem || !m_caster->IsPlayer())
5205 return;
5206
5207 // not remove cast item at triggered spell (equipping, weapon damage, etc)
5209 return;
5210
5211 ItemTemplate const* proto = m_CastItem->GetTemplate();
5212
5213 if (!proto)
5214 {
5215 // This code is to avoid a crash
5216 // I'm not sure, if this is really an error, but I guess every item needs a prototype
5217 LOG_ERROR("spells", "Cast item has no item prototype {}", m_CastItem->GetGUID().ToString());
5218 return;
5219 }
5220
5221 bool expendable = false;
5222 bool withoutCharges = false;
5223
5224 for (int i = 0; i < MAX_ITEM_PROTO_SPELLS; ++i)
5225 {
5226 if (proto->Spells[i].SpellId)
5227 {
5228 // item has limited charges
5229 if (proto->Spells[i].SpellCharges)
5230 {
5231 if (proto->Spells[i].SpellCharges < 0)
5232 expendable = true;
5233
5234 int32 charges = m_CastItem->GetSpellCharges(i);
5235
5236 // item has charges left
5237 if (charges)
5238 {
5239 (charges > 0) ? --charges : ++charges; // std::abs(charges) less at 1 after use
5240 if (proto->Stackable == 1)
5241 m_CastItem->SetSpellCharges(i, charges);
5243 }
5244
5245 // all charges used
5246 withoutCharges = (charges == 0);
5247 }
5248 }
5249 }
5250
5251 if (expendable && withoutCharges)
5252 {
5253 uint32 count = 1;
5254 m_caster->ToPlayer()->DestroyItemCount(m_CastItem, count, true);
5255
5256 // prevent crash at access to deleted m_targets.GetItemTarget
5258 m_targets.SetItemTarget(nullptr);
5259
5260 m_CastItem = nullptr;
5262 }
5263}
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 ( )
5266{
5268 return;
5269
5270 //Don't take power if the spell is cast while .cheat power is enabled.
5271 if (m_caster->IsPlayer())
5273 return;
5274
5276 bool hit = true;
5277 if (m_caster->IsPlayer())
5278 {
5280 if (ObjectGuid targetGUID = m_targets.GetUnitTargetGUID())
5281 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
5282 if (ihit->targetGUID == targetGUID)
5283 {
5284 if (ihit->missCondition != SPELL_MISS_NONE && ihit->missCondition != SPELL_MISS_BLOCK && ihit->missCondition != SPELL_MISS_ABSORB && ihit->missCondition != SPELL_MISS_REFLECT)
5285 {
5286 hit = false;
5287 //lower spell cost on fail (by talent aura)
5288 if (Player* modOwner = m_caster->ToPlayer()->GetSpellModOwner())
5289 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_SPELL_COST_REFUND_ON_FAIL, m_powerCost, this);
5290 }
5291 break;
5292 }
5293 }
5294
5295 if (PowerType == POWER_RUNE)
5296 {
5297 TakeRunePower(hit);
5298 return;
5299 }
5300
5301 if (!m_powerCost)
5302 return;
5303
5304 // health as power used
5305 if (PowerType == POWER_HEALTH)
5306 {
5308 return;
5309 }
5310
5311 if (PowerType >= MAX_POWERS)
5312 {
5313 LOG_ERROR("spells", "Spell::TakePower: Unknown power type '{}'", PowerType);
5314 return;
5315 }
5316
5317 if (hit)
5319 else
5321
5322 // Set the five second timer
5323 if (PowerType == POWER_MANA && m_powerCost > 0)
5324 {
5326 }
5327}
@ SPELL_MISS_ABSORB
Definition SharedDefines.h:1533
@ SPELLMOD_SPELL_COST_REFUND_ON_FAIL
Definition SpellDefines.h:106
void TakeRunePower(bool didHit)
Definition Spell.cpp:5413
int32 ModifyHealth(int32 val)
Definition Unit.cpp:10966
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 ( )
5483{
5484 if (!m_caster->IsPlayer())
5485 return;
5486
5487 ItemTemplate const* castItemTemplate = m_CastItem ? m_CastItem->GetTemplate() : nullptr;
5488
5489 // do not take reagents for these item casts
5490 if (castItemTemplate && castItemTemplate->HasFlag(ITEM_FLAG_NO_REAGENT_COST))
5491 return;
5492
5493 Player* p_caster = m_caster->ToPlayer();
5494 if (p_caster->CanNoReagentCast(m_spellInfo))
5495 return;
5496
5497 for (uint32 x = 0; x < MAX_SPELL_REAGENTS; ++x)
5498 {
5499 if (m_spellInfo->Reagent[x] <= 0)
5500 continue;
5501
5502 uint32 itemid = m_spellInfo->Reagent[x];
5503 uint32 itemcount = m_spellInfo->ReagentCount[x];
5504
5505 // if CastItem is also spell reagent
5506 if (castItemTemplate && castItemTemplate->ItemId == itemid)
5507 {
5508 for (int s = 0; s < MAX_ITEM_PROTO_SPELLS; ++s)
5509 {
5510 // CastItem will be used up and does not count as reagent
5511 int32 charges = m_CastItem->GetSpellCharges(s);
5512 if (castItemTemplate->Spells[s].SpellCharges < 0 && std::abs(charges) < 2)
5513 {
5514 ++itemcount;
5515 break;
5516 }
5517 }
5518
5519 m_CastItem = nullptr;
5521 }
5522
5523 // if GetItemTarget is also spell reagent
5524 if (m_targets.GetItemTargetEntry() == itemid)
5525 m_targets.SetItemTarget(nullptr);
5526
5527 p_caster->DestroyItemCount(itemid, itemcount, true);
5528 }
5529}
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)
5414{
5416 return;
5417
5418 SpellRuneCostEntry const* runeCostData = sSpellRuneCostStore.LookupEntry(m_spellInfo->RuneCostID);
5419 if (!runeCostData || (runeCostData->NoRuneCost() && runeCostData->NoRunicPowerGain()))
5420 return;
5421
5422 Player* player = m_caster->ToPlayer();
5423 m_runesState = player->GetRunesState(); // store previous state
5424
5425 int32 runeCost[NUM_RUNE_TYPES]; // blood, frost, unholy, death
5426
5427 for (uint32 i = 0; i < RUNE_DEATH; ++i)
5428 {
5429 runeCost[i] = runeCostData->RuneCost[i];
5430 if (Player* modOwner = m_caster->GetSpellModOwner())
5431 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_COST, runeCost[i], this);
5432 }
5433
5434 runeCost[RUNE_DEATH] = 0; // calculated later
5435
5436 for (uint32 i = 0; i < MAX_RUNES; ++i)
5437 {
5438 RuneType rune = player->GetCurrentRune(i);
5439 if (!player->GetRuneCooldown(i) && runeCost[rune] > 0)
5440 {
5441 player->SetRuneCooldown(i, didHit ? player->GetRuneBaseCooldown(i, false) : uint32(RUNE_MISS_COOLDOWN));
5442 player->SetLastUsedRune(rune);
5443 runeCost[rune]--;
5444 }
5445 }
5446
5447 // Xinef: firstly consume death runes of base type
5448 // Xinef: in second loop consume all available
5449 for (uint8 loop = 0; loop < 2; ++loop)
5450 {
5451 runeCost[RUNE_DEATH] = runeCost[RUNE_BLOOD] + runeCost[RUNE_UNHOLY] + runeCost[RUNE_FROST];
5452 if (runeCost[RUNE_DEATH] > 0)
5453 {
5454 for (uint8 i = 0; i < MAX_RUNES; ++i)
5455 {
5456 RuneType rune = player->GetCurrentRune(i);
5457 if (!player->GetRuneCooldown(i) && rune == RUNE_DEATH && (loop ? true : (runeCost[player->GetBaseRune(i)] > 0)))
5458 {
5459 player->SetRuneCooldown(i, didHit ? player->GetRuneBaseCooldown(i, false) : uint32(RUNE_MISS_COOLDOWN));
5460 player->SetLastUsedRune(rune);
5461 runeCost[rune]--;
5462 if (!loop)
5463 runeCost[player->GetBaseRune(i)]--;
5464
5465 // keep Death Rune type if missed
5466 if (didHit)
5467 player->RestoreBaseRune(i);
5468
5469 if (runeCost[RUNE_DEATH] == 0)
5470 break;
5471 }
5472 }
5473 }
5474 }
5475
5476 // you can gain some runic power when use runes
5477 if (didHit)
5478 if (int32 rp = int32(runeCostData->runePowerGain * sWorld->getRate(RATE_POWER_RUNICPOWER_INCOME)))
5479 player->ModifyPower(POWER_RUNIC_POWER, int32(rp));
5480}
@ 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:395
void SetLastUsedRune(RuneType type)
Definition Player.h:2550
uint32 GetRuneBaseCooldown(uint8 index, bool skipGrace)
Definition Player.cpp:13423
void RestoreBaseRune(uint8 index)
Definition Player.cpp:13452
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
8879{
8881 if (!gcd)
8882 {
8883 // Xinef: fix for charmed pet spells with no cooldown info
8885 gcd = MIN_GCD;
8886 else
8887 return;
8888 }
8889
8890 if (m_caster->IsPlayer())
8892 return;
8893
8894 // Global cooldown can't leave range 1..1.5 secs
8895 // There are some spells (mostly not casted directly by player) that have < 1 sec and > 1.5 sec global cooldowns
8896 // but as tests show are not affected by any spell mods.
8898 {
8899 // gcd modifier auras are applied only to own spells and only players have such mods
8900 if (m_caster->IsPlayer())
8902
8903 // Apply haste rating
8906 {
8907 gcd = int32(float(gcd) * m_caster->GetFloatValue(UNIT_MOD_CAST_SPEED));
8908 }
8909
8910 if (gcd < MIN_GCD)
8911 gcd = MIN_GCD;
8912 else if (gcd > MAX_GCD)
8913 gcd = MAX_GCD;
8914 }
8915
8916 // Only players or controlled units have global cooldown
8917 if (m_caster->GetCharmInfo())
8919 else if (m_caster->IsPlayer())
8921}
@ SPELLMOD_GLOBAL_COOLDOWN
Definition SpellDefines.h:97
@ MIN_GCD
Definition Spell.cpp:8863
@ MAX_GCD
Definition Spell.cpp:8864
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)
4346{
4347 // update pointers based at it's GUIDs
4348 if (!UpdatePointers())
4349 {
4350 // cancel the spell if UpdatePointers() returned false, something wrong happened there
4351 cancel();
4352 return;
4353 }
4354
4356 {
4357 LOG_DEBUG("spells.aura", "Spell {} is cancelled due to removal of target.", m_spellInfo->Id);
4358 cancel();
4359 return;
4360 }
4361
4362 // check if the player caster has moved before the spell finished
4363 // xinef: added preparing state (real cast, skip channels as they have other flags for this)
4364 if ((m_caster->IsPlayer() && m_timer != 0) &&
4367 {
4368 // don't cancel for melee, autorepeat, triggered and instant spells
4370 cancel(true);
4371 }
4372
4373 switch (m_spellState)
4374 {
4376 {
4377 if (m_timer > 0)
4378 {
4379 if (difftime >= (uint32)m_timer)
4380 m_timer = 0;
4381 else
4382 m_timer -= difftime;
4383 }
4384
4385 if (m_timer == 0 && !IsNextMeleeSwingSpell() && !IsAutoRepeat())
4386 // don't CheckCast for instant spells - done in spell::prepare, skip duplicate checks, needed for range checks for example
4387 cast(!m_casttime);
4388 break;
4389 }
4391 {
4392 if (m_timer)
4393 {
4394 if (m_timer > 0)
4395 {
4396 if (difftime >= (uint32)m_timer)
4397 m_timer = 0;
4398 else
4399 m_timer -= difftime;
4400 }
4401 }
4402
4403 if (m_timer == 0)
4404 {
4406
4407 finish();
4408
4409 // 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
4410 if (Creature* creatureCaster = m_caster->ToCreature())
4411 if (creatureCaster->IsAIEnabled)
4412 creatureCaster->AI()->OnChannelFinished(m_spellInfo);
4413 }
4414 // Xinef: Dont update channeled target list on last tick, allow auras to update duration properly
4415 // Xinef: Added this strange check because of diffrent update routines for players / creatures
4416 // Xinef: If creature gets new aura in 800ms and in 840ms its updated with diff 270, not 40 is removed from duration but 270
4417 // Xinef: so the aura can be removed in different updates for all units
4418 else if ((m_timer < 0 || m_timer > 300) && !UpdateChanneledTargetList())
4419 {
4420 LOG_DEBUG("spells.aura", "Channeled spell {} is removed due to lack of targets", m_spellInfo->Id);
4422 finish();
4423 }
4424 break;
4425 }
4426 default:
4427 break;
4428 }
4429}
bool UpdateChanneledTargetList()
Definition Spell.cpp:3316

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
3317{
3318 // Not need check return true
3320 return true;
3321
3322 uint8 channelTargetEffectMask = m_channelTargetEffectMask;
3323 uint8 channelAuraMask = 0;
3324 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
3326 channelAuraMask |= 1 << i;
3327
3328 channelAuraMask &= channelTargetEffectMask;
3329
3330 float range = 0;
3331 if (channelAuraMask)
3332 {
3334 if (range == 0)
3335 for(int i = EFFECT_0; i <= EFFECT_2; ++i)
3336 if (channelAuraMask & (1 << i) && m_spellInfo->Effects[i].RadiusEntry)
3337 {
3338 range = m_spellInfo->Effects[i].CalcRadius(nullptr, nullptr);
3339 break;
3340 }
3341
3342 if (Player* modOwner = m_caster->GetSpellModOwner())
3343 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_RANGE, range, this);
3344
3345 // xinef: add little tolerance level
3346 range += std::min(3.0f, range * 0.1f); // 10% but no more than 3yd
3347 }
3348
3349 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
3350 {
3351 if (ihit->missCondition == SPELL_MISS_NONE && (channelTargetEffectMask & ihit->effectMask))
3352 {
3353 Unit* unit = m_caster->GetGUID() == ihit->targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID);
3354
3355 if (!unit)
3356 continue;
3357
3358 if (IsValidDeadOrAliveTarget(unit))
3359 {
3360 if (channelAuraMask & ihit->effectMask)
3361 {
3363 {
3364 if (m_caster != unit)
3365 {
3366 if (!m_caster->IsWithinDistInMap(unit, range))
3367 {
3368 ihit->effectMask &= ~aurApp->GetEffectMask();
3369 unit->RemoveAura(aurApp);
3370 continue;
3371 }
3372 // Xinef: Update Orientation server side (non players wont sent appropriate packets)
3375 }
3376 }
3377 else // aura is dispelled
3378 continue;
3379 }
3380
3381 channelTargetEffectMask &= ~ihit->effectMask; // remove from need alive mask effect that have alive target
3382 }
3383 }
3384 }
3385
3386 // Xinef: not all effects are covered, remove applications from all targets
3387 if (channelTargetEffectMask != 0)
3388 {
3389 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
3390 if (ihit->missCondition == SPELL_MISS_NONE && (channelAuraMask & ihit->effectMask))
3391 if (Unit* unit = m_caster->GetGUID() == ihit->targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID))
3392 if (IsValidDeadOrAliveTarget(unit))
3394 {
3395 ihit->effectMask &= ~aurApp->GetEffectMask();
3396 unit->RemoveAura(aurApp);
3397 }
3398 }
3399
3400 // is all effects from m_needAliveTargetMask have alive targets
3401 return channelTargetEffectMask == 0;
3402}
@ SPELL_ATTR1_TRACK_TARGET_IN_CHANNEL
Definition SharedDefines.h:421
bool IsValidDeadOrAliveTarget(Unit const *target) const
Definition Spell.cpp:8242
AuraApplication * GetAuraApplication(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemCasterGUID=ObjectGuid::Empty, uint8 reqEffMask=0, AuraApplication *except=nullptr) const
Definition Unit.cpp:5840
void UpdateOrientation(float orientation)
Only server-side orientation update, does not broadcast to client.
Definition Unit.cpp:16034
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 ( )
7881{
7884 else
7885 {
7888 m_originalCaster = nullptr;
7889 }
7890
7892 {
7894 // cast item not found, somehow the item is no longer where we expected
7895 if (!m_CastItem)
7896 return false;
7897 }
7898 else
7899 m_CastItem = nullptr;
7900
7902
7903 // further actions done only for dest targets
7904 if (!m_targets.HasDst())
7905 return true;
7906
7907 // cache last transport
7908 WorldObject* transport = nullptr;
7909
7910 // update effect destinations (in case of moved transport dest target)
7911 for (uint8 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
7912 {
7913 SpellDestination& dest = m_destTargets[effIndex];
7914 if (!dest._transportGUID)
7915 continue;
7916
7917 if (!transport || transport->GetGUID() != dest._transportGUID)
7919
7920 if (transport)
7921 {
7922 dest._position.Relocate(transport);
7924 }
7925 }
7926
7927 return true;
7928}
void Update(Unit *caster)
Definition Spell.cpp:478
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)
4879{
4880 uint32 ammoInventoryType = 0;
4881 uint32 ammoDisplayID = 0;
4882
4883 if (m_caster->IsPlayer())
4884 {
4886 if (pItem)
4887 {
4888 ammoInventoryType = pItem->GetTemplate()->InventoryType;
4889 if (ammoInventoryType == INVTYPE_THROWN)
4890 ammoDisplayID = pItem->GetTemplate()->DisplayInfoID;
4891 else
4892 {
4894 if (ammoID)
4895 {
4896 ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(ammoID);
4897 if (pProto)
4898 {
4899 ammoDisplayID = pProto->DisplayInfoID;
4900 ammoInventoryType = pProto->InventoryType;
4901 }
4902 }
4903 else if (m_caster->HasAura(46699)) // Requires No Ammo
4904 {
4905 ammoDisplayID = 5996; // normal arrow
4906 ammoInventoryType = INVTYPE_AMMO;
4907 }
4908 }
4909 }
4910 }
4911 else
4912 {
4913 uint32 nonRangedAmmoDisplayID = 0;
4914 uint32 nonRangedAmmoInventoryType = 0;
4915 for (uint8 i = 0; i < 3; ++i)
4916 {
4918 {
4919 if (ItemEntry const* itemEntry = sItemStore.LookupEntry(item_id))
4920 {
4921 if (itemEntry->ClassID == ITEM_CLASS_WEAPON)
4922 {
4923 switch (itemEntry->SubclassID)
4924 {
4926 ammoDisplayID = itemEntry->DisplayInfoID;
4927 ammoInventoryType = itemEntry->InventoryType;
4928 break;
4931 ammoDisplayID = 5996; // is this need fixing?
4932 ammoInventoryType = INVTYPE_AMMO;
4933 break;
4935 ammoDisplayID = 5998; // is this need fixing?
4936 ammoInventoryType = INVTYPE_AMMO;
4937 break;
4938 default:
4939 nonRangedAmmoDisplayID = itemEntry->DisplayInfoID;
4940 nonRangedAmmoInventoryType = itemEntry->InventoryType;
4941 break;
4942 }
4943
4944 if (ammoDisplayID)
4945 break;
4946 }
4947 }
4948 }
4949 }
4950
4951 if (!ammoDisplayID && !ammoInventoryType)
4952 {
4953 ammoDisplayID = nonRangedAmmoDisplayID;
4954 ammoInventoryType = nonRangedAmmoInventoryType;
4955 }
4956 }
4957
4958 *data << uint32(ammoDisplayID);
4959 *data << uint32(ammoInventoryType);
4960}
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
4515{
4516 data << uint8(castCount); // single cast or multi 2.3 (0/1)
4517 data << uint32(spellInfo->Id);
4518 data << uint8(result); // problem
4519 switch (result)
4520 {
4522 data << uint32(spellInfo->RequiresSpellFocus); // SpellFocusObject.dbc id
4523 break;
4524 case SPELL_FAILED_REQUIRES_AREA: // AreaTable.dbc id
4525 // hardcode areas limitation case
4526 switch (spellInfo->Id)
4527 {
4528 case 41617: // Cenarion Mana Salve
4529 case 41619: // Cenarion Healing Salve
4530 data << uint32(3905);
4531 break;
4532 case 41618: // Bottled Nethergon Energy
4533 case 41620: // Bottled Nethergon Vapor
4534 data << uint32(3842);
4535 break;
4536 case 45373: // Bloodberry Elixir
4537 data << uint32(4075);
4538 break;
4539 default: // default case (don't must be)
4540 data << uint32(0);
4541 break;
4542 }
4543 break;
4545 if (spellInfo->Totem[0])
4546 data << uint32(spellInfo->Totem[0]);
4547 if (spellInfo->Totem[1])
4548 data << uint32(spellInfo->Totem[1]);
4549 break;
4551 if (spellInfo->TotemCategory[0])
4552 data << uint32(spellInfo->TotemCategory[0]);
4553 if (spellInfo->TotemCategory[1])
4554 data << uint32(spellInfo->TotemCategory[1]);
4555 break;
4559 data << uint32(spellInfo->EquippedItemClass);
4560 data << uint32(spellInfo->EquippedItemSubClassMask);
4561 break;
4563 {
4564 uint32 item = 0;
4565 for (int8 eff = 0; eff < MAX_SPELL_EFFECTS; eff++)
4566 if (spellInfo->Effects[eff].ItemType)
4567 item = spellInfo->Effects[eff].ItemType;
4568 ItemTemplate const* proto = sObjectMgr->GetItemTemplate(item);
4569 if (proto && proto->ItemLimitCategory)
4570 data << uint32(proto->ItemLimitCategory);
4571 break;
4572 }
4574 data << uint32(customError);
4575 break;
4577 {
4578 uint32 missingItem = 0;
4579 for (uint32 i = 0; i < MAX_SPELL_REAGENTS; i++)
4580 {
4581 if (spellInfo->Reagent[i] <= 0)
4582 continue;
4583
4584 uint32 itemid = spellInfo->Reagent[i];
4585 uint32 itemcount = spellInfo->ReagentCount[i];
4586
4587 if (!caster->HasItemCount(itemid, itemcount))
4588 {
4589 missingItem = itemid;
4590 break;
4591 }
4592 }
4593
4594 data << uint32(missingItem); // first missing item
4595 break;
4596 }
4598 data << uint32(spellInfo->Mechanic);
4599 break;
4601 data << uint32(spellInfo->EquippedItemSubClassMask);
4602 break;
4604 data << uint32(0); // Item entry
4605 data << uint32(0); // Count
4606 break;
4608 data << uint32(0); // SkillLine.dbc Id
4609 data << uint32(0); // Amount
4610 break;
4612 data << uint32(0); // Skill level
4613 break;
4614 default:
4615 break;
4616 }
4617}
@ 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.

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