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:3493
@ 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:1554
@ SPELL_DAMAGE_CLASS_MAGIC
Definition SharedDefines.h:1552
@ SPELL_DAMAGE_CLASS_MELEE
Definition SharedDefines.h:1553
@ 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:490
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:158
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:734
@ 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:1551
@ SPELL_MISS_NONE
Definition SharedDefines.h:1525
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:10019
void StartTimedAchievement(AchievementCriteriaTimedTypes type, uint32 entry, uint32 timeLost=0)
Definition Player.cpp:13945
void RemoveSpellMods(Spell *spell)
Definition Player.cpp:9945
Pet * GetPet() const
Definition Player.cpp:8946
bool GetCommandStatus(uint32 command) const
Definition Player.h:1197
void RemovePet(Pet *pet, PetSaveMode mode, bool returnreagent=false)
Definition Player.cpp:9096
TradeData * GetTradeData() const
Definition Player.h:1393
void RemoveSpellCooldown(uint32 spell_id, bool update=false)
Definition Player.cpp:3513
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:7753
std::vector< AuraEffect * > AuraEffectList
Definition Unit.h:680
Player * GetSpellModOwner() const
Definition Unit.cpp:12925
bool IsNonMeleeSpellCast(bool withDelayed, bool skipChanneled=false, bool skipAutorepeat=false, bool isAutoshoot=false, bool skipInstant=true) const
Definition Unit.cpp:4272
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:1350
void RemoveAurasDueToSpell(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, uint8 reqEffMask=0, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition Unit.cpp:5157
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:6746
bool HasUnitState(const uint32 f) const
Definition Unit.h:736
void SetInFront(WorldObject const *target)
Definition Unit.cpp:16405
void resetAttackTimer(WeaponAttackType type=BASE_ATTACK)
Definition Unit.cpp:761
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:11026
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:7698
void ClearComboPoints()
Definition Unit.cpp:13227
void AddComboPoints(Unit *target, int8 count)
Definition Unit.cpp:13201
void RemoveAurasByType(AuraType auraType, ObjectGuid casterGUID=ObjectGuid::Empty, Aura *except=nullptr, bool negative=true, bool positive=true)
Definition Unit.cpp:5365

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:1599
@ 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:1712
@ CREATURE_FAMILY_SUCCUBUS
Definition SharedDefines.h:2660
@ SPELL_MISS_PARRY
Definition SharedDefines.h:1529
@ SPELL_MISS_IMMUNE
Definition SharedDefines.h:1532
@ SPELL_MISS_EVADE
Definition SharedDefines.h:1531
@ SPELL_MISS_REFLECT
Definition SharedDefines.h:1536
@ 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:1793
SpellMissInfo SpellHitResult(Unit *victim, SpellInfo const *spell, bool canReflect=false)
Definition Unit.cpp:3628
virtual bool IsImmunedToSpellEffect(SpellInfo const *spellInfo, uint32 index, Unit const *caster=nullptr) const
Definition Unit.cpp:10076
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
1154{
1156 if (Creature* creature = m_caster->ToCreature())
1157 runSpeed *= creature->GetCreatureTemplate()->speed_run;
1158
1159 float multiplier = m_spellInfo->Effects[i].ValueMultiplier;
1160 if (multiplier <= 0.0f)
1161 multiplier = 1.0f;
1162
1163 speedXY = std::min(runSpeed * 3.0f * multiplier, std::max(28.0f, m_caster->GetSpeed(MOVE_RUN) * 4.0f));
1164
1165 float duration = dist / speedXY;
1166 float durationSqr = duration * duration;
1167 float minHeight = m_spellInfo->Effects[i].MiscValue ? m_spellInfo->Effects[i].MiscValue / 10.0f : 0.5f; // Lower bound is blizzlike
1168 float maxHeight = m_spellInfo->Effects[i].MiscValueB ? m_spellInfo->Effects[i].MiscValueB / 10.0f : 1000.0f; // Upper bound is unknown
1169 float height;
1170 if (durationSqr < minHeight * 8 / Movement::gravity)
1171 height = minHeight;
1172 else if (durationSqr > maxHeight * 8 / Movement::gravity)
1173 height = maxHeight;
1174 else
1175 height = Movement::gravity * durationSqr / 8;
1176
1177 speedZ = std::sqrt(2 * Movement::gravity * height);
1178}
@ MOVE_RUN
Definition UnitDefines.h:357
float baseMoveSpeed[MAX_MOVE_TYPE]
Definition Unit.cpp:78
float playerBaseMoveSpeed[MAX_MOVE_TYPE]
Definition Unit.cpp:91
float GetSpeed(UnitMoveType mtype) const
Definition Unit.cpp:11265
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:11558
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:15505
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:6566
bool RemoveDynObject(uint32 spellId)
Definition Unit.cpp:6510
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:1820
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:1416
@ 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:1436
LockType
Definition SharedDefines.h:2597
@ LOCK_KEY_ITEM
Definition SharedDefines.h:2591
@ LOCK_KEY_SKILL
Definition SharedDefines.h:2592
@ LOCK_KEY_SPELL
Definition SharedDefines.h:2593
@ SPELL_FAILED_BAD_TARGETS
Definition SharedDefines.h:949
@ SPELL_FAILED_LOW_CASTLEVEL
Definition SharedDefines.h:986
SkillType SkillByLockType(LockType locktype)
Definition SharedDefines.h:3255
@ SKILL_NONE
Definition SharedDefines.h:3099
@ SKILL_LOCKPICKING
Definition SharedDefines.h:3210
uint16 GetSkillValue(uint32 skill) const
Definition Player.cpp:5438
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:2592
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:292
@ CONDITION_SOURCE_TYPE_SPELL
Definition ConditionMgr.h:142
std::list< Condition * > ConditionList
Definition ConditionMgr.h:239
@ 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:104
@ LINEOFSIGHT_ALL_CHECKS
Definition Map.h:111
@ 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:1572
@ GAMEOBJECT_TYPE_DOOR
Definition SharedDefines.h:1566
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:1559
@ SPELL_ATTR5_ALWAYS_AOE_LINE_OF_SIGHT
Definition SharedDefines.h:581
@ TARGET_UNIT_PET
Definition SharedDefines.h:1420
@ TARGET_GAMEOBJECT_TARGET
Definition SharedDefines.h:1433
@ 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:3941
@ PET_TAME_DEAD
Definition SharedDefines.h:3944
@ PET_TAME_CANT_CONTROL_EXOTIC
Definition SharedDefines.h:3946
@ CLASS_WARLOCK
Definition SharedDefines.h:134
@ IMMUNITY_MECHANIC
Definition SharedDefines.h:1405
@ SPELLFAMILY_WARRIOR
Definition SharedDefines.h:3790
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:1376
@ 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:3520
@ SUMMON_CATEGORY_PUPPET
Definition SharedDefines.h:3521
SkillType
Definition SharedDefines.h:3098
@ SKILL_MINING
Definition SharedDefines.h:3154
@ SKILL_HERBALISM
Definition SharedDefines.h:3150
@ 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:229
CreatureTemplate const * GetCreatureTemplate() const
Definition Creature.h:206
bool IsSpellProhibited(SpellSchoolMask idSchoolMask) const
Definition Creature.cpp:2876
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:295
bool IsBattlegroundOrArena() const
Definition Map.h:303
GameObject * GetGameObject(ObjectGuid const &guid)
Definition Map.cpp:2341
uint32 GetId() const
Definition Map.h:230
Difficulty GetDifficulty() const
Definition Map.h:290
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:2534
bool IsInSameRaidWith(Player const *p) const
Definition Player.h:1902
bool CanTameExoticPets() const
Definition Player.h:2208
bool CanUseBattlegroundObject(GameObject *gameobject) const
Definition Player.cpp:13238
bool InBattleground() const
Definition Player.h:2287
PetStable * GetPetStable()
Definition Player.h:1221
Battleground * GetBattleground(bool create=false) const
Definition Player.cpp:12153
WorldSession * GetSession() const
Definition Player.h:2019
bool HasSpellCooldown(uint32 spell_id) const override
Definition Player.cpp:16350
uint32 GetLastPotionId()
Definition Player.h:1827
Group * GetGroup()
Definition Player.h:2504
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:6775
bool HasPlayerFlag(PlayerFlags flags) const
Definition Player.h:1123
std::unique_ptr< DuelInfo > duel
Definition Player.h:1894
Item * GetItemByGuid(ObjectGuid guid) const
Definition PlayerStorage.cpp:409
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:1926
SpellImmuneContainer m_spellImmune[MAX_SPELL_IMMUNITY]
Definition Unit.h:2089
Unit * GetOwner() const
Definition Unit.cpp:7682
Pet * ToPet()
Definition Unit.h:729
virtual bool HasSpellCooldown(uint32) const
Definition Unit.h:1335
ShapeshiftForm GetShapeshiftForm() const
Definition Unit.h:1957
virtual bool HasSpellItemCooldown(uint32, uint32) const
Definition Unit.h:1336
bool IsInDisallowedMountForm() const
Definition Unit.cpp:17268
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:6093
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:1841
bool HasAura(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemCasterGUID=ObjectGuid::Empty, uint8 reqEffMask=0) const
Definition Unit.cpp:5982
std::map< uint8, AuraApplication * > VisibleAuraMap
Definition Unit.h:687
bool IsInFlight() const
Definition Unit.h:1705
void SendTameFailure(uint8 result)
Definition Unit.cpp:15941
void GetDispellableAuraList(Unit *caster, uint32 dispelMask, DispelChargesList &dispelList, SpellInfo const *dispelSpell)
Definition Unit.cpp:5866
bool HasUnitMovementFlag(uint32 f) const
Definition Unit.h:774
virtual bool IsInWater() const
Definition Unit.cpp:4521
bool HasAuraState(AuraStateType flag, SpellInfo const *spellProto=nullptr, Unit const *Caster=nullptr) const
Definition Unit.cpp:7629
bool isMoving() const
Definition Unit.h:1708
void EngageWithTarget(Unit *who)
Definition Unit.cpp:7502
ObjectGuid GetCharmGUID() const
Definition Unit.h:721
VisibleAuraMap const * GetVisibleAuras()
Definition Unit.h:1539
bool IsMounted() const
Definition Unit.h:1886
Unit * GetVictim() const
Definition Unit.h:903
bool IsCritter() const
Definition Unit.h:833
bool IsFriendlyTo(Unit const *unit) const
Definition Unit.cpp:7241
ObjectGuid GetOwnerGUID() const
Definition Unit.h:713
bool IsHighestExclusiveAuraEffect(SpellInfo const *spellInfo, AuraType auraType, int32 effectAmount, uint8 auraEffectMask, bool removeOtherAuraApplications=false)
Definition Unit.cpp:4570
uint8 GetComboPoints(Unit const *who=nullptr) const
Definition Unit.h:1014
ObjectGuid GetCharmerGUID() const
Definition Unit.h:719
uint32 getTransForm() const
Definition Unit.h:1968
virtual bool HasActivePowerType(Powers power)
Definition Unit.h:1132
void RemoveMovementImpairingAuras(bool withRoot)
Definition Unit.cpp:5489
bool IsTotem() const
Definition Unit.h:799
Guardian * GetGuardianPet() const
Definition Unit.cpp:7733
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:610
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:3137
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:3120
uint32 GetZoneId() const
Definition Object.cpp:3112
void GetZoneAndAreaId(uint32 &zoneid, uint32 &areaid) const
Definition Object.cpp:3128
uint32 GetRecruiterId() const
Definition WorldSession.h:607
uint32 GetAccountId() const
Definition WorldSession.h:443
Seconds GetGameTime()
Definition GameTime.cpp:38
Player * FindPlayer(ObjectGuid const guid)
Definition ObjectAccessor.cpp:245
Definition DBCStructure.h:519
Definition ConditionMgr.h:184
Condition * mLastFailedCondition
Definition ConditionMgr.h:186
WorldObject * mConditionTargets[MAX_CONDITION_TARGETS]
Definition ConditionMgr.h:185
uint32 ErrorType
Definition ConditionMgr.h:207
uint8 ConditionTarget
Definition ConditionMgr.h:211
uint32 ErrorTextId
Definition ConditionMgr.h:208
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:122
bool AllowMount
Definition Map.h:125
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 uint32 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 |= 1 << 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 uint32 mask = (1 << MECHANIC_STUN) | (1 << MECHANIC_FREEZE) | (1 << MECHANIC_HORROR);
6875 // Barkskin should skip sleep effects, sap and fears
6876 if (m_spellInfo->Id == 22812)
6877 mask |= 1 << MECHANIC_SAPPED | 1 << MECHANIC_HORROR | 1 << 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 |= (1 << MECHANIC_SAPPED) | (1 << 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 uint32 mask = 1 << MECHANIC_STUN;
6940 // Barkskin should skip sleep effects, sap and fears
6941 if (m_spellInfo->Id == 22812)
6942 mask |= 1 << MECHANIC_SAPPED | 1 << MECHANIC_HORROR | 1 << 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 |= (1 << MECHANIC_SAPPED) | (1 << 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:1560
@ SPELL_PREVENTION_TYPE_PACIFY
Definition SharedDefines.h:1561
@ 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:204
Definition Corpse.h:49
ObjectGuid GetOwnerGUID() const
Definition Corpse.h:68
bool HasFlag(uint16 index, uint32 flag) const
Definition Object.cpp:871
ObjectGuid GetCorpseTargetGUID() const
Definition Spell.cpp:280
bool IsARecruiter() const
Definition WorldSession.h:608
#define sWorld
Definition World.h:316
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:3789
TotemCategory
Definition SharedDefines.h:3318
@ 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:3237
@ SKILL_ENCHANTING
Definition SharedDefines.h:3189
@ SKILL_JEWELCRAFTING
Definition SharedDefines.h:3220
@ 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:12489
uint32 GetFreeInventorySpace() const
Definition PlayerStorage.cpp:468
Item * GetItemByEntry(uint32 entry) const
Definition PlayerStorage.cpp:3430
bool HasItemCount(uint32 item, uint32 count=1, bool inBankAlso=false) const
Definition PlayerStorage.cpp:657
bool HasItemTotemCategory(uint32 TotemCategory) const
Definition PlayerStorage.cpp:858
bool CanNoReagentCast(SpellInfo const *spellInfo) const
Definition Player.cpp:12565
void SendEquipError(InventoryResult msg, Item *pItem, Item *pItem2=nullptr, uint32 itemid=0)
Definition PlayerStorage.cpp:4088
InventoryResult CanStoreNewItem(uint8 bag, uint8 slot, ItemPosCountVec &dest, uint32 item, uint32 count, uint32 *no_space_count=nullptr) const
Definition Player.h:1297
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:17323
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:821
bool IsWithinCombatRange(Unit const *obj, float dist2compare) const
Definition Unit.cpp:766
float GetSpellMinRangeForTarget(Unit const *target, SpellInfo const *spellInfo) const
Definition Unit.cpp:11874
bool IsWithinMeleeRange(Unit const *obj, float dist=0.f) const
Definition Unit.cpp:782
float GetSpellMaxRangeForTarget(Unit const *target, SpellInfo const *spellInfo) const
Definition Unit.cpp:11854
bool IsWithinRange(Unit const *obj, float dist) const
Definition Unit.cpp:806
float GetMeleeRange(Unit const *target) const
Definition Unit.cpp:800
bool HasLeewayMovement() const
Definition Unit.h:1729
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:2544
bool IsClass(Classes playerClass, ClassContext context=CLASS_CONTEXT_NONE) const override
Definition Player.cpp:1301
RuneType GetCurrentRune(uint8 index) const
Definition Player.h:2543
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:164
void Visit(const Cell &cell, TypeContainerVisitor< T, CONTAINER > &visitor)
Definition Map.h:702
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:170
@ 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:9759
bool isDelayableNoMore()
Definition Spell.h:649
int32 GetTotalAuraModifier(AuraType auratype) const
Definition Unit.cpp:6268
virtual void SendMessageToSet(WorldPacket const *data, bool self) const
Definition Object.cpp:2113
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:6497

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:9147
float SpellDoneCritChance(Unit const *, SpellInfo const *spellProto, SpellSchoolMask schoolMask, WeaponAttackType attackType, bool skipEffectCheck) const
Definition Unit.cpp:9057
int32 CalculateAOEDamageReduction(int32 damage, uint32 schoolMask, bool npcCaster) const
Definition Unit.cpp:16284

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:306
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:1542
SpellMissInfo
Definition SharedDefines.h:1524
@ SPELL_MISS_DODGE
Definition SharedDefines.h:1528
@ SPELL_MISS_IMMUNE2
Definition SharedDefines.h:1533
@ SPELL_MISS_RESIST
Definition SharedDefines.h:1527
@ SPELL_MISS_MISS
Definition SharedDefines.h:1526
@ SPELL_MISS_BLOCK
Definition SharedDefines.h:1530
@ 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:162
virtual void SpellHit(Unit *, SpellInfo const *)
Definition CreatureAI.h:159
void LowerPlayerDamageReq(uint32 unDamage, bool damagedByPlayer=true)
Definition Creature.cpp:3761
CreatureAI * AI() const
Definition Creature.h:143
Definition Unit.h:336
Definition Unit.h:383
void RestoreSpellMods(Spell *spell, uint32 ownerAuraId=0, Aura *aura=nullptr)
Definition Player.cpp:9885
void CastItemCombatSpell(Unit *target, WeaponAttackType attType, uint32 procVictim, uint32 procEx)
Definition Player.cpp:7221
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:760
uint32 m_lastSanctuaryTime
Definition Unit.h:2090
void DealSpellDamage(SpellNonMeleeDamage *damageInfo, bool durabilityLoss, Spell const *spell=nullptr)
Definition Unit.cpp:1626
void SetInCombatWith(Unit *enemy, bool addSecondUnitSuppressed=false)
Definition Unit.h:939
void SendSpellMiss(Unit *target, uint32 spellID, SpellMissInfo missInfo)
Definition Unit.cpp:6836
void SendSpellNonMeleeReflectLog(SpellNonMeleeDamage *log, Unit *attacker)
Definition Unit.cpp:6647
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:9519
void AtTargetAttacked(Unit *target, bool canInitialAggro)
Definition Unit.cpp:11424
int32 HealBySpell(HealInfo &healInfo, bool critical=false)
Definition Unit.cpp:8336
bool IsStandState() const
Definition Unit.cpp:13074
int32 GetHealthGain(int32 dVal)
Definition Unit.cpp:10972
bool IsImmunedToDamage(SpellSchoolMask schoolMask) const
Definition Unit.cpp:9809
static uint32 SpellCriticalHealingBonus(Unit const *caster, SpellInfo const *spellProto, uint32 damage, Unit const *victim)
Definition Unit.cpp:9395
void SendSpellNonMeleeDamageLog(SpellNonMeleeDamage *log)
Definition Unit.cpp:6679
ThreatManager & GetThreatMgr()
Definition Unit.h:951
bool IsAIEnabled
Definition Unit.h:2097
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:9639
void SetStandState(uint8 state)
Definition Unit.cpp:13089
void RemoveAurasWithInterruptFlags(uint32 flag, uint32 except=0, bool isAutoshot=false)
Definition Unit.cpp:5436
static void DealDamageMods(Unit const *victim, uint32 &damage, uint32 *absorb)
Definition Unit.cpp:973
void CalculateSpellDamageTaken(SpellNonMeleeDamage *damageInfo, int32 damage, SpellInfo const *spellInfo, WeaponAttackType attackType=BASE_ATTACK, bool crit=false)
Definition Unit.cpp:1483
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 
)
1652{
1653 if (!unitTarget)
1654 return;
1655
1656 Player* player = unitTarget->ToPlayer();
1657 if (!player)
1658 {
1659 return;
1660 }
1661
1662 uint32 newitemid = itemId;
1663
1664 ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(newitemid);
1665 if (!pProto)
1666 {
1667 player->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, nullptr, nullptr);
1668 return;
1669 }
1670
1671 uint32 addNumber = damage;
1672
1673 // bg reward have some special in code work
1674 bool SelfCast = true;
1675 switch (m_spellInfo->Id)
1676 {
1681 case SPELL_WS_MARK_TIE:
1684 SelfCast = true;
1685 break;
1687 if (player->HasAura(55629 /*SPELL_LIEUTENANT*/))
1688 addNumber = 3;
1689 else if (player->HasAura(33280 /*SPELL_CORPORAL*/))
1690 addNumber = 2;
1691 else
1692 addNumber = 1;
1693 SelfCast = true;
1694 break;
1695 }
1696
1697 if (addNumber < 1)
1698 addNumber = 1;
1699 if (addNumber > pProto->GetMaxStackSize())
1700 addNumber = pProto->GetMaxStackSize();
1701
1702 /* == gem perfection handling == */
1703
1704 // the chance of getting a perfect result
1705 float perfectCreateChance = 0.0f;
1706
1707 // the resulting perfect item if successful
1708 uint32 perfectItemType = itemId;
1709
1710 // get perfection capability and chance
1711 if (CanCreatePerfectItem(player, m_spellInfo->Id, perfectCreateChance, perfectItemType))
1712 if (roll_chance_f(perfectCreateChance)) // if the roll succeeds...
1713 newitemid = perfectItemType; // the perfect item replaces the regular one
1714
1715 /* == gem perfection handling over == */
1716
1717 /* == profession specialization handling == */
1718
1719 // init items_count to 1, since 1 item will be created regardless of specialization
1720 int32 itemsCount = 1;
1721 float additionalCreateChance = 0.0f;
1722 int32 additionalMaxNum = 0;
1723 // get the chance and maximum number for creating extra items
1724 if (canCreateExtraItems(player, m_spellInfo->Id, additionalCreateChance, additionalMaxNum))
1725 {
1726 // roll with this chance till we roll not to create or we create the max num
1727 while (roll_chance_f(additionalCreateChance) && itemsCount <= additionalMaxNum)
1728 ++itemsCount;
1729 }
1730
1731 // really will be created more items
1732 addNumber *= itemsCount;
1733
1734 /* == profession specialization handling over == */
1735
1736 // can the player store the new item?
1737 ItemPosCountVec dest;
1738 uint32 no_space = 0;
1739 InventoryResult msg = player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, newitemid, addNumber, &no_space);
1740 if (msg != EQUIP_ERR_OK)
1741 {
1742 // convert to possible store amount
1744 addNumber -= no_space;
1745 else
1746 {
1747 // if not created by another reason from full inventory or unique items amount limitation
1748 player->SendEquipError(msg, nullptr, nullptr, newitemid);
1749 return;
1750 }
1751 }
1752
1753 if (addNumber)
1754 {
1755 // create the new item and store it
1756 Item* pItem = player->StoreNewItem(dest, newitemid, true);
1757
1758 // was it successful? return error if not
1759 if (!pItem)
1760 {
1761 player->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, nullptr, nullptr);
1762 return;
1763 }
1764
1765 // set the "Crafted by ..." property of the item
1766 if (m_caster->IsPlayer() && pItem->GetTemplate()->HasSignature())
1767 pItem->SetGuidValue(ITEM_FIELD_CREATOR, player->GetGUID());
1768
1769 // send info to the client
1770 player->SendNewItem(pItem, addNumber, true, SelfCast);
1771
1772 sScriptMgr->OnPlayerCreateItem(player, pItem, addNumber);
1773
1774 // we succeeded in creating at least one item, so a levelup is possible
1775 if (SelfCast)
1777 }
1778}
@ 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:4812
Item * StoreNewItem(ItemPosCountVec const &pos, uint32 item, bool update, int32 randomPropertyId=0, bool refund=false)
Definition PlayerStorage.cpp:2596
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:3511
@ 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:3484
@ DRTYPE_PLAYER
Definition SharedDefines.h:3486
@ DRTYPE_ALL
Definition SharedDefines.h:3487
@ 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:123
bool IsInEvadeMode() const
Definition Creature.h:137
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:6022
DiminishingLevels GetDiminishing(DiminishingGroup group)
Definition Unit.cpp:11714
void IncrDiminishing(DiminishingGroup group)
Definition Unit.cpp:11740
void SetContestedPvP(Player *attackedPlayer=nullptr, bool lookForNearContestedGuards=true)
Definition Unit.cpp:13623
bool HasUnitFlag(UnitFlags flags) const
Definition Unit.h:747
float ApplyDiminishingToDuration(DiminishingGroup group, int32 &duration, Unit *caster, DiminishingLevels Level, int32 limitduration)
Definition Unit.cpp:11754
int32 ModSpellDuration(SpellInfo const *spellProto, Unit const *target, int32 duration, bool positive, uint32 effectMask)
Definition Unit.cpp:11580
virtual void AddSpellCooldown(uint32, uint32, uint32, bool needSendToClient=false, bool forceSendToSpectator=false)
Definition Unit.h:1337
bool HasReflectSpellsAura() const
Definition Unit.h:1816
bool IsCharmedOwnedByPlayerOrPlayer() const
Definition Unit.h:1309
bool IsImmunedToSchool(SpellSchoolMask schoolMask) const
Definition Unit.cpp:9870
virtual bool IsImmunedToSpell(SpellInfo const *spellInfo, Spell const *spell=nullptr)
Definition Unit.cpp:9982
CombatManager & GetCombatManager()
Definition Unit.h:953
bool IsHostileTo(Unit const *unit) const
Definition Unit.cpp:7236
bool _IsValidAttackTarget(Unit const *target, SpellInfo const *bySpell, WorldObject const *obj=nullptr) const
Definition Unit.cpp:10711
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:5842
Aura * AddAura(uint32 spellId, Unit *target)
Definition Unit.cpp:15088

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)
4215{
4217 return;
4218
4219 if (!gameObjTarget)
4220 return;
4221
4222 GameObjectActions action = GameObjectActions(m_spellInfo->Effects[effIndex].MiscValue);
4223 switch (action)
4224 {
4230 break;
4231 case GameObjectActions::Disturb: // What's the difference with Open?
4233 if (Unit* unitCaster = m_caster->ToUnit())
4234 gameObjTarget->Use(unitCaster);
4235 break;
4237 if (Unit* unitCaster = m_caster->ToUnit())
4238 gameObjTarget->UseDoorOrButton(0, false, unitCaster);
4239 [[fallthrough]];
4243 break;
4247 break;
4250 break;
4254 break;
4258 break;
4260 if (Unit* unitCaster = m_caster->ToUnit())
4261 gameObjTarget->UseDoorOrButton(0, true, unitCaster);
4262 break;
4267 {
4268 GameObjectTemplateAddon const* templateAddon = gameObjTarget->GetTemplateAddon();
4269
4270 uint32 artKitIndex = uint32(action) - uint32(GameObjectActions::UseArtKit0);
4271
4272 uint32 artKitValue = 0;
4273 if (templateAddon)
4274 artKitValue = templateAddon->artKits[artKitIndex];
4275
4276 if (artKitValue == 0)
4277 LOG_ERROR("sql.sql", "GameObject {} hit by spell {} needs `artkit{}` in `gameobject_template_addon`", gameObjTarget->GetEntry(), m_spellInfo->Id, artKitIndex);
4278 else
4279 gameObjTarget->SetGoArtKit(artKitValue);
4280
4281 break;
4282 }
4284 LOG_FATAL("spell", "Spell {} has action type NONE in effect {}", m_spellInfo->Id, int32(effIndex));
4285 break;
4286 default:
4287 LOG_ERROR("spell", "Spell {} has unhandled action {} in effect {}", m_spellInfo->Id, int32(action), int32(effIndex));
4288 break;
4289 }
4290}
GameObjectActions
Definition GameObject.h:76
#define LOG_FATAL(filterType__,...)
Definition Log.h:154
@ GO_FLAG_NOT_SELECTABLE
Definition SharedDefines.h:1613
@ GO_FLAG_LOCKED
Definition SharedDefines.h:1610
@ GAMEOBJECT_FLAGS
Definition UpdateFields.h:399
void UseDoorOrButton(uint32 time_to_restore=0, bool alternative=false, Unit *user=nullptr)
Definition GameObject.cpp:1405
void SetGoArtKit(uint8 artkit)
Definition GameObject.cpp:1419
void SendCustomAnim(uint32 anim)
Definition GameObject.cpp:2137
void ResetDoorOrButton()
Definition GameObject.cpp:1395
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:1455
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)
5752{
5754 return;
5755
5756 if (!m_caster->IsPlayer())
5757 return;
5758
5759 Player* player = m_caster->ToPlayer();
5760
5762 return;
5763
5764 // needed later
5766
5767 uint32 count = damage;
5768 if (count == 0) count = 1;
5769 for (uint32 j = 0; j < MAX_RUNES && count > 0; ++j)
5770 {
5771 if (player->GetRuneCooldown(j) && player->GetCurrentRune(j) == RuneType(m_spellInfo->Effects[effIndex].MiscValue))
5772 {
5773 if (m_spellInfo->Id == 45529)
5774 if (player->GetBaseRune(j) != RuneType(m_spellInfo->Effects[effIndex].MiscValueB))
5775 continue;
5776 player->SetRuneCooldown(j, 0);
5777 player->SetGracePeriod(j, player->IsInCombat()); // xinef: reset grace period
5778 --count;
5779 }
5780 }
5781
5782 // Blood Tap
5783 if (m_spellInfo->Id == 45529 && count > 0)
5784 {
5785 for (uint32 l = 0; l < MAX_RUNES && count > 0; ++l)
5786 {
5787 // Check if both runes are on cd as that is the only time when this needs to come into effect
5788 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)))
5789 {
5790 // Should always update the rune with the lowest cd
5791 if (player->GetRuneCooldown(l) >= player->GetRuneCooldown(l + 1))
5792 l++;
5793 player->SetRuneCooldown(l, 0);
5794 player->SetGracePeriod(l, player->IsInCombat()); // xinef: reset grace period
5795 --count;
5796 }
5797 else
5798 break;
5799 }
5800 }
5801
5802 // Empower rune weapon
5803 if (m_spellInfo->Id == 47568)
5804 {
5805 // Need to do this just once
5806 if (effIndex != 0)
5807 return;
5808
5809 for (uint32 i = 0; i < MAX_RUNES; ++i)
5810 {
5811 if (player->GetRuneCooldown(i) && (player->GetCurrentRune(i) == RUNE_FROST || player->GetCurrentRune(i) == RUNE_DEATH))
5812 {
5813 player->SetRuneCooldown(i, 0);
5814 player->SetGracePeriod(i, player->IsInCombat()); // xinef: reset grace period
5815 }
5816 }
5817 }
5818
5819 // is needed to push through to the client that the rune is active
5820 //player->ResyncRunes(MAX_RUNES);
5821 m_caster->CastSpell(m_caster, 47804, true);
5822}
@ RUNE_FROST
Definition Player.h:398
void SetRuneCooldown(uint8 index, uint32 cooldown)
Definition Player.h:2552
uint8 GetRunesState() const
Definition Player.h:2541
void SetGracePeriod(uint8 index, uint32 period)
Definition Player.h:2553
RuneType GetBaseRune(uint8 index) const
Definition Player.h:2542

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)
6130{
6132 return;
6133
6134 if (!unitTarget)
6135 return;
6136
6137 if (Player* player = unitTarget->ToPlayer())
6138 {
6139 player->ActivateSpec(damage - 1); // damage is 1 or 2, spec is 0 or 1
6140 }
6141}

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

◆ EffectAddComboPoints()

void Spell::EffectAddComboPoints ( SpellEffIndex  effIndex)
4051{
4053 {
4054 return;
4055 }
4056
4057 if (!unitTarget || damage <= 0)
4058 {
4059 return;
4060 }
4061
4063}
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)
4635{
4637 {
4638 return;
4639 }
4640
4641 if (!unitTarget || !unitTarget->IsAlive())
4642 {
4643 return;
4644 }
4645
4647
4649}
void ExecuteLogEffectExtraAttacks(uint8 effIndex, Unit *victim, uint32 attCount)
Definition Spell.cpp:5066
void AddExtraAttacks(uint32 count)
Definition Unit.cpp:2926

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

◆ EffectAddFarsight()

void Spell::EffectAddFarsight ( SpellEffIndex  effIndex)
2732{
2734 return;
2735
2736 if (!m_caster->IsPlayer())
2737 return;
2738
2739 float radius = m_spellInfo->Effects[effIndex].CalcRadius();
2740 int32 duration = m_spellInfo->GetDuration();
2741 // Caster not in world, might be spell triggered from aura removal
2742 if (!m_caster->IsInWorld())
2743 return;
2744
2745 // Remove old farsight if exist
2746 bool updateViewerVisibility = m_caster->RemoveDynObject(m_spellInfo->Id);
2747
2748 DynamicObject* dynObj = new DynamicObject();
2750 {
2751 delete dynObj;
2752 return;
2753 }
2754
2755 dynObj->SetDuration(duration);
2756 dynObj->SetCasterViewpoint(updateViewerVisibility);
2757}
@ 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:480
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)
2802{
2804 return;
2805
2806 if (!unitTarget->IsPlayer())
2807 return;
2808
2809 // not scale value for item based reward (/10 value expected)
2810 if (m_CastItem)
2811 {
2812 unitTarget->ToPlayer()->RewardHonor(nullptr, 1, damage / 10, false);
2813 LOG_DEBUG("spells.aura", "SpellEffect::AddHonor (spell_id {}) rewards {} honor points (item {}) for player: {}",
2815 return;
2816 }
2817
2818 // do not allow to add too many honor for player (50 * 21) = 1040 at level 70, or (50 * 31) = 1550 at level 80
2819 if (damage <= 50)
2820 {
2822 unitTarget->ToPlayer()->RewardHonor(nullptr, 1, honor_reward, false);
2823 LOG_DEBUG("spells.aura", "SpellEffect::AddHonor (spell_id {}) rewards {} honor points (scale) to player: {}",
2824 m_spellInfo->Id, honor_reward, unitTarget->ToPlayer()->GetGUID().ToString());
2825 }
2826 else
2827 {
2828 //maybe we have correct honor_gain in damage already
2829 unitTarget->ToPlayer()->RewardHonor(nullptr, 1, damage, false);
2830 LOG_DEBUG("spells.aura", "SpellEffect::AddHonor (spell_id {}) rewards {} honor points (non scale) for player: {}",
2832 }
2833}
std::string ToString() const
Definition ObjectGuid.cpp:47
bool RewardHonor(Unit *victim, uint32 groupsize, int32 honor=-1, bool awardXP=true)
Definition Player.cpp:6082
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)
1320{
1322 return;
1323
1324 if (!m_spellAura || !unitTarget)
1325 return;
1328}
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)
4293{
4295 return;
4296
4298 return;
4299
4300 Player* player = m_caster->ToPlayer();
4301
4302 // glyph sockets level requirement
4303 uint8 minLevel = 0;
4304 switch (m_glyphIndex)
4305 {
4306 case 0:
4307 case 1:
4308 minLevel = 15;
4309 break;
4310 case 2:
4311 minLevel = 50;
4312 break;
4313 case 3:
4314 minLevel = 30;
4315 break;
4316 case 4:
4317 minLevel = 70;
4318 break;
4319 case 5:
4320 minLevel = 80;
4321 break;
4322 }
4323 if (minLevel && m_caster->GetLevel() < minLevel)
4324 {
4326 return;
4327 }
4328
4329 // apply new one
4330 if (uint32 glyph = m_spellInfo->Effects[effIndex].MiscValue)
4331 {
4332 if (GlyphPropertiesEntry const* glyphEntry = sGlyphPropertiesStore.LookupEntry(glyph))
4333 {
4334 if (GlyphSlotEntry const* glyphSlotEntry = sGlyphSlotStore.LookupEntry(player->GetGlyphSlot(m_glyphIndex)))
4335 {
4336 if (glyphEntry->TypeFlags != glyphSlotEntry->TypeFlags)
4337 {
4339 return; // glyph slot mismatch
4340 }
4341 }
4342
4343 // remove old glyph aura
4344 if (uint32 oldGlyph = player->GetGlyph(m_glyphIndex))
4345 if (GlyphPropertiesEntry const* oldGlyphEntry = sGlyphPropertiesStore.LookupEntry(oldGlyph))
4346 {
4347 player->RemoveAurasDueToSpell(oldGlyphEntry->SpellId);
4348
4349 // Removed any triggered auras
4350 Unit::AuraMap& ownedAuras = player->GetOwnedAuras();
4351 for (Unit::AuraMap::iterator iter = ownedAuras.begin(); iter != ownedAuras.end();)
4352 {
4353 Aura* aura = iter->second;
4354 if (SpellInfo const* triggeredByAuraSpellInfo = aura->GetTriggeredByAuraSpellInfo())
4355 {
4356 if (triggeredByAuraSpellInfo->Id == oldGlyphEntry->SpellId)
4357 {
4358 player->RemoveOwnedAura(iter);
4359 continue;
4360 }
4361 }
4362 ++iter;
4363 }
4364
4365 player->SendLearnPacket(oldGlyphEntry->SpellId, false); // Send packet to properly handle client-side spell tooltips
4366 }
4367
4368 player->SendLearnPacket(glyphEntry->SpellId, true); // Send packet to properly handle client-side spell tooltips
4370 player->SetGlyph(m_glyphIndex, glyph, !player->GetSession()->PlayerLoading());
4371 player->SendTalentsInfoData(false);
4372 }
4373 }
4374}
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:14527
void SendLearnPacket(uint32 spellId, bool learn)
Definition Player.cpp:3010
uint32 GetGlyph(uint8 slot) const
Definition Player.h:1781
uint32 GetGlyphSlot(uint8 slot) const
Definition Player.h:1772
void SetGlyph(uint8 slot, uint32 glyph, bool save)
Definition Player.h:1773
void RemoveOwnedAura(AuraMap::iterator &i, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition Unit.cpp:4953
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)
6263{
6265 return;
6266
6267 if (!unitTarget)
6268 return;
6269
6270 Player* player = unitTarget->ToPlayer();
6271 if (!player)
6272 {
6273 return;
6274 }
6275
6276 WorldLocation homeLoc;
6277 uint32 areaId = player->GetAreaId();
6278
6279 if (m_spellInfo->Effects[effIndex].MiscValue)
6280 areaId = m_spellInfo->Effects[effIndex].MiscValue;
6281
6282 if (m_targets.HasDst())
6283 homeLoc.WorldRelocate(*destTarget);
6284 else
6285 {
6286 homeLoc = player->GetWorldLocation();
6287 }
6288
6289 player->SetHomebind(homeLoc, areaId);
6290
6291 // binding
6292 WorldPacket data(SMSG_BINDPOINTUPDATE, 4 + 4 + 4 + 4 + 4);
6293 data << float(homeLoc.GetPositionX());
6294 data << float(homeLoc.GetPositionY());
6295 data << float(homeLoc.GetPositionZ());
6296 data << uint32(homeLoc.GetMapId());
6297 data << uint32(areaId);
6298 player->SendDirectMessage(&data);
6299
6300 LOG_DEBUG("spells.aura", "EffectBind: New homebind X: {}, Y: {}, Z: {}, MapId: {}, AreaId: {}",
6301 homeLoc.GetPositionX(), homeLoc.GetPositionY(), homeLoc.GetPositionZ(), homeLoc.GetMapId(), areaId);
6302 // zone update
6303 data.Initialize(SMSG_PLAYERBOUND, 8 + 4);
6304 data << m_caster->GetGUID();
6305 data << uint32(areaId);
6306 player->SendDirectMessage(&data);
6307}
void SendDirectMessage(WorldPacket const *data) const
Definition Player.cpp:5680
void SetHomebind(WorldLocation const &loc, uint32 areaId)
Definition PlayerStorage.cpp:4958
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)
4661{
4663 return;
4664
4665 if (m_caster->IsPlayer())
4666 m_caster->ToPlayer()->SetCanBlock(true);
4667}
void SetCanBlock(bool value)
Definition Player.cpp:13145

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.

6190{
6192 return;
6193
6194 if (!m_caster->IsPlayer())
6195 return;
6196
6197 Player* p_caster = m_caster->ToPlayer();
6198 uint32 button_id = m_spellInfo->Effects[effIndex].MiscValue + 132;
6199 uint32 n_buttons = m_spellInfo->Effects[effIndex].MiscValueB;
6200
6201 for (; n_buttons; --n_buttons, ++button_id)
6202 {
6203 ActionButton const* ab = p_caster->GetActionButton(button_id);
6204 if (!ab || ab->GetType() != ACTION_BUTTON_SPELL)
6205 continue;
6206
6209 uint32 spell_id = ab->GetAction();
6210 if (!spell_id)
6211 continue;
6212
6213 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spell_id);
6214 if (!spellInfo)
6215 continue;
6216
6217 if (!p_caster->HasSpell(spell_id) || p_caster->HasSpellCooldown(spell_id))
6218 continue;
6219
6221 continue;
6222
6223 uint32 cost = spellInfo->CalcPowerCost(m_caster, spellInfo->GetSchoolMask(), this);
6224 if (m_caster->GetPower(POWER_MANA) < cost)
6225 continue;
6226
6228 m_caster->CastSpell(m_caster, spell_id, triggerFlags);
6229 }
6230}
@ 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:5639
bool HasSpell(uint32 spell) const override
Definition Player.cpp:3869
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)
4880{
4882 {
4883 if (!unitTarget)
4884 return;
4885
4886 ObjectGuid targetGUID = ObjectGuid::Empty;
4887 Player* player = m_caster->ToPlayer();
4888 if (player)
4889 {
4890 // charge changes fall time
4892
4894 {
4895 targetGUID = unitTarget->GetGUID();
4896 }
4897 }
4898
4899 float speed = G3D::fuzzyGt(m_spellInfo->Speed, 0.0f) ? m_spellInfo->Speed : SPEED_CHARGE;
4900 // Spell is not using explicit target - no generated path
4901 if (!m_preGeneratedPath)
4902 {
4904 m_caster->GetMotionMaster()->MoveCharge(pos.m_positionX, pos.m_positionY, pos.m_positionZ, speed, EVENT_CHARGE, nullptr, false, 0.0f, targetGUID);
4905 }
4906 else
4907 {
4908 m_caster->GetMotionMaster()->MoveCharge(*m_preGeneratedPath, speed, targetGUID);
4909 }
4910
4911 if (player)
4912 {
4913 sScriptMgr->AnticheatSetUnderACKmount(player);
4914 }
4915 }
4916}
#define SPEED_CHARGE
Definition MotionMaster.h:135
@ EVENT_CHARGE
Definition SharedDefines.h:3562
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:2371
MotionMaster * GetMotionMaster()
Definition Unit.h:1758
Position GetFirstCollisionPosition(float startX, float startY, float startZ, float destX, float destY)
Definition Object.cpp:2888
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)
1781{
1783 return;
1784
1785 DoCreateItem(effIndex, m_spellInfo->Effects[effIndex].ItemType);
1786 ExecuteLogEffectCreateItem(effIndex, m_spellInfo->Effects[effIndex].ItemType);
1787}
void ExecuteLogEffectCreateItem(uint8 effIndex, uint32 entry)
Definition Spell.cpp:5094
void DoCreateItem(uint8 effIndex, uint32 itemId)
Definition SpellEffects.cpp:1651

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);
1790{
1792 return;
1793
1794 if (!unitTarget)
1795 return;
1796
1797 Player* player = unitTarget->ToPlayer();
1798 if (!player)
1799 {
1800 return;
1801 }
1802
1803 uint32 itemId = m_spellInfo->Effects[effIndex].ItemType;
1804
1805 if (itemId)
1806 DoCreateItem(effIndex, itemId);
1807
1808 // special case: fake item replaced by generate using spell_loot_template
1810 {
1811 if (itemId)
1812 {
1813 if (!player->HasItemCount(itemId))
1814 return;
1815
1816 // remove reagent
1817 uint32 count = 1;
1818 player->DestroyItemCount(itemId, count, true);
1819
1820 // create some random items
1822 }
1823 else
1824 player->AutoStoreLoot(m_spellInfo->Id, LootTemplates_Spell); // create some random items
1825 }
1827}
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:13508
void DestroyItemCount(uint32 item, uint32 count, bool update, bool unequip_check=false)
Definition PlayerStorage.cpp:3182
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);
1830{
1832 return;
1833
1834 if (!unitTarget)
1835 return;
1836
1837 Player* player = unitTarget->ToPlayer();
1838 if (!player)
1839 {
1840 return;
1841 }
1842
1843 // create some random items
1846}

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)
5825{
5827 return;
5828
5830 return;
5831
5832 uint32 creatureEntry = m_spellInfo->Effects[effIndex].MiscValue;
5833 Pet* pet = unitTarget->CreateTamedPetFrom(creatureEntry, m_spellInfo->Id);
5834 if (!pet)
5835 return;
5836
5837 // add to world
5838 pet->GetMap()->AddToMap(pet->ToCreature(), true);
5839
5840 // unitTarget has pet now
5841 unitTarget->SetMinion(pet, true);
5842
5843 pet->InitTalentForLevel();
5844
5845 if (unitTarget->IsPlayer())
5846 {
5849 }
5850}
@ CLASS_HUNTER
Definition SharedDefines.h:128
bool AddToMap(T *, bool checkTransport=false)
Definition Map.cpp:303
void InitTalentForLevel()
Definition Pet.cpp:2210
void SavePetToDB(PetSaveMode mode)
Definition Pet.cpp:502
void PetSpellInitialize()
Definition Player.cpp:9498
void SetMinion(Minion *minion, bool apply)
Definition Unit.cpp:7767
Pet * CreateTamedPetFrom(Creature *creatureTarget, uint32 spell_id=0)
Definition Unit.cpp:13726

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)
5231{
5233 return;
5234
5235 int32 mana = 0;
5236 for (uint8 slot = SUMMON_SLOT_TOTEM_FIRE; slot < MAX_TOTEM_SLOT; ++slot)
5237 {
5238 if (!m_caster->m_SummonSlot[slot])
5239 continue;
5240
5242 if (totem && totem->IsTotem())
5243 {
5244 uint32 spell_id = totem->GetUInt32Value(UNIT_CREATED_BY_SPELL);
5245 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spell_id);
5246 if (spellInfo)
5247 {
5248 mana += spellInfo->ManaCost;
5250 }
5251 totem->ToTotem()->UnSummon();
5252 }
5253 }
5254 ApplyPct(mana, damage);
5255 if (mana)
5256 m_caster->CastCustomSpell(m_caster, 39104, &mana, nullptr, nullptr, true);
5257}
#define MAX_TOTEM_SLOT
Definition SharedDefines.h:3557
@ SUMMON_SLOT_TOTEM_FIRE
Definition SharedDefines.h:3547
@ 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:2336
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:1407
uint32 GetCreateMana() const
Definition Unit.h:1148
ObjectGuid m_SummonSlot[MAX_SUMMON_SLOT]
Definition Unit.h:2078

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)
5853{
5855 return;
5856
5857 if (!unitTarget)
5858 return;
5859
5860 Player* player = unitTarget->ToPlayer();
5861 if (!player)
5862 {
5863 return;
5864 }
5865
5866 uint32 nodeid = m_spellInfo->Effects[effIndex].MiscValue;
5867 if (sTaxiNodesStore.LookupEntry(nodeid))
5868 player->GetSession()->SendDiscoverNewTaxiNode(nodeid);
5869}
DBCStorage< TaxiNodesEntry > sTaxiNodesStore(TaxiNodesEntryfmt)
void SendDiscoverNewTaxiNode(uint32 nodeid)
Definition TaxiHandler.cpp:151

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)
4430{
4432 return;
4433
4435 return;
4436
4437 if (Player* caster = m_caster->ToPlayer())
4438 {
4439 caster->UpdateCraftSkill(m_spellInfo->Id);
4440 caster->SendLoot(itemTarget->GetGUID(), LOOT_DISENCHANTING);
4441 }
4442
4443 // item will be removed at disenchanting end
4444}
@ 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)
4516{
4518 return;
4519
4520 if (!unitTarget || !unitTarget->IsPet())
4521 return;
4522
4523 Pet* pet = unitTarget->ToPet();
4524
4525 ExecuteLogEffectUnsummonObject(effIndex, pet);
4527}
@ 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)
2581{
2583 return;
2584
2585 if (!unitTarget)
2586 return;
2587
2588 // Create dispel mask by dispel type
2589 uint32 dispel_type = m_spellInfo->Effects[effIndex].MiscValue;
2590 uint32 dispelMask = SpellInfo::GetDispelMask(DispelType(dispel_type));
2591
2592 DispelChargesList dispel_list;
2593 unitTarget->GetDispellableAuraList(m_caster, dispelMask, dispel_list, m_spellInfo);
2594 if (dispel_list.empty())
2595 return;
2596
2597 // Ok if exist some buffs for dispel try dispel it
2598 uint32 failCount = 0;
2599 DispelChargesList success_list;
2600 WorldPacket dataFail(SMSG_DISPEL_FAILED, 8 + 8 + 4 + 4 + damage * 4);
2601 // dispel N = damage buffs (or while exist buffs for dispel)
2602 for (int32 count = 0; count < damage && !dispel_list.empty();)
2603 {
2604 // Random select buff for dispel
2605 DispelChargesList::iterator itr = dispel_list.begin();
2606 std::advance(itr, urand(0, dispel_list.size() - 1));
2607
2608 int32 chance = itr->first->CalcDispelChance(unitTarget, !unitTarget->IsFriendlyTo(m_caster));
2609 // 2.4.3 Patch Notes: "Dispel effects will no longer attempt to remove effects that have 100% dispel resistance."
2610 if (!chance)
2611 {
2612 dispel_list.erase(itr);
2613 continue;
2614 }
2615 else
2616 {
2617 if (roll_chance_i(chance))
2618 {
2619 bool alreadyListed = false;
2620 for (DispelChargesList::iterator successItr = success_list.begin(); successItr != success_list.end(); ++successItr)
2621 {
2622 if (successItr->first->GetId() == itr->first->GetId())
2623 {
2624 ++successItr->second;
2625 alreadyListed = true;
2626 }
2627 }
2628 if (!alreadyListed)
2629 success_list.push_back(std::make_pair(itr->first, 1));
2630 --itr->second;
2631 if (itr->second <= 0)
2632 dispel_list.erase(itr);
2633 }
2634 else
2635 {
2636 if (!failCount)
2637 {
2638 // Failed to dispell
2639 dataFail << m_caster->GetGUID(); // Caster GUID
2640 dataFail << unitTarget->GetGUID(); // Victim GUID
2641 dataFail << uint32(m_spellInfo->Id); // dispel spell id
2642 }
2643 ++failCount;
2644 dataFail << uint32(itr->first->GetId()); // Spell Id
2645 }
2646 ++count;
2647 }
2648 }
2649
2650 if (failCount)
2651 m_caster->SendMessageToSet(&dataFail, true);
2652
2653 // put in combat
2656
2657 if (success_list.empty())
2658 return;
2659
2660 WorldPacket dataSuccess(SMSG_SPELLDISPELLOG, 8 + 8 + 4 + 1 + 4 + success_list.size() * 5);
2661 // Send packet header
2662 dataSuccess << unitTarget->GetPackGUID(); // Victim GUID
2663 dataSuccess << m_caster->GetPackGUID(); // Caster GUID
2664 dataSuccess << uint32(m_spellInfo->Id); // dispel spell id
2665 dataSuccess << uint8(0); // not used
2666 dataSuccess << uint32(success_list.size()); // count
2667 for (DispelChargesList::iterator itr = success_list.begin(); itr != success_list.end(); ++itr)
2668 {
2669 // Send dispelled spell info
2670 dataSuccess << uint32(itr->first->GetId()); // Spell Id
2671 dataSuccess << uint8(0); // 0 - dispelled !=0 cleansed
2672 unitTarget->RemoveAurasDueToSpellByDispel(itr->first->GetId(), m_spellInfo->Id, itr->first->GetCasterGUID(), m_caster, itr->second);
2673 }
2674 m_caster->SendMessageToSet(&dataSuccess, true);
2675
2676 // On success dispel
2677 // Devour Magic
2679 {
2680 int32 heal_amount = m_spellInfo->Effects[EFFECT_1].CalcValue();
2681 m_caster->CastCustomSpell(m_caster, 19658, &heal_amount, nullptr, nullptr, true);
2682 // Glyph of Felhunter
2683 if (Unit* owner = m_caster->GetOwner())
2684 if (owner->GetAura(56249))
2685 owner->CastCustomSpell(owner, 19658, &heal_amount, nullptr, nullptr, true);
2686 }
2687}
uint32 urand(uint32 min, uint32 max)
Definition Random.cpp:44
@ SPELLFAMILY_WARLOCK
Definition SharedDefines.h:3791
@ 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:5190
@ 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)
5136{
5138 return;
5139
5140 if (!unitTarget)
5141 return;
5142
5143 uint32 mechanic = m_spellInfo->Effects[effIndex].MiscValue;
5144
5145 std::queue<std::pair<uint32, ObjectGuid>> dispel_list;
5146
5147 Unit::AuraMap const& auras = unitTarget->GetOwnedAuras();
5148 for (Unit::AuraMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
5149 {
5150 Aura* aura = itr->second;
5152 continue;
5154 {
5155 if ((aura->GetSpellInfo()->GetAllEffectsMechanicMask() & (UI64LIT(1) << mechanic)))
5156 {
5157 dispel_list.push(std::make_pair(aura->GetId(), aura->GetCasterGUID()));
5158
5159 // spell only removes 1 bleed effect do not continue
5160 if (m_spellInfo->Effects[effIndex].BasePoints == 1)
5161 {
5162 break;
5163 }
5164 }
5165 }
5166 }
5167
5168 for (; dispel_list.size(); dispel_list.pop())
5169 {
5170 unitTarget->RemoveAura(dispel_list.front().first, dispel_list.front().second, 0, AURA_REMOVE_BY_ENEMY_SPELL);
5171 }
5172
5173 // put in combat
5176}
#define UI64LIT(N)
Definition Define.h:97
@ 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:5024

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, UI64LIT, and unitTarget.

◆ EffectDistract()

void Spell::EffectDistract ( SpellEffIndex  effIndex)

@BUG Causes the player to stop moving.

2704{
2706 return;
2707
2708 // Check for possible target
2709 if (!unitTarget || unitTarget->IsEngaged())
2710 return;
2711
2712 // target must be OK to do this
2714 return;
2715
2718}
@ 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:16411
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)
2690{
2692 return;
2693
2695}
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)
4066{
4068 return;
4069
4070 if (!unitTarget || !m_caster->IsPlayer() || !unitTarget->IsPlayer())
4071 return;
4072
4073 Player* caster = m_caster->ToPlayer();
4074 Player* target = unitTarget->ToPlayer();
4075
4076 // caster or target already have requested duel
4077 if (caster->duel || target->duel || !target->GetSocial() || target->GetSocial()->HasIgnore(caster->GetGUID()))
4078 return;
4079
4080 // Players can only fight a duel in zones with this flag
4081 AreaTableEntry const* casterAreaEntry = sAreaTableStore.LookupEntry(caster->GetAreaId());
4082 if (casterAreaEntry && !(casterAreaEntry->flags & AREA_FLAG_ALLOW_DUELS))
4083 {
4084 SendCastResult(SPELL_FAILED_NO_DUELING); // Dueling isn't allowed here
4085 return;
4086 }
4087
4088 AreaTableEntry const* targetAreaEntry = sAreaTableStore.LookupEntry(target->GetAreaId());
4089 if (targetAreaEntry && !(targetAreaEntry->flags & AREA_FLAG_ALLOW_DUELS))
4090 {
4091 SendCastResult(SPELL_FAILED_NO_DUELING); // Dueling isn't allowed here
4092 return;
4093 }
4094
4095 //CREATE DUEL FLAG OBJECT
4096 uint32 gameobject_id = m_spellInfo->Effects[effIndex].MiscValue;
4097 GameObject* pGameObj = sObjectMgr->IsGameObjectStaticTransport(gameobject_id) ? new StaticTransport() : new GameObject();
4098
4099 Map* map = m_caster->GetMap();
4100 G3D::Quat rotation = G3D::Quat::fromAxisAngleRotation(G3D::Vector3::unitZ(), m_caster->GetOrientation());
4101 if (!pGameObj->Create(map->GenerateLowGuid<HighGuid::GameObject>(), gameobject_id,
4102 map, m_caster->GetPhaseMask(),
4106 m_caster->GetOrientation(), rotation, 0, GO_STATE_READY))
4107 {
4108 delete pGameObj;
4109 return;
4110 }
4111
4114 int32 duration = m_spellInfo->GetDuration();
4115 pGameObj->SetRespawnTime(duration > 0 ? duration / IN_MILLISECONDS : 0);
4116 pGameObj->SetSpellId(m_spellInfo->Id);
4117
4118 ExecuteLogEffectSummonObject(effIndex, pGameObj);
4119
4120 m_caster->AddGameObject(pGameObj);
4121 map->AddToMap(pGameObj, true);
4122 //END
4123
4124 // Send request
4125 WorldPacket data(SMSG_DUEL_REQUESTED, 8 + 8);
4126 data << pGameObj->GetGUID();
4127 data << caster->GetGUID();
4128 caster->SendDirectMessage(&data);
4129 target->SendDirectMessage(&data);
4130
4131 // create duel-info
4132 bool isMounted = (GetSpellInfo()->Id == 62875);
4133 caster->duel = std::make_unique<DuelInfo>(target, caster, isMounted);
4134 target->duel = std::make_unique<DuelInfo>(caster, caster, isMounted);
4135
4136 caster->SetGuidValue(PLAYER_DUEL_ARBITER, pGameObj->GetGUID());
4137 target->SetGuidValue(PLAYER_DUEL_ARBITER, pGameObj->GetGUID());
4138
4139 sScriptMgr->OnPlayerDuelRequest(target, caster);
4140}
@ 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:1279
void SetSpellId(uint32 id)
Definition GameObject.h:176
void SetUInt32Value(uint16 index, uint32 value)
Definition Object.cpp:639
bool HasIgnore(ObjectGuid const &ignore_guid) const
Definition SocialMgr.cpp:193
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:6548
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)
663{
665 return;
666
668 return;
669
670 // selection by spell family
672 {
674 {
675 switch (m_spellInfo->Id)
676 {
677 // Trial of the Champion, Trample
678 case 67866:
679 {
681 unitTarget->CastSpell(unitTarget, 67867, false);
682 return;
683 }
684 // Trial of the Champion, Hammer of the Righteous
685 case 66867:
686 {
687 if (!unitTarget)
688 return;
689 if (unitTarget->HasAura(66940))
690 m_caster->CastSpell(unitTarget, 66903, true);
691 else
692 m_caster->CastSpell(unitTarget, 66904, true);
693 return;
694 }
695 case 17731:
696 case 69294:
697 {
699 return;
700
704 trigger->CastSpell(trigger, 17731, false);
705
706 return;
707 }
708 // HoL, Arc Weld
709 case 59086:
710 {
712 m_caster->CastSpell(m_caster, 59097, true);
713
714 return;
715 }
716 }
717 break;
718 }
720 switch (m_spellInfo->Id)
721 {
722 case 31789: // Righteous Defense (step 1)
723 {
724 if (!unitTarget)
725 return;
726 // not empty (checked), copy
728
729 // remove invalid attackers
730 for (Unit::AttackerSet::iterator aItr = attackers.begin(); aItr != attackers.end();)
731 if (!(*aItr)->IsValidAttackTarget(m_caster))
732 aItr = attackers.erase(aItr);
733 else
734 ++aItr;
735
736 // selected from list 3
737 uint32 maxTargets = std::min<uint32>(3, attackers.size());
738 for (uint32 i = 0; i < maxTargets; ++i)
739 {
740 Unit::AttackerSet::iterator aItr = attackers.begin();
741 std::advance(aItr, urand(0, attackers.size() - 1));
742 m_caster->CastSpell((*aItr), 31790, true);
743 attackers.erase(aItr);
744 }
745
746 return;
747 }
748 }
749 break;
751 // Hunger for Blood
752 if (m_spellInfo->Id == 51662)
753 {
754 m_caster->CastSpell(m_caster, 63848, true);
755 return;
756 }
757 break;
758 }
759
760 // pet auras
761 if (PetAura const* petSpell = sSpellMgr->GetPetAura(m_spellInfo->Id, effIndex))
762 {
763 m_caster->AddPetAura(petSpell);
764 return;
765 }
766
767 // normal DB scripted effect
768 LOG_DEBUG("spells.aura", "Spell ScriptStart spellid {} in EffectDummy({})", m_spellInfo->Id, effIndex);
770
771 if (gameObjTarget)
772 {
773 sScriptMgr->OnDummyEffect(m_caster, m_spellInfo->Id, effIndex, gameObjTarget);
774 }
775 else if (unitTarget && unitTarget->IsCreature())
776 {
777 sScriptMgr->OnDummyEffect(m_caster, m_spellInfo->Id, effIndex, unitTarget->ToCreature());
778 }
779 else if (itemTarget)
780 {
781 sScriptMgr->OnDummyEffect(m_caster, m_spellInfo->Id, effIndex, itemTarget);
782 }
783}
ScriptMapMap sSpellScripts
Definition ObjectMgr.cpp:60
@ TEMPSUMMON_TIMED_DESPAWN
Definition Object.h:51
@ SPELLFAMILY_GENERIC
Definition SharedDefines.h:3786
@ SPELLFAMILY_PALADIN
Definition SharedDefines.h:3796
@ SPELLFAMILY_ROGUE
Definition SharedDefines.h:3794
@ UNIT_FIELD_MOUNTDISPLAYID
Definition UpdateFields.h:126
uint8 GetGoAnimProgress() const
Definition GameObject.h:208
time_t GetRespawnTime() const
Definition GameObject.h:183
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:13672
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:2394

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)
5260{
5262 return;
5263
5264 if (!unitTarget)
5265 return;
5266
5267 Player* player = unitTarget->ToPlayer();
5268 if (!player)
5269 {
5270 return;
5271 }
5272
5273 int32 slot = m_spellInfo->Effects[effIndex].MiscValue;
5274
5275 // -1 means all player equipped items and -2 all items
5276 if (slot < 0)
5277 {
5278 player->DurabilityPointsLossAll(damage, (slot < -1));
5280 return;
5281 }
5282
5283 // invalid slot value
5284 if (slot >= INVENTORY_SLOT_BAG_END)
5285 return;
5286
5287 if (Item* item = player->GetItemByPos(INVENTORY_SLOT_BAG_0, slot))
5288 {
5289 player->DurabilityPointsLoss(item, damage);
5290 ExecuteLogEffectDurabilityDamage(effIndex, unitTarget, item->GetEntry(), slot);
5291 }
5292}
@ 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:443
void DurabilityPointsLossAll(int32 points, bool inventory)
Definition Player.cpp:4666
void DurabilityPointsLoss(Item *item, int32 points)
Definition Player.cpp:4692
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)
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 // FIXME: some spells effects have value -1/-2
5311 // Possibly its mean -1 all player equipped items and -2 all items
5312 if (slot < 0)
5313 {
5314 player->DurabilityLossAll(float(damage) / 100.0f, (slot < -1));
5315 return;
5316 }
5317
5318 // invalid slot value
5319 if (slot >= INVENTORY_SLOT_BAG_END)
5320 return;
5321
5322 if (damage <= 0)
5323 return;
5324
5325 if (Item* item = player->GetItemByPos(INVENTORY_SLOT_BAG_0, slot))
5326 player->DurabilityLoss(item, float(damage) / 100.0f);
5327}
void DurabilityLossAll(double percent, bool inventory)
Definition Player.cpp:4622
void DurabilityLoss(Item *item, double percent)
Definition Player.cpp:4648

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)
4377{
4379 return;
4380
4381 // this is only item spell effect applied to main-hand weapon of target player (players in area)
4382 if (!unitTarget)
4383 return;
4384
4385 Player* item_owner = unitTarget->ToPlayer();
4386 if (!item_owner)
4387 {
4388 return;
4389 }
4390
4392 if (!item)
4393 return;
4394
4395 // must be equipped
4396 if (!item->IsEquipped())
4397 return;
4398
4399 if (m_spellInfo->Effects[effIndex].MiscValue)
4400 {
4401 uint32 enchant_id = m_spellInfo->Effects[effIndex].MiscValue;
4402 int32 duration = m_spellInfo->GetDuration(); //Try duration index first ..
4403 if (!duration)
4404 duration = damage * IN_MILLISECONDS; //+1; //Base points after ..
4405 if (!duration)
4406 duration = 10 * IN_MILLISECONDS; //10 seconds for enchants which don't have listed duration
4407
4408 // Xinef: Venomhide poison, no other spell uses this effect...
4409 if (m_spellInfo->Id == 14792)
4410 duration = 5 * MINUTE * IN_MILLISECONDS;
4411
4412 SpellItemEnchantmentEntry const* pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id);
4413 if (!pEnchant)
4414 return;
4415
4416 // Always go to temp enchantment slot
4418
4419 // Enchantment will not be applied if a different one already exists
4420 if (item->GetEnchantmentId(slot) && item->GetEnchantmentId(slot) != enchant_id)
4421 return;
4422
4423 // Apply the temporary enchantment
4424 item->SetEnchantment(slot, enchant_id, duration, pEnchant->charges, m_caster->GetGUID());
4425 item_owner->ApplyEnchantment(item, slot, true);
4426 }
4427}
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:4371
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)
2848{
2850 return;
2851
2852 if (!m_caster->IsPlayer())
2853 return;
2854 if (!itemTarget)
2855 return;
2856
2857 Player* p_caster = m_caster->ToPlayer();
2858
2859 // Handle vellums
2861 {
2862 // destroy one vellum from stack
2863 uint32 count = 1;
2864 p_caster->DestroyItemCount(itemTarget, count, true);
2865 unitTarget = p_caster;
2866 // and add a scroll
2867 DoCreateItem(effIndex, m_spellInfo->Effects[effIndex].ItemType);
2868 itemTarget = nullptr;
2869 m_targets.SetItemTarget(nullptr);
2870 }
2871 else
2872 {
2873 // do not increase skill if vellum used
2875 p_caster->UpdateCraftSkill(m_spellInfo->Id);
2876
2877 uint32 enchant_id = m_spellInfo->Effects[effIndex].MiscValue;
2878 if (!enchant_id)
2879 return;
2880
2881 SpellItemEnchantmentEntry const* pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id);
2882 if (!pEnchant)
2883 return;
2884
2885 // item can be in trade slot and have owner diff. from caster
2886 Player* item_owner = itemTarget->GetOwner();
2887 if (!item_owner)
2888 return;
2889
2890 // remove old enchanting before applying new if equipped
2892
2894
2895 // add new enchanting if equipped
2897
2898 item_owner->RemoveTradeableItem(itemTarget);
2900 }
2901}
@ PERM_ENCHANTMENT_SLOT
Definition Item.h:169
void ClearSoulboundTradeable(Player *currentOwner)
Definition Item.cpp:1264
void RemoveTradeableItem(Item *item)
Definition PlayerStorage.cpp:4206
void SetItemTarget(Item *item)
Definition Spell.cpp:327

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

◆ EffectEnchantItemPrismatic()

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

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

◆ EffectEnchantItemTmp()

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

◆ EffectEnergize()

void Spell::EffectEnergize ( SpellEffIndex  effIndex)
1883{
1885 return;
1886
1887 if (!unitTarget)
1888 return;
1889 if (!unitTarget->IsAlive())
1890 return;
1891
1893 {
1895 return;
1896 }
1897
1898 if (m_spellInfo->Effects[effIndex].MiscValue < 0 || m_spellInfo->Effects[effIndex].MiscValue >= int8(MAX_POWERS))
1899 return;
1900
1901 Powers power = Powers(m_spellInfo->Effects[effIndex].MiscValue);
1902
1905 return;
1906
1907 if (unitTarget->GetMaxPower(power) == 0)
1908 return;
1909
1910 // Some level depends spells
1911 int level_multiplier = 0;
1912 int level_diff = 0;
1913 switch (m_spellInfo->Id)
1914 {
1915 case 9512: // Restore Energy
1916 level_diff = m_caster->GetLevel() - 40;
1917 level_multiplier = 2;
1918 break;
1919 case 24571: // Blood Fury
1920 level_diff = m_caster->GetLevel() - 60;
1921 level_multiplier = 10;
1922 break;
1923 case 24532: // Burst of Energy
1924 level_diff = m_caster->GetLevel() - 60;
1925 level_multiplier = 4;
1926 break;
1927 case 31930: // Judgements of the Wise
1928 case 63375: // Improved Stormstrike
1929 case 68082: // Glyph of Seal of Command
1931 break;
1932 case 48542: // Revitalize
1934 break;
1935 case 71132: // Glyph of Shadow Word: Pain
1936 damage = int32(CalculatePct(unitTarget->GetCreateMana(), 1)); // set 1 as value, missing in dbc
1937 break;
1938 default:
1939 break;
1940 }
1941
1942 if (level_diff > 0)
1943 damage -= level_multiplier * level_diff;
1944
1945 if (damage < 0)
1946 return;
1947
1949
1950 // Mad Alchemist's Potion
1951 if (m_spellInfo->Id == 45051)
1952 {
1953 // find elixirs on target
1954 bool guardianFound = false;
1955 bool battleFound = false;
1957 for (Unit::AuraApplicationMap::iterator itr = Auras.begin(); itr != Auras.end(); ++itr)
1958 {
1959 if (!guardianFound && sSpellMgr->IsSpellMemberOfSpellGroup(itr->second->GetBase()->GetId(), SPELL_GROUP_ELIXIR_GUARDIAN))
1960 guardianFound = true;
1961 if (!battleFound && sSpellMgr->IsSpellMemberOfSpellGroup(itr->second->GetBase()->GetId(), SPELL_GROUP_ELIXIR_BATTLE))
1962 battleFound = true;
1963 if (battleFound && guardianFound)
1964 break;
1965 }
1966
1967 // get all available elixirs by mask and spell level
1968 std::set<uint32> availableElixirs;
1969 if (!guardianFound)
1970 sSpellMgr->GetSetOfSpellsInSpellGroup(SPELL_GROUP_ELIXIR_GUARDIAN, availableElixirs);
1971 if (!battleFound)
1972 sSpellMgr->GetSetOfSpellsInSpellGroup(SPELL_GROUP_ELIXIR_BATTLE, availableElixirs);
1973 for (std::set<uint32>::iterator itr = availableElixirs.begin(); itr != availableElixirs.end();)
1974 {
1975 SpellInfo const* spellInfo = sSpellMgr->AssertSpellInfo(*itr);
1976 if (spellInfo->SpellLevel < m_spellInfo->SpellLevel || spellInfo->SpellLevel > unitTarget->GetLevel())
1977 availableElixirs.erase(itr++);
1978 else
1979 ++itr;
1980 }
1981
1982 if (!availableElixirs.empty())
1983 {
1984 // cast random elixir on target
1986 }
1987 }
1988}
@ SPELL_ATTR7_ONLY_IN_SPELLBOOK_UNTIL_LEARNED
Definition SharedDefines.h:645
@ SPELLFAMILY_POTION
Definition SharedDefines.h:3799
@ 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:8363
void SendSpellDamageImmune(Unit *target, uint32 spellId)
Definition Unit.cpp:6860
bool IsImmunedToAuraPeriodicTick(Unit const *caster, SpellInfo const *spellInfo) const
Definition Unit.cpp:9947
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)
1991{
1993 return;
1994
1995 if (!unitTarget)
1996 return;
1997 if (!unitTarget->IsAlive())
1998 return;
1999
2001 {
2003 return;
2004 }
2005
2006 if (m_spellInfo->Effects[effIndex].MiscValue < 0 || m_spellInfo->Effects[effIndex].MiscValue >= int8(MAX_POWERS))
2007 return;
2008
2009 Powers power = Powers(m_spellInfo->Effects[effIndex].MiscValue);
2010
2012 return;
2013
2014 uint32 maxPower = unitTarget->GetMaxPower(power);
2015 if (maxPower == 0)
2016 return;
2017
2018 uint32 gain = CalculatePct(maxPower, damage);
2020}
@ 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)
299{
301 return;
302
303 if (!unitTarget || !unitTarget->IsAlive())
304 return;
305
306 if (unitTarget->IsPlayer())
308 else
309 {
311
312 uint32 absorb = dmgInfo.GetAbsorb();
313 uint32 resist = dmgInfo.GetResist();
314 uint32 envDamage = dmgInfo.GetDamage();
315
316 Unit::DealDamageMods(unitTarget, envDamage, &absorb);
317 damage = envDamage;
318
320 }
321}
@ DAMAGE_FIRE
Definition Player.h:832
uint32 EnvironmentalDamage(EnviromentalDamage type, uint32 damage)
Definition Player.cpp:770

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
4483{
4485 return;
4486
4487 Player* player = m_caster->ToPlayer();
4488 if (!player)
4489 return;
4490
4491 Item* foodItem = itemTarget;
4492 if (!foodItem)
4493 return;
4494
4495 Pet* pet = player->GetPet();
4496 if (!pet)
4497 return;
4498
4499 if (!pet->IsAlive())
4500 return;
4501
4502 int32 benefit = pet->GetCurrentFoodBenefitLevel(foodItem->GetTemplate()->ItemLevel);
4503 if (benefit <= 0)
4504 return;
4505
4506 ExecuteLogEffectDestroyItem(effIndex, foodItem->GetEntry());
4507
4508 uint32 count = 1;
4509 player->DestroyItemCount(foodItem, count, true);
4511
4512 m_caster->CastCustomSpell(pet, m_spellInfo->Effects[effIndex].TriggerSpell, &benefit, nullptr, nullptr, true);
4513}
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)
997{
999 return;
1000
1001 if (!unitTarget)
1002 return;
1003
1004 uint32 triggered_spell_id = m_spellInfo->Effects[effIndex].TriggerSpell;
1005
1006 // normal case
1007 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(triggered_spell_id);
1008
1009 if (!spellInfo)
1010 {
1011 LOG_ERROR("spells.effect", "Spell::EffectForceCast of spell {}: triggering unknown spell id {}", m_spellInfo->Id, triggered_spell_id);
1012 return;
1013 }
1014
1015 if (m_spellInfo->Effects[effIndex].Effect == SPELL_EFFECT_FORCE_CAST && damage)
1016 {
1017 switch (m_spellInfo->Id)
1018 {
1019 case 52588: // Skeletal Gryphon Escape
1020 case 48598: // Ride Flamebringer Cue
1022 break;
1023 case 52463: // Hide In Mine Car
1024 case 52349: // Overtake
1025 unitTarget->CastCustomSpell(unitTarget, spellInfo->Id, &damage, nullptr, nullptr, true, nullptr, nullptr, m_originalCasterGUID);
1026 return;
1027 case 72378: // Blood Nova
1028 case 73058: // Blood Nova
1029 m_caster->CastSpell(unitTarget, damage, true); // additional spell cast
1030 break;
1031 }
1032 }
1033
1034 CustomSpellValues values;
1035 // set basepoints for trigger with value effect
1037 {
1038 // maybe need to set value only when basepoints == 0?
1042 }
1043
1044 SpellCastTargets targets;
1045 targets.SetUnitTarget(m_caster);
1046
1047 unitTarget->CastSpell(targets, spellInfo, &values, TRIGGERED_FULL_MASK);
1048}
@ 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)
4740{
4742 return;
4743
4744 // xinef: clear focus
4746
4748 data << m_caster->GetGUID();
4749
4751 Acore::MessageDistDelivererToHostile notifier(m_caster, &data, dist);
4752 Cell::VisitObjects(m_caster, notifier, dist);
4753
4754 // xinef: we should also force pets to remove us from current target
4755 Unit::AttackerSet attackerSet;
4756 for (Unit::AttackerSet::const_iterator itr = m_caster->getAttackers().begin(); itr != m_caster->getAttackers().end(); ++itr)
4757 if ((*itr)->IsCreature() && !(*itr)->CanHaveThreatList())
4758 attackerSet.insert(*itr);
4759
4760 for (Unit::AttackerSet::const_iterator itr = attackerSet.begin(); itr != attackerSet.end(); ++itr)
4761 (*itr)->AttackStop();
4762
4763 // Xinef: Mirror images code Initialize Images
4764 if (m_spellInfo->Id == 58836)
4765 {
4766 std::vector<Unit*> images;
4767 for (Unit::ControlSet::const_iterator itr = m_caster->m_Controlled.begin(); itr != m_caster->m_Controlled.end(); ++itr)
4768 if ((*itr)->GetEntry() == 31216 /*NPC_MIRROR_IMAGE*/)
4769 images.push_back(*itr);
4770
4771 if (images.empty())
4772 return;
4773
4774 UnitList targets;
4775 Acore::AnyUnfriendlyUnitInObjectRangeCheck u_check(m_caster, m_caster, m_caster->GetVisibilityRange()); // no VISIBILITY_COMPENSATION, distance is enough
4778 for (UnitList::iterator iter = targets.begin(); iter != targets.end(); ++iter)
4779 {
4780 if (!(*iter)->HasUnitState(UNIT_STATE_CASTING))
4781 continue;
4782
4783 if (Spell* spell = (*iter)->GetCurrentSpell(CURRENT_GENERIC_SPELL))
4784 {
4785 if (spell->m_targets.GetUnitTargetGUID() == m_caster->GetGUID())
4786 {
4787 SpellInfo const* si = spell->GetSpellInfo();
4788 if (si->HasAttribute(SPELL_ATTR6_IGNORE_PHASE_SHIFT) && (*iter)->IsCreature())
4789 {
4790 Creature* c = (*iter)->ToCreature();
4791 if ((!c->IsPet() && c->GetCreatureTemplate()->rank == CREATURE_ELITE_WORLDBOSS) || c->isWorldBoss() || c->IsDungeonBoss())
4792 continue;
4793 }
4794
4795 bool interrupt = false; // pussywizard: skip spells that don't target units, but casted on unit (eg. TARGET_DEST_TARGET_ENEMY)
4796 for (uint8 j = 0; j < MAX_SPELL_EFFECTS; ++j)
4797 if (si->Effects[j].Effect && (si->Effects[j].GetUsedTargetObjectType() == TARGET_OBJECT_TYPE_UNIT || si->Effects[j].GetUsedTargetObjectType() == TARGET_OBJECT_TYPE_UNIT_AND_DEST))
4798 {
4799 // at least one effect truly targets an unit, interrupt the spell
4800 interrupt = true;
4801 break;
4802 }
4803
4804 if (interrupt)
4805 spell->m_targets.SetUnitTarget(images.at(urand(0, images.size() - 1)));
4806 }
4807 }
4808 }
4809 }
4810}
#define VISIBILITY_COMPENSATION
Definition ObjectDefines.h:26
@ CREATURE_ELITE_WORLDBOSS
Definition SharedDefines.h:2969
@ 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:3205
ControlSet m_Controlled
Definition Unit.h:2074
void SendClearTarget()
Definition Unit.cpp:16216
@ 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)
5897{
5899 return;
5900
5901 if (!gameObjTarget)
5902 return;
5903
5904 Unit* caster = m_originalCaster;
5905 if (!caster)
5906 return;
5907
5908 FactionTemplateEntry const* casterFaction = caster->GetFactionTemplateEntry();
5910 // Do not allow to damage GO's of friendly factions (ie: Wintergrasp Walls/Ulduar Storm Beacons)
5911 if ((casterFaction && targetFaction && !casterFaction->IsFriendlyTo(*targetFaction)) || !targetFaction)
5913}
DBCStorage< FactionTemplateEntry > sFactionTemplateStore(FactionTemplateEntryfmt)
void ModifyHealth(int32 change, Unit *attackerOrHealer=nullptr, uint32 spellId=0)
Definition GameObject.cpp:2292
FactionTemplateEntry const * GetFactionTemplateEntry() const
Definition Unit.cpp:7034
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)
5927{
5929 return;
5930
5932 return;
5933
5936}
GameObjectDestructibleState
Definition SharedDefines.h:1632
void SetDestructibleState(GameObjectDestructibleState state, Player *eventInvoker=nullptr, bool setHealth=false)
Definition GameObject.cpp:2355

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)
1473{
1475 return;
1476
1477 if (unitTarget && unitTarget->IsAlive() && damage >= 0)
1478 {
1479 // Try to get original caster
1481
1482 // Skip if m_originalCaster not available
1483 if (!caster)
1484 return;
1485
1486 int32 addhealth = damage;
1487
1488 // Vessel of the Naaru (Vial of the Sunwell trinket)
1489 if (m_spellInfo->Id == 45064)
1490 {
1491 // Amount of heal - depends from stacked Holy Energy
1492 int damageAmount = 0;
1493 if (AuraEffect const* aurEff = m_caster->GetAuraEffect(45062, 0))
1494 {
1495 damageAmount += aurEff->GetAmount();
1497 }
1498
1499 addhealth += damageAmount;
1500 }
1501 // Swiftmend - consumes Regrowth or Rejuvenation
1503 {
1505 // find most short by duration
1506 AuraEffect* forcedTargetAura = nullptr;
1507 AuraEffect* targetAura = nullptr;
1508 for (Unit::AuraEffectList::const_iterator i = RejorRegr.begin(); i != RejorRegr.end(); ++i)
1509 {
1510 if ((*i)->GetSpellInfo()->SpellFamilyName == SPELLFAMILY_DRUID
1511 && (*i)->GetSpellInfo()->SpellFamilyFlags[0] & 0x50)
1512 {
1513 if (m_caster->GetGUID() == (*i)->GetCasterGUID())
1514 {
1515 if (!forcedTargetAura || (*i)->GetBase()->GetDuration() < forcedTargetAura->GetBase()->GetDuration())
1516 forcedTargetAura = *i;
1517 }
1518 else if (!targetAura || (*i)->GetBase()->GetDuration() < targetAura->GetBase()->GetDuration())
1519 targetAura = *i;
1520 }
1521 }
1522
1523 if (forcedTargetAura)
1524 targetAura = forcedTargetAura;
1525
1526 if (!targetAura)
1527 {
1528 LOG_ERROR("spells.effect", "Target({}) has aurastate AURA_STATE_SWIFTMEND but no matching aura.", unitTarget->GetGUID().ToString());
1529 return;
1530 }
1531
1532 int32 tickheal = targetAura->GetAmount();
1533 if (Unit* auraCaster = targetAura->GetCaster())
1534 tickheal = unitTarget->SpellHealingBonusTaken(auraCaster, targetAura->GetSpellInfo(), tickheal, DOT);
1535
1536 //int32 tickheal = targetAura->GetSpellInfo()->EffectBasePoints[idx] + 1;
1537 //It is said that talent bonus should not be included
1538
1539 int32 tickcount = 0;
1540 // Rejuvenation
1541 if (targetAura->GetSpellInfo()->SpellFamilyFlags[0] & 0x10)
1542 tickcount = 4;
1543 // Regrowth
1544 else // if (targetAura->GetSpellInfo()->SpellFamilyFlags[0] & 0x40)
1545 tickcount = 6;
1546
1547 addhealth += tickheal * tickcount;
1548
1549 // Glyph of Swiftmend
1550 if (!caster->HasAura(54824))
1551 unitTarget->RemoveAura(targetAura->GetId(), targetAura->GetCasterGUID());
1552
1553 //addhealth += tickheal * tickcount;
1554 //addhealth = caster->SpellHealingBonus(m_spellInfo, addhealth, HEAL, unitTarget);
1555 }
1556 // Death Pact - return pct of max health to caster
1558 {
1559 addhealth = caster->SpellHealingBonusDone(unitTarget, m_spellInfo, int32(caster->CountPctFromMaxHealth(damage)), HEAL, effIndex);
1560 m_damageBeforeTakenMods -= addhealth;
1561 addhealth = unitTarget->SpellHealingBonusTaken(caster, m_spellInfo, addhealth, HEAL);
1562 }
1563 else if (m_spellInfo->Id != 33778) // not lifebloom
1564 {
1565 addhealth = caster->SpellHealingBonusDone(unitTarget, m_spellInfo, addhealth, HEAL, effIndex);
1566 m_damageBeforeTakenMods -= addhealth;
1567 addhealth = unitTarget->SpellHealingBonusTaken(caster, m_spellInfo, addhealth, HEAL);
1568 }
1569
1570 // Implemented this way as there is no other way to do it currently (that I know :P)...
1571 if (caster->ToPlayer() && caster->HasAura(23401)) // Nefarian Corrupted Healing (priest)
1572 {
1574 {
1575 m_damage = 0;
1576 caster->CastSpell(unitTarget, 23402, false); // Nefarian Corrupted Healing Periodic Damage effect.
1577 return;
1578 }
1579 }
1580
1581 m_damage -= addhealth;
1582 }
1583}
@ SPELLFAMILY_DRUID
Definition SharedDefines.h:3793
@ SPELLFAMILY_DEATHKNIGHT
Definition SharedDefines.h:3801
@ AURA_STATE_SWIFTMEND
Definition SharedDefines.h:1295
@ SPELL_SCHOOL_MASK_HOLY
Definition SharedDefines.h:286
@ 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:5755
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_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)
3677{
3679 return;
3680
3681 if (!unitTarget || !unitTarget->IsAlive())
3682 return;
3683
3685 {
3687 return;
3688 }
3689
3690 int32 addhealth = 0;
3691
3692 // damage == 0 - heal for caster max health
3693 if (damage == 0)
3694 addhealth = m_caster->GetMaxHealth();
3695 else
3696 addhealth = unitTarget->GetMaxHealth() - unitTarget->GetHealth();
3697
3698 m_healing += addhealth;
3699}
uint32 GetMaxHealth() const
Definition Unit.h: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)
1623{
1625 return;
1626
1627 if (!unitTarget || !unitTarget->IsAlive() || damage < 0)
1628 return;
1629
1632
1633 LOG_DEBUG("spells.aura", "HealthLeech :{}", damage);
1634
1635 // xinef: handled in spell.cpp
1636 //float healMultiplier = m_spellInfo->Effects[effIndex].CalcValueMultiplier(m_originalCaster, this);
1637
1638 m_damage += damage;
1639 // get max possible damage, don't count overkill for heal
1640 //uint32 healthGain = uint32(-unitTarget->GetHealthGain(-damage) * healMultiplier);
1641
1642 //if (m_caster->IsAlive())
1643 //{
1644 // healthGain = m_caster->SpellHealingBonusDone(m_caster, m_spellInfo, healthGain, HEAL);
1645 // healthGain = m_caster->SpellHealingBonusTaken(m_caster, m_spellInfo, healthGain, HEAL);
1646
1647 // m_caster->HealBySpell(m_caster, m_spellInfo, uint32(healthGain));
1648 //}
1649}
uint32 SpellDamageBonusTaken(Unit *caster, SpellInfo const *spellProto, uint32 pdamage, DamageEffectType damagetype, uint32 stack=1)
Definition Unit.cpp:8869
uint32 SpellDamageBonusDone(Unit *victim, SpellInfo const *spellProto, uint32 pdamage, DamageEffectType damagetype, uint8 effIndex, float TotalMod=0.0f, uint32 stack=1)
Definition Unit.cpp:8701

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)
4447{
4449 return;
4450
4451 if (!unitTarget)
4452 return;
4453
4454 Player* player = unitTarget->ToPlayer();
4455 if (!player)
4456 {
4457 return;
4458 }
4459
4460 uint8 currentDrunk = player->GetDrunkValue();
4461 int32 drunkMod = damage;
4462
4463 if (drunkMod == 0)
4464 return;
4465
4466 // drunkMod may contain values ​​that are guaranteed to cause uint8 overflow/underflow (examples: 29690, 46874)
4467 // In addition, we would not want currentDrunk to become more than 100.
4468 // So before adding the values, let's check that everything is fine.
4469 if (drunkMod > 0 && drunkMod > static_cast<int32>(100 - currentDrunk))
4470 currentDrunk = 100;
4471 else if (drunkMod < 0 && drunkMod < static_cast<int32>(0 - currentDrunk))
4472 currentDrunk = 0;
4473 else
4474 currentDrunk += drunkMod; // Due to previous checks we can be sure that currentDrunk will not go beyond [0-100] range.
4475
4476 player->SetDrunkValue(currentDrunk, m_CastItem ? m_CastItem->GetEntry() : 0);
4477
4478 if (currentDrunk == 100 && roll_chance_i(25))
4479 player->CastSpell(player, 67468, false); // Drunken Vomit
4480}
uint8 GetDrunkValue() const
Definition Player.h:2190
void SetDrunkValue(uint8 newDrunkValue, uint32 itemId=0)
Definition Player.cpp:987

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)
275{
277 return;
278
279 if (!unitTarget || !unitTarget->IsAlive() || unitTarget->HasAura(27827)) // Spirit of redemption doesn't make you death, but can cause infinite loops
280 return;
281
282 if (unitTarget->IsPlayer())
284 return;
285
286 if (m_caster == unitTarget) // prevent interrupt message
287 finish();
288
289 WorldPacket data(SMSG_SPELLINSTAKILLLOG, 8 + 8 + 4);
290 data << m_caster->GetGUID();
291 data << unitTarget->GetGUID();
292 data << uint32(m_spellInfo->Id);
293 m_caster->SendMessageToSet(&data, true);
294
296}
@ 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:983
@ 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
3702{
3704 return;
3705
3706 if (!unitTarget || !unitTarget->IsAlive())
3707 return;
3708
3710 // also exist case: apply cooldown to interrupted cast only and to all spells
3711 // there is no CURRENT_AUTOREPEAT_SPELL spells that can be interrupted
3713 {
3715 {
3716 SpellInfo const* curSpellInfo = spell->m_spellInfo;
3717 // check if we can interrupt spell
3718 if ((spell->getState() == SPELL_STATE_CASTING
3719 || (spell->getState() == SPELL_STATE_PREPARING && spell->GetCastTime() > 0.0f))
3723 {
3724 if (m_originalCaster)
3725 {
3727 unitTarget->ProhibitSpellSchool(curSpellInfo->GetSchoolMask(), duration/*spellInfo->GetDuration()*/);
3728 }
3729 ExecuteLogEffectInterruptCast(effIndex, unitTarget, curSpellInfo->Id);
3731 }
3732 }
3733 }
3734}
@ 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:4230
int32 CalcSpellDuration(SpellInfo const *spellProto)
Definition Unit.cpp:11563
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)
1070{
1072 return;
1073
1074 if (m_caster->IsInFlight())
1075 return;
1076
1077 if (!unitTarget)
1078 return;
1079
1080 float speedXY, speedZ;
1081 CalculateJumpSpeeds(effIndex, m_caster->GetExactDist2d(unitTarget), speedXY, speedZ);
1082 m_caster->GetMotionMaster()->MoveJump(*unitTarget, speedXY, speedZ);
1083
1084 if (m_caster->IsPlayer())
1085 {
1086 sScriptMgr->AnticheatSetUnderACKmount(m_caster->ToPlayer());
1087 }
1088}
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:1153
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)
1091{
1093 return;
1094
1095 if (m_caster->IsInFlight())
1096 return;
1097
1098 if (!m_targets.HasDst() || m_caster->GetVehicle())
1099 return;
1100
1101 // Init dest coordinates
1102 float x, y, z;
1103 destTarget->GetPosition(x, y, z);
1104 // xinef: this can happen if MovePositionToFirstCollision detects that X, Y cords are invalid and returns prematurely
1105 if (!Acore::IsValidMapCoord(x, y, z) || z <= INVALID_HEIGHT)
1106 return;
1107
1108 float speedXY, speedZ;
1109 float dist = m_caster->GetExactDist2d(x, y);
1110 CalculateJumpSpeeds(effIndex, dist, speedXY, speedZ);
1111
1112 // Override, calculations are incorrect
1113 if (m_spellInfo->Id == 49376) // feral charge
1114 {
1115 speedXY = pow(speedZ * 10, 8);
1117
1118 if (Player* player = m_caster->ToPlayer())
1119 {
1120 player->SetCanTeleport(true);
1121 }
1122
1123 if (m_caster->IsPlayer())
1124 {
1125 sScriptMgr->AnticheatSetUnderACKmount(m_caster->ToPlayer());
1126 }
1127
1128 return;
1129 }
1130
1131 if (m_spellInfo->Id == 57604) // death grip
1132 {
1133 speedZ = 3.0f;
1134 speedXY = 50.0f;
1135 }
1136
1137 // crash fix?
1138 if (speedXY < 1.0f)
1139 speedXY = 1.0f;
1140
1141 if (Player* player = m_caster->ToPlayer())
1142 {
1143 player->SetCanTeleport(true);
1144 }
1145 m_caster->GetMotionMaster()->MoveJump(x, y, z, speedXY, speedZ);
1146
1147 if (m_caster->IsPlayer())
1148 {
1149 sScriptMgr->AnticheatSetUnderACKmount(m_caster->ToPlayer());
1150 }
1151}
#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)
5689{
5691 return;
5692
5693 if (!unitTarget)
5694 return;
5695
5697 if (!player)
5698 {
5699 return;
5700 }
5701
5702 int32 creatureEntry = m_spellInfo->Effects[effIndex].MiscValue;
5703 if (!creatureEntry)
5704 {
5705 if (m_spellInfo->Id == 42793) // Burn Body
5706 creatureEntry = 24008; // Fallen Combatant
5707 }
5708
5709 if (creatureEntry)
5710 player->RewardPlayerAndGroupAtEvent(creatureEntry, unitTarget);
5711}
void RewardPlayerAndGroupAtEvent(uint32 creature_id, WorldObject *pRewardSource)
Definition Player.cpp:12733

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

◆ EffectKillCreditPersonal()

void Spell::EffectKillCreditPersonal ( SpellEffIndex  effIndex)
5675{
5677 return;
5678
5679 if (!unitTarget)
5680 return;
5681
5683 {
5684 player->KilledMonsterCredit(m_spellInfo->Effects[effIndex].MiscValue);
5685 }
5686}

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

◆ EffectKnockBack()

void Spell::EffectKnockBack ( SpellEffIndex  effIndex)
4944{
4946 return;
4947
4948 if (!unitTarget)
4949 return;
4950
4951 // Xinef: allow entry specific spells to skip those checks
4952 if (m_spellInfo->Effects[effIndex].TargetA.GetCheckType() != TARGET_CHECK_ENTRY && m_spellInfo->Effects[effIndex].TargetB.GetCheckType() != TARGET_CHECK_ENTRY)
4953 {
4955 return;
4956
4957 if (unitTarget->GetVehicle())
4958 return;
4959
4960 if (Creature* creatureTarget = unitTarget->ToCreature())
4961 if (creatureTarget->isWorldBoss() || creatureTarget->IsDungeonBoss() || creatureTarget->IsImmuneToKnockback() || unitTarget->ToCreature()->GetCreatureType() == CREATURE_TYPE_GIANT)
4962 return;
4963 }
4964
4965 // Spells with SPELL_EFFECT_KNOCK_BACK(like Thunderstorm) can't knoback target if target has ROOT
4967 return;
4968
4969 // Instantly interrupt non melee spells being casted
4972
4973 float ratio = 0.1f;
4974 float speedxy = float(m_spellInfo->Effects[effIndex].MiscValue) * ratio;
4975 float speedz = float(damage) * ratio;
4976 if (speedxy <= 0.1f && speedz <= 0.1f)
4977 return;
4978
4979 float x, y;
4980 Unit* reflectionSource = m_reflectionTarget;
4981
4982 if (!reflectionSource && !m_reflectionTargetGuid.IsEmpty())
4983 {
4985 reflectionSource = resolvedSource;
4986 }
4987
4988 if (reflectionSource)
4989 {
4990 reflectionSource->GetPosition(x, y);
4991 }
4992 else if (!m_reflectionTargetGuid.IsEmpty())
4993 {
4996 }
4997 else if (m_spellInfo->Effects[effIndex].Effect == SPELL_EFFECT_KNOCK_BACK_DEST)
4998 {
4999 if (m_targets.HasDst())
5000 destTarget->GetPosition(x, y);
5001 else
5002 return;
5003 }
5004 else //if (m_spellInfo->Effects[i].Effect == SPELL_EFFECT_KNOCK_BACK)
5005 {
5006 m_caster->GetPosition(x, y);
5007 }
5008
5009 unitTarget->KnockbackFrom(x, y, speedxy, speedz);
5010
5011 if (unitTarget->IsPlayer())
5012 {
5013 sScriptMgr->AnticheatSetUnderACKmount(unitTarget->ToPlayer());
5014 }
5015}
@ SPELL_EFFECT_KNOCK_BACK_DEST
Definition SharedDefines.h:910
@ CREATURE_TYPE_GIANT
Definition SharedDefines.h:2628
@ CREATURE_TYPE_BEAST
Definition SharedDefines.h:2624
bool IsEmpty() const
Definition ObjectGuid.h:161
void InterruptNonMeleeSpells(bool withDelayed, uint32 spellid=0, bool withInstant=true, bool bySelf=false)
Definition Unit.cpp:4302
uint32 GetCreatureType() const
Definition Unit.cpp:11894
void KnockbackFrom(float x, float y, float speedXY, float speedZ)
Definition Unit.cpp:15356

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)
4670{
4672 return;
4673
4674 if (!unitTarget || unitTarget->IsInFlight())
4675 return;
4676
4677 if (!m_targets.HasDst())
4678 return;
4679
4680 Position dstpos = destTarget->GetPosition();
4682}
void NearTeleportTo(Position &pos, bool casting=false, bool vehicleTeleport=false, bool withPet=false, bool removeTransport=false)
Definition Unit.cpp:15921

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

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)
3269{
3271 return;
3272
3273 if (!unitTarget)
3274 return;
3275
3276 if (unitTarget->ToPlayer())
3277 {
3278 EffectLearnSpell(effIndex);
3279 return;
3280 }
3281 Pet* pet = unitTarget->ToPet();
3282 if (!pet)
3283 return;
3284
3285 SpellInfo const* learn_spellproto = sSpellMgr->GetSpellInfo(m_spellInfo->Effects[effIndex].TriggerSpell);
3286 if (!learn_spellproto)
3287 return;
3288
3289 pet->learnSpell(learn_spellproto->Id);
3291 pet->GetOwner()->PetSpellInitialize();
3292}
bool learnSpell(uint32 spell_id)
Definition Pet.cpp:1897
void EffectLearnSpell(SpellEffIndex effIndex)
Definition SpellEffects.cpp:2555

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)
2786{
2788 return;
2789
2790 if (!unitTarget->IsPlayer())
2791 return;
2792
2793 if (damage < 0)
2794 return;
2795
2796 uint32 skillid = m_spellInfo->Effects[effIndex].MiscValue;
2797 uint16 skillval = unitTarget->ToPlayer()->GetPureSkillValue(skillid);
2798 unitTarget->ToPlayer()->SetSkill(skillid, m_spellInfo->Effects[effIndex].CalcValue(), skillval ? skillval : 1, damage * 75);
2799}
uint16 GetPureSkillValue(uint32 skill) const
Definition Player.cpp:5503
void SetSkill(uint16 id, uint16 step, uint16 currVal, uint16 maxVal)
Definition Player.cpp:5314

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)
2556{
2558 return;
2559
2560 if (!unitTarget)
2561 return;
2562
2563 if (!unitTarget->IsPlayer())
2564 {
2565 if (unitTarget->ToPet())
2566 EffectLearnPetSpell(effIndex);
2567 return;
2568 }
2569
2570 Player* player = unitTarget->ToPlayer();
2571
2572 uint32 spellToLearn = (m_spellInfo->Id == 483 || m_spellInfo->Id == 55884) ? damage : m_spellInfo->Effects[effIndex].TriggerSpell;
2573 player->learnSpell(spellToLearn);
2574
2575 LOG_DEBUG("spells.aura", "Spell: Player {} has learned spell {} from Npc {}",
2576 player->GetGUID().ToString(), spellToLearn, m_caster->GetGUID().ToString());
2577}
void learnSpell(uint32 spellId, bool temporary=false, bool learnFromSkill=false)
Definition Player.cpp:3281
void EffectLearnPetSpell(SpellEffIndex effIndex)
Definition SpellEffects.cpp:3268

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)
5498{
5500 return;
5501
5502 if (!m_caster->IsPlayer())
5503 return;
5504
5505 Player* p_caster = m_caster->ToPlayer();
5507 return;
5508
5509 if (itemTarget->GetCount() < 5)
5510 return;
5511
5512 if (sWorld->getBoolConfig(CONFIG_SKILL_MILLING))
5513 {
5514 uint32 SkillValue = p_caster->GetPureSkillValue(SKILL_INSCRIPTION);
5515 uint32 reqSkillValue = itemTarget->GetTemplate()->RequiredSkillRank;
5516 p_caster->UpdateGatherSkill(SKILL_INSCRIPTION, SkillValue, reqSkillValue);
5517 }
5518
5520}
@ LOOT_MILLING
Definition LootMgr.h:87
@ CONFIG_SKILL_MILLING
Definition WorldConfig.h:51
void SendLoot(ObjectGuid guid, LootType loot_type)
Definition Player.cpp:7798
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)
5330{
5332 return;
5333
5334 if (!unitTarget)
5335 return;
5336
5338}
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)
239{
240 LOG_DEBUG("spells.aura", "WORLD: Spell Effect DUMMY");
241}

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
2089{
2091 return;
2092
2093 if (!m_caster->IsPlayer())
2094 {
2095 LOG_DEBUG("spells.aura", "WORLD: Open Lock - No Player Caster!");
2096 return;
2097 }
2098
2099 Player* player = m_caster->ToPlayer();
2100
2101 uint32 lockId = 0;
2102 ObjectGuid guid;
2103
2104 // Get lockId
2105 if (gameObjTarget)
2106 {
2107 GameObjectTemplate const* goInfo = gameObjTarget->GetGOInfo();
2108 // Arathi Basin banner opening. /// @todo: Verify correctness of this check
2109 if ((goInfo->type == GAMEOBJECT_TYPE_BUTTON && goInfo->button.noDamageImmune) ||
2110 (goInfo->type == GAMEOBJECT_TYPE_GOOBER && goInfo->goober.losOK))
2111 {
2112 //CanUseBattlegroundObject() already called in CheckCast()
2113 // in battleground check
2114 if (Battleground* bg = player->GetBattleground())
2115 {
2116 bg->EventPlayerClickedOnFlag(player, gameObjTarget);
2117 return;
2118 }
2119 }
2120 else if (goInfo->type == GAMEOBJECT_TYPE_FLAGSTAND)
2121 {
2122 //CanUseBattlegroundObject() already called in CheckCast()
2123 // in battleground check
2124 if (Battleground* bg = player->GetBattleground())
2125 {
2126 if (bg->GetBgTypeID(true) == BATTLEGROUND_EY)
2127 bg->EventPlayerClickedOnFlag(player, gameObjTarget);
2128 return;
2129 }
2130 }
2131 else if (m_spellInfo->Id == 1842 && gameObjTarget->GetGOInfo()->type == GAMEOBJECT_TYPE_TRAP)
2132 {
2135 {
2137 }
2138 return;
2139 }
2141 // handle outdoor pvp object opening, return true if go was registered for handling
2142 // these objects must have been spawned by outdoorpvp!
2143 else if (gameObjTarget->GetGOInfo()->type == GAMEOBJECT_TYPE_GOOBER && sOutdoorPvPMgr->HandleOpenGo(player, gameObjTarget))
2144 return;
2145 lockId = goInfo->GetLockId();
2146 guid = gameObjTarget->GetGUID();
2147 }
2148 else if (itemTarget)
2149 {
2150 lockId = itemTarget->GetTemplate()->LockID;
2151 guid = itemTarget->GetGUID();
2152 }
2153 else
2154 {
2155 LOG_DEBUG("spells.aura", "WORLD: Open Lock - No GameObject/Item Target!");
2156 return;
2157 }
2158
2159 SkillType skillId = SKILL_NONE;
2160 int32 reqSkillValue = 0;
2161 int32 skillValue;
2162
2163 SpellCastResult res = CanOpenLock(effIndex, lockId, skillId, reqSkillValue, skillValue);
2164 if (res != SPELL_CAST_OK)
2165 {
2166 SendCastResult(res);
2167 return;
2168 }
2169
2170 if (gameObjTarget)
2171 SendLoot(guid, LOOT_SKINNING);
2172 else if (itemTarget)
2173 {
2175 if (Player* itemOwner = itemTarget->GetOwner())
2176 itemTarget->SetState(ITEM_CHANGED, itemOwner);
2177 }
2178
2179 // not allow use skill grow at item base open
2180 if (!m_CastItem && skillId != SKILL_NONE)
2181 {
2182 // update skill if really known
2183 if (uint32 pureSkillValue = player->GetPureSkillValue(skillId))
2184 {
2185 if (gameObjTarget)
2186 {
2187 // Allow one skill-up until respawned
2188 if (!gameObjTarget->IsInSkillupList(player->GetGUID()))
2189 {
2191 player->UpdateGatherSkill(skillId, pureSkillValue, reqSkillValue);
2192 }
2193
2194 }
2195 else if (itemTarget)
2196 {
2197 // Do one skill-up
2198 player->UpdateGatherSkill(skillId, pureSkillValue, reqSkillValue);
2199 }
2200 }
2201 }
2203}
@ 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:1567
@ GAMEOBJECT_TYPE_FLAGSTAND
Definition SharedDefines.h:1590
@ GAMEOBJECT_TYPE_GOOBER
Definition SharedDefines.h:1576
@ BATTLEGROUND_EY
Definition SharedDefines.h:3745
@ ITEM_FIELD_FLAGS
Definition UpdateFields.h:42
Unit * GetOwner() const
Definition GameObject.cpp:1214
LootState getLootState() const
Definition GameObject.h:223
void SetLootState(LootState s, Unit *unit=nullptr)
Definition GameObject.cpp:2457
bool IsInSkillupList(ObjectGuid const &playerGuid) const
Definition GameObject.cpp:3089
void AddToSkillupList(ObjectGuid const &playerGuid)
Definition GameObject.cpp:3083
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:2022
Definition GameObjectData.h:32
uint32 GetAutoCloseTime() const
Definition GameObjectData.h:511
struct GameObjectTemplate::@234::@245 goober
struct GameObjectTemplate::@234::@237 button
uint32 noDamageImmune
Definition GameObjectData.h:49
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)
4652{
4654 return;
4655
4656 if (m_caster->IsPlayer())
4657 m_caster->ToPlayer()->SetCanParry(true);
4658}
void SetCanParry(bool value)
Definition Player.cpp:13136

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

◆ EffectPersistentAA()

void Spell::EffectPersistentAA ( SpellEffIndex  effIndex)
1849{
1851 return;
1852
1853 if (!m_spellAura)
1854 {
1856 float radius = m_spellInfo->Effects[effIndex].CalcRadius(caster);
1857
1858 // Caster not in world, might be spell triggered from aura removal
1859 if (!caster->IsInWorld() || !caster->FindMap() || !ObjectAccessor::GetUnit(*caster, caster->GetGUID())) // pussywizard: temporary crash fix (FindMap and GetUnit are mine)
1860 return;
1861 DynamicObject* dynObj = new DynamicObject();
1863 {
1864 delete dynObj;
1865 return;
1866 }
1867
1869 {
1870 m_spellAura = aura;
1873 }
1874 else
1875 return;
1876 }
1877
1880}
#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)
6091{
6093 return;
6094
6095 if (!unitTarget)
6096 return;
6097
6098 Player* player = unitTarget->ToPlayer();
6099 if (!player)
6100 {
6101 return;
6102 }
6103
6104 uint32 soundid = m_spellInfo->Effects[effIndex].MiscValue;
6105
6106 if (!sSoundEntriesStore.LookupEntry(soundid))
6107 {
6108 LOG_ERROR("spells.effect", "EffectPlayMusic: Sound (Id: {}) not exist in spell {}.", soundid, m_spellInfo->Id);
6109 return;
6110 }
6111
6113}
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)
6144{
6146 return;
6147
6148 if (!unitTarget)
6149 return;
6150
6151 Player* player = unitTarget->ToPlayer();
6152 if (!player)
6153 {
6154 return;
6155 }
6156
6157 switch (m_spellInfo->Id)
6158 {
6159 case 58730: // Restricted Flight Area
6160 case 58600: // Restricted Flight Area
6162 break;
6163 default:
6164 break;
6165 }
6166
6167 uint32 soundId = m_spellInfo->Effects[effIndex].MiscValue;
6168
6169 if (!sSoundEntriesStore.LookupEntry(soundId))
6170 {
6171 LOG_ERROR("spells.effect", "EffectPlayerSound: Sound (Id: {}) not exist in spell {}.", soundId, m_spellInfo->Id);
6172 return;
6173 }
6174
6175 player->PlayDirectSound(soundId, player);
6176}
@ LANG_ZONE_NOFLYZONE
Definition Language.h:761
Definition Chat.h:37
void SendNotification(std::string_view str)
Definition Chat.cpp:105
void PlayDirectSound(uint32 sound_id, Player *target=nullptr)
Definition Object.cpp:2957

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)
1431{
1433 return;
1434
1435 if (m_spellInfo->Effects[effIndex].MiscValue < 0 || m_spellInfo->Effects[effIndex].MiscValue >= int8(MAX_POWERS))
1436 return;
1437
1438 Powers PowerType = Powers(m_spellInfo->Effects[effIndex].MiscValue);
1439
1441 return;
1442
1443 // burn x% of target's mana, up to maximum of 2x% of caster's mana (Mana Burn)
1444 if (m_spellInfo->Id == 8129)
1445 {
1448 damage = std::min(damage, maxDamage);
1449
1450 // Remove fear
1452 }
1453
1454 int32 power = damage;
1455 // resilience reduce mana draining effect at spell crit damage reduction (added in 2.4)
1456 if (PowerType == POWER_MANA)
1457 power -= unitTarget->GetSpellCritDamageReduction(power);
1458
1459 int32 newDamage = -(unitTarget->ModifyPower(PowerType, -power));
1460
1461 // NO - Not a typo - EffectPowerBurn uses effect value multiplier - not effect damage multiplier
1462 float dmgMultiplier = m_spellInfo->Effects[effIndex].CalcValueMultiplier(m_originalCaster, this);
1463
1464 // add log data before multiplication (need power amount, not damage)
1465 ExecuteLogEffectTakeTargetPower(effIndex, unitTarget, PowerType, newDamage, 0.0f);
1466
1467 newDamage = int32(newDamage * dmgMultiplier);
1468
1469 m_damage += newDamage;
1470}
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:10998
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)
1352{
1354 return;
1355
1356 if (m_spellInfo->Effects[effIndex].MiscValue < 0 || m_spellInfo->Effects[effIndex].MiscValue >= int8(MAX_POWERS))
1357 return;
1358
1359 Powers PowerType = Powers(m_spellInfo->Effects[effIndex].MiscValue);
1360
1362 return;
1363
1364 // add spell damage bonus
1367
1368 // resilience reduce mana draining effect at spell crit damage reduction (added in 2.4)
1369 int32 power = damage;
1370 if (PowerType == POWER_MANA)
1371 power -= unitTarget->GetSpellCritDamageReduction(power);
1372
1373 int32 newDamage = -(unitTarget->ModifyPower(PowerType, -int32(power)));
1374
1375 float gainMultiplier = 0.0f;
1376
1377 // Don`t restore from self drain
1378 if (m_caster != unitTarget)
1379 {
1380 gainMultiplier = m_spellInfo->Effects[effIndex].CalcValueMultiplier(m_originalCaster, this);
1381
1382 int32 gain = int32(newDamage * gainMultiplier);
1383
1385 }
1386 ExecuteLogEffectTakeTargetPower(effIndex, unitTarget, PowerType, newDamage, gainMultiplier);
1387}

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)
2315{
2317 return;
2318
2319 if (!m_caster->IsPlayer())
2320 return;
2321 Player* p_target = m_caster->ToPlayer();
2322
2324 if (m_spellInfo->EquippedItemClass == ITEM_CLASS_WEAPON && !(p_target->GetWeaponProficiency() & subClassMask))
2325 {
2326 p_target->AddWeaponProficiency(subClassMask);
2328 }
2329 if (m_spellInfo->EquippedItemClass == ITEM_CLASS_ARMOR && !(p_target->GetArmorProficiency() & subClassMask))
2330 {
2331 p_target->AddArmorProficiency(subClassMask);
2333 }
2334}
uint32 GetArmorProficiency() const
Definition Player.h:1378
void SendProficiency(ItemClass itemClass, uint32 itemSubclassMask)
Definition Player.cpp:10031
uint32 GetWeaponProficiency() const
Definition Player.h:1377
void AddArmorProficiency(uint32 newflag)
Definition Player.h:1376
void AddWeaponProficiency(uint32 newflag)
Definition Player.h:1375
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
2698{
2700 EffectNULL(effIndex);
2701}
void EffectNULL(SpellEffIndex effIndex)
Definition SpellEffects.cpp:238

References EffectNULL().

◆ EffectPullTowards()

void Spell::EffectPullTowards ( SpellEffIndex  effIndex)
5103{
5105 return;
5106
5107 if (!unitTarget)
5108 return;
5109
5110 Position pos;
5111 if (m_spellInfo->Effects[effIndex].Effect == SPELL_EFFECT_PULL_TOWARDS_DEST)
5112 {
5113 if (m_targets.HasDst())
5114 pos.Relocate(*destTarget);
5115 else
5116 return;
5117 }
5118 else //if (m_spellInfo->Effects[i].Effect == SPELL_EFFECT_PULL_TOWARDS)
5119 {
5120 // Xinef: Increase Z position a little bit, should protect from falling through textures
5122 }
5123
5124 float speedXY = float(m_spellInfo->Effects[effIndex].MiscValue) ? float(m_spellInfo->Effects[effIndex].MiscValue) * 0.1f : 30.f;
5125 float speedZ = unitTarget->GetDistance(pos) / speedXY * 0.5f * Movement::gravity;
5126
5127 unitTarget->GetMotionMaster()->MoveJump(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), speedXY, speedZ);
5128
5129 if (unitTarget->IsPlayer())
5130 {
5131 sScriptMgr->AnticheatSetUnderACKmount(unitTarget->ToPlayer());
5132 }
5133}
@ 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)
5041{
5043 return;
5044
5045 if (!unitTarget)
5046 return;
5047
5048 Player* player = unitTarget->ToPlayer();
5049 if (!player)
5050 {
5051 return;
5052 }
5053
5054 uint32 quest_id = m_spellInfo->Effects[effIndex].MiscValue;
5055
5056 Quest const* quest = sObjectMgr->GetQuestTemplate(quest_id);
5057
5058 if (!quest)
5059 return;
5060
5061 // Player has never done this quest
5062 if (player->GetQuestStatus(quest_id) == QUEST_STATUS_NONE)
5063 return;
5064
5065 // remove all quest entries for 'entry' from quest log
5066 for (uint8 slot = 0; slot < MAX_QUEST_LOG_SIZE; ++slot)
5067 {
5068 uint32 logQuest = player->GetQuestSlotQuestId(slot);
5069 if (logQuest == quest_id)
5070 {
5071 player->SetQuestSlot(slot, 0);
5072
5073 // we ignore unequippable quest items in this case, it's still be equipped
5074 player->TakeQuestSourceItem(logQuest, false);
5075
5076 if (quest->HasFlag(QUEST_FLAGS_FLAGS_PVP))
5077 {
5078 player->pvpInfo.IsHostile = player->pvpInfo.IsInHostileArea || player->HasPvPForcingQuest();
5079 player->UpdatePvPState();
5080 }
5081 }
5082 }
5083
5084 player->RemoveRewardedQuest(quest_id);
5085 player->RemoveActiveQuest(quest_id, false);
5086}
@ 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:2527
void UpdatePvPState()
Definition PlayerUpdates.cpp:1432
uint32 GetQuestSlotQuestId(uint16 slot) const
Definition Player.h:1502
void SetQuestSlot(uint16 slot, uint32 quest_id, uint32 timer=0)
Definition Player.h:1506
PvPInfo pvpInfo
Definition Player.h:1863
bool TakeQuestSourceItem(uint32 questId, bool msg)
Definition PlayerQuest.cpp:1397
void RemoveActiveQuest(uint32 questId, bool update=true)
Definition PlayerQuest.cpp:1527
QuestStatus GetQuestStatus(uint32 quest_id) const
Definition PlayerQuest.cpp:1462
void RemoveRewardedQuest(uint32 questId, bool update=true)
Definition PlayerQuest.cpp:1545
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)
4711{
4713 return;
4714
4715 if (!unitTarget)
4716 return;
4717
4718 Player* player = unitTarget->ToPlayer();
4719 if (!player)
4720 {
4721 return;
4722 }
4723
4724 uint32 questId = m_spellInfo->Effects[effIndex].MiscValue;
4725 if (questId)
4726 {
4727 Quest const* quest = sObjectMgr->GetQuestTemplate(questId);
4728 if (!quest)
4729 return;
4730
4731 uint16 logSlot = player->FindQuestSlot(questId);
4732 if (logSlot < MAX_QUEST_LOG_SIZE)
4733 player->AreaExploredOrEventHappens(questId);
4734 else if (player->CanTakeQuest(quest, false)) // Check if the quest has already been turned in.
4735 player->SetRewardedQuest(questId); // If not, set status to rewarded without broadcasting it to client.
4736 }
4737}
uint16 FindQuestSlot(uint32 quest_id) const
Definition PlayerQuest.cpp:1814
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:1823

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)
5714{
5716 return;
5717
5718 if (!unitTarget)
5719 return;
5720
5721 if (Player* player = unitTarget->ToPlayer())
5722 {
5723 player->FailQuest(m_spellInfo->Effects[effIndex].MiscValue);
5724 }
5725}

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

◆ EffectQuestStart()

void Spell::EffectQuestStart ( SpellEffIndex  effIndex)
5728{
5730 return;
5731
5732 if (!unitTarget)
5733 return;
5734
5735 Player* player = unitTarget->ToPlayer();
5736 if (!player)
5737 return;
5738
5739 if (Quest const* quest = sObjectMgr->GetQuestTemplate(m_spellInfo->Effects[effIndex].MiscValue))
5740 {
5741 if (!player->CanTakeQuest(quest, false))
5742 return;
5743
5744 if (quest->IsAutoAccept() && player->CanAddQuest(quest, false))
5745 player->AddQuestAndCheckCompletion(quest, player);
5746
5747 player->PlayerTalkClass->SendQuestGiverQuestDetails(quest, player->GetGUID(), true);
5748 }
5749}
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:2274

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

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)
5888{
5890 return;
5891
5892 if (unitTarget)
5894}
void RegisterRedirectThreat(uint32 spellId, ObjectGuid const &victim, uint32 pct)
== REDIRECT SYSTEM ==
Definition ThreatManager.cpp:831

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)
6179{
6181 return;
6182
6183 if (!unitTarget)
6184 return;
6185 // there may be need of specifying casterguid of removed auras
6186 unitTarget->RemoveAurasDueToSpell(m_spellInfo->Effects[effIndex].TriggerSpell);
6187}

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

◆ EffectRenamePet()

void Spell::EffectRenamePet ( SpellEffIndex  effIndex)
6079{
6081 return;
6082
6083 if (!unitTarget || !unitTarget->IsCreature() ||
6085 return;
6086
6088}
@ 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)
4685{
4687 return;
4688
4689 if (!unitTarget)
4690 return;
4691
4692 Player* player = unitTarget->ToPlayer();
4693 if (!player)
4694 {
4695 return;
4696 }
4697
4698 float repChange = static_cast<float>(damage);
4699
4700 uint32 factionId = m_spellInfo->Effects[effIndex].MiscValue;
4701
4702 FactionEntry const* factionEntry = sFactionStore.LookupEntry(factionId);
4703 if (!factionEntry)
4704 return;
4705
4706 repChange = player->CalculateReputationGain(REPUTATION_SOURCE_SPELL, 0, repChange, factionId);
4707 player->GetReputationMgr().ModifyReputation(factionEntry, repChange);
4708}
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:5853
ReputationMgr & GetReputationMgr()
Definition Player.h:2144
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)
4603{
4605 return;
4606
4607 if (!unitTarget)
4608 return;
4609
4610 if (!unitTarget)
4611 return;
4612
4613 Player* target = unitTarget->ToPlayer();
4614 if (!target)
4615 {
4616 return;
4617 }
4618
4619 if (unitTarget->IsAlive() || !unitTarget->IsInWorld())
4620 return;
4621
4622 if (target->isResurrectRequested()) // already have one active request
4623 return;
4624
4625 uint32 health = target->CountPctFromMaxHealth(damage);
4627
4628 ExecuteLogEffectResurrect(effIndex, target);
4629
4631 SendResurrectRequest(target);
4632}
void setResurrectRequestData(ObjectGuid guid, uint32 mapId, float X, float Y, float Z, uint32 health, uint32 mana)
Definition Player.h:1832
bool isResurrectRequested() const
Definition Player.h:1844
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
5179{
5181 return;
5182
5183 if (damage < 0)
5184 return;
5185
5186 Player* player = m_caster->ToPlayer();
5187 if (!player)
5188 {
5189 return;
5190 }
5191
5192 Pet* pet = player->GetPet();
5193 if (!pet)
5194 {
5195 // Position passed to SummonPet is irrelevant with current implementation,
5196 // pet will be relocated without using these coords in Pet::LoadPetFromDB
5197 player->SummonPet(0, 0.0f, 0.0f, 0.0f, 0.0f, SUMMON_PET, 0ms, damage);
5198 return;
5199 }
5200
5202 if (pet->IsAlive())
5203 {
5204 return;
5205 }
5206
5207 // Reposition the pet's corpse before reviving so as not to grab aggro
5208 // We can use a different, more accurate version of GetClosePoint() since we have a pet
5209 float x, y, z; // Will be used later to reposition the pet if we have one
5210 player->GetClosePoint(x, y, z, pet->GetCombatReach(), PET_FOLLOW_DIST, pet->GetFollowAngle());
5211 pet->NearTeleportTo(x, y, z, player->GetOrientation());
5212 pet->Relocate(x, y, z, player->GetOrientation()); // This is needed so SaveStayPosition() will get the proper coords.
5216 pet->ClearUnitState(uint32(UNIT_STATE_ALL_STATE & ~(UNIT_STATE_POSSESSED))); // xinef: just in case
5218 pet->SetDisplayId(pet->GetNativeDisplayId());
5219
5220 // xinef: restore movement
5221 if (auto ci = pet->GetCharmInfo())
5222 {
5223 ci->SetIsAtStay(false);
5224 ci->SetIsFollowing(false);
5225 }
5226
5228}
constexpr float PET_FOLLOW_DIST
Definition PetDefines.h:206
@ SUMMON_PET
Definition PetDefines.h:32
@ UNIT_DYNFLAG_NONE
Definition SharedDefines.h:3355
@ 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:8969
void ReplaceAllDynamicFlags(uint32 flag) override
Definition Unit.h:769
void SetHealth(uint32 val)
Definition Unit.cpp:12315
uint32 GetNativeDisplayId() const
Definition Unit.h:1976
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:2766

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)
3991{
3993 return;
3994
3995 if (!unitTarget)
3996 return;
3997
3999
4001 {
4002 // stop all pve combat for players outside dungeons, suppress pvp combat
4003 unitTarget->CombatStop(false, false);
4004 }
4005 else
4006 {
4007 // in dungeons (or for nonplayers), reset this unit on all enemies' threat lists
4008 for (auto const& pair : unitTarget->GetThreatMgr().GetThreatenedByMeList())
4009 pair.second->ScaleThreat(0.0f);
4010 }
4011
4012 UnitList targets;
4013 Acore::AnyUnfriendlyUnitInObjectRangeCheck u_check(unitTarget, unitTarget, unitTarget->GetVisibilityRange()); // no VISIBILITY_COMPENSATION, distance is enough
4016 for (UnitList::iterator iter = targets.begin(); iter != targets.end(); ++iter)
4017 {
4018 if (!(*iter)->HasUnitState(UNIT_STATE_CASTING))
4019 continue;
4020
4022 {
4023 if ((*iter)->GetCurrentSpell(i) && (*iter)->GetCurrentSpell(i)->m_targets.GetUnitTargetGUID() == unitTarget->GetGUID())
4024 {
4025 SpellInfo const* si = (*iter)->GetCurrentSpell(i)->GetSpellInfo();
4026 if (si->HasAttribute(SPELL_ATTR6_IGNORE_PHASE_SHIFT) && (*iter)->IsCreature())
4027 {
4028 Creature* c = (*iter)->ToCreature();
4029 if ((!c->IsPet() && c->GetCreatureTemplate()->rank == CREATURE_ELITE_WORLDBOSS) || c->isWorldBoss() || c->IsDungeonBoss())
4030 continue;
4031 }
4032 bool interrupt = false; // pussywizard: skip spells that don't target units, but casted on unit (eg. TARGET_DEST_TARGET_ENEMY)
4033 for (uint8 j = 0; j < MAX_SPELL_EFFECTS; ++j)
4034 if (si->Effects[j].Effect && (si->Effects[j].GetUsedTargetObjectType() == TARGET_OBJECT_TYPE_UNIT || si->Effects[j].GetUsedTargetObjectType() == TARGET_OBJECT_TYPE_UNIT_AND_DEST))
4035 {
4036 // at least one effect truly targets an unit, interrupt the spell
4037 interrupt = true;
4038 break;
4039 }
4040 if (interrupt)
4041 (*iter)->InterruptSpell(CurrentSpellTypes(i), false);
4042 }
4043 }
4044 }
4045
4046 // Xinef: Set last sanctuary time
4048}
#define CURRENT_MAX_SPELL
Definition Unit.h:562
void EvaluateSuppressed(bool canExpire=false)
Definition ThreatManager.cpp:370
void CombatStop(bool includingCast=false, bool mutualPvP=true)
Definition Unit.cpp:7469

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?
324{
326 return;
327
328 if (unitTarget && unitTarget->IsAlive())
329 {
330 bool apply_direct_bonus = true;
332 {
334 {
335 // Meteor like spells (divided damage to targets)
337 {
338 uint32 count = 0;
339 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
340 if (ihit->effectMask & (1 << effIndex))
341 ++count;
342
343 damage /= count; // divide to all targets
344 }
345 break;
346 }
348 {
349 // Shield Slam
350 if (m_spellInfo->SpellFamilyFlags[1] & 0x200 && m_spellInfo->GetCategory() == 1209)
351 {
352 uint8 level = m_caster->GetLevel();
353 // xinef: shield block should increase the limit
354 float limit = m_caster->HasAura(2565) ? 2.0f : 1.0f;
355 uint32 block_value = m_caster->GetShieldBlockValue(uint32(float(level) * 24.5f * limit), uint32(float(level) * 34.5f * limit));
356
357 damage += int32(m_caster->ApplyEffectModifiers(m_spellInfo, effIndex, float(block_value)));
358 }
359 // Victory Rush
360 else if (m_spellInfo->SpellFamilyFlags[1] & 0x100)
362 // Shockwave
363 else if (m_spellInfo->Id == 46968)
364 {
366 if (pct > 0)
368 break;
369 }
370 break;
371 }
373 {
374 // Incinerate Rank 1 & 2
375 if ((m_spellInfo->SpellFamilyFlags[1] & 0x000040) && m_spellInfo->SpellIconID == 2128)
376 {
377 // Incinerate does more dmg (dmg*0.25) if the target have Immolate debuff.
378 // Check aura state for speed but aura state set not only for Immolate spell
380 {
382 damage += damage / 4;
383 }
384 }
385 // Conflagrate - consumes Immolate or Shadowflame
387 {
388 AuraEffect const* aura = nullptr; // found req. aura for damage calculation
389
391 for (Unit::AuraEffectList::const_iterator i = mPeriodic.begin(); i != mPeriodic.end(); ++i)
392 {
393 // for caster applied auras only
394 if ((*i)->GetSpellInfo()->SpellFamilyName != SPELLFAMILY_WARLOCK ||
395 (*i)->GetCasterGUID() != m_caster->GetGUID())
396 continue;
397
398 // Immolate
399 if ((*i)->GetSpellInfo()->SpellFamilyFlags[0] & 0x4)
400 {
401 aura = *i; // it selected always if exist
402 break;
403 }
404
405 // Shadowflame
406 if ((*i)->GetSpellInfo()->SpellFamilyFlags[2] & 0x00000002)
407 aura = *i; // remember but wait possible Immolate as primary priority
408 }
409
410 // found Immolate or Shadowflame
411 if (aura)
412 {
413 uint32 pdamage = uint32(std::max(aura->GetAmount(), 0));
414 pdamage = unitTarget->SpellDamageBonusTaken(m_caster, aura->GetSpellInfo(), pdamage, DOT, aura->GetBase()->GetStackAmount());
415 uint32 pct_dir = m_caster->CalculateSpellDamage(unitTarget, m_spellInfo, (effIndex + 1));
416 uint8 baseTotalTicks = uint8(m_caster->CalcSpellDuration(aura->GetSpellInfo()) / aura->GetSpellInfo()->Effects[EFFECT_0].Amplitude);
417
418 damage += int32(CalculatePct(pdamage * baseTotalTicks, pct_dir));
419
420 uint32 pct_dot = m_caster->CalculateSpellDamage(unitTarget, m_spellInfo, (effIndex + 2)) / 3;
421 m_spellValue->EffectBasePoints[1] = m_spellInfo->Effects[EFFECT_1].CalcBaseValue(int32(CalculatePct(pdamage * baseTotalTicks, pct_dot)));
422
423 apply_direct_bonus = false;
424 // Glyph of Conflagrate
425 if (!m_caster->HasAura(56235))
427
428 break;
429 }
430 }
431 // Shadow Bite
432 else if (m_spellInfo->SpellFamilyFlags[1] & 0x400000)
433 {
434 if (m_caster->IsCreature() && m_caster->IsPet())
435 {
436 if (Player* owner = m_caster->GetOwner()->ToPlayer())
437 {
438 if (AuraEffect* aurEff = owner->GetAuraEffect(SPELL_AURA_ADD_FLAT_MODIFIER, SPELLFAMILY_WARLOCK, 214, 0))
439 {
440 int32 bp0 = aurEff->GetId() == 54037 ? 4 : 8;
441 m_caster->CastCustomSpell(m_caster, 54425, &bp0, nullptr, nullptr, true);
442 }
443 }
444 }
445 }
446 break;
447 }
449 {
450 // Improved Mind Blast (Mind Blast in shadow form bonus)
451 if (m_caster->GetShapeshiftForm() == FORM_SHADOW && (m_spellInfo->SpellFamilyFlags[0] & 0x00002000))
452 {
454 for (Unit::AuraEffectList::const_iterator i = ImprMindBlast.begin(); i != ImprMindBlast.end(); ++i)
455 {
456 if ((*i)->GetSpellInfo()->SpellFamilyName == SPELLFAMILY_PRIEST &&
457 ((*i)->GetSpellInfo()->SpellIconID == 95))
458 {
459 int chance = (*i)->GetSpellInfo()->Effects[EFFECT_1].CalcValue(m_caster);
460 if (roll_chance_i(chance))
461 // Mind Trauma
462 m_caster->CastSpell(unitTarget, 48301, true, 0);
463 break;
464 }
465 }
466 }
467 break;
468 }
470 {
471 // Ferocious Bite
472 if (m_caster->IsPlayer() && (m_spellInfo->SpellFamilyFlags[0] & 0x000800000) && m_spellInfo->SpellVisual[0] == 6587)
473 {
474 // converts each extra point of energy into ($f1+$AP/410) additional damage
476 float multiple = ap / 410 + m_spellInfo->Effects[effIndex].DamageMultiplier;
477 int32 energy = -(m_caster->ModifyPower(POWER_ENERGY, -30));
478 damage += int32(energy * multiple);
480 }
481 // Wrath
482 else if (m_spellInfo->SpellFamilyFlags[0] & 0x00000001)
483 {
484 // Improved Insect Swarm
485 if (AuraEffect const* aurEff = m_caster->GetDummyAuraEffect(SPELLFAMILY_DRUID, 1771, 0))
487 AddPct(damage, aurEff->GetAmount());
488 }
489 break;
490 }
492 {
493 // Envenom
494 if (m_spellInfo->SpellFamilyFlags[1] & 0x00000008)
495 {
496 if (Player* player = m_caster->ToPlayer())
497 {
498 // consume from stack dozes not more that have combo-points
499 if (uint32 combo = player->GetComboPoints())
500 {
501 // Lookup for Deadly poison (only attacker applied)
503 {
504 // count consumed deadly poison doses at target
505 bool needConsume = true;
506 uint32 spellId = aurEff->GetId();
507
508 uint32 doses = aurEff->GetBase()->GetStackAmount();
509 if (doses > combo)
510 doses = combo;
511
512 // Master Poisoner
513 Unit::AuraEffectList const& auraList = player->GetAuraEffectsByType(SPELL_AURA_MOD_AURA_DURATION_BY_DISPEL_NOT_STACK);
514 for (Unit::AuraEffectList::const_iterator iter = auraList.begin(); iter != auraList.end(); ++iter)
515 {
516 if ((*iter)->GetSpellInfo()->SpellFamilyName == SPELLFAMILY_ROGUE && (*iter)->GetSpellInfo()->SpellIconID == 1960)
517 {
518 uint32 chance = (*iter)->GetSpellInfo()->Effects[EFFECT_2].CalcValue(m_caster);
519
520 if (chance && roll_chance_i(chance))
521 needConsume = false;
522
523 break;
524 }
525 }
526
527 if (needConsume)
528 for (uint32 i = 0; i < doses; ++i)
530
531 damage *= doses;
532 damage += int32(player->GetTotalAttackPowerValue(BASE_ATTACK) * 0.09f * combo);
533 }
534
535 // Eviscerate and Envenom Bonus Damage (item set effect)
536 if (m_caster->HasAura(37169))
537 damage += combo * 40;
538 }
539 }
540 }
541 // Eviscerate
542 else if (m_spellInfo->SpellFamilyFlags[0] & 0x00020000)
543 {
544 if (m_caster->IsPlayer())
545 {
546 if (uint32 combo = m_caster->ToPlayer()->GetComboPoints())
547 {
549 damage += int32(ap * combo * 0.07f);
550
551 // Eviscerate and Envenom Bonus Damage (item set effect)
552 if (m_caster->HasAura(37169))
553 damage += combo * 40;
554 }
555 }
556 }
557 break;
558 }
560 {
561 //Gore
562 if (m_spellInfo->SpellIconID == 1578)
563 {
564 if (m_caster->HasAura(57627)) // Charge 6 sec post-affect
565 damage *= 2;
566 }
567 // Steady Shot
568 else if (m_spellInfo->SpellFamilyFlags[1] & 0x1)
569 {
570 bool found = false;
571 // check dazed affect
573 for (Unit::AuraEffectList::const_iterator iter = decSpeedList.begin(); iter != decSpeedList.end(); ++iter)
574 {
575 if ((*iter)->GetSpellInfo()->SpellIconID == 15 && (*iter)->GetSpellInfo()->Dispel == 0)
576 {
577 found = true;
578 break;
579 }
580 }
581
583 if (found)
584 damage += m_spellInfo->Effects[EFFECT_1].CalcValue();
585
586 if (Player* caster = m_caster->ToPlayer())
587 {
588 // Add Ammo and Weapon damage plus RAP * 0.1
589 float dmg_min = 0.f;
590 float dmg_max = 0.f;
591 for (uint8 i = 0; i < MAX_ITEM_PROTO_DAMAGES; ++i)
592 {
593 dmg_min += caster->GetWeaponDamageRange(RANGED_ATTACK, MINDAMAGE, i);
594 dmg_max += caster->GetWeaponDamageRange(RANGED_ATTACK, MAXDAMAGE, i);
595 }
596
597 if (dmg_max == 0.0f && dmg_min > dmg_max)
598 {
599 damage += int32(dmg_min);
600 }
601 else
602 {
603 damage += irand(int32(dmg_min), int32(dmg_max));
604 }
605 damage += int32(caster->GetAmmoDPS() * caster->GetAttackTime(RANGED_ATTACK) * 0.001f);
606 }
607 }
608 break;
609 }
611 {
612 // Hammer of the Righteous
613 if (m_spellInfo->SpellFamilyFlags[1] & 0x00040000)
614 {
615 // Add main hand dps * effect[2] amount
616 if (Player* player = m_caster->ToPlayer())
617 {
618 float minTotal = 0.f;
619 float maxTotal = 0.f;
620 for (uint8 i = 0; i < MAX_ITEM_PROTO_DAMAGES; ++i)
621 {
622 float tmpMin, tmpMax;
623 player->CalculateMinMaxDamage(BASE_ATTACK, false, false, tmpMin, tmpMax, i);
624 minTotal += tmpMin;
625 maxTotal += tmpMax;
626 }
627
628 float average = (minTotal + maxTotal) / 2;
631 }
632 break;
633 }
634 // Shield of Righteousness
635 if (m_spellInfo->SpellFamilyFlags[EFFECT_1] & 0x100000)
636 {
637 uint8 level = m_caster->GetLevel();
638 uint32 block_value = m_caster->GetShieldBlockValue(uint32(float(level) * 29.5f), uint32(float(level) * 34.5f));
639 if (m_caster->GetAuraEffect(64882, EFFECT_0))
640 block_value += 225;
641 damage += CalculatePct(block_value, m_spellInfo->Effects[EFFECT_1].CalcValue());
642 break;
643 }
644 break;
645 }
646 }
647
648 if (m_originalCaster /*&& damage > 0 Xinef: this can be increased from 0*/ && apply_direct_bonus)
649 {
650 // Xinef: protection
651 if (damage < 0)
652 damage = 0;
653
656 }
657
658 m_damage += damage;
659 }
660}
#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:3792
@ 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:12265
float ApplyEffectModifiers(SpellInfo const *spellProto, uint8 effect_index, float value) const
Definition Unit.cpp:11536
virtual uint32 GetShieldBlockValue() const =0
void RemoveAuraFromStack(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition Unit.cpp:5173
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)
3788{
3790 return;
3791
3793
3795 {
3797 {
3798 switch (m_spellInfo->Id)
3799 {
3800 // Shadow Flame (All script effects, not just end ones to prevent player from dodging the last triggered spell)
3801 case 22539:
3802 case 22972:
3803 case 22975:
3804 case 22976:
3805 case 22977:
3806 case 22978:
3807 case 22979:
3808 case 22980:
3809 case 22981:
3810 case 22982:
3811 case 22983:
3812 case 22984:
3813 case 22985:
3814 {
3815 if (!unitTarget || !unitTarget->IsAlive())
3816 return;
3817
3818 // Onyxia Scale Cloak
3819 if (unitTarget->HasAura(22683))
3820 return;
3821
3822 // Shadow Flame
3823 m_caster->CastSpell(unitTarget, 22682, true);
3824 return;
3825 }
3826 // Plant Warmaul Ogre Banner
3827 case 32307:
3828 if (Player* caster = m_caster->ToPlayer())
3829 {
3830 caster->RewardPlayerAndGroupAtEvent(18388, unitTarget);
3831 if (Creature* target = unitTarget->ToCreature())
3832 {
3833 target->setDeathState(DeathState::Corpse);
3834 target->RemoveCorpse();
3835 }
3836 }
3837 break;
3838 // SOTA defender teleport
3839 case 54640:
3840 {
3841 if (Player* player = unitTarget->ToPlayer())
3842 if (player->GetBattleground() && player->GetBattleground()->GetBgTypeID(true) == BATTLEGROUND_SA)
3843 {
3844 if (GameObject* dportal = player->FindNearestGameObject(192819, 10.0f))
3845 {
3846 BattlegroundSA* bg = ((BattlegroundSA*)player->GetBattleground());
3847 bg->DefendersPortalTeleport(dportal, player);
3848 }
3849 }
3850 return;
3851 }
3852 /*// Mug Transformation
3853 case 41931:
3854 {
3855 if (!m_caster->IsPlayer())
3856 return;
3857
3858 uint8 bag = 19;
3859 uint8 slot = 0;
3860 Item* item = nullptr;
3861
3862 while (bag) // 256 = 0 due to var type
3863 {
3864 item = m_caster->ToPlayer()->GetItemByPos(bag, slot);
3865 if (item && item->GetEntry() == 38587)
3866 break;
3867
3868 ++slot;
3869 if (slot == 39)
3870 {
3871 slot = 0;
3872 ++bag;
3873 }
3874 }
3875 if (bag)
3876 {
3877 if (m_caster->ToPlayer()->GetItemByPos(bag, slot)->GetCount() == 1) m_caster->ToPlayer()->RemoveItem(bag, slot, true);
3878 else m_caster->ToPlayer()->GetItemByPos(bag, slot)->SetCount(m_caster->ToPlayer()->GetItemByPos(bag, slot)->GetCount()-1);
3879 // Spell 42518 (Braufest - Gratisprobe des Braufest herstellen)
3880 m_caster->CastSpell(m_caster, 42518, true);
3881 return;
3882 }
3883 break;
3884 }*/
3885 // Roll Dice - Decahedral Dwarven Dice
3886 case 47770:
3887 {
3888 char buf[128];
3889 const char* gender = "his";
3890 if (m_caster->getGender() > 0)
3891 gender = "her";
3892 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));
3893 m_caster->TextEmote(buf);
3894 break;
3895 }
3896 case 52173: // Coyote Spirit Despawn
3897 case 60243: // Blood Parrot Despawn
3900 return;
3901 case 57347: // Retrieving (Wintergrasp RP-GG pickup spell)
3902 {
3904 return;
3905
3907
3908 return;
3909 }
3910 case 57349: // Drop RP-GG (Wintergrasp RP-GG at death drop spell)
3911 {
3912 if (!m_caster->IsPlayer())
3913 return;
3914
3915 // Delete item from inventory at death
3917
3918 return;
3919 }
3920 case 58418: // Portal to Orgrimmar
3921 case 58420: // Portal to Stormwind
3922 {
3923 if (!unitTarget || !unitTarget->IsPlayer() || effIndex != 0)
3924 return;
3925
3926 uint32 spellID = m_spellInfo->Effects[EFFECT_0].CalcValue();
3927 uint32 questID = m_spellInfo->Effects[EFFECT_1].CalcValue();
3928
3930 unitTarget->CastSpell(unitTarget, spellID, true);
3931
3932 return;
3933 }
3934 case 61263: // for item Intravenous Healing Potion (44698)
3935 {
3936 if (!m_caster || !unitTarget)
3937 return;
3938
3939 m_caster->CastSpell(m_caster, 61267, true);
3940 m_caster->CastSpell(m_caster, 61268, true);
3941 return;
3942 }
3943 }
3944 break;
3945 }
3946 case SPELLFAMILY_ROGUE:
3947 {
3948 switch (m_spellInfo->Id)
3949 {
3950 // Master of Subtlety
3951 case 31666:
3952 {
3953 if (!unitTarget)
3954 return;
3955
3956 Aura* mos = unitTarget->GetAura(31665);
3957 if (mos)
3958 {
3959 mos->SetMaxDuration(6000);
3960 mos->SetDuration(6000, true);
3961 }
3962
3963 break;
3964 }
3965 // Overkill
3966 case 58428:
3967 {
3968 if (!unitTarget)
3969 return;
3970
3971 Aura* overkill = unitTarget->GetAura(58427);
3972 if (overkill)
3973 {
3974 overkill->SetMaxDuration(20000);
3975 overkill->SetDuration(20000, true);
3976 }
3977
3978 break;
3979 }
3980 }
3981 break;
3982 }
3983 }
3984
3985 // normal DB scripted effect
3986 LOG_DEBUG("spells.aura", "Spell ScriptStart spellid {} in EffectScriptEffect({})", m_spellInfo->Id, effIndex);
3988}
@ QUEST_STATUS_COMPLETE
Definition QuestDef.h:101
@ BATTLEGROUND_SA
Definition SharedDefines.h:3747
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:2126
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:17150
GameObject * FindNearestGameObject(uint32 entry, float range, bool onlySpawned=false) const
Definition Object.cpp:2508
std::string const & GetName() const
Definition Object.h:528

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)
4813{
4815 return;
4816
4817 if (!m_caster || m_caster->IsAlive())
4818 return;
4819 if (!m_caster->IsPlayer())
4820 return;
4821 if (!m_caster->IsInWorld())
4822 return;
4823
4824 uint32 health = 0;
4825 uint32 mana = 0;
4826
4827 // flat case
4828 if (damage < 0)
4829 {
4830 health = uint32(-damage);
4831 mana = m_spellInfo->Effects[effIndex].MiscValue;
4832 }
4833 // percent case
4834 else
4835 {
4839 }
4840
4841 Player* player = m_caster->ToPlayer();
4842 player->ResurrectPlayer(0.0f);
4843
4844 player->SetHealth(health);
4845 player->SetPower(POWER_MANA, mana);
4846 player->SetPower(POWER_RAGE, 0);
4847 player->SetPower(POWER_ENERGY, player->GetMaxPower(POWER_ENERGY));
4848
4849 player->SpawnCorpseBones();
4850}
@ POWER_RAGE
Definition SharedDefines.h:258
void SpawnCorpseBones(bool triggerSave=true)
Definition Player.cpp:4592
void ResurrectPlayer(float restore_percent, bool applySickness=false)
Definition Player.cpp:4374
void SetPower(Powers power, uint32 val, bool withPowerUpdate=true, bool fromRegenerate=false)
Definition Unit.cpp:12403

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
1390{
1391 // we do not handle a flag dropping or clicking on flag in battleground by sendevent system
1394 return;
1395
1396 WorldObject* target = nullptr;
1397
1398 // call events for object target if present
1400 {
1401 if (unitTarget)
1402 target = unitTarget;
1403 else if (gameObjTarget)
1404 target = gameObjTarget;
1405 }
1406 else // if (effectHandleMode == SPELL_EFFECT_HANDLE_HIT)
1407 {
1408 // let's prevent executing effect handler twice in case when spell effect is capable of targeting an object
1409 // this check was requested by scripters, but it has some downsides:
1410 // now it's impossible to script (using sEventScripts) a cast which misses all targets
1411 // or to have an ability to script the moment spell hits dest (in a case when there are object targets present)
1412 if (m_spellInfo->Effects[effIndex].GetProvidedTargetMask() & (TARGET_FLAG_UNIT_MASK | TARGET_FLAG_GAMEOBJECT_MASK))
1413 return;
1414 // some spells have no target entries in dbc and they use focus target
1415 if (focusObject)
1416 target = focusObject;
1418 }
1419
1420 LOG_DEBUG("spells.aura", "Spell ScriptStart {} for spellid {} in EffectSendEvent ", m_spellInfo->Effects[effIndex].MiscValue, m_spellInfo->Id);
1421
1422 if (ZoneScript* zoneScript = m_caster->GetZoneScript())
1423 zoneScript->ProcessEvent(target, m_spellInfo->Effects[effIndex].MiscValue);
1424 else if (InstanceScript* instanceScript = m_caster->GetInstanceScript()) // needed in case Player is the caster
1425 instanceScript->ProcessEvent(target, m_spellInfo->Effects[effIndex].MiscValue);
1426
1427 m_caster->GetMap()->ScriptsStart(sEventScripts, m_spellInfo->Effects[effIndex].MiscValue, m_caster, target);
1428}
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)
5089{
5091 return;
5092
5093 if (!unitTarget)
5094 return;
5095
5096 if (Player* player = unitTarget->ToPlayer())
5097 {
5098 player->ActivateTaxiPathTo(m_spellInfo->Effects[effIndex].MiscValue, m_spellInfo->Id);
5099 }
5100}

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

◆ EffectSkill()

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

References effectHandleMode, LOG_DEBUG, and SPELL_EFFECT_HANDLE_HIT.

◆ EffectSkinning()

void Spell::EffectSkinning ( SpellEffIndex  effIndex)
4853{
4855 return;
4856
4857 if (!unitTarget->IsCreature())
4858 return;
4859 if (!m_caster->IsPlayer())
4860 return;
4861
4862 Creature* creature = unitTarget->ToCreature();
4863 int32 targetLevel = creature->GetLevel();
4864
4865 uint32 skill = creature->GetCreatureTemplate()->GetRequiredLootSkill();
4866
4870
4871 int32 reqValue = targetLevel < 10 ? 0 : targetLevel < 20 ? (targetLevel - 10) * 10 : targetLevel * 5;
4872
4873 int32 skillValue = m_caster->ToPlayer()->GetPureSkillValue(skill);
4874
4875 // Double chances for elites
4876 m_caster->ToPlayer()->UpdateGatherSkill(skill, skillValue, reqValue, creature->isElite() ? 2 : 1);
4877}
@ UNIT_DYNFLAG_LOOTABLE
Definition SharedDefines.h:3356
bool isElite() const
Definition Creature.h:114
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)
5554{
5556 return;
5557
5558 LOG_DEBUG("spells.aura", "Effect: SkinPlayerCorpse");
5559 if ((!m_caster->IsPlayer()) || (!unitTarget->IsPlayer()) || (unitTarget->IsAlive()))
5560 return;
5561
5563
5564 // We have a corpse object as the target.
5565 // This target was deleted in RemovedInsignia() -> ConvertCorpseToBones().
5567}
void RemovedInsignia(Player *looterPlr)
Definition Player.cpp:7759
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)
6116{
6118 return;
6119
6120 if (!unitTarget)
6121 return;
6122
6123 if (Player* player = unitTarget->ToPlayer())
6124 {
6125 player->UpdateSpecCount(damage);
6126 }
6127}

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

◆ EffectSpiritHeal()

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

References effectHandleMode, and SPELL_EFFECT_HANDLE_HIT_TARGET.

◆ EffectStealBeneficialBuff()

void Spell::EffectStealBeneficialBuff ( SpellEffIndex  effIndex)
5570{
5572 return;
5573
5574 LOG_DEBUG("spells.aura", "Effect: StealBeneficialBuff");
5575
5576 if (!unitTarget || unitTarget == m_caster) // can't steal from self
5577 return;
5578
5579 DispelChargesList steal_list;
5580
5581 // Create dispel mask by dispel type
5582 uint32 dispelMask = SpellInfo::GetDispelMask(DispelType(m_spellInfo->Effects[effIndex].MiscValue));
5583 Unit::AuraMap const& auras = unitTarget->GetOwnedAuras();
5584 for (Unit::AuraMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
5585 {
5586 Aura* aura = itr->second;
5588 if (!aurApp)
5589 continue;
5590
5591 if ((aura->GetSpellInfo()->GetDispelMask()) & dispelMask)
5592 {
5593 // Need check for passive? this
5594 if (!aurApp->IsPositive() || aura->IsPassive() || aura->GetSpellInfo()->HasAttribute(SPELL_ATTR4_CANNOT_BE_STOLEN))
5595 continue;
5596
5597 // The charges / stack amounts don't count towards the total number of auras that can be dispelled.
5598 // Ie: A dispel on a target with 5 stacks of Winters Chill and a Polymorph has 1 / (1 + 1) -> 50% chance to dispell
5599 // Polymorph instead of 1 / (5 + 1) -> 16%.
5600 bool dispel_charges = aura->GetSpellInfo()->HasAttribute(SPELL_ATTR7_DISPEL_REMOVES_CHARGES);
5601 uint8 charges = dispel_charges ? aura->GetCharges() : aura->GetStackAmount();
5602 if (charges > 0)
5603 steal_list.push_back(std::make_pair(aura, charges));
5604 }
5605 }
5606
5607 if (steal_list.empty())
5608 return;
5609
5610 // Ok if exist some buffs for dispel try dispel it
5611 uint32 failCount = 0;
5612 DispelList success_list;
5613 WorldPacket dataFail(SMSG_DISPEL_FAILED, 8 + 8 + 4 + 4 + damage * 4);
5614 // dispel N = damage buffs (or while exist buffs for dispel)
5615 for (int32 count = 0; count < damage && !steal_list.empty();)
5616 {
5617 // Random select buff for dispel
5618 DispelChargesList::iterator itr = steal_list.begin();
5619 std::advance(itr, urand(0, steal_list.size() - 1));
5620
5621 int32 chance = itr->first->CalcDispelChance(unitTarget, !unitTarget->IsFriendlyTo(m_caster));
5622 // 2.4.3 Patch Notes: "Dispel effects will no longer attempt to remove effects that have 100% dispel resistance."
5623 if (!chance)
5624 {
5625 steal_list.erase(itr);
5626 continue;
5627 }
5628 else
5629 {
5630 if (roll_chance_i(chance))
5631 {
5632 success_list.push_back(std::make_pair(itr->first->GetId(), itr->first->GetCasterGUID()));
5633 --itr->second;
5634 if (itr->second <= 0)
5635 steal_list.erase(itr);
5636 }
5637 else
5638 {
5639 if (!failCount)
5640 {
5641 // Failed to dispell
5642 dataFail << m_caster->GetGUID(); // Caster GUID
5643 dataFail << unitTarget->GetGUID(); // Victim GUID
5644 dataFail << uint32(m_spellInfo->Id); // dispel spell id
5645 }
5646 ++failCount;
5647 dataFail << uint32(itr->first->GetId()); // Spell Id
5648 }
5649 ++count;
5650 }
5651 }
5652
5653 if (failCount)
5654 m_caster->SendMessageToSet(&dataFail, true);
5655
5656 if (success_list.empty())
5657 return;
5658
5659 WorldPacket dataSuccess(SMSG_SPELLSTEALLOG, 8 + 8 + 4 + 1 + 4 + damage * 5);
5660 dataSuccess << unitTarget->GetPackGUID(); // Victim GUID
5661 dataSuccess << m_caster->GetPackGUID(); // Caster GUID
5662 dataSuccess << uint32(m_spellInfo->Id); // dispel spell id
5663 dataSuccess << uint8(0); // not used
5664 dataSuccess << uint32(success_list.size()); // count
5665 for (DispelList::iterator itr = success_list.begin(); itr != success_list.end(); ++itr)
5666 {
5667 dataSuccess << uint32(itr->first); // Spell Id
5668 dataSuccess << uint8(0); // 0 - steals !=0 transfers
5669 unitTarget->RemoveAurasDueToSpellBySteal(itr->first, itr->second, m_caster);
5670 }
5671 m_caster->SendMessageToSet(&dataSuccess, true);
5672}
@ 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:2579
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:5254
@ 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)
4143{
4145 return;
4146
4147 if (!m_caster->IsPlayer())
4148 return;
4149
4150 Player* target = m_caster->ToPlayer();
4151 if (target->IsInFlight())
4152 return;
4153
4154 // xinef: if player is dead - teleport to graveyard
4155 if (!target->IsAlive())
4156 {
4157 if (target->HasPreventResurectionAura())
4158 return;
4159
4160 // xinef: player is in corpse
4161 if (!target->HasPlayerFlag(PLAYER_FLAGS_GHOST))
4162 target->BuildPlayerRepop();
4163 target->RepopAtGraveyard();
4164 return;
4165 }
4166
4167 // xinef: no hearthstone in bag or on cooldown
4168 Item* hearthStone = target->GetItemByEntry(6948);
4169 if (!hearthStone || target->HasSpellCooldown(8690))
4170 {
4171 float o = rand_norm() * 2 * M_PI;
4172 Position pos = *target;
4173 target->MovePositionToFirstCollision(pos, 5.0f, o);
4174 target->NearTeleportTo(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), target->GetOrientation());
4175 return;
4176 }
4177
4178 // xinef: we have hearthstone not on cooldown, just use it
4180}
@ PLAYER_FLAGS_GHOST
Definition Player.h:463
double rand_norm()
Definition Random.cpp:85
void RepopAtGraveyard()
Definition Player.cpp:4824
void BuildPlayerRepop()
Definition Player.cpp:4326
bool HasPreventResurectionAura() const
Definition Unit.h:1807
void MovePositionToFirstCollision(Position &pos, float dist, float angle)
Definition Object.cpp:2925

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)
2206{
2208 return;
2209
2210 if (!m_caster->IsPlayer())
2211 return;
2212
2213 Player* player = m_caster->ToPlayer();
2214
2215 // applied only to using item
2216 if (!m_CastItem)
2217 return;
2218
2219 // ... only to item in own inventory/bank/equip_slot
2220 if (m_CastItem->GetOwnerGUID() != player->GetGUID())
2221 return;
2222
2223 uint32 newitemid = m_spellInfo->Effects[effIndex].ItemType;
2224 if (!newitemid)
2225 return;
2226
2227 uint16 pos = m_CastItem->GetPos();
2228
2229 Item* pNewItem = Item::CreateItem(newitemid, 1, player);
2230 if (!pNewItem)
2231 return;
2232
2233 // Client-side enchantment durations update
2235
2239
2241 {
2243 player->DurabilityLoss(pNewItem, lossPercent);
2244 }
2245
2246 if (player->IsInventoryPos(pos))
2247 {
2248 ItemPosCountVec dest;
2249 InventoryResult msg = player->CanStoreItem(m_CastItem->GetBagSlot(), m_CastItem->GetSlot(), dest, pNewItem, true);
2250 if (msg == EQUIP_ERR_OK)
2251 {
2252 player->DestroyItem(m_CastItem->GetBagSlot(), m_CastItem->GetSlot(), true);
2253
2254 // prevent crash at access and unexpected charges counting with item update queue corrupt
2256 m_targets.SetItemTarget(nullptr);
2257
2258 m_CastItem = nullptr;
2260
2261 player->StoreItem(dest, pNewItem, true);
2262 player->ItemAddedQuestCheck(pNewItem->GetEntry(), 1);
2263 return;
2264 }
2265 }
2266 else if (player->IsBankPos(pos))
2267 {
2268 ItemPosCountVec dest;
2269 uint8 msg = player->CanBankItem(m_CastItem->GetBagSlot(), m_CastItem->GetSlot(), dest, pNewItem, true);
2270 if (msg == EQUIP_ERR_OK)
2271 {
2272 player->DestroyItem(m_CastItem->GetBagSlot(), m_CastItem->GetSlot(), true);
2273
2274 // prevent crash at access and unexpected charges counting with item update queue corrupt
2276 m_targets.SetItemTarget(nullptr);
2277
2278 m_CastItem = nullptr;
2280
2281 player->BankItem(dest, pNewItem, true);
2282 return;
2283 }
2284 }
2285 else if (player->IsEquipmentPos(pos))
2286 {
2287 uint16 dest;
2288
2289 player->DestroyItem(m_CastItem->GetBagSlot(), m_CastItem->GetSlot(), true);
2290
2291 uint8 msg = player->CanEquipItem(m_CastItem->GetSlot(), dest, pNewItem, true);
2292
2293 if (msg == EQUIP_ERR_OK || msg == EQUIP_ERR_CANT_DO_RIGHT_NOW)
2294 {
2296
2297 // prevent crash at access and unexpected charges counting with item update queue corrupt
2299 m_targets.SetItemTarget(nullptr);
2300
2301 m_CastItem = nullptr;
2303
2304 player->EquipItem(dest, pNewItem, true);
2305 player->AutoUnequipOffhandIfNeed();
2306 return;
2307 }
2308 }
2309
2310 // fail
2311 delete pNewItem;
2312}
@ 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:1277
InventoryResult CanEquipItem(uint8 slot, uint16 &dest, Item *pItem, bool swap, bool not_loading=true) const
Definition PlayerStorage.cpp:1872
Item * BankItem(ItemPosCountVec const &dest, Item *pItem, bool update)
Definition Player.h:1351
InventoryResult CanStoreItem(uint8 bag, uint8 slot, ItemPosCountVec &dest, Item *pItem, bool swap=false) const
Definition Player.h:1302
void UpdateEnchantmentDurations()
Definition PlayerStorage.cpp:4796
Item * StoreItem(ItemPosCountVec const &pos, Item *pItem, bool update)
Definition PlayerStorage.cpp:2651
void DestroyItem(uint8 bag, uint8 slot, bool update)
Definition PlayerStorage.cpp:3089
static bool IsInventoryPos(uint16 pos)
Definition Player.h:1275
void AutoUnequipOffhandIfNeed(bool force=false)
Definition Player.cpp:12434
Item * EquipItem(uint16 pos, Item *pItem, bool update)
Definition PlayerStorage.cpp:2798
InventoryResult CanBankItem(uint8 bag, uint8 slot, ItemPosCountVec &dest, Item *pItem, bool swap, bool not_loading=true) const
Definition PlayerStorage.cpp:2104
void ItemAddedQuestCheck(uint32 entry, uint32 count)
Definition PlayerQuest.cpp:1867
static bool IsBankPos(uint16 pos)
Definition Player.h:1280

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)
4530{
4532 return;
4533
4534 uint32 gameobjectId = m_spellInfo->Effects[effIndex].MiscValue;
4535
4536 uint8 slot = 0;
4537 switch (m_spellInfo->Effects[effIndex].Effect)
4538 {
4540 slot = 0;
4541 break;
4543 slot = 1;
4544 break;
4546 slot = 2;
4547 break;
4549 slot = 3;
4550 break;
4551 default:
4552 return;
4553 }
4554
4555 if (m_caster)
4556 {
4557 ObjectGuid guid = m_caster->m_ObjectSlot[slot];
4558 if (guid)
4559 {
4560 if (GameObject* gameObject = m_caster->GetMap()->GetGameObject(guid))
4561 {
4562 // Recast case - null spell id to make auras not be removed on object remove from world
4563 if (m_spellInfo->Id == gameObject->GetSpellId())
4564 gameObject->SetSpellId(0);
4565 m_caster->RemoveGameObject(gameObject, true);
4566 }
4567 m_caster->m_ObjectSlot[slot].Clear();
4568 }
4569 }
4570
4571 GameObject* pGameObj = sObjectMgr->IsGameObjectStaticTransport(gameobjectId) ? new StaticTransport() : new GameObject();
4572
4573 float x, y, z;
4574 // If dest location if present
4575 if (m_targets.HasDst())
4576 destTarget->GetPosition(x, y, z);
4577 // Summon in random point all other units if location present
4578 else
4580
4581 Map* map = m_caster->GetMap();
4582 G3D::Quat rotation = G3D::Quat::fromAxisAngleRotation(G3D::Vector3::unitZ(), m_caster->GetOrientation());
4583 if (!pGameObj->Create(map->GenerateLowGuid<HighGuid::GameObject>(), gameobjectId, map, m_caster->GetPhaseMask(), x, y, z, m_caster->GetOrientation(), rotation, 0, GO_STATE_READY))
4584 {
4585 delete pGameObj;
4586 return;
4587 }
4588
4589 //pGameObj->SetUInt32Value(GAMEOBJECT_LEVEL, m_caster->GetLevel());
4590 int32 duration = m_spellInfo->GetDuration();
4591 pGameObj->SetRespawnTime(duration > 0 ? duration / IN_MILLISECONDS : 0);
4592 pGameObj->SetSpellId(m_spellInfo->Id);
4593 m_caster->AddGameObject(pGameObj);
4594
4595 ExecuteLogEffectSummonObject(effIndex, pGameObj);
4596
4597 map->AddToMap(pGameObj, true);
4598
4599 m_caster->m_ObjectSlot[slot] = pGameObj->GetGUID();
4600}
#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:2079

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

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)
3155{
3157 return;
3158
3159 if (!m_originalCaster)
3160 return;
3161
3162 uint32 petentry = m_spellInfo->Effects[effIndex].MiscValue;
3163 int32 duration = m_spellInfo->GetDuration();
3164
3165 if (Player* modOwner = m_originalCaster->GetSpellModOwner())
3166 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_DURATION, duration);
3167
3168 Player* owner = m_originalCaster->ToPlayer();
3169 if (!owner && m_originalCaster->ToCreature()->IsTotem())
3171
3172 if (!owner)
3173 {
3174 SummonPropertiesEntry const* properties = sSummonPropertiesStore.LookupEntry(67);
3175 if (properties)
3176 {
3177 // Xinef: unsummon old guardian
3178 if (Guardian* oldPet = m_originalCaster->GetGuardianPet())
3179 oldPet->UnSummon();
3180 SummonGuardian(effIndex, petentry, properties, 1, false);
3181 }
3182 return;
3183 }
3184
3185 Pet* OldSummon = owner->GetPet();
3186
3187 // if pet requested type already exist
3188 if (OldSummon)
3189 {
3190 if (petentry == 0 || OldSummon->GetEntry() == petentry)
3191 {
3192 // pet in corpse state can't be summoned
3193 if (OldSummon->isDead())
3194 return;
3195
3196 ASSERT(OldSummon->GetMap() == owner->GetMap());
3197
3198 //OldSummon->GetMap()->Remove(OldSummon->ToCreature(), false);
3199
3200 float px, py, pz;
3201 owner->GetClosePoint(px, py, pz, OldSummon->GetObjectSize());
3202
3203 OldSummon->NearTeleportTo(px, py, pz, OldSummon->GetOrientation());
3204 OldSummon->UpdateObjectVisibility();
3205
3206 OldSummon->SetHealth(OldSummon->GetMaxHealth());
3207 OldSummon->SetPower(OldSummon->getPowerType(), OldSummon->GetMaxPower(OldSummon->getPowerType()));
3208 // notify player
3209 for (CreatureSpellCooldowns::const_iterator itr = OldSummon->m_CreatureSpellCooldowns.begin(); itr != OldSummon->m_CreatureSpellCooldowns.end(); ++itr)
3210 owner->SendClearCooldown(itr->first, OldSummon);
3211
3212 // actually clear cooldowns
3213 OldSummon->m_CreatureSpellCooldowns.clear();
3214 Unit::AuraApplicationMap& myAuras = OldSummon->GetAppliedAuras();
3215 for (Unit::AuraApplicationMap::iterator i = myAuras.begin(); i != myAuras.end();)
3216 {
3217 Aura const* aura = i->second->GetBase();
3218 if (!aura->IsPassive() && !OldSummon->IsPetAura(aura) && aura->CanBeSentToClient())
3219 OldSummon->RemoveAura(i);
3220 else
3221 ++i;
3222 }
3223 return;
3224 }
3225
3226 if (owner->IsPlayer())
3227 owner->ToPlayer()->RemovePet(OldSummon, PET_SAVE_NOT_IN_SLOT, false);
3228 else
3229 return;
3230 }
3231
3232 float x, y, z;
3233 owner->GetClosePoint(x, y, z, owner->GetObjectSize());
3234 Pet* pet = owner->SummonPet(petentry, x, y, z, owner->GetOrientation(), SUMMON_PET);
3235 if (!pet)
3236 return;
3237
3238 if (m_caster->IsCreature())
3239 {
3240 if (m_caster->ToCreature()->IsTotem())
3242 else
3244 }
3245
3247
3248 // Reset cooldowns
3250 {
3251 pet->m_CreatureSpellCooldowns.clear();
3252 owner->PetSpellInitialize();
3253 }
3254
3255 // Set health to max if new pet is summoned
3256 // in this function old pet is saved with current health eg. 20% and new one is loaded from db with same amount
3257 // pet should have full health
3258 pet->SetHealth(pet->GetMaxHealth());
3259
3260 // generate new name for summon pet
3261 std::string new_name = sObjectMgr->GeneratePetName(petentry);
3262 if (!new_name.empty())
3263 pet->SetName(new_name);
3264
3265 // ExecuteLogEffectSummonObject(effectInfo->EffectIndex, pet);
3266}
@ 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:254
void SetReactState(ReactStates state)
A creature can have 3 ReactStates : Agressive, Passive, Neutral.
Definition Creature.h:99
Definition TemporarySummon.h:106
void SendClearCooldown(uint32 spell_id, Unit *target)
Definition Player.cpp:14757
void SummonGuardian(uint32 i, uint32 entry, SummonPropertiesEntry const *properties, uint32 numSummons, bool personalSpawn)
Definition SpellEffects.cpp:5938
bool IsPetAura(Aura const *aura)
Definition Unit.cpp:13711
void UpdateObjectVisibility(bool forced=true, bool fromUpdate=false) override
Definition Unit.cpp:15343
Powers getPowerType() const
Definition Unit.h:1131
bool isDead() const
Definition Unit.h:1795
void SetName(std::string const &newname)
Definition Object.h:529
float GetObjectSize() const
Definition Object.cpp:2838

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)
4183{
4184 // workaround - this effect should not use target map
4186 return;
4187
4188 if (!unitTarget)
4189 return;
4190
4191 Player* player = unitTarget->ToPlayer();
4192 if (!player)
4193 {
4194 return;
4195 }
4196
4197 // Evil Twin (ignore player summon, but hide this for summoner)
4198 // Xinef: Unit Target may be on other map!!!, Need workaround
4199 if (unitTarget->HasAura(23445))
4200 return;
4201
4202 float x, y, z;
4203 m_caster->GetPosition(x, y, z);
4204
4205 player->SetSummonPoint(m_caster->GetMapId(), x, y, z);
4206
4207 WorldPacket data(SMSG_SUMMON_REQUEST, 8 + 4 + 4);
4208 data << m_caster->GetGUID(); // summoner guid
4209 data << uint32(m_caster->GetZoneId()); // summoner zone
4210 data << uint32(MAX_PLAYER_SUMMON_DELAY * IN_MILLISECONDS); // auto decline after msecs
4211 player->SendDirectMessage(&data);
4212}
#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:16335
@ 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)
6310{
6312 return;
6313
6314 if (!m_caster->IsPlayer())
6315 return;
6316
6317 if (!unitTarget)
6318 return;
6319
6320 Player* player = unitTarget->ToPlayer();
6321 if (!player)
6322 {
6323 return;
6324 }
6325
6326 float x, y, z;
6327 m_caster->GetPosition(x, y, z);
6329 WorldPacket data(SMSG_SUMMON_REQUEST, 8 + 4 + 4);
6330 data << m_caster->GetGUID();
6331 data << uint32(m_caster->GetZoneId());
6332 data << uint32(MAX_PLAYER_SUMMON_DELAY * IN_MILLISECONDS); // auto decline after msecs
6333 player->SendDirectMessage(&data);
6334}

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)
2337{
2339 return;
2340
2341 uint32 entry = m_spellInfo->Effects[effIndex].MiscValue;
2342
2343 if (m_spellValue->MiscVal[effIndex])
2344 entry = m_spellValue->MiscVal[effIndex];
2345
2346 if (!entry)
2347 return;
2348
2349 SummonPropertiesEntry const* properties = sSummonPropertiesStore.LookupEntry(m_spellInfo->Effects[effIndex].MiscValueB);
2350 if (!properties)
2351 {
2352 LOG_ERROR("spells.effect", "EffectSummonType: Unhandled summon type {}", m_spellInfo->Effects[effIndex].MiscValueB);
2353 return;
2354 }
2355
2356 if (!m_originalCaster)
2357 return;
2358
2359 bool personalSpawn = (properties->Flags & SUMMON_PROP_FLAG_ONLY_VISIBLE_TO_SUMMONER) != 0;
2360 int32 duration = m_spellInfo->GetDuration();
2361 if (Player* modOwner = m_originalCaster->GetSpellModOwner())
2362 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_DURATION, duration);
2363
2364 TempSummon* summon = nullptr;
2365
2366 // determine how many units should be summoned
2367 uint32 numSummons;
2368
2369 // some spells need to summon many units, for those spells number of summons is stored in effect value
2370 // however so far noone found a generic check to find all of those (there's no related data in summonproperties.dbc
2371 // and in spell attributes, possibly we need to add a table for those)
2372 // so here's a list of MiscValueB values, which is currently most generic check
2373 switch (properties->Id)
2374 {
2375 case 64:
2376 case 61:
2377 case 1101:
2378 case 66:
2379 case 648:
2380 case 2301:
2381 case 1061:
2382 case 1261:
2383 case 629:
2384 case 181:
2385 case 715:
2386 case 1562:
2387 case 833:
2388 case 1161:
2389 case 713: // xinef, bloodworms
2390 numSummons = (damage > 0) ? damage : 1;
2391 break;
2392 default:
2393 numSummons = 1;
2394 break;
2395 }
2396
2397 switch (properties->Category)
2398 {
2402 if (properties->Flags & 512)
2403 {
2404 SummonGuardian(effIndex, entry, properties, numSummons, personalSpawn);
2405 break;
2406 }
2407 switch (properties->Type)
2408 {
2409 case SUMMON_TYPE_PET:
2412 case SUMMON_TYPE_MINION:
2413 SummonGuardian(effIndex, entry, properties, numSummons, personalSpawn);
2414 break;
2415 // Summons a vehicle, but doesn't force anyone to enter it (see SUMMON_CATEGORY_VEHICLE)
2418 summon = m_caster->GetMap()->SummonCreature(entry, *destTarget, properties, duration, m_originalCaster, m_spellInfo->Id, 0, personalSpawn);
2419 break;
2421 case SUMMON_TYPE_TOTEM:
2422 {
2423 // protection code
2424 summon = m_caster->GetMap()->SummonCreature(entry, *destTarget, properties, duration, m_originalCaster, m_spellInfo->Id, 0, personalSpawn);
2425 if (!summon || !summon->IsTotem())
2426 return;
2427
2428 // Mana Tide Totem
2429 if (m_spellInfo->Id == 16190)
2431
2432 if (damage && properties->Type != SUMMON_TYPE_LIGHTWELL) // Health set in script for lightwell
2433 {
2434 summon->SetMaxHealth(damage);
2435 summon->SetHealth(damage);
2436 }
2437 break;
2438 }
2440 // For companions, recalculate the position to ensure they spawn at the intended π/4 angle.
2444 ));
2445 [[fallthrough]];
2446 case SUMMON_TYPE_JEEVES:
2447 {
2448 summon = m_caster->GetMap()->SummonCreature(entry, *destTarget, properties, duration, m_originalCaster, m_spellInfo->Id, 0, personalSpawn);
2449 if (!summon || !summon->HasUnitTypeMask(UNIT_MASK_MINION))
2450 return;
2451
2452 summon->SelectLevel(); // some summoned creaters have different from 1 DB data for level/hp
2454
2455 summon->SetImmuneToAll(true);
2457
2458 // Xinef: Pet can have some auras in creature_addon or in scripts, do not remove them instantly
2459 //summon->AI()->EnterEvadeMode();
2460 if (properties->Type != SUMMON_TYPE_JEEVES)
2461 {
2463 summon->GetMotionMaster()->Clear(false);
2465 }
2466 break;
2467 }
2468 default:
2469 {
2470 float radius = m_spellInfo->Effects[effIndex].CalcRadius();
2471
2472 TempSummonType summonType = (duration <= 0) ? TEMPSUMMON_DEAD_DESPAWN : TEMPSUMMON_TIMED_DESPAWN;
2473
2474 for (uint32 count = 0; count < numSummons; ++count)
2475 {
2476 Position pos;
2477 if (count == 0)
2478 pos = *destTarget;
2479 else
2480 // randomize position for multiple summons
2481 pos = m_caster->GetRandomPoint(*destTarget, radius);
2482
2483 summon = m_originalCaster->SummonCreature(entry, pos, summonType, duration, 0, nullptr, personalSpawn);
2484 if (!summon)
2485 continue;
2486
2487 summon->SetTempSummonType(summonType);
2488
2489 if (properties->Category == SUMMON_CATEGORY_ALLY)
2490 {
2493 }
2494
2495 ExecuteLogEffectSummonObject(effIndex, summon);
2496 }
2497 return;
2498 }
2499 }//switch
2500 break;
2502 // Xinef: SummonGuardian function can summon a few npcs of same type, remove old summons with same entry here
2503 if (m_originalCaster)
2505 SummonGuardian(effIndex, entry, properties, numSummons, personalSpawn);
2506 break;
2508 summon = m_caster->GetMap()->SummonCreature(entry, *destTarget, properties, duration, m_originalCaster, m_spellInfo->Id, 0, personalSpawn);
2509 break;
2511 // Summoning spells (usually triggered by npc_spellclick) that spawn a vehicle and that cause the clicker
2512 // to cast a ride vehicle spell on the summoned unit.
2513 //float x, y, z;
2514 //m_caster->GetClosePoint(x, y, z, DEFAULT_WORLD_OBJECT_SIZE);
2515 // xinef: vehicles summoned in air, eg. Cold Hearted quest
2516 if (std::fabs(m_caster->GetPositionZ() - destTarget->GetPositionZ()) > 6.0f)
2518
2519 summon = m_originalCaster->GetMap()->SummonCreature(entry, *destTarget, properties, duration, m_caster, m_spellInfo->Id, 0, personalSpawn);
2520 if (!summon || !summon->IsVehicle())
2521 return;
2522
2523 // The spell that this effect will trigger. It has SPELL_AURA_CONTROL_VEHICLE
2525 int32 basePoints = m_spellInfo->Effects[effIndex].CalcValue();
2526 if (basePoints > 1) // xinef: some summoning spells have value 1 - indicates vehicle seat
2527 {
2528 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(basePoints);
2529 if (spellInfo && spellInfo->HasAura(SPELL_AURA_CONTROL_VEHICLE))
2530 spellId = spellInfo->Id;
2531 }
2532
2533 // xinef: if we have small value, it indicates seat position
2534 if (basePoints > 0 && basePoints < MAX_VEHICLE_SEATS)
2535 m_originalCaster->CastCustomSpell(spellId, SPELLVALUE_BASE_POINT0, basePoints, summon, true);
2536 else
2537 m_originalCaster->CastSpell(summon, spellId, true);
2538
2539 // xinef: i think this is wrong, found only 2 vehicles with faction override and one of them should inherit caster faction...
2540 //uint32 faction = properties->Faction;
2541 //if (!faction)
2542 uint32 faction = m_originalCaster->GetFaction();
2543
2544 summon->SetFaction(faction);
2545 break;
2546 }
2547
2548 if (summon)
2549 {
2551 ExecuteLogEffectSummonObject(effIndex, summon);
2552 }
2553}
@ 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:3539
@ SUMMON_TYPE_LIGHTWELL
Definition SharedDefines.h:3540
@ SUMMON_TYPE_MINION
Definition SharedDefines.h:3532
@ SUMMON_TYPE_GUARDIAN
Definition SharedDefines.h:3531
@ SUMMON_TYPE_JEEVES
Definition SharedDefines.h:3541
@ SUMMON_TYPE_PET
Definition SharedDefines.h:3530
@ SUMMON_TYPE_TOTEM
Definition SharedDefines.h:3533
@ SUMMON_TYPE_VEHICLE
Definition SharedDefines.h:3538
@ SUMMON_TYPE_MINIPET
Definition SharedDefines.h:3534
@ SUMMON_TYPE_GUARDIAN2
Definition SharedDefines.h:3535
@ SUMMON_CATEGORY_VEHICLE
Definition SharedDefines.h:3522
@ SUMMON_CATEGORY_ALLY
Definition SharedDefines.h:3519
@ SUMMON_CATEGORY_WILD
Definition SharedDefines.h:3518
@ SUMMON_CATEGORY_UNK
Definition SharedDefines.h:3523
@ 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:1472
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:2188
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:16421
void SetFaction(uint32 faction)
Definition Unit.cpp:7056
void SetOwnerGUID(ObjectGuid owner)
Definition Unit.cpp:7655
uint32 HasUnitTypeMask(uint32 mask) const
Definition Unit.h:741
void SetMaxHealth(uint32 val)
Definition Unit.cpp:12365
void SetCreatorGUID(ObjectGuid creator)
Definition Unit.h:716
void ReplaceAllNpcFlags(NPCFlags flags)
Definition Unit.h:766
void RemoveAllMinionsByEntry(uint32 entry)
Definition Unit.cpp:7945
void SetImmuneToAll(bool apply, bool keepCombat=false)
Definition Unit.h:924
Position GetNearPosition(float dist, float angle)
Definition Object.cpp:2795
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(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), WorldObject::GetRandomPoint(), Unit::GetSpellModOwner(), SpellInfo::HasAura(), Unit::HasUnitTypeMask(), SpellInfo::Id, SummonPropertiesEntry::Id, Unit::IsTotem(), Unit::IsVehicle(), LOG_ERROR, m_caster, m_originalCaster, Position::m_positionZ, m_spellInfo, 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)
3099{
3101 return;
3102
3103 if (m_caster->GetPetGUID())
3104 return;
3105
3106 if (!unitTarget)
3107 return;
3108
3109 if (!unitTarget->IsCreature())
3110 return;
3111
3112 Creature* creatureTarget = unitTarget->ToCreature();
3113
3114 if (creatureTarget->IsPet())
3115 return;
3116
3118 return;
3119
3120 // cast finish successfully
3121 //SendChannelUpdate(0);
3122 finish();
3123
3124 Pet* pet = m_caster->CreateTamedPetFrom(creatureTarget, m_spellInfo->Id);
3125 if (!pet) // in very specific state like near world end/etc.
3126 return;
3127
3128 // "kill" original creature
3129 creatureTarget->DespawnOrUnsummon();
3130
3131 uint8 level = (creatureTarget->GetLevel() < (m_caster->GetLevel() - 5)) ? (m_caster->GetLevel() - 5) : creatureTarget->GetLevel();
3132
3133 // prepare visual effect for levelup
3134 pet->SetUInt32Value(UNIT_FIELD_LEVEL, level - 1);
3135
3136 // add to world
3137 pet->GetMap()->AddToMap(pet->ToCreature(), true);
3138
3139 // visual effect for levelup
3140 pet->SetUInt32Value(UNIT_FIELD_LEVEL, level);
3141
3142 // caster have pet now
3143 m_caster->SetMinion(pet, true);
3144
3145 pet->InitTalentForLevel();
3146
3147 if (m_caster->IsPlayer())
3148 {
3151 }
3152}
@ 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)
3295{
3297 return;
3298
3299 if (!unitTarget)
3300 return;
3301
3302 // xinef: Hand of Reckoning, cast before checking canhavethreatlist. fixes damage against pets
3303 if (m_spellInfo->Id == 62124 && unitTarget->GetVictim() != m_caster)
3304 m_caster->CastSpell(unitTarget, 67485, true);
3305
3307 {
3309 return;
3310 }
3311
3313 if (mgr.GetCurrentVictim() == m_caster)
3314 {
3316 return;
3317 }
3318
3319 if (!mgr.IsThreatListEmpty())
3321}
Definition ThreatManager.h:90
Unit * GetCurrentVictim()
Definition ThreatManager.cpp:244
bool IsThreatListEmpty(bool includeOffline=false) const
Definition ThreatManager.cpp:267
void MatchUnitThreatToHighestThreat(Unit *target)
Definition ThreatManager.cpp:502
bool CanHaveThreatList(bool skipAliveCheck=false) const
Definition Unit.cpp:11394

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

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)
3661{
3663 return;
3664
3665 if (!unitTarget || !unitTarget->IsAlive() || !m_caster->IsAlive())
3666 return;
3667
3668 // xinef: skip if target cannot have threat list or caster is friendly (ghoul leap)
3670 return;
3671
3672 // SPELL_EFFECT_THREAT adds flat threat that should not be modified by threat reduction
3674}
void AddThreat(Unit *target, float amount, SpellInfo const *spell=nullptr, bool ignoreModifiers=false, bool ignoreRedirects=false)
== AFFECT MY THREAT LIST ==
Definition ThreatManager.cpp:388

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)
5872{
5874 return;
5875
5876 if (m_caster->IsPlayer())
5877 {
5878 if (Aura* aur = m_caster->GetAura(49152))
5879 aur->RecalculateAmountOfEffects();
5880 else
5881 m_caster->CastSpell(unitTarget, 49152, true); // damage reduction
5882
5884 }
5885}
void SetCanTitanGrip(bool value)
Definition Player.cpp:13154

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)
2836{
2838 return;
2839
2840 if (!m_caster->IsPlayer())
2841 return;
2842 // uint32 skillid = m_spellInfo->Effects[i].MiscValue;
2843 // uint16 skillmax = unitTarget->ToPlayer()->(skillid);
2844 // m_caster->ToPlayer()->SetSkill(skillid, skillval?skillval:1, skillmax+75);
2845}

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

◆ EffectTransmitted()

void Spell::EffectTransmitted ( SpellEffIndex  effIndex)
5341{
5343 return;
5344
5345 uint32 name_id = m_spellInfo->Effects[effIndex].MiscValue;
5346
5347 GameObjectTemplate const* goinfo = sObjectMgr->GetGameObjectTemplate(name_id);
5348
5349 if (!goinfo)
5350 {
5351 LOG_ERROR("sql.sql", "Gameobject (Entry: {}) not exist and not created at spell (ID: {}) cast", name_id, m_spellInfo->Id);
5352 return;
5353 }
5354
5355 float fx, fy, fz;
5356
5357 if (m_targets.HasDst())
5358 destTarget->GetPosition(fx, fy, fz);
5359 //FIXME: this can be better check for most objects but still hack
5360 else if (m_spellInfo->Effects[effIndex].HasRadius() && m_spellInfo->Speed == 0)
5361 {
5362 float dis = m_spellInfo->Effects[effIndex].CalcRadius(m_originalCaster);
5364 }
5365 else
5366 {
5367 //GO is always friendly to it's creator, get range for friends
5368 float min_dis = m_spellInfo->GetMinRange(true);
5369 float max_dis = m_spellInfo->GetMaxRange(true);
5370 float dis = (float)rand_norm() * (max_dis - min_dis) + min_dis;
5371
5373 }
5374
5375 // Seaforium charge
5376 if (m_spellInfo->Id == 52410 || m_spellInfo->Id == 66268 || m_spellInfo->Id == 66674) // SotA / IoC / IoC Huge
5377 {
5378 fx = m_caster->GetPositionX();
5379 fy = m_caster->GetPositionY();
5380 fz = m_caster->GetPositionZ();
5381 }
5382
5383 Map* cMap = m_caster->GetMap();
5384
5385 GameObject* pGameObj = sObjectMgr->IsGameObjectStaticTransport(name_id) ? new StaticTransport() : new GameObject();
5386
5387 G3D::Quat rotation = G3D::Quat::fromAxisAngleRotation(G3D::Vector3::unitZ(), m_caster->GetOrientation());
5388 if (!pGameObj->Create(cMap->GenerateLowGuid<HighGuid::GameObject>(), name_id, cMap, m_caster->GetPhaseMask(), fx, fy, fz, m_caster->GetOrientation(), rotation, 100, GO_STATE_READY))
5389 {
5390 delete pGameObj;
5391 return;
5392 }
5393
5394 int32 duration = m_spellInfo->GetDuration();
5395
5396 switch (goinfo->type)
5397 {
5399 {
5401 m_caster->AddGameObject(pGameObj); // will removed at spell cancel
5402
5403 // end time of range when possible catch fish (FISHING_BOBBER_READY_TIME..GetDuration(m_spellInfo))
5404 // start time == fish-FISHING_BOBBER_READY_TIME (0..GetDuration(m_spellInfo)-FISHING_BOBBER_READY_TIME)
5405 int32 lastSec = 0;
5406 switch (urand(0, 2))
5407 {
5408 case 0:
5409 lastSec = 3;
5410 break;
5411 case 1:
5412 lastSec = 7;
5413 break;
5414 case 2:
5415 lastSec = 13;
5416 break;
5417 }
5418
5419 // Duration of the fishing bobber can't be higher than the Fishing channeling duration
5420 duration = std::min(duration, duration - lastSec*IN_MILLISECONDS + FISHING_BOBBER_READY_TIME*IN_MILLISECONDS);
5421
5422 break;
5423 }
5425 {
5426 if (m_caster->IsPlayer())
5427 {
5428 pGameObj->AddUniqueUse(m_caster->ToPlayer());
5429 m_caster->AddGameObject(pGameObj); // will be removed at spell cancel
5430 }
5431 break;
5432 }
5433 case GAMEOBJECT_TYPE_DUEL_ARBITER: // 52991
5434 m_caster->AddGameObject(pGameObj);
5435 break;
5438 default:
5439 break;
5440 }
5441
5442 pGameObj->SetRespawnTime(duration > 0 ? duration / IN_MILLISECONDS : 0);
5443
5444 pGameObj->SetOwnerGUID(m_caster->GetGUID());
5445
5446 //pGameObj->SetUInt32Value(GAMEOBJECT_LEVEL, m_caster->GetLevel());
5447 pGameObj->SetSpellId(m_spellInfo->Id);
5448
5449 ExecuteLogEffectSummonObject(effIndex, pGameObj);
5450
5451 LOG_DEBUG("spells.effect", "AddObject at SpellEfects.cpp EffectTransmitted");
5452 //m_caster->AddGameObject(pGameObj);
5453 //m_ObjToDel.push_back(pGameObj);
5454
5455 cMap->AddToMap(pGameObj, true);
5456
5457 if (GameObject* linkedTrap = pGameObj->GetLinkedTrap())
5458 {
5459 linkedTrap->SetRespawnTime(duration > 0 ? duration / IN_MILLISECONDS : 0);
5460 linkedTrap->SetSpellId(m_spellInfo->Id);
5461 linkedTrap->SetOwnerGUID(m_caster->GetGUID());
5462
5463 ExecuteLogEffectSummonObject(effIndex, linkedTrap);
5464 }
5465
5466 if (Player* player = m_caster->ToPlayer())
5467 {
5468 player->SetCanTeleport(true);
5469 }
5470}
#define FISHING_BOBBER_READY_TIME
Definition GameObject.h:117
@ GAMEOBJECT_TYPE_DUEL_ARBITER
Definition SharedDefines.h:1582
@ GAMEOBJECT_TYPE_SUMMONING_RITUAL
Definition SharedDefines.h:1584
@ GAMEOBJECT_TYPE_CHEST
Definition SharedDefines.h:1569
@ GAMEOBJECT_TYPE_FISHINGHOLE
Definition SharedDefines.h:1591
@ GAMEOBJECT_TYPE_FISHINGNODE
Definition SharedDefines.h:1583
@ UNIT_FIELD_CHANNEL_OBJECT
Definition UpdateFields.h:93
void SetOwnerGUID(ObjectGuid owner)
Definition GameObject.h:163
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)
943{
946 return;
947
948 uint32 triggered_spell_id = m_spellInfo->Effects[effIndex].TriggerSpell;
949
950 // normal case
951 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(triggered_spell_id);
952 if (!spellInfo)
953 {
954 LOG_DEBUG("spells.aura", "Spell::EffectTriggerMissileSpell spell {} tried to trigger unknown spell {}", m_spellInfo->Id, triggered_spell_id);
955 return;
956 }
957
958 SpellCastTargets targets;
960 {
961 if (!spellInfo->NeedsToBeTriggeredByCaster(m_spellInfo, effIndex))
962 return;
963 targets.SetUnitTarget(unitTarget);
964 }
965 else //if (effectHandleMode == SPELL_EFFECT_HANDLE_HIT)
966 {
967 if (spellInfo->NeedsToBeTriggeredByCaster(m_spellInfo, effIndex) && (m_spellInfo->Effects[effIndex].GetProvidedTargetMask() & TARGET_FLAG_UNIT_MASK))
968 return;
969
971 targets.SetDst(m_targets);
972
973 targets.SetUnitTarget(m_caster);
974 }
975
976 CustomSpellValues values;
977 // set basepoints for trigger with value effect
979 {
980 // maybe need to set value only when basepoints == 0?
984 }
985
986 // Remove spell cooldown (not category) if spell triggering spell with cooldown and same category
987 if (m_caster->IsPlayer() && spellInfo->CategoryRecoveryTime && m_spellInfo->GetCategory() == spellInfo->GetCategory())
988 {
989 m_caster->ToPlayer()->RemoveSpellCooldown(spellInfo->Id);
990 }
991
992 // original caster guid only for GO cast
993 m_caster->CastSpell(targets, spellInfo, &values, TRIGGERED_FULL_MASK, nullptr, nullptr, m_originalCasterGUID);
994}
@ 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)
1051{
1053 return;
1054
1055 uint32 triggered_spell_id = m_spellInfo->Effects[effIndex].TriggerSpell;
1056 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(triggered_spell_id);
1057
1058 if (!spellInfo)
1059 {
1060 LOG_ERROR("spells.effect", "EffectTriggerRitualOfSummoning of spell {}: triggering unknown spell id {}", m_spellInfo->Id, triggered_spell_id);
1061 return;
1062 }
1063
1064 finish();
1065
1066 m_caster->CastSpell((Unit*)nullptr, spellInfo, true);
1067}

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

◆ EffectUnlearnSpecialization()

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

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)
2760{
2762 return;
2763
2764 if (!unitTarget || m_caster->IsPlayer())
2765 return;
2766
2767 if (ObjectGuid guid = m_caster->GetGUID()) // the trainer is the caster
2769}
void SendTalentWipeConfirm(ObjectGuid guid)
Definition Player.cpp:8918

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)
244{
245 // NOT USED BY ANY SPELL OR USELESS OR IMPLEMENTED IN DIFFERENT WAY IN TRINITY
246}

◆ EffectWeaponDmg()

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

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:160
@ 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:2493
void UpdatePotionCooldown(Spell *spell=nullptr)
Definition PlayerUpdates.cpp:1552
Definition TemporarySummon.h:125
virtual void setDeathState(DeathState s, bool despawn=false)
Definition Unit.cpp:11335
void UpdateInterruptMask()
Definition Unit.cpp:885
void ModifyAuraState(AuraStateType flag, bool apply)
Definition Unit.cpp:7579
bool AttackStop()
Force the unit to stop attacking. This will clear UNIT_STATE_MELEE_ATTACKING, Interrupt current spell...
Definition Unit.cpp:7436

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()

Unit * Spell::GetCaster ( ) const
inline

◆ 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:2614
@ 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:3472
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:4127
bool IsSitState() const
Definition Unit.cpp:13065
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:8145
Unit * GetMagicHitRedirectTarget(Unit *victim, SpellInfo const *spellInfo)
Definition Unit.cpp:8107

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:6368
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:1482
@ TARGET_DEST_DB
Definition SharedDefines.h:1428
@ TARGET_DEST_CASTER_FRONT_LEAP
Definition SharedDefines.h:1465
@ TARGET_DEST_CASTER_FRONT_LEFT
Definition SharedDefines.h:1454
@ TARGET_DEST_CASTER_BACK_RIGHT
Definition SharedDefines.h:1452
@ TARGET_DEST_CASTER_FISHING
Definition SharedDefines.h:1449
@ TARGET_DEST_CASTER_BACK_LEFT
Definition SharedDefines.h:1453
@ TARGET_DEST_CASTER_SUMMON
Definition SharedDefines.h:1442
@ TARGET_DEST_CASTER
Definition SharedDefines.h:1429
@ TARGET_DEST_CASTER_FRONT_RIGHT
Definition SharedDefines.h:1451
@ TARGET_DEST_CASTER_36
Definition SharedDefines.h:1446
@ TARGET_DEST_HOME
Definition SharedDefines.h:1424
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:1292
float GetHeight(float x, float y, float z, bool checkVMap=true, float maxSearchDist=DEFAULT_HEIGHT_SEARCH) const
Definition Map.cpp:1144
MapCollisionData & GetMapCollisionData()
Definition Map.h:525
bool IsInWater(uint32 phaseMask, float x, float y, float z, float collisionHeight) const
Definition Map.cpp:1573
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:17107
float GetMapHeight(float x, float y, float z, bool vmap=true, float distanceToSearch=50.0f) const
Definition Object.cpp:3086
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:2693
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:1507
@ TARGET_UNIT_PASSENGER_6
Definition SharedDefines.h:1512
@ TARGET_UNIT_VEHICLE
Definition SharedDefines.h:1504
@ TARGET_UNIT_PASSENGER_2
Definition SharedDefines.h:1508
@ TARGET_UNIT_PASSENGER_4
Definition SharedDefines.h:1510
@ TARGET_UNIT_PASSENGER_7
Definition SharedDefines.h:1513
@ TARGET_UNIT_MASTER
Definition SharedDefines.h:1437
@ TARGET_UNIT_PASSENGER_5
Definition SharedDefines.h:1511
@ TARGET_UNIT_PASSENGER_3
Definition SharedDefines.h:1509
@ TARGET_UNIT_SUMMONER
Definition SharedDefines.h:1502
@ TARGET_UNIT_PASSENGER_0
Definition SharedDefines.h:1506
Unit * GetSummonerUnit() const
Definition TemporarySummon.cpp:44
Unit * GetVehicleBase() const
Definition Unit.cpp:14967
Unit * GetPassenger(int8 seatId) const
Definition Vehicle.cpp:229

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:1455
@ 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:1486
@ TARGET_UNIT_CHANNEL_TARGET
Definition SharedDefines.h:1487
@ TARGET_DEST_CHANNEL_CASTER
Definition SharedDefines.h:1516
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:1438
@ TARGET_DEST_DEST_RANDOM
Definition SharedDefines.h:1496
@ TARGET_DEST_DEST
Definition SharedDefines.h:1497
@ TARGET_DEST_DYNOBJ_NONE
Definition SharedDefines.h:1498
@ TARGET_DEST_DYNOBJ_ALLY
Definition SharedDefines.h:1439
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:2843

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:1473
@ TARGET_DEST_TARGET_BACK
Definition SharedDefines.h:1475
@ TARGET_DEST_TARGET_RANDOM
Definition SharedDefines.h:1484
@ TARGET_DEST_TARGET_ENEMY
Definition SharedDefines.h:1463
@ 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:2710
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:1927
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
2023{
2024 Player* player = m_caster->ToPlayer();
2025 if (!player)
2026 return;
2027
2028 if (gameObjTarget)
2029 {
2030 // Players shouldn't be able to loot gameobjects that are currently despawned
2031 if (!gameObjTarget->isSpawned() && !player->IsGameMaster())
2032 {
2033 LOG_ERROR("spells.effect", "Possible hacking attempt: Player {} [{}] tried to loot a gameobject [{}] which is on respawn time without being in GM mode!",
2034 player->GetName(), player->GetGUID().ToString(), gameObjTarget->GetGUID().ToString());
2035 return;
2036 }
2037 // special case, already has GossipHello inside so return and avoid calling twice
2039 {
2041 return;
2042 }
2043
2044 if (sScriptMgr->OnGossipHello(player, gameObjTarget))
2045 return;
2046
2047 if (gameObjTarget->AI()->GossipHello(player, false))
2048 return;
2049
2050 switch (gameObjTarget->GetGoType())
2051 {
2053 gameObjTarget->UseDoorOrButton(0, false, player);
2054 return;
2056 gameObjTarget->UseDoorOrButton(0, false, player);
2057
2058 // Xinef: properly link possible traps
2059 if (uint32 trapEntry = gameObjTarget->GetGOInfo()->button.linkedTrap)
2060 gameObjTarget->TriggeringLinkedGameObject(trapEntry, player);
2061 return;
2065 return;
2066
2068 // triggering linked GO
2071 return;
2072
2074 // triggering linked GO
2075 if (uint32 trapEntry = gameObjTarget->GetGOInfo()->chest.linkedTrapId)
2077
2078 // Don't return, let loots been taken
2079 default:
2080 break;
2081 }
2082 }
2083
2084 // Send loot
2085 player->SendLoot(guid, loottype);
2086}
@ GAMEOBJECT_TYPE_SPELL_FOCUS
Definition SharedDefines.h:1574
@ GAMEOBJECT_TYPE_QUESTGIVER
Definition SharedDefines.h:1568
virtual bool GossipHello(Player *, bool)
Definition GameObjectAI.h:54
bool isSpawned() const
Definition GameObject.h:189
void TriggeringLinkedGameObject(uint32 trapEntry, Unit *target)
Definition GameObject.cpp:1361
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::@234::@239 chest
struct GameObjectTemplate::@234::@238 questgiver
struct GameObjectTemplate::@234::@243 spellFocus
uint32 linkedTrapId
Definition GameObjectData.h:91

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

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:149
uint32 GetMaxStackCount() const
Definition Item.h:274
void DurabilityPointLossForEquipSlot(EquipmentSlots slot)
Definition Player.cpp:4722

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:1535
@ 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:10940
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:397
void SetLastUsedRune(RuneType type)
Definition Player.h:2549
uint32 GetRuneBaseCooldown(uint8 index, bool skipGrace)
Definition Player.cpp:13388
void RestoreBaseRune(uint8 index)
Definition Player.cpp:13417
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:5823
void UpdateOrientation(float orientation)
Only server-side orientation update, does not broadcast to client.
Definition Unit.cpp:16005
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: